backends: Re-add support for edge scrolling with some touchpads

Add support for setting edge-scrolling separately from two-finger
scrolling. We now have 2 separate boolean settings for those, with the
Mouse panel in gnome-control-center allowing to set only one of those at
a time, but nothing precludes both being set in the configuration.

We need to handle:
- two-finger-scrolling-enabled and edge-scrolling-enabled settings both
  being set.
- those 2 settings being change out-of-order
- two-finger-scrolling being set on a device that doesn't support it
- edge-scrolling-enabled on a device that doesn't support it

And the combinations of one touchpad supporting just one of edge
scrolling and two-finger scrolling and another vice-versa.

https://bugzilla.gnome.org/show_bug.cgi?id=768245
This commit is contained in:
Bastien Nocera 2016-06-30 14:27:23 +02:00
parent 2e4eb86340
commit 36cd7177fd
4 changed files with 139 additions and 20 deletions

View File

@ -71,6 +71,9 @@ struct _MetaInputSettingsClass
void (* set_edge_scroll) (MetaInputSettings *settings, void (* set_edge_scroll) (MetaInputSettings *settings,
ClutterInputDevice *device, ClutterInputDevice *device,
gboolean enabled); gboolean enabled);
void (* set_two_finger_scroll) (MetaInputSettings *settings,
ClutterInputDevice *device,
gboolean enabled);
void (* set_scroll_button) (MetaInputSettings *settings, void (* set_scroll_button) (MetaInputSettings *settings,
ClutterInputDevice *device, ClutterInputDevice *device,
guint button); guint button);

View File

@ -449,6 +449,36 @@ update_touchpad_edge_scroll (MetaInputSettings *input_settings,
} }
} }
static void
update_touchpad_two_finger_scroll (MetaInputSettings *input_settings,
ClutterInputDevice *device)
{
MetaInputSettingsClass *input_settings_class;
gboolean two_finger_scroll_enabled;
MetaInputSettingsPrivate *priv;
if (device &&
clutter_input_device_get_device_type (device) != CLUTTER_TOUCHPAD_DEVICE)
return;
priv = meta_input_settings_get_instance_private (input_settings);
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
two_finger_scroll_enabled = g_settings_get_boolean (priv->touchpad_settings, "two-finger-scrolling-enabled");
if (device)
{
settings_device_set_bool_setting (input_settings, device,
input_settings_class->set_two_finger_scroll,
two_finger_scroll_enabled);
}
else
{
settings_set_bool_setting (input_settings, CLUTTER_TOUCHPAD_DEVICE,
(ConfigBoolFunc) input_settings_class->set_two_finger_scroll,
two_finger_scroll_enabled);
}
}
static void static void
update_touchpad_click_method (MetaInputSettings *input_settings, update_touchpad_click_method (MetaInputSettings *input_settings,
ClutterInputDevice *device) ClutterInputDevice *device)
@ -837,6 +867,8 @@ meta_input_settings_changed_cb (GSettings *settings,
update_touchpad_send_events (input_settings, NULL); update_touchpad_send_events (input_settings, NULL);
else if (strcmp (key, "edge-scrolling-enabled") == 0) else if (strcmp (key, "edge-scrolling-enabled") == 0)
update_touchpad_edge_scroll (input_settings, NULL); update_touchpad_edge_scroll (input_settings, NULL);
else if (strcmp (key, "two-finger-scrolling-enabled") == 0)
update_touchpad_two_finger_scroll (input_settings, NULL);
else if (strcmp (key, "click-method") == 0) else if (strcmp (key, "click-method") == 0)
update_touchpad_click_method (input_settings, NULL); update_touchpad_click_method (input_settings, NULL);
} }
@ -1150,6 +1182,7 @@ apply_device_settings (MetaInputSettings *input_settings,
update_touchpad_tap_enabled (input_settings, device); update_touchpad_tap_enabled (input_settings, device);
update_touchpad_send_events (input_settings, device); update_touchpad_send_events (input_settings, device);
update_touchpad_edge_scroll (input_settings, device); update_touchpad_edge_scroll (input_settings, device);
update_touchpad_two_finger_scroll (input_settings, device);
update_touchpad_click_method (input_settings, device); update_touchpad_click_method (input_settings, device);
update_trackball_scroll_button (input_settings, device); update_trackball_scroll_button (input_settings, device);

View File

@ -161,16 +161,18 @@ meta_input_settings_native_set_edge_scroll (MetaInputSettings *settin
enum libinput_config_scroll_method scroll_method = 0; enum libinput_config_scroll_method scroll_method = 0;
struct libinput_device *libinput_device; struct libinput_device *libinput_device;
enum libinput_config_scroll_method supported; enum libinput_config_scroll_method supported;
enum libinput_config_scroll_method current;
libinput_device = clutter_evdev_input_device_get_libinput_device (device); libinput_device = clutter_evdev_input_device_get_libinput_device (device);
supported = libinput_device_config_scroll_get_methods (libinput_device); supported = libinput_device_config_scroll_get_methods (libinput_device);
current = libinput_device_config_scroll_get_method (libinput_device);
if (supported & LIBINPUT_CONFIG_SCROLL_2FG) /* Don't set edge scrolling if two-finger scrolling is enabled and available */
{ if (current == LIBINPUT_CONFIG_SCROLL_2FG)
scroll_method = LIBINPUT_CONFIG_SCROLL_2FG; return;
}
else if (supported & LIBINPUT_CONFIG_SCROLL_EDGE && if (supported & LIBINPUT_CONFIG_SCROLL_EDGE &&
edge_scrolling_enabled) edge_scrolling_enabled)
{ {
scroll_method = LIBINPUT_CONFIG_SCROLL_EDGE; scroll_method = LIBINPUT_CONFIG_SCROLL_EDGE;
} }
@ -182,6 +184,38 @@ meta_input_settings_native_set_edge_scroll (MetaInputSettings *settin
device_set_scroll_method (libinput_device, scroll_method); device_set_scroll_method (libinput_device, scroll_method);
} }
static void
meta_input_settings_native_set_two_finger_scroll (MetaInputSettings *settings,
ClutterInputDevice *device,
gboolean two_finger_scroll_enabled)
{
enum libinput_config_scroll_method scroll_method = 0;
struct libinput_device *libinput_device;
enum libinput_config_scroll_method supported;
enum libinput_config_scroll_method current;
libinput_device = clutter_evdev_input_device_get_libinput_device (device);
supported = libinput_device_config_scroll_get_methods (libinput_device);
current = libinput_device_config_scroll_get_method (libinput_device);
if (two_finger_scroll_enabled &&
!(supported & LIBINPUT_CONFIG_SCROLL_2FG))
return;
if (two_finger_scroll_enabled)
{
scroll_method = LIBINPUT_CONFIG_SCROLL_2FG;
}
else if (current != LIBINPUT_CONFIG_SCROLL_EDGE)
{
scroll_method = LIBINPUT_CONFIG_SCROLL_NO_SCROLL;
}
else
return;
device_set_scroll_method (libinput_device, scroll_method);
}
static void static void
meta_input_settings_native_set_scroll_button (MetaInputSettings *settings, meta_input_settings_native_set_scroll_button (MetaInputSettings *settings,
ClutterInputDevice *device, ClutterInputDevice *device,
@ -290,6 +324,7 @@ meta_input_settings_native_class_init (MetaInputSettingsNativeClass *klass)
input_settings_class->set_tap_enabled = meta_input_settings_native_set_tap_enabled; input_settings_class->set_tap_enabled = meta_input_settings_native_set_tap_enabled;
input_settings_class->set_invert_scroll = meta_input_settings_native_set_invert_scroll; input_settings_class->set_invert_scroll = meta_input_settings_native_set_invert_scroll;
input_settings_class->set_edge_scroll = meta_input_settings_native_set_edge_scroll; input_settings_class->set_edge_scroll = meta_input_settings_native_set_edge_scroll;
input_settings_class->set_two_finger_scroll = meta_input_settings_native_set_two_finger_scroll;
input_settings_class->set_scroll_button = meta_input_settings_native_set_scroll_button; input_settings_class->set_scroll_button = meta_input_settings_native_set_scroll_button;
input_settings_class->set_click_method = meta_input_settings_native_set_click_method; input_settings_class->set_click_method = meta_input_settings_native_set_click_method;
input_settings_class->set_keyboard_repeat = meta_input_settings_native_set_keyboard_repeat; input_settings_class->set_keyboard_repeat = meta_input_settings_native_set_keyboard_repeat;

View File

@ -204,30 +204,77 @@ meta_input_settings_x11_set_edge_scroll (MetaInputSettings *settings,
gboolean edge_scroll_enabled) gboolean edge_scroll_enabled)
{ {
guchar values[3] = { 0 }; /* 2fg, edge, button. The last value is unused */ guchar values[3] = { 0 }; /* 2fg, edge, button. The last value is unused */
guchar *defaults;
guchar *available; guchar *available;
available = get_property (device, "libinput Scroll Methods Available", available = get_property (device, "libinput Scroll Methods Available",
XA_INTEGER, 8, 3); XA_INTEGER, 8, 3);
if (!available) defaults = get_property (device, "libinput Scroll Method Enabled",
return; XA_INTEGER, 8, 3);
if (!available || !defaults)
goto out;
memcpy (values, defaults, 3);
/* Don't set edge scrolling if two-finger scrolling is enabled and available */
if (available[1] && !(available[0] && values[0]))
{
values[1] = !!edge_scroll_enabled;
change_property (device, "libinput Scroll Method Enabled",
XA_INTEGER, 8, &values, 3);
}
out:
if (available)
meta_XFree (available);
if (defaults)
meta_XFree (defaults);
}
static void
meta_input_settings_x11_set_two_finger_scroll (MetaInputSettings *settings,
ClutterInputDevice *device,
gboolean two_finger_scroll_enabled)
{
guchar values[3] = { 0 }; /* 2fg, edge, button. The last value is unused */
guchar *defaults;
guchar *available;
gboolean changed;
available = get_property (device, "libinput Scroll Methods Available",
XA_INTEGER, 8, 3);
defaults = get_property (device, "libinput Scroll Method Enabled",
XA_INTEGER, 8, 3);
if (!available || !defaults)
goto out;
memcpy (values, defaults, 3);
changed = FALSE;
if (available[0]) if (available[0])
{ {
values[0] = 1; values[0] = !!two_finger_scroll_enabled;
} changed = TRUE;
else if (available[1] && edge_scroll_enabled)
{
values[1] = 1;
}
else
{
/* Disabled */
} }
change_property (device, "libinput Scroll Method Enabled", /* Disable edge scrolling when two-finger scrolling is enabled */
XA_INTEGER, 8, &values, 3); if (values[0] && values[1])
{
values[1] = 0;
changed = TRUE;
}
meta_XFree (available); if (changed)
{
change_property (device, "libinput Scroll Method Enabled",
XA_INTEGER, 8, &values, 3);
}
out:
if (available)
meta_XFree (available);
if (defaults)
meta_XFree (defaults);
} }
static void static void
@ -342,6 +389,7 @@ meta_input_settings_x11_class_init (MetaInputSettingsX11Class *klass)
input_settings_class->set_tap_enabled = meta_input_settings_x11_set_tap_enabled; input_settings_class->set_tap_enabled = meta_input_settings_x11_set_tap_enabled;
input_settings_class->set_invert_scroll = meta_input_settings_x11_set_invert_scroll; input_settings_class->set_invert_scroll = meta_input_settings_x11_set_invert_scroll;
input_settings_class->set_edge_scroll = meta_input_settings_x11_set_edge_scroll; input_settings_class->set_edge_scroll = meta_input_settings_x11_set_edge_scroll;
input_settings_class->set_two_finger_scroll = meta_input_settings_x11_set_two_finger_scroll;
input_settings_class->set_scroll_button = meta_input_settings_x11_set_scroll_button; input_settings_class->set_scroll_button = meta_input_settings_x11_set_scroll_button;
input_settings_class->set_click_method = meta_input_settings_x11_set_click_method; input_settings_class->set_click_method = meta_input_settings_x11_set_click_method;
input_settings_class->set_keyboard_repeat = meta_input_settings_x11_set_keyboard_repeat; input_settings_class->set_keyboard_repeat = meta_input_settings_x11_set_keyboard_repeat;