core: fix workspace persistence tracking (#11239)

This commit is contained in:
Vaxry 2025-07-27 18:46:23 +02:00 committed by GitHub
parent 5d4b4ecbfb
commit c63d0003a1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 140 additions and 10 deletions

View file

@ -3109,6 +3109,8 @@ void CCompositor::ensurePersistentWorkspacesPresent(const std::vector<SWorkspace
if (!m_lastMonitor)
return;
std::vector<PHLWORKSPACE> persistentFound;
for (const auto& rule : rules) {
if (!rule.isPersistent)
continue;
@ -3142,17 +3144,20 @@ void CCompositor::ensurePersistentWorkspacesPresent(const std::vector<SWorkspace
}
PWORKSPACE = getWorkspaceByID(id);
if (!PWORKSPACE)
createNewWorkspace(id, PMONITOR ? PMONITOR->m_id : m_lastMonitor->m_id, wsname, false);
PWORKSPACE = createNewWorkspace(id, PMONITOR ? PMONITOR->m_id : m_lastMonitor->m_id, wsname, false);
}
if (PWORKSPACE)
PWORKSPACE->m_persistent = true;
if (!PMONITOR) {
Debug::log(ERR, "ensurePersistentWorkspacesPresent: couldn't resolve monitor for {}, skipping", rule.monitor);
continue;
}
if (PWORKSPACE)
PWORKSPACE->setPersistent(true);
if (!pWorkspace)
persistentFound.emplace_back(PWORKSPACE);
if (PWORKSPACE) {
if (PWORKSPACE->m_monitor == PMONITOR) {
Debug::log(LOG, "ensurePersistentWorkspacesPresent: workspace persistent {} already on {}", rule.workspaceString, PMONITOR->m_name);
@ -3165,4 +3170,22 @@ void CCompositor::ensurePersistentWorkspacesPresent(const std::vector<SWorkspace
continue;
}
}
if (!pWorkspace) {
// check non-persistent and downgrade if workspace is no longer persistent
std::vector<PHLWORKSPACEREF> toDowngrade;
for (auto& w : getWorkspaces()) {
if (!w->isPersistent())
continue;
if (std::ranges::contains(persistentFound, w.lock()))
continue;
toDowngrade.emplace_back(w);
}
for (auto& ws : toDowngrade) {
ws->setPersistent(false);
}
}
}

View file

@ -355,12 +355,12 @@ std::string CHyprCtl::getWorkspaceData(PHLWORKSPACE w, eHyprCtlOutputFormat form
}})#",
w->m_id, escapeJSONStrings(w->m_name), escapeJSONStrings(PMONITOR ? PMONITOR->m_name : "?"),
escapeJSONStrings(PMONITOR ? std::to_string(PMONITOR->m_id) : "null"), w->getWindows(), w->m_hasFullscreenWindow ? "true" : "false",
(uintptr_t)PLASTW.get(), PLASTW ? escapeJSONStrings(PLASTW->m_title) : "", w->m_persistent ? "true" : "false");
(uintptr_t)PLASTW.get(), PLASTW ? escapeJSONStrings(PLASTW->m_title) : "", w->isPersistent() ? "true" : "false");
} else {
return std::format(
"workspace ID {} ({}) on monitor {}:\n\tmonitorID: {}\n\twindows: {}\n\thasfullscreen: {}\n\tlastwindow: 0x{:x}\n\tlastwindowtitle: {}\n\tispersistent: {}\n\n",
w->m_id, w->m_name, PMONITOR ? PMONITOR->m_name : "?", PMONITOR ? std::to_string(PMONITOR->m_id) : "null", w->getWindows(), (int)w->m_hasFullscreenWindow,
(uintptr_t)PLASTW.get(), PLASTW ? PLASTW->m_title : "", (int)w->m_persistent);
(uintptr_t)PLASTW.get(), PLASTW ? PLASTW->m_title : "", (int)w->isPersistent());
}
}
@ -1183,6 +1183,9 @@ static std::string dispatchKeyword(eHyprCtlOutputFormat format, std::string in)
}
}
if (COMMAND.contains("workspace"))
g_pConfigManager->ensurePersistentWorkspacesPresent();
Debug::log(LOG, "Hyprctl: keyword {} : {}", COMMAND, VALUE);
if (retval.empty())

View file

@ -44,7 +44,7 @@ void CWorkspace::init(PHLWORKSPACE self) {
m_inert = false;
const auto WORKSPACERULE = g_pConfigManager->getWorkspaceRuleFor(self);
m_persistent = WORKSPACERULE.isPersistent;
setPersistent(WORKSPACERULE.isPersistent);
if (self->m_wasCreatedEmpty)
if (auto cmd = WORKSPACERULE.onCreatedEmptyRunCmd)
@ -639,7 +639,7 @@ void CWorkspace::rename(const std::string& name) {
m_name = name;
const auto WORKSPACERULE = g_pConfigManager->getWorkspaceRuleFor(m_self.lock());
m_persistent = WORKSPACERULE.isPersistent;
setPersistent(WORKSPACERULE.isPersistent);
if (WORKSPACERULE.isPersistent)
g_pCompositor->ensurePersistentWorkspacesPresent(std::vector<SWorkspaceRule>{WORKSPACERULE}, m_self.lock());
@ -658,3 +658,19 @@ void CWorkspace::updateWindows() {
w->updateDynamicRules();
}
}
void CWorkspace::setPersistent(bool persistent) {
if (m_persistent == persistent)
return;
m_persistent = persistent;
if (persistent)
m_selfPersistent = m_self.lock();
else
m_selfPersistent.reset();
}
bool CWorkspace::isPersistent() {
return m_persistent;
}

View file

@ -58,8 +58,6 @@ class CWorkspace {
bool m_wasCreatedEmpty = true;
bool m_persistent = false;
// Inert: destroyed and invalid. If this is true, release the ptr you have.
bool inert();
void startAnim(bool in, bool left, bool instant = false);
@ -83,6 +81,8 @@ class CWorkspace {
void rename(const std::string& name = "");
void forceReportSizesToWindows();
void updateWindows();
void setPersistent(bool persistent);
bool isPersistent();
struct {
CSignalT<> destroy;
@ -99,6 +99,9 @@ class CWorkspace {
SP<HOOK_CALLBACK_FN> m_focusedWindowHook;
bool m_inert = true;
SP<CWorkspace> m_selfPersistent; // for persistent workspaces.
bool m_persistent = false;
};
inline bool valid(const PHLWORKSPACE& ref) {