From f40328fdc38313b535d14202b87f517117f845c4 Mon Sep 17 00:00:00 2001 From: Clement Lefebvre Date: Thu, 3 Sep 2015 15:08:22 +0100 Subject: Touchpad: Added support for natural scrolling (along with minor changes to fix a few warnings and make var names more consistent with one another) --- ...org.mate.peripherals-touchpad.gschema.xml.in.in | 5 ++ plugins/mouse/msd-mouse-manager.c | 76 +++++++++++++++++++--- 2 files changed, 72 insertions(+), 9 deletions(-) diff --git a/data/org.mate.peripherals-touchpad.gschema.xml.in.in b/data/org.mate.peripherals-touchpad.gschema.xml.in.in index 64e630f..8cfe8d4 100644 --- a/data/org.mate.peripherals-touchpad.gschema.xml.in.in +++ b/data/org.mate.peripherals-touchpad.gschema.xml.in.in @@ -20,6 +20,11 @@ <_summary>Enable horizontal scrolling <_description>Set this to TRUE to allow horizontal scrolling by the same method selected with the scroll_method key. + + false + <_summary>Natural scrolling + <_description>Set this to true to enable natural (reverse) scrolling for touchpads + true <_summary>Enable touchpad diff --git a/plugins/mouse/msd-mouse-manager.c b/plugins/mouse/msd-mouse-manager.c index 3fd7430..95b0073 100644 --- a/plugins/mouse/msd-mouse-manager.c +++ b/plugins/mouse/msd-mouse-manager.c @@ -63,9 +63,9 @@ #define KEY_TOUCHPAD_DISABLE_W_TYPING "disable-while-typing" #ifdef HAVE_X11_EXTENSIONS_XINPUT_H -#define KEY_TWO_FINGER_CLICK "two-finger-click" -#define KEY_THREE_FINGER_CLICK "three-finger-click" - +#define KEY_TOUCHPAD_TWO_FINGER_CLICK "two-finger-click" +#define KEY_TOUCHPAD_THREE_FINGER_CLICK "three-finger-click" +#define KEY_TOUCHPAD_NATURAL_SCROLL "natural-scroll" #define KEY_TOUCHPAD_TAP_TO_CLICK "tap-to-click" #define KEY_TOUCHPAD_ONE_FINGER_TAP "tap-button-one-finger" #define KEY_TOUCHPAD_TWO_FINGER_TAP "tap-button-two-finger" @@ -101,6 +101,7 @@ static void set_mouse_settings (MsdMouseManager *manager); #ifdef HAVE_X11_EXTENSIONS_XINPUT_H static void set_tap_to_click (MsdMouseManager * manager); static void set_click_actions (MsdMouseManager * manager); +static void set_natural_scroll (MsdMouseManager * manager); #endif G_DEFINE_TYPE (MsdMouseManager, msd_mouse_manager, G_TYPE_OBJECT) @@ -693,14 +694,14 @@ set_click_actions (MsdMouseManager * manager) Atom prop, type; if (devicelist == NULL) - return 0; + return; prop = XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), "Synaptics Click Action", False); if (!prop) return; - gint enable_two_finger_click = g_settings_get_int (manager->priv->settings_touchpad, KEY_TWO_FINGER_CLICK); - gint enable_three_finger_click = g_settings_get_int (manager->priv->settings_touchpad, KEY_THREE_FINGER_CLICK); + gint enable_two_finger_click = g_settings_get_int (manager->priv->settings_touchpad, KEY_TOUCHPAD_TWO_FINGER_CLICK); + gint enable_three_finger_click = g_settings_get_int (manager->priv->settings_touchpad, KEY_TOUCHPAD_THREE_FINGER_CLICK); for (i = 0; i < numdevices; i++) { if ((device = device_is_touchpad (devicelist[i]))) { @@ -729,6 +730,59 @@ set_click_actions (MsdMouseManager * manager) XFreeDeviceList (devicelist); } +static void +set_natural_scroll (MsdMouseManager * manager) +{ + int numdevices, i, format, rc; + unsigned long nitems, bytes_after; + XDeviceInfo *devicelist = XListInputDevices (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), &numdevices); + XDevice * device; + unsigned char* data; + glong *ptr; + Atom prop, type; + + if (devicelist == NULL) + return; + + prop = XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), "Synaptics Scrolling Distance", False); + if (!prop) + return; + + gboolean natural_scroll = g_settings_get_boolean (manager->priv->settings_touchpad, KEY_TOUCHPAD_NATURAL_SCROLL); + + for (i = 0; i < numdevices; i++) { + if ((device = device_is_touchpad (devicelist[i]))) { + g_debug ("Trying to set %s for \"%s\"", natural_scroll ? "natural (reverse) scroll" : "normal scroll", devicelist[i].name); + gdk_error_trap_push (); + rc = XGetDeviceProperty (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), device, prop, 0, 2, + False, XA_INTEGER, &type, &format, &nitems, + &bytes_after, &data); + + if (rc == Success && type == XA_INTEGER && format == 32 && nitems >= 2) { + ptr = (glong *) data; + if (natural_scroll) { + ptr[0] = -abs(ptr[0]); + ptr[1] = -abs(ptr[1]); + } else { + ptr[0] = abs(ptr[0]); + ptr[1] = abs(ptr[1]); + } + + XChangeDeviceProperty (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), device, prop, XA_INTEGER, 32, PropModeReplace, data, nitems); + } + + if (rc == Success) + XFree (data); + XCloseDevice (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), device); + if (gdk_error_trap_pop ()) { + g_warning ("Error in setting natural scroll on \"%s\"", devicelist[i].name); + continue; + } + } + } + XFreeDeviceList (devicelist); +} + static int set_horiz_scroll (gboolean state) { @@ -1009,6 +1063,7 @@ set_mouse_settings (MsdMouseManager *manager) set_click_actions (manager); set_edge_scroll (g_settings_get_int (manager->priv->settings_touchpad, KEY_TOUCHPAD_SCROLL_METHOD)); set_horiz_scroll (g_settings_get_boolean (manager->priv->settings_touchpad, KEY_TOUCHPAD_PAD_HORIZ_SCROLL)); + set_natural_scroll (manager); set_touchpad_enabled (g_settings_get_boolean (manager->priv->settings_touchpad, KEY_TOUCHPAD_ENABLED)); #endif } @@ -1026,12 +1081,12 @@ mouse_callback (GSettings *settings, set_motion_threshold (manager, g_settings_get_int (settings, key)); } else if (g_strcmp0 (key, KEY_TOUCHPAD_DISABLE_W_TYPING) == 0) { set_disable_w_typing (manager, g_settings_get_boolean (settings, key)); - } else if (g_str_equal (key, KEY_MIDDLE_BUTTON_EMULATION)) { - set_middle_button (manager, g_settings_get_boolean (settings, key)); + } else if (g_str_equal (key, KEY_MIDDLE_BUTTON_EMULATION)) { + set_middle_button (manager, g_settings_get_boolean (settings, key)); #ifdef HAVE_X11_EXTENSIONS_XINPUT_H } else if (g_strcmp0 (key, KEY_TOUCHPAD_TAP_TO_CLICK) == 0) { set_tap_to_click (manager); - } else if (g_str_equal (key, KEY_TWO_FINGER_CLICK) || g_str_equal (key, KEY_THREE_FINGER_CLICK)) { + } else if (g_str_equal (key, KEY_TOUCHPAD_TWO_FINGER_CLICK) || g_str_equal (key, KEY_TOUCHPAD_THREE_FINGER_CLICK)) { set_click_actions(manager); } else if (g_strcmp0 (key, KEY_TOUCHPAD_ONE_FINGER_TAP) == 0) { set_tap_to_click (manager); @@ -1042,6 +1097,8 @@ mouse_callback (GSettings *settings, } else if (g_strcmp0 (key, KEY_TOUCHPAD_SCROLL_METHOD) == 0) { set_edge_scroll (g_settings_get_int (settings, key)); set_horiz_scroll (g_settings_get_boolean (settings, KEY_TOUCHPAD_PAD_HORIZ_SCROLL)); + } else if (g_str_equal (key, KEY_TOUCHPAD_NATURAL_SCROLL)) { + set_natural_scroll (manager); } else if (g_strcmp0 (key, KEY_TOUCHPAD_PAD_HORIZ_SCROLL) == 0) { set_horiz_scroll (g_settings_get_boolean (settings, key)); #endif @@ -1103,6 +1160,7 @@ msd_mouse_manager_idle_cb (MsdMouseManager *manager) set_click_actions (manager); set_edge_scroll (g_settings_get_int (manager->priv->settings_touchpad, KEY_TOUCHPAD_SCROLL_METHOD)); set_horiz_scroll (g_settings_get_boolean (manager->priv->settings_touchpad, KEY_TOUCHPAD_PAD_HORIZ_SCROLL)); + set_natural_scroll (manager); set_touchpad_enabled (g_settings_get_boolean (manager->priv->settings_touchpad, KEY_TOUCHPAD_ENABLED)); #endif -- cgit v1.2.1