summaryrefslogtreecommitdiff
path: root/src/backends/x11/meta-backend-x11.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backends/x11/meta-backend-x11.c')
-rw-r--r--src/backends/x11/meta-backend-x11.c71
1 files changed, 58 insertions, 13 deletions
diff --git a/src/backends/x11/meta-backend-x11.c b/src/backends/x11/meta-backend-x11.c
index f01fa9ffd..8e95a5a5d 100644
--- a/src/backends/x11/meta-backend-x11.c
+++ b/src/backends/x11/meta-backend-x11.c
@@ -60,6 +60,10 @@ struct _MetaBackendX11Private
XSyncAlarm user_active_alarm;
XSyncCounter counter;
+ int current_touch_replay_sync_serial;
+ int pending_touch_replay_sync_serial;
+ Atom touch_replay_sync_atom;
+
int xinput_opcode;
int xinput_event_base;
int xinput_error_base;
@@ -169,6 +173,26 @@ meta_backend_x11_translate_device_event (MetaBackendX11 *x11,
}
static void
+maybe_translate_touch_replay_pointer_event (MetaBackendX11 *x11,
+ XIDeviceEvent *device_event)
+{
+ MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
+
+ if (!device_event->send_event &&
+ device_event->time != META_CURRENT_TIME &&
+ priv->current_touch_replay_sync_serial !=
+ priv->pending_touch_replay_sync_serial &&
+ XSERVER_TIME_IS_BEFORE (device_event->time, priv->latest_evtime))
+ {
+ /* Emulated pointer events received after XIRejectTouch is received
+ * on a passive touch grab will contain older timestamps, update those
+ * so we dont get InvalidTime at grabs.
+ */
+ device_event->time = priv->latest_evtime;
+ }
+}
+
+static void
translate_device_event (MetaBackendX11 *x11,
XIDeviceEvent *device_event)
{
@@ -177,19 +201,7 @@ translate_device_event (MetaBackendX11 *x11,
meta_backend_x11_translate_device_event (x11, device_event);
if (!device_event->send_event && device_event->time != META_CURRENT_TIME)
- {
- if (XSERVER_TIME_IS_BEFORE (device_event->time, priv->latest_evtime))
- {
- /* Emulated pointer events received after XIRejectTouch is received
- * on a passive touch grab will contain older timestamps, update those
- * so we dont get InvalidTime at grabs.
- */
- device_event->time = priv->latest_evtime;
- }
-
- /* Update the internal latest evtime, for any possible later use */
- priv->latest_evtime = device_event->time;
- }
+ priv->latest_evtime = device_event->time;
}
static void
@@ -254,6 +266,9 @@ maybe_spoof_event_as_stage_event (MetaBackendX11 *x11,
case XI_Motion:
case XI_ButtonPress:
case XI_ButtonRelease:
+ maybe_translate_touch_replay_pointer_event (x11,
+ (XIDeviceEvent *) input_event);
+ /* Intentional fall-through */
case XI_KeyPress:
case XI_KeyRelease:
case XI_TouchBegin:
@@ -321,6 +336,17 @@ handle_host_xevent (MetaBackend *backend,
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
gboolean bypass_clutter = FALSE;
+ switch (event->type)
+ {
+ case ClientMessage:
+ if (event->xclient.window == meta_backend_x11_get_xwindow (x11) &&
+ event->xclient.message_type == priv->touch_replay_sync_atom)
+ priv->current_touch_replay_sync_serial = event->xclient.data.l[0];
+ break;
+ default:
+ break;
+ }
+
XGetEventData (priv->xdisplay, &event->xcookie);
{
@@ -528,6 +554,10 @@ meta_backend_x11_post_init (MetaBackend *backend)
monitor_manager = meta_backend_get_monitor_manager (backend);
g_signal_connect (monitor_manager, "monitors-changed-internal",
G_CALLBACK (on_monitors_changed), backend);
+
+ priv->touch_replay_sync_atom = XInternAtom (priv->xdisplay,
+ "_MUTTER_TOUCH_SEQUENCE_SYNC",
+ False);
}
static ClutterBackend *
@@ -604,6 +634,21 @@ meta_backend_x11_finish_touch_sequence (MetaBackend *backend,
META_VIRTUAL_CORE_POINTER_ID,
clutter_x11_event_sequence_get_touch_detail (sequence),
DefaultRootWindow (priv->xdisplay), event_mode);
+
+ if (state == META_SEQUENCE_REJECTED)
+ {
+ XClientMessageEvent ev;
+
+ ev = (XClientMessageEvent) {
+ .type = ClientMessage,
+ .window = meta_backend_x11_get_xwindow (x11),
+ .message_type = priv->touch_replay_sync_atom,
+ .format = 32,
+ .data.l[0] = ++priv->pending_touch_replay_sync_serial,
+ };
+ XSendEvent (priv->xdisplay, meta_backend_x11_get_xwindow (x11),
+ False, 0, (XEvent *) &ev);
+ }
}
static void