diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 43efdac1..3421c314 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -3024,3 +3024,46 @@ bool CCompositor::shouldChangePreferredImageDescription() { Debug::log(WARN, "FIXME: color management protocol is enabled and outputs changed, check preferred image description changes"); return false; } + +void CCompositor::ensurePersistentWorkspacesPresent(const std::vector& rules) { + for (const auto& rule : rules) { + if (!rule.isPersistent) + continue; + + const auto PMONITOR = getMonitorFromString(rule.monitor); + + if (!PMONITOR) { + Debug::log(ERR, "ensurePersistentWorkspacesPresent: couldn't resolve monitor for {}, skipping", rule.monitor); + continue; + } + + WORKSPACEID id = rule.workspaceId; + std::string wsname = rule.workspaceName; + if (id == WORKSPACE_INVALID) { + const auto R = getWorkspaceIDNameFromString(rule.workspaceString); + id = R.id; + wsname = R.name; + } + + if (id == WORKSPACE_INVALID) { + Debug::log(ERR, "ensurePersistentWorkspacesPresent: couldn't resolve id for workspace {}", rule.workspaceString); + continue; + } + + if (const auto PWORKSPACE = getWorkspaceByID(id); PWORKSPACE) { + if (PWORKSPACE->m_pMonitor == PMONITOR) { + Debug::log(LOG, "ensurePersistentWorkspacesPresent: workspace persistent {} already on {}", rule.workspaceString, PMONITOR->szName); + continue; + } + + Debug::log(LOG, "ensurePersistentWorkspacesPresent: workspace persistent {} not on {}, moving", rule.workspaceString, PMONITOR->szName); + moveWorkspaceToMonitor(PWORKSPACE, PMONITOR); + continue; + } + + createNewWorkspace(id, PMONITOR ? PMONITOR : m_pLastMonitor.lock(), wsname, false); + } + + // cleanup old + sanityCheckWorkspaces(); +} diff --git a/src/Compositor.hpp b/src/Compositor.hpp index 295878df..e55d7e1e 100644 --- a/src/Compositor.hpp +++ b/src/Compositor.hpp @@ -15,6 +15,7 @@ #include class CWLSurfaceResource; +struct SWorkspaceRule; enum eManagersInitStage : uint8_t { STAGE_PRIORITY = 0, @@ -151,6 +152,7 @@ class CCompositor { void setPreferredTransformForSurface(SP pSurface, wl_output_transform transform); void updateSuspendedStates(); void onNewMonitor(SP output); + void ensurePersistentWorkspacesPresent(const std::vector& rules); SImageDescription getPreferredImageDescription(); bool shouldChangePreferredImageDescription(); diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index fd4783da..93289bf7 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -1034,6 +1034,10 @@ void CConfigManager::postConfigReload(const Hyprlang::CParseResult& result) { // update plugins handlePluginLoads(); + // update persistent workspaces + if (!isFirstLaunch) + ensurePersistentWorkspacesPresent(); + EMIT_HOOK_EVENT("configReloaded", nullptr); if (g_pEventManager) g_pEventManager->postEvent(SHyprIPCEvent{"configreloaded", ""}); @@ -2830,3 +2834,7 @@ std::string SConfigOptionDescription::jsonify() const { return json; } + +void CConfigManager::ensurePersistentWorkspacesPresent() { + g_pCompositor->ensurePersistentWorkspacesPresent(m_vWorkspaceRules); +} diff --git a/src/config/ConfigManager.hpp b/src/config/ConfigManager.hpp index 564c1ebf..ae0ba759 100644 --- a/src/config/ConfigManager.hpp +++ b/src/config/ConfigManager.hpp @@ -169,6 +169,7 @@ class CConfigManager { std::vector> getMatchingRules(PHLWINDOW, bool dynamic = true, bool shadowExec = false); std::vector> getMatchingRules(PHLLS); + void ensurePersistentWorkspacesPresent(); const std::vector& getAllDescriptions(); diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp index 1f00e4ad..6fcaeeee 100644 --- a/src/helpers/Monitor.cpp +++ b/src/helpers/Monitor.cpp @@ -51,6 +51,8 @@ void CMonitor::onConnect(bool noRule) { EMIT_HOOK_EVENT("preMonitorAdded", self.lock()); CScopeGuard x = {[]() { g_pCompositor->arrangeMonitors(); }}; + g_pEventLoopManager->doLater([] { g_pConfigManager->ensurePersistentWorkspacesPresent(); }); + if (output->supportsExplicit) { inTimeline = CSyncTimeline::create(output->getBackend()->drmFD()); outTimeline = CSyncTimeline::create(output->getBackend()->drmFD());