diff --git a/src/config/ConfigDescriptions.hpp b/src/config/ConfigDescriptions.hpp index 23635760df2..1283050d9c8 100644 --- a/src/config/ConfigDescriptions.hpp +++ b/src/config/ConfigDescriptions.hpp @@ -501,6 +501,12 @@ inline static const std::vector CONFIG_OPTIONS = { .type = CONFIG_OPTION_INT, .data = SConfigOptionDescription::SRangeData{1, 0, 3}, }, + SConfigOptionDescription{ + .value = "input:follow_mouse_threshold", + .description = "The smallest distance in logical pixels the mouse needs to travel for the window under it to get focused. Works only with follow_mouse = 1.", + .type = CONFIG_OPTION_FLOAT, + .data = SConfigOptionDescription::SFloatData{}, + }, SConfigOptionDescription{ .value = "input:focus_on_close", .description = "Controls the window focus behavior when a window is closed. When set to 0, focus will shift to the next window candidate. When set to 1, focus will shift " diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 00dba2003c7..dc56d73fd4b 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -539,6 +539,7 @@ CConfigManager::CConfigManager() { m_pConfig->addConfigValue("animations:first_launch_animation", Hyprlang::INT{1}); m_pConfig->addConfigValue("input:follow_mouse", Hyprlang::INT{1}); + m_pConfig->addConfigValue("input:follow_mouse_threshold", Hyprlang::FLOAT{0}); m_pConfig->addConfigValue("input:focus_on_close", Hyprlang::INT{0}); m_pConfig->addConfigValue("input:mouse_refocus", Hyprlang::INT{1}); m_pConfig->addConfigValue("input:special_fallthrough", Hyprlang::INT{0}); diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp index 3d8c6de8e71..1d16f9151f4 100644 --- a/src/managers/input/InputManager.cpp +++ b/src/managers/input/InputManager.cpp @@ -161,17 +161,23 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool mouse) { if (MOUSECOORDSFLOORED == m_vLastCursorPosFloored && !refocus) return; - static auto PFOLLOWMOUSE = CConfigValue("input:follow_mouse"); - static auto PMOUSEREFOCUS = CConfigValue("input:mouse_refocus"); - static auto PFOLLOWONDND = CConfigValue("misc:always_follow_on_dnd"); - static auto PFLOATBEHAVIOR = CConfigValue("input:float_switch_override_focus"); - static auto PMOUSEFOCUSMON = CConfigValue("misc:mouse_move_focuses_monitor"); - static auto PRESIZEONBORDER = CConfigValue("general:resize_on_border"); - static auto PRESIZECURSORICON = CConfigValue("general:hover_icon_on_border"); - static auto PZOOMFACTOR = CConfigValue("cursor:zoom_factor"); + static auto PFOLLOWMOUSE = CConfigValue("input:follow_mouse"); + static auto PFOLLOWMOUSETHRESHOLD = CConfigValue("input:follow_mouse_threshold"); + static auto PMOUSEREFOCUS = CConfigValue("input:mouse_refocus"); + static auto PFOLLOWONDND = CConfigValue("misc:always_follow_on_dnd"); + static auto PFLOATBEHAVIOR = CConfigValue("input:float_switch_override_focus"); + static auto PMOUSEFOCUSMON = CConfigValue("misc:mouse_move_focuses_monitor"); + static auto PRESIZEONBORDER = CConfigValue("general:resize_on_border"); + static auto PRESIZECURSORICON = CConfigValue("general:hover_icon_on_border"); + static auto PZOOMFACTOR = CConfigValue("cursor:zoom_factor"); const auto FOLLOWMOUSE = *PFOLLOWONDND && PROTO::data->dndActive() ? 1 : *PFOLLOWMOUSE; + if (FOLLOWMOUSE == 1 && m_tmrLastCursorMovement.getSeconds() < 0.5) + m_fMousePosDelta += MOUSECOORDSFLOORED.distance(m_vLastCursorPosFloored); + else + m_fMousePosDelta = 0; + m_pFoundSurfaceToFocus.reset(); m_pFoundLSToFocus.reset(); m_pFoundWindowToFocus.reset(); @@ -513,9 +519,10 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool mouse) { // TODO: this looks wrong. When over a popup, it constantly is switching. // Temp fix until that's figured out. Otherwise spams windowrule lookups and other shit. - if (m_pLastMouseFocus.lock() != pFoundWindow || g_pCompositor->m_pLastWindow.lock() != pFoundWindow) - g_pCompositor->focusWindow(pFoundWindow, foundSurface); - else + if (m_pLastMouseFocus.lock() != pFoundWindow || g_pCompositor->m_pLastWindow.lock() != pFoundWindow) { + if (m_fMousePosDelta > *PFOLLOWMOUSETHRESHOLD || refocus) + g_pCompositor->focusWindow(pFoundWindow, foundSurface); + } else g_pCompositor->focusSurface(foundSurface, pFoundWindow); } } diff --git a/src/managers/input/InputManager.hpp b/src/managers/input/InputManager.hpp index 3afb1b887b7..7774a6db8b7 100644 --- a/src/managers/input/InputManager.hpp +++ b/src/managers/input/InputManager.hpp @@ -255,6 +255,7 @@ class CInputManager { // used for warping back after non-mouse input Vector2D m_vLastMousePos = {}; + double m_fMousePosDelta = 0; bool m_bLastInputMouse = true; // for holding focus on buttons held