summaryrefslogtreecommitdiff
path: root/gtk/gtkwidget.c
diff options
context:
space:
mode:
Diffstat (limited to 'gtk/gtkwidget.c')
-rw-r--r--gtk/gtkwidget.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index c7406fc882..23ab0d8e62 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -706,6 +706,7 @@ static void gtk_widget_set_device_enabled_internal (GtkWidget *widget,
GdkDevice *device,
gboolean recurse,
gboolean enabled);
+static gboolean event_window_is_still_viewable (GdkEvent *event);
/* --- variables --- */
static gpointer gtk_widget_parent_class = NULL;
@@ -5951,6 +5952,59 @@ gtk_widget_event (GtkWidget *widget,
return gtk_widget_event_internal (widget, event);
}
+void
+_gtk_widget_set_captured_event_handler (GtkWidget *widget,
+ GtkCapturedEventHandler callback)
+{
+ g_object_set_data (G_OBJECT (widget), "captured-event-handler", callback);
+}
+
+gboolean
+_gtk_widget_captured_event (GtkWidget *widget,
+ GdkEvent *event)
+{
+ gboolean return_val = FALSE;
+ GtkCapturedEventHandler handler;
+
+ g_return_val_if_fail (GTK_IS_WIDGET (widget), TRUE);
+ g_return_val_if_fail (WIDGET_REALIZED_FOR_EVENT (widget, event), TRUE);
+
+ if (event->type == GDK_EXPOSE)
+ {
+ g_warning ("Events of type GDK_EXPOSE cannot be synthesized. To get "
+ "the same effect, call gdk_window_invalidate_rect/region(), "
+ "followed by gdk_window_process_updates().");
+ return TRUE;
+ }
+
+ if (!event_window_is_still_viewable (event))
+ return TRUE;
+
+ handler = g_object_get_data (G_OBJECT (widget), "captured-event-handler");
+ if (!handler)
+ return FALSE;
+
+ g_object_ref (widget);
+
+ return_val = handler (widget, event);
+ return_val |= !WIDGET_REALIZED_FOR_EVENT (widget, event);
+
+ /* The widget that was originally to receive the event
+ * handles motion hints, but the capturing widget might
+ * not, so ensure we get further motion events.
+ */
+ if (return_val &&
+ event->type == GDK_MOTION_NOTIFY &&
+ event->motion.is_hint &&
+ (gdk_window_get_events (event->any.window) &
+ GDK_POINTER_MOTION_HINT_MASK) != 0)
+ gdk_event_request_motions (&event->motion);
+
+ g_object_unref (widget);
+
+ return return_val;
+}
+
/* Returns TRUE if a translation should be done */
gboolean
_gtk_widget_get_translation_to_window (GtkWidget *widget,