From 7eca164413da16e71b8835d1af6aaf23ed990af6 Mon Sep 17 00:00:00 2001 From: ItsDrike Date: Fri, 31 Mar 2023 22:32:25 +0200 Subject: [PATCH] Add initial support for children groupping --- src/main.cpp | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 73 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 9e1abaa..9e6a829 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,6 +2,7 @@ #include "globals.hpp" +#include #include #include #include @@ -10,13 +11,80 @@ const CColor s_pluginColor = {0x61 / 255.0f, 0xAF / 255.0f, 0xEF / 255.0f, 1.0f} inline std::function originalToggleGroup = nullptr; +typedef SDwindleNodeData* (*nodeFromWindowT)(void*, CWindow*); +inline nodeFromWindowT g_pNodeFromWindow = nullptr; + +void addChildNodesToDequeRecursive(std::deque* pDeque, std::deque* pParents, SDwindleNodeData* node) +{ + if (node->isNode) { + pParents->push_back(node); + addChildNodesToDequeRecursive(pDeque, pParents, node->children[0]); + addChildNodesToDequeRecursive(pDeque, pParents, node->children[1]); + } + else { + pDeque->emplace_back(node); + } +} void toggleGroup(std::string args) { // Run the original function, creating the group originalToggleGroup(args); - HyprlandAPI::addNotification(PHANDLE, "[dwindle-autogroup] Group toggeld!", s_pluginColor, 5000); + // We only care about group creations, not group disolves + const auto PWINDOW = g_pCompositor->m_pLastWindow; + + if (!PWINDOW || !g_pCompositor->windowValidMapped(PWINDOW)) + return; + + if (!PWINDOW->m_sGroupData.pNextWindow) { + Debug::log(LOG, "Ignoring autogroup for group disolve"); + return; + } + + // Don't do anything if we're not on "dwindle" layout + IHyprLayout* layout = g_pLayoutManager->getCurrentLayout(); + if (layout->getLayoutName() != "dwindle") { + return; + } + CHyprDwindleLayout* cur_dwindle = (CHyprDwindleLayout*)layout; + + const auto PNODE = g_pNodeFromWindow(cur_dwindle, PWINDOW); + if (!PNODE) { + Debug::log(LOG, "Ignoring autogroup for floating window"); + return; + } + + const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(PNODE->workspaceID); + if (PWORKSPACE->m_bHasFullscreenWindow) { + Debug::log(ERR, "Ignoring autogroupgroup on a fullscreen window"); + return; + } + + if (!PNODE->pParent) { + Debug::log(LOG, "Ignoring autogroup for a solitary window"); + } + + std::deque newGroupMembers; + std::deque parentNodes; + + addChildNodesToDequeRecursive( + &newGroupMembers, &parentNodes, PNODE->pParent->children[0] == PNODE ? PNODE->pParent->children[1] : PNODE->pParent->children[0]); + + for (auto& n : newGroupMembers) { + if (n->pWindow->m_sGroupData.pNextWindow) { + Debug::log(LOG, "Ignoring autogroup for nested groups"); + } + } + + // Add all of the children nodes into the group + for (auto& n : newGroupMembers) { + auto window = n->pWindow; + layout->onWindowRemoved(window); + PWINDOW->insertWindowToGroup(window); + window->m_dWindowDecorations.emplace_back(std::make_unique(window)); + PWINDOW->setGroupCurrent(PWINDOW); + } } // Do NOT change this function. @@ -29,6 +97,10 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) { PHANDLE = handle; + // Get address of the private CHyprDwindleLayout::getNodeFromWindow, we'll need it in toggleGroup + g_pNodeFromWindow = + (nodeFromWindowT)HyprlandAPI::getFunctionAddressFromSignature(PHANDLE, "_ZN18CHyprDwindleLayout17getNodeFromWindowEP7CWindow"); + originalToggleGroup = g_pKeybindManager->m_mDispatchers["togglegroup"]; HyprlandAPI::addDispatcher(PHANDLE, "togglegroup", toggleGroup);