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