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

This commit is contained in:
Carlos Garnacho
2011-10-24 10:59:23 +02:00
parent a404a56254
commit 4f2ce2f7b6

View File

@@ -133,7 +133,8 @@
#include "a11y/gailutil.h"
static gboolean gtk_propagate_captured_event (GtkWidget *widget,
GdkEvent *event);
GdkEvent *event,
GtkWidget *topmost);
/* Private type definitions
*/
@@ -1476,6 +1477,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;
@@ -1535,6 +1537,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.
@@ -1639,7 +1649,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;
@@ -1689,7 +1699,7 @@ gtk_main_do_event (GdkEvent *event)
case GDK_BUTTON_RELEASE:
case GDK_PROXIMITY_IN:
case GDK_PROXIMITY_OUT:
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;
@@ -2339,7 +2349,8 @@ gtk_get_event_widget (GdkEvent *event)
static gboolean
propagate_event_up (GtkWidget *widget,
GdkEvent *event)
GdkEvent *event,
GtkWidget *topmost)
{
gboolean handled_event = FALSE;
@@ -2366,6 +2377,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)
@@ -2377,20 +2391,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))
@@ -2410,7 +2428,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);
@@ -2452,7 +2471,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);
}
/**
@@ -2486,12 +2507,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);
}