diff options
| author | Zynix <89567766+alper-han@users.noreply.github.com> | 2026-03-01 00:49:47 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-02-28 21:49:47 +0000 |
| commit | c2bed4103c0382de83f5277c5583bb15ae702c2a (patch) | |
| tree | cc045b65eb9f5ff93ee1e4dbdbbaafbef1fc19d7 /src/helpers/Monitor.cpp | |
| parent | 82729db330d11d8b39625f04b88bea093f99b33e (diff) | |
monitor: keep workspace monitor bindings on full reconnect (#13384)
When all monitors disconnect, non-active workspaces could migrate to the wrong output after reconnect. Preserve workspace ownership and re-apply assigned monitor bindings on connect.
Diffstat (limited to 'src/helpers/Monitor.cpp')
| -rw-r--r-- | src/helpers/Monitor.cpp | 36 |
1 files changed, 25 insertions, 11 deletions
diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp index f287bff3..d77a7e76 100644 --- a/src/helpers/Monitor.cpp +++ b/src/helpers/Monitor.cpp @@ -82,7 +82,10 @@ void CMonitor::onConnect(bool noRule) { m_zoomAnimProgress->setValueAndWarp(0.F); m_zoomAnimFrameCounter = 0; - g_pEventLoopManager->doLater([] { g_pConfigManager->ensurePersistentWorkspacesPresent(); }); + g_pEventLoopManager->doLater([] { + g_pConfigManager->ensurePersistentWorkspacesPresent(); + g_pCompositor->ensureWorkspacesOnAssignedMonitors(); + }); m_listeners.frame = m_output->events.frame.listen([this] { if (m_frameScheduler) @@ -290,10 +293,16 @@ void CMonitor::onConnect(bool noRule) { if (!valid(ws)) continue; - if (ws->m_lastMonitor == m_name || g_pCompositor->m_monitors.size() == 1 /* avoid lost workspaces on recover */) { + const auto CURRENTMON = ws->m_monitor.lock(); + const bool ORPHANED = !CURRENTMON || std::ranges::none_of(g_pCompositor->m_monitors, [&](const auto& mon) { return mon == CURRENTMON; }); + const bool RETURNING = ws->m_lastMonitor == m_name; + const bool RECOVERY = g_pCompositor->m_monitors.size() == 1 && ORPHANED; // temporarily recover orphaned workspaces + + if (RETURNING || RECOVERY) { g_pCompositor->moveWorkspaceToMonitor(ws, m_self.lock()); g_pDesktopAnimationManager->startAnimation(ws, CDesktopAnimationManager::ANIMATION_TYPE_IN, true, true); - ws->m_lastMonitor = ""; + if (RETURNING) + ws->m_lastMonitor = ""; } } @@ -429,19 +438,24 @@ void CMonitor::onDisconnect(bool destroy) { m_enabled = false; m_renderingInitPassed = false; + std::vector<PHLWORKSPACE> wspToMove; + for (auto const& w : g_pCompositor->getWorkspaces()) { + if (w->m_monitor == m_self || !w->m_monitor) + wspToMove.emplace_back(w.lock()); + } + + // Preserve ownership across cascaded monitor disconnects. + // The first disconnected monitor "owns" where a workspace should return. + for (auto const& w : wspToMove) { + if (w && w->m_lastMonitor.empty()) + w->m_lastMonitor = m_name; + } + if (BACKUPMON) { // snap cursor g_pCompositor->warpCursorTo(BACKUPMON->m_position + BACKUPMON->m_transformedSize / 2.F, true); - // move workspaces - std::vector<PHLWORKSPACE> wspToMove; - for (auto const& w : g_pCompositor->getWorkspaces()) { - if (w->m_monitor == m_self || !w->m_monitor) - wspToMove.emplace_back(w.lock()); - } - for (auto const& w : wspToMove) { - w->m_lastMonitor = m_name; g_pCompositor->moveWorkspaceToMonitor(w, BACKUPMON); g_pDesktopAnimationManager->startAnimation(w, CDesktopAnimationManager::ANIMATION_TYPE_IN, true, true); } |
