From 027140b7315efe3cd2e7b78fa608bd36da839894 Mon Sep 17 00:00:00 2001 From: Maximilian Seidler <78690852+PaideiaDilemma@users.noreply.github.com> Date: Wed, 4 Sep 2024 15:59:00 +0000 Subject: [PATCH] sessionLock: ensure sls focus in some edge cases (#7647) * input: return early in mouseMoveUnified when the session is locked * sessionLock: make make a commit an opportunity to focus session lock surfaces * compositor: allow resetting focus when session is locked * input: remove redundant PMONITOR checks PMONITOR is checked above * input: check isSessionLocked earlier in mouseMoveUnified A bit of reordering, so that we don't call some stuff that is irrelevant when the session is locked --- src/Compositor.cpp | 2 +- src/managers/SessionLockManager.cpp | 3 ++ src/managers/input/InputManager.cpp | 56 ++++++++++++++--------------- 3 files changed, 32 insertions(+), 29 deletions(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index eac75bd4..ba9ff96b 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -1117,7 +1117,7 @@ void CCompositor::focusSurface(SP pSurface, PHLWINDOW pWindo if (g_pSeatManager->state.keyboardFocus == pSurface || (pWindowOwner && g_pSeatManager->state.keyboardFocus == pWindowOwner->m_pWLSurface->resource())) return; // Don't focus when already focused on this. - if (g_pSessionLockManager->isSessionLocked() && !g_pSessionLockManager->isSurfaceSessionLock(pSurface)) + if (g_pSessionLockManager->isSessionLocked() && pSurface && !g_pSessionLockManager->isSurfaceSessionLock(pSurface)) return; if (g_pSeatManager->seatGrab && !g_pSeatManager->seatGrab->accepts(pSurface)) { diff --git a/src/managers/SessionLockManager.cpp b/src/managers/SessionLockManager.cpp index 7267b8f2..260a3992 100644 --- a/src/managers/SessionLockManager.cpp +++ b/src/managers/SessionLockManager.cpp @@ -30,6 +30,9 @@ SSessionLockSurface::SSessionLockSurface(SP surface_) : sur listeners.commit = surface_->events.commit.registerListener([this](std::any data) { const auto PMONITOR = g_pCompositor->getMonitorFromID(iMonitorID); + if (mapped && pWlrSurface != g_pCompositor->m_pLastFocus) + g_pInputManager->simulateMouseMovement(); + if (PMONITOR) g_pHyprRenderer->damageMonitor(PMONITOR); }); diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp index d7ccc5e4..cdf7d615 100644 --- a/src/managers/input/InputManager.cpp +++ b/src/managers/input/InputManager.cpp @@ -153,7 +153,6 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool silent) { Vector2D surfacePos = Vector2D(-1337, -1337); PHLWINDOW pFoundWindow; PHLLS pFoundLayerSurface; - SSessionLockSurface* pSessionLock = nullptr; if (!g_pCompositor->m_bReadyToProcess || g_pCompositor->m_bIsShuttingDown || g_pCompositor->m_bUnsafeState) return; @@ -190,17 +189,6 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool silent) { if (!PMONITOR->solitaryClient.lock() && g_pHyprRenderer->shouldRenderCursor() && g_pPointerManager->softwareLockedFor(PMONITOR->self.lock()) && !skipFrameSchedule) g_pCompositor->scheduleFrameForMonitor(PMONITOR, Aquamarine::IOutput::AQ_SCHEDULE_CURSOR_MOVE); - PHLWINDOW forcedFocus = m_pForcedFocus.lock(); - - if (!forcedFocus) - forcedFocus = g_pCompositor->getForceFocus(); - - if (forcedFocus) { - pFoundWindow = forcedFocus; - surfacePos = pFoundWindow->m_vRealPosition.value(); - foundSurface = pFoundWindow->m_pWLSurface->resource(); - } - // constraints if (!g_pSeatManager->mouse.expired() && isConstrained()) { const auto SURF = CWLSurface::fromResource(g_pCompositor->m_pLastFocus.lock()); @@ -227,6 +215,33 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool silent) { Debug::log(ERR, "BUG THIS: Null SURF/CONSTRAINT in mouse refocus. Ignoring constraints. {:x} {:x}", (uintptr_t)SURF.get(), (uintptr_t)CONSTRAINT.get()); } + if (PMONITOR != g_pCompositor->m_pLastMonitor.get() && (*PMOUSEFOCUSMON || refocus) && m_pForcedFocus.expired()) + g_pCompositor->setActiveMonitor(PMONITOR); + + if (g_pSessionLockManager->isSessionLocked()) { + const auto PSESSIONLOCKSURFACE = g_pSessionLockManager->getSessionLockSurfaceForMonitor(PMONITOR->ID); + surfacePos = PMONITOR->vecPosition; + + foundSurface = PSESSIONLOCKSURFACE ? PSESSIONLOCKSURFACE->surface->surface() : nullptr; + g_pCompositor->focusSurface(foundSurface); + + const auto SURFACELOCAL = mouseCoords - surfacePos; + g_pSeatManager->setPointerFocus(foundSurface, SURFACELOCAL); + g_pSeatManager->sendPointerMotion(time, SURFACELOCAL); + return; + } + + PHLWINDOW forcedFocus = m_pForcedFocus.lock(); + + if (!forcedFocus) + forcedFocus = g_pCompositor->getForceFocus(); + + if (forcedFocus) { + pFoundWindow = forcedFocus; + surfacePos = pFoundWindow->m_vRealPosition.value(); + foundSurface = pFoundWindow->m_pWLSurface->resource(); + } + // if we are holding a pointer button, // and we're not dnd-ing, don't refocus. Keep focus on last surface. if (!PROTO::data->dndActive() && !m_lCurrentlyHeldButtons.empty() && g_pCompositor->m_pLastFocus && g_pSeatManager->state.pointerFocus && !m_bHardInput) { @@ -258,19 +273,6 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool silent) { g_pLayoutManager->getCurrentLayout()->onMouseMove(getMouseCoordsInternal()); - if (PMONITOR && PMONITOR != g_pCompositor->m_pLastMonitor.get() && (*PMOUSEFOCUSMON || refocus) && m_pForcedFocus.expired()) - g_pCompositor->setActiveMonitor(PMONITOR); - - if (g_pSessionLockManager->isSessionLocked()) { - pSessionLock = PMONITOR ? g_pSessionLockManager->getSessionLockSurfaceForMonitor(PMONITOR->ID) : nullptr; - - if (!pSessionLock) - return; - - foundSurface = pSessionLock->surface->surface(); - surfacePos = PMONITOR->vecPosition; - } - if (!foundSurface) foundSurface = g_pCompositor->vectorToLayerPopupSurface(mouseCoords, PMONITOR, &surfaceCoords, &pFoundLayerSurface); @@ -460,9 +462,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool silent) { restoreCursorIconToApp(); } - if (pSessionLock != nullptr) - g_pCompositor->focusSurface(foundSurface); - else if (pFoundWindow) { + if (pFoundWindow) { // change cursor icon if hovering over border if (*PRESIZEONBORDER && *PRESIZECURSORICON) { if (!pFoundWindow->isFullscreen() && !pFoundWindow->hasPopupAt(mouseCoords)) {