From 46891b12cf307d8bf934b42e5b4919fa594075f0 Mon Sep 17 00:00:00 2001 From: Maarten van Gompel Date: Mon, 12 Dec 2022 15:34:52 +0100 Subject: [PATCH] Master layout: lose or inherit fullscreen on deliberate window switching (#1213) * Master layout: Lose fullscreen status when deliberately switching away from a fullscreen window * Master layout: implemented inherit_fullscreen config parameter When set, if you are on a fullscreen window and you cycle to the next, swap master, etc, it will be automatically fullscreened. --- src/config/ConfigManager.cpp | 1 + src/layout/MasterLayout.cpp | 63 ++++++++++++++++++++++++++++++++---- src/layout/MasterLayout.hpp | 2 ++ 3 files changed, 60 insertions(+), 6 deletions(-) diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 21659cf2..1092b1c4 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -110,6 +110,7 @@ void CConfigManager::setDefaultVars() { configValues["master:new_on_top"].intValue = 0; configValues["master:no_gaps_when_only"].intValue = 0; configValues["master:orientation"].strValue = "left"; + configValues["master:inherit_fullscreen"].intValue = 1; configValues["animations:enabled"].intValue = 1; configValues["animations:speed"].floatValue = 7.f; diff --git a/src/layout/MasterLayout.cpp b/src/layout/MasterLayout.cpp index 19f22fb5..186b0375 100644 --- a/src/layout/MasterLayout.cpp +++ b/src/layout/MasterLayout.cpp @@ -582,6 +582,8 @@ void CHyprMasterLayout::switchWindows(CWindow* pWindow, CWindow* pWindow2) { if (!PNODE2 || !PNODE) return; + const auto inheritFullscreen = prepareLoseFocus(pWindow); + if (PNODE->workspaceID != PNODE2->workspaceID) { std::swap(pWindow2->m_iMonitorID, pWindow->m_iMonitorID); std::swap(pWindow2->m_iWorkspaceID, pWindow->m_iWorkspaceID); @@ -597,6 +599,8 @@ void CHyprMasterLayout::switchWindows(CWindow* pWindow, CWindow* pWindow2) { g_pHyprRenderer->damageWindow(pWindow); g_pHyprRenderer->damageWindow(pWindow2); + + prepareNewFocus(pWindow2, inheritFullscreen); } void CHyprMasterLayout::alterSplitRatioBy(CWindow* pWindow, float ratio) { @@ -651,14 +655,14 @@ CWindow* CHyprMasterLayout::getNextWindow(CWindow* pWindow, bool next) { } } else { if (PNODE->isMaster) { - // focus the first non master + // focus the last non master for (auto it = m_lMasterNodesData.rbegin(); it != m_lMasterNodesData.rend(); it++) { if (it->pWindow != pWindow && it->workspaceID == pWindow->m_iWorkspaceID) { return it->pWindow; } } } else { - // focus next + // focus previous bool reached = false; bool found = false; for (auto it = m_lMasterNodesData.rbegin(); it != m_lMasterNodesData.rend(); it++) { @@ -683,6 +687,28 @@ CWindow* CHyprMasterLayout::getNextWindow(CWindow* pWindow, bool next) { return nullptr; } +bool CHyprMasterLayout::prepareLoseFocus(CWindow* pWindow) { + if (!pWindow) + return false; + + //if the current window is fullscreen, make it normal again if we are about to lose focus + if (pWindow->m_bIsFullscreen) { + g_pCompositor->setWindowFullscreen(pWindow, false, FULLSCREEN_FULL); + const auto INHERIT = &g_pConfigManager->getConfigValuePtr("master:inherit_fullscreen")->intValue; + return *INHERIT == 1; + } + + return false; +} + +void CHyprMasterLayout::prepareNewFocus(CWindow* pWindow, bool inheritFullscreen) { + if (!pWindow) + return; + + if (inheritFullscreen) + g_pCompositor->setWindowFullscreen(pWindow, true, FULLSCREEN_MAXIMIZED); +} + std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::string message) { auto switchToWindow = [&](CWindow* PWINDOWTOCHANGETO) { if (!g_pCompositor->windowValidMapped(PWINDOWTOCHANGETO)) @@ -706,6 +732,7 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri if (!PMASTER) return 0; + if (PMASTER->pWindow != PWINDOW) { switchWindows(PWINDOW, PMASTER->pWindow); switchToWindow(PWINDOW); @@ -726,17 +753,21 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri if (!PWINDOW) return 0; + const bool inheritFullscreen = prepareLoseFocus(PWINDOW); + const auto PMASTER = getMasterNodeOnWorkspace(PWINDOW->m_iWorkspaceID); if (!PMASTER) return 0; - if (PMASTER->pWindow != PWINDOW) + if (PMASTER->pWindow != PWINDOW) { switchToWindow(PMASTER->pWindow); - else { + prepareNewFocus(PMASTER->pWindow, inheritFullscreen); + } else { for (auto& n : m_lMasterNodesData) { if (n.workspaceID == PMASTER->workspaceID && !n.isMaster) { switchToWindow(n.pWindow); + prepareNewFocus(n.pWindow, inheritFullscreen); break; } } @@ -749,14 +780,22 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri if (!PWINDOW) return 0; - switchToWindow(getNextWindow(PWINDOW, true)); + const bool inheritFullscreen = prepareLoseFocus(PWINDOW); + + const auto PNEXTWINDOW = getNextWindow(PWINDOW, true); + switchToWindow(PNEXTWINDOW); + prepareNewFocus(PNEXTWINDOW, inheritFullscreen); } else if (message == "cycleprev") { const auto PWINDOW = header.pWindow; if (!PWINDOW) return 0; - switchToWindow(getNextWindow(PWINDOW, false)); + const bool inheritFullscreen = prepareLoseFocus(PWINDOW); + + const auto PPREVWINDOW = getNextWindow(PWINDOW, true); + switchToWindow(PPREVWINDOW); + prepareNewFocus(PPREVWINDOW, inheritFullscreen); } else if (message == "swapnext") { if (!g_pCompositor->windowValidMapped(header.pWindow)) return 0; @@ -769,6 +808,7 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri const auto PWINDOWTOSWAPWITH = getNextWindow(header.pWindow, true); if (PWINDOWTOSWAPWITH) { + prepareLoseFocus(header.pWindow); switchWindows(header.pWindow, PWINDOWTOSWAPWITH); g_pCompositor->focusWindow(header.pWindow); } @@ -784,6 +824,7 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri const auto PWINDOWTOSWAPWITH = getNextWindow(header.pWindow, false); if (PWINDOWTOSWAPWITH) { + prepareLoseFocus(header.pWindow); switchWindows(header.pWindow, PWINDOWTOSWAPWITH); g_pCompositor->focusWindow(header.pWindow); } @@ -802,6 +843,8 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri if (MASTERS + 2 > WINDOWS) return 0; + prepareLoseFocus(header.pWindow); + if (!PNODE || PNODE->isMaster) { // first non-master node for (auto& n : m_lMasterNodesData) { @@ -832,6 +875,8 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri if (WINDOWS < 2 || MASTERS < 2) return 0; + prepareLoseFocus(header.pWindow); + if (!PNODE || !PNODE->isMaster) { // first non-master node for (auto it = m_lMasterNodesData.rbegin(); it != m_lMasterNodesData.rend(); it++) { @@ -851,6 +896,8 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri if (!PWINDOW) return 0; + prepareLoseFocus(PWINDOW); + const auto PWORKSPACEDATA = getMasterWorkspaceData(PWINDOW->m_iWorkspaceID); if (message == "orientationleft") @@ -870,6 +917,8 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri if (!PWINDOW) return 0; + prepareLoseFocus(PWINDOW); + const auto PWORKSPACEDATA = getMasterWorkspaceData(PWINDOW->m_iWorkspaceID); if (PWORKSPACEDATA->orientation == ORIENTATION_BOTTOM) { @@ -885,6 +934,8 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri if (!PWINDOW) return 0; + prepareLoseFocus(PWINDOW); + const auto PWORKSPACEDATA = getMasterWorkspaceData(PWINDOW->m_iWorkspaceID); if (PWORKSPACEDATA->orientation == ORIENTATION_LEFT) { diff --git a/src/layout/MasterLayout.hpp b/src/layout/MasterLayout.hpp index b7761cef..06dd8f00 100644 --- a/src/layout/MasterLayout.hpp +++ b/src/layout/MasterLayout.hpp @@ -75,6 +75,8 @@ private: void calculateWorkspace(const int&); CWindow* getNextWindow(CWindow*, bool); int getMastersOnWorkspace(const int&); + bool prepareLoseFocus(CWindow*); + void prepareNewFocus(CWindow*, bool inherit_fullscreen); friend struct SMasterNodeData; friend struct SMasterWorkspaceData;