Skip to content

Commit 933d41c

Browse files
committed
Initial release
0 parents  commit 933d41c

7 files changed

Lines changed: 1567 additions & 0 deletions

File tree

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
dist/
2+
build/
3+
WindowLayout/current_layout.txt
4+
WindowLayout/window_layouts.txt

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 Stefano Menci
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
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`.

WindowLayout.cmd

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
@echo off
2+
setlocal
3+
4+
set "SCRIPT_DIR=%~dp0WindowLayout"
5+
set "SCRIPT_PATH=%SCRIPT_DIR%\WindowLayout.ps1"
6+
7+
if not exist "%SCRIPT_PATH%" (
8+
echo Could not find "%SCRIPT_PATH%".
9+
echo Keep WindowLayout.cmd next to the WindowLayout folder.
10+
pause
11+
exit /b 1
12+
)
13+
14+
powershell.exe -NoLogo -NoProfile -ExecutionPolicy Bypass -File "%SCRIPT_PATH%" %*
15+
set "EXIT_CODE=%ERRORLEVEL%"
16+
17+
if not "%EXIT_CODE%"=="0" (
18+
echo.
19+
echo Script finished with exit code %EXIT_CODE%.
20+
pause
21+
)
22+
23+
exit /b %EXIT_CODE%

0 commit comments

Comments
 (0)