settings: Support mouse and trackball accel profile
Support changing the mouse and trackball acceleration profile. This makes it possible to for example disable pointer acceleration by choosing the 'flat' profile. This adds an optional dependency on gudev. Gudev is used by the X11 backend to detect whether a device is a mouse or not. Without gudev support, the accel profile settings has have effect for mouse devices. Trackball still uses the "strstr" approach, since udev doesn't support tagging devices as trackball devices yet. https://bugzilla.gnome.org/show_bug.cgi?id=769179
This commit is contained in:
@ -31,10 +31,21 @@
|
||||
#include <X11/Xatom.h>
|
||||
#include <X11/extensions/XInput2.h>
|
||||
#include <X11/XKBlib.h>
|
||||
#ifdef HAVE_LIBGUDEV
|
||||
#include <gudev/gudev.h>
|
||||
#endif
|
||||
|
||||
#include <meta/errors.h>
|
||||
|
||||
G_DEFINE_TYPE (MetaInputSettingsX11, meta_input_settings_x11, META_TYPE_INPUT_SETTINGS)
|
||||
typedef struct _MetaInputSettingsX11Private
|
||||
{
|
||||
#ifdef HAVE_LIBGUDEV
|
||||
GUdevClient *udev_client;
|
||||
#endif
|
||||
} MetaInputSettingsX11Private;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (MetaInputSettingsX11, meta_input_settings_x11,
|
||||
META_TYPE_INPUT_SETTINGS)
|
||||
|
||||
enum {
|
||||
SCROLL_METHOD_FIELD_2FG,
|
||||
@ -360,6 +371,135 @@ meta_input_settings_x11_set_keyboard_repeat (MetaInputSettings *settings,
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
has_udev_property (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
const char *property_name)
|
||||
{
|
||||
#ifdef HAVE_LIBGUDEV
|
||||
MetaInputSettingsX11 *settings_x11 = META_INPUT_SETTINGS_X11 (settings);
|
||||
MetaInputSettingsX11Private *priv =
|
||||
meta_input_settings_x11_get_instance_private (settings_x11);
|
||||
const char *device_node;
|
||||
GUdevDevice *udev_device = NULL;
|
||||
GUdevDevice *parent_udev_device = NULL;
|
||||
|
||||
device_node = clutter_input_device_get_device_node (device);
|
||||
if (!device_node)
|
||||
return FALSE;
|
||||
|
||||
udev_device = g_udev_client_query_by_device_file (priv->udev_client,
|
||||
device_node);
|
||||
if (!udev_device)
|
||||
return FALSE;
|
||||
|
||||
if (NULL != g_udev_device_get_property (udev_device, property_name))
|
||||
{
|
||||
g_object_unref (udev_device);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
parent_udev_device = g_udev_device_get_parent (udev_device);
|
||||
g_object_unref (udev_device);
|
||||
|
||||
if (!parent_udev_device)
|
||||
return FALSE;
|
||||
|
||||
if (NULL != g_udev_device_get_property (parent_udev_device, property_name))
|
||||
{
|
||||
g_object_unref (parent_udev_device);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
g_object_unref (parent_udev_device);
|
||||
return FALSE;
|
||||
#else
|
||||
g_warning ("Failed to set acceleration profile: no udev support");
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_mouse (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device)
|
||||
{
|
||||
return (has_udev_property (settings, device, "ID_INPUT_MOUSE") &&
|
||||
!has_udev_property (settings, device, "ID_INPUT_POINTINGSTICK"));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_trackball (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device)
|
||||
{
|
||||
return meta_input_device_is_trackball (device);
|
||||
}
|
||||
|
||||
static void
|
||||
set_device_accel_profile (ClutterInputDevice *device,
|
||||
GDesktopPointerAccelProfile profile)
|
||||
{
|
||||
guchar *defaults, *available;
|
||||
guchar values[2] = { 0 }; /* adaptive, flat */
|
||||
|
||||
defaults = get_property (device, "libinput Accel Profile Enabled Default",
|
||||
XA_INTEGER, 8, 2);
|
||||
if (!defaults)
|
||||
return;
|
||||
|
||||
available = get_property (device, "libinput Accel Profiles Available",
|
||||
XA_INTEGER, 8, 2);
|
||||
if (!available)
|
||||
goto err_available;
|
||||
|
||||
switch (profile)
|
||||
{
|
||||
case G_DESKTOP_POINTER_ACCEL_PROFILE_FLAT:
|
||||
values[0] = 0;
|
||||
values[1] = 1;
|
||||
break;
|
||||
case G_DESKTOP_POINTER_ACCEL_PROFILE_ADAPTIVE:
|
||||
values[0] = 1;
|
||||
values[1] = 0;
|
||||
break;
|
||||
default:
|
||||
g_warn_if_reached ();
|
||||
case G_DESKTOP_POINTER_ACCEL_PROFILE_DEFAULT:
|
||||
values[0] = defaults[0];
|
||||
values[1] = defaults[1];
|
||||
break;
|
||||
}
|
||||
|
||||
change_property (device, "libinput Accel Profile Enabled",
|
||||
XA_INTEGER, 8, &values, 2);
|
||||
|
||||
meta_XFree (available);
|
||||
|
||||
err_available:
|
||||
meta_XFree (defaults);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_x11_set_mouse_accel_profile (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
GDesktopPointerAccelProfile profile)
|
||||
{
|
||||
if (!is_mouse (settings, device))
|
||||
return;
|
||||
|
||||
set_device_accel_profile (device, profile);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_x11_set_trackball_accel_profile (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
GDesktopPointerAccelProfile profile)
|
||||
{
|
||||
if (!is_trackball (settings, device))
|
||||
return;
|
||||
|
||||
set_device_accel_profile (device, profile);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_x11_set_tablet_mapping (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
@ -385,11 +525,28 @@ meta_input_settings_x11_set_tablet_area (MetaInputSettings *settings,
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_x11_dispose (GObject *object)
|
||||
{
|
||||
#ifdef HAVE_LIBGUDEV
|
||||
MetaInputSettingsX11 *settings_x11 = META_INPUT_SETTINGS_X11 (object);
|
||||
MetaInputSettingsX11Private *priv =
|
||||
meta_input_settings_x11_get_instance_private (settings_x11);
|
||||
|
||||
g_clear_object (&priv->udev_client);
|
||||
#endif
|
||||
|
||||
G_OBJECT_CLASS (meta_input_settings_x11_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_x11_class_init (MetaInputSettingsX11Class *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
MetaInputSettingsClass *input_settings_class = META_INPUT_SETTINGS_CLASS (klass);
|
||||
|
||||
object_class->dispose = meta_input_settings_x11_dispose;
|
||||
|
||||
input_settings_class->set_send_events = meta_input_settings_x11_set_send_events;
|
||||
input_settings_class->set_matrix = meta_input_settings_x11_set_matrix;
|
||||
input_settings_class->set_speed = meta_input_settings_x11_set_speed;
|
||||
@ -405,9 +562,19 @@ meta_input_settings_x11_class_init (MetaInputSettingsX11Class *klass)
|
||||
input_settings_class->set_tablet_mapping = meta_input_settings_x11_set_tablet_mapping;
|
||||
input_settings_class->set_tablet_keep_aspect = meta_input_settings_x11_set_tablet_keep_aspect;
|
||||
input_settings_class->set_tablet_area = meta_input_settings_x11_set_tablet_area;
|
||||
|
||||
input_settings_class->set_mouse_accel_profile = meta_input_settings_x11_set_mouse_accel_profile;
|
||||
input_settings_class->set_trackball_accel_profile = meta_input_settings_x11_set_trackball_accel_profile;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_x11_init (MetaInputSettingsX11 *settings)
|
||||
{
|
||||
#ifdef HAVE_LIBGUDEV
|
||||
MetaInputSettingsX11Private *priv =
|
||||
meta_input_settings_x11_get_instance_private (settings);
|
||||
const char *subsystems[] = { NULL };
|
||||
|
||||
priv->udev_client = g_udev_client_new (subsystems);
|
||||
#endif
|
||||
}
|
||||
|
Reference in New Issue
Block a user