[mutter/wip/carlosg/input-thread: 75/101] backends/native: Make some MetaSeatImpl API "async"




commit 42aae6fba1f10a4f8ef5e74e67dfacd8cf9ba1bf
Author: Carlos Garnacho <carlosg gnome org>
Date:   Wed Aug 12 15:37:43 2020 +0200

    backends/native: Make some MetaSeatImpl API "async"
    
    This API is the one accessed from different bits of the UI thread,
    make it "async" (it's basically one-way setters, so API stays the same
    in the surface) and able to run in the MetaSeatImpl main context.

 src/backends/native/meta-seat-impl.c | 281 ++++++++++++++++++++++++++++-------
 src/backends/native/meta-seat-impl.h |   5 +
 2 files changed, 235 insertions(+), 51 deletions(-)
---
diff --git a/src/backends/native/meta-seat-impl.c b/src/backends/native/meta-seat-impl.c
index 7e7d3ac17d..6bcbbf7511 100644
--- a/src/backends/native/meta-seat-impl.c
+++ b/src/backends/native/meta-seat-impl.c
@@ -137,6 +137,23 @@ void meta_seat_impl_filter_relative_motion (MetaSeatImpl       *seat_impl,
                                             float              *dy);
 void meta_seat_impl_clear_repeat_timer (MetaSeatImpl *seat_impl);
 
+void
+meta_seat_impl_run_input_task (MetaSeatImpl *seat_impl,
+                               GTask        *task,
+                               GSourceFunc   dispatch_func)
+{
+  GSource *source;
+
+  source = g_idle_source_new ();
+  g_source_set_priority (source, G_PRIORITY_HIGH);
+  g_source_set_callback (source,
+                         dispatch_func,
+                         g_object_ref (task),
+                         g_object_unref);
+  g_source_attach (source, seat_impl->input_context);
+  g_source_unref (source);
+}
+
 void
 meta_seat_impl_sync_leds (MetaSeatImpl *seat_impl)
 {
@@ -2658,12 +2675,36 @@ meta_seat_impl_get_keymap (MetaSeatImpl *seat_impl)
   return g_object_ref (seat_impl->keymap);
 }
 
+static gboolean
+warp_pointer (GTask *task)
+{
+  MetaSeatImpl *seat = g_task_get_source_object (task);
+  graphene_point_t *point;
+
+  point = g_task_get_task_data (task);
+  notify_absolute_motion (seat->core_pointer, 0,
+                          point->x, point->y, NULL);
+  g_task_return_boolean (task, TRUE);
+
+  return G_SOURCE_REMOVE;
+}
+
 void
 meta_seat_impl_warp_pointer (MetaSeatImpl *seat_impl,
                              int           x,
                              int           y)
 {
-  notify_absolute_motion (seat_impl->core_pointer, 0, x, y, NULL);
+  graphene_point_t *point;
+  GTask *task;
+
+  point = graphene_point_alloc ();
+  point->x = x;
+  point->y = y;
+
+  task = g_task_new (seat_impl, NULL, NULL, NULL);
+  g_task_set_task_data (task, point, (GDestroyNotify) graphene_point_free);
+  meta_seat_impl_run_input_task (seat_impl, task, (GSourceFunc) warp_pointer);
+  g_object_unref (task);
 }
 
 gboolean
@@ -2675,6 +2716,7 @@ meta_seat_impl_query_state (MetaSeatImpl         *seat_impl,
 {
   MetaInputDeviceNative *device_native = META_INPUT_DEVICE_NATIVE (device);
   gboolean retval = FALSE;
+  ClutterModifierType mods = 0;
 
   g_rw_lock_reader_lock (&seat_impl->state_lock);
 
@@ -2694,8 +2736,8 @@ meta_seat_impl_query_state (MetaSeatImpl         *seat_impl,
           coords->y = touch_state->coords.y;
         }
 
-      if (modifiers)
-        *modifiers = meta_xkb_translate_modifiers (seat_impl->xkb, 0);
+      if (seat_impl->xkb)
+        mods = meta_xkb_translate_modifiers (seat_impl->xkb, 0);
 
       retval = TRUE;
     }
@@ -2707,15 +2749,18 @@ meta_seat_impl_query_state (MetaSeatImpl         *seat_impl,
           coords->y = device_native->pointer_y;
         }
 
-      if (modifiers)
+      if (seat_impl->xkb)
         {
-          *modifiers = meta_xkb_translate_modifiers (seat_impl->xkb,
-                                                     seat_impl->button_state);
+          mods = meta_xkb_translate_modifiers (seat_impl->xkb,
+                                               seat_impl->button_state);
         }
 
       retval = TRUE;
     }
 
+  if (modifiers)
+    *modifiers = mods;
+
  out:
   g_rw_lock_reader_unlock (&seat_impl->state_lock);
   return retval;
@@ -2864,6 +2909,30 @@ meta_seat_impl_update_xkb_state (MetaSeatImpl *seat_impl)
   g_rw_lock_writer_unlock (&seat_impl->state_lock);
 }
 
+static gboolean
+release_devices (GTask *task)
+{
+  MetaSeatImpl *seat_impl = g_task_get_source_object (task);
+
+  if (seat_impl->released)
+    {
+      g_warning ("meta_seat_impl_release_devices() shouldn't be called "
+                 "multiple times without a corresponding call to "
+                 "meta_seat_impl_reclaim_devices() first");
+    }
+  else
+    {
+      libinput_suspend (seat_impl->libinput);
+      process_events (seat_impl);
+
+      seat_impl->released = TRUE;
+    }
+
+  g_task_return_boolean (task, TRUE);
+
+  return G_SOURCE_REMOVE;
+}
+
 /**
  * meta_seat_impl_release_devices:
  *
@@ -2877,18 +2946,38 @@ meta_seat_impl_update_xkb_state (MetaSeatImpl *seat_impl)
 void
 meta_seat_impl_release_devices (MetaSeatImpl *seat_impl)
 {
+  GTask *task;
+
+  g_return_if_fail (META_IS_SEAT_IMPL (seat_impl));
+
+  task = g_task_new (seat_impl, NULL, NULL, NULL);
+  meta_seat_impl_run_input_task (seat_impl, task,
+                                 (GSourceFunc) release_devices);
+  g_object_unref (task);
+}
+
+static gboolean
+reclaim_devices (GTask *task)
+{
+  MetaSeatImpl *seat_impl = g_task_get_source_object (task);
+
   if (seat_impl->released)
     {
-      g_warning ("meta_seat_impl_release_devices() shouldn't be called "
-                 "multiple times without a corresponding call to "
-                 "meta_seat_impl_reclaim_devices() first");
-      return;
+      libinput_resume (seat_impl->libinput);
+      meta_seat_impl_update_xkb_state (seat_impl);
+      process_events (seat_impl);
+
+      seat_impl->released = FALSE;
+    }
+  else
+    {
+      g_warning ("Spurious call to meta_seat_impl_reclaim_devices() without "
+                 "previous call to meta_seat_impl_release_devices");
     }
 
-  libinput_suspend (seat_impl->libinput);
-  process_events (seat_impl);
+  g_task_return_boolean (task, TRUE);
 
-  seat_impl->released = TRUE;
+  return G_SOURCE_REMOVE;
 }
 
 /**
@@ -2905,18 +2994,29 @@ meta_seat_impl_release_devices (MetaSeatImpl *seat_impl)
 void
 meta_seat_impl_reclaim_devices (MetaSeatImpl *seat_impl)
 {
-  if (!seat_impl->released)
-    {
-      g_warning ("Spurious call to meta_seat_impl_reclaim_devices() without "
-                 "previous call to meta_seat_impl_release_devices");
-      return;
-    }
+  GTask *task;
+
+  g_return_if_fail (META_IS_SEAT_IMPL (seat_impl));
+
+  task = g_task_new (seat_impl, NULL, NULL, NULL);
+  meta_seat_impl_run_input_task (seat_impl, task, (GSourceFunc) reclaim_devices);
+  g_object_unref (task);
+}
+
+static gboolean
+set_keyboard_map (GTask *task)
+{
+  MetaSeatImpl *seat_impl = g_task_get_source_object (task);
+  struct xkb_keymap *xkb_keymap = g_task_get_task_data (task);
+  MetaKeymapNative *keymap;
+
+  keymap = seat_impl->keymap;
+  meta_keymap_native_set_keyboard_map (keymap, xkb_keymap);
 
-  libinput_resume (seat_impl->libinput);
   meta_seat_impl_update_xkb_state (seat_impl);
-  process_events (seat_impl);
+  g_task_return_boolean (task, TRUE);
 
-  seat_impl->released = FALSE;
+  return G_SOURCE_REMOVE;
 }
 
 /**
@@ -2933,34 +3033,28 @@ void
 meta_seat_impl_set_keyboard_map (MetaSeatImpl      *seat_impl,
                                  struct xkb_keymap *xkb_keymap)
 {
-  MetaKeymapNative *keymap;
+  GTask *task;
 
   g_return_if_fail (META_IS_SEAT_IMPL (seat_impl));
 
-  keymap = seat_impl->keymap;
-  meta_keymap_native_set_keyboard_map (keymap, xkb_keymap);
-
-  meta_seat_impl_update_xkb_state (seat_impl);
+  task = g_task_new (seat_impl, NULL, NULL, NULL);
+  g_task_set_task_data (task,
+                        xkb_keymap_ref (xkb_keymap),
+                        (GDestroyNotify) xkb_keymap_unref);
+  meta_seat_impl_run_input_task (seat_impl, task, (GSourceFunc) set_keyboard_map);
+  g_object_unref (task);
 }
 
-/**
- * meta_seat_impl_set_keyboard_layout_index: (skip)
- * @seat: the #ClutterSeat created by the evdev backend
- * @idx: the xkb layout index to set
- *
- * Sets the xkb layout index on the backend's #xkb_state .
- */
-void
-meta_seat_impl_set_keyboard_layout_index (MetaSeatImpl       *seat_impl,
-                                          xkb_layout_index_t  idx)
+static gboolean
+set_keyboard_layout_index (GTask *task)
 {
+  MetaSeatImpl *seat_impl = g_task_get_source_object (task);
+  xkb_layout_index_t idx = GPOINTER_TO_UINT (g_task_get_task_data (task));
   xkb_mod_mask_t depressed_mods;
   xkb_mod_mask_t latched_mods;
   xkb_mod_mask_t locked_mods;
   struct xkb_state *state;
 
-  g_return_if_fail (META_IS_SEAT_IMPL (seat_impl));
-
   g_rw_lock_writer_lock (&seat_impl->state_lock);
 
   state = seat_impl->xkb;
@@ -2975,19 +3069,39 @@ meta_seat_impl_set_keyboard_layout_index (MetaSeatImpl       *seat_impl,
   seat_impl->layout_idx = idx;
 
   g_rw_lock_writer_unlock (&seat_impl->state_lock);
+
+  g_task_return_boolean (task, TRUE);
+
+  return G_SOURCE_REMOVE;
 }
 
 /**
- * meta_seat_impl_set_keyboard_numlock: (skip)
+ * meta_seat_impl_set_keyboard_layout_index: (skip)
  * @seat: the #ClutterSeat created by the evdev backend
- * @numlock_set: TRUE to set NumLock ON, FALSE otherwise.
+ * @idx: the xkb layout index to set
  *
- * Sets the NumLock state on the backend's #xkb_state .
+ * Sets the xkb layout index on the backend's #xkb_state .
  */
 void
-meta_seat_impl_set_keyboard_numlock (MetaSeatImpl *seat_impl,
-                                     gboolean      numlock_state)
+meta_seat_impl_set_keyboard_layout_index (MetaSeatImpl       *seat_impl,
+                                          xkb_layout_index_t  idx)
+{
+  GTask *task;
+
+  g_return_if_fail (META_IS_SEAT_IMPL (seat_impl));
+
+  task = g_task_new (seat_impl, NULL, NULL, NULL);
+  g_task_set_task_data (task, GUINT_TO_POINTER (idx), NULL);
+  meta_seat_impl_run_input_task (seat_impl, task,
+                                 (GSourceFunc) set_keyboard_layout_index);
+  g_object_unref (task);
+}
+
+static gboolean
+set_keyboard_numlock (GTask *task)
 {
+  MetaSeatImpl *seat_impl = g_task_get_source_object (task);
+  gboolean numlock_state = GPOINTER_TO_UINT (g_task_get_task_data (task));
   xkb_mod_mask_t depressed_mods;
   xkb_mod_mask_t latched_mods;
   xkb_mod_mask_t locked_mods;
@@ -2996,8 +3110,6 @@ meta_seat_impl_set_keyboard_numlock (MetaSeatImpl *seat_impl,
   struct xkb_keymap *xkb_keymap;
   MetaKeymapNative *keymap;
 
-  g_return_if_fail (META_IS_SEAT_IMPL (seat_impl));
-
   g_rw_lock_writer_lock (&seat_impl->state_lock);
 
   keymap = seat_impl->keymap;
@@ -3030,6 +3142,32 @@ meta_seat_impl_set_keyboard_numlock (MetaSeatImpl *seat_impl,
   meta_keymap_native_update (seat_impl->keymap);
 
   g_rw_lock_writer_unlock (&seat_impl->state_lock);
+
+  g_task_return_boolean (task, TRUE);
+
+  return G_SOURCE_REMOVE;
+}
+
+/**
+ * meta_seat_impl_set_keyboard_numlock: (skip)
+ * @seat: the #ClutterSeat created by the evdev backend
+ * @numlock_set: TRUE to set NumLock ON, FALSE otherwise.
+ *
+ * Sets the NumLock state on the backend's #xkb_state .
+ */
+void
+meta_seat_impl_set_keyboard_numlock (MetaSeatImpl *seat_impl,
+                                     gboolean      numlock_state)
+{
+  GTask *task;
+
+  g_return_if_fail (META_IS_SEAT_IMPL (seat_impl));
+
+  task = g_task_new (seat_impl, NULL, NULL, NULL);
+  g_task_set_task_data (task, GUINT_TO_POINTER (numlock_state), NULL);
+  meta_seat_impl_run_input_task (seat_impl, task,
+                                 (GSourceFunc) set_keyboard_numlock);
+  g_object_unref (task);
 }
 
 /**
@@ -3069,25 +3207,66 @@ meta_seat_impl_get_barrier_manager (MetaSeatImpl *seat_impl)
   return seat_impl->barrier_manager;
 }
 
-void
-meta_seat_impl_set_pointer_constraint (MetaSeatImpl              *seat_impl,
-                                       MetaPointerConstraintImpl *constraint_impl)
+static gboolean
+set_pointer_constraint (GTask *task)
 {
+  MetaSeatImpl *seat_impl = g_task_get_source_object (task);
+  MetaPointerConstraintImpl *constraint_impl = g_task_get_task_data (task);
+
   if (!g_set_object (&seat_impl->pointer_constraint, constraint_impl))
-    return;
+    return G_SOURCE_REMOVE;
 
   if (constraint_impl)
     {
       meta_pointer_constraint_impl_ensure_constrained (constraint_impl,
                                                        seat_impl->core_pointer);
     }
+
+  g_task_return_boolean (task, TRUE);
+
+  return G_SOURCE_REMOVE;
+}
+
+void
+meta_seat_impl_set_pointer_constraint (MetaSeatImpl              *seat,
+                                       MetaPointerConstraintImpl *constraint_impl)
+{
+  GTask *task;
+
+  g_return_if_fail (META_IS_SEAT_IMPL (seat));
+
+  task = g_task_new (seat, NULL, NULL, NULL);
+  g_task_set_task_data (task, g_object_ref (constraint_impl), g_object_unref);
+  meta_seat_impl_run_input_task (seat, task,
+                                 (GSourceFunc) set_pointer_constraint);
+  g_object_unref (task);
+}
+
+static gboolean
+set_viewports (GTask *task)
+{
+  MetaSeatImpl *seat = g_task_get_source_object (task);
+  MetaViewportInfo *viewports = g_task_get_task_data (task);
+
+  g_set_object (&seat->viewports, viewports);
+  g_task_return_boolean (task, TRUE);
+
+  return G_SOURCE_REMOVE;
 }
 
 void
 meta_seat_impl_set_viewports (MetaSeatImpl     *seat_impl,
                               MetaViewportInfo *viewports)
 {
-  g_set_object (&seat_impl->viewports, viewports);
+  GTask *task;
+
+  g_return_if_fail (META_IS_SEAT_IMPL (seat_impl));
+
+  task = g_task_new (seat_impl, NULL, NULL, NULL);
+  g_task_set_task_data (task, g_object_ref (viewports), g_object_unref);
+  meta_seat_impl_run_input_task (seat_impl, task,
+                                 (GSourceFunc) set_viewports);
+  g_object_unref (task);
 }
 
 MetaSeatImpl *
diff --git a/src/backends/native/meta-seat-impl.h b/src/backends/native/meta-seat-impl.h
index a62af83f5d..8e8de727f1 100644
--- a/src/backends/native/meta-seat-impl.h
+++ b/src/backends/native/meta-seat-impl.h
@@ -54,6 +54,7 @@ struct _MetaSeatImpl
 {
   GObject parent_instance;
 
+  GMainContext *input_context;
   MetaSeatNative *seat_native;
   char *seat_id;
   MetaEventSource *event_source;
@@ -116,6 +117,10 @@ G_DECLARE_FINAL_TYPE (MetaSeatImpl, meta_seat_impl,
 MetaSeatImpl * meta_seat_impl_new (MetaSeatNative *seat_native,
                                    const char     *seat_id);
 
+void meta_seat_impl_run_input_task (MetaSeatImpl *seat_impl,
+                                    GTask        *task,
+                                    GSourceFunc   dispatch_func);
+
 void meta_seat_impl_notify_key (MetaSeatImpl       *seat_impl,
                                 ClutterInputDevice *device,
                                 uint64_t            time_us,


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