summaryrefslogtreecommitdiff
path: root/src/Compositor.cpp
diff options
context:
space:
mode:
authorMihail Costea <mihail.costea@dealfront.com>2026-04-20 18:56:30 +0300
committerGitHub <noreply@github.com>2026-04-20 16:56:30 +0100
commite12d2b7cc846485a172444c2e5288c55fa3a3c59 (patch)
tree34ee6c646d31160c686a029ae1ca634bb1e6bfad /src/Compositor.cpp
parenta360c31d0434898888e710f4a5f560200f50cecf (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.cpp12
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;
}