From 7ea555da7fff0a2457e24e06bbd34986c0755025 Mon Sep 17 00:00:00 2001 From: thejch <66577496+thejch@users.noreply.github.com> Date: Tue, 12 Mar 2024 19:09:20 -0700 Subject: [PATCH] master: Fix master layout window focus and scroll (#5074) * fix master switch window scrolling * fix some more dispatchers and remove some duplicate code * refactor and remove duplicate code * fix focusmonitor: https://github.com/hyprwm/Hyprland/issues/5006#issuecomment-1986977255 * change check --- src/Compositor.cpp | 5 ++ src/layout/MasterLayout.cpp | 87 +++++++++++---------------------- src/layout/MasterLayout.hpp | 4 +- src/managers/KeybindManager.cpp | 6 ++- 4 files changed, 39 insertions(+), 63 deletions(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index f061bf6b..4d3fd65b 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -2297,6 +2297,11 @@ void CCompositor::setWindowFullscreen(CWindow* pWindow, bool on, eFullscreenMode return; } + if (pWindow->m_bIsFullscreen == on) { + Debug::log(LOG, "Window is already in the required fullscreen state"); + return; + } + const auto PMONITOR = getMonitorFromID(pWindow->m_iMonitorID); const auto PWORKSPACE = getWorkspaceByID(pWindow->m_iWorkspaceID); diff --git a/src/layout/MasterLayout.cpp b/src/layout/MasterLayout.cpp index d266d816..0a51401f 100644 --- a/src/layout/MasterLayout.cpp +++ b/src/layout/MasterLayout.cpp @@ -245,8 +245,7 @@ void CHyprMasterLayout::onWindowRemovedTiling(CWindow* pWindow) { pWindow->updateSpecialRenderData(); - if (pWindow->m_bIsFullscreen) - g_pCompositor->setWindowFullscreen(pWindow, false, FULLSCREEN_FULL); + g_pCompositor->setWindowFullscreen(pWindow, false, FULLSCREEN_FULL); if (PNODE->isMaster && (MASTERSLEFT <= 1 || *SMALLSPLIT == 1)) { // find a new master from top of the list @@ -1017,8 +1016,6 @@ 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); @@ -1034,8 +1031,6 @@ void CHyprMasterLayout::switchWindows(CWindow* pWindow, CWindow* pWindow2) { g_pHyprRenderer->damageWindow(pWindow); g_pHyprRenderer->damageWindow(pWindow2); - - prepareNewFocus(pWindow2, inheritFullscreen); } void CHyprMasterLayout::alterSplitRatio(CWindow* pWindow, float ratio, bool exact) { @@ -1076,35 +1071,27 @@ CWindow* CHyprMasterLayout::getNextWindow(CWindow* pWindow, bool next) { return CANDIDATE == nodes.end() ? nullptr : CANDIDATE->pWindow; } -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); - static auto INHERIT = CConfigValue("master:inherit_fullscreen"); - return *INHERIT == 1; - } - - return false; -} - -void CHyprMasterLayout::prepareNewFocus(CWindow* pWindow, bool inheritFullscreen) { - if (!pWindow) - return; - - if (inheritFullscreen) - g_pCompositor->setWindowFullscreen(pWindow, true, g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID)->m_efFullscreenMode); -} - std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::string message) { auto switchToWindow = [&](CWindow* PWINDOWTOCHANGETO) { if (!g_pCompositor->windowValidMapped(PWINDOWTOCHANGETO)) return; - g_pCompositor->focusWindow(PWINDOWTOCHANGETO); - g_pCompositor->warpCursorTo(PWINDOWTOCHANGETO->middle()); + if (header.pWindow->m_bIsFullscreen) { + const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(header.pWindow->m_iWorkspaceID); + const auto FSMODE = PWORKSPACE->m_efFullscreenMode; + static auto INHERITFULLSCREEN = CConfigValue("master:inherit_fullscreen"); + g_pCompositor->setWindowFullscreen(header.pWindow, false, FULLSCREEN_FULL); + g_pCompositor->focusWindow(PWINDOWTOCHANGETO); + if (*INHERITFULLSCREEN) + g_pCompositor->setWindowFullscreen(PWINDOWTOCHANGETO, true, FSMODE); + } else { + g_pCompositor->focusWindow(PWINDOWTOCHANGETO); + g_pCompositor->warpCursorTo(PWINDOWTOCHANGETO->middle()); + } + + g_pInputManager->m_pForcedFocus = PWINDOWTOCHANGETO; + g_pInputManager->simulateMouseMovement(); + g_pInputManager->m_pForcedFocus = nullptr; }; CVarList vars(message, 0, ' '); @@ -1138,23 +1125,19 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri const auto NEWCHILD = PMASTER->pWindow; if (PMASTER->pWindow != PWINDOW) { - const auto NEWMASTER = PWINDOW; - const bool newFocusToChild = vars.size() >= 2 && vars[1] == "child"; - const bool inheritFullscreen = prepareLoseFocus(NEWMASTER); + const auto NEWMASTER = PWINDOW; + const bool newFocusToChild = vars.size() >= 2 && vars[1] == "child"; switchWindows(NEWMASTER, NEWCHILD); const auto NEWFOCUS = newFocusToChild ? NEWCHILD : NEWMASTER; switchToWindow(NEWFOCUS); - prepareNewFocus(NEWFOCUS, inheritFullscreen); } else { for (auto& n : m_lMasterNodesData) { if (n.workspaceID == PMASTER->workspaceID && !n.isMaster) { - const auto NEWMASTER = n.pWindow; - const bool inheritFullscreen = prepareLoseFocus(NEWCHILD); + const auto NEWMASTER = n.pWindow; switchWindows(NEWMASTER, NEWCHILD); const bool newFocusToMaster = vars.size() >= 2 && vars[1] == "master"; const auto NEWFOCUS = newFocusToMaster ? NEWMASTER : NEWCHILD; switchToWindow(NEWFOCUS); - prepareNewFocus(NEWFOCUS, inheritFullscreen); break; } } @@ -1172,8 +1155,6 @@ 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) @@ -1181,7 +1162,6 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri if (PMASTER->pWindow != PWINDOW) { switchToWindow(PMASTER->pWindow); - prepareNewFocus(PMASTER->pWindow, inheritFullscreen); } else if (vars.size() >= 2 && vars[1] == "master") { return 0; } else { @@ -1189,7 +1169,6 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri for (auto& n : m_lMasterNodesData) { if (n.workspaceID == PMASTER->workspaceID && !n.isMaster) { switchToWindow(n.pWindow); - prepareNewFocus(n.pWindow, inheritFullscreen); break; } } @@ -1202,22 +1181,16 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri if (!PWINDOW) return 0; - const bool inheritFullscreen = prepareLoseFocus(PWINDOW); - const auto PNEXTWINDOW = getNextWindow(PWINDOW, true); switchToWindow(PNEXTWINDOW); - prepareNewFocus(PNEXTWINDOW, inheritFullscreen); } else if (command == "cycleprev") { const auto PWINDOW = header.pWindow; if (!PWINDOW) return 0; - const bool inheritFullscreen = prepareLoseFocus(PWINDOW); - const auto PPREVWINDOW = getNextWindow(PWINDOW, false); switchToWindow(PPREVWINDOW); - prepareNewFocus(PPREVWINDOW, inheritFullscreen); } else if (command == "swapnext") { if (!g_pCompositor->windowValidMapped(header.pWindow)) return 0; @@ -1230,9 +1203,9 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri const auto PWINDOWTOSWAPWITH = getNextWindow(header.pWindow, true); if (PWINDOWTOSWAPWITH) { - prepareLoseFocus(header.pWindow); + g_pCompositor->setWindowFullscreen(header.pWindow, false, FULLSCREEN_FULL); switchWindows(header.pWindow, PWINDOWTOSWAPWITH); - g_pCompositor->focusWindow(header.pWindow); + switchToWindow(header.pWindow); } } else if (command == "swapprev") { if (!g_pCompositor->windowValidMapped(header.pWindow)) @@ -1246,9 +1219,9 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri const auto PWINDOWTOSWAPWITH = getNextWindow(header.pWindow, false); if (PWINDOWTOSWAPWITH) { - prepareLoseFocus(header.pWindow); + g_pCompositor->setWindowFullscreen(header.pWindow, false, FULLSCREEN_FULL); switchWindows(header.pWindow, PWINDOWTOSWAPWITH); - g_pCompositor->focusWindow(header.pWindow); + switchToWindow(header.pWindow); } } else if (command == "addmaster") { if (!g_pCompositor->windowValidMapped(header.pWindow)) @@ -1265,7 +1238,7 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri if (MASTERS + 2 > WINDOWS && *SMALLSPLIT == 0) return 0; - prepareLoseFocus(header.pWindow); + g_pCompositor->setWindowFullscreen(header.pWindow, false, FULLSCREEN_FULL); if (!PNODE || PNODE->isMaster) { // first non-master node @@ -1297,7 +1270,7 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri if (WINDOWS < 2 || MASTERS < 2) return 0; - prepareLoseFocus(header.pWindow); + g_pCompositor->setWindowFullscreen(header.pWindow, false, FULLSCREEN_FULL); if (!PNODE || !PNODE->isMaster) { // first non-master node @@ -1318,7 +1291,7 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri if (!PWINDOW) return 0; - prepareLoseFocus(PWINDOW); + g_pCompositor->setWindowFullscreen(PWINDOW, false, FULLSCREEN_FULL); const auto PWORKSPACEDATA = getMasterWorkspaceData(PWINDOW->m_iWorkspaceID); @@ -1373,9 +1346,7 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri nd.isMaster = true; const auto NEWMASTERIT = std::find(m_lMasterNodesData.begin(), m_lMasterNodesData.end(), nd); m_lMasterNodesData.splice(OLDMASTERIT, m_lMasterNodesData, NEWMASTERIT); - const bool inheritFullscreen = prepareLoseFocus(PWINDOW); switchToWindow(nd.pWindow); - prepareNewFocus(nd.pWindow, inheritFullscreen); OLDMASTER->isMaster = false; m_lMasterNodesData.splice(m_lMasterNodesData.end(), m_lMasterNodesData, OLDMASTERIT); break; @@ -1401,9 +1372,7 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri nd.isMaster = true; const auto NEWMASTERIT = std::find(m_lMasterNodesData.begin(), m_lMasterNodesData.end(), nd); m_lMasterNodesData.splice(OLDMASTERIT, m_lMasterNodesData, NEWMASTERIT); - const bool inheritFullscreen = prepareLoseFocus(PWINDOW); switchToWindow(nd.pWindow); - prepareNewFocus(nd.pWindow, inheritFullscreen); OLDMASTER->isMaster = false; m_lMasterNodesData.splice(m_lMasterNodesData.begin(), m_lMasterNodesData, OLDMASTERIT); break; @@ -1430,7 +1399,7 @@ void CHyprMasterLayout::runOrientationCycle(SLayoutMessageHeader& header, CVarLi if (!PWINDOW) return; - prepareLoseFocus(PWINDOW); + g_pCompositor->setWindowFullscreen(PWINDOW, false, FULLSCREEN_FULL); const auto PWORKSPACEDATA = getMasterWorkspaceData(PWINDOW->m_iWorkspaceID); diff --git a/src/layout/MasterLayout.hpp b/src/layout/MasterLayout.hpp index d48aefdc..6f8ea120 100644 --- a/src/layout/MasterLayout.hpp +++ b/src/layout/MasterLayout.hpp @@ -87,8 +87,6 @@ class CHyprMasterLayout : public IHyprLayout { 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; @@ -108,4 +106,4 @@ struct std::formatter : std::formatter { std::format_to(out, ", window: {:x}", node->pWindow); return std::format_to(out, "]"); } -}; \ No newline at end of file +}; diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index 26326104..2125e9ba 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -227,7 +227,6 @@ bool CKeybindManager::tryMoveFocusToMonitor(CMonitor* monitor) { const auto PNEWMAINWORKSPACE = g_pCompositor->getWorkspaceByID(monitor->activeWorkspace); g_pInputManager->unconstrainMouse(); - g_pCompositor->setActiveMonitor(monitor); PNEWMAINWORKSPACE->rememberPrevWorkspace(PWORKSPACE); const auto PNEWWORKSPACE = monitor->specialWorkspaceID != 0 ? g_pCompositor->getWorkspaceByID(monitor->specialWorkspaceID) : PNEWMAINWORKSPACE; @@ -236,10 +235,15 @@ bool CKeybindManager::tryMoveFocusToMonitor(CMonitor* monitor) { if (PNEWWINDOW) { g_pCompositor->focusWindow(PNEWWINDOW); g_pCompositor->warpCursorTo(PNEWWINDOW->middle()); + + g_pInputManager->m_pForcedFocus = PNEWWINDOW; + g_pInputManager->simulateMouseMovement(); + g_pInputManager->m_pForcedFocus = nullptr; } else { g_pCompositor->focusWindow(nullptr); g_pCompositor->warpCursorTo(monitor->middle()); } + g_pCompositor->setActiveMonitor(monitor); return true; }