From 929c250c5c2a19ccf55d45d6a3a41316ad59a1a3 Mon Sep 17 00:00:00 2001 From: Aqa-Ib Date: Thu, 17 Oct 2024 22:14:13 +0200 Subject: [PATCH] compositor: add group_on_movetoworkspace --- src/Compositor.cpp | 48 ++++++++++++++++++++++++------- src/config/ConfigDescriptions.hpp | 6 ++++ src/config/ConfigManager.cpp | 1 + src/layout/IHyprLayout.cpp | 5 ++-- 4 files changed, 47 insertions(+), 13 deletions(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index fd4979b0214..47f178029b7 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -34,6 +34,7 @@ #include "render/Renderer.hpp" #include "xwayland/XWayland.hpp" #include "helpers/ByteOperations.hpp" +#include "render/decorations/CHyprGroupBarDecoration.hpp" #include #include @@ -2748,21 +2749,46 @@ void CCompositor::moveWindowToWorkspaceSafe(PHLWINDOW pWindow, PHLWORKSPACE pWor if (FULLSCREEN) setWindowFullscreenInternal(pWindow, FSMODE_NONE); - if (!pWindow->m_bIsFloating) { + PHLWINDOW pFirstWindowOnWorkspace = g_pCompositor->getFirstWindowOnWorkspace(pWorkspace->m_iID); + const auto PWINDOWMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID); + const auto POSTOMON = pWindow->m_vRealPosition.goal() - PWINDOWMONITOR->vecPosition; + const auto PWORKSPACEMONITOR = g_pCompositor->getMonitorFromID(pWorkspace->m_iMonitorID); + + if (!pWindow->m_bIsFloating) g_pLayoutManager->getCurrentLayout()->onWindowRemovedTiling(pWindow); - pWindow->moveToWorkspace(pWorkspace); - pWindow->m_iMonitorID = pWorkspace->m_iMonitorID; - g_pLayoutManager->getCurrentLayout()->onWindowCreatedTiling(pWindow); - } else { - const auto PWINDOWMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID); - const auto POSTOMON = pWindow->m_vRealPosition.goal() - PWINDOWMONITOR->vecPosition; - const auto PWORKSPACEMONITOR = g_pCompositor->getMonitorFromID(pWorkspace->m_iMonitorID); + pWindow->moveToWorkspace(pWorkspace); + pWindow->m_iMonitorID = pWorkspace->m_iMonitorID; - pWindow->moveToWorkspace(pWorkspace); - pWindow->m_iMonitorID = pWorkspace->m_iMonitorID; + static auto PGROUPONMOVETOWORKSPACE = CConfigValue("group:group_on_movetoworkspace"); + if (*PGROUPONMOVETOWORKSPACE && pFirstWindowOnWorkspace && pFirstWindowOnWorkspace != pWindow && pFirstWindowOnWorkspace->m_sGroupData.pNextWindow.lock() && + pWindow->canBeGroupedInto(pFirstWindowOnWorkspace)) { + + pWindow->m_bIsFloating = pFirstWindowOnWorkspace->m_bIsFloating; // match the floating state. Needed to group tiled into floated and vice versa. + if (!pWindow->m_sGroupData.pNextWindow.expired()) { + PHLWINDOW next = pWindow->m_sGroupData.pNextWindow.lock(); + while (next != pWindow) { + next->m_bIsFloating = pFirstWindowOnWorkspace->m_bIsFloating; // match the floating state of group members + next = next->m_sGroupData.pNextWindow.lock(); + } + } + + static auto USECURRPOS = CConfigValue("group:insert_after_current"); + (*USECURRPOS ? pFirstWindowOnWorkspace : pFirstWindowOnWorkspace->getGroupTail())->insertWindowToGroup(pWindow); + + pFirstWindowOnWorkspace->setGroupCurrent(pWindow); + pWindow->updateWindowDecos(); + g_pLayoutManager->getCurrentLayout()->recalculateWindow(pWindow); + + if (!pWindow->getDecorationByType(DECORATION_GROUPBAR)) + pWindow->addWindowDeco(std::make_unique(pWindow)); + + } else { + if (!pWindow->m_bIsFloating) + g_pLayoutManager->getCurrentLayout()->onWindowCreatedTiling(pWindow); - pWindow->m_vRealPosition = POSTOMON + PWORKSPACEMONITOR->vecPosition; + if (pWindow->m_bIsFloating) + pWindow->m_vRealPosition = POSTOMON + PWORKSPACEMONITOR->vecPosition; } pWindow->updateToplevel(); diff --git a/src/config/ConfigDescriptions.hpp b/src/config/ConfigDescriptions.hpp index bef5ee5313f..d41fed09720 100644 --- a/src/config/ConfigDescriptions.hpp +++ b/src/config/ConfigDescriptions.hpp @@ -790,6 +790,12 @@ inline static const std::vector CONFIG_OPTIONS = { .type = CONFIG_OPTION_BOOL, .data = SConfigOptionDescription::SBoolData{false}, }, + SConfigOptionDescription{ + .value = "group:group_on_movetoworkspace", + .description = "whether using movetoworkspace[silent] will merge the window into the first window of the workspace if it is a unlocked group", + .type = CONFIG_OPTION_BOOL, + .data = SConfigOptionDescription::SBoolData{false}, + }, /* * group:groupbar: diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 6ec63d4c25f..69bf21a79f6 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -380,6 +380,7 @@ CConfigManager::CConfigManager() { m_pConfig->addConfigValue("group:merge_floated_into_tiled_on_groupbar", Hyprlang::INT{0}); m_pConfig->addConfigValue("group:auto_group", Hyprlang::INT{1}); m_pConfig->addConfigValue("group:drag_into_group", Hyprlang::INT{1}); + m_pConfig->addConfigValue("group:group_on_movetoworkspace", Hyprlang::INT{0}); m_pConfig->addConfigValue("group:groupbar:enabled", Hyprlang::INT{1}); m_pConfig->addConfigValue("group:groupbar:font_family", {STRVAL_EMPTY}); m_pConfig->addConfigValue("group:groupbar:font_size", Hyprlang::INT{8}); diff --git a/src/layout/IHyprLayout.cpp b/src/layout/IHyprLayout.cpp index b8d92636210..54e6d83ad0f 100644 --- a/src/layout/IHyprLayout.cpp +++ b/src/layout/IHyprLayout.cpp @@ -194,8 +194,9 @@ bool IHyprLayout::onWindowCreatedAutoGroup(PHLWINDOW pWindow) { denied = true; if (*PAUTOGROUP // check if auto_group is enabled. - && OPENINGON->m_sGroupData.pNextWindow.lock() // check if OPENINGON is a group. + && OPENINGON // this shouldn't be 0, but honestly, better safe than sorry. && OPENINGON != pWindow // prevent freeze when the "group set" window rule makes the new window to be already a group. + && OPENINGON->m_sGroupData.pNextWindow.lock() // check if OPENINGON is a group. && pWindow->canBeGroupedInto(OPENINGON) // check if the new window can be grouped into OPENINGON. && !g_pXWaylandManager->shouldBeFloated(pWindow) // don't group child windows. Fix for floated groups. Tiled groups don't need this because we check if !denied. && !denied) { // don't group a new floated window into a tiled group (for convenience). @@ -352,7 +353,7 @@ void IHyprLayout::onEndDragWindow() { DRAGGINGWINDOW->m_bDraggingTiled = false; } - if (DRAGGINGWINDOW->m_sGroupData.pNextWindow.lock()) { + if (!DRAGGINGWINDOW->m_sGroupData.pNextWindow.expired()) { std::vector members; PHLWINDOW curr = DRAGGINGWINDOW->getGroupHead(); do {