From 62f4503f07066762af9546bb4a2acdd58b72d4bf Mon Sep 17 00:00:00 2001 From: vaxerski <43317083+vaxerski@users.noreply.github.com> Date: Sat, 10 Dec 2022 14:43:46 +0000 Subject: [PATCH] handle constraint cursor hints better --- src/events/Devices.cpp | 13 ++++++++---- src/helpers/WLClasses.hpp | 3 +++ src/managers/input/InputManager.cpp | 33 ++++++++++++++++++++++++----- src/managers/input/InputManager.hpp | 1 + 4 files changed, 41 insertions(+), 9 deletions(-) diff --git a/src/events/Devices.cpp b/src/events/Devices.cpp index 6ab23a67..146c8c54 100644 --- a/src/events/Devices.cpp +++ b/src/events/Devices.cpp @@ -110,6 +110,11 @@ void Events::listener_newConstraint(wl_listener* listener, void* data) { if (g_pCompositor->m_pLastFocus == PCONSTRAINT->surface) { g_pInputManager->constrainMouse(CONSTRAINT->pMouse, PCONSTRAINT); + + if (!CONSTRAINT->hintSet) { + const auto PWINDOW = g_pCompositor->getConstraintWindow(g_pCompositor->m_sSeat.mouse); + CONSTRAINT->positionHint = g_pInputManager->getMouseCoordsInternal() - PWINDOW->m_vRealPosition.goalv(); + } } } @@ -124,14 +129,14 @@ void Events::listener_destroyConstraint(void* owner, void* data) { if (PWINDOW) { if (PWINDOW->m_bIsX11) { wlr_cursor_warp(g_pCompositor->m_sWLRCursor, nullptr, - PCONSTRAINT->constraint->current.cursor_hint.x + PWINDOW->m_uSurface.xwayland->x, PWINDOW->m_uSurface.xwayland->y + PCONSTRAINT->constraint->current.cursor_hint.y); + PCONSTRAINT->positionHint.x + PWINDOW->m_uSurface.xwayland->x, PWINDOW->m_uSurface.xwayland->y + PCONSTRAINT->positionHint.y); - wlr_seat_pointer_warp(PCONSTRAINT->constraint->seat, PCONSTRAINT->constraint->current.cursor_hint.x, PCONSTRAINT->constraint->current.cursor_hint.y); + wlr_seat_pointer_warp(PCONSTRAINT->constraint->seat, PCONSTRAINT->positionHint.x, PCONSTRAINT->positionHint.y); } else { wlr_cursor_warp(g_pCompositor->m_sWLRCursor, nullptr, - PCONSTRAINT->constraint->current.cursor_hint.x + PWINDOW->m_vRealPosition.vec().x, PCONSTRAINT->constraint->current.cursor_hint.y + PWINDOW->m_vRealPosition.vec().y); + PCONSTRAINT->positionHint.x + PWINDOW->m_vRealPosition.vec().x, PCONSTRAINT->positionHint.y + PWINDOW->m_vRealPosition.vec().y); - wlr_seat_pointer_warp(PCONSTRAINT->constraint->seat, PCONSTRAINT->constraint->current.cursor_hint.x, PCONSTRAINT->constraint->current.cursor_hint.y); + wlr_seat_pointer_warp(PCONSTRAINT->constraint->seat, PCONSTRAINT->positionHint.x, PCONSTRAINT->positionHint.y); } } diff --git a/src/helpers/WLClasses.hpp b/src/helpers/WLClasses.hpp index 66581077..1461e481 100644 --- a/src/helpers/WLClasses.hpp +++ b/src/helpers/WLClasses.hpp @@ -146,6 +146,9 @@ struct SConstraint { SMouse* pMouse = nullptr; wlr_pointer_constraint_v1* constraint = nullptr; + bool hintSet = false; + Vector2D positionHint; // the position hint, but will be set to the current cursor pos if not set. + DYNLISTENER(setConstraintRegion); DYNLISTENER(destroyConstraint); diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp index e8e22343..51d5d4e2 100644 --- a/src/managers/input/InputManager.cpp +++ b/src/managers/input/InputManager.cpp @@ -73,9 +73,9 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) { // XWayland windows sometimes issue constraints weirdly. // TODO: We probably should search their parent. wlr_xwayland_surface->parent const auto CONSTRAINTWINDOW = g_pCompositor->getConstraintWindow(g_pCompositor->m_sSeat.mouse); - const auto PCONSTRAINT = g_pCompositor->m_sSeat.mouse->currentConstraint; + const auto PCONSTRAINT = constraintFromWlr(g_pCompositor->m_sSeat.mouse->currentConstraint); - if (!CONSTRAINTWINDOW) { + if (!CONSTRAINTWINDOW || !PCONSTRAINT) { unconstrainMouse(); } else { // Native Wayland apps know how 2 constrain themselves. @@ -86,7 +86,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) { if (g_pCompositor->m_sSeat.mouse->currentConstraint->type == WLR_POINTER_CONSTRAINT_V1_LOCKED) { // we just snap the cursor to where it should be. - Vector2D hint = { PCONSTRAINT->current.cursor_hint.x, PCONSTRAINT->current.cursor_hint.y }; + Vector2D hint = { PCONSTRAINT->positionHint.x, PCONSTRAINT->positionHint.y }; wlr_cursor_warp_closest(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sSeat.mouse->mouse, CONSTRAINTPOS.x + hint.x, CONSTRAINTPOS.y + hint.y); @@ -94,7 +94,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) { // these are usually FPS games. They will use the relative motion. } else { // we restrict the cursor to the confined region - if (!pixman_region32_contains_point(&PCONSTRAINT->region, mouseCoords.x - CONSTRAINTPOS.x, mouseCoords.y - CONSTRAINTPOS.y, nullptr)) { + if (!pixman_region32_contains_point(&PCONSTRAINT->constraint->region, mouseCoords.x - CONSTRAINTPOS.x, mouseCoords.y - CONSTRAINTPOS.y, nullptr)) { if (g_pCompositor->m_sSeat.mouse->constraintActive) { wlr_cursor_warp_closest(g_pCompositor->m_sWLRCursor, NULL, mouseCoords.x, mouseCoords.y); mouseCoords = getMouseCoordsInternal(); @@ -964,6 +964,12 @@ void CInputManager::constrainMouse(SMouse* pMouse, wlr_pointer_constraint_v1* co wlr_seat_pointer_warp(constraint->seat, constraint->current.cursor_hint.x, constraint->current.cursor_hint.y); } } + + const auto PCONSTRAINT = constraintFromWlr(constraint); + if (PCONSTRAINT) { // should never be null but who knows + PCONSTRAINT->positionHint = Vector2D(constraint->current.cursor_hint.x, constraint->current.cursor_hint.y); + PCONSTRAINT->hintSet = true; + } } } @@ -1009,7 +1015,15 @@ void CInputManager::unconstrainMouse() { } void Events::listener_commitConstraint(void* owner, void* data) { - //g_pInputManager->recheckConstraint((SMouse*)owner); + const auto PMOUSE = (SMouse*)owner; + + if (PMOUSE->currentConstraint->current.committed & WLR_POINTER_CONSTRAINT_V1_STATE_CURSOR_HINT) { + const auto PCONSTRAINT = g_pInputManager->constraintFromWlr(PMOUSE->currentConstraint); + if (PCONSTRAINT) { // should never be null but who knows + PCONSTRAINT->positionHint = Vector2D(PMOUSE->currentConstraint->current.cursor_hint.x, PMOUSE->currentConstraint->current.cursor_hint.y); + PCONSTRAINT->hintSet = true; + } + } } void CInputManager::updateCapabilities() { @@ -1224,3 +1238,12 @@ std::string CInputManager::getNameForNewDevice(std::string internalName) { return proposedNewName + (dupeno == 0 ? "" : ("-" + std::to_string(dupeno))); } + +SConstraint* CInputManager::constraintFromWlr(wlr_pointer_constraint_v1* constraint) { + for (auto& c : m_lConstraints) { + if (c.constraint == constraint) + return &c; + } + + return nullptr; +} diff --git a/src/managers/input/InputManager.hpp b/src/managers/input/InputManager.hpp index 01f2aec6..5645f163 100644 --- a/src/managers/input/InputManager.hpp +++ b/src/managers/input/InputManager.hpp @@ -50,6 +50,7 @@ public: void constrainMouse(SMouse*, wlr_pointer_constraint_v1*); void recheckConstraint(SMouse*); void unconstrainMouse(); + SConstraint* constraintFromWlr(wlr_pointer_constraint_v1*); std::string getActiveLayoutForKeyboard(SKeyboard*); Vector2D getMouseCoordsInternal();