commit 605bfbf5c26adba7b19dcc4ebd836f211445614c Author: Craig Cabrey Date: Fri Jul 1 14:54:57 2022 -0500 backend/native: support for three finger drag After initially looking at implementing this feature in libinput itself, it was determined that it made more sense for the compositing layer to emulate the functionality. This patch adds the necessary emulation for the native/Wayland input handling backend in Mutter. Closes: https://bugzilla.gnome.org/show_bug.cgi?id=768421 Supercedes: https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1021 -- Note that this will only work on Wayland, the X11 implementation is left empty intentionally. diff --git a/src/backends/meta-input-settings-private.h b/src/backends/meta-input-settings-private.h index 226b195bc..581ae0323 100644 --- a/src/backends/meta-input-settings-private.h +++ b/src/backends/meta-input-settings-private.h @@ -102,6 +102,10 @@ struct _MetaInputSettingsClass ClutterInputDevice *device, GDesktopTouchpadClickMethod mode); + void (* set_three_finger_drag) (MetaInputSettings *settings, + ClutterInputDevice *device, + gboolean enabled); + void (* set_keyboard_repeat) (MetaInputSettings *settings, gboolean repeat, guint delay, diff --git a/src/backends/meta-input-settings.c b/src/backends/meta-input-settings.c index 1d98247b1..997666ceb 100644 --- a/src/backends/meta-input-settings.c +++ b/src/backends/meta-input-settings.c @@ -912,6 +912,39 @@ update_touchpad_click_method (MetaInputSettings *input_settings, } } +static void +update_touchpad_three_finger_drag (MetaInputSettings *input_settings, + ClutterInputDevice *device) +{ + MetaInputSettingsClass *input_settings_class; + MetaInputSettingsPrivate *priv; + gboolean enabled; + + 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); + enabled = g_settings_get_boolean (priv->touchpad_settings, + "three-finger-drag"); + + if (device) + { + settings_device_set_bool_setting (input_settings, device, + input_settings_class->set_three_finger_drag, + enabled); + } + else + { + settings_set_bool_setting (input_settings, + CLUTTER_INPUT_CAPABILITY_TOUCHPAD, + CLUTTER_INPUT_CAPABILITY_NONE, + NULL, + input_settings_class->set_three_finger_drag, + enabled); + } +} + static void update_touchpad_send_events (MetaInputSettings *input_settings, ClutterInputDevice *device) @@ -1234,6 +1267,8 @@ meta_input_settings_changed_cb (GSettings *settings, update_touchpad_two_finger_scroll (input_settings, NULL); else if (strcmp (key, "click-method") == 0) update_touchpad_click_method (input_settings, NULL); + else if (strcmp (key, "three-finger-drag") == 0) + update_touchpad_three_finger_drag (input_settings, NULL); else if (strcmp (key, "middle-click-emulation") == 0) update_middle_click_emulation (input_settings, settings, NULL); } diff --git a/src/backends/native/meta-input-device-native.c b/src/backends/native/meta-input-device-native.c index 7dcaabe40..8cc3d55c8 100644 --- a/src/backends/native/meta-input-device-native.c +++ b/src/backends/native/meta-input-device-native.c @@ -1360,6 +1360,7 @@ meta_input_device_native_init (MetaInputDeviceNative *self) self->output_ratio = 0; self->width = -1; self->height = -1; + self->three_finger_drag_enabled = FALSE; } static void diff --git a/src/backends/native/meta-input-device-native.h b/src/backends/native/meta-input-device-native.h index 80a980491..3fb8ccd6a 100644 --- a/src/backends/native/meta-input-device-native.h +++ b/src/backends/native/meta-input-device-native.h @@ -85,6 +85,8 @@ struct _MetaInputDeviceNative double output_ratio; /* w:h */ MetaInputDeviceMapping mapping_mode; + gboolean three_finger_drag_enabled; + /* Pointer position */ float pointer_x; float pointer_y; diff --git a/src/backends/native/meta-input-settings-native.c b/src/backends/native/meta-input-settings-native.c index 840272cab..2254d5e72 100644 --- a/src/backends/native/meta-input-settings-native.c +++ b/src/backends/native/meta-input-settings-native.c @@ -662,6 +662,15 @@ meta_input_settings_native_set_tablet_aspect_ratio (MetaInputSettings *settings g_object_unref (task); } +static void +meta_input_settings_native_set_three_finger_drag (MetaInputSettings *settings, + ClutterInputDevice *device, + gboolean enabled) +{ + MetaInputDeviceNative *native_device = META_INPUT_DEVICE_NATIVE (device); + native_device->three_finger_drag_enabled = enabled; +} + static void meta_input_settings_native_set_tablet_area (MetaInputSettings *settings, ClutterInputDevice *device, @@ -830,6 +839,7 @@ meta_input_settings_native_class_init (MetaInputSettingsNativeClass *klass) 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_disable_while_typing = meta_input_settings_native_set_disable_while_typing; + input_settings_class->set_three_finger_drag = meta_input_settings_native_set_three_finger_drag; input_settings_class->set_tablet_mapping = meta_input_settings_native_set_tablet_mapping; input_settings_class->set_tablet_aspect_ratio = meta_input_settings_native_set_tablet_aspect_ratio; diff --git a/src/backends/native/meta-seat-impl.c b/src/backends/native/meta-seat-impl.c index eb7b30872..e3ac3b255 100644 --- a/src/backends/native/meta-seat-impl.c +++ b/src/backends/native/meta-seat-impl.c @@ -1434,12 +1434,51 @@ notify_swipe_gesture_event (ClutterInputDevice *input_device, double dx_unaccel, double dy_unaccel) { + MetaInputDeviceNative *device_evdev; MetaSeatImpl *seat_impl; ClutterEvent *event = NULL; float x, y; + device_evdev = META_INPUT_DEVICE_NATIVE (input_device); seat_impl = seat_impl_from_device (input_device); + if (device_evdev->three_finger_drag_enabled) + { + if (n_fingers == 3) + { + switch (phase) + { + case CLUTTER_TOUCHPAD_GESTURE_PHASE_BEGIN: + meta_seat_impl_notify_button_in_impl (seat_impl, + input_device, + time_us, + BTN_LEFT, + LIBINPUT_BUTTON_STATE_PRESSED); + return; + case CLUTTER_TOUCHPAD_GESTURE_PHASE_CANCEL: + case CLUTTER_TOUCHPAD_GESTURE_PHASE_END: + meta_seat_impl_notify_button_in_impl (seat_impl, + input_device, + time_us, + BTN_LEFT, + LIBINPUT_BUTTON_STATE_RELEASED); + return; + case CLUTTER_TOUCHPAD_GESTURE_PHASE_UPDATE: + meta_seat_impl_notify_relative_motion_in_impl (seat_impl, + input_device, + time_us, + dx, dy, + dx_unaccel, dy_unaccel, + NULL); + return; + } + } + else if (n_fingers == 4) + { + n_fingers--; + } + } + meta_input_device_native_get_coords_in_impl (META_INPUT_DEVICE_NATIVE (seat_impl->core_pointer), &x, &y); event =