diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 8441e1bc..d811b8d5 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -1875,3 +1875,17 @@ bool CCompositor::cursorOnReservedArea() { return !VECINRECT(CURSORPOS, XY1.x, XY1.y, XY2.x, XY2.y); } + +CWorkspace* CCompositor::createNewWorkspace(const int& id, const int& monid, const std::string& name) { + const auto NAME = name == "" ? std::to_string(id) : name; + const auto PWORKSPACE = m_vWorkspaces.emplace_back(std::make_unique(monid, NAME, id == SPECIAL_WORKSPACE_ID)).get(); + + // We are required to set the name here immediately + if (id != SPECIAL_WORKSPACE_ID) + wlr_ext_workspace_handle_v1_set_name(PWORKSPACE->m_pWlrHandle, NAME.c_str()); + + PWORKSPACE->m_iID = id; + PWORKSPACE->m_iMonitorID = monid; + + return PWORKSPACE; +} diff --git a/src/Compositor.hpp b/src/Compositor.hpp index 68178246..c447425c 100644 --- a/src/Compositor.hpp +++ b/src/Compositor.hpp @@ -166,6 +166,7 @@ public: Vector2D parseWindowVectorArgsRelative(const std::string&, const Vector2D&); void forceReportSizesToWindowsOnWorkspace(const int&); bool cursorOnReservedArea(); + CWorkspace* createNewWorkspace(const int&, const int&, const std::string& name = ""); // will be deleted next frame if left empty and unfocused! std::string explicitConfigPath; diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp index 54000a6a..93dddc84 100644 --- a/src/events/Windows.cpp +++ b/src/events/Windows.cpp @@ -114,6 +114,7 @@ void Events::listener_mapWindow(void* owner, void* data) { bool workspaceSilent = false; bool requestsFullscreen = PWINDOW->m_bWantsInitialFullscreen || (!PWINDOW->m_bIsX11 && PWINDOW->m_uSurface.xdg->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL && PWINDOW->m_uSurface.xdg->toplevel->requested.fullscreen); bool shouldFocus = true; + bool workspaceSpecial = false; for (auto& r : WINDOWRULES) { if (r.szRule.find("monitor") == 0) { @@ -223,6 +224,7 @@ void Events::listener_mapWindow(void* owner, void* data) { } if (requestedWorkspace == "special") { + workspaceSpecial = true; workspaceSilent = true; } @@ -234,6 +236,44 @@ void Events::listener_mapWindow(void* owner, void* data) { } } + if (workspaceSilent) { + // get the workspace + + auto PWORKSPACE = g_pCompositor->getWorkspaceByString(requestedWorkspace); + + if (!PWORKSPACE) { + std::string workspaceName = ""; + int workspaceID = 0; + + if (requestedWorkspace.find("name:") == 0) { + workspaceName = requestedWorkspace.substr(5); + workspaceID = g_pCompositor->getNextAvailableNamedWorkspace(); + } else if (workspaceSpecial) { + workspaceName = ""; + workspaceID = SPECIAL_WORKSPACE_ID; + } else { + try { + workspaceID = std::stoi(requestedWorkspace); + } catch (...) { + workspaceID = -1; + Debug::log(ERR, "Invalid workspace requested in workspace silent rule!"); + } + + if (workspaceID < 1) { + workspaceID = -1; // means invalid + } + } + + if (workspaceID != -1) + PWORKSPACE = g_pCompositor->createNewWorkspace(workspaceID, PWINDOW->m_iMonitorID, workspaceName); + } + + if (PWORKSPACE) { + PWINDOW->m_iWorkspaceID = PWORKSPACE->m_iID; + PWINDOW->m_iMonitorID = PWORKSPACE->m_iMonitorID; + } + } + if (PWINDOW->m_bIsFloating) { g_pLayoutManager->getCurrentLayout()->onWindowCreatedFloating(PWINDOW); PWINDOW->m_bCreatedOverFullscreen = true; @@ -317,8 +357,7 @@ void Events::listener_mapWindow(void* owner, void* data) { PWINDOW->m_vPseudoSize = PWINDOW->m_vRealSize.goalv(); g_pCompositor->moveWindowToTop(PWINDOW); - } - else { + } else { g_pLayoutManager->getCurrentLayout()->onWindowCreated(PWINDOW); // Set the pseudo size here too so that it doesnt end up being 0x0 @@ -333,7 +372,7 @@ void Events::listener_mapWindow(void* owner, void* data) { PWINDOW->m_bX11ShouldntFocus = false; } - if (!PWINDOW->m_bNoFocus && !PWINDOW->m_bNoInitialFocus && PWINDOW->m_iX11Type != 2) { + if (!PWINDOW->m_bNoFocus && !PWINDOW->m_bNoInitialFocus && PWINDOW->m_iX11Type != 2 && !workspaceSilent) { g_pCompositor->focusWindow(PWINDOW); PWINDOW->m_fActiveInactiveAlpha.setValueAndWarp(*PACTIVEALPHA); PWINDOW->m_fDimPercent.setValueAndWarp(*PDIMSTRENGTH); @@ -371,32 +410,6 @@ void Events::listener_mapWindow(void* owner, void* data) { const auto TIMER = wl_event_loop_add_timer(g_pCompositor->m_sWLEventLoop, setAnimToMove, PWINDOW); wl_event_source_timer_update(TIMER, PWINDOW->m_vRealPosition.getDurationLeftMs() + 5); - if (workspaceSilent) { - // move the window - const auto OLDWORKSPACE = PWINDOW->m_iWorkspaceID; - - if (g_pCompositor->m_pLastWindow == PWINDOW) { - if (requestedWorkspace != "special") { - g_pKeybindManager->m_mDispatchers["movetoworkspacesilent"](requestedWorkspace); - } else { - g_pKeybindManager->m_mDispatchers["movetoworkspace"]("special"); - } - } else { - // yes this is fucking weird no clue why this won't work for everyone - std::stringstream stream; - stream << std::hex << (uintptr_t)PWINDOW; - std::string hexStr(stream.str()); - - if (requestedWorkspace != "special") { - g_pKeybindManager->m_mDispatchers["movetoworkspacesilent"](requestedWorkspace + ",address:0x" + hexStr); - } else { - g_pKeybindManager->m_mDispatchers["movetoworkspace"]("special,address:0x" + hexStr); - } - } - - g_pCompositor->forceReportSizesToWindowsOnWorkspace(OLDWORKSPACE); - } - if (requestsFullscreen) { // fix fullscreen on requested (basically do a switcheroo) if (PWORKSPACE->m_bHasFullscreenWindow) { diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index fde07236..0f5c4faa 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -769,7 +769,7 @@ void CKeybindManager::changeworkspace(std::string args) { if (const auto POLDWORKSPACE = g_pCompositor->getWorkspaceByID(OLDWORKSPACE); POLDWORKSPACE) POLDWORKSPACE->startAnim(false, ANIMTOLEFT); - const auto PWORKSPACE = g_pCompositor->m_vWorkspaces.emplace_back(std::make_unique(PMONITOR->ID, workspaceName, workspaceToChangeTo == SPECIAL_WORKSPACE_ID)).get(); + const auto PWORKSPACE = g_pCompositor->createNewWorkspace(workspaceToChangeTo, PMONITOR->ID, workspaceName); if (!isSwitchingToPrevious) // Remember previous workspace. @@ -778,13 +778,6 @@ void CKeybindManager::changeworkspace(std::string args) { // start anim on new workspace PWORKSPACE->startAnim(true, ANIMTOLEFT); - // We are required to set the name here immediately - if (workspaceToChangeTo != SPECIAL_WORKSPACE_ID) - wlr_ext_workspace_handle_v1_set_name(PWORKSPACE->m_pWlrHandle, workspaceName.c_str()); - - PWORKSPACE->m_iID = workspaceToChangeTo; - PWORKSPACE->m_iMonitorID = PMONITOR->ID; - PMONITOR->specialWorkspaceOpen = false; // fix pinned windows