core: move workspace ptrs to weak (#11194)

Fixes some race conditions that come up in tests. We only clean up workspaces when we render a frame. With this, they are always cleared instantly.
This commit is contained in:
Vaxry
2025-07-24 00:36:29 +02:00
committed by GitHub
parent ecc04e8ba7
commit 31cc7f3b87
11 changed files with 67 additions and 73 deletions

View File

@@ -1338,29 +1338,14 @@ PHLWINDOW CCompositor::getWindowFromHandle(uint32_t handle) {
}
PHLWORKSPACE CCompositor::getWorkspaceByID(const WORKSPACEID& id) {
for (auto const& w : m_workspaces) {
for (auto const& w : getWorkspaces()) {
if (w->m_id == id && !w->inert())
return w;
return w.lock();
}
return nullptr;
}
void CCompositor::sanityCheckWorkspaces() {
auto it = m_workspaces.begin();
while (it != m_workspaces.end()) {
const auto& WORKSPACE = *it;
// If ref == 1, only the compositor holds a ref, which means it's inactive and has no mapped windows.
if (!WORKSPACE->m_persistent && WORKSPACE.strongRef() == 1) {
it = m_workspaces.erase(it);
continue;
}
++it;
}
}
PHLWINDOW CCompositor::getUrgentWindow() {
for (auto const& w : m_windows) {
if (w->m_isMapped && w->m_isUrgent)
@@ -1732,7 +1717,7 @@ PHLWINDOW CCompositor::getWindowCycle(PHLWINDOW cur, bool focusableOnly, std::op
WORKSPACEID CCompositor::getNextAvailableNamedWorkspace() {
WORKSPACEID lowest = -1337 + 1;
for (auto const& w : m_workspaces) {
for (auto const& w : getWorkspaces()) {
if (w->m_id < -1 && w->m_id < lowest)
lowest = w->m_id;
}
@@ -1741,9 +1726,9 @@ WORKSPACEID CCompositor::getNextAvailableNamedWorkspace() {
}
PHLWORKSPACE CCompositor::getWorkspaceByName(const std::string& name) {
for (auto const& w : m_workspaces) {
for (auto const& w : getWorkspaces()) {
if (w->m_name == name && !w->inert())
return w;
return w.lock();
}
return nullptr;
@@ -2144,7 +2129,7 @@ void CCompositor::moveWorkspaceToMonitor(PHLWORKSPACE pWorkspace, PHLMONITOR pMo
if (!SWITCHINGISACTIVE)
nextWorkspaceOnMonitorID = pWorkspace->m_id;
else {
for (auto const& w : m_workspaces) {
for (auto const& w : getWorkspaces()) {
if (w->m_monitor == POLDMON && w->m_id != pWorkspace->m_id && !w->m_isSpecialWorkspace) {
nextWorkspaceOnMonitorID = w->m_id;
break;
@@ -2258,7 +2243,7 @@ bool CCompositor::workspaceIDOutOfBounds(const WORKSPACEID& id) {
WORKSPACEID lowestID = INT64_MAX;
WORKSPACEID highestID = INT64_MIN;
for (auto const& w : m_workspaces) {
for (auto const& w : getWorkspaces()) {
if (w->m_isSpecialWorkspace)
continue;
lowestID = std::min(w->m_id, lowestID);
@@ -2660,7 +2645,7 @@ PHLWORKSPACE CCompositor::createNewWorkspace(const WORKSPACEID& id, const MONITO
return nullptr;
}
const auto PWORKSPACE = m_workspaces.emplace_back(CWorkspace::create(id, PMONITOR, NAME, SPECIAL, isEmpty));
const auto PWORKSPACE = CWorkspace::create(id, PMONITOR, NAME, SPECIAL, isEmpty);
PWORKSPACE->m_alpha->setValueAndWarp(0);
@@ -2694,15 +2679,19 @@ bool CCompositor::isWorkspaceSpecial(const WORKSPACEID& id) {
WORKSPACEID CCompositor::getNewSpecialID() {
WORKSPACEID highest = SPECIAL_WORKSPACE_START;
for (auto const& ws : m_workspaces) {
if (ws->m_isSpecialWorkspace && ws->m_id > highest) {
for (auto const& ws : getWorkspaces()) {
if (ws->m_isSpecialWorkspace && ws->m_id > highest)
highest = ws->m_id;
}
}
return highest + 1;
}
void CCompositor::registerWorkspace(PHLWORKSPACE w) {
m_workspaces.emplace_back(w);
w->m_events.destroy.listenStatic([this, weak = PHLWORKSPACEREF{w}] { std::erase(m_workspaces, weak); });
}
void CCompositor::performUserChecks() {
static auto PNOCHECKXDG = CConfigValue<Hyprlang::INT>("misc:disable_xdg_env_checks");
static auto PNOCHECKQTUTILS = CConfigValue<Hyprlang::INT>("misc:disable_hyprland_qtutils_check");
@@ -3176,7 +3165,4 @@ void CCompositor::ensurePersistentWorkspacesPresent(const std::vector<SWorkspace
continue;
}
}
// cleanup old
sanityCheckWorkspaces();
}