842991
From 0c20ed4d58f7b55bcc12fa288b93d1c6d88a7dcc Mon Sep 17 00:00:00 2001
842991
From: Stephan Bergmann <sbergman@redhat.com>
842991
Date: Thu, 14 May 2020 14:47:21 +0200
842991
Subject: [PATCH] Keep order of GDK input events intact
842991
842991
As explained at <https://bugzilla.redhat.com/show_bug.cgi?id=1377293#c12>
842991
"[Wayland] When typing fast at high CPU load, LibreOffice breaks key (letter)
842991
order":  "with a local LO master --with-lang=ALL ASan+UBSan build (i.e., which
842991
executes somewhat slowly):  When typing 'file' in Writer right after it started
842991
up (but no longer after more typing), that gets garbled as 'fiel'."  The reason
842991
for that (but probably not for the original issue reported in that rhbz#1377293)
842991
apparently was:
842991
842991
Two GDK_KEY_PRESS events (A and B) were in the GTK event queue.
842991
GtkInstance::AnyInput consumed only A, because it broke from the first while
842991
loop as soon as it saw the first event of appropriate type.  In the second while
842991
loop it put A back on the end of the GTK event loop, so that it now followed B.
842991
GtkSalFrame::signalKey (vcl/unx/gtk3/gtk3gtkframe.cxx) thus received the events
842991
in the wrong order.
842991
842991
Dropping the "break" also reveals that GtkInstance::AnyInput should obviously
842991
use a queue (i.e., deque) rather than a stack to hold the events it consumed and
842991
needs to re-enqueue.
842991
842991
This appears to be a regression introduced with
842991
658954e8b50fc264428402dc5a95b0d6f690d191 "Resolves: fdo#48011 writer
842991
idle-callbacks are halting when events pending".
842991
842991
Change-Id: I87d601df118a20ea3dd59e9cebbcf5176db04be8
842991
---
842991
 vcl/unx/gtk/gtkinst.cxx | 9 ++++-----
842991
 1 file changed, 4 insertions(+), 5 deletions(-)
842991
842991
diff --git a/vcl/unx/gtk/gtkinst.cxx b/vcl/unx/gtk/gtkinst.cxx
842991
index 02ed688f366b..744c66b0baf0 100644
842991
--- a/vcl/unx/gtk/gtkinst.cxx
842991
+++ b/vcl/unx/gtk/gtkinst.cxx
842991
@@ -427,25 +427,24 @@ bool GtkInstance::AnyInput( VclInputFlags nType )
842991
         return true;
842991
 
842991
     bool bRet = false;
842991
-    std::stack<GdkEvent*> aEvents;
842991
+    std::deque<GdkEvent*> aEvents;
842991
     GdkEvent *pEvent = nullptr;
842991
     while ((pEvent = gdk_event_get()))
842991
     {
842991
-        aEvents.push(pEvent);
842991
+        aEvents.push_back(pEvent);
842991
         VclInputFlags nEventType = categorizeEvent(pEvent);
842991
         if ( (nEventType & nType) || ( nEventType == VclInputFlags::NONE && (nType & VclInputFlags::OTHER) ) )
842991
         {
842991
             bRet = true;
842991
-            break;
842991
         }
842991
     }
842991
 
842991
     while (!aEvents.empty())
842991
     {
842991
-        pEvent = aEvents.top();
842991
+        pEvent = aEvents.front();
842991
         gdk_event_put(pEvent);
842991
         gdk_event_free(pEvent);
842991
-        aEvents.pop();
842991
+        aEvents.pop_front();
842991
     }
842991
 #endif
842991
     return bRet;
842991
-- 
842991
2.25.4
842991