From b6f7b079c62415d799ec865dc86ef45d79f0de12 Mon Sep 17 00:00:00 2001 From: Paul Cornett Date: Fri, 15 Aug 2014 17:09:39 +0000 Subject: [PATCH] Fix handling of identical consecutive key events Events generated programmatically may have the same timestamp as the previous event, which caused them to be ignored on the assumption that they were the same event being sent to a parent window. Fix this by detecting when a new event could be generated by the event loop. Closes #15802 git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_3_0_BRANCH@77074 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/gtk/window.cpp | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index ff9cf46aad..62c69a9490 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -929,10 +929,13 @@ void AdjustCharEventKeyCodes(wxKeyEvent& event) // navigation will work. #define wxPROCESS_EVENT_ONCE(EventType, event) \ static EventType eventPrev; \ - if (memcmp(&eventPrev, event, sizeof(EventType)) == 0) \ + if (!gs_isNewEvent && memcmp(&eventPrev, event, sizeof(EventType)) == 0) \ return false; \ + gs_isNewEvent = false; \ eventPrev = *event +static bool gs_isNewEvent; + extern "C" { static gboolean gtk_window_key_press_callback( GtkWidget *WXUNUSED(widget), @@ -2694,8 +2697,44 @@ wxWindowGTK::GTKConnectWidget(const char *signal, wxGTKCallback callback) return g_signal_connect(m_widget, signal, callback, this); } +// GSource callback functions for source used to detect new GDK events +extern "C" { +static gboolean source_prepare(GSource*, int*) +{ + return !gs_isNewEvent; +} + +static gboolean source_check(GSource*) +{ + // 'check' will only be called if 'prepare' returned false + return false; +} + +static gboolean source_dispatch(GSource*, GSourceFunc, void*) +{ + gs_isNewEvent = true; + // don't remove this source + return true; +} +} + void wxWindowGTK::ConnectWidget( GtkWidget *widget ) { + static bool isSourceAttached; + if (!isSourceAttached) + { + // attach GSource to detect new GDK events + isSourceAttached = true; + static GSourceFuncs funcs = { + source_prepare, source_check, source_dispatch, + NULL, NULL, NULL + }; + GSource* source = g_source_new(&funcs, sizeof(GSource)); + // priority slightly higher than GDK_PRIORITY_EVENTS + g_source_set_priority(source, GDK_PRIORITY_EVENTS - 1); + g_source_attach(source, NULL); + } + g_signal_connect (widget, "key_press_event", G_CALLBACK (gtk_window_key_press_callback), this); g_signal_connect (widget, "key_release_event",