diff --git a/gdk/x11/gdkdisplay-x11.c b/gdk/x11/gdkdisplay-x11.c index a7f57aa61d..a05bc511ce 100644 --- a/gdk/x11/gdkdisplay-x11.c +++ b/gdk/x11/gdkdisplay-x11.c @@ -31,6 +31,7 @@ #include #include "gdkx.h" +#include "gdkasync.h" #include "gdkdisplay.h" #include "gdkdisplay-x11.h" #include "gdkscreen.h" @@ -591,6 +592,25 @@ _gdk_x11_display_is_root_window (GdkDisplay *display, return FALSE; } +struct XPointerUngrabInfo { + GdkDisplay *display; + guint32 time; +}; + +static void +pointer_ungrab_callback (gpointer _data) +{ + struct XPointerUngrabInfo *data = _data; + + _gdk_display_unset_has_pointer_grab (data->display, + FALSE, + FALSE, + data->time); + + g_free (data); +} + + #define XSERVER_TIME_IS_LATER(time1, time2) \ ( (( time1 > time2 ) && ( time1 - time2 < ((guint32)-1)/2 )) || \ (( time1 < time2 ) && ( time2 - time1 > ((guint32)-1)/2 )) \ @@ -625,10 +645,16 @@ gdk_display_pointer_ungrab (GdkDisplay *display, display->pointer_grab.time == GDK_CURRENT_TIME || !XSERVER_TIME_IS_LATER (display->pointer_grab.time, time_)) { - _gdk_display_unset_has_pointer_grab (display, - FALSE, - FALSE, - time_); + struct XPointerUngrabInfo *data; + + data = g_new (struct XPointerUngrabInfo, 1); + + data->display = GDK_DISPLAY_OBJECT (display_x11); + data->time = time_; + + _gdk_x11_roundtrip_async (data->display, + pointer_ungrab_callback, + data); } } diff --git a/gdk/x11/gdkmain-x11.c b/gdk/x11/gdkmain-x11.c index e17abc52f0..bfe2117054 100644 --- a/gdk/x11/gdkmain-x11.c +++ b/gdk/x11/gdkmain-x11.c @@ -44,6 +44,7 @@ #include "gdk.h" #include "gdkx.h" +#include "gdkasync.h" #include "gdkdisplay-x11.h" #include "gdkinternals.h" #include "gdkintl.h" @@ -158,6 +159,33 @@ generate_grab_broken_event (GdkWindow *window, } } +struct XPointerGrabInfo { + GdkDisplay *display; + GdkWindow *window; + GdkWindow *native_window; + gboolean owner_events; + gulong serial; + guint event_mask; + guint32 time; +}; + +static void +has_pointer_grab_callback (gpointer _data) +{ + struct XPointerGrabInfo *data = _data; + + _gdk_display_set_has_pointer_grab (data->display, + data->window, + data->native_window, + data->owner_events, + data->event_mask, + data->serial, + data->time, + FALSE); + + g_free (data); +} + /* *-------------------------------------------------------------- * gdk_pointer_grab @@ -276,14 +304,21 @@ gdk_pointer_grab (GdkWindow * window, if (return_val == GrabSuccess) { - _gdk_display_set_has_pointer_grab (GDK_DISPLAY_OBJECT (display_x11), - window, - native, - owner_events, - event_mask, - serial, - time, - FALSE); + struct XPointerGrabInfo *data; + + data = g_new (struct XPointerGrabInfo, 1); + + data->display = GDK_DISPLAY_OBJECT (display_x11); + data->window = window; + data->native_window = native; + data->owner_events = owner_events; + data->event_mask = event_mask; + data->serial = serial; + data->time = time; + + _gdk_x11_roundtrip_async (data->display, + has_pointer_grab_callback, + data); } return gdk_x11_convert_grab_status (return_val);