|
| 1 | +# Window Layout |
| 2 | + |
| 3 | +Save and restore complex Windows desktop layouts from a simple folder, with no installation beyond Windows itself. |
| 4 | + |
| 5 | +This project uses PowerShell plus built-in Windows APIs to: |
| 6 | + |
| 7 | +- Capture the current monitor-aware window arrangement |
| 8 | +- Restore named layouts from a text file |
| 9 | +- Work across different monitor numbering by matching monitors by position |
| 10 | +- Support multiple monitor setups such as `3 monitors`, `ultrawide`, or `laptop` |
| 11 | +- Support both per-window rules and cascade rules for multi-instance apps |
| 12 | + |
| 13 | +## Why It Is Useful |
| 14 | + |
| 15 | +- Windows can renumber monitors after events such as screensaver/sleep/wake, but this tool identifies monitors by position rather than number |
| 16 | +- Similar home and office monitor layouts can still match even when positions and sizes are close but not identical |
| 17 | +- Different monitor resolutions still work because window placement uses percentages instead of fixed pixel coordinates |
| 18 | +- Configurations can be copied from computer to computer |
| 19 | + |
| 20 | +## What It Looks Like |
| 21 | + |
| 22 | +The launcher shows layouts in the form: |
| 23 | + |
| 24 | +- `3 monitors - developer`: IDE large, CAD smaller |
| 25 | +- `3 monitors - engineer`: CAD large, IDE smaller |
| 26 | +- `ultrawide - developer`: IDE on the left |
| 27 | +- `ultrawide - engineer`: CAD on the left |
| 28 | +- `laptop - laptop`: mostly full-screen windows on a single monitor |
| 29 | + |
| 30 | +You can also apply a layout directly from an interactive terminal or from a shortcut script: |
| 31 | + |
| 32 | +```cmd |
| 33 | +WindowLayout.cmd -ApplyLayout "3 monitors - developer" |
| 34 | +``` |
| 35 | + |
| 36 | +## Features |
| 37 | + |
| 38 | +- `No dependencies`: runs with built-in Windows PowerShell and .NET only |
| 39 | +- `Portable`: works from a folder such as the desktop |
| 40 | +- `Monitor setups`: separate physical monitor arrangements from window layouts |
| 41 | +- `Relative monitor matching`: matches the current monitors to a saved setup by relative position, not Windows numbering |
| 42 | +- `Capture workflow`: captures the current layout into `current_layout.txt`, which you can trim and copy into `window_layouts.txt` |
| 43 | +- `Readable config`: uses a pipe-delimited text format instead of JSON |
| 44 | +- `Regex titles`: supports `regex` title matching, including `|` inside regex patterns |
| 45 | +- `Cascade support`: capture emits both a cascade row and individual rows for multi-instance apps |
| 46 | + |
| 47 | +## Folder Layout |
| 48 | + |
| 49 | +Release zip contents: |
| 50 | + |
| 51 | +```text |
| 52 | +WindowLayout.cmd |
| 53 | +WindowLayout/ |
| 54 | + WindowLayout.ps1 |
| 55 | + readme.txt |
| 56 | +``` |
| 57 | + |
| 58 | +`window_layouts.txt` is created on first run. |
| 59 | + |
| 60 | +`current_layout.txt` is generated only when you capture a layout. |
| 61 | + |
| 62 | +## Quick Start |
| 63 | + |
| 64 | +1. Download the release zip and extract it. |
| 65 | +2. Keep `WindowLayout.cmd` next to the `WindowLayout` folder. |
| 66 | +3. Double-click `WindowLayout.cmd`. |
| 67 | +4. Choose a saved layout, or capture the current layout. |
| 68 | +5. After capture, copy the parts you want from `current_layout.txt` into `window_layouts.txt`. |
| 69 | + |
| 70 | +Capture usually sees more windows than you want to keep, including helper windows and some windows that are not obvious to the user. Trim the captured file before keeping it. |
| 71 | + |
| 72 | +## Configuration Model |
| 73 | + |
| 74 | +The config separates: |
| 75 | + |
| 76 | +- `MonitorSetup`: the physical monitor arrangement |
| 77 | +- `Layout`: the app/window arrangement for that monitor setup |
| 78 | + |
| 79 | +Example: |
| 80 | + |
| 81 | +```text |
| 82 | +[MonitorSetup 3 monitors] |
| 83 | +role | x | y |
| 84 | +primary | 0 | 0 |
| 85 | +upper-left | -1600 | 1250 |
| 86 | +lower-left | -1600 | 2160 |
| 87 | +
|
| 88 | +[MonitorSetup ultrawide] |
| 89 | +role | x | y |
| 90 | +primary | 0 | 0 |
| 91 | +left | -1600 | 1250 |
| 92 | +
|
| 93 | +[MonitorSetup laptop] |
| 94 | +role | x | y |
| 95 | +primary | 0 | 0 |
| 96 | +
|
| 97 | +[Layout developer] |
| 98 | +monitorSetup | 3 monitors |
| 99 | +processName | title | match | x | y | w | h | monitorRole | cascade |
| 100 | +chrome.exe | Main | contains | 20 | 20 | 60 | 70 | primary | no |
| 101 | +chrome.exe | Personal | contains | 0 | 0 | 30 | 100 | lower-left | no |
| 102 | +ms-teams.exe| | contains | 45 | 0 | 55 | 100 | upper-left | no |
| 103 | +``` |
| 104 | + |
| 105 | +That shows the main idea: |
| 106 | + |
| 107 | +- monitor setups describe the physical arrangement |
| 108 | +- Layouts describe where apps go inside that setup |
| 109 | +- A row with a title targets a specific window pattern |
| 110 | +- A row with an empty title can target any window from that process |
| 111 | + |
| 112 | +Excel example: |
| 113 | + |
| 114 | +```text |
| 115 | +[Layout engineer] |
| 116 | +monitorSetup | 3 monitors |
| 117 | +processName | title | match | x | y | w | h | monitorRole | cascade |
| 118 | +excel.exe | Visual Basic | contains | 2 | 0 | 60 | 100 | primary | no |
| 119 | +excel.exe | - Excel$ | regex | 60 | 10 | 35 | 40 | primary | yes |
| 120 | +``` |
| 121 | + |
| 122 | +That shows a useful pattern: |
| 123 | + |
| 124 | +- The Excel VBA editor (`Visual Basic`) is pinned on the left |
| 125 | +- All normal workbook windows (`- Excel$`) are handled together with `cascade = yes` |
| 126 | +- In regex mode, `- Excel$` means the title ends with `- Excel`; `$` marks the end of the title |
| 127 | + |
| 128 | +## Commands |
| 129 | + |
| 130 | +```cmd |
| 131 | +WindowLayout.cmd |
| 132 | +WindowLayout.cmd -ListLayouts |
| 133 | +WindowLayout.cmd -CaptureCurrent |
| 134 | +WindowLayout.cmd -ApplyLayout "3 monitors - developer" |
| 135 | +``` |
| 136 | + |
| 137 | +## Build A Release Zip |
| 138 | + |
| 139 | +This repo includes a packaging script: |
| 140 | + |
| 141 | +```powershell |
| 142 | +.\build-release.ps1 |
| 143 | +``` |
| 144 | + |
| 145 | +It creates `dist\WindowLayout.zip` with the deployable files only. |
| 146 | + |
| 147 | +## License |
| 148 | + |
| 149 | +MIT. See `LICENSE`. |
0 commit comments