Skip to content

feat: persist workspace-to-monitor assignments across disconnections#1284

Open
durdn wants to merge 1 commit intoglzr-io:mainfrom
durdn:feat/monitor-workspace-persistence
Open

feat: persist workspace-to-monitor assignments across disconnections#1284
durdn wants to merge 1 commit intoglzr-io:mainfrom
durdn:feat/monitor-workspace-persistence

Conversation

@durdn
Copy link

@durdn durdn commented Feb 24, 2026

Summary

When monitors temporarily disconnect (PC sleep, monitor standby, dock/undock), GlazeWM loses track of which workspaces were on which monitors. The current code treats every disconnection as permanent — it removes the monitor from the container tree and scatters its workspaces to remaining monitors. On reconnection, the monitor is treated as brand new and gets whatever workspace the config dictates, not what was actually there. This causes disruptive workspace shuffling that forces users to manually rearrange their layout after every sleep/wake cycle.

This PR introduces a Disconnected Monitor Registry — a lightweight record kept alongside the container tree that remembers which workspaces belonged to which monitor. When a monitor disconnects, we capture its identity (device_path, hardware_id, device_name) and its workspace names ordered by focus. When the same physical monitor reconnects, we restore its workspaces automatically.

Key design decisions

  • No ghost monitors in the container tree. The registry is a simple Vec<DisconnectedMonitor> on WmState. This avoids breaking sort_monitors, monitor.index(), to_rect(), and all other code that assumes every monitor in the tree is live.
  • Config bindings take priority. bind_to_monitor workspace configs are processed first; ghost restoration fills in the remaining workspaces after. This means user config is always respected.
  • Matching is robust. We match reconnecting monitors by device_path first (most reliable), then fall back to hardware_id only when it's unique across all connected + disconnected monitors.
  • Self-cleaning. Ghost records are deduplicated by device_path on each disconnect and pruned after 1 hour to prevent unbounded growth.
  • remove_monitor is untouched. The new disconnect_monitor wraps it — captures the record, then delegates to the existing removal logic.

Edge cases handled

All monitors disconnect (sleep) — Last monitor preserved (existing logic). Others get ghost records. On wake, ghosts restore workspaces.

User moves windows while monitor is off — Ghost stores workspace names, not windows. Workspaces return with whatever windows they now contain.

Empty workspace was garbage-collected — Ghost has the name but workspace no longer exists — silently skipped.

Same monitor disconnects repeatedly — Ghost record is replaced (deduped by device_path).

Duplicate hardware IDs (e.g. identical monitors) — device_path match is preferred. hardware_id only used when unique.

Fixes #1130, #907, #318.

Test plan

  • Build: cargo build passes
  • Lint: cargo clippy passes with no new warnings
  • Multi-monitor: place windows on each monitor, disconnect one, verify workspaces move to remaining monitor, reconnect, verify workspaces return to the correct monitor
  • Sleep/wake: put PC to sleep with multi-monitor layout, wake up, verify full layout restoration
  • Single monitor: disconnect/reconnect the only monitor — no crash, layout preserved

When monitors temporarily disconnect (sleep, dock/undock), record their
identity and workspace names in a registry so workspaces are restored to
the correct monitor on reconnection instead of being scattered.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@github-project-automation github-project-automation bot moved this to 📬 Needs triage in glazewm Feb 24, 2026
@durdn
Copy link
Author

durdn commented Feb 25, 2026

I will add some corollary after using this patch myself for the whole of today. I am so happy finally my PC goes in hibernation or sleep, the monitors switch off (I have 4) and when the system reactivates all my windows and workspaces are in the exact same place. I really really really am so happy.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: 📬 Needs triage

Development

Successfully merging this pull request may close these issues.

[Bug] inconsistancy with connecting and disconnecting external monitors

1 participant