Kaydet (Commit) 3bf6c970 authored tarafından Jan-Marek Glogowski's avatar Jan-Marek Glogowski

tdf#112975 WIN correctly handle VclInputFlags::OTHER

On Windows we can just check the message queue for existing
messages. But VclInputFlags::OTHER is used to check for any
messages, which can't be explicitly checked.

In the case of checking for VclInputFlags::OTHER while
excluding an other message type, we have to make multiple
PeekMessage calls and exclude all non-checked message ids.

Change-Id: I1cedd4b76444769842c74228fc547f0d924f8b60
Reviewed-on: https://gerrit.libreoffice.org/43337Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarJan-Marek Glogowski <glogow@fbihome.de>
üst fb4e7be5
...@@ -47,6 +47,7 @@ public: ...@@ -47,6 +47,7 @@ public:
virtual void Stop() override; virtual void Stop() override;
inline bool IsDirectTimeout() const; inline bool IsDirectTimeout() const;
inline bool HasTimerElapsed() const;
}; };
inline bool WinSalTimer::IsDirectTimeout() const inline bool WinSalTimer::IsDirectTimeout() const
...@@ -54,6 +55,11 @@ inline bool WinSalTimer::IsDirectTimeout() const ...@@ -54,6 +55,11 @@ inline bool WinSalTimer::IsDirectTimeout() const
return m_bDirectTimeout; return m_bDirectTimeout;
} }
inline bool WinSalTimer::HasTimerElapsed() const
{
return m_bDirectTimeout || ExistsValidEvent();
}
#endif #endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
...@@ -689,10 +689,119 @@ LRESULT CALLBACK SalComWndProcW( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lPa ...@@ -689,10 +689,119 @@ LRESULT CALLBACK SalComWndProcW( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lPa
return nRet; return nRet;
} }
struct MsgRange
{
UINT nStart;
UINT nEnd;
};
static std::vector<MsgRange> GetOtherRanges( VclInputFlags nType )
{
assert( nType != VCL_INPUT_ANY );
// this array must be kept sorted!
const UINT nExcludeMsgIds[] =
{
0,
WM_MOVE, // 3
WM_SIZE, // 5
WM_PAINT, // 15
WM_KEYDOWN, // 256
WM_TIMER, // 275
WM_MOUSEFIRST, // 512
513,
514,
515,
516,
517,
518,
519,
520,
WM_MOUSELAST, // 521
SAL_MSG_POSTMOVE, // WM_USER+136
SAL_MSG_POSTCALLSIZE, // WM_USER+137
SAL_MSG_TIMER_CALLBACK, // WM_USER+162
UINT_MAX
};
const unsigned MAX_EXCL = SAL_N_ELEMENTS( nExcludeMsgIds );
bool aExcludeMsgList[ MAX_EXCL ] = { false, };
std::vector<MsgRange> aResult;
// set the excluded values
if ( !(nType & VclInputFlags::MOUSE) )
{
for ( unsigned i = 0; nExcludeMsgIds[ 6 + i ] <= WM_MOUSELAST; ++i )
aExcludeMsgList[ 6 + i ] = true;
}
if ( !(nType & VclInputFlags::KEYBOARD) )
aExcludeMsgList[ 4 ] = true;
if ( !(nType & VclInputFlags::PAINT) )
{
aExcludeMsgList[ 1 ] = true;
aExcludeMsgList[ 2 ] = true;
aExcludeMsgList[ 3 ] = true;
aExcludeMsgList[ 16 ] = true;
aExcludeMsgList[ 17 ] = true;
}
if ( !(nType & VclInputFlags::TIMER) )
{
aExcludeMsgList[ 5 ] = true;
aExcludeMsgList[ 18 ] = true;
}
// build the message ranges to check
MsgRange aRange = { 0, 0 };
bool doEnd = true;
for ( unsigned i = 1; i < MAX_EXCL; ++i )
{
if ( aExcludeMsgList[ i ] )
{
if ( !doEnd )
{
if ( nExcludeMsgIds[ i ] == aRange.nStart )
++aRange.nStart;
else
doEnd = true;
}
if ( doEnd )
{
aRange.nEnd = nExcludeMsgIds[ i ] - 1;
aResult.push_back( aRange );
doEnd = false;
aRange.nStart = aRange.nEnd + 2;
}
}
}
if ( aRange.nStart != UINT_MAX )
{
aRange.nEnd = UINT_MAX;
aResult.push_back( aRange );
}
return aResult;
}
bool WinSalInstance::AnyInput( VclInputFlags nType ) bool WinSalInstance::AnyInput( VclInputFlags nType )
{ {
MSG aMsg; MSG aMsg;
if ( nType & VclInputFlags::TIMER )
{
const WinSalTimer* pTimer = static_cast<WinSalTimer*>( ImplGetSVData()->maSchedCtx.mpSalTimer );
if ( pTimer && pTimer->HasTimerElapsed() )
return true;
}
if ( (nType & VCL_INPUT_ANY) == VCL_INPUT_ANY ) if ( (nType & VCL_INPUT_ANY) == VCL_INPUT_ANY )
{ {
// revert bugfix for #108919# which never reported timeouts when called from the timer handler // revert bugfix for #108919# which never reported timeouts when called from the timer handler
...@@ -702,32 +811,52 @@ bool WinSalInstance::AnyInput( VclInputFlags nType ) ...@@ -702,32 +811,52 @@ bool WinSalInstance::AnyInput( VclInputFlags nType )
} }
else else
{ {
if ( nType & VclInputFlags::MOUSE ) const bool bCheck_KEYBOARD (nType & VclInputFlags::KEYBOARD);
{ const bool bCheck_OTHER (nType & VclInputFlags::OTHER);
// Test for mouse input
if ( PeekMessageW( &aMsg, nullptr, WM_MOUSEFIRST, WM_MOUSELAST,
PM_NOREMOVE | PM_NOYIELD ) )
return true;
}
if ( nType & VclInputFlags::KEYBOARD ) // If there is a modifier key event, it counts as OTHER
// Previously we were simply ignoring these events...
if ( bCheck_KEYBOARD || bCheck_OTHER )
{ {
// Test for key input
if ( PeekMessageW( &aMsg, nullptr, WM_KEYDOWN, WM_KEYDOWN, if ( PeekMessageW( &aMsg, nullptr, WM_KEYDOWN, WM_KEYDOWN,
PM_NOREMOVE | PM_NOYIELD ) ) PM_NOREMOVE | PM_NOYIELD ) )
{ {
if ( (aMsg.wParam == VK_SHIFT) || const bool bIsModifier = ( (aMsg.wParam == VK_SHIFT) ||
(aMsg.wParam == VK_CONTROL) || (aMsg.wParam == VK_CONTROL) || (aMsg.wParam == VK_MENU) );
(aMsg.wParam == VK_MENU) ) if ( bCheck_KEYBOARD && !bIsModifier )
return false; return true;
else if ( bCheck_OTHER && bIsModifier )
return true; return true;
} }
} }
// Other checks for all messages not excluded.
// The less we exclude, the less ranges have to be checked!
if ( bCheck_OTHER )
{
// TIMER and KEYBOARD are already handled, so always exclude them!
VclInputFlags nOtherType = nType &
~VclInputFlags(VclInputFlags::KEYBOARD | VclInputFlags::TIMER);
std::vector<MsgRange> aMsgRangeList( GetOtherRanges( nOtherType ) );
for ( MsgRange aRange : aMsgRangeList )
if ( PeekMessageW( &aMsg, nullptr, aRange.nStart,
aRange.nEnd, PM_NOREMOVE | PM_NOYIELD ) )
return true;
// MOUSE and PAINT already handled, so skip futher checks
return false;
}
if ( nType & VclInputFlags::MOUSE )
{
if ( PeekMessageW( &aMsg, nullptr, WM_MOUSEFIRST, WM_MOUSELAST,
PM_NOREMOVE | PM_NOYIELD ) )
return true;
}
if ( nType & VclInputFlags::PAINT ) if ( nType & VclInputFlags::PAINT )
{ {
// Test for paint input
if ( PeekMessageW( &aMsg, nullptr, WM_PAINT, WM_PAINT, if ( PeekMessageW( &aMsg, nullptr, WM_PAINT, WM_PAINT,
PM_NOREMOVE | PM_NOYIELD ) ) PM_NOREMOVE | PM_NOYIELD ) )
return true; return true;
...@@ -748,22 +877,6 @@ bool WinSalInstance::AnyInput( VclInputFlags nType ) ...@@ -748,22 +877,6 @@ bool WinSalInstance::AnyInput( VclInputFlags nType )
PM_NOREMOVE | PM_NOYIELD ) ) PM_NOREMOVE | PM_NOYIELD ) )
return true; return true;
} }
if ( nType & VclInputFlags::TIMER )
{
// Test for timer input
if ( PeekMessageW( &aMsg, nullptr, WM_TIMER, WM_TIMER,
PM_NOREMOVE | PM_NOYIELD ) )
return true;
}
if ( nType & VclInputFlags::OTHER )
{
// Test for any input
if ( PeekMessageW( &aMsg, nullptr, 0, 0, PM_NOREMOVE | PM_NOYIELD ) )
return true;
}
} }
return false; return false;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment