vcl/win/app/salinst.cxx |  185 ++++--------------------------------------------
 1 file changed, 18 insertions(+), 167 deletions(-)

New commits:
commit 843af72bcc9047867588e29c8e10b84a5e58d70e
Author:     Luboš Luňák <l.lu...@centrum.cz>
AuthorDate: Wed Feb 10 16:37:17 2021 +0000
Commit:     Luboš Luňák <l.lu...@collabora.com>
CommitDate: Thu Feb 11 11:07:11 2021 +0100

    make win32 variant AnyInput() not deliver events (tdf#140293)
    
    Win32 API PeekMessage() actually may deliver events, despite
    what the name may suggest, even with PM_NOREMOVE argument.
    That means this is problematic for use in AnyInput(), as that
    function should just check the event queue but not do anything
    with it. Using GetQueueStatus() should solve the problem.
    
    See 
https://lists.freedesktop.org/archives/libreoffice/2021-February/086788.html
    for further details.
    
    Change-Id: I10d3423f89f6f050534625110113dee60959f7a3
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/110718
    Reviewed-by: Jan-Marek Glogowski <glo...@fbihome.de>
    Reviewed-by: Luboš Luňák <l.lu...@collabora.com>
    Tested-by: Jenkins

diff --git a/vcl/win/app/salinst.cxx b/vcl/win/app/salinst.cxx
index ea4c9420beb0..18605f2f17d4 100644
--- a/vcl/win/app/salinst.cxx
+++ b/vcl/win/app/salinst.cxx
@@ -665,116 +665,8 @@ LRESULT CALLBACK SalComWndProcW( HWND hWnd, UINT nMsg, 
WPARAM wParam, LPARAM lPa
     return nRet;
 }
 
-namespace {
-
-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 )
 {
-    MSG aMsg;
-
     if ( nType & VclInputFlags::TIMER )
     {
         const WinSalTimer* pTimer = static_cast<WinSalTimer*>( 
ImplGetSVData()->maSchedCtx.mpSalTimer );
@@ -782,81 +674,40 @@ bool WinSalInstance::AnyInput( VclInputFlags nType )
             return true;
     }
 
+    // Note: Do not use PeekMessage(), despite the name it may dispatch events,
+    // even with PM_NOREMOVE specified, which may lead to unwanted recursion.
+
     if ( (nType & VCL_INPUT_ANY) == VCL_INPUT_ANY )
     {
         // revert bugfix for #108919# which never reported timeouts when 
called from the timer handler
         // which made the application completely unresponsive during 
background formatting
-        if ( PeekMessageW( &aMsg, nullptr, 0, 0, PM_NOREMOVE | PM_NOYIELD ) )
+        if ( GetQueueStatus( QS_ALLEVENTS ))
             return true;
     }
     else
     {
-        const bool bCheck_KEYBOARD (nType & VclInputFlags::KEYBOARD);
-        const bool bCheck_OTHER    (nType & VclInputFlags::OTHER);
-
-        // If there is a modifier key event, it counts as OTHER
-        // Previously we were simply ignoring these events...
-        if ( bCheck_KEYBOARD || bCheck_OTHER )
-        {
-            if ( PeekMessageW( &aMsg, nullptr, WM_KEYDOWN, WM_KEYDOWN,
-                                  PM_NOREMOVE | PM_NOYIELD ) )
-            {
-                const bool bIsModifier = ( (aMsg.wParam == VK_SHIFT) ||
-                    (aMsg.wParam == VK_CONTROL) || (aMsg.wParam == VK_MENU) );
-                if ( bCheck_KEYBOARD && !bIsModifier )
-                    return true;
-                if ( bCheck_OTHER && bIsModifier )
-                    return true;
-            }
-        }
+        UINT flags = 0;
 
-        // 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 const & aRange : aMsgRangeList )
-                if ( PeekMessageW( &aMsg, nullptr, aRange.nStart,
-                                   aRange.nEnd, PM_NOREMOVE | PM_NOYIELD ) )
-                    return true;
-
-            // MOUSE and PAINT already handled, so skip further checks
-            return false;
-        }
+        // This code previously considered modifier keys as OTHER,
+        // but that makes this hard to do without PeekMessage,
+        // is inconsistent with the X11 backend, and I see no good reason.
+        if ( nType & VclInputFlags::KEYBOARD )
+            flags |= QS_KEY;
 
         if ( nType & VclInputFlags::MOUSE )
-        {
-            if ( PeekMessageW( &aMsg, nullptr, WM_MOUSEFIRST, WM_MOUSELAST,
-                                  PM_NOREMOVE | PM_NOYIELD ) )
-                return true;
-        }
+            flags |= QS_MOUSE;
 
         if ( nType & VclInputFlags::PAINT )
-        {
-            if ( PeekMessageW( &aMsg, nullptr, WM_PAINT, WM_PAINT,
-                                  PM_NOREMOVE | PM_NOYIELD ) )
-                return true;
+            flags |= QS_PAINT;
 
-            if ( PeekMessageW( &aMsg, nullptr, WM_SIZE, WM_SIZE,
-                                  PM_NOREMOVE | PM_NOYIELD ) )
-                return true;
+        if ( nType & VclInputFlags::TIMER )
+            flags |= QS_TIMER;
 
-            if ( PeekMessageW( &aMsg, nullptr, SAL_MSG_POSTCALLSIZE, 
SAL_MSG_POSTCALLSIZE,
-                                  PM_NOREMOVE | PM_NOYIELD ) )
-                return true;
+        if( nType & VclInputFlags::OTHER )
+            flags |= QS_ALLEVENTS & ~QS_KEY & ~QS_MOUSE & ~QS_PAINT & 
~QS_TIMER;
 
-            if ( PeekMessageW( &aMsg, nullptr, WM_MOVE, WM_MOVE,
-                                  PM_NOREMOVE | PM_NOYIELD ) )
-                return true;
-
-            if ( PeekMessageW( &aMsg, nullptr, SAL_MSG_POSTMOVE, 
SAL_MSG_POSTMOVE,
-                                  PM_NOREMOVE | PM_NOYIELD ) )
-                return true;
-        }
+        if( GetQueueStatus( flags ))
+            return true;
     }
 
     return false;
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to