From b0d5e4008b96f2cdbb6f6c2449c790d921d1546b Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Tue, 12 Sep 2023 14:37:08 -0700 Subject: [PATCH] layout: Allow the layout to control how windows are raised in groups (#3275) * Allow the layout to control how windows are raised in groups Previously windows could only be focused if they weren't hidden or were part of a group. This shifts the logic for picking the window out of a group to the layout allowing for alternate group implementations to function normally. * Fix doc comment consistency * Fix tabs in comments --- src/Compositor.cpp | 7 ++----- src/layout/IHyprLayout.cpp | 12 +++++++++++- src/layout/IHyprLayout.hpp | 14 +++++++++++++- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index e1fb60cbd..749c9d27e 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -829,10 +829,7 @@ void CCompositor::focusWindow(CWindow* pWindow, wlr_surface* pSurface) { return; } - if (pWindow && pWindow->isHidden() && pWindow->m_sGroupData.pNextWindow) { - // grouped, change the current to us - pWindow->setGroupCurrent(pWindow); - } + g_pLayoutManager->getCurrentLayout()->bringWindowToTop(pWindow); if (!pWindow || !windowValidMapped(pWindow)) { const auto PLASTWINDOW = m_pLastWindow; @@ -2171,7 +2168,7 @@ CWindow* CCompositor::getWindowByRegex(const std::string& regexp) { } for (auto& w : g_pCompositor->m_vWindows) { - if (!w->m_bIsMapped || (w->isHidden() && !w->m_sGroupData.pNextWindow)) + if (!w->m_bIsMapped || (w->isHidden() && !g_pLayoutManager->getCurrentLayout()->isWindowReachable(w.get()))) continue; switch (mode) { diff --git a/src/layout/IHyprLayout.cpp b/src/layout/IHyprLayout.cpp index b0c1d50cd..5466282fa 100644 --- a/src/layout/IHyprLayout.cpp +++ b/src/layout/IHyprLayout.cpp @@ -535,12 +535,22 @@ CWindow* IHyprLayout::getNextWindowCandidate(CWindow* pWindow) { return PWINDOWCANDIDATE; } -void IHyprLayout::requestFocusForWindow(CWindow* pWindow) { +bool IHyprLayout::isWindowReachable(CWindow* pWindow) { + return pWindow && (!pWindow->isHidden() || pWindow->m_sGroupData.pNextWindow); +} + +void IHyprLayout::bringWindowToTop(CWindow* pWindow) { + if (pWindow == nullptr) + return; + if (pWindow->isHidden() && pWindow->m_sGroupData.pNextWindow) { // grouped, change the current to this window pWindow->setGroupCurrent(pWindow); } +} +void IHyprLayout::requestFocusForWindow(CWindow* pWindow) { + bringWindowToTop(pWindow); g_pCompositor->focusWindow(pWindow); } diff --git a/src/layout/IHyprLayout.hpp b/src/layout/IHyprLayout.hpp index a0d5b2bb1..282eb1ea6 100644 --- a/src/layout/IHyprLayout.hpp +++ b/src/layout/IHyprLayout.hpp @@ -155,10 +155,22 @@ class IHyprLayout { */ virtual void replaceWindowDataWith(CWindow* from, CWindow* to) = 0; + /* + Determines if a window can be focused. If hidden this usually means the window is part of a group. + */ + virtual bool isWindowReachable(CWindow*); + + /* + Called before an attempt is made to focus a window. + Brings the window to the top of any groups and ensures it is not hidden. + If the window is unmapped following this call, the focus attempt will fail. + */ + virtual void bringWindowToTop(CWindow*); + /* Called via the foreign toplevel activation protocol. Focuses a window, bringing it to the top of its group if applicable. - May be ignored. + May be ignored. */ virtual void requestFocusForWindow(CWindow*);