[mutter] cursor-tracker: Add way to force tracking cursor position



commit eeee7bed1dbc58f159ecc4ef84848237452b87b1
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Wed Jul 29 11:22:19 2020 +0200

    cursor-tracker: Add way to force tracking cursor position
    
    On X11 we won't always receive cursor positions, as some other client
    might have grabbed the pointer (e.g. for implementing a popup menu). To
    make screen casting show a somewhat correct cursor position, we need to
    actively poll the X server about the current cursor position.
    
    We only really want to do this when screen casting or taking a
    screenshot, so add an API that forces the cursor tracker to track the
    cursor position.
    
    On the native backend this is a no-op as we by default always track the
    cursor position anyway.
    
    https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1391

 clutter/clutter/clutter-private.h          |  6 +++
 src/backends/meta-cursor-renderer.c        |  2 -
 src/backends/meta-cursor-tracker-private.h |  7 +++
 src/backends/meta-cursor-tracker.c         | 47 +++++++++++++++++++-
 src/backends/x11/meta-cursor-tracker-x11.c | 70 ++++++++++++++++++++++++++++++
 5 files changed, 128 insertions(+), 4 deletions(-)
---
diff --git a/clutter/clutter/clutter-private.h b/clutter/clutter/clutter-private.h
index e3f89ed09c..e4119b99fa 100644
--- a/clutter/clutter/clutter-private.h
+++ b/clutter/clutter/clutter-private.h
@@ -313,6 +313,12 @@ us (uint64_t us)
   return us;
 }
 
+static inline uint32_t
+ms (uint32_t ms)
+{
+  return ms;
+}
+
 static inline uint64_t
 ms2us (uint64_t ms)
 {
diff --git a/src/backends/meta-cursor-renderer.c b/src/backends/meta-cursor-renderer.c
index c4d680235f..c8bf6578d5 100644
--- a/src/backends/meta-cursor-renderer.c
+++ b/src/backends/meta-cursor-renderer.c
@@ -383,8 +383,6 @@ meta_cursor_renderer_set_position (MetaCursorRenderer *renderer,
 {
   MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
 
-  g_assert (meta_is_wayland_compositor ());
-
   priv->current_x = x;
   priv->current_y = y;
 
diff --git a/src/backends/meta-cursor-tracker-private.h b/src/backends/meta-cursor-tracker-private.h
index 54cdb588e8..2a3d99a13e 100644
--- a/src/backends/meta-cursor-tracker-private.h
+++ b/src/backends/meta-cursor-tracker-private.h
@@ -30,6 +30,9 @@
 struct _MetaCursorTrackerClass
 {
   GObjectClass parent_class;
+
+  void (* set_force_track_position) (MetaCursorTracker *tracker,
+                                     gboolean           is_enabled);
 };
 
 gboolean meta_cursor_tracker_handle_xevent (MetaCursorTracker *tracker,
@@ -45,6 +48,10 @@ void     meta_cursor_tracker_update_position (MetaCursorTracker *tracker,
                                               float              new_x,
                                               float              new_y);
 
+void meta_cursor_tracker_track_position (MetaCursorTracker *tracker);
+
+void meta_cursor_tracker_untrack_position (MetaCursorTracker *tracker);
+
 MetaCursorSprite * meta_cursor_tracker_get_displayed_cursor (MetaCursorTracker *tracker);
 
 #endif
diff --git a/src/backends/meta-cursor-tracker.c b/src/backends/meta-cursor-tracker.c
index f9331b6f62..a411413e27 100644
--- a/src/backends/meta-cursor-tracker.c
+++ b/src/backends/meta-cursor-tracker.c
@@ -62,6 +62,8 @@ typedef struct _MetaCursorTrackerPrivate
 
   gboolean is_showing;
 
+  int track_position_count;
+
   float x;
   float y;
 
@@ -175,6 +177,12 @@ sync_cursor (MetaCursorTracker *tracker)
     g_signal_emit (tracker, signals[CURSOR_CHANGED], 0);
 }
 
+static void
+meta_cursor_tracker_real_set_force_track_position (MetaCursorTracker *tracker,
+                                                   gboolean           is_enabled)
+{
+}
+
 static void
 meta_cursor_tracker_init (MetaCursorTracker *tracker)
 {
@@ -251,6 +259,9 @@ meta_cursor_tracker_class_init (MetaCursorTrackerClass *klass)
   object_class->set_property = meta_cursor_tracker_set_property;
   object_class->finalize = meta_cursor_tracker_finalize;
 
+  klass->set_force_track_position =
+    meta_cursor_tracker_real_set_force_track_position;
+
   obj_props[PROP_BACKEND] =
     g_param_spec_object ("backend",
                          "backend",
@@ -491,8 +502,6 @@ meta_cursor_tracker_update_position (MetaCursorTracker *tracker,
     meta_backend_get_cursor_renderer (priv->backend);
   gboolean position_changed;
 
-  g_assert (meta_is_wayland_compositor ());
-
   if (priv->x != new_x || priv->y != new_y)
     {
       position_changed = TRUE;
@@ -567,6 +576,40 @@ meta_cursor_tracker_get_pointer (MetaCursorTracker   *tracker,
     get_pointer_position_gdk (x, y, (int*)mods);
 }
 
+void
+meta_cursor_tracker_track_position (MetaCursorTracker *tracker)
+{
+  MetaCursorTrackerPrivate *priv =
+    meta_cursor_tracker_get_instance_private (tracker);
+
+  priv->track_position_count++;
+  if (priv->track_position_count == 1)
+    {
+      MetaCursorTrackerClass *klass =
+        META_CURSOR_TRACKER_GET_CLASS (tracker);
+
+      klass->set_force_track_position (tracker, TRUE);
+    }
+}
+
+void
+meta_cursor_tracker_untrack_position (MetaCursorTracker *tracker)
+{
+  MetaCursorTrackerPrivate *priv =
+    meta_cursor_tracker_get_instance_private (tracker);
+
+  g_return_if_fail (priv->track_position_count <= 0);
+
+  priv->track_position_count--;
+  if (priv->track_position_count == 0)
+    {
+      MetaCursorTrackerClass *klass =
+        META_CURSOR_TRACKER_GET_CLASS (tracker);
+
+      klass->set_force_track_position (tracker, FALSE);
+    }
+}
+
 gboolean
 meta_cursor_tracker_get_pointer_visible (MetaCursorTracker *tracker)
 {
diff --git a/src/backends/x11/meta-cursor-tracker-x11.c b/src/backends/x11/meta-cursor-tracker-x11.c
index 7072275a68..f47ca9c23d 100644
--- a/src/backends/x11/meta-cursor-tracker-x11.c
+++ b/src/backends/x11/meta-cursor-tracker-x11.c
@@ -22,14 +22,77 @@
 
 #include "backends/x11/meta-cursor-tracker-x11.h"
 
+#include "clutter/clutter-private.h"
+
+#define UPDATE_POSITION_TIMEOUT_MS (ms (100))
+
 struct _MetaCursorTrackerX11
 {
   MetaCursorTracker parent;
+
+  gboolean is_force_track_position_enabled;
+  guint update_position_timeout_id;
 };
 
 G_DEFINE_TYPE (MetaCursorTrackerX11, meta_cursor_tracker_x11,
                META_TYPE_CURSOR_TRACKER)
 
+static void
+update_position (MetaCursorTrackerX11 *tracker_x11)
+{
+  MetaCursorTracker *tracker = META_CURSOR_TRACKER (tracker_x11);
+  int x, y;
+
+  meta_cursor_tracker_get_pointer (tracker, &x, &y, NULL);
+  meta_cursor_tracker_update_position (tracker, x, y);
+}
+
+static gboolean
+update_position_timeout (gpointer user_data)
+{
+  MetaCursorTrackerX11 *tracker_x11 = user_data;
+
+  update_position (tracker_x11);
+
+  return G_SOURCE_CONTINUE;
+}
+
+static void
+meta_cursor_tracker_x11_set_force_track_position (MetaCursorTracker *tracker,
+                                                  gboolean           is_enabled)
+{
+  MetaCursorTrackerX11 *tracker_x11 = META_CURSOR_TRACKER_X11 (tracker);
+
+  if (tracker_x11->is_force_track_position_enabled == is_enabled)
+    return;
+
+  tracker_x11->is_force_track_position_enabled = is_enabled;
+
+  if (is_enabled)
+    {
+      tracker_x11->update_position_timeout_id =
+        g_timeout_add (UPDATE_POSITION_TIMEOUT_MS,
+                       update_position_timeout,
+                       tracker_x11);
+      update_position (tracker_x11);
+    }
+  else
+    {
+      g_clear_handle_id (&tracker_x11->update_position_timeout_id,
+                         g_source_remove);
+    }
+}
+
+static void
+meta_cursor_tracker_x11_dispose (GObject *object)
+{
+  MetaCursorTrackerX11 *tracker_x11 = META_CURSOR_TRACKER_X11 (object);
+
+  g_clear_handle_id (&tracker_x11->update_position_timeout_id, g_source_remove);
+
+  G_OBJECT_CLASS (meta_cursor_tracker_x11_parent_class)->dispose (object);
+}
+
 static void
 meta_cursor_tracker_x11_init (MetaCursorTrackerX11 *tracker_x11)
 {
@@ -38,4 +101,11 @@ meta_cursor_tracker_x11_init (MetaCursorTrackerX11 *tracker_x11)
 static void
 meta_cursor_tracker_x11_class_init (MetaCursorTrackerX11Class *klass)
 {
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  MetaCursorTrackerClass *tracker_class = META_CURSOR_TRACKER_CLASS (klass);
+
+  object_class->dispose = meta_cursor_tracker_x11_dispose;
+
+  tracker_class->set_force_track_position =
+    meta_cursor_tracker_x11_set_force_track_position;
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]