Skip to content

Commit 419eaff

Browse files
committed
Add management of virtual desktops
1 parent f3aff3e commit 419eaff

File tree

5 files changed

+731
-89
lines changed

5 files changed

+731
-89
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ dist/
22
build/
33
WindowLayout/current_layout.txt
44
WindowLayout/window_layouts.txt
5+
WindowLayout/processes_to_ignore.txt
56
WindowLayout/*.cmd

README.md

Lines changed: 45 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
# Window Layout
22

3-
Save and restore complex Windows desktop layouts from a simple folder, with no installation beyond Windows itself.
3+
Save and restore complex Windows desktop layouts from a simple folder, with no installation required.
44

55
This project uses PowerShell plus built-in Windows APIs to:
66

77
- Capture the current monitor-aware window arrangement
88
- Restore named layouts from a text file
9+
- Reorganize windows across multiple virtual desktops without dragging them around manually
910
- Work across different monitor numbering by matching monitors by position
1011
- Support multiple monitor setups such as `3 monitors`, `ultrawide`, or `laptop`
1112
- Support both per-window rules and cascade rules for multi-instance apps
@@ -15,38 +16,45 @@ This project uses PowerShell plus built-in Windows APIs to:
1516
- Windows can renumber monitors after events such as screensaver/sleep/wake, but this tool identifies monitors by position rather than number
1617
- Similar home and office monitor layouts can still match even when positions and sizes are close but not identical
1718
- Different monitor resolutions still work because window placement uses percentages instead of fixed pixel coordinates
19+
- Virtual desktops are tedious to organize by hand when you first open a group of windows; this tool can place them on the right desktops for you
20+
- You can also use partial layouts, for example a `MyProject.cmd` script that opens a few apps and then runs `WindowLayout.cmd -ApplyLayout "MyProject"` to arrange only those windows
1821
- Configurations can be copied from computer to computer
1922

2023
## What It Looks Like
2124

22-
The launcher shows layouts in the form:
25+
Setup examples:
2326

2427
- `3 monitors - developer`: IDE large, CAD smaller
2528
- `3 monitors - engineer`: CAD large, IDE smaller
2629
- `ultrawide - developer`: IDE on the left
2730
- `ultrawide - engineer`: CAD on the left
28-
- `laptop - laptop`: mostly full-screen windows on a single monitor
31+
- `laptop - default`: mostly full-screen windows on a single monitor
2932

3033
You can also apply a layout directly from an interactive terminal or from a shortcut script:
3134

3235
```cmd
3336
WindowLayout.cmd -ApplyLayout "3 monitors - developer"
3437
```
3538

39+
When `WindowLayout\window_layouts.txt` is reformatted, the script also regenerates one `.cmd` file per saved layout inside `WindowLayout\`, for example `WindowLayout\WindowLayout - 3 monitors - developer.cmd`.
40+
3641
## Features
3742

3843
- `No dependencies`: runs with built-in Windows PowerShell and .NET only
39-
- `Portable`: works from a folder such as the desktop
44+
- `Portable`: runs directly from a folder such as the desktop
4045
- `Monitor setups`: separate physical monitor arrangements from window layouts
4146
- `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`
47+
- `Capture workflow`: saves the current layout to `current_layout.txt`, which you can trim and copy into `window_layouts.txt`
4348
- `Readable config`: uses a pipe-delimited text format instead of JSON
4449
- `Regex titles`: supports `regex` title matching, including `|` inside regex patterns
4550
- `Cascade support`: capture emits both a cascade row and individual rows for multi-instance apps
51+
- `Virtual desktops`: captures and restores a manually editable desktop number for each window
52+
- `Editable percentages`: capture writes integer `x`, `y`, `w`, and `h` values, but you can manually change them to decimals for finer positioning
53+
- `Ignore list`: processes without a valid desktop number are written to `processes_to_ignore.txt` and excluded from future captures and restores
4654

4755
## Folder Layout
4856

49-
Release zip contents:
57+
Folder contents:
5058

5159
```text
5260
WindowLayout.cmd
@@ -57,24 +65,28 @@ WindowLayout/
5765

5866
`window_layouts.txt` is created on first run.
5967

68+
Per-layout `.cmd` shortcut scripts inside `WindowLayout\` are generated from `window_layouts.txt` when it is reformatted.
69+
6070
`current_layout.txt` is generated only when you capture a layout.
6171

72+
`processes_to_ignore.txt` is updated automatically when capture finds processes without a valid desktop number.
73+
6274
## Quick Start
6375

64-
1. Download the release zip and extract it.
76+
1. Download or copy the folder.
6577
2. Keep `WindowLayout.cmd` next to the `WindowLayout` folder.
6678
3. Double-click `WindowLayout.cmd`.
6779
4. Choose a saved layout, or capture the current layout.
6880
5. After capture, copy the parts you want from `current_layout.txt` into `window_layouts.txt`.
6981

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.
82+
Capture usually sees more windows than you want to keep, including helper windows and some windows that are not obvious at first glance. Processes without a valid desktop number are not written to `current_layout.txt`; instead, their process names are added to `WindowLayout\processes_to_ignore.txt`.
7183

7284
## Configuration Model
7385

7486
The config separates:
7587

7688
- `MonitorSetup`: the physical monitor arrangement
77-
- `Layout`: the app/window arrangement for that monitor setup
89+
- `Layout`: the window arrangement for that monitor setup
7890

7991
Example:
8092

@@ -96,10 +108,10 @@ primary | 0 | 0
96108
97109
[Layout developer]
98110
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
111+
processName | title | match | x | y | w | h | monitorRole | cascade | desktop
112+
chrome.exe | Main | contains | 20 | 20 | 60 | 70 | primary | no | 1
113+
chrome.exe | YouTube | contains | 0 | 0 | 30 | 100 | lower-left | no | 2
114+
notepad.exe | | contains | 45 | 0 | 55 | 100 | upper-left | no | 2
103115
```
104116

105117
That shows the main idea:
@@ -108,22 +120,39 @@ That shows the main idea:
108120
- Layouts describe where apps go inside that setup
109121
- A row with a title targets a specific window pattern
110122
- A row with an empty title can target any window from that process
123+
- `desktop` is a 1-based virtual desktop number and can be edited manually to place windows across multiple virtual desktops
124+
- Captured `x`, `y`, `w`, and `h` values are written as integers, but you can manually edit them to decimal values when you want finer control
111125

112126
Excel example:
113127

114128
```text
115129
[Layout engineer]
116130
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
131+
processName | title | match | x | y | w | h | monitorRole | cascade | desktop
132+
excel.exe | Visual Basic | contains | 2 | 0 | 60 | 100 | primary | no | 1
133+
excel.exe | - Excel$ | regex | 60 | 10 | 35 | 40 | primary | yes | 2
120134
```
121135

122136
That shows a useful pattern:
123137

124138
- The Excel VBA editor (`Visual Basic`) is pinned on the left
125139
- All normal workbook windows (`- Excel$`) are handled together with `cascade = yes`
126140
- In regex mode, `- Excel$` means the title ends with `- Excel`; `$` marks the end of the title
141+
- Those workbook windows are moved to desktop `2` during restore
142+
- Changing the `desktop` numbers in `window_layouts.txt` is the normal way to place windows across multiple desktops
143+
144+
## Capture Notes
145+
146+
- Capture learns ignored processes automatically and stores them in `WindowLayout\processes_to_ignore.txt`
147+
- Processes without a valid desktop number are blacklisted and omitted from `current_layout.txt`
148+
- Capture still writes integer percentages, but manual decimal edits in `window_layouts.txt` are preserved when the file is reformatted
149+
150+
## Restore Notes
151+
152+
- Restore moves each window to its saved desktop number before applying size and position
153+
- If a window is already on the target desktop, the script skips the desktop move and only applies size/position
154+
- If a saved desktop number is missing during restore, the script leaves that window on its current desktop and continues with the rest of the layout
155+
- Restore also uses `WindowLayout\processes_to_ignore.txt`, so previously blacklisted processes are skipped
127156

128157
## Commands
129158

@@ -134,16 +163,6 @@ WindowLayout.cmd -CaptureCurrent
134163
WindowLayout.cmd -ApplyLayout "3 monitors - developer"
135164
```
136165

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-
147166
## License
148167

149168
MIT. See `LICENSE`.

0 commit comments

Comments
 (0)