diff options
Diffstat (limited to 'src/backends/x11/meta-backend-x11.c')
-rw-r--r-- | src/backends/x11/meta-backend-x11.c | 71 |
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 |