From 8518bc9b6ce13b0beffde1e59dae347e25adec84 Mon Sep 17 00:00:00 2001 From: honjow Date: Tue, 25 Jun 2024 21:52:11 +0800 Subject: [PATCH 1/3] feat: Support libinput pointer settings. --- src/main.cpp | 43 +++++++++++++++++++++++++++++++++++++++++++ src/main.hpp | 12 ++++++++++++ src/wlserver.cpp | 44 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 99 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index e8ebd66a30..37dfb8ebcb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -145,6 +145,12 @@ const struct option *gamescope_options = (struct option[]){ // Steam Deck options { "mura-map", required_argument, nullptr, 0 }, + // Pointer options + { "tap-to-click", no_argument, nullptr, 0 }, + { "tap-to-drag", no_argument, nullptr, 0 }, + { "drag-lock", no_argument, nullptr, 0 }, + { "natural-scrolling", required_argument, nullptr, 0 }, + {} // keep last }; @@ -256,6 +262,16 @@ const char usage[] = "Steam Deck options:\n" " --mura-map Set the mura compensation map to use for the display. Takes in a path to the mura map.\n" "\n" + "Libinput Pointer options:\n" + " --tap-to-click enable tap-to-click feature for pointer devices\n" + " --tap-and-drag enable tap-and-drag feature for pointer devices\n" + " --drag-lock enable drag-lock feature for pointer devices\n" + " --natural-scrolling enable natural scrolling for ...\n" + " none => No pointer device\n" + " touchpad => Only for touchpad\n" + " mouse => Only for mouse\n" + " all => All pointer device\n" + "\n" "Keyboard shortcuts:\n" " Super + F toggle fullscreen\n" " Super + N toggle nearest neighbour filtering\n" @@ -305,6 +321,11 @@ float g_flMaxWindowScale = FLT_MAX; uint32_t g_preferVendorID = 0; uint32_t g_preferDeviceID = 0; +bool g_tapToClick = false; +bool g_tapAndDrag = false; +bool g_dragLock = false; +SelectedPointerType g_naturalScrolling = SelectedPointerType::NONE; + pthread_t g_mainThread; static void steamCompMgrThreadRun(int argc, char **argv); @@ -438,6 +459,20 @@ static gamescope::ConCommand cc_shutdown( "shutdown", "Cleanly shutdown gamescop console_log.infof( "Shutting down..." ); ShutdownGamescope(); }); +static SelectedPointerType parse_selected_pointer_type(const char* str) +{ + if (!str || !*str) + return SelectedPointerType::NONE; + + if (!strcmp(str, "all")) + return SelectedPointerType::ALL; + else if (!strcmp(str, "touchpad")) + return SelectedPointerType::TOUCHPAD; + else if (!strcmp(str, "mouse")) + return SelectedPointerType::MOUSE; + else + return SelectedPointerType::NONE; +} static void handle_signal( int sig ) { @@ -754,6 +789,14 @@ int main(int argc, char **argv) g_nCursorScaleHeight = atoi(optarg); } else if (strcmp(opt_name, "mangoapp") == 0) { g_bLaunchMangoapp = true; + } else if (strcmp(opt_name, "tap-to-click") == 0) { + g_tapToClick = true; + } else if (strcmp(opt_name, "tap-and-drag") == 0) { + g_tapAndDrag = true; + } else if (strcmp(opt_name, "drag-lock") == 0) { + g_dragLock = true; + } else if (strcmp(opt_name, "natural-scrolling") == 0) { + g_naturalScrolling = parse_selected_pointer_type( optarg ); } break; case '?': diff --git a/src/main.hpp b/src/main.hpp index 8cfe62915f..c8948f7bdc 100644 --- a/src/main.hpp +++ b/src/main.hpp @@ -66,3 +66,15 @@ extern int g_nXWaylandCount; extern uint32_t g_preferVendorID; extern uint32_t g_preferDeviceID; +enum class SelectedPointerType : uint32_t +{ + NONE, + TOUCHPAD, + MOUSE, + ALL, +}; + +extern bool g_tapToClick; +extern bool g_tapAndDrag; +extern bool g_dragLock; +extern SelectedPointerType g_naturalScrolling; diff --git a/src/wlserver.cpp b/src/wlserver.cpp index ee6891d103..95b250ec4a 100644 --- a/src/wlserver.cpp +++ b/src/wlserver.cpp @@ -484,6 +484,48 @@ static void wlserver_handle_touch_motion(struct wl_listener *listener, void *dat wlserver_touchmotion( event->x, event->y, event->touch_id, event->time_msec ); } +static void wlserver_set_libinput_pointer(struct wlr_input_device *device) +{ +#ifdef WLR_BACKEND_LIBINPUT_H + if (device->type != WLR_INPUT_DEVICE_POINTER || !wlr_input_device_is_libinput(device)) + return; + + struct libinput_device* libinput_device = wlr_libinput_get_device_handle(device); + + if (g_tapToClick) + libinput_device_config_tap_set_enabled(libinput_device, LIBINPUT_CONFIG_TAP_ENABLED); + else + libinput_device_config_tap_set_enabled(libinput_device, LIBINPUT_CONFIG_TAP_DISABLED); + + if (g_tapAndDrag) + libinput_device_config_tap_set_drag_enabled(libinput_device, LIBINPUT_CONFIG_DRAG_ENABLED); + else + libinput_device_config_tap_set_drag_enabled(libinput_device, LIBINPUT_CONFIG_DRAG_DISABLED); + + if (g_dragLock) + libinput_device_config_tap_set_drag_lock_enabled(libinput_device, LIBINPUT_CONFIG_DRAG_LOCK_ENABLED); + else + libinput_device_config_tap_set_drag_lock_enabled(libinput_device, LIBINPUT_CONFIG_DRAG_LOCK_DISABLED); + + if (libinput_device_config_scroll_has_natural_scroll(libinput_device) != 0) + switch (g_naturalScrolling) + { + case SelectedPointerType::TOUCHPAD: + if (libinput_device_config_tap_get_finger_count(libinput_device) != 0) + libinput_device_config_scroll_set_natural_scroll_enabled(libinput_device, true); + break; + case SelectedPointerType::MOUSE: + if (libinput_device_config_tap_get_finger_count(libinput_device) == 0) + libinput_device_config_scroll_set_natural_scroll_enabled(libinput_device, true); + break; + case SelectedPointerType::ALL: + libinput_device_config_scroll_set_natural_scroll_enabled(libinput_device, true); + case SelectedPointerType::NONE: + break; + } +#endif +} + static void wlserver_new_input(struct wl_listener *listener, void *data) { struct wlr_input_device *device = (struct wlr_input_device *) data; @@ -534,6 +576,8 @@ static void wlserver_new_input(struct wl_listener *listener, void *data) wl_signal_add( &pointer->wlr->events.axis, &pointer->axis); pointer->frame.notify = wlserver_handle_pointer_frame; wl_signal_add( &pointer->wlr->events.frame, &pointer->frame); + + wlserver_set_libinput_pointer(device); } break; case WLR_INPUT_DEVICE_TOUCH: From 8f3bd1747ec3f72e8f5598e4de6a962ec44eecf4 Mon Sep 17 00:00:00 2001 From: Chenx Dust Date: Fri, 5 Jul 2024 14:30:07 +0000 Subject: [PATCH 2/3] feat: Add more options for libinput pointer device --- src/main.cpp | 53 +++++++++++++++++++++++++--- src/main.hpp | 14 ++++++++ src/wlserver.cpp | 90 ++++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 142 insertions(+), 15 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 37dfb8ebcb..5eda5e8133 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -145,11 +145,17 @@ const struct option *gamescope_options = (struct option[]){ // Steam Deck options { "mura-map", required_argument, nullptr, 0 }, - // Pointer options + // Libinput options { "tap-to-click", no_argument, nullptr, 0 }, { "tap-to-drag", no_argument, nullptr, 0 }, { "drag-lock", no_argument, nullptr, 0 }, + { "middle-emulation", no_argument, nullptr, 0 }, + { "disable-while-typing", no_argument, nullptr, 0 }, + { "disable-while-trackpointing", no_argument, nullptr, 0 }, + { "left-handed", no_argument, nullptr, 0 }, { "natural-scrolling", required_argument, nullptr, 0 }, + { "pointer-accel-profile", required_argument, nullptr, 0 }, + { "pointer-accel-speed", required_argument, nullptr, 0 }, {} // keep last }; @@ -266,11 +272,19 @@ const char usage[] = " --tap-to-click enable tap-to-click feature for pointer devices\n" " --tap-and-drag enable tap-and-drag feature for pointer devices\n" " --drag-lock enable drag-lock feature for pointer devices\n" + " --middle-emulation enable middle button emulation for pointer devices\n" + " --left-handed enable left handed mode for pointer devices\n" + " --disable-while-typing disable pointer devices while typing\n" + " --disable-while-trackpointing disable pointer devices while trackpointing\n" " --natural-scrolling enable natural scrolling for ...\n" - " none => No pointer device\n" - " touchpad => Only for touchpad\n" - " mouse => Only for mouse\n" + " none => No pointer device (default)\n" + " touchpad => Only touchpad\n" + " mouse => Only mouse\n" " all => All pointer device\n" + " --pointer-accel-profile set acceleration profile for pointer devices to ...\n" + " adaptive => takes the current speed of the device into account when deciding on acceleration (default)\n" + " flat => simply a constant factor applied to all device deltas, regardless of the speed of motion\n" + " --pointer-accel-speed set acceleration speed for pointer devices within [-1, 1] (default 0)\n" "\n" "Keyboard shortcuts:\n" " Super + F toggle fullscreen\n" @@ -324,7 +338,13 @@ uint32_t g_preferDeviceID = 0; bool g_tapToClick = false; bool g_tapAndDrag = false; bool g_dragLock = false; +bool g_middleEmu = false; +bool g_leftHanded = false; +bool g_dwt = false; +bool g_dwtp = false; SelectedPointerType g_naturalScrolling = SelectedPointerType::NONE; +PointerAccelProfileType g_accelProfile = PointerAccelProfileType::ADAPTIVE; +double g_accelSpeed = false; pthread_t g_mainThread; @@ -474,6 +494,19 @@ static SelectedPointerType parse_selected_pointer_type(const char* str) return SelectedPointerType::NONE; } +static PointerAccelProfileType parse_pointer_accel_profile(const char* str) +{ + if (!str || !*str) + return PointerAccelProfileType::ADAPTIVE; + + if (!strcmp(str, "adaptive")) + return PointerAccelProfileType::ADAPTIVE; + else if (!strcmp(str, "flat")) + return PointerAccelProfileType::FLAT; + else + return PointerAccelProfileType::ADAPTIVE; +} + static void handle_signal( int sig ) { switch ( sig ) { @@ -795,8 +828,20 @@ int main(int argc, char **argv) g_tapAndDrag = true; } else if (strcmp(opt_name, "drag-lock") == 0) { g_dragLock = true; + } else if (strcmp(opt_name, "middle-emulation") == 0) { + g_middleEmu = true; + } else if (strcmp(opt_name, "left-handed") == 0) { + g_leftHanded = true; + } else if (strcmp(opt_name, "disable-while-typing") == 0) { + g_dwt = true; + } else if (strcmp(opt_name, "disable-while-trackpointing") == 0) { + g_dwtp = true; } else if (strcmp(opt_name, "natural-scrolling") == 0) { g_naturalScrolling = parse_selected_pointer_type( optarg ); + } else if (strcmp(opt_name, "pointer-accel-profile") == 0) { + g_accelProfile = parse_pointer_accel_profile( optarg ); + } else if (strcmp(opt_name, "pointer-accel-speed") == 0) { + g_accelSpeed = atof( optarg ); } break; case '?': diff --git a/src/main.hpp b/src/main.hpp index c8948f7bdc..58eed11701 100644 --- a/src/main.hpp +++ b/src/main.hpp @@ -74,7 +74,21 @@ enum class SelectedPointerType : uint32_t ALL, }; +enum class PointerAccelProfileType : uint32_t +{ + NONE, + FLAT, + ADAPTIVE, + CUSTOM, +}; + extern bool g_tapToClick; extern bool g_tapAndDrag; extern bool g_dragLock; +extern bool g_middleEmu; +extern bool g_leftHanded; +extern bool g_dwt; +extern bool g_dwtp; extern SelectedPointerType g_naturalScrolling; +extern PointerAccelProfileType g_accelProfile; +extern double g_accelSpeed; diff --git a/src/wlserver.cpp b/src/wlserver.cpp index 95b250ec4a..7d7778f6ee 100644 --- a/src/wlserver.cpp +++ b/src/wlserver.cpp @@ -486,28 +486,76 @@ static void wlserver_handle_touch_motion(struct wl_listener *listener, void *dat static void wlserver_set_libinput_pointer(struct wlr_input_device *device) { -#ifdef WLR_BACKEND_LIBINPUT_H +#ifdef HAVE_DRM if (device->type != WLR_INPUT_DEVICE_POINTER || !wlr_input_device_is_libinput(device)) return; struct libinput_device* libinput_device = wlr_libinput_get_device_handle(device); - if (g_tapToClick) + if (g_tapToClick) { libinput_device_config_tap_set_enabled(libinput_device, LIBINPUT_CONFIG_TAP_ENABLED); - else + } else { libinput_device_config_tap_set_enabled(libinput_device, LIBINPUT_CONFIG_TAP_DISABLED); - - if (g_tapAndDrag) + } + if (g_tapAndDrag) { libinput_device_config_tap_set_drag_enabled(libinput_device, LIBINPUT_CONFIG_DRAG_ENABLED); - else + } else { libinput_device_config_tap_set_drag_enabled(libinput_device, LIBINPUT_CONFIG_DRAG_DISABLED); - - if (g_dragLock) + } + if (g_dragLock) { libinput_device_config_tap_set_drag_lock_enabled(libinput_device, LIBINPUT_CONFIG_DRAG_LOCK_ENABLED); - else + } else { libinput_device_config_tap_set_drag_lock_enabled(libinput_device, LIBINPUT_CONFIG_DRAG_LOCK_DISABLED); - - if (libinput_device_config_scroll_has_natural_scroll(libinput_device) != 0) + } + if (libinput_device_config_middle_emulation_is_available(libinput_device)) { + if (g_middleEmu) { + libinput_device_config_middle_emulation_set_enabled(libinput_device, LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED); + } else { + libinput_device_config_middle_emulation_set_enabled(libinput_device, LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED); + } + } else { + if (device->name) { + printf("Libinput pointer \"%s\": Middle button emulation not supported", device->name); + } else { + printf("Unnamed libinput pointer: Middle button emulation not supported"); + } + } + if (libinput_device_config_left_handed_is_available(libinput_device)) { + libinput_device_config_left_handed_set(libinput_device, g_leftHanded); + } else { + if (device->name) { + printf("Libinput pointer \"%s\": Left handed mode not supported", device->name); + } else { + printf("Unnamed libinput pointer: Left handed mode not supported"); + } + } + if (libinput_device_config_dwt_is_available(libinput_device)) { + if (g_dwt) { + libinput_device_config_dwt_set_enabled(libinput_device, LIBINPUT_CONFIG_DWT_ENABLED); + } else { + libinput_device_config_dwt_set_enabled(libinput_device, LIBINPUT_CONFIG_DWT_DISABLED); + } + } else { + if (device->name) { + printf("Libinput pointer \"%s\": Disable while typing not supported", device->name); + } else { + printf("Unnamed libinput pointer: Disable while typing not supported"); + } + } + if (libinput_device_config_dwtp_is_available(libinput_device)) { + if (g_dwtp) { + libinput_device_config_dwtp_set_enabled(libinput_device, LIBINPUT_CONFIG_DWTP_ENABLED); + } else { + libinput_device_config_dwtp_set_enabled(libinput_device, LIBINPUT_CONFIG_DWTP_DISABLED); + } + } else { + if (device->name) { + printf("Libinput pointer \"%s\": Disable while track pointing not supported", device->name); + } else { + printf("Unnamed libinput pointer: Disable while track pointing not supported"); + } + } + if (libinput_device_config_scroll_has_natural_scroll(libinput_device) != 0) { switch (g_naturalScrolling) { case SelectedPointerType::TOUCHPAD: @@ -520,9 +568,29 @@ static void wlserver_set_libinput_pointer(struct wlr_input_device *device) break; case SelectedPointerType::ALL: libinput_device_config_scroll_set_natural_scroll_enabled(libinput_device, true); + break; case SelectedPointerType::NONE: break; } + } + if (libinput_device_config_accel_is_available(libinput_device)) { + switch (g_accelProfile) { + case PointerAccelProfileType::FLAT: + libinput_device_config_accel_set_profile(libinput_device, LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT); + break; + case PointerAccelProfileType::ADAPTIVE: + default: + libinput_device_config_accel_set_profile(libinput_device, LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE); + break; + } + libinput_device_config_accel_set_speed(libinput_device, g_accelSpeed); + } else { + if (device->name) { + printf("Libinput pointer \"%s\": Accelation not supported", device->name); + } else { + printf("Unnamed libinput pointer: Accelation not supported"); + } + } #endif } From f69e6bcb2d1c49911f9e9aaf1a6f8e0f182eb29c Mon Sep 17 00:00:00 2001 From: Chenx Dust Date: Thu, 17 Oct 2024 04:41:02 +0000 Subject: [PATCH 3/3] fix: Fix typo of "tap and drag" option in `main.cpp` --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 5eda5e8133..05f8d26517 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -147,7 +147,7 @@ const struct option *gamescope_options = (struct option[]){ // Libinput options { "tap-to-click", no_argument, nullptr, 0 }, - { "tap-to-drag", no_argument, nullptr, 0 }, + { "tap-and-drag", no_argument, nullptr, 0 }, { "drag-lock", no_argument, nullptr, 0 }, { "middle-emulation", no_argument, nullptr, 0 }, { "disable-while-typing", no_argument, nullptr, 0 },