]> git.saurik.com Git - wxWidgets.git/commitdiff
Don't reuse the same event object for multiple events in wxGTK.
authorVadim Zeitlin <vadim@wxwidgets.org>
Sun, 18 Jul 2010 11:53:04 +0000 (11:53 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sun, 18 Jul 2010 11:53:04 +0000 (11:53 +0000)
The old code simply called SetEventType() to change the type of the event and
called HandleWindowEvent() again with it. This was incorrect as the event was
modified after being processed the first time, notably its WasProcessed() flag
was set and so wxApp::FilterEvent() wasn't called when it was being processed
the second time. In practice this meant that FilterEvent() was never called
for wxEVT_CHAR events -- for which it's nevertheless very useful to have as it
allows to implement application-wide keyboard processing.

Also refactor the code to avoid duplication, exactly the same event sending
code was used in gtk_window_key_press_callback() and gtk_wxwindow_commit_cb().
Extract it now in a private SendCharHookAndCharEvents() function.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@65005 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

src/gtk/window.cpp

index 209f7be8199b849cc28eaabd1f9389e324fbd67e..eb4d2df8cd2fab92486794d3225a6edbff796de1 100644 (file)
@@ -822,6 +822,37 @@ struct wxGtkIMData
     }
 };
 
     }
 };
 
+namespace
+{
+
+// Send wxEVT_CHAR_HOOK event to the parent of the window and if it wasn't
+// processed, send wxEVT_CHAR to the window itself. Return true if either of
+// them was handled.
+bool
+SendCharHookAndCharEvents(const wxKeyEvent& event, wxWindow *win)
+{
+    // wxEVT_CHAR_HOOK must be sent to the top level parent window to allow it
+    // to handle key events in all of its children.
+    wxWindow * const parent = wxGetTopLevelParent(win);
+    if ( parent )
+    {
+        // We need to make a copy of the event object because it is
+        // modified while it's handled, notably its WasProcessed() flag
+        // is set after it had been processed once.
+        wxKeyEvent eventCharHook(event);
+        eventCharHook.SetEventType(wxEVT_CHAR_HOOK);
+        if ( parent->HandleWindowEvent(eventCharHook) )
+            return true;
+    }
+
+    // As above, make a copy of the event first.
+    wxKeyEvent eventChar(event);
+    eventChar.SetEventType(wxEVT_CHAR);
+    return win->HandleWindowEvent(eventChar);
+}
+
+} // anonymous namespace
+
 extern "C" {
 static gboolean
 gtk_window_key_press_callback( GtkWidget *WXUNUSED(widget),
 extern "C" {
 static gboolean
 gtk_window_key_press_callback( GtkWidget *WXUNUSED(widget),
@@ -938,21 +969,7 @@ gtk_window_key_press_callback( GtkWidget *WXUNUSED(widget),
 #endif
             }
 
 #endif
             }
 
-            // Implement OnCharHook by checking ancestor top level windows
-            wxWindow *parent = win;
-            while (parent && !parent->IsTopLevel())
-                parent = parent->GetParent();
-            if (parent)
-            {
-                event.SetEventType( wxEVT_CHAR_HOOK );
-                ret = parent->HandleWindowEvent( event );
-            }
-
-            if (!ret)
-            {
-                event.SetEventType(wxEVT_CHAR);
-                ret = win->HandleWindowEvent( event );
-            }
+            ret = SendCharHookAndCharEvents(event, win);
         }
     }
 
         }
     }
 
@@ -984,13 +1001,6 @@ gtk_wxwindow_commit_cb (GtkIMContext * WXUNUSED(context),
     if( data.empty() )
         return;
 
     if( data.empty() )
         return;
 
-    bool ret = false;
-
-    // Implement OnCharHook by checking ancestor top level windows
-    wxWindow *parent = window;
-    while (parent && !parent->IsTopLevel())
-        parent = parent->GetParent();
-
     for( wxString::const_iterator pstr = data.begin(); pstr != data.end(); ++pstr )
     {
 #if wxUSE_UNICODE
     for( wxString::const_iterator pstr = data.begin(); pstr != data.end(); ++pstr )
     {
 #if wxUSE_UNICODE
@@ -1018,17 +1028,7 @@ gtk_wxwindow_commit_cb (GtkIMContext * WXUNUSED(context),
 #endif
         }
 
 #endif
         }
 
-        if (parent)
-        {
-            event.SetEventType( wxEVT_CHAR_HOOK );
-            ret = parent->HandleWindowEvent( event );
-        }
-
-        if (!ret)
-        {
-            event.SetEventType(wxEVT_CHAR);
-            ret = window->HandleWindowEvent( event );
-        }
+        SendCharHookAndCharEvents(event, window);
     }
 }
 }
     }
 }
 }