{"id":50561902,"url":"https://github.com/clustmart/winlayout","last_synced_at":"2026-06-04T12:01:25.100Z","repository":{"id":355890673,"uuid":"1229446763","full_name":"Clustmart/winlayout","owner":"Clustmart","description":"Save and restore macOS window layouts from the command line — no background service, no subscription. ","archived":false,"fork":false,"pushed_at":"2026-05-05T17:18:03.000Z","size":2042,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-05T19:24:55.248Z","etag":null,"topics":["applescript","bash","cli","macos","productivity","shell","window-manager"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"unlicense","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Clustmart.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-05T03:49:42.000Z","updated_at":"2026-05-05T17:18:07.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/Clustmart/winlayout","commit_stats":null,"previous_names":["clustmart/winlayout"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/Clustmart/winlayout","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Clustmart%2Fwinlayout","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Clustmart%2Fwinlayout/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Clustmart%2Fwinlayout/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Clustmart%2Fwinlayout/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Clustmart","download_url":"https://codeload.github.com/Clustmart/winlayout/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Clustmart%2Fwinlayout/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33903134,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-04T02:00:06.755Z","response_time":64,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["applescript","bash","cli","macos","productivity","shell","window-manager"],"created_at":"2026-06-04T12:01:24.282Z","updated_at":"2026-06-04T12:01:25.088Z","avatar_url":"https://github.com/Clustmart.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# winlayout — Save and Restore macOS Window Layouts\n\nSave and restore your macOS window layout with a single shell script.\n\n![winlayout demo](winlayout-demo.gif)\n\n`winlayout.sh` records the position and size of every open application window and puts them back on demand. Run it before unplugging a monitor, then `--restore` after reconnecting to put every window back where it was. Also useful after rebooting, waking from sleep, or the classic \"all my windows collapsed to one screen\" macOS moment.\n\nA free, open-source alternative to tools like Moom, Stay, Display Maid, and BetterSnapTool. No background service, no menu bar icon, no subscription.\n\n## Requirements\n\n- macOS — tested on Tahoe 26.3.1; likely works on earlier recent versions\n- Xcode Command Line Tools for the fast save path — install with `xcode-select --install`; without it the script falls back to AppleScript automatically (save takes ~10 s instead of ~1 s)\n\n## Quick Start\n\n```bash\ngit clone https://github.com/Clustmart/winlayout.git\ncd winlayout\nchmod +x winlayout.sh\n```\n\nOr download `winlayout.sh` directly from the repository and make it executable:\n\n```bash\nchmod +x winlayout.sh\n```\n\n**Save** the current layout:\n\n```bash\n./winlayout.sh -s\n```\n\n**Restore** it:\n\n```bash\n./winlayout.sh -r\n```\n\n**List** all saved layouts:\n\n```bash\n./winlayout.sh -l\n```\n\nRunning the script without arguments prints a usage summary.\n\nAll flag variants are equivalent:\n\n```bash\n./winlayout.sh --save      # same as -s\n./winlayout.sh --restore   # same as -r\n./winlayout.sh --list      # same as -l\n```\n\nLayout is saved to `~/.window-layout.txt` by default.\n\n### Named layouts\n\nPass an optional name to save and restore independent layouts — useful when you switch between different monitor setups or workflows:\n\n```bash\n./winlayout.sh -s work          # saves to ~/.window-layout-work.txt\n./winlayout.sh -s home          # saves to ~/.window-layout-home.txt\n./winlayout.sh -r work          # restores the work layout\n./winlayout.sh -l               # lists all saved layouts\n```\n\nOmitting the name always uses the default `~/.window-layout.txt`.\n\n**Optional — make it available system-wide:**\n\n```bash\nmkdir -p ~/bin \u0026\u0026 cp winlayout.sh ~/bin/winlayout\n# If ~/bin is not on your PATH, add to ~/.zshrc: export PATH=\"$HOME/bin:$PATH\"\n```\n\n## Permissions\n\nmacOS will usually prompt for the required permissions on first use. If windows are not moving, open **System Settings → Privacy \u0026 Security** and check:\n\n| Permission | Required for | Grant to |\n|---|---|---|\n| Accessibility | Restore — moving windows | Your terminal app |\n| Automation | Restore — finding apps via System Events | Your terminal app |\n| Screen Recording | Optional — saving window titles | Your terminal app |\n\nScreen Recording is not required. Without it, windows are matched by their saved order within each app rather than by title, which works well in most cases.\n\nRestart your terminal after changing any permission.\n\n## Automate with Shortcuts\n\nThe fastest way to restore your layout without opening a terminal is a keyboard shortcut in the macOS **Shortcuts** app:\n\n1. Open **Shortcuts** and create a new shortcut.\n2. Add a **Run Shell Script** action, set the shell to `/bin/zsh`, and enter:\n   ```\n   /full/path/to/winlayout.sh -r\n   ```\n3. Open the shortcut settings and assign a keyboard shortcut.\n\nPress the key and all windows snap back to their saved positions.\n\nA nice touch: the Apple Extended Keyboard has dedicated function keys (F13–F19) that no app uses by default — assigning restore to **F19** gives you a one-key shortcut with zero chance of conflicts.\n\nTo also save from a shortcut, create a second one using `-s` (or `-s work` for a named layout).\n\n## How It Works\n\n**Save** queries all visible windows from the macOS window server in a single CoreGraphics call — completes in under one second. The fallback AppleScript path, used when Swift is unavailable, queries each running app individually and takes around ten seconds.\n\n**Restore** uses the macOS Accessibility API to match each saved record to a live window and set its position and size. Windows are matched by title first. For apps with dynamic titles (Terminal, code editors) or when Screen Recording is not granted, windows are matched by their saved position within that app's window list.\n\nEach window is stored as one tab-delimited line:\n\n```\nAppName    WindowTitle    x    y    width    height\n```\n\n## Limitations\n\n- Not a snapping or tiling tool; does not create zones or keyboard-driven resize presets.\n- Works best when the same apps and windows are open at restore time; apps that are not running are skipped.\n- Cannot move windows that an app or macOS blocks through the Accessibility API.\n- Coordinates are specific to a display arrangement. Re-save when you change your monitor setup.\n\n## Troubleshooting\n\n**Some windows are not restored at all and stay in their current position.**  \nThis happens occasionally — some windows are not reachable during a restore pass. Running the restore command 1–3 times is usually enough to catch them all.\n\n**Nothing moves when I restore.**  \nCheck Accessibility and Automation permissions for your terminal app, then restart it.\n\n**Some windows move but others do not.**  \nThe app may not expose its windows through Accessibility. Confirm the app is running and has at least one visible window.\n\n**Windows end up on the wrong monitor.**  \nSave the layout with the exact monitor arrangement you want to restore to.\n\n**Window titles are empty in `~/.window-layout.txt`.**  \nGrant Screen Recording permission to your terminal. The script still works without it.\n\n**Permission prompts appear every time.**  \nGrant permissions permanently in System Settings rather than dismissing the prompt each time.\n\n## License\n\n[The Unlicense](LICENSE) — public domain, no conditions.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclustmart%2Fwinlayout","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fclustmart%2Fwinlayout","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclustmart%2Fwinlayout/lists"}