[gtk+/multitouch: 33/57] gtk: emit ::captured-event starting from the GTK grab widget



commit 24527d93a85a19677e071f6f77437a3dac47d516
Author: Carlos Garnacho <carlosg gnome org>
Date:   Mon Oct 24 10:59:23 2011 +0200

    gtk: emit ::captured-event starting from the GTK grab widget

 gtk/gtkmain.c |   44 +++++++++++++++++++++++++++++++++-----------
 1 files changed, 33 insertions(+), 11 deletions(-)
---
diff --git a/gtk/gtkmain.c b/gtk/gtkmain.c
index 26fb042..3a399c3 100644
--- a/gtk/gtkmain.c
+++ b/gtk/gtkmain.c
@@ -130,7 +130,8 @@
 #include "gtkwindowprivate.h"
 
 static gboolean gtk_propagate_captured_event (GtkWidget *widget,
-                                              GdkEvent  *event);
+                                              GdkEvent  *event,
+                                              GtkWidget *topmost);
 
 /* Private type definitions
  */
@@ -1471,6 +1472,7 @@ gtk_main_do_event (GdkEvent *event)
 {
   GtkWidget *event_widget;
   GtkWidget *grab_widget = NULL;
+  GtkWidget *topmost_widget = NULL;
   GtkWindowGroup *window_group;
   GdkEvent *rewritten_event = NULL;
   GdkDevice *device;
@@ -1530,6 +1532,14 @@ gtk_main_do_event (GdkEvent *event)
   if (!grab_widget)
     grab_widget = gtk_window_group_get_current_grab (window_group);
 
+  /* Find out the topmost widget where captured event propagation
+   * should start, which is the widget holding the GTK+ grab
+   * if any, otherwise it's left NULL and events are emitted
+   * from the toplevel (or topmost parentless parent).
+   */
+  if (grab_widget)
+    topmost_widget = grab_widget;
+
   /* If the grab widget is an ancestor of the event widget
    * then we send the event to the original event widget.
    * This is the key to implementing modality.
@@ -1634,7 +1644,7 @@ gtk_main_do_event (GdkEvent *event)
     case GDK_BUTTON_PRESS:
     case GDK_2BUTTON_PRESS:
     case GDK_3BUTTON_PRESS:
-      if (!gtk_propagate_captured_event (grab_widget, event))
+      if (!gtk_propagate_captured_event (grab_widget, event, topmost_widget))
         gtk_propagate_event (grab_widget, event);
       break;
 
@@ -1693,7 +1703,7 @@ gtk_main_do_event (GdkEvent *event)
     case GDK_MULTITOUCH_ADDED:
     case GDK_MULTITOUCH_REMOVED:
     case GDK_MULTITOUCH_UPDATED:
-      if (!gtk_propagate_captured_event (grab_widget, event))
+      if (!gtk_propagate_captured_event (grab_widget, event, topmost_widget))
         gtk_propagate_event (grab_widget, event);
       break;
 
@@ -2346,7 +2356,8 @@ gtk_get_event_widget (GdkEvent *event)
 
 static gboolean
 propagate_event_up (GtkWidget *widget,
-                    GdkEvent  *event)
+                    GdkEvent  *event,
+                    GtkWidget *topmost)
 {
   gboolean handled_event = FALSE;
 
@@ -2373,6 +2384,9 @@ propagate_event_up (GtkWidget *widget,
       tmp = gtk_widget_get_parent (widget);
       g_object_unref (widget);
 
+      if (widget == topmost)
+        break;
+
       widget = tmp;
 
       if (handled_event || !widget)
@@ -2384,20 +2398,24 @@ propagate_event_up (GtkWidget *widget,
 
 static gboolean
 propagate_event_down (GtkWidget *widget,
-                      GdkEvent  *event)
+                      GdkEvent  *event,
+                      GtkWidget *topmost)
 {
   gint handled_event = FALSE;
   GList *widgets = NULL;
   GList *l;
 
   widgets = g_list_prepend (widgets, g_object_ref (widget));
-  while (TRUE)
+  while (widget && widget != topmost)
     {
       widget = gtk_widget_get_parent (widget);
       if (!widget)
         break;
 
       widgets = g_list_prepend (widgets, g_object_ref (widget));
+
+      if (widget == topmost)
+        break;
     }
 
   for (l = widgets; l && !handled_event; l = g_list_next (l))
@@ -2417,7 +2435,8 @@ propagate_event_down (GtkWidget *widget,
 static gboolean
 propagate_event (GtkWidget *widget,
                  GdkEvent  *event,
-                 gboolean   captured)
+                 gboolean   captured,
+                 GtkWidget *topmost)
 {
   gboolean handled_event = FALSE;
   gboolean (* propagate_func) (GtkWidget *widget, GdkEvent  *event);
@@ -2459,7 +2478,9 @@ propagate_event (GtkWidget *widget,
     }
 
   /* Other events get propagated up/down the widget tree */
-  return captured ? propagate_event_down (widget, event) : propagate_event_up (widget, event);
+  return captured ?
+    propagate_event_down (widget, event, topmost) :
+    propagate_event_up (widget, event, topmost);
 }
 
 /**
@@ -2493,12 +2514,13 @@ gtk_propagate_event (GtkWidget *widget,
   g_return_if_fail (GTK_IS_WIDGET (widget));
   g_return_if_fail (event != NULL);
 
-  propagate_event (widget, event, FALSE);
+  propagate_event (widget, event, FALSE, NULL);
 }
 
 static gboolean
 gtk_propagate_captured_event (GtkWidget *widget,
-                              GdkEvent  *event)
+                              GdkEvent  *event,
+                              GtkWidget *topmost)
 {
-  return propagate_event (widget, event, TRUE);
+  return propagate_event (widget, event, TRUE, topmost);
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]