diff --git a/src/Compositor.cpp b/src/Compositor.cpp index a45d48a0..cfc5e258 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -466,16 +466,16 @@ bool CCompositor::windowExists(CWindow* pWindow) { CWindow* CCompositor::vectorToWindow(const Vector2D& pos) { const auto PMONITOR = getMonitorFromVector(pos); - if (PMONITOR->specialWorkspaceOpen) { + if (PMONITOR->specialWorkspaceID) { for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) { wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y}; - if ((*w)->m_bIsFloating && (*w)->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && (*w)->m_bIsMapped && wlr_box_contains_point(&box, pos.x, pos.y) && !(*w)->isHidden()) + if ((*w)->m_bIsFloating && (*w)->m_iWorkspaceID == PMONITOR->specialWorkspaceID && (*w)->m_bIsMapped && wlr_box_contains_point(&box, pos.x, pos.y) && !(*w)->isHidden()) return (*w).get(); } for (auto& w : m_vWindows) { wlr_box box = {w->m_vRealPosition.vec().x, w->m_vRealPosition.vec().y, w->m_vRealSize.vec().x, w->m_vRealSize.vec().y}; - if (w->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && wlr_box_contains_point(&box, pos.x, pos.y) && w->m_bIsMapped && !w->m_bIsFloating && !w->isHidden()) + if (w->m_iWorkspaceID == PMONITOR->specialWorkspaceID && wlr_box_contains_point(&box, pos.x, pos.y) && w->m_bIsMapped && !w->m_bIsFloating && !w->isHidden()) return w.get(); } } @@ -506,10 +506,10 @@ CWindow* CCompositor::vectorToWindow(const Vector2D& pos) { CWindow* CCompositor::vectorToWindowTiled(const Vector2D& pos) { const auto PMONITOR = getMonitorFromVector(pos); - if (PMONITOR->specialWorkspaceOpen) { + if (PMONITOR->specialWorkspaceID) { for (auto& w : m_vWindows) { wlr_box box = {w->m_vPosition.x, w->m_vPosition.y, w->m_vSize.x, w->m_vSize.y}; - if (w->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && wlr_box_contains_point(&box, pos.x, pos.y) && !w->m_bIsFloating && !w->isHidden()) + if (w->m_iWorkspaceID == PMONITOR->specialWorkspaceID && wlr_box_contains_point(&box, pos.x, pos.y) && !w->m_bIsFloating && !w->isHidden()) return w.get(); } } @@ -536,16 +536,16 @@ CWindow* CCompositor::vectorToWindowIdeal(const Vector2D& pos) { const auto PMONITOR = getMonitorFromVector(pos); // special workspace - if (PMONITOR->specialWorkspaceOpen) { + if (PMONITOR->specialWorkspaceID) { for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) { wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y}; - if ((*w)->m_bIsFloating && (*w)->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && (*w)->m_bIsMapped && wlr_box_contains_point(&box, pos.x, pos.y) && !(*w)->isHidden() && !(*w)->m_bX11ShouldntFocus) + if ((*w)->m_bIsFloating && (*w)->m_iWorkspaceID == PMONITOR->specialWorkspaceID && (*w)->m_bIsMapped && wlr_box_contains_point(&box, pos.x, pos.y) && !(*w)->isHidden() && !(*w)->m_bX11ShouldntFocus) return (*w).get(); } for (auto& w : m_vWindows) { wlr_box box = {w->m_vPosition.x, w->m_vPosition.y, w->m_vSize.x, w->m_vSize.y}; - if (!w->m_bIsFloating && w->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && w->m_bIsMapped && wlr_box_contains_point(&box, pos.x, pos.y) && !w->isHidden() && !w->m_bX11ShouldntFocus) + if (!w->m_bIsFloating && w->m_iWorkspaceID == PMONITOR->specialWorkspaceID && w->m_bIsMapped && wlr_box_contains_point(&box, pos.x, pos.y) && !w->isHidden() && !w->m_bX11ShouldntFocus) return w.get(); } } @@ -624,16 +624,16 @@ CWindow* CCompositor::vectorToWindowIdeal(const Vector2D& pos) { CWindow* CCompositor::windowFromCursor() { const auto PMONITOR = getMonitorFromCursor(); - if (PMONITOR->specialWorkspaceOpen) { + if (PMONITOR->specialWorkspaceID) { for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) { wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y}; - if ((*w)->m_bIsFloating && (*w)->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && (*w)->m_bIsMapped && wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y) && !(*w)->isHidden()) + if ((*w)->m_bIsFloating && (*w)->m_iWorkspaceID == PMONITOR->specialWorkspaceID && (*w)->m_bIsMapped && wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y) && !(*w)->isHidden()) return (*w).get(); } for (auto& w : m_vWindows) { wlr_box box = {w->m_vPosition.x, w->m_vPosition.y, w->m_vSize.x, w->m_vSize.y}; - if (w->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y) && w->m_bIsMapped) + if (w->m_iWorkspaceID == PMONITOR->specialWorkspaceID && wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y) && w->m_bIsMapped) return w.get(); } } @@ -924,7 +924,7 @@ bool CCompositor::isWorkspaceVisible(const int& w) { if (m->activeWorkspace == w) return true; - if (m->specialWorkspaceOpen && w == SPECIAL_WORKSPACE_ID) + if (m->specialWorkspaceID && isWorkspaceSpecial(w)) return true; } @@ -953,10 +953,8 @@ void CCompositor::sanityCheckWorkspaces() { continue; } - if ((*it)->m_iID == SPECIAL_WORKSPACE_ID && WINDOWSONWORKSPACE == 0) { - for (auto& m : m_vMonitors) { - m->specialWorkspaceOpen = false; - } + if ((*it)->m_bIsSpecialWorkspace && WINDOWSONWORKSPACE == 0) { + getMonitorFromID((*it)->m_iMonitorID)->specialWorkspaceID = 0; it = m_vWorkspaces.erase(it); @@ -1714,7 +1712,7 @@ bool CCompositor::workspaceIDOutOfBounds(const int& id) { int highestID = -99999; for (auto& w : m_vWorkspaces) { - if (w->m_iID == SPECIAL_WORKSPACE_ID) + if (w->m_bIsSpecialWorkspace) continue; if (w->m_iID < lowestID) @@ -1991,10 +1989,12 @@ CWorkspace* CCompositor::createNewWorkspace(const int& id, const int& monid, con monID = PMONITOR->ID; } - const auto PWORKSPACE = m_vWorkspaces.emplace_back(std::make_unique(monID, NAME, id == SPECIAL_WORKSPACE_ID)).get(); + const bool SPECIAL = id >= SPECIAL_WORKSPACE_START && id <= -2; + + const auto PWORKSPACE = m_vWorkspaces.emplace_back(std::make_unique(monID, NAME, SPECIAL)).get(); // We are required to set the name here immediately - if (id != SPECIAL_WORKSPACE_ID) + if (!SPECIAL) wlr_ext_workspace_handle_v1_set_name(PWORKSPACE->m_pWlrHandle, NAME.c_str()); PWORKSPACE->m_iID = id; @@ -2017,3 +2017,18 @@ void CCompositor::setActiveMonitor(CMonitor* pMonitor) { g_pEventManager->postEvent(SHyprIPCEvent{"focusedmon", pMonitor->szName + "," + PWORKSPACE->m_szName}); m_pLastMonitor = pMonitor; } + +bool CCompositor::isWorkspaceSpecial(const int& id) { + return id >= SPECIAL_WORKSPACE_START && id <= -2; +} + +int CCompositor::getNewSpecialID() { + int highest = -100; + for (auto& ws : m_vWorkspaces) { + if (ws->m_bIsSpecialWorkspace && ws->m_iID > highest) { + highest = ws->m_iID; + } + } + + return highest + 1; +} diff --git a/src/Compositor.hpp b/src/Compositor.hpp index 9cf73acc..7bc47176 100644 --- a/src/Compositor.hpp +++ b/src/Compositor.hpp @@ -170,6 +170,8 @@ public: bool cursorOnReservedArea(); CWorkspace* createNewWorkspace(const int&, const int&, const std::string& name = ""); // will be deleted next frame if left empty and unfocused! void setActiveMonitor(CMonitor*); + bool isWorkspaceSpecial(const int&); + int getNewSpecialID(); std::string explicitConfigPath; diff --git a/src/defines.hpp b/src/defines.hpp index 4e517754..7f2c6e45 100644 --- a/src/defines.hpp +++ b/src/defines.hpp @@ -78,6 +78,6 @@ #define GIT_DIRTY "?" #endif -#define SPECIAL_WORKSPACE_ID -99 +#define SPECIAL_WORKSPACE_START -99 #define PI 3.14159265358979 diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp index 256b58d7..5683eb45 100644 --- a/src/events/Windows.cpp +++ b/src/events/Windows.cpp @@ -53,10 +53,10 @@ void Events::listener_mapWindow(void* owner, void* data) { static auto *const PSWALLOWREGEX = &g_pConfigManager->getConfigValuePtr("misc:swallow_regex")->strValue; auto PMONITOR = g_pCompositor->m_pLastMonitor; - const auto PWORKSPACE = PMONITOR->specialWorkspaceOpen ? g_pCompositor->getWorkspaceByID(SPECIAL_WORKSPACE_ID) : g_pCompositor->getWorkspaceByID(PMONITOR->activeWorkspace); + const auto PWORKSPACE = PMONITOR->specialWorkspaceID ? g_pCompositor->getWorkspaceByID(PMONITOR->specialWorkspaceID) : g_pCompositor->getWorkspaceByID(PMONITOR->activeWorkspace); PWINDOW->m_iMonitorID = PMONITOR->ID; PWINDOW->m_bMappedX11 = true; - PWINDOW->m_iWorkspaceID = PMONITOR->specialWorkspaceOpen ? SPECIAL_WORKSPACE_ID : PMONITOR->activeWorkspace; + PWINDOW->m_iWorkspaceID = PMONITOR->specialWorkspaceID ? PMONITOR->specialWorkspaceID : PMONITOR->activeWorkspace; PWINDOW->m_bIsMapped = true; PWINDOW->m_bReadyToDelete = false; PWINDOW->m_bFadingOut = false; @@ -211,9 +211,8 @@ void Events::listener_mapWindow(void* owner, void* data) { shouldFocus = true; } - if (requestedWorkspace == "special") { + if (requestedWorkspace.find("special" == 0)) { workspaceSpecial = true; - workspaceSilent = true; } if (!workspaceSilent) { @@ -240,7 +239,7 @@ void Events::listener_mapWindow(void* owner, void* data) { workspaceID = g_pCompositor->getNextAvailableNamedWorkspace(); } else if (workspaceSpecial) { workspaceName = ""; - workspaceID = SPECIAL_WORKSPACE_ID; + workspaceID = getWorkspaceIDFromString(requestedWorkspace, workspaceName); } else { try { workspaceID = std::stoi(requestedWorkspace); diff --git a/src/helpers/MiscFunctions.cpp b/src/helpers/MiscFunctions.cpp index 37828c5d..5f2aae6a 100644 --- a/src/helpers/MiscFunctions.cpp +++ b/src/helpers/MiscFunctions.cpp @@ -234,7 +234,18 @@ int getWorkspaceIDFromString(const std::string& in, std::string& outName) { int result = INT_MAX; if (in.find("special") == 0) { outName = "special"; - return SPECIAL_WORKSPACE_ID; + + if (in.length() > 8) { + const auto NAME = in.substr(8); + + const auto WS = g_pCompositor->getWorkspaceByName("special:" + NAME); + + outName = "special:" + NAME; + + return WS ? WS->m_iID : g_pCompositor->getNewSpecialID(); + } + + return SPECIAL_WORKSPACE_START; } else if (in.find("name:") == 0) { const auto WORKSPACENAME = in.substr(in.find_first_of(':') + 1); const auto WORKSPACE = g_pCompositor->getWorkspaceByName(WORKSPACENAME); @@ -281,7 +292,7 @@ int getWorkspaceIDFromString(const std::string& in, std::string& outName) { int highestID = -99999; for (auto& w : g_pCompositor->m_vWorkspaces) { - if (w->m_iID == SPECIAL_WORKSPACE_ID) + if (g_pCompositor->isWorkspaceSpecial(w->m_iID)) continue; if (w->m_iID < lowestID) @@ -297,7 +308,7 @@ int getWorkspaceIDFromString(const std::string& in, std::string& outName) { searchID = lowestID; } - if (const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(searchID); PWORKSPACE && PWORKSPACE->m_iID != SPECIAL_WORKSPACE_ID) { + if (const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(searchID); PWORKSPACE && !PWORKSPACE->m_bIsSpecialWorkspace) { if (onAllMonitors || PWORKSPACE->m_iMonitorID == g_pCompositor->m_pLastMonitor->ID) { currentID = PWORKSPACE->m_iID; diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp index eb481748..451eaf6a 100644 --- a/src/helpers/Monitor.cpp +++ b/src/helpers/Monitor.cpp @@ -245,7 +245,7 @@ void CMonitor::setupDefaultWS(const SMonitorRule& monitorRule) { std::string newDefaultWorkspaceName = ""; auto WORKSPACEID = monitorRule.defaultWorkspace == "" ? g_pCompositor->m_vWorkspaces.size() + 1 : getWorkspaceIDFromString(monitorRule.defaultWorkspace, newDefaultWorkspaceName); - if (WORKSPACEID == INT_MAX || WORKSPACEID == (long unsigned int)SPECIAL_WORKSPACE_ID) { + if (WORKSPACEID == INT_MAX || (WORKSPACEID >= SPECIAL_WORKSPACE_START && WORKSPACEID <= -2)) { WORKSPACEID = g_pCompositor->m_vWorkspaces.size() + 1; newDefaultWorkspaceName = std::to_string(WORKSPACEID); diff --git a/src/helpers/Monitor.hpp b/src/helpers/Monitor.hpp index c2cc179b..257bdd64 100644 --- a/src/helpers/Monitor.hpp +++ b/src/helpers/Monitor.hpp @@ -46,8 +46,8 @@ public: CMonitor* pMirrorOf = nullptr; std::vector mirrors; - // for the special workspace - bool specialWorkspaceOpen = false; + // for the special workspace. 0 means not open. + int specialWorkspaceID = 0; // Double-linked list because we need to have constant mem addresses for signals // We have to store pointers and use raw new/delete because they might be moved between them diff --git a/src/layout/DwindleLayout.cpp b/src/layout/DwindleLayout.cpp index c4b1e5a9..3c491d72 100644 --- a/src/layout/DwindleLayout.cpp +++ b/src/layout/DwindleLayout.cpp @@ -144,9 +144,9 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode, bool for CMonitor* PMONITOR = nullptr; - if (pNode->workspaceID == SPECIAL_WORKSPACE_ID) { + if (g_pCompositor->isWorkspaceSpecial(pNode->workspaceID)) { for (auto& m : g_pCompositor->m_vMonitors) { - if (m->specialWorkspaceOpen) { + if (m->specialWorkspaceID == pNode->workspaceID) { PMONITOR = m.get(); break; } @@ -188,7 +188,7 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode, bool for const auto NODESONWORKSPACE = getNodesOnWorkspace(PWINDOW->m_iWorkspaceID); - if (*PNOGAPSWHENONLY && PWINDOW->m_iWorkspaceID != SPECIAL_WORKSPACE_ID && (NODESONWORKSPACE == 1 || (pNode->isGroupMember() && pNode->getGroupMemberCount() == NODESONWORKSPACE) || (PWINDOW->m_bIsFullscreen && g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID)->m_efFullscreenMode == FULLSCREEN_MAXIMIZED))) { + if (*PNOGAPSWHENONLY && !g_pCompositor->isWorkspaceSpecial(PWINDOW->m_iWorkspaceID) && (NODESONWORKSPACE == 1 || (pNode->isGroupMember() && pNode->getGroupMemberCount() == NODESONWORKSPACE) || (PWINDOW->m_bIsFullscreen && g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID)->m_efFullscreenMode == FULLSCREEN_MAXIMIZED))) { PWINDOW->m_vRealPosition = calcPos - Vector2D(*PBORDERSIZE, *PBORDERSIZE); PWINDOW->m_vRealSize = calcSize + Vector2D(2 * *PBORDERSIZE, 2 * *PBORDERSIZE); @@ -238,7 +238,7 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode, bool for } } - if (PWINDOW->m_iWorkspaceID == SPECIAL_WORKSPACE_ID) { + if (g_pCompositor->isWorkspaceSpecial(PWINDOW->m_iWorkspaceID)) { // if special, we adjust the coords a bit static auto *const PSCALEFACTOR = &g_pConfigManager->getConfigValuePtr("dwindle:special_scale_factor")->floatValue; @@ -293,7 +293,7 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow) { SDwindleNodeData* OPENINGON; const auto MONFROMCURSOR = g_pCompositor->getMonitorFromCursor(); - if (PMONITOR->ID == MONFROMCURSOR->ID && (PNODE->workspaceID == PMONITOR->activeWorkspace || (PNODE->workspaceID == SPECIAL_WORKSPACE_ID && PMONITOR->specialWorkspaceOpen)) && !*PUSEACTIVE) { + if (PMONITOR->ID == MONFROMCURSOR->ID && (PNODE->workspaceID == PMONITOR->activeWorkspace || (g_pCompositor->isWorkspaceSpecial(PNODE->workspaceID) && PMONITOR->specialWorkspaceID)) && !*PUSEACTIVE) { OPENINGON = getNodeFromWindow(g_pCompositor->vectorToWindowTiled(g_pInputManager->getMouseCoordsInternal())); // happens on reserved area @@ -567,8 +567,8 @@ void CHyprDwindleLayout::recalculateMonitor(const int& monid) { g_pHyprRenderer->damageMonitor(PMONITOR); - if (PMONITOR->specialWorkspaceOpen) { - const auto TOPNODE = getMasterNodeOnWorkspace(SPECIAL_WORKSPACE_ID); + if (PMONITOR->specialWorkspaceID) { + const auto TOPNODE = getMasterNodeOnWorkspace(PMONITOR->specialWorkspaceID); if (TOPNODE && PMONITOR) { TOPNODE->position = PMONITOR->vecPosition + PMONITOR->vecReservedTopLeft; @@ -709,7 +709,7 @@ void CHyprDwindleLayout::fullscreenRequestForWindow(CWindow* pWindow, eFullscree if (!g_pCompositor->windowValidMapped(pWindow)) return; - if (on == pWindow->m_bIsFullscreen || pWindow->m_iWorkspaceID == SPECIAL_WORKSPACE_ID) + if (on == pWindow->m_bIsFullscreen || g_pCompositor->isWorkspaceSpecial(pWindow->m_iWorkspaceID)) return; // ignore const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID); diff --git a/src/layout/MasterLayout.cpp b/src/layout/MasterLayout.cpp index 683dcdce..932f4d30 100644 --- a/src/layout/MasterLayout.cpp +++ b/src/layout/MasterLayout.cpp @@ -153,8 +153,8 @@ void CHyprMasterLayout::recalculateMonitor(const int& monid) { g_pHyprRenderer->damageMonitor(PMONITOR); - if (PMONITOR->specialWorkspaceOpen) { - calculateWorkspace(SPECIAL_WORKSPACE_ID); + if (PMONITOR->specialWorkspaceID) { + calculateWorkspace(PMONITOR->specialWorkspaceID); } if (PWORKSPACE->m_bHasFullscreenWindow) { @@ -248,9 +248,9 @@ void CHyprMasterLayout::calculateWorkspace(const int& ws) { void CHyprMasterLayout::applyNodeDataToWindow(SMasterNodeData* pNode) { CMonitor* PMONITOR = nullptr; - if (pNode->workspaceID == SPECIAL_WORKSPACE_ID) { + if (g_pCompositor->isWorkspaceSpecial(pNode->workspaceID)) { for (auto& m : g_pCompositor->m_vMonitors) { - if (m->specialWorkspaceOpen) { + if (m->specialWorkspaceID == pNode->workspaceID) { PMONITOR = m.get(); break; } @@ -289,7 +289,7 @@ void CHyprMasterLayout::applyNodeDataToWindow(SMasterNodeData* pNode) { auto calcPos = PWINDOW->m_vPosition + Vector2D(*PBORDERSIZE, *PBORDERSIZE); auto calcSize = PWINDOW->m_vSize - Vector2D(2 * *PBORDERSIZE, 2 * *PBORDERSIZE); - if (*PNOGAPSWHENONLY && PWINDOW->m_iWorkspaceID != SPECIAL_WORKSPACE_ID && (getNodesOnWorkspace(PWINDOW->m_iWorkspaceID) == 1 || (PWINDOW->m_bIsFullscreen && g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID)->m_efFullscreenMode == FULLSCREEN_MAXIMIZED))) { + if (*PNOGAPSWHENONLY && !g_pCompositor->isWorkspaceSpecial(PWINDOW->m_iWorkspaceID) && (getNodesOnWorkspace(PWINDOW->m_iWorkspaceID) == 1 || (PWINDOW->m_bIsFullscreen && g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID)->m_efFullscreenMode == FULLSCREEN_MAXIMIZED))) { PWINDOW->m_vRealPosition = calcPos - Vector2D(*PBORDERSIZE, *PBORDERSIZE); PWINDOW->m_vRealSize = calcSize + Vector2D(2 * *PBORDERSIZE, 2 * *PBORDERSIZE); @@ -315,7 +315,7 @@ void CHyprMasterLayout::applyNodeDataToWindow(SMasterNodeData* pNode) { calcPos = calcPos + OFFSETTOPLEFT; calcSize = calcSize - OFFSETTOPLEFT - OFFSETBOTTOMRIGHT; - if (PWINDOW->m_iWorkspaceID == SPECIAL_WORKSPACE_ID) { + if (g_pCompositor->isWorkspaceSpecial(PWINDOW->m_iWorkspaceID)) { static auto *const PSCALEFACTOR = &g_pConfigManager->getConfigValuePtr("master:special_scale_factor")->floatValue; PWINDOW->m_vRealPosition = calcPos + (calcSize - calcSize * *PSCALEFACTOR) / 2.f; @@ -395,7 +395,7 @@ void CHyprMasterLayout::fullscreenRequestForWindow(CWindow* pWindow, eFullscreen if (!g_pCompositor->windowValidMapped(pWindow)) return; - if (on == pWindow->m_bIsFullscreen || pWindow->m_iWorkspaceID == SPECIAL_WORKSPACE_ID) + if (on == pWindow->m_bIsFullscreen || g_pCompositor->isWorkspaceSpecial(pWindow->m_iWorkspaceID)) return; // ignore const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID); diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index f6e91309..661467e4 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -594,7 +594,7 @@ void CKeybindManager::toggleActiveFloating(std::string args) { // remove drag status g_pInputManager->currentlyDraggedWindow = nullptr; - if (PWINDOW->m_iWorkspaceID == SPECIAL_WORKSPACE_ID) + if (g_pCompositor->isWorkspaceSpecial(PWINDOW->m_iWorkspaceID)) return; PWINDOW->m_bIsFloating = !PWINDOW->m_bIsFloating; @@ -723,7 +723,7 @@ void CKeybindManager::changeworkspace(std::string args) { // Remember previous workspace. PWORKSPACETOCHANGETO->m_iPrevWorkspaceID = g_pCompositor->m_pLastMonitor->activeWorkspace; - if (workspaceToChangeTo == SPECIAL_WORKSPACE_ID) + if (g_pCompositor->isWorkspaceSpecial(workspaceToChangeTo)) PWORKSPACETOCHANGETO->m_iMonitorID = PMONITOR->ID; // if it's not visible, make it visible. @@ -738,10 +738,10 @@ void CKeybindManager::changeworkspace(std::string args) { } // change it - if (workspaceToChangeTo != SPECIAL_WORKSPACE_ID) + if (!g_pCompositor->isWorkspaceSpecial(workspaceToChangeTo)) PMONITOR->activeWorkspace = workspaceToChangeTo; else - PMONITOR->specialWorkspaceOpen = true; + PMONITOR->specialWorkspaceID = workspaceToChangeTo; // here and only here begin anim. we don't want to anim visible workspaces on other monitors. // check if anim left or right @@ -817,7 +817,7 @@ void CKeybindManager::changeworkspace(std::string args) { // start anim on new workspace PWORKSPACE->startAnim(true, ANIMTOLEFT); - PMONITOR->specialWorkspaceOpen = false; + PMONITOR->specialWorkspaceID = 0; // fix pinned windows for (auto& w : g_pCompositor->m_vWindows) { @@ -826,10 +826,10 @@ void CKeybindManager::changeworkspace(std::string args) { } } - if (workspaceToChangeTo != SPECIAL_WORKSPACE_ID) + if (!g_pCompositor->isWorkspaceSpecial(workspaceToChangeTo)) PMONITOR->activeWorkspace = workspaceToChangeTo; else - PMONITOR->specialWorkspaceOpen = true; + PMONITOR->specialWorkspaceID = workspaceToChangeTo; // set active and deactivate all other g_pCompositor->deactivateAllWLRWorkspaces(PWORKSPACE->m_pWlrHandle); @@ -862,7 +862,7 @@ void CKeybindManager::fullscreenActive(std::string args) { if (!PWINDOW) return; - if (PWINDOW->m_iWorkspaceID == SPECIAL_WORKSPACE_ID) + if (g_pCompositor->isWorkspaceSpecial(PWINDOW->m_iWorkspaceID)) return; g_pCompositor->setWindowFullscreen(PWINDOW, !PWINDOW->m_bIsFullscreen, args == "1" ? FULLSCREEN_MAXIMIZED : FULLSCREEN_FULL); @@ -885,8 +885,8 @@ void CKeybindManager::moveActiveToWorkspace(std::string args) { const auto OLDWORKSPACE = g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID); // hack - std::string unusedName; - const auto WORKSPACEID = getWorkspaceIDFromString(args, unusedName); + std::string workspaceName; + const auto WORKSPACEID = getWorkspaceIDFromString(args, workspaceName); if (WORKSPACEID == PWINDOW->m_iWorkspaceID) { Debug::log(LOG, "Not moving to workspace because it didn't change."); @@ -937,14 +937,14 @@ void CKeybindManager::moveActiveToWorkspace(std::string args) { } // undo the damage if we are moving to the special workspace - if (WORKSPACEID == SPECIAL_WORKSPACE_ID) { + if (g_pCompositor->isWorkspaceSpecial(WORKSPACEID)) { changeworkspace("[internal]" + std::to_string(OLDWORKSPACE->m_iID)); OLDWORKSPACE->startAnim(true, true, true); - toggleSpecialWorkspace(""); - g_pCompositor->getWorkspaceByID(SPECIAL_WORKSPACE_ID)->startAnim(false, false, true); + toggleSpecialWorkspace(workspaceName.length() > 7 ? workspaceName.substr(8) : workspaceName /* remove special: */); + g_pCompositor->getWorkspaceByID(WORKSPACEID)->startAnim(false, false, true); for (auto& m : g_pCompositor->m_vMonitors) - m->specialWorkspaceOpen = false; + m->specialWorkspaceID = 0; } else { g_pCompositor->focusWindow(PWINDOW); } @@ -1327,48 +1327,85 @@ void CKeybindManager::moveWorkspaceToMonitor(std::string args) { void CKeybindManager::toggleSpecialWorkspace(std::string args) { - if (g_pCompositor->getWindowsOnWorkspace(SPECIAL_WORKSPACE_ID) == 0) { + std::string workspaceName = ""; + int workspaceID = getWorkspaceIDFromString("special:" + args, workspaceName); + + if (workspaceID == INT_MAX || !g_pCompositor->isWorkspaceSpecial(workspaceID)) { + Debug::log(ERR, "Invalid workspace passed to special"); + return; + } + + if (g_pCompositor->getWindowsOnWorkspace(workspaceID) == 0) { Debug::log(LOG, "Can't open empty special workspace!"); return; } - bool open = false; + bool requestedWorkspaceIsAlreadyOpen = false; + int specialOpenOnMonitor = g_pCompositor->m_pLastMonitor->specialWorkspaceID; for (auto& m : g_pCompositor->m_vMonitors) { - if (m->specialWorkspaceOpen) { - open = true; + if (m->specialWorkspaceID == workspaceID) { + requestedWorkspaceIsAlreadyOpen = true; break; } } - if (open) - Debug::log(LOG, "Toggling special workspace to closed"); + if (requestedWorkspaceIsAlreadyOpen && specialOpenOnMonitor == workspaceID) + Debug::log(LOG, "Toggling special workspace %d to closed"); else - Debug::log(LOG, "Toggling special workspace to open"); + Debug::log(LOG, "Toggling special workspace %d to open"); - if (open) { - for (auto& m : g_pCompositor->m_vMonitors) { - if (m->specialWorkspaceOpen != !open) { - m->specialWorkspaceOpen = !open; - g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m->ID); + if (requestedWorkspaceIsAlreadyOpen && specialOpenOnMonitor == workspaceID) { + // already open on this monitor - g_pCompositor->getWorkspaceByID(SPECIAL_WORKSPACE_ID)->startAnim(false, false); - } - } + g_pCompositor->m_pLastMonitor->specialWorkspaceID = 0; + g_pLayoutManager->getCurrentLayout()->recalculateMonitor(g_pCompositor->m_pLastMonitor->ID); + + g_pCompositor->getWorkspaceByID(workspaceID)->startAnim(false, false); if (const auto PWINDOW = g_pCompositor->getWorkspaceByID(g_pCompositor->m_pLastMonitor->activeWorkspace)->getLastFocusedWindow(); PWINDOW) g_pCompositor->focusWindow(PWINDOW); else g_pInputManager->refocus(); + } else if (requestedWorkspaceIsAlreadyOpen) { + // already open on another monitor + + if (specialOpenOnMonitor) { + g_pCompositor->getWorkspaceByID(g_pCompositor->m_pLastMonitor->specialWorkspaceID)->startAnim(false, false); + g_pCompositor->m_pLastMonitor->specialWorkspaceID = 0; + g_pLayoutManager->getCurrentLayout()->recalculateMonitor(g_pCompositor->m_pLastMonitor->ID); + } + + // move to current + const auto PSPECIALWORKSPACE = g_pCompositor->getWorkspaceByID(workspaceID); + const auto POLDMON = g_pCompositor->getMonitorFromID(PSPECIALWORKSPACE->m_iMonitorID); + + POLDMON->specialWorkspaceID = 0; + g_pLayoutManager->getCurrentLayout()->recalculateMonitor(POLDMON->ID); + g_pCompositor->m_pLastMonitor->specialWorkspaceID = workspaceID; + g_pLayoutManager->getCurrentLayout()->recalculateMonitor(g_pCompositor->m_pLastMonitor->ID); + + if (const auto PWINDOW = PSPECIALWORKSPACE->getLastFocusedWindow(); PWINDOW) + g_pCompositor->focusWindow(PWINDOW); + else + g_pInputManager->refocus(); } else { - auto PSPECIALWORKSPACE = g_pCompositor->getWorkspaceByID(SPECIAL_WORKSPACE_ID); + // not open anywhere + + if (specialOpenOnMonitor) { + g_pCompositor->getWorkspaceByID(g_pCompositor->m_pLastMonitor->specialWorkspaceID)->startAnim(false, false); + g_pCompositor->m_pLastMonitor->specialWorkspaceID = 0; + g_pLayoutManager->getCurrentLayout()->recalculateMonitor(g_pCompositor->m_pLastMonitor->ID); + } + + auto PSPECIALWORKSPACE = g_pCompositor->getWorkspaceByID(workspaceID); if (!PSPECIALWORKSPACE) { // ??? happens sometimes...? - PSPECIALWORKSPACE = g_pCompositor->m_vWorkspaces.emplace_back(std::make_unique(g_pCompositor->m_pLastMonitor->ID, "special", true)).get(); + PSPECIALWORKSPACE = g_pCompositor->createNewWorkspace(workspaceID, g_pCompositor->m_pLastMonitor->ID, workspaceName); } - g_pCompositor->m_pLastMonitor->specialWorkspaceOpen = true; + g_pCompositor->m_pLastMonitor->specialWorkspaceID = workspaceID; g_pLayoutManager->getCurrentLayout()->recalculateMonitor(g_pCompositor->m_pLastMonitor->ID); PSPECIALWORKSPACE->startAnim(true, true); diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp index eade4bda..bd983c30 100644 --- a/src/managers/input/InputManager.cpp +++ b/src/managers/input/InputManager.cpp @@ -152,7 +152,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) { // only check floating because tiled cant be over fullscreen for (auto w = g_pCompositor->m_vWindows.rbegin(); w != g_pCompositor->m_vWindows.rend(); w++) { wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y}; - if ((((*w)->m_bIsFloating && (*w)->m_bIsMapped && ((*w)->m_bCreatedOverFullscreen || (*w)->m_bPinned)) || ((*w)->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && PMONITOR->specialWorkspaceOpen)) && wlr_box_contains_point(&box, mouseCoords.x, mouseCoords.y) && g_pCompositor->isWorkspaceVisible((*w)->m_iWorkspaceID) && !(*w)->isHidden()) { + if ((((*w)->m_bIsFloating && (*w)->m_bIsMapped && ((*w)->m_bCreatedOverFullscreen || (*w)->m_bPinned)) || (g_pCompositor->isWorkspaceSpecial((*w)->m_iWorkspaceID) && PMONITOR->specialWorkspaceID)) && wlr_box_contains_point(&box, mouseCoords.x, mouseCoords.y) && g_pCompositor->isWorkspaceVisible((*w)->m_iWorkspaceID) && !(*w)->isHidden()) { pFoundWindow = (*w).get(); break; } @@ -171,10 +171,10 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) { if (!foundSurface) { if (PWORKSPACE->m_bHasFullscreenWindow && PWORKSPACE->m_efFullscreenMode == FULLSCREEN_MAXIMIZED) { - if (PMONITOR->specialWorkspaceOpen) { + if (PMONITOR->specialWorkspaceID) { pFoundWindow = g_pCompositor->vectorToWindowIdeal(mouseCoords); - if (pFoundWindow && pFoundWindow->m_iWorkspaceID != SPECIAL_WORKSPACE_ID) { + if (pFoundWindow && !g_pCompositor->isWorkspaceSpecial(pFoundWindow->m_iWorkspaceID)) { pFoundWindow = g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID); } } else { diff --git a/src/managers/input/Swipe.cpp b/src/managers/input/Swipe.cpp index ab3a0418..ab85a988 100644 --- a/src/managers/input/Swipe.cpp +++ b/src/managers/input/Swipe.cpp @@ -11,7 +11,7 @@ void CInputManager::onSwipeBegin(wlr_pointer_swipe_begin_event* e) { int onMonitor = 0; for (auto& w : g_pCompositor->m_vWorkspaces) { - if (w->m_iMonitorID == g_pCompositor->m_pLastMonitor->ID && w->m_iID != SPECIAL_WORKSPACE_ID) { + if (w->m_iMonitorID == g_pCompositor->m_pLastMonitor->ID && !g_pCompositor->isWorkspaceSpecial(w->m_iID)) { onMonitor++; } } diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index c441bd1e..8b73f0aa 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -750,7 +750,7 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, wlr_box* pBox, } // vvv TODO: layered blur fbs? - const bool USENEWOPTIMIZE = (*PBLURNEWOPTIMIZE && m_pCurrentWindow && !m_pCurrentWindow->m_bIsFloating && m_RenderData.pCurrentMonData->blurFB.m_cTex.m_iTexID && m_pCurrentWindow->m_iWorkspaceID != SPECIAL_WORKSPACE_ID); + const bool USENEWOPTIMIZE = (*PBLURNEWOPTIMIZE && m_pCurrentWindow && !m_pCurrentWindow->m_bIsFloating && m_RenderData.pCurrentMonData->blurFB.m_cTex.m_iTexID && !g_pCompositor->isWorkspaceSpecial(m_pCurrentWindow->m_iWorkspaceID)); const auto POUTFB = USENEWOPTIMIZE ? &m_RenderData.pCurrentMonData->blurFB : blurMainFramebufferWithDamage(a, pBox, &inverseOpaque); diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index d1e60367..3fd33876 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -88,7 +88,7 @@ bool CHyprRenderer::shouldRenderWindow(CWindow* pWindow, CMonitor* pMonitor) { if (g_pCompositor->isWorkspaceVisible(pWindow->m_iWorkspaceID) && pWindow->m_bIsFloating /* tiled windows can't be multi-ws */) return !pWindow->m_bIsFullscreen; // Do not draw fullscreen windows on other monitors - if (pMonitor->specialWorkspaceOpen && pWindow->m_iWorkspaceID == SPECIAL_WORKSPACE_ID) + if (pMonitor->specialWorkspaceID && g_pCompositor->isWorkspaceSpecial(pWindow->m_iWorkspaceID)) return true; return false; @@ -111,7 +111,7 @@ bool CHyprRenderer::shouldRenderWindow(CWindow* pWindow) { if (PWORKSPACE && PWORKSPACE->m_iMonitorID == m->ID && (PWORKSPACE->m_vRenderOffset.isBeingAnimated() || PWORKSPACE->m_fAlpha.isBeingAnimated())) return true; - if (m->specialWorkspaceOpen && pWindow->m_iWorkspaceID == SPECIAL_WORKSPACE_ID) + if (m->specialWorkspaceID && g_pCompositor->isWorkspaceSpecial(pWindow->m_iWorkspaceID)) return true; } @@ -183,11 +183,11 @@ void CHyprRenderer::renderWorkspaceWithFullscreenWindow(CMonitor* pMonitor, CWor } // and then special windows - for (auto& w : g_pCompositor->m_vWindows) { + if (pMonitor->specialWorkspaceID) for (auto& w : g_pCompositor->m_vWindows) { if (!g_pCompositor->windowValidMapped(w.get()) && !w->m_bFadingOut) continue; - if (w->m_iWorkspaceID != SPECIAL_WORKSPACE_ID) + if (w->m_iWorkspaceID != pMonitor->specialWorkspaceID) continue; if (!shouldRenderWindow(w.get(), pMonitor)) @@ -404,7 +404,7 @@ void CHyprRenderer::renderAllClientsForMonitor(const int& ID, timespec* time) { if (w->m_bIsFloating) continue; // floating are in the second pass - if (w->m_iWorkspaceID == SPECIAL_WORKSPACE_ID) + if (g_pCompositor->isWorkspaceSpecial(w->m_iWorkspaceID)) continue; // special are in the third pass if (!shouldRenderWindow(w.get(), PMONITOR)) @@ -431,7 +431,7 @@ void CHyprRenderer::renderAllClientsForMonitor(const int& ID, timespec* time) { if (w->m_bIsFloating) continue; // floating are in the second pass - if (w->m_iWorkspaceID == SPECIAL_WORKSPACE_ID) + if (g_pCompositor->isWorkspaceSpecial(w->m_iWorkspaceID)) continue; // special are in the third pass if (!shouldRenderWindow(w.get(), PMONITOR)) @@ -449,7 +449,7 @@ void CHyprRenderer::renderAllClientsForMonitor(const int& ID, timespec* time) { if (!w->m_bIsFloating) continue; - if (w->m_iWorkspaceID == SPECIAL_WORKSPACE_ID) + if (g_pCompositor->isWorkspaceSpecial(w->m_iWorkspaceID)) continue; if (!shouldRenderWindow(w.get(), PMONITOR)) @@ -464,7 +464,7 @@ void CHyprRenderer::renderAllClientsForMonitor(const int& ID, timespec* time) { if (w->isHidden() && !w->m_bIsMapped && !w->m_bFadingOut) continue; - if (w->m_iWorkspaceID != SPECIAL_WORKSPACE_ID) + if (!g_pCompositor->isWorkspaceSpecial(w->m_iWorkspaceID)) continue; if (!shouldRenderWindow(w.get(), PMONITOR)) @@ -567,7 +567,7 @@ bool CHyprRenderer::attemptDirectScanout(CMonitor* pMonitor) { const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pMonitor->activeWorkspace); - if (!PWORKSPACE || !PWORKSPACE->m_bHasFullscreenWindow || g_pInputManager->m_sDrag.drag || g_pCompositor->m_sSeat.exclusiveClient || pMonitor->specialWorkspaceOpen) + if (!PWORKSPACE || !PWORKSPACE->m_bHasFullscreenWindow || g_pInputManager->m_sDrag.drag || g_pCompositor->m_sSeat.exclusiveClient || pMonitor->specialWorkspaceID) return false; const auto PCANDIDATE = g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID);