summaryrefslogtreecommitdiff
path: root/vcl/win/app
diff options
context:
space:
mode:
authorJan-Marek Glogowski <glogow@fbihome.de>2017-10-12 18:19:12 +0200
committerJan-Marek Glogowski <glogow@fbihome.de>2017-10-13 16:49:22 +0200
commitabe3af8e9871907aa75b913f2b8094cac651bc6d (patch)
treec3a4a6a623988d3d79c12baff6c4dcf624055c1a /vcl/win/app
parent3bf6c97029d26ddf20007c47ca6b68e5cc52d846 (diff)
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@libreoffice.org> Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de>
Diffstat (limited to 'vcl/win/app')
-rw-r--r--vcl/win/app/salinst.cxx11
-rw-r--r--vcl/win/app/saltimer.cxx34
2 files changed, 43 insertions, 2 deletions
diff --git a/vcl/win/app/salinst.cxx b/vcl/win/app/salinst.cxx
index ade332297fc6..54598a420040 100644
--- a/vcl/win/app/salinst.cxx
+++ b/vcl/win/app/salinst.cxx
@@ -530,6 +530,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;
}
@@ -665,6 +669,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 fe22d53db8c8..9d20c70bdb5a 100644
--- a/vcl/win/app/saltimer.cxx
+++ b/vcl/win/app/saltimer.cxx
@@ -41,12 +41,15 @@ void WinSalTimer::ImplStop()
const WinSalInstance *pInst = pSalData->mpInstance;
assert( !pInst || pSalData->mnAppThreadId == GetCurrentThreadId() );
+ if ( m_bForceRealTimer && m_bDirectTimeout )
+ KillTimer( GetSalData()->mpInstance->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.
@@ -73,13 +76,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()->mpInstance->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 )
{
}
@@ -156,4 +167,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: */