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:
parent
cfe5d7429a
commit
23c4ac6c7f
24
configure.ac
24
configure.ac
@ -116,6 +116,11 @@ AC_ARG_WITH(libwacom,
|
||||
[disable the use of libwacom for advanced tablet management]),,
|
||||
with_libwacom=auto)
|
||||
|
||||
AC_ARG_WITH(gudev,
|
||||
AC_HELP_STRING([--without-gudev],
|
||||
[disable the use of gudev for device type detection]),,
|
||||
with_gudev=auto)
|
||||
|
||||
AC_ARG_WITH([xwayland-path],
|
||||
[AS_HELP_STRING([--with-xwayland-path], [Absolute path for an X Wayland server])],
|
||||
[XWAYLAND_PATH="$withval"],
|
||||
@ -195,6 +200,24 @@ else
|
||||
fi
|
||||
fi
|
||||
|
||||
have_gudev=no
|
||||
AC_MSG_CHECKING([gudev])
|
||||
if test x$with_gudev = xno ; then
|
||||
AC_MSG_RESULT([disabled])
|
||||
else
|
||||
if $PKG_CONFIG --exists gudev-1.0; then
|
||||
have_gudev=yes
|
||||
AC_MSG_RESULT(yes)
|
||||
MUTTER_PC_MODULES="$MUTTER_PC_MODULES gudev-1.0"
|
||||
AC_DEFINE([HAVE_LIBGUDEV], 1, [Building with gudev for device type detection])
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
if test x$with_gudev = xyes ; then
|
||||
AC_MSG_ERROR([gudev forced but not found])
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
INTROSPECTION_VERSION=0.9.5
|
||||
GOBJECT_INTROSPECTION_CHECK([$INTROSPECTION_VERSION])
|
||||
|
||||
@ -449,6 +472,7 @@ mutter-$VERSION
|
||||
Startup notification: ${have_startup_notification}
|
||||
libcanberra: ${have_libcanberra}
|
||||
libwacom: ${have_libwacom}
|
||||
gudev ${have_gudev}
|
||||
Introspection: ${found_introspection}
|
||||
Session management: ${found_sm}
|
||||
Wayland: ${have_wayland}
|
||||
|
@ -100,6 +100,13 @@ struct _MetaInputSettingsClass
|
||||
gdouble padding_right,
|
||||
gdouble padding_top,
|
||||
gdouble padding_bottom);
|
||||
|
||||
void (* set_mouse_accel_profile) (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
GDesktopPointerAccelProfile profile);
|
||||
void (* set_trackball_accel_profile) (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
GDesktopPointerAccelProfile profile);
|
||||
};
|
||||
|
||||
GType meta_input_settings_get_type (void) G_GNUC_CONST;
|
||||
@ -140,4 +147,6 @@ WacomDevice * meta_input_settings_get_tablet_wacom_device (MetaInputSettings *se
|
||||
ClutterInputDevice *device);
|
||||
#endif
|
||||
|
||||
gboolean meta_input_device_is_trackball (ClutterInputDevice *device);
|
||||
|
||||
#endif /* META_INPUT_SETTINGS_PRIVATE_H */
|
||||
|
@ -310,6 +310,63 @@ update_mouse_left_handed (MetaInputSettings *input_settings,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_update_pointer_accel_profile (MetaInputSettings *input_settings,
|
||||
GSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
GDesktopPointerAccelProfile profile)
|
||||
{
|
||||
MetaInputSettingsPrivate *priv =
|
||||
meta_input_settings_get_instance_private (input_settings);
|
||||
MetaInputSettingsClass *input_settings_class =
|
||||
META_INPUT_SETTINGS_GET_CLASS (input_settings);
|
||||
|
||||
if (settings == priv->mouse_settings)
|
||||
input_settings_class->set_mouse_accel_profile (input_settings,
|
||||
device,
|
||||
profile);
|
||||
else if (settings == priv->trackball_settings)
|
||||
input_settings_class->set_trackball_accel_profile (input_settings,
|
||||
device,
|
||||
profile);
|
||||
}
|
||||
|
||||
static void
|
||||
update_pointer_accel_profile (MetaInputSettings *input_settings,
|
||||
GSettings *settings,
|
||||
ClutterInputDevice *device)
|
||||
{
|
||||
GDesktopPointerAccelProfile profile;
|
||||
|
||||
profile = g_settings_get_enum (settings, "accel-profile");
|
||||
|
||||
if (device)
|
||||
{
|
||||
do_update_pointer_accel_profile (input_settings, settings,
|
||||
device, profile);
|
||||
}
|
||||
else
|
||||
{
|
||||
MetaInputSettingsPrivate *priv =
|
||||
meta_input_settings_get_instance_private (input_settings);
|
||||
const GSList *devices;
|
||||
const GSList *l;
|
||||
|
||||
devices = clutter_device_manager_peek_devices (priv->device_manager);
|
||||
for (l = devices; l; l = l->next)
|
||||
{
|
||||
device = l->data;
|
||||
|
||||
if (clutter_input_device_get_device_mode (device) ==
|
||||
CLUTTER_INPUT_MODE_MASTER)
|
||||
continue;
|
||||
|
||||
do_update_pointer_accel_profile (input_settings, settings,
|
||||
device, profile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static GSettings *
|
||||
get_settings_for_device_type (MetaInputSettings *input_settings,
|
||||
ClutterInputDeviceType type)
|
||||
@ -539,8 +596,8 @@ update_touchpad_send_events (MetaInputSettings *input_settings,
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
device_is_trackball (ClutterInputDevice *device)
|
||||
gboolean
|
||||
meta_input_device_is_trackball (ClutterInputDevice *device)
|
||||
{
|
||||
gboolean is_trackball;
|
||||
char *name;
|
||||
@ -563,7 +620,7 @@ update_trackball_scroll_button (MetaInputSettings *input_settings,
|
||||
MetaInputSettingsPrivate *priv;
|
||||
guint button;
|
||||
|
||||
if (device && !device_is_trackball (device))
|
||||
if (device && !meta_input_device_is_trackball (device))
|
||||
return;
|
||||
|
||||
priv = meta_input_settings_get_instance_private (input_settings);
|
||||
@ -586,7 +643,7 @@ update_trackball_scroll_button (MetaInputSettings *input_settings,
|
||||
{
|
||||
device = devices->data;
|
||||
|
||||
if (device_is_trackball (device))
|
||||
if (meta_input_device_is_trackball (device))
|
||||
input_settings_class->set_scroll_button (input_settings, device, button);
|
||||
|
||||
devices = devices->next;
|
||||
@ -852,6 +909,8 @@ meta_input_settings_changed_cb (GSettings *settings,
|
||||
update_device_speed (input_settings, NULL);
|
||||
else if (strcmp (key, "natural-scroll") == 0)
|
||||
update_device_natural_scroll (input_settings, NULL);
|
||||
else if (strcmp (key, "accel-profile") == 0)
|
||||
update_pointer_accel_profile (input_settings, settings, NULL);
|
||||
}
|
||||
else if (settings == priv->touchpad_settings)
|
||||
{
|
||||
@ -876,6 +935,8 @@ meta_input_settings_changed_cb (GSettings *settings,
|
||||
{
|
||||
if (strcmp (key, "scroll-wheel-emulation-button") == 0)
|
||||
update_trackball_scroll_button (input_settings, NULL);
|
||||
else if (strcmp (key, "accel-profile") == 0)
|
||||
update_pointer_accel_profile (input_settings, settings, NULL);
|
||||
}
|
||||
else if (settings == priv->keyboard_settings)
|
||||
{
|
||||
|
@ -275,6 +275,112 @@ meta_input_settings_native_set_keyboard_repeat (MetaInputSettings *settings,
|
||||
clutter_evdev_set_keyboard_repeat (manager, enabled, delay, interval);
|
||||
}
|
||||
|
||||
static void
|
||||
set_device_accel_profile (ClutterInputDevice *device,
|
||||
GDesktopPointerAccelProfile profile)
|
||||
{
|
||||
struct libinput_device *libinput_device;
|
||||
enum libinput_config_accel_profile libinput_profile;
|
||||
uint32_t profiles;
|
||||
|
||||
libinput_device = clutter_evdev_input_device_get_libinput_device (device);
|
||||
|
||||
switch (profile)
|
||||
{
|
||||
case G_DESKTOP_POINTER_ACCEL_PROFILE_FLAT:
|
||||
libinput_profile = LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT;
|
||||
break;
|
||||
case G_DESKTOP_POINTER_ACCEL_PROFILE_ADAPTIVE:
|
||||
libinput_profile = LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE;
|
||||
break;
|
||||
default:
|
||||
g_warn_if_reached ();
|
||||
case G_DESKTOP_POINTER_ACCEL_PROFILE_DEFAULT:
|
||||
libinput_profile =
|
||||
libinput_device_config_accel_get_default_profile (libinput_device);
|
||||
}
|
||||
|
||||
profiles = libinput_device_config_accel_get_profiles (libinput_device);
|
||||
if ((profiles & libinput_profile) == 0)
|
||||
{
|
||||
libinput_profile =
|
||||
libinput_device_config_accel_get_default_profile (libinput_device);
|
||||
}
|
||||
|
||||
libinput_device_config_accel_set_profile (libinput_device,
|
||||
libinput_profile);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
has_udev_property (ClutterInputDevice *device,
|
||||
const char *property)
|
||||
{
|
||||
struct libinput_device *libinput_device;
|
||||
struct udev_device *udev_device;
|
||||
struct udev_device *parent_udev_device;
|
||||
|
||||
libinput_device = clutter_evdev_input_device_get_libinput_device (device);
|
||||
if (!libinput_device)
|
||||
return FALSE;
|
||||
|
||||
udev_device = libinput_device_get_udev_device (libinput_device);
|
||||
|
||||
if (!udev_device)
|
||||
return FALSE;
|
||||
|
||||
if (NULL != udev_device_get_property_value (udev_device, property))
|
||||
{
|
||||
udev_device_unref (udev_device);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
parent_udev_device = udev_device_get_parent (udev_device);
|
||||
udev_device_unref (udev_device);
|
||||
|
||||
if (!parent_udev_device)
|
||||
return FALSE;
|
||||
|
||||
if (NULL != udev_device_get_property_value (parent_udev_device, property))
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_mouse_device (ClutterInputDevice *device)
|
||||
{
|
||||
return (has_udev_property (device, "ID_INPUT_MOUSE") &&
|
||||
!has_udev_property (device, "ID_INPUT_POINTINGSTICK"));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_trackball_device (ClutterInputDevice *device)
|
||||
{
|
||||
return meta_input_device_is_trackball (device);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_native_set_mouse_accel_profile (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
GDesktopPointerAccelProfile profile)
|
||||
{
|
||||
if (!is_mouse_device (device))
|
||||
return;
|
||||
|
||||
set_device_accel_profile (device, profile);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_native_set_trackball_accel_profile (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
GDesktopPointerAccelProfile profile)
|
||||
{
|
||||
if (!is_trackball_device (device))
|
||||
return;
|
||||
|
||||
set_device_accel_profile (device, profile);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_native_set_tablet_mapping (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
@ -332,6 +438,9 @@ meta_input_settings_native_class_init (MetaInputSettingsNativeClass *klass)
|
||||
input_settings_class->set_tablet_mapping = meta_input_settings_native_set_tablet_mapping;
|
||||
input_settings_class->set_tablet_keep_aspect = meta_input_settings_native_set_tablet_keep_aspect;
|
||||
input_settings_class->set_tablet_area = meta_input_settings_native_set_tablet_area;
|
||||
|
||||
input_settings_class->set_mouse_accel_profile = meta_input_settings_native_set_mouse_accel_profile;
|
||||
input_settings_class->set_trackball_accel_profile = meta_input_settings_native_set_trackball_accel_profile;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user