summaryrefslogtreecommitdiff
path: root/src/managers/input
diff options
context:
space:
mode:
authorfazzi <18248986+fxzzi@users.noreply.github.com>2026-05-02 20:34:43 +0100
committerGitHub <noreply@github.com>2026-05-02 20:34:43 +0100
commite180c59b467bad2002efc7770acd4bfd5437da1b (patch)
treecf05591642fae0eb449e6c8466404aa26c48d804 /src/managers/input
parent30cd345addf0412baf87b71ad7213508c534e334 (diff)
desktop/windowRule: add `confine_pointer` window rule (#13379)
Diffstat (limited to 'src/managers/input')
-rw-r--r--src/managers/input/InputManager.cpp65
1 files changed, 42 insertions, 23 deletions
diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp
index 7ed7b4f6..2f9b64a3 100644
--- a/src/managers/input/InputManager.cpp
+++ b/src/managers/input/InputManager.cpp
@@ -265,31 +265,50 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool mouse, st
g_pCompositor->scheduleFrameForMonitor(PMONITOR, Aquamarine::IOutput::AQ_SCHEDULE_CURSOR_MOVE);
// constraints
- if (!overridePos.has_value() && !g_pSeatManager->m_mouse.expired() && isConstrained()) {
- const auto SURF = Desktop::View::CWLSurface::fromResource(Desktop::focusState()->surface());
- const auto CONSTRAINT = SURF ? SURF->constraint() : nullptr;
-
- if (CONSTRAINT) {
- if (CONSTRAINT->isLocked()) {
- const auto HINT = CONSTRAINT->logicPositionHint();
- g_pCompositor->warpCursorTo(HINT, true);
- } else {
- const auto RG = CONSTRAINT->logicConstraintRegion();
- const auto CLOSEST = RG.closestPoint(mouseCoords);
- const auto BOX = SURF->getSurfaceBoxGlobal();
- const auto WINDOW = Desktop::View::CWindow::fromView(SURF->view());
- const auto CLOSESTLOCAL = (CLOSEST - (BOX.has_value() ? BOX->pos() : Vector2D{})) * (WINDOW ? WINDOW->m_X11SurfaceScaledBy : 1.0);
-
- g_pCompositor->warpCursorTo(CLOSEST, true);
- g_pSeatManager->sendPointerMotion(time, CLOSESTLOCAL);
- PROTO::relativePointer->sendRelativeMotion(sc<uint64_t>(time) * 1000, {}, {});
- }
+ auto confineToRegion = [&](const CRegion& rg, SP<Desktop::View::CWLSurface> surf) {
+ const auto CLOSEST = rg.closestPoint(mouseCoords);
+ const auto BOX = surf->getSurfaceBoxGlobal();
+ const auto WINDOW = Desktop::View::CWindow::fromView(surf->view());
+ const auto CLOSESTLOCAL = (CLOSEST - (BOX.has_value() ? BOX->pos() : Vector2D{})) * (WINDOW ? WINDOW->m_X11SurfaceScaledBy : 1.0);
+
+ g_pCompositor->warpCursorTo(CLOSEST, true);
+ g_pSeatManager->sendPointerMotion(time, CLOSESTLOCAL);
+ PROTO::relativePointer->sendRelativeMotion(sc<uint64_t>(time) * 1000, {}, {});
+ };
- return;
+ if (!g_pSeatManager->m_mouse.expired()) {
+ const auto SURF = Desktop::View::CWLSurface::fromResource(Desktop::focusState()->surface());
+
+ if (isConstrained()) {
+ const auto CONSTRAINT = SURF ? SURF->constraint() : nullptr;
- } else
- Log::logger->log(Log::ERR, "BUG THIS: Null SURF/CONSTRAINT in mouse refocus. Ignoring constraints. {:x} {:x}", rc<uintptr_t>(SURF.get()),
- rc<uintptr_t>(CONSTRAINT.get()));
+ if (CONSTRAINT) {
+ if (CONSTRAINT->isLocked()) {
+ const auto HINT = CONSTRAINT->logicPositionHint();
+ g_pCompositor->warpCursorTo(HINT, true);
+ } else {
+ confineToRegion(CONSTRAINT->logicConstraintRegion(), SURF);
+ }
+
+ return;
+ } else {
+ Log::logger->log(Log::ERR, "BUG THIS: Null SURF/CONSTRAINT in mouse refocus. Ignoring constraints. {:x} {:x}", rc<uintptr_t>(SURF.get()),
+ rc<uintptr_t>(CONSTRAINT.get()));
+ }
+ } else {
+ const auto WINDOW = SURF ? Desktop::View::CWindow::fromView(SURF->view()) : nullptr;
+ if (WINDOW) {
+ if (WINDOW->m_ruleApplicator->confinePointer().valueOrDefault()) {
+ const auto BOX = SURF->getSurfaceBoxGlobal();
+ if (BOX.has_value()) {
+ CRegion rg;
+ rg.set(*BOX);
+ confineToRegion(rg, SURF);
+ }
+ return;
+ }
+ }
+ }
}
if (PMONITOR != Desktop::focusState()->monitor() && (*PMOUSEFOCUSMON || refocus) && m_forcedFocus.expired())