From 140371064e9190efa7d8838d442e86967c3562ac Mon Sep 17 00:00:00 2001 From: Paul Cornett Date: Tue, 20 Mar 2012 03:34:18 +0000 Subject: [PATCH] Fix keyboard navigation broken in r70324, see #14084 Also fixes some other keyboard navigation problems, closes #2849 git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@70945 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/gtk/window.cpp | 48 ++++++++++++++++++++-------------------------- 1 file changed, 21 insertions(+), 27 deletions(-) diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index f5d1fbb070..b8734c412d 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -887,6 +887,17 @@ void AdjustCharEventKeyCodes(wxKeyEvent& event) } // anonymous namespace +// If a widget does not handle a key or mouse event, GTK+ sends it up the +// parent chain until it is handled. These events are not supposed to propagate +// in wxWidgets, so this code avoids handling them in any parent wxWindow, +// while still allowing the event to propagate so things like native keyboard +// navigation will work. +#define wxPROCESS_EVENT_ONCE(EventType, event) \ + static EventType eventPrev; \ + if (memcmp(&eventPrev, event, sizeof(EventType)) == 0) \ + return false; \ + eventPrev = *event + extern "C" { static gboolean gtk_window_key_press_callback( GtkWidget *WXUNUSED(widget), @@ -898,6 +909,8 @@ gtk_window_key_press_callback( GtkWidget *WXUNUSED(widget), if (g_blockEventsOnDrag) return FALSE; + wxPROCESS_EVENT_ONCE(GdkEventKey, gdk_event); + wxKeyEvent event( wxEVT_KEY_DOWN ); bool ret = false; bool return_after_IM = false; @@ -1069,6 +1082,8 @@ gtk_window_key_release_callback( GtkWidget * WXUNUSED(widget), if (g_blockEventsOnDrag) return FALSE; + wxPROCESS_EVENT_ONCE(GdkEventKey, gdk_event); + wxKeyEvent event( wxEVT_KEY_UP ); if ( !wxTranslateGTKKeyEventToWx(event, win, gdk_event) ) { @@ -1080,21 +1095,6 @@ gtk_window_key_release_callback( GtkWidget * WXUNUSED(widget), } } -//----------------------------------------------------------------------------- -// key and mouse events, after, from m_widget -//----------------------------------------------------------------------------- - -extern "C" { -static gboolean key_and_mouse_event_after(GtkWidget* widget, GdkEventKey*, wxWindow*) -{ - // If a widget does not handle a key or mouse event, GTK+ sends it up the - // parent chain until it is handled. These events are not supposed to - // propagate in wxWidgets, so prevent it unless widget is in a native - // container. - return WX_IS_PIZZA(gtk_widget_get_parent(widget)); -} -} - // ============================================================================ // the mouse events // ============================================================================ @@ -1279,6 +1279,8 @@ gtk_window_button_press_callback( GtkWidget *widget, GdkEventButton *gdk_event, wxWindowGTK *win ) { + wxPROCESS_EVENT_ONCE(GdkEventButton, gdk_event); + wxCOMMON_CALLBACK_PROLOGUE(gdk_event, win); g_lastButtonNumber = gdk_event->button; @@ -1476,6 +1478,8 @@ gtk_window_button_release_callback( GtkWidget *WXUNUSED(widget), GdkEventButton *gdk_event, wxWindowGTK *win ) { + wxPROCESS_EVENT_ONCE(GdkEventButton, gdk_event); + wxCOMMON_CALLBACK_PROLOGUE(gdk_event, win); g_lastButtonNumber = 0; @@ -1539,6 +1543,8 @@ gtk_window_motion_notify_callback( GtkWidget * WXUNUSED(widget), GdkEventMotion *gdk_event, wxWindowGTK *win ) { + wxPROCESS_EVENT_ONCE(GdkEventMotion, gdk_event); + wxCOMMON_CALLBACK_PROLOGUE(gdk_event, win); if (gdk_event->is_hint) @@ -2430,18 +2436,6 @@ void wxWindowGTK::PostCreation() ConnectWidget( connect_widget ); - // connect handler to prevent events from propagating up parent chain - g_signal_connect_after(m_widget, - "key_press_event", G_CALLBACK(key_and_mouse_event_after), this); - g_signal_connect_after(m_widget, - "key_release_event", G_CALLBACK(key_and_mouse_event_after), this); - g_signal_connect_after(m_widget, - "button_press_event", G_CALLBACK(key_and_mouse_event_after), this); - g_signal_connect_after(m_widget, - "button_release_event", G_CALLBACK(key_and_mouse_event_after), this); - g_signal_connect_after(m_widget, - "motion_notify_event", G_CALLBACK(key_and_mouse_event_after), this); - // We cannot set colours, fonts and cursors before the widget has been // realized, so we do this directly after realization -- unless the widget // was in fact realized already. -- 2.47.2