[Libreoffice-commits] core.git: Branch 'distro/lhm/libreoffice-5-2+backports' - vcl/inc vcl/win
Libreoffice Gerrit user
logerrit at kemper.freedesktop.org
Wed Jan 16 18:33:50 UTC 2019
vcl/inc/win/saltimer.h | 20 ++++++++++++++++++++
vcl/win/app/salinst.cxx | 11 +++++++++++
vcl/win/app/saltimer.cxx | 34 ++++++++++++++++++++++++++++++++--
vcl/win/window/salframe.cxx | 11 +++++++++++
4 files changed, 74 insertions(+), 2 deletions(-)
New commits:
commit babcb6298a8fed0a09108cb74f6c3e654531742e
Author: Jan-Marek Glogowski <glogow at fbihome.de>
AuthorDate: Thu Oct 12 18:19:12 2017 +0200
Commit: Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Wed Jan 16 19:33:25 2019 +0100
WIN fix redraw during window move and resize
During window move and resize, Windows spawns a nested message
loop, blocking our direct processing. In this case we switch to
timer messages for all timeouts.
But if LO is busy with background jobs, the posted 0ms timer
messages will block any system event processing, halting any
updates until we're idle again. So for these cases we switch
to the WM_TIMER based SetTimer timer.
Change-Id: I854f4984d7c75d6829f82cda5cb4479967edce48
Reviewed-on: https://gerrit.libreoffice.org/43350
Tested-by: Jenkins <ci at libreoffice.org>
Reviewed-by: Jan-Marek Glogowski <glogow at fbihome.de>
Reviewed-on: https://gerrit.libreoffice.org/66452
Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
Tested-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
diff --git a/vcl/inc/win/saltimer.h b/vcl/inc/win/saltimer.h
index 68973e1cadc3..d762b51b6716 100644
--- a/vcl/inc/win/saltimer.h
+++ b/vcl/inc/win/saltimer.h
@@ -31,13 +31,20 @@ class WinSalTimer final : public SalTimer, protected VersionedEvent
// for access to ImplHandleElapsedTimer
friend bool ImplSalYield( bool bWait, bool bHandleAllCurrentEvents );
+ /**
+ * Identifier for our SetTimer based timer
+ */
+ static constexpr UINT_PTR m_aWmTimerId = 0xdeadbeef;
+
HANDLE m_nTimerId; ///< Windows timer id
bool m_bDirectTimeout; ///< timeout can be processed directly
+ bool m_bForceRealTimer; ///< enforce using a real timer for 0ms
void ImplStart( sal_uIntPtr nMS );
void ImplStop();
void ImplHandleTimerEvent( WPARAM aWPARAM );
void ImplHandleElapsedTimer();
+ void ImplHandle_WM_TIMER( WPARAM aWPARAM );
public:
WinSalTimer();
@@ -48,6 +55,14 @@ public:
inline bool IsDirectTimeout() const;
inline bool HasTimerElapsed() const;
+
+ /**
+ * Enforces the usage of a real timer instead of the message queue
+ *
+ * Needed for Window resize processing, as this starts a modal event loop.
+ */
+ void SetForceRealTimer( bool bVal );
+ inline bool GetForceRealTimer() const;
};
inline bool WinSalTimer::IsDirectTimeout() const
@@ -60,6 +75,11 @@ inline bool WinSalTimer::HasTimerElapsed() const
return m_bDirectTimeout || ExistsValidEvent();
}
+inline bool WinSalTimer::GetForceRealTimer() const
+{
+ return m_bForceRealTimer;
+}
+
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/win/app/salinst.cxx b/vcl/win/app/salinst.cxx
index 7bef41e8ac4c..75dce1c1edef 100644
--- a/vcl/win/app/salinst.cxx
+++ b/vcl/win/app/salinst.cxx
@@ -633,6 +633,10 @@ bool ImplSalYield( bool bWait, bool bHandleAllCurrentEvents )
}
}
+ // we're back in the main loop after resize or move
+ if ( pTimer )
+ pTimer->SetForceRealTimer( false );
+
return bWasMsg;
}
@@ -757,6 +761,13 @@ LRESULT CALLBACK SalComWndProc( HWND, UINT nMsg, WPARAM wParam, LPARAM lParam, i
pTimer->ImplHandleTimerEvent( wParam );
break;
}
+ case WM_TIMER:
+ {
+ WinSalTimer *const pTimer = static_cast<WinSalTimer*>( ImplGetSVData()->maSchedCtx.mpSalTimer );
+ assert( pTimer != nullptr );
+ pTimer->ImplHandle_WM_TIMER( wParam );
+ break;
+ }
}
return nRet;
diff --git a/vcl/win/app/saltimer.cxx b/vcl/win/app/saltimer.cxx
index f155de0d4ce8..6fdd1a3b3e86 100644
--- a/vcl/win/app/saltimer.cxx
+++ b/vcl/win/app/saltimer.cxx
@@ -43,12 +43,15 @@ void WinSalTimer::ImplStop()
const WinSalInstance *pInst = pSalData->mpFirstInstance;
assert( !pInst || pSalData->mnAppThreadId == GetCurrentThreadId() );
+ if ( m_bForceRealTimer && m_bDirectTimeout )
+ KillTimer( GetSalData()->mpFirstInstance->mhComWnd, m_aWmTimerId );
+ m_bDirectTimeout = false;
+
const HANDLE hTimer = m_nTimerId;
if ( nullptr == hTimer )
return;
m_nTimerId = nullptr;
- m_bDirectTimeout = false;
DeleteTimerQueueTimer( nullptr, hTimer, INVALID_HANDLE_VALUE );
// Keep InvalidateEvent after DeleteTimerQueueTimer, because the event id
// is set in SalTimerProc, which DeleteTimerQueueTimer will finish or cancel.
@@ -75,13 +78,21 @@ void WinSalTimer::ImplStart( sal_uLong nMS )
if ( !m_bDirectTimeout )
CreateTimerQueueTimer(&m_nTimerId, nullptr, SalTimerProc, this,
nMS, 0, WT_EXECUTEINTIMERTHREAD | WT_EXECUTEONLYONCE);
- // We don't need any wakeup message, as this code can just run in the
+ else if ( m_bForceRealTimer )
+ {
+ // so we don't block the nested message queue in move and resize
+ // with posted 0ms SAL_MSG_TIMER_CALLBACK messages
+ SetTimer( GetSalData()->mpFirstInstance->mhComWnd, m_aWmTimerId,
+ USER_TIMER_MINIMUM, nullptr );
+ }
+ // we don't need any wakeup message, as this code can just run in the
// main thread!
}
WinSalTimer::WinSalTimer()
: m_nTimerId( nullptr )
, m_bDirectTimeout( false )
+ , m_bForceRealTimer( false )
{
}
@@ -173,4 +184,23 @@ void WinSalTimer::ImplHandleTimerEvent( const WPARAM aWPARAM )
ImplHandleElapsedTimer();
}
+void WinSalTimer::SetForceRealTimer( const bool bVal )
+{
+ if ( m_bForceRealTimer == bVal )
+ return;
+
+ m_bForceRealTimer = bVal;
+
+ // we need a real timer, as m_bDirectTimeout won't be processed
+ if ( bVal && m_bDirectTimeout )
+ Start( 0 );
+}
+
+void WinSalTimer::ImplHandle_WM_TIMER( const WPARAM aWPARAM )
+{
+ assert( m_aWmTimerId == aWPARAM );
+ if ( m_aWmTimerId == aWPARAM && m_bDirectTimeout && m_bForceRealTimer )
+ ImplHandleElapsedTimer();
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/win/window/salframe.cxx b/vcl/win/window/salframe.cxx
index 7aeec51d8cac..b14bbfd281e6 100644
--- a/vcl/win/window/salframe.cxx
+++ b/vcl/win/window/salframe.cxx
@@ -3997,6 +3997,10 @@ static void ImplHandleSizeMsg( HWND hWnd, WPARAM wParam, LPARAM lParam )
ImplSaveFrameState( pFrame );
// Call Hdl
ImplCallSizeHdl( hWnd );
+
+ WinSalTimer* pTimer = static_cast<WinSalTimer*>( ImplGetSVData()->maSchedCtx.mpSalTimer );
+ if ( pTimer )
+ pTimer->SetForceRealTimer( true );
}
}
}
@@ -4803,6 +4807,13 @@ static int ImplHandleSysCommand( HWND hWnd, WPARAM wParam, LPARAM lParam )
}
}
+ if ( nCommand == SC_MOVE )
+ {
+ WinSalTimer* pTimer = static_cast<WinSalTimer*>( ImplGetSVData()->maSchedCtx.mpSalTimer );
+ if ( pTimer )
+ pTimer->SetForceRealTimer( true );
+ }
+
if ( nCommand == SC_KEYMENU )
{
// do not process SC_KEYMENU if we have a native menu
More information about the Libreoffice-commits
mailing list