Track pointer grabs on Xserver time
After a successful grab/ungrab we wait for an xserver roundtrip until we change the tracked grab in GdkDisplay. This way that data is always up-to-date wrt events comming in.
This commit is contained in:
committed by
Alexander Larsson
parent
d2c1c0a8db
commit
016c5fd081
@ -31,6 +31,7 @@
|
|||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include "gdkx.h"
|
#include "gdkx.h"
|
||||||
|
#include "gdkasync.h"
|
||||||
#include "gdkdisplay.h"
|
#include "gdkdisplay.h"
|
||||||
#include "gdkdisplay-x11.h"
|
#include "gdkdisplay-x11.h"
|
||||||
#include "gdkscreen.h"
|
#include "gdkscreen.h"
|
||||||
@ -591,6 +592,25 @@ _gdk_x11_display_is_root_window (GdkDisplay *display,
|
|||||||
return FALSE;
|
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) \
|
#define XSERVER_TIME_IS_LATER(time1, time2) \
|
||||||
( (( time1 > time2 ) && ( time1 - time2 < ((guint32)-1)/2 )) || \
|
( (( time1 > time2 ) && ( time1 - time2 < ((guint32)-1)/2 )) || \
|
||||||
(( time1 < time2 ) && ( time2 - time1 > ((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 ||
|
display->pointer_grab.time == GDK_CURRENT_TIME ||
|
||||||
!XSERVER_TIME_IS_LATER (display->pointer_grab.time, time_))
|
!XSERVER_TIME_IS_LATER (display->pointer_grab.time, time_))
|
||||||
{
|
{
|
||||||
_gdk_display_unset_has_pointer_grab (display,
|
struct XPointerUngrabInfo *data;
|
||||||
FALSE,
|
|
||||||
FALSE,
|
data = g_new (struct XPointerUngrabInfo, 1);
|
||||||
time_);
|
|
||||||
|
data->display = GDK_DISPLAY_OBJECT (display_x11);
|
||||||
|
data->time = time_;
|
||||||
|
|
||||||
|
_gdk_x11_roundtrip_async (data->display,
|
||||||
|
pointer_ungrab_callback,
|
||||||
|
data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -44,6 +44,7 @@
|
|||||||
#include "gdk.h"
|
#include "gdk.h"
|
||||||
|
|
||||||
#include "gdkx.h"
|
#include "gdkx.h"
|
||||||
|
#include "gdkasync.h"
|
||||||
#include "gdkdisplay-x11.h"
|
#include "gdkdisplay-x11.h"
|
||||||
#include "gdkinternals.h"
|
#include "gdkinternals.h"
|
||||||
#include "gdkintl.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
|
* gdk_pointer_grab
|
||||||
@ -276,14 +304,21 @@ gdk_pointer_grab (GdkWindow * window,
|
|||||||
|
|
||||||
if (return_val == GrabSuccess)
|
if (return_val == GrabSuccess)
|
||||||
{
|
{
|
||||||
_gdk_display_set_has_pointer_grab (GDK_DISPLAY_OBJECT (display_x11),
|
struct XPointerGrabInfo *data;
|
||||||
window,
|
|
||||||
native,
|
data = g_new (struct XPointerGrabInfo, 1);
|
||||||
owner_events,
|
|
||||||
event_mask,
|
data->display = GDK_DISPLAY_OBJECT (display_x11);
|
||||||
serial,
|
data->window = window;
|
||||||
time,
|
data->native_window = native;
|
||||||
FALSE);
|
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);
|
return gdk_x11_convert_grab_status (return_val);
|
||||||
|
|||||||
Reference in New Issue
Block a user