[gnome-settings-daemon] mouse: Add touchpad natural scroll



commit 31d66cc496fbd498ccb32c6006986c9c3bb83405
Author: Ondrej Holy <oholy redhat com>
Date:   Thu Aug 9 15:47:04 2012 +0200

    mouse: Add touchpad natural scroll
    
    https://bugzilla.gnome.org/show_bug.cgi?id=659498

 ...e.settings-daemon.peripherals.gschema.xml.in.in |    5 ++
 plugins/mouse/gsd-mouse-manager.c                  |   64 ++++++++++++++++++++
 2 files changed, 69 insertions(+), 0 deletions(-)
---
diff --git a/data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in b/data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in
index e082bfe..cbdf120 100644
--- a/data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in
+++ b/data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in
@@ -55,6 +55,11 @@
       <summary>Motion Threshold</summary>
       <description>Distance in pixels the pointer must move before accelerated mouse motion is activated. A value of -1 is the system default.</description>
     </key>
+    <key name="natural-scroll" type="b">
+      <default>false</default>
+      <summary>Natural scrolling</summary>
+      <description>Set this to TRUE to enable natural (reverse) scrolling for touchpads.</description>
+    </key>
   </schema>
   <schema gettext-domain="@GETTEXT_PACKAGE@" id="org.gnome.settings-daemon.peripherals.keyboard" path="/org/gnome/settings-daemon/peripherals/keyboard/">
     <key name="repeat" type="b">
diff --git a/plugins/mouse/gsd-mouse-manager.c b/plugins/mouse/gsd-mouse-manager.c
index 0ce9ec1..151fc6d 100644
--- a/plugins/mouse/gsd-mouse-manager.c
+++ b/plugins/mouse/gsd-mouse-manager.c
@@ -68,6 +68,7 @@
 #define KEY_SCROLL_METHOD                "scroll-method"
 #define KEY_TAP_TO_CLICK                 "tap-to-click"
 #define KEY_TOUCHPAD_ENABLED             "touchpad-enabled"
+#define KEY_NATURAL_SCROLL_ENABLED       "natural-scroll"
 
 /* Mouse settings */
 #define KEY_LOCATE_POINTER               "locate-pointer"
@@ -960,6 +961,67 @@ set_mouse_settings (GsdMouseManager *manager,
 }
 
 static void
+set_natural_scroll (GsdMouseManager *manager,
+                    GdkDevice       *device,
+                    gboolean         natural_scroll)
+{
+        XDevice *xdevice;
+        Atom scrolling_distance, act_type;
+        int rc, act_format;
+        unsigned long nitems, bytes_after;
+        unsigned char *data;
+        gint32 *ptr;
+
+        xdevice = open_gdk_device (device);
+        if (xdevice == NULL)
+                return;
+
+        if (!device_is_touchpad (xdevice)) {
+                XCloseDevice (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), xdevice);
+                return;
+        }
+
+        g_debug ("Trying to set %s for \"%s\"",
+                 natural_scroll ? "natural (reverse) scroll" : "normal scroll",
+                 gdk_device_get_name (device));
+
+        scrolling_distance = XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
+                                          "Synaptics Scrolling Distance", False);
+
+        gdk_error_trap_push ();
+        rc = XGetDeviceProperty (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), xdevice,
+                                 scrolling_distance, 0, 2, False,
+                                 XA_INTEGER, &act_type, &act_format, &nitems,
+                                 &bytes_after, &data);
+
+        if (rc == Success && act_type == XA_INTEGER && act_format == 32 && nitems >= 2) {
+                ptr = (gint32 *) 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 ()), xdevice,
+                                       scrolling_distance, XA_INTEGER, act_format,
+                                       PropModeReplace, data, nitems);
+        }
+
+        if (gdk_error_trap_pop ())
+                g_warning ("Error setting %s for \"%s\"",
+                           natural_scroll ? "natural (reverse) scroll" : "normal scroll",
+                           gdk_device_get_name (device));
+
+        if (rc == Success)
+                XFree (data);
+
+        XCloseDevice (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), xdevice);
+}
+
+static void
 mouse_callback (GSettings       *settings,
                 const gchar     *key,
                 GsdMouseManager *manager)
@@ -1039,6 +1101,8 @@ touchpad_callback (GSettings       *settings,
                         gboolean mouse_left_handed;
                         mouse_left_handed = g_settings_get_boolean (manager->priv->mouse_settings, KEY_LEFT_HANDED);
                         set_left_handed (manager, device, mouse_left_handed, get_touchpad_handedness (manager, mouse_left_handed));
+                } else if (g_str_equal (key, KEY_NATURAL_SCROLL_ENABLED)) {
+                        set_natural_scroll (manager, device, g_settings_get_boolean (settings, key));
                 }
         }
         g_list_free (devices);



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