[mutter/wip/rstrode/rhel-8.0.0: 111/117] backends/x11: Add disable while typing support for synaptics



commit b0067b45b989dcfac7f31ad15372b275fde8da88
Author: Rui Matos <tiagomatos gmail com>
Date:   Mon Oct 9 18:55:56 2017 +0200

    backends/x11: Add disable while typing support for synaptics
    
    This is basically a copy of the old g-s-d mouse plugin code to manage
    syndaemon when the synaptics driver is being used.

 src/backends/x11/meta-input-settings-x11.c | 112 +++++++++++++++++++++++++++++
 1 file changed, 112 insertions(+)
---
diff --git a/src/backends/x11/meta-input-settings-x11.c b/src/backends/x11/meta-input-settings-x11.c
index 5a82edbe6..33abd0c72 100644
--- a/src/backends/x11/meta-input-settings-x11.c
+++ b/src/backends/x11/meta-input-settings-x11.c
@@ -35,6 +35,9 @@
 #ifdef HAVE_LIBGUDEV
 #include <gudev/gudev.h>
 #endif
+#ifdef __linux
+#include <sys/prctl.h>
+#endif
 
 #include <meta/errors.h>
 #include "backends/meta-logical-monitor.h"
@@ -44,6 +47,8 @@ typedef struct _MetaInputSettingsX11Private
 #ifdef HAVE_LIBGUDEV
   GUdevClient *udev_client;
 #endif
+  gboolean syndaemon_spawned;
+  GPid syndaemon_pid;
 } MetaInputSettingsX11Private;
 
 G_DEFINE_TYPE_WITH_PRIVATE (MetaInputSettingsX11, meta_input_settings_x11,
@@ -332,6 +337,107 @@ change_synaptics_speed (ClutterInputDevice *device,
   XCloseDevice (xdisplay, xdevice);
 }
 
+/* Ensure that syndaemon dies together with us, to avoid running several of
+ * them */
+static void
+setup_syndaemon (gpointer user_data)
+{
+#ifdef __linux
+  prctl (PR_SET_PDEATHSIG, SIGHUP);
+#endif
+}
+
+static gboolean
+have_program_in_path (const char *name)
+{
+  gchar *path;
+  gboolean result;
+
+  path = g_find_program_in_path (name);
+  result = (path != NULL);
+  g_free (path);
+  return result;
+}
+
+static void
+syndaemon_died (GPid     pid,
+                gint     status,
+                gpointer user_data)
+{
+  MetaInputSettingsX11 *settings_x11 = META_INPUT_SETTINGS_X11 (user_data);
+  MetaInputSettingsX11Private *priv =
+    meta_input_settings_x11_get_instance_private (settings_x11);
+  GError *error = NULL;
+
+  if (!g_spawn_check_exit_status (status, &error))
+    {
+      if ((WIFSIGNALED (status) && WTERMSIG (status) != SIGHUP) ||
+          error->domain == G_SPAWN_EXIT_ERROR)
+        g_warning ("Syndaemon exited unexpectedly: %s", error->message);
+      g_error_free (error);
+    }
+
+  g_spawn_close_pid (pid);
+  priv->syndaemon_spawned = FALSE;
+}
+
+static void
+set_synaptics_disable_w_typing (MetaInputSettings *settings,
+                                gboolean           state)
+{
+  MetaInputSettingsX11 *settings_x11 = META_INPUT_SETTINGS_X11 (settings);
+  MetaInputSettingsX11Private *priv =
+    meta_input_settings_x11_get_instance_private (settings_x11);
+
+  if (state)
+    {
+      GError *error = NULL;
+      GPtrArray *args;
+
+      if (priv->syndaemon_spawned)
+        return;
+
+      if (!have_program_in_path ("syndaemon"))
+        return;
+
+      args = g_ptr_array_new ();
+
+      g_ptr_array_add (args, "syndaemon");
+      g_ptr_array_add (args, "-i");
+      g_ptr_array_add (args, "1.0");
+      g_ptr_array_add (args, "-t");
+      g_ptr_array_add (args, "-K");
+      g_ptr_array_add (args, "-R");
+      g_ptr_array_add (args, NULL);
+
+      /* we must use G_SPAWN_DO_NOT_REAP_CHILD to avoid
+       * double-forking, otherwise syndaemon will immediately get
+       * killed again through (PR_SET_PDEATHSIG when the intermediate
+       * process dies */
+      g_spawn_async (g_get_home_dir (), (char **) args->pdata, NULL,
+                     G_SPAWN_SEARCH_PATH|G_SPAWN_DO_NOT_REAP_CHILD, setup_syndaemon, NULL,
+                     &priv->syndaemon_pid, &error);
+
+      priv->syndaemon_spawned = (error == NULL);
+      g_ptr_array_free (args, TRUE);
+
+      if (error)
+        {
+          g_warning ("Failed to launch syndaemon: %s", error->message);
+          g_error_free (error);
+        }
+      else
+        {
+          g_child_watch_add (priv->syndaemon_pid, syndaemon_died, settings);
+        }
+    }
+  else if (priv->syndaemon_spawned)
+    {
+      kill (priv->syndaemon_pid, SIGHUP);
+      priv->syndaemon_spawned = FALSE;
+    }
+}
+
 static void
 meta_input_settings_x11_set_send_events (MetaInputSettings        *settings,
                                          ClutterInputDevice       *device,
@@ -456,6 +562,12 @@ meta_input_settings_x11_set_disable_while_typing (MetaInputSettings  *settings,
 {
   guchar value = (enabled) ? 1 : 0;
 
+  if (is_device_synaptics (device))
+    {
+      set_synaptics_disable_w_typing (settings, enabled);
+      return;
+    }
+
   change_property (device, "libinput Disable While Typing Enabled",
                    XA_INTEGER, 8, &value, 1);
 }


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