diff options
| author | Vaxry <43317083+vaxerski@users.noreply.github.com> | 2025-09-02 13:16:43 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-09-02 13:16:43 +0200 |
| commit | 127aab815908ecbd3db4d23f127d2e96b79855f9 (patch) | |
| tree | 289ee3e7c9be70c3b45ff91a693b33fe7598502a /src | |
| parent | 78e86d879fa9bf3afeb73b29a3e668d47df5e9ab (diff) | |
input: add per-device scroll-factor (#11241)
Diffstat (limited to 'src')
| -rw-r--r-- | src/config/ConfigManager.cpp | 10 | ||||
| -rw-r--r-- | src/config/ConfigManager.hpp | 1 | ||||
| -rw-r--r-- | src/debug/HyprCtl.cpp | 10 | ||||
| -rw-r--r-- | src/desktop/Window.cpp | 8 | ||||
| -rw-r--r-- | src/desktop/Window.hpp | 2 | ||||
| -rw-r--r-- | src/devices/IPointer.hpp | 15 | ||||
| -rw-r--r-- | src/managers/PointerManager.cpp | 4 | ||||
| -rw-r--r-- | src/managers/input/InputManager.cpp | 26 | ||||
| -rw-r--r-- | src/managers/input/InputManager.hpp | 3 |
9 files changed, 60 insertions, 19 deletions
diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 9277b89b..16183498 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -810,6 +810,7 @@ CConfigManager::CConfigManager() { m_config->addSpecialConfigValue("device", "scroll_button", Hyprlang::INT{0}); m_config->addSpecialConfigValue("device", "scroll_button_lock", Hyprlang::INT{0}); m_config->addSpecialConfigValue("device", "scroll_points", {STRVAL_EMPTY}); + m_config->addSpecialConfigValue("device", "scroll_factor", Hyprlang::FLOAT{-1}); m_config->addSpecialConfigValue("device", "transform", Hyprlang::INT{-1}); m_config->addSpecialConfigValue("device", "output", {STRVAL_EMPTY}); m_config->addSpecialConfigValue("device", "enabled", Hyprlang::INT{1}); // only for mice, touchpads, and touchdevices @@ -1335,13 +1336,18 @@ Hyprlang::CConfigValue* CConfigManager::getConfigValueSafeDevice(const std::stri const auto VAL = m_config->getSpecialConfigValuePtr("device", val.c_str(), dev.c_str()); - if ((!VAL || !VAL->m_bSetByUser) && !fallback.empty()) { + if ((!VAL || !VAL->m_bSetByUser) && !fallback.empty()) return m_config->getConfigValuePtr(fallback.c_str()); - } return VAL; } +bool CConfigManager::deviceConfigExplicitlySet(const std::string& dev, const std::string& val) { + const auto VAL = m_config->getSpecialConfigValuePtr("device", val.c_str(), dev.c_str()); + + return VAL && VAL->m_bSetByUser; +} + int CConfigManager::getDeviceInt(const std::string& dev, const std::string& v, const std::string& fallback) { return std::any_cast<Hyprlang::INT>(getConfigValueSafeDevice(dev, v, fallback)->getValue()); } diff --git a/src/config/ConfigManager.hpp b/src/config/ConfigManager.hpp index fe1adc50..cff146f3 100644 --- a/src/config/ConfigManager.hpp +++ b/src/config/ConfigManager.hpp @@ -210,6 +210,7 @@ class CConfigManager { float getDeviceFloat(const std::string&, const std::string&, const std::string& fallback = ""); Vector2D getDeviceVec(const std::string&, const std::string&, const std::string& fallback = ""); std::string getDeviceString(const std::string&, const std::string&, const std::string& fallback = ""); + bool deviceConfigExplicitlySet(const std::string&, const std::string&); bool deviceConfigExists(const std::string&); Hyprlang::CConfigValue* getConfigValueSafeDevice(const std::string& dev, const std::string& val, const std::string& fallback); bool shouldBlurLS(const std::string&); diff --git a/src/debug/HyprCtl.cpp b/src/debug/HyprCtl.cpp index a9388789..8598b1f6 100644 --- a/src/debug/HyprCtl.cpp +++ b/src/debug/HyprCtl.cpp @@ -722,10 +722,11 @@ static std::string devicesRequest(eHyprCtlOutputFormat format, std::string reque R"#( {{ "address": "0x{:x}", "name": "{}", - "defaultSpeed": {:.5f} + "defaultSpeed": {:.5f}, + "scrollFactor": {:.2f} }},)#", rc<uintptr_t>(m.get()), escapeJSONStrings(m->m_hlName), - m->aq() && m->aq()->getLibinputHandle() ? libinput_device_config_accel_get_default_speed(m->aq()->getLibinputHandle()) : 0.f); + m->aq() && m->aq()->getLibinputHandle() ? libinput_device_config_accel_get_default_speed(m->aq()->getLibinputHandle()) : 0.f, m->m_scrollFactor.value_or(-1)); } trimTrailingComma(result); @@ -826,8 +827,9 @@ static std::string devicesRequest(eHyprCtlOutputFormat format, std::string reque result += "mice:\n"; for (auto const& m : g_pInputManager->m_pointers) { - result += std::format("\tMouse at {:x}:\n\t\t{}\n\t\t\tdefault speed: {:.5f}\n", rc<uintptr_t>(m.get()), m->m_hlName, - (m->aq() && m->aq()->getLibinputHandle() ? libinput_device_config_accel_get_default_speed(m->aq()->getLibinputHandle()) : 0.f)); + result += std::format("\tMouse at {:x}:\n\t\t{}\n\t\t\tdefault speed: {:.5f}\n\t\t\tscroll factor: {:.2f}\n", rc<uintptr_t>(m.get()), m->m_hlName, + (m->aq() && m->aq()->getLibinputHandle() ? libinput_device_config_accel_get_default_speed(m->aq()->getLibinputHandle()) : 0.f), + m->m_scrollFactor.value_or(-1)); } result += "\n\nKeyboards:\n"; diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp index 3c952005..78f12a11 100644 --- a/src/desktop/Window.cpp +++ b/src/desktop/Window.cpp @@ -1249,6 +1249,14 @@ float CWindow::getScrollTouchpad() { return m_windowData.scrollTouchpad.valueOr(*PTOUCHPADSCROLLFACTOR); } +bool CWindow::isScrollMouseOverridden() { + return m_windowData.scrollMouse.hasValue(); +} + +bool CWindow::isScrollTouchpadOverridden() { + return m_windowData.scrollTouchpad.hasValue(); +} + bool CWindow::canBeTorn() { static auto PTEARING = CConfigValue<Hyprlang::INT>("general:allow_tearing"); return m_windowData.tearing.valueOr(m_tearingHint) && *PTEARING; diff --git a/src/desktop/Window.hpp b/src/desktop/Window.hpp index e58d4fb6..9d94baea 100644 --- a/src/desktop/Window.hpp +++ b/src/desktop/Window.hpp @@ -363,6 +363,8 @@ class CWindow { int getRealBorderSize(); float getScrollMouse(); float getScrollTouchpad(); + bool isScrollMouseOverridden(); + bool isScrollTouchpadOverridden(); void updateWindowData(); void updateWindowData(const struct SWorkspaceRule&); void onBorderAngleAnimEnd(WP<Hyprutils::Animation::CBaseAnimatedVariable> pav); diff --git a/src/devices/IPointer.hpp b/src/devices/IPointer.hpp index e5d76344..197ba123 100644 --- a/src/devices/IPointer.hpp +++ b/src/devices/IPointer.hpp @@ -108,11 +108,12 @@ class IPointer : public IHID { CSignalT<SHoldEndEvent> holdEnd; } m_pointerEvents; - bool m_connected = false; // means connected to the cursor - std::string m_boundOutput = ""; - bool m_flipX = false; // decide to invert horizontal movement - bool m_flipY = false; // decide to invert vertical movement - bool m_isTouchpad = false; - - WP<IPointer> m_self; + bool m_connected = false; // means connected to the cursor + std::string m_boundOutput = ""; + bool m_flipX = false; // decide to invert horizontal movement + bool m_flipY = false; // decide to invert vertical movement + bool m_isTouchpad = false; + std::optional<float> m_scrollFactor = {}; + + WP<IPointer> m_self; }; diff --git a/src/managers/PointerManager.cpp b/src/managers/PointerManager.cpp index 093c751d..aeabe412 100644 --- a/src/managers/PointerManager.cpp +++ b/src/managers/PointerManager.cpp @@ -919,8 +919,8 @@ void CPointerManager::attachPointer(SP<IPointer> pointer) { PROTO::idle->onActivity(); }); - listener->axis = pointer->m_pointerEvents.axis.listen([](const IPointer::SAxisEvent& event) { - g_pInputManager->onMouseWheel(event); + listener->axis = pointer->m_pointerEvents.axis.listen([weak = WP<IPointer>(pointer)](const IPointer::SAxisEvent& event) { + g_pInputManager->onMouseWheel(event, weak.lock()); PROTO::idle->onActivity(); }); diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp index 5224f940..5e844bec 100644 --- a/src/managers/input/InputManager.cpp +++ b/src/managers/input/InputManager.cpp @@ -835,7 +835,7 @@ void CInputManager::processMouseDownKill(const IPointer::SButtonEvent& e) { m_clickBehavior = CLICKMODE_DEFAULT; } -void CInputManager::onMouseWheel(IPointer::SAxisEvent e) { +void CInputManager::onMouseWheel(IPointer::SAxisEvent e, SP<IPointer> pointer) { static auto POFFWINDOWAXIS = CConfigValue<Hyprlang::INT>("input:off_window_axis_events"); static auto PINPUTSCROLLFACTOR = CConfigValue<Hyprlang::FLOAT>("input:scroll_factor"); static auto PTOUCHPADSCROLLFACTOR = CConfigValue<Hyprlang::FLOAT>("input:touchpad:scroll_factor"); @@ -845,7 +845,10 @@ void CInputManager::onMouseWheel(IPointer::SAxisEvent e) { const bool ISTOUCHPADSCROLL = *PTOUCHPADSCROLLFACTOR <= 0.f || e.source == WL_POINTER_AXIS_SOURCE_FINGER; auto factor = ISTOUCHPADSCROLL ? *PTOUCHPADSCROLLFACTOR : *PINPUTSCROLLFACTOR; - const auto EMAP = std::unordered_map<std::string, std::any>{{"event", e}}; + if (pointer && pointer->m_scrollFactor.has_value()) + factor = *pointer->m_scrollFactor; + + const auto EMAP = std::unordered_map<std::string, std::any>{{"event", e}}; EMIT_HOOK_EVENT_CANCELLABLE("mouseAxis", EMAP); if (e.mouse) @@ -888,7 +891,11 @@ void CInputManager::onMouseWheel(IPointer::SAxisEvent e) { if (*PFOLLOWMOUSE == 1 && PCURRWINDOW && PWINDOW != PCURRWINDOW) simulateMouseMovement(); } - factor = ISTOUCHPADSCROLL ? PWINDOW->getScrollTouchpad() : PWINDOW->getScrollMouse(); + + if (!ISTOUCHPADSCROLL && PWINDOW->isScrollMouseOverridden()) + factor = PWINDOW->getScrollMouse(); + else if (ISTOUCHPADSCROLL && PWINDOW->isScrollTouchpadOverridden()) + factor = PWINDOW->getScrollTouchpad(); } } @@ -1117,6 +1124,14 @@ void CInputManager::newVirtualMouse(SP<CVirtualPointerV1Resource> mouse) { Debug::log(LOG, "New virtual mouse created"); } +void CInputManager::newMouse(SP<IPointer> mouse) { + m_pointers.emplace_back(mouse); + + setupMouse(mouse); + + Debug::log(LOG, "New mouse created, pointer Hypr: {:x}", rc<uintptr_t>(mouse.get())); +} + void CInputManager::newMouse(SP<Aquamarine::IPointer> mouse) { const auto PMOUSE = m_pointers.emplace_back(CMouse::create(mouse)); @@ -1172,6 +1187,11 @@ void CInputManager::setPointerConfigs() { } } + if (g_pConfigManager->deviceConfigExplicitlySet(devname, "scroll_factor")) + m->m_scrollFactor = std::clamp(g_pConfigManager->getDeviceFloat(devname, "scroll_factor", "input:scroll_factor"), 0.F, 100.F); + else + m->m_scrollFactor = std::nullopt; + if (m->aq() && m->aq()->getLibinputHandle()) { const auto LIBINPUTDEV = m->aq()->getLibinputHandle(); diff --git a/src/managers/input/InputManager.hpp b/src/managers/input/InputManager.hpp index 56751cf5..60ff49ef 100644 --- a/src/managers/input/InputManager.hpp +++ b/src/managers/input/InputManager.hpp @@ -90,13 +90,14 @@ class CInputManager { void onMouseMoved(IPointer::SMotionEvent); void onMouseWarp(IPointer::SMotionAbsoluteEvent); void onMouseButton(IPointer::SButtonEvent); - void onMouseWheel(IPointer::SAxisEvent); + void onMouseWheel(IPointer::SAxisEvent, SP<IPointer> pointer = nullptr); void onKeyboardKey(const IKeyboard::SKeyEvent&, SP<IKeyboard>); void onKeyboardMod(SP<IKeyboard>); void newKeyboard(SP<IKeyboard>); void newKeyboard(SP<Aquamarine::IKeyboard>); void newVirtualKeyboard(SP<CVirtualKeyboardV1Resource>); + void newMouse(SP<IPointer>); void newMouse(SP<Aquamarine::IPointer>); void newVirtualMouse(SP<CVirtualPointerV1Resource>); void newTouchDevice(SP<Aquamarine::ITouch>); |
