diff --git a/src/Compositor.cpp b/src/Compositor.cpp index fee98f8e..8a717600 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -1280,6 +1280,16 @@ int CCompositor::getWindowsOnWorkspace(const int& id, std::optional onlyTi return no; } +int CCompositor::getGroupsOnWorkspace(const int& id, std::optional onlyTiled) { + int no = 0; + for (auto& w : m_vWindows) { + if (w->workspaceID() == id && w->m_bIsMapped && !(onlyTiled.has_value() && !w->m_bIsFloating != onlyTiled.value()) && w->m_sGroupData.head) + no++; + } + + return no; +} + CWindow* CCompositor::getUrgentWindow() { for (auto& w : m_vWindows) { if (w->m_bIsMapped && w->m_bIsUrgent) diff --git a/src/Compositor.hpp b/src/Compositor.hpp index 4604f687..11be7c81 100644 --- a/src/Compositor.hpp +++ b/src/Compositor.hpp @@ -151,6 +151,7 @@ class CCompositor { void sanityCheckWorkspaces(); void updateWorkspaceWindowDecos(const int&); int getWindowsOnWorkspace(const int& id, std::optional onlyTiled = {}); + int getGroupsOnWorkspace(const int& id, std::optional onlyTiled = {}); CWindow* getUrgentWindow(); bool hasUrgentWindowOnWorkspace(const int&); CWindow* getFirstWindowOnWorkspace(const int&); diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp index 902ec2ca..7c3ceb6e 100644 --- a/src/desktop/Window.cpp +++ b/src/desktop/Window.cpp @@ -852,6 +852,7 @@ void CWindow::destroyGroup() { return; } m_sGroupData.pNextWindow = nullptr; + m_sGroupData.head = false; updateWindowDecos(); return; } diff --git a/src/desktop/Workspace.cpp b/src/desktop/Workspace.cpp index cbc4b16e..70a0f370 100644 --- a/src/desktop/Workspace.cpp +++ b/src/desktop/Workspace.cpp @@ -249,7 +249,8 @@ bool CWorkspace::matchesStaticSelector(const std::string& selector_) { // s - special: s[true] // n - named: n[true] or n[s:string] or n[e:string] // m - monitor: m[monitor_selector] - // w - windowCount: w[0-4] or w[1], optional flag t or f for tiled or floating, e.g. w[t0-1] + // w - windowCount: w[1-4] or w[1], optional flag t or f for tiled or floating and + // flag g to count groups instead of windows, e.g. w[t1-2], w[fg4] const auto NEXTSPACE = selector.find_first_of(' ', i); std::string prop = selector.substr(i, NEXTSPACE == std::string::npos ? std::string::npos : NEXTSPACE - i); @@ -354,15 +355,25 @@ bool CWorkspace::matchesStaticSelector(const std::string& selector_) { prop = prop.substr(2, prop.length() - 3); - int wantsOnlyTiled = -1; + int wantsOnlyTiled = -1; + bool wantsCountGroup = false; - if (prop.starts_with("t")) { - wantsOnlyTiled = 1; - prop = prop.substr(1); - } else if (prop.starts_with("f")) { - wantsOnlyTiled = 0; - prop = prop.substr(1); + int flagCount = 0; + for (auto& flag : prop) { + if (flag == 't' && wantsOnlyTiled == -1) { + wantsOnlyTiled = 1; + flagCount++; + } else if (flag == 'f' && wantsOnlyTiled == -1) { + wantsOnlyTiled = 0; + flagCount++; + } else if (flag == 'g' && !wantsCountGroup) { + wantsCountGroup = true; + flagCount++; + } else { + break; + } } + prop = prop.substr(flagCount); if (!prop.contains("-")) { // try single @@ -379,7 +390,15 @@ bool CWorkspace::matchesStaticSelector(const std::string& selector_) { return false; } - return g_pCompositor->getWindowsOnWorkspace(m_iID, wantsOnlyTiled == -1 ? std::nullopt : std::optional((bool)wantsOnlyTiled)) == from; + int count; + if (wantsCountGroup) + count = g_pCompositor->getGroupsOnWorkspace(m_iID, wantsOnlyTiled == -1 ? std::nullopt : std::optional((bool)wantsOnlyTiled)); + else + count = g_pCompositor->getWindowsOnWorkspace(m_iID, wantsOnlyTiled == -1 ? std::nullopt : std::optional((bool)wantsOnlyTiled)); + + if (count != from) + return false; + continue; } const auto DASHPOS = prop.find("-"); @@ -403,8 +422,13 @@ bool CWorkspace::matchesStaticSelector(const std::string& selector_) { return false; } - const auto WINDOWSONWORKSPACE = g_pCompositor->getWindowsOnWorkspace(m_iID, wantsOnlyTiled == -1 ? std::nullopt : std::optional((bool)wantsOnlyTiled)); - if (std::clamp(WINDOWSONWORKSPACE, from, to) != WINDOWSONWORKSPACE) + int count; + if (wantsCountGroup) + count = g_pCompositor->getGroupsOnWorkspace(m_iID, wantsOnlyTiled == -1 ? std::nullopt : std::optional((bool)wantsOnlyTiled)); + else + count = g_pCompositor->getWindowsOnWorkspace(m_iID, wantsOnlyTiled == -1 ? std::nullopt : std::optional((bool)wantsOnlyTiled)); + + if (std::clamp(count, from, to) != count) return false; continue; }