Skip to content
Dotfiles
Esc
navigateopen⌘Jpreview
On this page

Workspace Session Recovery

Capture and restore Hyprland window sessions after restarts, crashes, or layout experiments.

The workspace session scripts save the current Hyprland clients to JSON, then restore the latest capture by moving existing windows back to their saved workspaces and relaunching the supported missing apps.

Use this before risky layout work, before restarting Hyprland, or when you want a quick recovery point for open workspaces.

Capture a session

Capture every visible workspace:

workspace-capture

Capture only the active workspace:

workspace-capture --current-workspace

By default captures are written to:

~/.local/state/workspace-sessions/workspace-<timestamp>.json

The script also writes a capture log to:

~/.local/state/workspace-sessions/capture.log

To write a named capture:

workspace-capture --output=~/workspace-before-restart.json

Restore safely

Start with a dry run. It prints the restore plan without launching or moving windows:

workspace-restore --dry-run

Restore the newest capture from the state directory:

workspace-restore

Restore a specific file:

workspace-restore --file=~/workspace-before-restart.json

Search a different state directory for the newest capture and write restore.log there:

workspace-restore --state-dir=~/somewhere

The restore log is written to:

~/.local/state/workspace-sessions/restore.log

What gets restored

The restore script reads hyprctl -j clients and tries these paths in order:

  • Reuse a still-running window by saved address.
  • Match an existing window by class and workspace.
  • Launch a supported missing app, then move it to the saved workspace.
  • Restore floating geometry or tiled size when the saved client has enough geometry data.
  • Switch back to the saved active workspace at the end.

Supported relaunch paths are encoded in workspace-restore and cover Chromium, work Chrome app windows, Slack, Discord, Twitch webapps, generic Chrome webapps with captured URLs, and Ghostty terminals. Ghostty launches through ghostty-host-config to keep the active config.$OMARCHY_HOST override, and passes --working-directory when the saved directory still exists.

Captured browser URLs are passed to the Hyprland launcher as one shell-quoted argument, so query strings and shell metacharacters are preserved as URL data rather than interpreted as commands.

Unsupported classes are skipped with a reason in the restore output.

Browser URLs

workspace-capture can attach a real browser URL when the browser URL state file exists:

${XDG_STATE_HOME:-~/.local/state}/browser-urls.json

When that file is missing, Chromium windows can still be matched or relaunched by class, but generic webapp URL recovery is limited.

Workspace menu

The Omarchy menu wraps the common actions:

workspace-menu

The shared Hypr binding is:

SUPER+ALT+W

It offers capture, dry-run restore, restore, and relayout actions. On the desktop host it also exposes the host-specific workspace setup action.

Recovery flow

  1. Run workspace-capture before the risky change.
  2. Make the change, restart Hyprland, or recover from the crash.
  3. Run workspace-restore --dry-run and read the plan.
  4. Run workspace-restore when the plan looks safe.
  5. Check restore.log for skipped windows.

Troubleshooting

If nothing restores, check that a capture exists:

ls ~/.local/state/workspace-sessions

If restore launches too much, try moving only existing windows:

workspace-restore --no-launch

If restore launches apps but leaves current placement alone:

workspace-restore --no-move

If you want to inspect one capture directly:

jq '.clients[] | {workspace: .workspace.id, class, title, browser_url}' ~/.local/state/workspace-sessions/workspace-*.json

Rollback

The restore script only moves, resizes, and launches windows. There is no persistent layout state to undo. Move windows manually or rerun a better capture file with --file=....

Last updated on August 22, 2026