[gtk+/multitouch: 127/129] gtk: Release captured events down the hierarchy



commit a3283138856d126aafbe9a93f45e0783495b8b8f
Author: Carlos Garnacho <carlosg gnome org>
Date:   Sat Feb 18 17:29:13 2012 +0100

    gtk: Release captured events down the hierarchy
    
    Instead of releasing directly onto the target widget,
    release down the hierarchy as if uncaptured.

 gtk/gtkmain.c    |   20 ++++++++------------
 gtk/gtkprivate.h |    4 ++++
 gtk/gtkwidget.c  |   40 ++++++++++++++++++++++++++++++++++++++--
 3 files changed, 50 insertions(+), 14 deletions(-)
---
diff --git a/gtk/gtkmain.c b/gtk/gtkmain.c
index 39cefd1..2264986 100644
--- a/gtk/gtkmain.c
+++ b/gtk/gtkmain.c
@@ -132,10 +132,6 @@
 
 #include "a11y/gailutil.h"
 
-static gboolean gtk_propagate_captured_event (GtkWidget *widget,
-                                              GdkEvent  *event,
-                                              GtkWidget *topmost);
-
 /* Private type definitions
  */
 typedef struct _GtkKeySnooperData        GtkKeySnooperData;
@@ -1667,7 +1663,7 @@ gtk_main_do_event (GdkEvent *event)
           _gtk_widget_press_and_hold_check_start (grab_widget, &event->button);
         }
 
-      if (!gtk_propagate_captured_event (grab_widget, event, topmost_widget))
+      if (!_gtk_propagate_captured_event (grab_widget, event, topmost_widget))
         gtk_propagate_event (grab_widget, event);
       break;
 
@@ -1731,7 +1727,7 @@ gtk_main_do_event (GdkEvent *event)
         _gtk_widget_press_and_hold_check_threshold (grab_widget,
                                                     &event->motion);
 
-      if (!gtk_propagate_captured_event (grab_widget, event, topmost_widget))
+      if (!_gtk_propagate_captured_event (grab_widget, event, topmost_widget))
         gtk_propagate_event (grab_widget, event);
       break;
 
@@ -1742,7 +1738,7 @@ gtk_main_do_event (GdkEvent *event)
                                        gdk_event_get_device (event),
                                        event->any.window);
       if (gtk_widget_is_sensitive (grab_widget) &&
-	  !gtk_propagate_captured_event (grab_widget, event, topmost_widget))
+	  !_gtk_propagate_captured_event (grab_widget, event, topmost_widget))
         gtk_widget_event (grab_widget, event);
       break;
 
@@ -1753,7 +1749,7 @@ gtk_main_do_event (GdkEvent *event)
                                        gdk_event_get_device (event),
                                        NULL);
       if (gtk_widget_is_sensitive (grab_widget) &&
-          !gtk_propagate_captured_event (grab_widget, event, topmost_widget))
+          !_gtk_propagate_captured_event (grab_widget, event, topmost_widget))
         gtk_widget_event (grab_widget, event);
       break;
 
@@ -2557,10 +2553,10 @@ gtk_propagate_event (GtkWidget *widget,
   propagate_event (widget, event, FALSE, NULL);
 }
 
-static gboolean
-gtk_propagate_captured_event (GtkWidget *widget,
-                              GdkEvent  *event,
-                              GtkWidget *topmost)
+gboolean
+_gtk_propagate_captured_event (GtkWidget *widget,
+                               GdkEvent  *event,
+                               GtkWidget *topmost)
 {
   return propagate_event (widget, event, TRUE, topmost);
 }
diff --git a/gtk/gtkprivate.h b/gtk/gtkprivate.h
index 957176f..2ab7ad4 100644
--- a/gtk/gtkprivate.h
+++ b/gtk/gtkprivate.h
@@ -78,6 +78,10 @@ gboolean _gtk_translate_keyboard_accel_state   (GdkKeymap       *keymap,
                                                 gint            *level,
                                                 GdkModifierType *consumed_modifiers);
 
+gboolean        _gtk_propagate_captured_event  (GtkWidget       *widget,
+                                                GdkEvent        *event,
+                                                GtkWidget       *topmost);
+
 G_END_DECLS
 
 #endif /* __GTK_PRIVATE_H__ */
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 7b10a06..c557d53 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -14574,8 +14574,9 @@ _gtk_widget_set_style (GtkWidget *widget,
  *
  * Releases the events that a widget has captured and stored
  * in the #GtkWidget::captured-event signal. if @emit is #TRUE,
- * the events will be emitted on the target widget (the widget
- * that would receive the event if no signal capturing happened)
+ * event emission will continue as if uncaptured (i.e. the
+ * capturing phase will continue down the hierarchy to the event
+ * widget, followed by the event being propagated up again).
  *
  * Since: 3.4
  **/
@@ -14598,9 +14599,44 @@ gtk_widget_release_captured_events (GtkWidget *widget,
         {
           GtkWidget *event_widget;
           GdkEvent *event = l->data;
+          gboolean propagated = FALSE;
 
           event_widget = gtk_get_event_widget (event);
 
+          /* Find out the next widget handling the captured event,
+           * if event_widget == widget, the capturing phase for
+           * this event has finished, so the next thing is bubbling
+           * it up.
+           */
+          if (event_widget != widget &&
+              gtk_widget_is_ancestor (event_widget, widget))
+            {
+              GtkWidget *parent, *intermediate;
+
+              intermediate = event_widget;
+
+              while (intermediate)
+                {
+                  parent = gtk_widget_get_parent (intermediate);
+
+                  /* Found the next intermediate that should handle
+                   * the captured event.
+                   */
+                  if (parent == widget)
+                    break;
+
+                  intermediate = parent;
+                }
+
+              if (intermediate)
+                propagated = _gtk_propagate_captured_event (event_widget,
+                                                            event,
+                                                            intermediate);
+            }
+
+          if (propagated)
+            continue;
+
           switch (event->type)
             {
             case GDK_PROPERTY_NOTIFY:



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