]> git.saurik.com Git - wxWidgets.git/commitdiff
Fix keyboard navigation broken in r70324, see #14084
authorPaul Cornett <paulcor@bullseye.com>
Tue, 20 Mar 2012 03:34:18 +0000 (03:34 +0000)
committerPaul Cornett <paulcor@bullseye.com>
Tue, 20 Mar 2012 03:34:18 +0000 (03:34 +0000)
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

index f5d1fbb070bc4e7c121ecb6b548f389d1dae978d..b8734c412dbd081c5baaae3f597d9f8805d0eaa2 100644 (file)
@@ -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.