diff options
author | Carlos Garnacho <carlosg@gnome.org> | 2012-02-18 17:29:13 +0100 |
---|---|---|
committer | Carlos Garnacho <carlosg@gnome.org> | 2012-02-18 18:05:00 +0100 |
commit | a3283138856d126aafbe9a93f45e0783495b8b8f (patch) | |
tree | 44fd5d166e5c88fb784efbeeadcee075f1efd644 | |
parent | 8528385c80a3daac9f8b3f1a798c23df7db0466d (diff) | |
download | gtk+-a3283138856d126aafbe9a93f45e0783495b8b8f.tar.gz |
gtk: Release captured events down the hierarchy
Instead of releasing directly onto the target widget,
release down the hierarchy as if uncaptured.
-rw-r--r-- | gtk/gtkmain.c | 20 | ||||
-rw-r--r-- | gtk/gtkprivate.h | 4 | ||||
-rw-r--r-- | gtk/gtkwidget.c | 40 |
3 files changed, 50 insertions, 14 deletions
diff --git a/gtk/gtkmain.c b/gtk/gtkmain.c index 39cefd1e88..2264986f58 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 957176fec2..2ab7ad4e6b 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 7b10a06613..c557d532d0 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: |