From 278e5bd1707601a75273737b49ecdbcd452ff42e Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Thu, 11 Jun 2009 21:49:17 +0200 Subject: [PATCH] Send crossing event due to geometry change in idle Doing this directly had some issues with picking going recursive in clutter-gtk. Furthermore, doing it in an idle means we can coalesce multiple calls (which is common due to widget changes) in the same toplevel to just one call. --- gdk/gdkinternals.h | 1 + gdk/gdkwindow.c | 39 +++++++++++++++++++++++++++++++++++---- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/gdk/gdkinternals.h b/gdk/gdkinternals.h index b6da9bb1dd..cb140068c9 100644 --- a/gdk/gdkinternals.h +++ b/gdk/gdkinternals.h @@ -256,6 +256,7 @@ struct _GdkWindowObject GdkRegion *clip_region_with_children; /* Clip region in window coords */ GdkCursor *cursor; gint8 toplevel_window_type; + guint synthesize_crossing_event_queued : 1; guint effective_visibility : 2; guint visibility : 2; /* The visibility wrt the toplevel (i.e. based on clip_region) */ guint native_visibility : 2; /* the native visibility of a impl windows */ diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c index fae8bbbb2d..7c5011218a 100644 --- a/gdk/gdkwindow.c +++ b/gdk/gdkwindow.c @@ -8691,18 +8691,22 @@ gdk_window_offscreen_children_changed (GdkWindow *window) _gdk_syntesize_crossing_events_for_geometry_change (window); } -void -_gdk_syntesize_crossing_events_for_geometry_change (GdkWindow *changed_window) +static gboolean +do_synthesize_crossing_event (gpointer data) { GdkDisplay *display; GdkWindow *changed_toplevel; + GdkWindowObject *changed_toplevel_priv; GdkWindow *new_window_under_pointer; gulong serial; - display = gdk_drawable_get_display (changed_window); + changed_toplevel = data; + changed_toplevel_priv = (GdkWindowObject *)changed_toplevel; + display = gdk_drawable_get_display (changed_toplevel); serial = _gdk_windowing_window_get_next_serial (display); - changed_toplevel = get_event_toplevel (changed_window); + + changed_toplevel_priv->synthesize_crossing_event_queued = FALSE; if (changed_toplevel == display->pointer_info.toplevel_under_pointer) { @@ -8727,6 +8731,33 @@ _gdk_syntesize_crossing_events_for_geometry_change (GdkWindow *changed_window) _gdk_display_set_window_under_pointer (display, new_window_under_pointer); } } + + return FALSE; +} + +void +_gdk_syntesize_crossing_events_for_geometry_change (GdkWindow *changed_window) +{ + GdkDisplay *display; + GdkWindow *toplevel; + GdkWindowObject *toplevel_priv; + GdkWindow *new_window_under_pointer; + gulong serial; + + display = gdk_drawable_get_display (changed_window); + + toplevel = get_event_toplevel (changed_window); + toplevel_priv = (GdkWindowObject *)toplevel; + + if (toplevel == display->pointer_info.toplevel_under_pointer && + !toplevel_priv->synthesize_crossing_event_queued) + { + toplevel_priv->synthesize_crossing_event_queued = TRUE; + g_idle_add_full (GDK_PRIORITY_EVENTS - 1, + do_synthesize_crossing_event, + g_object_ref (toplevel), + g_object_unref); + } } /* Don't use for crossing events */