From f79a148d978f792848f4e85b143bf94edc09e5ec Mon Sep 17 00:00:00 2001 From: Daniel van Vugt Date: Sun, 18 Mar 2018 12:56:36 -0400 Subject: [PATCH] backends/x11: Support input-synaptics, if present. Add support for configuring the Xorg synaptics touchpad driver. Turns out it's very simple to support both libinput and synaptics simultaneously, both under the heading of XI2. Bug-Ubuntu: https://launchpad.net/bugs/1686081 Forwarded: https://gitlab.gnome.org/GNOME/mutter/merge_requests/37 Last-Update: 2018-03-16 Gbp-Pq: Name synaptics-support.patch --- .../clutter/x11/clutter-device-manager-xi2.c | 15 +- src/backends/x11/meta-input-settings-x11.c | 150 ++++++++++++++++-- 2 files changed, 148 insertions(+), 17 deletions(-) diff --git a/clutter/clutter/x11/clutter-device-manager-xi2.c b/clutter/clutter/x11/clutter-device-manager-xi2.c index 62f5583..b22982a 100644 --- a/clutter/clutter/x11/clutter-device-manager-xi2.c +++ b/clutter/clutter/x11/clutter-device-manager-xi2.c @@ -267,8 +267,9 @@ is_touch_device (XIAnyClassInfo **classes, } static gboolean -is_touchpad_device (ClutterBackendX11 *backend_x11, - XIDeviceInfo *info) +has_8bit_property (ClutterBackendX11 *backend_x11, + XIDeviceInfo *info, + const char *name) { gulong nitems, bytes_after; guint32 *data = NULL; @@ -276,7 +277,7 @@ is_touchpad_device (ClutterBackendX11 *backend_x11, Atom type; Atom prop; - prop = XInternAtom (backend_x11->xdpy, "libinput Tapping Enabled", True); + prop = XInternAtom (backend_x11->xdpy, name, True); if (prop == None) return FALSE; @@ -297,6 +298,14 @@ is_touchpad_device (ClutterBackendX11 *backend_x11, return TRUE; } +static gboolean +is_touchpad_device (ClutterBackendX11 *backend_x11, + XIDeviceInfo *info) +{ + return has_8bit_property (backend_x11, info, "libinput Tapping Enabled") || + has_8bit_property (backend_x11, info, "Synaptics Off"); +} + static gboolean get_device_ids (ClutterBackendX11 *backend_x11, XIDeviceInfo *info, diff --git a/src/backends/x11/meta-input-settings-x11.c b/src/backends/x11/meta-input-settings-x11.c index 9687fb3..43752df 100644 --- a/src/backends/x11/meta-input-settings-x11.c +++ b/src/backends/x11/meta-input-settings-x11.c @@ -169,8 +169,6 @@ meta_input_settings_x11_set_send_events (MetaInputSettings *settings, available = get_property (device, "libinput Send Events Modes Available", XA_INTEGER, 8, 2); - if (!available) - return; switch (mode) { @@ -184,6 +182,11 @@ meta_input_settings_x11_set_send_events (MetaInputSettings *settings, break; } + change_property (device, "Synaptics Off", XA_INTEGER, 8, &values, 1); + + if (!available) + return; + if ((values[0] && !available[0]) || (values[1] && !available[1])) g_warning ("Device '%s' does not support sendevents mode %d\n", clutter_input_device_get_device_name (device), mode); @@ -217,11 +220,23 @@ meta_input_settings_x11_set_speed (MetaInputSettings *settings, { MetaBackend *backend = meta_get_backend (); Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend)); - gfloat value = speed; + gfloat *accel = get_property (device, "libinput Accel Speed", + XInternAtom (xdisplay, "FLOAT", False), 32, 1); - change_property (device, "libinput Accel Speed", - XInternAtom (xdisplay, "FLOAT", False), - 32, &value, 1); + if (accel) + { + *accel = speed; /* Sounds confused, but libinput is confused. */ + change_property (device, "libinput Accel Speed", + XInternAtom (xdisplay, "FLOAT", False), 32, accel, 1); + meta_XFree (accel); + } + else + { + gfloat scale = (speed <= -1.0) ? 1.0 : (speed + 1.0) * 12.5; + + change_property (device, "Device Accel Velocity Scaling", + XInternAtom (xdisplay, "FLOAT", False), 32, &scale, 1); + } } static void @@ -259,6 +274,9 @@ meta_input_settings_x11_set_disable_while_typing (MetaInputSettings *settings, change_property (device, "libinput Disable While Typing Enabled", XA_INTEGER, 8, &value, 1); + + change_property (device, "Synaptics Palm Detection", + XA_INTEGER, 8, &value, 1); } static void @@ -267,9 +285,13 @@ meta_input_settings_x11_set_tap_enabled (MetaInputSettings *settings, gboolean enabled) { guchar value = (enabled) ? 1 : 0; + gint32 tap_time = (enabled) ? 180 : 0; change_property (device, "libinput Tapping Enabled", XA_INTEGER, 8, &value, 1); + + change_property (device, "Synaptics Tap Time", + XA_INTEGER, 32, &tap_time, 1); } static void @@ -281,6 +303,9 @@ meta_input_settings_x11_set_tap_and_drag_enabled (MetaInputSettings *settings, change_property (device, "libinput Tapping Drag Enabled", XA_INTEGER, 8, &value, 1); + + change_property (device, "Synaptics Gestures", + XA_INTEGER, 8, &value, 1); } static void @@ -288,10 +313,22 @@ meta_input_settings_x11_set_invert_scroll (MetaInputSettings *settings, ClutterInputDevice *device, gboolean inverted) { - guchar value = (inverted) ? 1 : 0; + gint32 *scroll_dist = get_property (device, "Synaptics Scrolling Distance", + XA_INTEGER, 32, 2); + if (scroll_dist) + { + scroll_dist[0] = inverted ? -ABS (scroll_dist[0]) : ABS (scroll_dist[0]); + change_property (device, "Synaptics Scrolling Distance", + XA_INTEGER, 32, scroll_dist, 2); + meta_XFree (scroll_dist); + } + else + { + guchar value = (inverted) ? 1 : 0; - change_property (device, "libinput Natural Scrolling Enabled", - XA_INTEGER, 8, &value, 1); + change_property (device, "libinput Natural Scrolling Enabled", + XA_INTEGER, 8, &value, 1); + } } static void @@ -303,6 +340,16 @@ meta_input_settings_x11_set_edge_scroll (MetaInputSettings *settings, guchar *current = NULL; guchar *available = NULL; + current = get_property (device, "Synaptics Edge Scrolling", + XA_INTEGER, 8, 3); + if (current) + { + current[0] = current[1] = !!edge_scroll_enabled; + change_property (device, "Synaptics Edge Scrolling", + XA_INTEGER, 8, current, 3); + goto out; + } + available = get_property (device, "libinput Scroll Methods Available", XA_INTEGER, 8, SCROLL_METHOD_NUM_FIELDS); if (!available || !available[SCROLL_METHOD_FIELD_EDGE]) @@ -332,6 +379,16 @@ meta_input_settings_x11_set_two_finger_scroll (MetaInputSettings *set guchar *current = NULL; guchar *available = NULL; + current = get_property (device, "Synaptics Two-Finger Scrolling", + XA_INTEGER, 8, 2); + if (current) + { + current[0] = current[1] = !!two_finger_scroll_enabled; + change_property (device, "Synaptics Two-Finger Scrolling", + XA_INTEGER, 8, current, 2); + goto out; + } + available = get_property (device, "libinput Scroll Methods Available", XA_INTEGER, 8, SCROLL_METHOD_NUM_FIELDS); if (!available || !available[SCROLL_METHOD_FIELD_2FG]) @@ -359,10 +416,19 @@ meta_input_settings_x11_has_two_finger_scroll (MetaInputSettings *settings, guchar *available = NULL; gboolean has_two_finger = TRUE; - available = get_property (device, "libinput Scroll Methods Available", - XA_INTEGER, 8, SCROLL_METHOD_NUM_FIELDS); - if (!available || !available[SCROLL_METHOD_FIELD_2FG]) - has_two_finger = FALSE; + available = get_property (device, "Synaptics Two-Finger Scrolling", + XA_INTEGER, 8, 2); + if (available) + { + has_two_finger = available[0] || available[1]; + } + else + { + available = get_property (device, "libinput Scroll Methods Available", + XA_INTEGER, 8, SCROLL_METHOD_NUM_FIELDS); + if (!available || !available[SCROLL_METHOD_FIELD_2FG]) + has_two_finger = FALSE; + } meta_XFree (available); return has_two_finger; @@ -377,6 +443,58 @@ meta_input_settings_x11_set_scroll_button (MetaInputSettings *settings, XA_INTEGER, 32, &button, 1); } +static void +meta_input_settings_x11_set_click_method_synaptics (MetaInputSettings *settings, + ClutterInputDevice *device, + GDesktopTouchpadClickMethod mode) +{ + /* { RT corner, RB, LT, LB, 1 finger, 2 fingers, 3 fingers } */ + guchar tap_action_default[7] = { 2, 3, 0, 0, 1, 3, 0 }; + guchar tap_action_areas[7] = { 2, 3, 0, 0, 1, 0, 0 }; + guchar tap_action_fingers[7] = { 0, 0, 0, 0, 1, 3, 2 }; + guchar tap_action_none[7] = { 0, 0, 0, 0, 1, 0, 0 }; + guchar *tap_action = tap_action_default; + + /* TODO On startup save the default value of 'Synaptics Soft Button Areas', + but save it where? */ + gint32 zero_button_areas[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + gint32 *button_areas_known = NULL; + + switch (mode) + { + case G_DESKTOP_TOUCHPAD_CLICK_METHOD_DEFAULT: + tap_action = tap_action_default; + /* Doing nothing right now will give the correct default, unless changed + during the session */ + break; + case G_DESKTOP_TOUCHPAD_CLICK_METHOD_NONE: + tap_action = tap_action_none; + button_areas_known = zero_button_areas; + break; + case G_DESKTOP_TOUCHPAD_CLICK_METHOD_AREAS: + tap_action = tap_action_areas; + /* Doing nothing right now will give the correct default, unless changed + during the session */ + break; + case G_DESKTOP_TOUCHPAD_CLICK_METHOD_FINGERS: + tap_action = tap_action_fingers; + button_areas_known = zero_button_areas; + break; + default: + g_assert_not_reached (); + return; + } + + change_property (device, "Synaptics Tap Action", + XA_INTEGER, 8, tap_action, 7); + change_property (device, "Synaptics Click Action", + XA_INTEGER, 8, tap_action + 4, 3); + + if (button_areas_known) + change_property (device, "Synaptics Soft Button Areas", + XA_INTEGER, 32, button_areas_known, 8); +} + static void meta_input_settings_x11_set_click_method (MetaInputSettings *settings, ClutterInputDevice *device, @@ -388,7 +506,11 @@ meta_input_settings_x11_set_click_method (MetaInputSettings *settings, available = get_property (device, "libinput Click Methods Available", XA_INTEGER, 8, 2); if (!available) - return; + { + meta_input_settings_x11_set_click_method_synaptics (settings, device, + mode); + return; + } switch (mode) { -- 2.30.2