From 1357b66091ecd73f097d19d527a23a9ae72a4ff1 Mon Sep 17 00:00:00 2001 From: memchr <118117622+memchr@users.noreply.github.com> Date: Thu, 21 Sep 2023 23:42:00 +0000 Subject: windowrules: add rule `group` to map windows grouped (#3279) * windows: add rule group to map windows grouped * group rule: use `invade` to force open a window in a locked group --- src/managers/KeybindManager.cpp | 100 +++++++++++++++------------------------- 1 file changed, 36 insertions(+), 64 deletions(-) (limited to 'src/managers/KeybindManager.cpp') diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index 0703ba2e..0e4d47b9 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -72,6 +72,7 @@ CKeybindManager::CKeybindManager() { m_mDispatchers["moveoutofgroup"] = moveOutOfGroup; m_mDispatchers["movewindoworgroup"] = moveWindowOrGroup; m_mDispatchers["setignoregrouplock"] = setIgnoreGroupLock; + m_mDispatchers["denywindowfromgroup"] = denyWindowFromGroup; m_mDispatchers["global"] = global; m_tScrollTimer.reset(); @@ -1151,46 +1152,10 @@ void CKeybindManager::toggleGroup(std::string args) { g_pCompositor->setWindowFullscreen(PWINDOW, false, FULLSCREEN_FULL); - if (!PWINDOW->m_sGroupData.pNextWindow) { - PWINDOW->m_sGroupData.pNextWindow = PWINDOW; - PWINDOW->m_sGroupData.head = true; - PWINDOW->m_sGroupData.locked = false; - - PWINDOW->m_dWindowDecorations.emplace_back(std::make_unique(PWINDOW)); - - PWINDOW->updateWindowDecos(); - g_pLayoutManager->getCurrentLayout()->recalculateWindow(PWINDOW); - } else { - if (PWINDOW->m_sGroupData.pNextWindow == PWINDOW) { - PWINDOW->m_sGroupData.pNextWindow = nullptr; - PWINDOW->updateWindowDecos(); - } else { - // enum all windows, remove their group state, readd to layout. - CWindow* curr = PWINDOW; - std::vector members; - do { - const auto PLASTWIN = curr; - curr = curr->m_sGroupData.pNextWindow; - PLASTWIN->m_sGroupData.pNextWindow = nullptr; - curr->setHidden(false); - members.push_back(curr); - } while (curr != PWINDOW); - - for (auto& w : members) { - if (w->m_sGroupData.head) - g_pLayoutManager->getCurrentLayout()->onWindowRemoved(curr); - w->m_sGroupData.head = false; - } - - const bool GROUPSLOCKEDPREV = g_pKeybindManager->m_bGroupsLocked; - g_pKeybindManager->m_bGroupsLocked = true; - for (auto& w : members) { - g_pLayoutManager->getCurrentLayout()->onWindowCreated(w); - w->updateWindowDecos(); - } - g_pKeybindManager->m_bGroupsLocked = GROUPSLOCKEDPREV; - } - } + if (!PWINDOW->m_sGroupData.pNextWindow) + PWINDOW->createGroup(); + else + PWINDOW->destroyGroup(); g_pCompositor->updateAllWindowsAnimatedDecorationValues(); } @@ -1978,6 +1943,9 @@ void CKeybindManager::lockActiveGroup(std::string args) { } void CKeybindManager::moveWindowIntoGroup(CWindow* pWindow, CWindow* pWindowInDirection) { + if (pWindow->m_sGroupData.deny) + return; + if (!pWindow->m_sGroupData.pNextWindow) pWindow->m_dWindowDecorations.emplace_back(std::make_unique(pWindow)); @@ -1995,6 +1963,7 @@ void CKeybindManager::moveWindowIntoGroup(CWindow* pWindow, CWindow* pWindowInDi } void CKeybindManager::moveWindowOutOfGroup(CWindow* pWindow, const std::string& dir) { + static auto* const BFOCUSREMOVEDWINDOW = &g_pConfigManager->getConfigValuePtr("misc:group_focus_removed_window")->intValue; const auto PWINDOWPREV = pWindow->getGroupPrevious(); eDirection direction; @@ -2010,8 +1979,7 @@ void CKeybindManager::moveWindowOutOfGroup(CWindow* pWindow, const std::string& } if (pWindow->m_sGroupData.pNextWindow == pWindow) { - pWindow->m_sGroupData.pNextWindow = nullptr; - pWindow->updateWindowDecos(); + pWindow->destroyGroup(); } else { g_pLayoutManager->getCurrentLayout()->onWindowRemoved(pWindow); @@ -2044,7 +2012,7 @@ void CKeybindManager::moveIntoGroup(std::string args) { const auto PWINDOW = g_pCompositor->m_pLastWindow; - if (!PWINDOW || PWINDOW->m_bIsFloating) + if (!PWINDOW || PWINDOW->m_bIsFloating || PWINDOW->m_sGroupData.deny) return; auto PWINDOWINDIR = g_pCompositor->getWindowInDirection(PWINDOW, arg); @@ -2071,7 +2039,7 @@ void CKeybindManager::moveOutOfGroup(std::string args) { void CKeybindManager::moveWindowOrGroup(std::string args) { char arg = args[0]; - static auto* const BIGNOREGROUPLOCK = &g_pConfigManager->getConfigValuePtr("binds:ignore_group_lock")->intValue; + static auto* const PIGNOREGROUPLOCK = &g_pConfigManager->getConfigValuePtr("binds:ignore_group_lock")->intValue; if (!isDirection(args)) { Debug::log(ERR, "Cannot move into group in direction %c, unsupported direction. Supported: l,r,u/t,d/b", arg); @@ -2079,40 +2047,31 @@ void CKeybindManager::moveWindowOrGroup(std::string args) { } const auto PWINDOW = g_pCompositor->m_pLastWindow; - if (!PWINDOW || PWINDOW->m_bIsFullscreen) return; + const auto PWINDOWINDIR = g_pCompositor->getWindowInDirection(PWINDOW, arg); - const auto ISWINDOWGROUP = PWINDOW->m_sGroupData.pNextWindow; - const auto ISWINDOWGROUPLOCKED = ISWINDOWGROUP && PWINDOW->getGroupHead()->m_sGroupData.locked; - - const auto PWINDOWINDIR = g_pCompositor->getWindowInDirection(PWINDOW, arg); - const auto ISWINDOWINDIRGROUP = PWINDOWINDIR && PWINDOWINDIR->m_sGroupData.pNextWindow; - const auto ISWINDOWINDIRGROUPLOCKED = ISWINDOWINDIRGROUP && PWINDOWINDIR->getGroupHead()->m_sGroupData.locked; + const bool ISWINDOWGROUP = PWINDOW->m_sGroupData.pNextWindow; + const bool ISWINDOWGROUPLOCKED = ISWINDOWGROUP && PWINDOW->getGroupHead()->m_sGroupData.locked; + const bool ISWINDOWGROUPSINGLE = ISWINDOWGROUP && PWINDOW->m_sGroupData.pNextWindow == PWINDOW; // note: PWINDOWINDIR is not null implies !PWINDOW->m_bIsFloating - if (ISWINDOWINDIRGROUP && !ISWINDOWINDIRGROUPLOCKED) { - if (ISWINDOWGROUPLOCKED && !*BIGNOREGROUPLOCK) { + if (PWINDOWINDIR && PWINDOWINDIR->m_sGroupData.pNextWindow) { // target is group + if (!*PIGNOREGROUPLOCK && (PWINDOWINDIR->getGroupHead()->m_sGroupData.locked || ISWINDOWGROUPLOCKED || PWINDOW->m_sGroupData.deny)) { g_pLayoutManager->getCurrentLayout()->moveWindowTo(PWINDOW, args); g_pCompositor->warpCursorTo(PWINDOW->middle()); } else moveWindowIntoGroup(PWINDOW, PWINDOWINDIR); - } else if (ISWINDOWINDIRGROUPLOCKED) { - if (!*BIGNOREGROUPLOCK) { + } else if (PWINDOWINDIR) { // target is regular window + if ((!*PIGNOREGROUPLOCK && ISWINDOWGROUPLOCKED) || !ISWINDOWGROUP || (ISWINDOWGROUPSINGLE && PWINDOW->m_eGroupRules & GROUP_SET_ALWAYS)) { g_pLayoutManager->getCurrentLayout()->moveWindowTo(PWINDOW, args); g_pCompositor->warpCursorTo(PWINDOW->middle()); } else - moveWindowIntoGroup(PWINDOW, PWINDOWINDIR); - } else if (PWINDOWINDIR) { - if (ISWINDOWGROUP && (*BIGNOREGROUPLOCK || !ISWINDOWGROUPLOCKED)) moveWindowOutOfGroup(PWINDOW, args); - else { - g_pLayoutManager->getCurrentLayout()->moveWindowTo(PWINDOW, args); - g_pCompositor->warpCursorTo(PWINDOW->middle()); - } - } else if (ISWINDOWGROUP && (*BIGNOREGROUPLOCK || !ISWINDOWGROUPLOCKED)) { + } else if ((*PIGNOREGROUPLOCK || !ISWINDOWGROUPLOCKED) && ISWINDOWGROUP) // no target window moveWindowOutOfGroup(PWINDOW, args); - } + + g_pCompositor->updateWindowAnimatedDecorationValues(PWINDOW); } void CKeybindManager::setIgnoreGroupLock(std::string args) { @@ -2126,6 +2085,19 @@ void CKeybindManager::setIgnoreGroupLock(std::string args) { g_pEventManager->postEvent(SHyprIPCEvent{"ignoregrouplock", std::to_string(*BIGNOREGROUPLOCK)}); } +void CKeybindManager::denyWindowFromGroup(std::string args) { + const auto PWINDOW = g_pCompositor->m_pLastWindow; + if (!PWINDOW || (PWINDOW && PWINDOW->m_sGroupData.pNextWindow)) + return; + + if (args == "toggle") + PWINDOW->m_sGroupData.deny = !PWINDOW->m_sGroupData.deny; + else + PWINDOW->m_sGroupData.deny = args == "on"; + + g_pCompositor->updateWindowAnimatedDecorationValues(PWINDOW); +} + void CKeybindManager::global(std::string args) { const auto APPID = args.substr(0, args.find_first_of(':')); const auto NAME = args.substr(args.find_first_of(':') + 1); -- cgit v1.2.3