From 6e7125f93bbe16980fc67e846af170102fc7ed84 Mon Sep 17 00:00:00 2001 From: Scott Moreau Date: Thu, 21 Nov 2024 21:50:26 -0700 Subject: [PATCH] input: Allow multiple keyboards and mice to have different configurations This patch checks for additional configuration sections so keyboards and mice can be matched by name or with udev properties. Running wayfire with '-d input-devices' will log the sections that are being checked, for reference. This allows multiple keyboards and mice to be configured differently, whereas before, all keyboards used the common configuration in the [input] section. To be clear, no additional configuration is required. If no matching configuration section is found for the device, [input] options will be used. --- src/api/wayfire/config-backend.hpp | 2 +- src/api/wayfire/plugin.hpp | 2 +- src/core/plugin.cpp | 8 +-- src/core/seat/input-manager.cpp | 4 +- src/core/seat/keyboard.cpp | 20 ++++--- src/core/seat/pointer.cpp | 23 +++++++- src/core/seat/pointing-device.cpp | 90 ++++++++++++++++-------------- src/core/seat/pointing-device.hpp | 39 ++++++------- 8 files changed, 104 insertions(+), 84 deletions(-) diff --git a/src/api/wayfire/config-backend.hpp b/src/api/wayfire/config-backend.hpp index 8a47601e7..54db71bb6 100644 --- a/src/api/wayfire/config-backend.hpp +++ b/src/api/wayfire/config-backend.hpp @@ -49,7 +49,7 @@ class config_backend_t * described in input-device.xml */ virtual std::shared_ptr get_input_device_section( - wlr_input_device *device); + std::string const & prefix, wlr_input_device *device); virtual ~config_backend_t() = default; diff --git a/src/api/wayfire/plugin.hpp b/src/api/wayfire/plugin.hpp index 3d4779ac2..2d21cbcd1 100644 --- a/src/api/wayfire/plugin.hpp +++ b/src/api/wayfire/plugin.hpp @@ -105,7 +105,7 @@ class plugin_interface_t using wayfire_plugin_load_func = wf::plugin_interface_t * (*)(); /** The version of Wayfire's API/ABI */ -constexpr uint32_t WAYFIRE_API_ABI_VERSION = 2024'10'01; +constexpr uint32_t WAYFIRE_API_ABI_VERSION = 2024'11'21; /** * Each plugin must also provide a function which returns the Wayfire API/ABI diff --git a/src/core/plugin.cpp b/src/core/plugin.cpp index 5f149d292..614e11217 100644 --- a/src/core/plugin.cpp +++ b/src/core/plugin.cpp @@ -44,7 +44,7 @@ static struct udev_property_and_desc }; std::shared_ptr wf::config_backend_t::get_input_device_section( - wlr_input_device *device) + std::string const & prefix, wlr_input_device *device) { auto& config = wf::get_core().config; std::shared_ptr section; @@ -65,7 +65,7 @@ std::shared_ptr wf::config_backend_t::get_input_device_sectio continue; } - std::string name = std::string("input-device:") + nonull(value); + std::string name = prefix + ":" + nonull(value); LOGC(INPUT_DEVICES, "Checking for config section [", name, "] ", pd.property_name, " (", pd.description, ")"); section = config.get_section(name); @@ -80,7 +80,7 @@ std::shared_ptr wf::config_backend_t::get_input_device_sectio } std::string name = nonull(device->name); - name = "input-device:" + name; + name = prefix + ":" + name; LOGC(INPUT_DEVICES, "Checking for config section [", name, "]"); section = config.get_section(name); if (section) @@ -90,7 +90,7 @@ std::shared_ptr wf::config_backend_t::get_input_device_sectio } config.merge_section( - config.get_section("input-device")->clone_with_name(name)); + config.get_section(prefix)->clone_with_name(name)); LOGC(INPUT_DEVICES, "Using config section [", name, "]"); return config.get_section(name); diff --git a/src/core/seat/input-manager.cpp b/src/core/seat/input-manager.cpp index a9b4a57a4..fbf0b09ed 100644 --- a/src/core/seat/input-manager.cpp +++ b/src/core/seat/input-manager.cpp @@ -60,7 +60,7 @@ void wf::input_manager_t::configure_input_device(std::unique_ptrget_wlr_handle(); auto cursor = wf::get_core().get_wlr_cursor(); auto section = - wf::get_core().config_backend->get_input_device_section(dev); + wf::get_core().config_backend->get_input_device_section("input-device", dev); auto mapped_output = section->get_option("output")->get_value_str(); if (mapped_output.empty()) @@ -152,8 +152,6 @@ void load_locked_mods_from_config(xkb_mod_mask_t& locked_mods) wf::input_manager_t::input_manager_t() { - wf::pointing_device_t::config.load(); - load_locked_mods_from_config(locked_mods); input_device_created.set_callback([&] (void *data) diff --git a/src/core/seat/keyboard.cpp b/src/core/seat/keyboard.cpp index ad3ab71b1..51a964dea 100644 --- a/src/core/seat/keyboard.cpp +++ b/src/core/seat/keyboard.cpp @@ -121,14 +121,18 @@ void wf::keyboard_t::setup_listeners() wf::keyboard_t::keyboard_t(wlr_input_device *dev) : handle(wlr_keyboard_from_input_device(dev)), device(dev) { - model.load_option("input/xkb_model"); - variant.load_option("input/xkb_variant"); - layout.load_option("input/xkb_layout"); - options.load_option("input/xkb_options"); - rules.load_option("input/xkb_rules"); - - repeat_rate.load_option("input/kb_repeat_rate"); - repeat_delay.load_option("input/kb_repeat_delay"); + auto section = + wf::get_core().config_backend->get_input_device_section("input", dev); + auto section_name = section->get_name(); + + model.load_option(section_name + "/xkb_model"); + variant.load_option(section_name + "/xkb_variant"); + layout.load_option(section_name + "/xkb_layout"); + options.load_option(section_name + "/xkb_options"); + rules.load_option(section_name + "/xkb_rules"); + + repeat_rate.load_option(section_name + "/kb_repeat_rate"); + repeat_delay.load_option(section_name + "/kb_repeat_delay"); // When the configuration options change, mark them as dirty. // They are applied at the config-reloaded signal. diff --git a/src/core/seat/pointer.cpp b/src/core/seat/pointer.cpp index 766c8b8bf..6664163ff 100644 --- a/src/core/seat/pointer.cpp +++ b/src/core/seat/pointer.cpp @@ -355,9 +355,26 @@ void wf::pointer_t::handle_pointer_axis(wlr_pointer_axis_event *ev, } /* Calculate speed settings */ - double mult = ev->source == WLR_AXIS_SOURCE_FINGER ? - wf::pointing_device_t::config.touchpad_scroll_speed : - wf::pointing_device_t::config.mouse_scroll_speed; + bool touchpad = ev->source == WLR_AXIS_SOURCE_FINGER; + double mult = 1.0; + for (const auto& device : wf::get_core_impl().input->input_devices) + { + auto dev = device->get_wlr_handle(); + if ((touchpad && (dev->type != WLR_INPUT_DEVICE_TABLET_TOOL)) || + (!touchpad && (dev->type != WLR_INPUT_DEVICE_POINTER)) || + (dev != &ev->pointer->base)) + { + continue; + } + + wf::pointing_device_t *pd = dynamic_cast(device.get()); + if (!pd) + { + break; + } + + mult = touchpad ? pd->touchpad_scroll_speed : pd->mouse_scroll_speed; + } ev->delta *= mult; ev->delta_discrete *= mult; diff --git a/src/core/seat/pointing-device.cpp b/src/core/seat/pointing-device.cpp index 725d5dc37..03d8387b8 100644 --- a/src/core/seat/pointing-device.cpp +++ b/src/core/seat/pointing-device.cpp @@ -3,32 +3,36 @@ wf::pointing_device_t::pointing_device_t(wlr_input_device *dev) : input_device_impl_t(dev) { + load_options(); update_options(); } -wf::pointing_device_t::config_t wf::pointing_device_t::config; -void wf::pointing_device_t::config_t::load() +void wf::pointing_device_t::load_options() { - left_handed_mode.load_option("input/left_handed_mode"); - middle_emulation.load_option("input/middle_emulation"); - - mouse_scroll_speed.load_option("input/mouse_scroll_speed"); - mouse_cursor_speed.load_option("input/mouse_cursor_speed"); - touchpad_cursor_speed.load_option("input/touchpad_cursor_speed"); - touchpad_scroll_speed.load_option("input/touchpad_scroll_speed"); - - mouse_natural_scroll_enabled.load_option("input/mouse_natural_scroll"); - touchpad_tap_enabled.load_option("input/tap_to_click"); - touchpad_dwt_enabled.load_option("input/disable_touchpad_while_typing"); - touchpad_dwmouse_enabled.load_option("input/disable_touchpad_while_mouse"); - touchpad_natural_scroll_enabled.load_option("input/natural_scroll"); - touchpad_drag_lock_enabled.load_option("input/drag_lock"); - - mouse_accel_profile.load_option("input/mouse_accel_profile"); - touchpad_accel_profile.load_option("input/touchpad_accel_profile"); - - touchpad_click_method.load_option("input/click_method"); - touchpad_scroll_method.load_option("input/scroll_method"); + auto section = + wf::get_core().config_backend->get_input_device_section("input", get_wlr_handle()); + auto section_name = section->get_name(); + + left_handed_mode.load_option(section_name + "/left_handed_mode"); + middle_emulation.load_option(section_name + "/middle_emulation"); + + mouse_scroll_speed.load_option(section_name + "/mouse_scroll_speed"); + mouse_cursor_speed.load_option(section_name + "/mouse_cursor_speed"); + touchpad_cursor_speed.load_option(section_name + "/touchpad_cursor_speed"); + touchpad_scroll_speed.load_option(section_name + "/touchpad_scroll_speed"); + + mouse_natural_scroll_enabled.load_option(section_name + "/mouse_natural_scroll"); + touchpad_tap_enabled.load_option(section_name + "/tap_to_click"); + touchpad_dwt_enabled.load_option(section_name + "/disable_touchpad_while_typing"); + touchpad_dwmouse_enabled.load_option(section_name + "/disable_touchpad_while_mouse"); + touchpad_natural_scroll_enabled.load_option(section_name + "/natural_scroll"); + touchpad_drag_lock_enabled.load_option(section_name + "/drag_lock"); + + mouse_accel_profile.load_option(section_name + "/mouse_accel_profile"); + touchpad_accel_profile.load_option(section_name + "/touchpad_accel_profile"); + + touchpad_click_method.load_option(section_name + "/click_method"); + touchpad_scroll_method.load_option(section_name + "/scroll_method"); } static void set_libinput_accel_profile(libinput_device *dev, std::string name) @@ -63,10 +67,10 @@ void wf::pointing_device_t::update_options() auto dev = wlr_libinput_get_device_handle(get_wlr_handle()); assert(dev); - libinput_device_config_left_handed_set(dev, config.left_handed_mode); + libinput_device_config_left_handed_set(dev, left_handed_mode); libinput_device_config_middle_emulation_set_enabled(dev, - config.middle_emulation ? + middle_emulation ? LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED : LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED); @@ -74,82 +78,82 @@ void wf::pointing_device_t::update_options() if (libinput_device_config_tap_get_finger_count(dev) > 0) { libinput_device_config_accel_set_speed(dev, - config.touchpad_cursor_speed); + touchpad_cursor_speed); - set_libinput_accel_profile(dev, config.touchpad_accel_profile); + set_libinput_accel_profile(dev, touchpad_accel_profile); libinput_device_config_tap_set_enabled(dev, - config.touchpad_tap_enabled ? + touchpad_tap_enabled ? LIBINPUT_CONFIG_TAP_ENABLED : LIBINPUT_CONFIG_TAP_DISABLED); - if ((std::string)config.touchpad_click_method == "default") + if ((std::string)touchpad_click_method == "default") { libinput_device_config_click_set_method(dev, libinput_device_config_click_get_default_method(dev)); - } else if ((std::string)config.touchpad_click_method == "none") + } else if ((std::string)touchpad_click_method == "none") { libinput_device_config_click_set_method(dev, LIBINPUT_CONFIG_CLICK_METHOD_NONE); - } else if ((std::string)config.touchpad_click_method == "button-areas") + } else if ((std::string)touchpad_click_method == "button-areas") { libinput_device_config_click_set_method(dev, LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS); - } else if ((std::string)config.touchpad_click_method == "clickfinger") + } else if ((std::string)touchpad_click_method == "clickfinger") { libinput_device_config_click_set_method(dev, LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER); } - if ((std::string)config.touchpad_scroll_method == "default") + if ((std::string)touchpad_scroll_method == "default") { libinput_device_config_scroll_set_method(dev, libinput_device_config_scroll_get_default_method(dev)); - } else if ((std::string)config.touchpad_scroll_method == "none") + } else if ((std::string)touchpad_scroll_method == "none") { libinput_device_config_scroll_set_method(dev, LIBINPUT_CONFIG_SCROLL_NO_SCROLL); - } else if ((std::string)config.touchpad_scroll_method == "two-finger") + } else if ((std::string)touchpad_scroll_method == "two-finger") { libinput_device_config_scroll_set_method(dev, LIBINPUT_CONFIG_SCROLL_2FG); - } else if ((std::string)config.touchpad_scroll_method == "edge") + } else if ((std::string)touchpad_scroll_method == "edge") { libinput_device_config_scroll_set_method(dev, LIBINPUT_CONFIG_SCROLL_EDGE); - } else if ((std::string)config.touchpad_scroll_method == "on-button-down") + } else if ((std::string)touchpad_scroll_method == "on-button-down") { libinput_device_config_scroll_set_method(dev, LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN); } libinput_device_config_dwt_set_enabled(dev, - config.touchpad_dwt_enabled ? + touchpad_dwt_enabled ? LIBINPUT_CONFIG_DWT_ENABLED : LIBINPUT_CONFIG_DWT_DISABLED); libinput_device_config_send_events_set_mode(dev, - config.touchpad_dwmouse_enabled ? + touchpad_dwmouse_enabled ? LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE : LIBINPUT_CONFIG_SEND_EVENTS_ENABLED); libinput_device_config_tap_set_drag_lock_enabled(dev, - config.touchpad_drag_lock_enabled ? + touchpad_drag_lock_enabled ? LIBINPUT_CONFIG_DRAG_LOCK_ENABLED : LIBINPUT_CONFIG_DRAG_LOCK_DISABLED); if (libinput_device_config_scroll_has_natural_scroll(dev) > 0) { libinput_device_config_scroll_set_natural_scroll_enabled(dev, - (bool)config.touchpad_natural_scroll_enabled); + (bool)touchpad_natural_scroll_enabled); } } else { libinput_device_config_accel_set_speed(dev, - config.mouse_cursor_speed); - set_libinput_accel_profile(dev, config.mouse_accel_profile); + mouse_cursor_speed); + set_libinput_accel_profile(dev, mouse_accel_profile); if (libinput_device_config_scroll_has_natural_scroll(dev) > 0) { libinput_device_config_scroll_set_natural_scroll_enabled(dev, - (bool)config.mouse_natural_scroll_enabled); + (bool)mouse_natural_scroll_enabled); } } } diff --git a/src/core/seat/pointing-device.hpp b/src/core/seat/pointing-device.hpp index 1a74e376a..2c8e46f56 100644 --- a/src/core/seat/pointing-device.hpp +++ b/src/core/seat/pointing-device.hpp @@ -10,29 +10,26 @@ struct pointing_device_t : public input_device_impl_t pointing_device_t(wlr_input_device *dev); virtual ~pointing_device_t() = default; + void load_options(); void update_options() override; - static struct config_t - { - wf::option_wrapper_t left_handed_mode; - wf::option_wrapper_t middle_emulation; - wf::option_wrapper_t mouse_cursor_speed; - wf::option_wrapper_t mouse_scroll_speed; - wf::option_wrapper_t tablet_motion_mode; - wf::option_wrapper_t touchpad_cursor_speed; - wf::option_wrapper_t touchpad_scroll_speed; - wf::option_wrapper_t touchpad_click_method; - wf::option_wrapper_t touchpad_scroll_method; - wf::option_wrapper_t touchpad_accel_profile; - wf::option_wrapper_t mouse_accel_profile; - wf::option_wrapper_t touchpad_tap_enabled; - wf::option_wrapper_t touchpad_dwt_enabled; - wf::option_wrapper_t touchpad_dwmouse_enabled; - wf::option_wrapper_t touchpad_natural_scroll_enabled; - wf::option_wrapper_t mouse_natural_scroll_enabled; - wf::option_wrapper_t touchpad_drag_lock_enabled; - void load(); - } config; + wf::option_wrapper_t left_handed_mode; + wf::option_wrapper_t middle_emulation; + wf::option_wrapper_t mouse_cursor_speed; + wf::option_wrapper_t mouse_scroll_speed; + wf::option_wrapper_t tablet_motion_mode; + wf::option_wrapper_t touchpad_cursor_speed; + wf::option_wrapper_t touchpad_scroll_speed; + wf::option_wrapper_t touchpad_click_method; + wf::option_wrapper_t touchpad_scroll_method; + wf::option_wrapper_t touchpad_accel_profile; + wf::option_wrapper_t mouse_accel_profile; + wf::option_wrapper_t touchpad_tap_enabled; + wf::option_wrapper_t touchpad_dwt_enabled; + wf::option_wrapper_t touchpad_dwmouse_enabled; + wf::option_wrapper_t touchpad_natural_scroll_enabled; + wf::option_wrapper_t mouse_natural_scroll_enabled; + wf::option_wrapper_t touchpad_drag_lock_enabled; }; }