diff options
| author | Mihail Costea <mihail.costea@dealfront.com> | 2026-04-20 18:56:30 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-04-20 16:56:30 +0100 |
| commit | e12d2b7cc846485a172444c2e5288c55fa3a3c59 (patch) | |
| tree | 34ee6c646d31160c686a029ae1ca634bb1e6bfad /src/Compositor.cpp | |
| parent | a360c31d0434898888e710f4a5f560200f50cecf (diff) | |
input: implement follow_mouse_shrink (#13707)
* input: implement follow_mouse_shrink
Add a new config option `input:follow_mouse_shrink` (INT, 0-300, default 0)
that shrinks inactive window hitboxes by the specified number of pixels for
focus detection purposes. This creates a dead zone in gaps between windows
where moving the cursor will not trigger a focus change.
The shrink only applies to inactive (non-focused) windows and only during
mouse-move focus checks (follow_mouse = 1). Click and scroll interactions
are unaffected — clicking on a window in the shrunk area still works
normally once the window is focused.
Closes #9973
* tests: add integration test for follow_mouse_shrink
Diffstat (limited to 'src/Compositor.cpp')
| -rw-r--r-- | src/Compositor.cpp | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 92f81fc6..f823b62c 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -895,7 +895,7 @@ bool CCompositor::monitorExists(PHLMONITOR pMonitor) { return std::ranges::any_of(m_realMonitors, [&](const PHLMONITOR& m) { return m == pMonitor; }); } -PHLWINDOW CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t properties, PHLWINDOW pIgnoreWindow) { +PHLWINDOW CCompositor::vectorToWindowUnified(const Vector2D& pos, uint16_t properties, PHLWINDOW pIgnoreWindow) { const auto PMONITOR = getMonitorFromVector(pos); if (!PMONITOR) return nullptr; @@ -905,8 +905,12 @@ PHLWINDOW CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t proper static auto PBORDERGRABEXTEND = CConfigValue<Hyprlang::INT>("general:extend_border_grab_area"); static auto PSPECIALFALLTHRU = CConfigValue<Hyprlang::INT>("input:special_fallthrough"); static auto PMODALPARENTBLOCKING = CConfigValue<Hyprlang::INT>("general:modal_parent_blocking"); + static auto PFOLLOWMOUSESHRINK = CConfigValue<Hyprlang::INT>("input:follow_mouse_shrink"); const auto BORDER_GRAB_AREA = *PRESIZEONBORDER ? *PBORDERSIZE + *PBORDERGRABEXTEND : 0; const bool ONLY_PRIORITY = properties & Desktop::View::FOCUS_PRIORITY; + const bool FOLLOW_MOUSE_CHECK = properties & Desktop::View::FOLLOW_MOUSE_CHECK; + const auto HITBOX_SHRINK = FOLLOW_MOUSE_CHECK ? *PFOLLOWMOUSESHRINK : 0; + const auto LASTFOCUSED = Desktop::focusState()->window(); const auto isShadowedByModal = [](PHLWINDOW w) -> bool { return *PMODALPARENTBLOCKING && w->m_xdgSurface && w->m_xdgSurface->m_toplevel && w->m_xdgSurface->m_toplevel->anyChildModal(); @@ -922,6 +926,8 @@ PHLWINDOW CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t proper w != pIgnoreWindow && !isShadowedByModal(w)) { const auto BB = w->getWindowBoxUnified(properties); CBox box = BB.copy().expand(!w->isX11OverrideRedirect() ? BORDER_GRAB_AREA : 0); + if (HITBOX_SHRINK > 0 && w != LASTFOCUSED) + box = box.copy().expand(-HITBOX_SHRINK); if (box.containsPoint(pos)) return w; @@ -964,6 +970,8 @@ PHLWINDOW CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t proper const auto BB = w->getWindowBoxUnified(properties); CBox box = BB.copy().expand(!w->isX11OverrideRedirect() ? BORDER_GRAB_AREA : 0); + if (HITBOX_SHRINK > 0 && w != LASTFOCUSED) + box = box.copy().expand(-HITBOX_SHRINK); if (box.containsPoint(pos)) { if (w->m_isX11 && w->isX11OverrideRedirect() && !w->m_xwaylandSurface->wantsFocus()) { @@ -1095,6 +1103,8 @@ PHLWINDOW CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t proper if (isWindowCloseToWorkAreaEdge(Math::eDirection::DIRECTION_DOWN)) box.height += BORDER_GRAB_AREA; } + if (HITBOX_SHRINK > 0 && w != LASTFOCUSED) + box = box.copy().expand(-HITBOX_SHRINK); if (box.containsPoint(pos)) return w; } |
