[mutter/wip/carlosg/shuffle-pointer-a11y: 1/2] clutter: Move pointer a11y settings management from MetaInputSettings




commit 4e8fb7c49dea0f0cdb691225dc1970c0992ce7c5
Author: Carlos Garnacho <carlosg gnome org>
Date:   Sun May 2 16:27:01 2021 +0200

    clutter: Move pointer a11y settings management from MetaInputSettings
    
    All pointer a11y is a fabrication of Clutter backend-independent
    code, with the help of a ClutterVirtualInputDevice and with some
    UI on top.
    
    On the other hand, MetaInputSettings is a backend implementation
    detail, this has 2 gotchas:
    - In the native backend, the MetaInputSettings (and pointer a11y
      with it) are initialized early, before the ClutterSeat core
      pointer is set up.
    - Doing this from the MetaInputSettings also means another dubious
      access from the input thread into main thread territory.
    
    Move the pointer a11y into ClutterSettings, making this effectively
    backend-independent business, invariably done from the main thread
    and ensured to happen after seat initialization.
    
    Fixes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1765

 clutter/clutter/clutter-seat.c             |  12 +++
 clutter/clutter/clutter-settings-private.h |   3 +
 clutter/clutter/clutter-settings.c         | 122 +++++++++++++++++++++++++++++
 clutter/meson.build                        |   1 +
 src/backends/meta-input-settings.c         |  98 -----------------------
 5 files changed, 138 insertions(+), 98 deletions(-)
---
diff --git a/clutter/clutter/clutter-seat.c b/clutter/clutter/clutter-seat.c
index 24f36edbdf..a62aeedc2a 100644
--- a/clutter/clutter/clutter-seat.c
+++ b/clutter/clutter/clutter-seat.c
@@ -31,6 +31,7 @@
 #include "clutter-private.h"
 #include "clutter-seat.h"
 #include "clutter-seat-private.h"
+#include "clutter-settings-private.h"
 #include "clutter-virtual-input-device.h"
 
 enum
@@ -114,6 +115,16 @@ clutter_seat_get_property (GObject    *object,
     }
 }
 
+static void
+clutter_seat_constructed (GObject *object)
+{
+  ClutterSettings *settings = clutter_settings_get_default ();
+
+  G_OBJECT_CLASS (clutter_seat_parent_class)->constructed (object);
+  clutter_settings_ensure_pointer_a11y_settings (settings,
+                                                 CLUTTER_SEAT (object));
+}
+
 static void
 clutter_seat_class_init (ClutterSeatClass *klass)
 {
@@ -121,6 +132,7 @@ clutter_seat_class_init (ClutterSeatClass *klass)
 
   object_class->set_property = clutter_seat_set_property;
   object_class->get_property = clutter_seat_get_property;
+  object_class->constructed = clutter_seat_constructed;
 
   signals[DEVICE_ADDED] =
     g_signal_new (I_("device-added"),
diff --git a/clutter/clutter/clutter-settings-private.h b/clutter/clutter/clutter-settings-private.h
index 7df4fccf18..a8a8e01e3f 100644
--- a/clutter/clutter/clutter-settings-private.h
+++ b/clutter/clutter/clutter-settings-private.h
@@ -13,6 +13,9 @@ void    clutter_settings_set_property_internal (ClutterSettings *settings,
                                                 const char *property,
                                                 GValue *value);
 
+void clutter_settings_ensure_pointer_a11y_settings (ClutterSettings *settings,
+                                                    ClutterSeat     *seat);
+
 G_END_DECLS
 
 #endif /* __CLUTTER_SETTINGS_PRIVATE_H__ */
diff --git a/clutter/clutter/clutter-settings.c b/clutter/clutter/clutter-settings.c
index e80dd2450f..f3dffdbbba 100644
--- a/clutter/clutter/clutter-settings.c
+++ b/clutter/clutter/clutter-settings.c
@@ -32,6 +32,7 @@
 #include "clutter-stage-private.h"
 #include "clutter-private.h"
 
+#include <gdesktop-enums.h>
 #include <stdlib.h>
 
 #define DEFAULT_FONT_NAME       "Sans 12"
@@ -67,6 +68,7 @@ struct _ClutterSettings
   ClutterBackend *backend;
   GSettings *font_settings;
   GSettings *mouse_settings;
+  GSettings *mouse_a11y_settings;
 
   gint double_click_time;
   gint double_click_distance;
@@ -436,11 +438,110 @@ on_mouse_settings_change_event (GSettings *settings,
   return FALSE;
 }
 
+struct _pointer_a11y_settings_flags_pair {
+  const char *name;
+  ClutterPointerA11yFlags flag;
+} pointer_a11y_settings_flags_pair[] = {
+  { "secondary-click-enabled", CLUTTER_A11Y_SECONDARY_CLICK_ENABLED },
+  { "dwell-click-enabled",     CLUTTER_A11Y_DWELL_ENABLED },
+};
+
+static ClutterPointerA11yDwellDirection
+pointer_a11y_dwell_direction_from_setting (ClutterSettings *self,
+                                           const char      *key)
+{
+  GDesktopMouseDwellDirection dwell_gesture_direction;
+
+  dwell_gesture_direction = g_settings_get_enum (self->mouse_a11y_settings,
+                                                 key);
+  switch (dwell_gesture_direction)
+    {
+    case G_DESKTOP_MOUSE_DWELL_DIRECTION_LEFT:
+      return CLUTTER_A11Y_DWELL_DIRECTION_LEFT;
+      break;
+    case G_DESKTOP_MOUSE_DWELL_DIRECTION_RIGHT:
+      return CLUTTER_A11Y_DWELL_DIRECTION_RIGHT;
+      break;
+    case G_DESKTOP_MOUSE_DWELL_DIRECTION_UP:
+      return CLUTTER_A11Y_DWELL_DIRECTION_UP;
+      break;
+    case G_DESKTOP_MOUSE_DWELL_DIRECTION_DOWN:
+      return CLUTTER_A11Y_DWELL_DIRECTION_DOWN;
+      break;
+    default:
+      break;
+    }
+  return CLUTTER_A11Y_DWELL_DIRECTION_NONE;
+}
+
+static void
+sync_pointer_a11y_settings (ClutterSettings *self,
+                            ClutterSeat     *seat)
+{
+  ClutterPointerA11ySettings pointer_a11y_settings;
+  GDesktopMouseDwellMode dwell_mode;
+  int i;
+
+  clutter_seat_get_pointer_a11y_settings (seat, &pointer_a11y_settings);
+  pointer_a11y_settings.controls = 0;
+  for (i = 0; i < G_N_ELEMENTS (pointer_a11y_settings_flags_pair); i++)
+    {
+      if (!g_settings_get_boolean (self->mouse_a11y_settings,
+                                   pointer_a11y_settings_flags_pair[i].name))
+        continue;
+
+      pointer_a11y_settings.controls |=
+        pointer_a11y_settings_flags_pair[i].flag;
+    }
+
+  /* "secondary-click-time" is expressed in seconds */
+  pointer_a11y_settings.secondary_click_delay =
+    (1000 * g_settings_get_double (self->mouse_a11y_settings,
+                                   "secondary-click-time"));
+  /* "dwell-time" is expressed in seconds */
+  pointer_a11y_settings.dwell_delay =
+    (1000 * g_settings_get_double (self->mouse_a11y_settings, "dwell-time"));
+  pointer_a11y_settings.dwell_threshold =
+    g_settings_get_int (self->mouse_a11y_settings, "dwell-threshold");
+
+  dwell_mode = g_settings_get_enum (self->mouse_a11y_settings, "dwell-mode");
+  if (dwell_mode == G_DESKTOP_MOUSE_DWELL_MODE_WINDOW)
+    pointer_a11y_settings.dwell_mode = CLUTTER_A11Y_DWELL_MODE_WINDOW;
+  else
+    pointer_a11y_settings.dwell_mode = CLUTTER_A11Y_DWELL_MODE_GESTURE;
+
+  pointer_a11y_settings.dwell_gesture_single =
+    pointer_a11y_dwell_direction_from_setting (self, "dwell-gesture-single");
+  pointer_a11y_settings.dwell_gesture_double =
+    pointer_a11y_dwell_direction_from_setting (self, "dwell-gesture-double");
+  pointer_a11y_settings.dwell_gesture_drag =
+    pointer_a11y_dwell_direction_from_setting (self, "dwell-gesture-drag");
+  pointer_a11y_settings.dwell_gesture_secondary =
+    pointer_a11y_dwell_direction_from_setting (self, "dwell-gesture-secondary");
+
+  clutter_seat_set_pointer_a11y_settings (seat, &pointer_a11y_settings);
+}
+
+static gboolean
+on_mouse_a11y_settings_change_event (GSettings *settings,
+                                     gpointer   keys,
+                                     int        n_keys,
+                                     gpointer   user_data)
+{
+  ClutterSettings *self = CLUTTER_SETTINGS (user_data);
+  ClutterSeat *seat = clutter_backend_get_default_seat (self->backend);
+
+  sync_pointer_a11y_settings (self, seat);
+
+  return FALSE;
+}
+
 static void
 load_initial_settings (ClutterSettings *self)
 {
   static const gchar *font_settings_path = "org.gnome.desktop.interface";
   static const gchar *mouse_settings_path = "org.gnome.desktop.peripherals.mouse";
+  static const char *mouse_a11y_settings_path = "org.gnome.desktop.a11y.mouse";
   GSettingsSchemaSource *source = g_settings_schema_source_get_default ();
   GSettingsSchema *schema;
 
@@ -477,6 +578,19 @@ load_initial_settings (ClutterSettings *self)
                             self);
         }
     }
+
+  schema = g_settings_schema_source_lookup (source, mouse_a11y_settings_path, TRUE);
+  if (!schema)
+    {
+      g_warning ("Failed to find schema: %s", mouse_settings_path);
+    }
+  else
+    {
+      self->mouse_a11y_settings = g_settings_new_full (schema, NULL, NULL);
+      g_signal_connect (self->mouse_a11y_settings, "change-event",
+                        G_CALLBACK (on_mouse_a11y_settings_change_event),
+                        self);
+    }
 }
 
 static void
@@ -490,6 +604,7 @@ clutter_settings_finalize (GObject *gobject)
 
   g_clear_object (&self->font_settings);
   g_clear_object (&self->mouse_settings);
+  g_clear_object (&self->mouse_a11y_settings);
 
   G_OBJECT_CLASS (clutter_settings_parent_class)->finalize (gobject);
 }
@@ -958,3 +1073,10 @@ _clutter_settings_set_backend (ClutterSettings *settings,
 
   load_initial_settings (settings);
 }
+
+void
+clutter_settings_ensure_pointer_a11y_settings (ClutterSettings *settings,
+                                               ClutterSeat     *seat)
+{
+  sync_pointer_a11y_settings (settings, seat);
+}
diff --git a/clutter/meson.build b/clutter/meson.build
index defa73f1c6..94f1eb0f19 100644
--- a/clutter/meson.build
+++ b/clutter/meson.build
@@ -81,6 +81,7 @@ endif
 clutter_deps = [
   clutter_pkg_deps,
   clutter_pkg_private_deps,
+  gsettings_desktop_schemas_dep,
   libmutter_cogl_dep,
   m_dep
 ]
diff --git a/src/backends/meta-input-settings.c b/src/backends/meta-input-settings.c
index 5a4ded9642..6448e65a2c 100644
--- a/src/backends/meta-input-settings.c
+++ b/src/backends/meta-input-settings.c
@@ -74,7 +74,6 @@ struct _MetaInputSettingsPrivate
   GSettings *trackball_settings;
   GSettings *keyboard_settings;
   GSettings *keyboard_a11y_settings;
-  GSettings *mouse_a11y_settings;
 
   GList *devices;
   GHashTable *mappable_devices;
@@ -152,7 +151,6 @@ meta_input_settings_dispose (GObject *object)
   g_clear_object (&priv->trackball_settings);
   g_clear_object (&priv->keyboard_settings);
   g_clear_object (&priv->keyboard_a11y_settings);
-  g_clear_object (&priv->mouse_a11y_settings);
   g_clear_pointer (&priv->mappable_devices, g_hash_table_unref);
   g_clear_pointer (&priv->current_tools, g_hash_table_unref);
 
@@ -1273,97 +1271,6 @@ meta_input_keyboard_a11y_settings_changed (GSettings  *settings,
   load_keyboard_a11y_settings (input_settings);
 }
 
-struct _pointer_a11y_settings_flags_pair {
-  const char *name;
-  ClutterPointerA11yFlags flag;
-} pointer_a11y_settings_flags_pair[] = {
-  { "secondary-click-enabled", CLUTTER_A11Y_SECONDARY_CLICK_ENABLED },
-  { "dwell-click-enabled",     CLUTTER_A11Y_DWELL_ENABLED },
-};
-
-static ClutterPointerA11yDwellDirection
-pointer_a11y_dwell_direction_from_setting (MetaInputSettings *input_settings,
-                                           const char        *key)
-{
-  MetaInputSettingsPrivate *priv = meta_input_settings_get_instance_private (input_settings);
-  GDesktopMouseDwellDirection dwell_gesture_direction;
-
-  dwell_gesture_direction = g_settings_get_enum (priv->mouse_a11y_settings, key);
-  switch (dwell_gesture_direction)
-    {
-    case G_DESKTOP_MOUSE_DWELL_DIRECTION_LEFT:
-      return CLUTTER_A11Y_DWELL_DIRECTION_LEFT;
-      break;
-    case G_DESKTOP_MOUSE_DWELL_DIRECTION_RIGHT:
-      return CLUTTER_A11Y_DWELL_DIRECTION_RIGHT;
-      break;
-    case G_DESKTOP_MOUSE_DWELL_DIRECTION_UP:
-      return CLUTTER_A11Y_DWELL_DIRECTION_UP;
-      break;
-    case G_DESKTOP_MOUSE_DWELL_DIRECTION_DOWN:
-      return CLUTTER_A11Y_DWELL_DIRECTION_DOWN;
-      break;
-    default:
-      break;
-    }
-  return CLUTTER_A11Y_DWELL_DIRECTION_NONE;
-}
-
-static void
-load_pointer_a11y_settings (MetaInputSettings  *input_settings)
-{
-  MetaInputSettingsPrivate *priv = meta_input_settings_get_instance_private (input_settings);
-  ClutterPointerA11ySettings pointer_a11y_settings;
-  GDesktopMouseDwellMode dwell_mode;
-  guint i;
-
-  clutter_seat_get_pointer_a11y_settings (CLUTTER_SEAT (priv->seat),
-                                          &pointer_a11y_settings);
-  pointer_a11y_settings.controls = 0;
-  for (i = 0; i < G_N_ELEMENTS (pointer_a11y_settings_flags_pair); i++)
-    {
-      if (g_settings_get_boolean (priv->mouse_a11y_settings, pointer_a11y_settings_flags_pair[i].name))
-        pointer_a11y_settings.controls |= pointer_a11y_settings_flags_pair[i].flag;
-    }
-
-  /* "secondary-click-time" is expressed in seconds */
-  pointer_a11y_settings.secondary_click_delay =
-    (1000 * g_settings_get_double (priv->mouse_a11y_settings, "secondary-click-time"));
-  /* "dwell-time" is expressed in seconds */
-  pointer_a11y_settings.dwell_delay =
-    (1000 * g_settings_get_double (priv->mouse_a11y_settings, "dwell-time"));
-  pointer_a11y_settings.dwell_threshold = g_settings_get_int (priv->mouse_a11y_settings,
-                                                              "dwell-threshold");
-
-  dwell_mode = g_settings_get_enum (priv->mouse_a11y_settings, "dwell-mode");
-  if (dwell_mode == G_DESKTOP_MOUSE_DWELL_MODE_WINDOW)
-    pointer_a11y_settings.dwell_mode = CLUTTER_A11Y_DWELL_MODE_WINDOW;
-  else
-    pointer_a11y_settings.dwell_mode = CLUTTER_A11Y_DWELL_MODE_GESTURE;
-
-  pointer_a11y_settings.dwell_gesture_single =
-    pointer_a11y_dwell_direction_from_setting (input_settings, "dwell-gesture-single");
-  pointer_a11y_settings.dwell_gesture_double =
-    pointer_a11y_dwell_direction_from_setting (input_settings, "dwell-gesture-double");
-  pointer_a11y_settings.dwell_gesture_drag =
-    pointer_a11y_dwell_direction_from_setting (input_settings, "dwell-gesture-drag");
-  pointer_a11y_settings.dwell_gesture_secondary =
-    pointer_a11y_dwell_direction_from_setting (input_settings, "dwell-gesture-secondary");
-
-  clutter_seat_set_pointer_a11y_settings (CLUTTER_SEAT (priv->seat),
-                                          &pointer_a11y_settings);
-}
-
-static void
-meta_input_mouse_a11y_settings_changed (GSettings  *settings,
-                                        const char *key,
-                                        gpointer    user_data)
-{
-  MetaInputSettings *input_settings = META_INPUT_SETTINGS (user_data);
-
-  load_pointer_a11y_settings (input_settings);
-}
-
 static GSettings *
 lookup_device_settings (ClutterInputDevice *device)
 {
@@ -1750,7 +1657,6 @@ meta_input_settings_constructed (GObject *object)
   check_mappable_devices (input_settings);
 
   load_keyboard_a11y_settings (input_settings);
-  load_pointer_a11y_settings (input_settings);
 }
 
 static void
@@ -1812,10 +1718,6 @@ meta_input_settings_init (MetaInputSettings *settings)
   g_signal_connect (priv->keyboard_a11y_settings, "changed",
                     G_CALLBACK (meta_input_keyboard_a11y_settings_changed), settings);
 
-  priv->mouse_a11y_settings = g_settings_new ("org.gnome.desktop.a11y.mouse");
-  g_signal_connect (priv->mouse_a11y_settings, "changed",
-                    G_CALLBACK (meta_input_mouse_a11y_settings_changed), settings);
-
   priv->mappable_devices =
     g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) device_mapping_info_free);
 


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