Blame SOURCES/input-after-long-idle-fix.patch

8d879e
From a86f1085d1f5056fb4b19f1d7f72a1905122cc24 Mon Sep 17 00:00:00 2001
baa59a
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
baa59a
Date: Thu, 24 Oct 2019 21:19:36 +0200
baa59a
Subject: [PATCH 1/2] display: Move finishing of touch sequence to the backend
baa59a
baa59a
We need to manipulate an X11 grab when a touch sequence ends; move that
baa59a
logic to where it belongs - in the X11 backend.
baa59a
baa59a
https://gitlab.gnome.org/GNOME/mutter/merge_requests/886
baa59a
---
baa59a
 src/backends/meta-backend-private.h     | 16 ++++++++++++
baa59a
 src/backends/meta-backend.c             | 14 +++++++++++
baa59a
 src/backends/x11/meta-backend-x11.c     | 23 +++++++++++++++++
baa59a
 src/core/display.c                      | 33 +++++++++++--------------
baa59a
 src/core/meta-gesture-tracker-private.h |  7 +-----
baa59a
 src/core/meta-gesture-tracker.c         |  1 +
baa59a
 6 files changed, 70 insertions(+), 24 deletions(-)
baa59a
baa59a
diff --git a/src/backends/meta-backend-private.h b/src/backends/meta-backend-private.h
baa59a
index a25275499..7f4a4ea0f 100644
baa59a
--- a/src/backends/meta-backend-private.h
baa59a
+++ b/src/backends/meta-backend-private.h
baa59a
@@ -51,6 +51,14 @@
baa59a
 #define META_TYPE_BACKEND (meta_backend_get_type ())
baa59a
 G_DECLARE_DERIVABLE_TYPE (MetaBackend, meta_backend, META, BACKEND, GObject)
baa59a
 
baa59a
+typedef enum _MetaSequenceState
baa59a
+{
baa59a
+  META_SEQUENCE_NONE,
baa59a
+  META_SEQUENCE_ACCEPTED,
baa59a
+  META_SEQUENCE_REJECTED,
baa59a
+  META_SEQUENCE_PENDING_END
baa59a
+} MetaSequenceState;
baa59a
+
baa59a
 struct _MetaBackendClass
baa59a
 {
baa59a
   GObjectClass parent_class;
baa59a
@@ -73,6 +81,10 @@ struct _MetaBackendClass
baa59a
                               int          device_id,
baa59a
                               uint32_t     timestamp);
baa59a
 
baa59a
+  void (* finish_touch_sequence) (MetaBackend          *backend,
baa59a
+                                  ClutterEventSequence *sequence,
baa59a
+                                  MetaSequenceState     state);
baa59a
+
baa59a
   void (* warp_pointer) (MetaBackend *backend,
baa59a
                          int          x,
baa59a
                          int          y);
baa59a
@@ -134,6 +146,10 @@ gboolean meta_backend_ungrab_device (MetaBackend *backend,
baa59a
                                      int          device_id,
baa59a
                                      uint32_t     timestamp);
baa59a
 
baa59a
+void meta_backend_finish_touch_sequence (MetaBackend          *backend,
baa59a
+                                         ClutterEventSequence *sequence,
baa59a
+                                         MetaSequenceState     state);
baa59a
+
baa59a
 void meta_backend_warp_pointer (MetaBackend *backend,
baa59a
                                 int          x,
baa59a
                                 int          y);
baa59a
diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c
baa59a
index ce7e385b9..fb4f69fe6 100644
baa59a
--- a/src/backends/meta-backend.c
baa59a
+++ b/src/backends/meta-backend.c
baa59a
@@ -846,6 +846,20 @@ meta_backend_ungrab_device (MetaBackend *backend,
baa59a
   return META_BACKEND_GET_CLASS (backend)->ungrab_device (backend, device_id, timestamp);
baa59a
 }
baa59a
 
baa59a
+/**
baa59a
+ * meta_backend_finish_touch_sequence: (skip)
baa59a
+ */
baa59a
+void
baa59a
+meta_backend_finish_touch_sequence (MetaBackend          *backend,
baa59a
+                                    ClutterEventSequence *sequence,
baa59a
+                                    MetaSequenceState     state)
baa59a
+{
baa59a
+  if (META_BACKEND_GET_CLASS (backend)->finish_touch_sequence)
baa59a
+    META_BACKEND_GET_CLASS (backend)->finish_touch_sequence (backend,
baa59a
+                                                             sequence,
baa59a
+                                                             state);
baa59a
+}
baa59a
+
baa59a
 /**
baa59a
  * meta_backend_warp_pointer: (skip)
baa59a
  */
baa59a
diff --git a/src/backends/x11/meta-backend-x11.c b/src/backends/x11/meta-backend-x11.c
baa59a
index 2b131d2d0..2835d47d6 100644
baa59a
--- a/src/backends/x11/meta-backend-x11.c
baa59a
+++ b/src/backends/x11/meta-backend-x11.c
baa59a
@@ -583,6 +583,28 @@ meta_backend_x11_ungrab_device (MetaBackend *backend,
baa59a
   return (ret == Success);
baa59a
 }
baa59a
 
baa59a
+static void
baa59a
+meta_backend_x11_finish_touch_sequence (MetaBackend          *backend,
baa59a
+                                        ClutterEventSequence *sequence,
baa59a
+                                        MetaSequenceState     state)
baa59a
+{
baa59a
+  MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
baa59a
+  MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
baa59a
+  int event_mode;
baa59a
+
baa59a
+  if (state == META_SEQUENCE_ACCEPTED)
baa59a
+    event_mode = XIAcceptTouch;
baa59a
+  else if (state == META_SEQUENCE_REJECTED)
baa59a
+    event_mode = XIRejectTouch;
baa59a
+  else
baa59a
+    g_return_if_reached ();
baa59a
+
baa59a
+  XIAllowTouchEvents (priv->xdisplay,
baa59a
+                      META_VIRTUAL_CORE_POINTER_ID,
baa59a
+                      clutter_x11_event_sequence_get_touch_detail (sequence),
baa59a
+                      DefaultRootWindow (priv->xdisplay), event_mode);
baa59a
+}
baa59a
+
baa59a
 static void
baa59a
 meta_backend_x11_warp_pointer (MetaBackend *backend,
baa59a
                                int          x,
baa59a
@@ -768,6 +790,7 @@ meta_backend_x11_class_init (MetaBackendX11Class *klass)
baa59a
   backend_class->post_init = meta_backend_x11_post_init;
baa59a
   backend_class->grab_device = meta_backend_x11_grab_device;
baa59a
   backend_class->ungrab_device = meta_backend_x11_ungrab_device;
baa59a
+  backend_class->finish_touch_sequence = meta_backend_x11_finish_touch_sequence;
baa59a
   backend_class->warp_pointer = meta_backend_x11_warp_pointer;
baa59a
   backend_class->get_current_logical_monitor = meta_backend_x11_get_current_logical_monitor;
baa59a
   backend_class->get_keymap = meta_backend_x11_get_keymap;
baa59a
diff --git a/src/core/display.c b/src/core/display.c
baa59a
index e7dd4534b..d4775cec3 100644
baa59a
--- a/src/core/display.c
baa59a
+++ b/src/core/display.c
baa59a
@@ -55,6 +55,7 @@
baa59a
 #include "backends/x11/meta-backend-x11.h"
baa59a
 #include "backends/meta-stage-private.h"
baa59a
 #include "backends/meta-input-settings-private.h"
baa59a
+#include "backends/meta-backend-private.h"
baa59a
 #include <clutter/x11/clutter-x11.h>
baa59a
 
baa59a
 #ifdef HAVE_RANDR
baa59a
@@ -533,27 +534,23 @@ gesture_tracker_state_changed (MetaGestureTracker   *tracker,
baa59a
                                MetaSequenceState     state,
baa59a
                                MetaDisplay          *display)
baa59a
 {
baa59a
-  if (meta_is_wayland_compositor ())
baa59a
+  switch (state)
baa59a
     {
baa59a
-      if (state == META_SEQUENCE_ACCEPTED)
baa59a
-        meta_display_cancel_touch (display);
baa59a
-    }
baa59a
-  else
baa59a
-    {
baa59a
-      MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ());
baa59a
-      int event_mode;
baa59a
+    case META_SEQUENCE_NONE:
baa59a
+    case META_SEQUENCE_PENDING_END:
baa59a
+      return;
baa59a
+    case META_SEQUENCE_ACCEPTED:
baa59a
+      meta_display_cancel_touch (display);
baa59a
 
baa59a
-      if (state == META_SEQUENCE_ACCEPTED)
baa59a
-        event_mode = XIAcceptTouch;
baa59a
-      else if (state == META_SEQUENCE_REJECTED)
baa59a
-        event_mode = XIRejectTouch;
baa59a
-      else
baa59a
-        return;
baa59a
+      /* Intentional fall-through */
baa59a
+    case META_SEQUENCE_REJECTED:
baa59a
+      {
baa59a
+        MetaBackend *backend;
baa59a
 
baa59a
-      XIAllowTouchEvents (meta_backend_x11_get_xdisplay (backend),
baa59a
-                          META_VIRTUAL_CORE_POINTER_ID,
baa59a
-                          clutter_x11_event_sequence_get_touch_detail (sequence),
baa59a
-                          DefaultRootWindow (display->xdisplay), event_mode);
baa59a
+        backend = meta_get_backend ();
baa59a
+        meta_backend_finish_touch_sequence (backend, sequence, state);
baa59a
+        break;
baa59a
+      }
baa59a
     }
baa59a
 }
baa59a
 
baa59a
diff --git a/src/core/meta-gesture-tracker-private.h b/src/core/meta-gesture-tracker-private.h
baa59a
index 0e39af27f..b4fb02a1e 100644
baa59a
--- a/src/core/meta-gesture-tracker-private.h
baa59a
+++ b/src/core/meta-gesture-tracker-private.h
baa59a
@@ -38,12 +38,7 @@
baa59a
 typedef struct _MetaGestureTracker MetaGestureTracker;
baa59a
 typedef struct _MetaGestureTrackerClass MetaGestureTrackerClass;
baa59a
 
baa59a
-typedef enum {
baa59a
-  META_SEQUENCE_NONE,
baa59a
-  META_SEQUENCE_ACCEPTED,
baa59a
-  META_SEQUENCE_REJECTED,
baa59a
-  META_SEQUENCE_PENDING_END
baa59a
-} MetaSequenceState;
baa59a
+typedef enum _MetaSequenceState MetaSequenceState;
baa59a
 
baa59a
 struct _MetaGestureTracker
baa59a
 {
baa59a
diff --git a/src/core/meta-gesture-tracker.c b/src/core/meta-gesture-tracker.c
baa59a
index e3b702f56..1313aad6d 100644
baa59a
--- a/src/core/meta-gesture-tracker.c
baa59a
+++ b/src/core/meta-gesture-tracker.c
baa59a
@@ -31,6 +31,7 @@
baa59a
 #include "config.h"
baa59a
 #include "meta-gesture-tracker-private.h"
baa59a
 #include "meta-surface-actor.h"
baa59a
+#include "meta-backend-private.h"
baa59a
 
baa59a
 #define DISTANCE_THRESHOLD 30
baa59a
 
baa59a
-- 
baa59a
2.23.0
baa59a
baa59a
8d879e
From 651a45057bce8d1dd8d493d1f6a0486e04d6571b Mon Sep 17 00:00:00 2001
baa59a
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
baa59a
Date: Fri, 25 Oct 2019 10:06:55 +0200
baa59a
Subject: [PATCH 2/2] x11: Limit touch replay pointer events to when replaying
baa59a
baa59a
When a touch sequence was rejected, the emulated pointer events would be
baa59a
replayed with old timestamps. This caused issues with grabs as they
baa59a
would be ignored due to being too old. This was mitigated by making sure
baa59a
device event timestamps never travelled back in time by tampering with
baa59a
any event that had a timestamp seemingly in the past.
baa59a
baa59a
This failed when the most recent timestamp that had been received were
baa59a
much older than the timestamp of the new event. This could for example
baa59a
happen when a session was left not interacted with for 40+ days or so;
baa59a
when interacted with again, as any new timestamp would according to
baa59a
XSERVER_TIME_IS_BEFORE() still be in the past compared to the "most
baa59a
recent" one. The effect is that we'd always use the `latest_evtime` for
baa59a
all new device events without ever updating it.
baa59a
baa59a
The end result of this was that passive grabs would become active when
baa59a
interacted with, but would then newer be released, as the timestamps to
baa59a
XIAllowEvents() would out of date, resulting in the desktop effectively
baa59a
freezing, as the Shell would have an active pointer grab.
baa59a
baa59a
To avoid the situation where we get stuck with an old `latest_evtime`
baa59a
timestamp, limit the tampering with device event timestamp to 1) only
baa59a
pointer events, and 2) only during the replay sequence. The second part
baa59a
is implemented by sending an asynchronous message via the X server after
baa59a
rejecting a touch sequence, only potentially tampering with the device
baa59a
event timestamps until the reply. This should avoid the stuck timestamp
baa59a
as in those situations, we'll always have a relatively up to date
baa59a
`latest_evtime` meaning XSERVER_TIME_IS_BEFORE() will not get confused.
baa59a
baa59a
https://gitlab.gnome.org/GNOME/mutter/merge_requests/886
baa59a
---
8d879e
 src/backends/x11/meta-backend-x11.c | 67 +++++++++++++++++++++++------
8d879e
 1 file changed, 54 insertions(+), 13 deletions(-)
baa59a
baa59a
diff --git a/src/backends/x11/meta-backend-x11.c b/src/backends/x11/meta-backend-x11.c
8d879e
index 2835d47d6..7b8ff1b94 100644
baa59a
--- a/src/backends/x11/meta-backend-x11.c
baa59a
+++ b/src/backends/x11/meta-backend-x11.c
baa59a
@@ -60,6 +60,10 @@ struct _MetaBackendX11Private
baa59a
   XSyncAlarm user_active_alarm;
baa59a
   XSyncCounter counter;
baa59a
 
baa59a
+  int current_touch_replay_sync_serial;
baa59a
+  int pending_touch_replay_sync_serial;
baa59a
+  Atom touch_replay_sync_atom;
baa59a
+
baa59a
   int xinput_opcode;
baa59a
   int xinput_event_base;
baa59a
   int xinput_error_base;
baa59a
@@ -168,6 +172,26 @@ meta_backend_x11_translate_device_event (MetaBackendX11 *x11,
baa59a
   backend_x11_class->translate_device_event (x11, device_event);
baa59a
 }
baa59a
 
baa59a
+static void
baa59a
+maybe_translate_touch_replay_pointer_event (MetaBackendX11 *x11,
baa59a
+                                            XIDeviceEvent  *device_event)
baa59a
+{
baa59a
+  MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
baa59a
+
baa59a
+  if (!device_event->send_event &&
baa59a
+      device_event->time != CurrentTime &&
baa59a
+      priv->current_touch_replay_sync_serial !=
baa59a
+      priv->pending_touch_replay_sync_serial &&
baa59a
+      XSERVER_TIME_IS_BEFORE (device_event->time, priv->latest_evtime))
baa59a
+    {
baa59a
+      /* Emulated pointer events received after XIRejectTouch is received
baa59a
+       * on a passive touch grab will contain older timestamps, update those
baa59a
+       * so we dont get InvalidTime at grabs.
baa59a
+       */
baa59a
+      device_event->time = priv->latest_evtime;
baa59a
+    }
baa59a
+}
baa59a
+
baa59a
 static void
baa59a
 translate_device_event (MetaBackendX11 *x11,
baa59a
                         XIDeviceEvent  *device_event)
baa59a
@@ -177,19 +201,7 @@ translate_device_event (MetaBackendX11 *x11,
baa59a
   meta_backend_x11_translate_device_event (x11, device_event);
baa59a
 
baa59a
   if (!device_event->send_event && device_event->time != CurrentTime)
baa59a
-    {
baa59a
-      if (XSERVER_TIME_IS_BEFORE (device_event->time, priv->latest_evtime))
baa59a
-        {
baa59a
-          /* Emulated pointer events received after XIRejectTouch is received
baa59a
-           * on a passive touch grab will contain older timestamps, update those
baa59a
-           * so we dont get InvalidTime at grabs.
baa59a
-           */
baa59a
-          device_event->time = priv->latest_evtime;
baa59a
-        }
baa59a
-
baa59a
-      /* Update the internal latest evtime, for any possible later use */
baa59a
-      priv->latest_evtime = device_event->time;
baa59a
-    }
baa59a
+    priv->latest_evtime = device_event->time;
baa59a
 }
baa59a
 
baa59a
 static void
baa59a
@@ -254,6 +266,9 @@ maybe_spoof_event_as_stage_event (MetaBackendX11 *x11,
baa59a
     case XI_Motion:
baa59a
     case XI_ButtonPress:
baa59a
     case XI_ButtonRelease:
baa59a
+      maybe_translate_touch_replay_pointer_event (x11,
baa59a
+                                                  (XIDeviceEvent *) input_event);
baa59a
+      /* Intentional fall-through */
baa59a
     case XI_KeyPress:
baa59a
     case XI_KeyRelease:
baa59a
     case XI_TouchBegin:
baa59a
@@ -321,6 +336,17 @@ handle_host_xevent (MetaBackend *backend,
baa59a
   MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
baa59a
   gboolean bypass_clutter = FALSE;
baa59a
 
baa59a
+  switch (event->type)
baa59a
+    {
baa59a
+    case ClientMessage:
baa59a
+      if (event->xclient.window == meta_backend_x11_get_xwindow (x11) &&
baa59a
+          event->xclient.message_type == priv->touch_replay_sync_atom)
baa59a
+        priv->current_touch_replay_sync_serial = event->xclient.data.l[0];
baa59a
+      break;
baa59a
+    default:
baa59a
+      break;
baa59a
+    }
baa59a
+
baa59a
   XGetEventData (priv->xdisplay, &event->xcookie);
baa59a
 
baa59a
   {
baa59a
@@ -528,6 +554,10 @@ meta_backend_x11_post_init (MetaBackend *backend)
baa59a
   monitor_manager = meta_backend_get_monitor_manager (backend);
baa59a
   g_signal_connect (monitor_manager, "monitors-changed-internal",
baa59a
                     G_CALLBACK (on_monitors_changed), backend);
baa59a
+
baa59a
+  priv->touch_replay_sync_atom = XInternAtom (priv->xdisplay,
baa59a
+                                              "_MUTTER_TOUCH_SEQUENCE_SYNC",
baa59a
+                                              False);
baa59a
 }
baa59a
 
baa59a
 static ClutterBackend *
8d879e
@@ -591,6 +621,7 @@ meta_backend_x11_finish_touch_sequence (MetaBackend          *backend,
8d879e
   MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
8d879e
   MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
8d879e
   int event_mode;
8d879e
+  XClientMessageEvent ev;
8d879e
 
8d879e
   if (state == META_SEQUENCE_ACCEPTED)
8d879e
     event_mode = XIAcceptTouch;
8d879e
@@ -603,6 +634,16 @@ meta_backend_x11_finish_touch_sequence (MetaBackend          *backend,
baa59a
                       META_VIRTUAL_CORE_POINTER_ID,
baa59a
                       clutter_x11_event_sequence_get_touch_detail (sequence),
baa59a
                       DefaultRootWindow (priv->xdisplay), event_mode);
baa59a
+
8d879e
+  ev = (XClientMessageEvent) {
8d879e
+    .type = ClientMessage,
8d879e
+    .window = meta_backend_x11_get_xwindow (x11),
8d879e
+    .message_type = priv->touch_replay_sync_atom,
8d879e
+    .format = 32,
8d879e
+    .data.l[0] = ++priv->pending_touch_replay_sync_serial,
8d879e
+  };
8d879e
+  XSendEvent (priv->xdisplay, meta_backend_x11_get_xwindow (x11),
8d879e
+              False, 0, (XEvent *) &ev;;
baa59a
 }
baa59a
 
baa59a
 static void
baa59a
-- 
baa59a
2.23.0
baa59a