From e14a84a718d9882d320de1f359c0547836a9b4e3 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 2 Apr 2009 13:50:10 +1000 Subject: [PATCH] Support touchpad configuration through device properties. This patch is based on Ubuntu's touchpad configuration. It adds a new tab to gnome-mouse-properties that allows to enable/disable the touchpad, tapping and select between edge scrolling and two-finger scrolling. It adds the following gconf keys: /desktop/gnome/peripherals/touchpad/disable_while_typing (boolean) /desktop/gnome/peripherals/touchpad/tap_to_click (boolean) /desktop/gnome/peripherals/touchpad/horiz_scroll_enabled (boolean) /desktop/gnome/peripherals/touchpad/scroll_method (integer) [0,1,2 for disabled, edge and two-finger scrolling, respectively] Signed-off-by: Peter Hutterer --- capplets/mouse/gnome-mouse-properties.c | 122 +++++++++ capplets/mouse/gnome-mouse-properties.glade | 283 ++++++++++++++++++++ configure.in | 14 + 3 files changed, 419 insertions(+) diff --git a/capplets/mouse/gnome-mouse-properties.c b/capplets/mouse/gnome-mouse-properties.c index dd81d0b02..2e39872b6 100644 --- a/capplets/mouse/gnome-mouse-properties.c +++ b/capplets/mouse/gnome-mouse-properties.c @@ -41,6 +41,10 @@ #include #include #include +#ifdef HAVE_XINPUT +#include +#include +#endif #ifdef HAVE_XCURSOR #include @@ -312,6 +316,99 @@ left_handed_to_gconf (GConfPropertyEditor *peditor, return new_value; } +static void +scrollmethod_radio_button_release_event (GtkWidget *widget, + GdkEventButton *event, + GladeXML *dialog) +{ + gtk_widget_set_sensitive (WID ("horiz_scroll_toggle"), + (widget != WID ("scroll_disabled_radio"))); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE); +} + +static GConfValue * +scroll_method_from_gconf (GConfPropertyEditor *peditor, + const GConfValue *value) +{ + GConfValue *new_value; + + new_value = gconf_value_new (GCONF_VALUE_INT); + + gconf_value_set_int (new_value, gconf_value_get_int (value)); + + return new_value; +} + +static GConfValue * +scroll_method_to_gconf (GConfPropertyEditor *peditor, + const GConfValue *value) +{ + GConfValue *new_value; + + new_value = gconf_value_new (GCONF_VALUE_INT); + + gconf_value_set_int (new_value, gconf_value_get_int (value)); + + return new_value; +} + +static gboolean +find_synaptics (void) +{ + gboolean ret = FALSE; +#ifdef HAVE_XINPUT + int numdevices, i; + XDeviceInfo *devicelist; + Atom realtype, prop; + int realformat; + unsigned long nitems, bytes_after; + unsigned char *data; + XExtensionVersion *version; + + /* Input device properties require version 1.5 or higher */ + version = XGetExtensionVersion (GDK_DISPLAY (), "XInputExtension"); + if (!version->present || + (version->major_version * 1000 + version->minor_version) < 1005) { + XFree (version); + return False; + } + + prop = XInternAtom (GDK_DISPLAY (), "Synaptics Off", True); + if (!prop) + return False; + + devicelist = XListInputDevices (GDK_DISPLAY (), &numdevices); + for (i = 0; i < numdevices; i++) { + if (devicelist[i].use != IsXExtensionPointer) + continue; + + gdk_error_trap_push(); + XDevice *device = XOpenDevice (GDK_DISPLAY (), + devicelist[i].id); + if (gdk_error_trap_pop ()) + continue; + + gdk_error_trap_push (); + if ((XGetDeviceProperty (GDK_DISPLAY (), device, prop, 0, 1, False, + XA_INTEGER, &realtype, &realformat, &nitems, + &bytes_after, &data) == Success) && (realtype != None)) { + XFree (data); + ret = TRUE; + } + gdk_error_trap_pop (); + + XCloseDevice (GDK_DISPLAY (), device); + + if (ret) + break; + } + + XFree (version); + XFreeDeviceList (devicelist); +#endif + return ret; +} + /* Set up the property editors in the dialog. */ static void setup_dialog (GladeXML *dialog, GConfChangeSet *changeset) @@ -362,6 +459,31 @@ setup_dialog (GladeXML *dialog, GConfChangeSet *changeset) (changeset, "/desktop/gnome/peripherals/mouse/drag_threshold", WID ("drag_threshold_scale"), "conv-to-widget-cb", drag_threshold_from_gconf, NULL); + + /* Trackpad page */ + if (find_synaptics () == FALSE) + gtk_notebook_remove_page (GTK_NOTEBOOK (WID ("prefs_widget")), -1); + else { + peditor = gconf_peditor_new_boolean + (changeset, "/desktop/gnome/peripherals/touchpad/disable_while_typing", WID ("disable_w_typing_toggle"), NULL); + peditor = gconf_peditor_new_boolean + (changeset, "/desktop/gnome/peripherals/touchpad/tap_to_click", WID ("tap_to_click_toggle"), NULL); + peditor = gconf_peditor_new_boolean + (changeset, "/desktop/gnome/peripherals/touchpad/horiz_scroll_enabled", WID ("horiz_scroll_toggle"), NULL); + radio = GTK_RADIO_BUTTON (WID ("scroll_disabled_radio")); + peditor = gconf_peditor_new_select_radio + (changeset, "/desktop/gnome/peripherals/touchpad/scroll_method", gtk_radio_button_get_group (radio), + "conv-to-widget-cb", scroll_method_from_gconf, + "conv-from-widget-cb", scroll_method_to_gconf, + NULL); + g_signal_connect (WID ("scroll_disabled_radio"), "button_release_event", + G_CALLBACK (scrollmethod_radio_button_release_event), dialog); + g_signal_connect (WID ("scroll_edge_radio"), "button_release_event", + G_CALLBACK (scrollmethod_radio_button_release_event), dialog); + g_signal_connect (WID ("scroll_twofinger_radio"), "button_release_event", + G_CALLBACK (scrollmethod_radio_button_release_event), dialog); + } + } /* Construct the dialog */ diff --git a/capplets/mouse/gnome-mouse-properties.glade b/capplets/mouse/gnome-mouse-properties.glade index 38c89f22e..834494730 100644 --- a/capplets/mouse/gnome-mouse-properties.glade +++ b/capplets/mouse/gnome-mouse-properties.glade @@ -1161,6 +1161,289 @@ False + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 12 + 18 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 6 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + 0 + <b>General</b> + True + + + False + False + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + 0 + + + + False + False + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + _Disable touchpad while typing + True + 0 + True + True + + + 1 + + + + + False + False + 1 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + 0 + + + + False + False + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Enable mouse _clicks with touchpad + True + 0 + True + True + + + 1 + + + + + False + False + 2 + + + + + False + False + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 6 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + 0 + <b>Scrolling</b> + True + + + False + False + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + 0 + + + + False + False + + + + + True + False + 0 + + + + True + True + _Disabled + True + GTK_RELIEF_NORMAL + True + False + False + True + + + 0 + False + False + + + + + + True + True + _Edge scrolling + True + GTK_RELIEF_NORMAL + True + False + False + True + scroll_disabled_radio + + + 0 + False + False + + + + + + True + True + Two-_finger scrolling + True + GTK_RELIEF_NORMAL + True + False + False + True + scroll_disabled_radio + + + 0 + False + False + + + + + 1 + + + + + False + False + 1 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + 0 + + + + False + False + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Enable _horizontal scrolling + True + 0 + True + + + 1 + + + + + False + False + 2 + + + + + False + False + 1 + + + + + 2 + + + + + True + Touchpad + GTK_JUSTIFY_CENTER + + + tab + 2 + False + + 1 diff --git a/configure.in b/configure.in index cb83a8544..0df03507a 100644 --- a/configure.in +++ b/configure.in @@ -188,6 +188,20 @@ fi CAPPLET_LIBS="$CAPPLET_LIBS $XCURSOR_LIBS" +dnl ============================================= +dnl X Input library >= 1.2 with property support +dnl ============================================= +have_xinput=no +PKG_CHECK_MODULES(XINPUT, [xi >= 1.2], + have_xinput=yes + AC_DEFINE(HAVE_XINPUT, 1, [Define if the XInput extension is available]), + have_xinput=no) +AM_CONDITIONAL(HAVE_XINPUT, [test $have_xinput=yes]) +AC_SUBST(XINPUT_CFLAGS) +AC_SUBST(XINPUT_LIBS) + +CAPPLET_LIBS="$CAPPLET_LIBS $XINPUT_LIBS" + dnl ============== dnl gswitchit dnl ==============