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 <peter.hutterer@who-t.net>
This commit is contained in:
parent
53d1d5e347
commit
e14a84a718
3 changed files with 419 additions and 0 deletions
|
@ -41,6 +41,10 @@
|
|||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <dirent.h>
|
||||
#ifdef HAVE_XINPUT
|
||||
#include <X11/Xatom.h>
|
||||
#include <X11/extensions/XInput.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_XCURSOR
|
||||
#include <X11/Xcursor/Xcursor.h>
|
||||
|
@ -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 */
|
||||
|
|
|
@ -1161,6 +1161,289 @@
|
|||
<property name="tab_fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox3">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="border_width">12</property>
|
||||
<property name="spacing">18</property>
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox15">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label18">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0</property>
|
||||
<property name="label" translatable="yes"><b>General</b></property>
|
||||
<property name="use_markup">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox3">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label19">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0</property>
|
||||
<property name="label"> </property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkCheckButton" id="disable_w_typing_toggle">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">_Disable touchpad while typing</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="response_id">0</property>
|
||||
<property name="active">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox11">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label22">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0</property>
|
||||
<property name="label"> </property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkCheckButton" id="tap_to_click_toggle">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">Enable mouse _clicks with touchpad</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="response_id">0</property>
|
||||
<property name="active">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox19">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label34">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0</property>
|
||||
<property name="label" translatable="yes"><b>Scrolling</b></property>
|
||||
<property name="use_markup">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox15">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label35">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0</property>
|
||||
<property name="label"> </property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox23">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">0</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkRadioButton" id="scroll_disabled_radio">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label" translatable="yes">_Disabled</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
<property name="active">False</property>
|
||||
<property name="inconsistent">False</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkRadioButton" id="scroll_edge_radio">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label" translatable="yes">_Edge scrolling</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
<property name="active">False</property>
|
||||
<property name="inconsistent">False</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<property name="group">scroll_disabled_radio</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkRadioButton" id="scroll_twofinger_radio">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label" translatable="yes">Two-_finger scrolling</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
<property name="active">False</property>
|
||||
<property name="inconsistent">False</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<property name="group">scroll_disabled_radio</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox16">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label36">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0</property>
|
||||
<property name="label"> </property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkCheckButton" id="horiz_scroll_toggle">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">Enable _horizontal scrolling</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="response_id">0</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label4">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Touchpad</property>
|
||||
<property name="justify">GTK_JUSTIFY_CENTER</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="type">tab</property>
|
||||
<property name="position">2</property>
|
||||
<property name="tab_fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
|
|
14
configure.in
14
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 ==============
|
||||
|
|
Loading…
Add table
Reference in a new issue