From 63a65df3cf42fe7ebf6986f3329c6743a299e1cf Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Sun, 9 Jun 2024 19:25:30 -0700 Subject: [PATCH 01/10] layerSurface: grab focus when an exclusive layer surface is mapped --- src/desktop/LayerSurface.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/desktop/LayerSurface.cpp b/src/desktop/LayerSurface.cpp index 62cae8f6e12..e4e11dd493c 100644 --- a/src/desktop/LayerSurface.cpp +++ b/src/desktop/LayerSurface.cpp @@ -133,12 +133,15 @@ void CLayerSurface::onMap() { surface->resource()->enter(PMONITOR->self.lock()); - if (layerSurface->current.interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE) + const bool isExclusive = layerSurface->current.interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE; + + if (isExclusive) g_pInputManager->m_dExclusiveLSes.push_back(self); - const bool GRABSFOCUS = layerSurface->current.interactivity != ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE && - // don't focus if constrained - (g_pSeatManager->mouse.expired() || !g_pInputManager->isConstrained()); + const bool GRABSFOCUS = isExclusive || + (layerSurface->current.interactivity != ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE && + // don't focus if constrained + (g_pSeatManager->mouse.expired() || !g_pInputManager->isConstrained())); if (GRABSFOCUS) { // TODO: use the new superb really very cool grab From f612e141cf63cfe2492adaec82878d508e273e66 Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Sun, 9 Jun 2024 20:28:00 -0700 Subject: [PATCH 02/10] layerSurface: focus last exclusive ls on unmap only if focused Also focus the last instead of the first. --- src/desktop/LayerSurface.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/desktop/LayerSurface.cpp b/src/desktop/LayerSurface.cpp index e4e11dd493c..d63fc772cbd 100644 --- a/src/desktop/LayerSurface.cpp +++ b/src/desktop/LayerSurface.cpp @@ -180,9 +180,6 @@ void CLayerSurface::onUnmap() { std::erase_if(g_pInputManager->m_dExclusiveLSes, [this](const auto& other) { return !other.lock() || other.lock() == self.lock(); }); - if (!g_pInputManager->m_dExclusiveLSes.empty()) - g_pCompositor->focusSurface(g_pInputManager->m_dExclusiveLSes[0]->surface->resource()); - if (!g_pCompositor->getMonitorFromID(monitorID) || g_pCompositor->m_bUnsafeState) { Debug::log(WARN, "Layersurface unmapping on invalid monitor (removed?) ignoring."); @@ -222,6 +219,10 @@ void CLayerSurface::onUnmap() { g_pCompositor->m_pLastFocus.reset(); + // try to focus the last exclusive ls first + if (!g_pInputManager->m_dExclusiveLSes.empty()) + g_pCompositor->focusSurface(g_pInputManager->m_dExclusiveLSes[g_pInputManager->m_dExclusiveLSes.size() - 1]->surface->resource()); + // find LS-es to focus foundSurface = g_pCompositor->vectorToLayerSurface(g_pInputManager->getMouseCoordsInternal(), &PMONITOR->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], &surfaceCoords, &pFoundLayerSurface); From 3ae7af3b1f23d4267945ddb3549d16f63873eada Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Mon, 10 Jun 2024 00:24:18 -0700 Subject: [PATCH 03/10] layerSurface: fix keyboard focus changing on commit post map --- src/desktop/LayerSurface.cpp | 45 ++++++++++++++++++++++++------------ src/desktop/LayerSurface.hpp | 5 ++-- 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/src/desktop/LayerSurface.cpp b/src/desktop/LayerSurface.cpp index d63fc772cbd..cc53f6b750d 100644 --- a/src/desktop/LayerSurface.cpp +++ b/src/desktop/LayerSurface.cpp @@ -4,6 +4,7 @@ #include "../protocols/LayerShell.hpp" #include "../protocols/core/Compositor.hpp" #include "../managers/SeatManager.hpp" +#include "managers/input/InputManager.hpp" PHLLS CLayerSurface::create(SP resource) { PHLLS pLS = SP(new CLayerSurface(resource)); @@ -116,8 +117,8 @@ void CLayerSurface::onDestroy() { void CLayerSurface::onMap() { Debug::log(LOG, "LayerSurface {:x} mapped", (uintptr_t)layerSurface); - mapped = true; - keyboardExclusive = layerSurface->current.interactivity; + mapped = true; + interactivity = layerSurface->current.interactivity; // fix if it changed its mon const auto PMONITOR = g_pCompositor->getMonitorFromID(monitorID); @@ -133,12 +134,12 @@ void CLayerSurface::onMap() { surface->resource()->enter(PMONITOR->self.lock()); - const bool isExclusive = layerSurface->current.interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE; + const bool ISEXCLUSIVE = layerSurface->current.interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE; - if (isExclusive) + if (ISEXCLUSIVE) g_pInputManager->m_dExclusiveLSes.push_back(self); - const bool GRABSFOCUS = isExclusive || + const bool GRABSFOCUS = ISEXCLUSIVE || (layerSurface->current.interactivity != ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE && // don't focus if constrained (g_pSeatManager->mouse.expired() || !g_pInputManager->isConstrained())); @@ -315,18 +316,32 @@ void CLayerSurface::onCommit() { realSize.setValueAndWarp(geometry.size()); } - if (layerSurface->current.interactivity && (g_pSeatManager->mouse.expired() || !g_pInputManager->isConstrained()) // don't focus if constrained - && !keyboardExclusive && mapped) { - g_pCompositor->focusSurface(surface->resource()); + if (mapped) { + const bool WASLASTFOCUS = g_pCompositor->m_pLastFocus == surface->resource(); + const bool WASEXCLUSIVE = interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE; + const bool ISEXCLUSIVE = layerSurface->current.interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE; - const auto LOCAL = g_pInputManager->getMouseCoordsInternal() - Vector2D(geometry.x + PMONITOR->vecPosition.x, geometry.y + PMONITOR->vecPosition.y); - g_pSeatManager->setPointerFocus(surface->resource(), LOCAL); - g_pInputManager->m_bEmptyFocusCursorSet = false; - } else if (!layerSurface->current.interactivity && (g_pSeatManager->mouse.expired() || !g_pInputManager->isConstrained()) && keyboardExclusive) { - g_pInputManager->refocus(); + if (!WASEXCLUSIVE && ISEXCLUSIVE) + g_pInputManager->m_dExclusiveLSes.push_back(self); + else if (WASEXCLUSIVE && !ISEXCLUSIVE) + std::erase_if(g_pInputManager->m_dExclusiveLSes, [this](const auto& other) { return !other.lock() || other.lock() == self.lock(); }); + + // if the surface was focused and interactive but now isn't, refocus + if (WASLASTFOCUS && !layerSurface->current.interactivity) { + g_pInputManager->refocus(); + } else if (!WASLASTFOCUS && (ISEXCLUSIVE || (layerSurface->current.interactivity && (g_pSeatManager->mouse.expired() || !g_pInputManager->isConstrained())))) { + // if not focused last and exclusive or accepting input + unconstrained + g_pSeatManager->setGrab(nullptr); + g_pInputManager->releaseAllMouseButtons(); + g_pCompositor->focusSurface(surface->resource()); + + const auto LOCAL = g_pInputManager->getMouseCoordsInternal() - Vector2D(geometry.x + PMONITOR->vecPosition.x, geometry.y + PMONITOR->vecPosition.y); + g_pSeatManager->setPointerFocus(surface->resource(), LOCAL); + g_pInputManager->m_bEmptyFocusCursorSet = false; + } } - keyboardExclusive = layerSurface->current.interactivity; + interactivity = layerSurface->current.interactivity; g_pHyprRenderer->damageSurface(surface->resource(), position.x, position.y); @@ -516,4 +531,4 @@ int CLayerSurface::popupsCount() { int no = -1; // we have one dummy popupHead->breadthfirst([](CPopup* p, void* data) { *(int*)data += 1; }, &no); return no; -} \ No newline at end of file +} diff --git a/src/desktop/LayerSurface.hpp b/src/desktop/LayerSurface.hpp index 9fa96d2d4a2..cfcdb324a76 100644 --- a/src/desktop/LayerSurface.hpp +++ b/src/desktop/LayerSurface.hpp @@ -34,7 +34,8 @@ class CLayerSurface { WP layerSurface; wl_list link; - bool keyboardExclusive = false; + // the header providing the enum type cannot be imported here + int interactivity = 0; SP surface; @@ -83,4 +84,4 @@ class CLayerSurface { bool operator==(const CLayerSurface& rhs) const { return layerSurface == rhs.layerSurface && monitorID == rhs.monitorID; } -}; \ No newline at end of file +}; From 34802b7f19bd252c2c6d297882198ae21d4bd0e3 Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Mon, 10 Jun 2024 12:18:50 -0700 Subject: [PATCH 04/10] layerSurface: focus last window when keyboard exclusivity is dropped --- src/desktop/LayerSurface.cpp | 42 +++++------------------------ src/managers/input/InputManager.cpp | 37 +++++++++++++++++++++++++ src/managers/input/InputManager.hpp | 5 ++-- 3 files changed, 46 insertions(+), 38 deletions(-) diff --git a/src/desktop/LayerSurface.cpp b/src/desktop/LayerSurface.cpp index cc53f6b750d..985ba8c3957 100644 --- a/src/desktop/LayerSurface.cpp +++ b/src/desktop/LayerSurface.cpp @@ -211,37 +211,7 @@ void CLayerSurface::onUnmap() { return; // refocus if needed - if (WASLASTFOCUS) { - g_pInputManager->releaseAllMouseButtons(); - - Vector2D surfaceCoords; - PHLLS pFoundLayerSurface; - SP foundSurface = nullptr; - - g_pCompositor->m_pLastFocus.reset(); - - // try to focus the last exclusive ls first - if (!g_pInputManager->m_dExclusiveLSes.empty()) - g_pCompositor->focusSurface(g_pInputManager->m_dExclusiveLSes[g_pInputManager->m_dExclusiveLSes.size() - 1]->surface->resource()); - - // find LS-es to focus - foundSurface = g_pCompositor->vectorToLayerSurface(g_pInputManager->getMouseCoordsInternal(), &PMONITOR->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], - &surfaceCoords, &pFoundLayerSurface); - - if (!foundSurface) - foundSurface = g_pCompositor->vectorToLayerSurface(g_pInputManager->getMouseCoordsInternal(), &PMONITOR->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], - &surfaceCoords, &pFoundLayerSurface); - - if (!foundSurface && g_pCompositor->m_pLastWindow.lock() && g_pCompositor->isWorkspaceVisible(g_pCompositor->m_pLastWindow->m_pWorkspace)) { - // if there isn't any, focus the last window - const auto PLASTWINDOW = g_pCompositor->m_pLastWindow.lock(); - g_pCompositor->focusWindow(nullptr); - g_pCompositor->focusWindow(PLASTWINDOW); - } else { - // otherwise, full refocus - g_pInputManager->refocus(); - } - } + if (WASLASTFOCUS) g_pInputManager->refocusLastWindow(PMONITOR); CBox geomFixed = {geometry.x + PMONITOR->vecPosition.x, geometry.y + PMONITOR->vecPosition.y, geometry.width, geometry.height}; g_pHyprRenderer->damageBox(&geomFixed); @@ -326,11 +296,11 @@ void CLayerSurface::onCommit() { else if (WASEXCLUSIVE && !ISEXCLUSIVE) std::erase_if(g_pInputManager->m_dExclusiveLSes, [this](const auto& other) { return !other.lock() || other.lock() == self.lock(); }); - // if the surface was focused and interactive but now isn't, refocus - if (WASLASTFOCUS && !layerSurface->current.interactivity) { - g_pInputManager->refocus(); - } else if (!WASLASTFOCUS && (ISEXCLUSIVE || (layerSurface->current.interactivity && (g_pSeatManager->mouse.expired() || !g_pInputManager->isConstrained())))) { - // if not focused last and exclusive or accepting input + unconstrained + // if the surface was focused and interactive but now isn't, refocus + if (WASLASTFOCUS && !layerSurface->current.interactivity) { + g_pInputManager->refocusLastWindow(g_pCompositor->getMonitorFromID(monitorID)); + } else if (!WASLASTFOCUS && (ISEXCLUSIVE || (layerSurface->current.interactivity && (g_pSeatManager->mouse.expired() || !g_pInputManager->isConstrained())))) { + // if not focused last and exclusive or accepting input + unconstrained g_pSeatManager->setGrab(nullptr); g_pInputManager->releaseAllMouseButtons(); g_pCompositor->focusSurface(surface->resource()); diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp index ff10f3037f4..a9536268c3c 100644 --- a/src/managers/input/InputManager.cpp +++ b/src/managers/input/InputManager.cpp @@ -1381,6 +1381,43 @@ void CInputManager::refocus() { mouseMoveUnified(0, true); } +void CInputManager::refocusLastWindow(CMonitor* pMonitor) { + if (!pMonitor) { + refocus(); + return; + } + + Vector2D surfaceCoords; + PHLLS pFoundLayerSurface; + SP foundSurface = nullptr; + + g_pInputManager->releaseAllMouseButtons(); + g_pCompositor->m_pLastFocus.reset(); + + // first try for an exclusive layer + if (!m_dExclusiveLSes.empty()) + foundSurface = m_dExclusiveLSes[m_dExclusiveLSes.size() - 1]->surface->resource(); + + // then any surfaces above windows on the same monitor + if (!foundSurface) + foundSurface = g_pCompositor->vectorToLayerSurface(g_pInputManager->getMouseCoordsInternal(), &pMonitor->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], + &surfaceCoords, &pFoundLayerSurface); + + if (!foundSurface) + foundSurface = g_pCompositor->vectorToLayerSurface(g_pInputManager->getMouseCoordsInternal(), &pMonitor->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], + &surfaceCoords, &pFoundLayerSurface); + + if (!foundSurface && g_pCompositor->m_pLastWindow.lock() && g_pCompositor->isWorkspaceVisible(g_pCompositor->m_pLastWindow->m_pWorkspace)) { + // then the last focused window if we're on the same workspace as it + const auto PLASTWINDOW = g_pCompositor->m_pLastWindow.lock(); + g_pCompositor->focusWindow(nullptr); + g_pCompositor->focusWindow(PLASTWINDOW); + } else { + // otherwise fall back to a normal refocus. + refocus(); + } +} + void CInputManager::unconstrainMouse() { if (g_pSeatManager->mouse.expired()) return; diff --git a/src/managers/input/InputManager.hpp b/src/managers/input/InputManager.hpp index 9fdf061c288..64e6e1826e3 100644 --- a/src/managers/input/InputManager.hpp +++ b/src/managers/input/InputManager.hpp @@ -103,8 +103,9 @@ class CInputManager { bool isConstrained(); Vector2D getMouseCoordsInternal(); - void refocus(); - void simulateMouseMovement(); + void refocus(); + void refocusLastWindow(CMonitor* pMonitor); + void simulateMouseMovement(); void sendMotionEventsToFocused(); void setKeyboardLayout(); From cbc14c57472eb8d0cf02c44371e3cb14f564fe01 Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Mon, 10 Jun 2024 14:45:18 -0700 Subject: [PATCH 05/10] clang-format --- src/desktop/LayerSurface.cpp | 14 ++++---- src/desktop/LayerSurface.hpp | 50 ++++++++++++++--------------- src/managers/input/InputManager.cpp | 1 - src/managers/input/InputManager.hpp | 6 ++-- 4 files changed, 35 insertions(+), 36 deletions(-) diff --git a/src/desktop/LayerSurface.cpp b/src/desktop/LayerSurface.cpp index 985ba8c3957..724326c92a7 100644 --- a/src/desktop/LayerSurface.cpp +++ b/src/desktop/LayerSurface.cpp @@ -4,7 +4,6 @@ #include "../protocols/LayerShell.hpp" #include "../protocols/core/Compositor.hpp" #include "../managers/SeatManager.hpp" -#include "managers/input/InputManager.hpp" PHLLS CLayerSurface::create(SP resource) { PHLLS pLS = SP(new CLayerSurface(resource)); @@ -211,7 +210,8 @@ void CLayerSurface::onUnmap() { return; // refocus if needed - if (WASLASTFOCUS) g_pInputManager->refocusLastWindow(PMONITOR); + if (WASLASTFOCUS) + g_pInputManager->refocusLastWindow(PMONITOR); CBox geomFixed = {geometry.x + PMONITOR->vecPosition.x, geometry.y + PMONITOR->vecPosition.y, geometry.width, geometry.height}; g_pHyprRenderer->damageBox(&geomFixed); @@ -296,11 +296,11 @@ void CLayerSurface::onCommit() { else if (WASEXCLUSIVE && !ISEXCLUSIVE) std::erase_if(g_pInputManager->m_dExclusiveLSes, [this](const auto& other) { return !other.lock() || other.lock() == self.lock(); }); - // if the surface was focused and interactive but now isn't, refocus - if (WASLASTFOCUS && !layerSurface->current.interactivity) { - g_pInputManager->refocusLastWindow(g_pCompositor->getMonitorFromID(monitorID)); - } else if (!WASLASTFOCUS && (ISEXCLUSIVE || (layerSurface->current.interactivity && (g_pSeatManager->mouse.expired() || !g_pInputManager->isConstrained())))) { - // if not focused last and exclusive or accepting input + unconstrained + // if the surface was focused and interactive but now isn't, refocus + if (WASLASTFOCUS && !layerSurface->current.interactivity) { + g_pInputManager->refocusLastWindow(g_pCompositor->getMonitorFromID(monitorID)); + } else if (!WASLASTFOCUS && (ISEXCLUSIVE || (layerSurface->current.interactivity && (g_pSeatManager->mouse.expired() || !g_pInputManager->isConstrained())))) { + // if not focused last and exclusive or accepting input + unconstrained g_pSeatManager->setGrab(nullptr); g_pInputManager->releaseAllMouseButtons(); g_pCompositor->focusSurface(surface->resource()); diff --git a/src/desktop/LayerSurface.hpp b/src/desktop/LayerSurface.hpp index cfcdb324a76..056f66a872c 100644 --- a/src/desktop/LayerSurface.hpp +++ b/src/desktop/LayerSurface.hpp @@ -35,40 +35,40 @@ class CLayerSurface { wl_list link; // the header providing the enum type cannot be imported here - int interactivity = 0; + int interactivity = 0; - SP surface; + SP surface; - bool mapped = false; - uint32_t layer = 0; + bool mapped = false; + uint32_t layer = 0; - int monitorID = -1; + int monitorID = -1; - bool fadingOut = false; - bool readyToDelete = false; - bool noProcess = false; - bool noAnimations = false; + bool fadingOut = false; + bool readyToDelete = false; + bool noProcess = false; + bool noAnimations = false; - bool forceBlur = false; - bool forceBlurPopups = false; - int xray = -1; - bool ignoreAlpha = false; - float ignoreAlphaValue = 0.f; - bool dimAround = false; + bool forceBlur = false; + bool forceBlurPopups = false; + int xray = -1; + bool ignoreAlpha = false; + float ignoreAlphaValue = 0.f; + bool dimAround = false; - std::optional animationStyle; + std::optional animationStyle; - PHLLSREF self; + PHLLSREF self; - CBox geometry = {0, 0, 0, 0}; - Vector2D position; - std::string szNamespace = ""; - std::unique_ptr popupHead; + CBox geometry = {0, 0, 0, 0}; + Vector2D position; + std::string szNamespace = ""; + std::unique_ptr popupHead; - void onDestroy(); - void onMap(); - void onUnmap(); - void onCommit(); + void onDestroy(); + void onMap(); + void onUnmap(); + void onCommit(); private: struct { diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp index a9536268c3c..9b7e12dc098 100644 --- a/src/managers/input/InputManager.cpp +++ b/src/managers/input/InputManager.cpp @@ -1410,7 +1410,6 @@ void CInputManager::refocusLastWindow(CMonitor* pMonitor) { if (!foundSurface && g_pCompositor->m_pLastWindow.lock() && g_pCompositor->isWorkspaceVisible(g_pCompositor->m_pLastWindow->m_pWorkspace)) { // then the last focused window if we're on the same workspace as it const auto PLASTWINDOW = g_pCompositor->m_pLastWindow.lock(); - g_pCompositor->focusWindow(nullptr); g_pCompositor->focusWindow(PLASTWINDOW); } else { // otherwise fall back to a normal refocus. diff --git a/src/managers/input/InputManager.hpp b/src/managers/input/InputManager.hpp index 64e6e1826e3..000a115ffdd 100644 --- a/src/managers/input/InputManager.hpp +++ b/src/managers/input/InputManager.hpp @@ -103,9 +103,9 @@ class CInputManager { bool isConstrained(); Vector2D getMouseCoordsInternal(); - void refocus(); - void refocusLastWindow(CMonitor* pMonitor); - void simulateMouseMovement(); + void refocus(); + void refocusLastWindow(CMonitor* pMonitor); + void simulateMouseMovement(); void sendMotionEventsToFocused(); void setKeyboardLayout(); From bcee3a4aaec716d60edfa5672781e2403355729c Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Mon, 10 Jun 2024 15:00:02 -0700 Subject: [PATCH 06/10] layerSurface: dont reset last focus on refocus --- src/managers/input/InputManager.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp index 9b7e12dc098..9928936f4ac 100644 --- a/src/managers/input/InputManager.cpp +++ b/src/managers/input/InputManager.cpp @@ -1392,7 +1392,6 @@ void CInputManager::refocusLastWindow(CMonitor* pMonitor) { SP foundSurface = nullptr; g_pInputManager->releaseAllMouseButtons(); - g_pCompositor->m_pLastFocus.reset(); // first try for an exclusive layer if (!m_dExclusiveLSes.empty()) From ff63262fa25b9697e48585aa467cb602998188b8 Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Mon, 10 Jun 2024 15:14:26 -0700 Subject: [PATCH 07/10] layerSurface: fix style --- src/desktop/LayerSurface.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/desktop/LayerSurface.cpp b/src/desktop/LayerSurface.cpp index 724326c92a7..025ea0eddbf 100644 --- a/src/desktop/LayerSurface.cpp +++ b/src/desktop/LayerSurface.cpp @@ -297,9 +297,9 @@ void CLayerSurface::onCommit() { std::erase_if(g_pInputManager->m_dExclusiveLSes, [this](const auto& other) { return !other.lock() || other.lock() == self.lock(); }); // if the surface was focused and interactive but now isn't, refocus - if (WASLASTFOCUS && !layerSurface->current.interactivity) { + if (WASLASTFOCUS && !layerSurface->current.interactivity) g_pInputManager->refocusLastWindow(g_pCompositor->getMonitorFromID(monitorID)); - } else if (!WASLASTFOCUS && (ISEXCLUSIVE || (layerSurface->current.interactivity && (g_pSeatManager->mouse.expired() || !g_pInputManager->isConstrained())))) { + else if (!WASLASTFOCUS && (ISEXCLUSIVE || (layerSurface->current.interactivity && (g_pSeatManager->mouse.expired() || !g_pInputManager->isConstrained())))) { // if not focused last and exclusive or accepting input + unconstrained g_pSeatManager->setGrab(nullptr); g_pInputManager->releaseAllMouseButtons(); From 73479963a2715ee174e8eb1d086f486dce3934f2 Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Mon, 10 Jun 2024 16:23:05 -0700 Subject: [PATCH 08/10] layerSurface: fix mouse buttons being released on press when exclusive --- src/desktop/LayerSurface.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/desktop/LayerSurface.cpp b/src/desktop/LayerSurface.cpp index 025ea0eddbf..d30235a198b 100644 --- a/src/desktop/LayerSurface.cpp +++ b/src/desktop/LayerSurface.cpp @@ -299,7 +299,8 @@ void CLayerSurface::onCommit() { // if the surface was focused and interactive but now isn't, refocus if (WASLASTFOCUS && !layerSurface->current.interactivity) g_pInputManager->refocusLastWindow(g_pCompositor->getMonitorFromID(monitorID)); - else if (!WASLASTFOCUS && (ISEXCLUSIVE || (layerSurface->current.interactivity && (g_pSeatManager->mouse.expired() || !g_pInputManager->isConstrained())))) { + else if (!WASEXCLUSIVE && !WASLASTFOCUS && + (ISEXCLUSIVE || (layerSurface->current.interactivity && (g_pSeatManager->mouse.expired() || !g_pInputManager->isConstrained())))) { // if not focused last and exclusive or accepting input + unconstrained g_pSeatManager->setGrab(nullptr); g_pInputManager->releaseAllMouseButtons(); From 58db6f753b4281d39be5e423f453891bf9afc6f6 Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Mon, 10 Jun 2024 16:54:49 -0700 Subject: [PATCH 09/10] layerSurface: forcibly unfocus surfaces when made non interactive --- src/desktop/LayerSurface.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/desktop/LayerSurface.cpp b/src/desktop/LayerSurface.cpp index d30235a198b..0b2e23a38f3 100644 --- a/src/desktop/LayerSurface.cpp +++ b/src/desktop/LayerSurface.cpp @@ -297,10 +297,13 @@ void CLayerSurface::onCommit() { std::erase_if(g_pInputManager->m_dExclusiveLSes, [this](const auto& other) { return !other.lock() || other.lock() == self.lock(); }); // if the surface was focused and interactive but now isn't, refocus - if (WASLASTFOCUS && !layerSurface->current.interactivity) + if (WASLASTFOCUS && !layerSurface->current.interactivity) { + // moveMouseUnified won't focus non interactive layers but it won't unfocus them either, + // so unfocus the surface here. + g_pCompositor->focusSurface(nullptr); g_pInputManager->refocusLastWindow(g_pCompositor->getMonitorFromID(monitorID)); - else if (!WASEXCLUSIVE && !WASLASTFOCUS && - (ISEXCLUSIVE || (layerSurface->current.interactivity && (g_pSeatManager->mouse.expired() || !g_pInputManager->isConstrained())))) { + } else if (!WASEXCLUSIVE && !WASLASTFOCUS && + (ISEXCLUSIVE || (layerSurface->current.interactivity && (g_pSeatManager->mouse.expired() || !g_pInputManager->isConstrained())))) { // if not focused last and exclusive or accepting input + unconstrained g_pSeatManager->setGrab(nullptr); g_pInputManager->releaseAllMouseButtons(); From 6c6840c3d3dae1384194c8043a836299d9bfab28 Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Mon, 10 Jun 2024 17:13:37 -0700 Subject: [PATCH 10/10] layerSurface: allow exclusive layers to focus from other exclusive layers --- src/managers/input/InputManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp index 9928936f4ac..075b807fccb 100644 --- a/src/managers/input/InputManager.cpp +++ b/src/managers/input/InputManager.cpp @@ -509,7 +509,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) { } if (pFoundLayerSurface && (pFoundLayerSurface->layerSurface->current.interactivity != ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE) && FOLLOWMOUSE != 3 && - allowKeyboardRefocus) { + (allowKeyboardRefocus || pFoundLayerSurface->layerSurface->current.interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE)) { g_pCompositor->focusSurface(foundSurface); }