aboutsummaryrefslogtreecommitdiffstats
path: root/docs/superpowers/specs/2026-10-15-expose-design.md
diff options
context:
space:
mode:
Diffstat (limited to 'docs/superpowers/specs/2026-10-15-expose-design.md')
-rw-r--r--docs/superpowers/specs/2026-10-15-expose-design.md35
1 files changed, 19 insertions, 16 deletions
diff --git a/docs/superpowers/specs/2026-10-15-expose-design.md b/docs/superpowers/specs/2026-10-15-expose-design.md
index c86bd7c..cc4eac9 100644
--- a/docs/superpowers/specs/2026-10-15-expose-design.md
+++ b/docs/superpowers/specs/2026-10-15-expose-design.md
@@ -61,19 +61,23 @@ pointer stops there.
`Expose.js`, pure JavaScript with no QML, like `Perf.js`:
- layout(rects, W, H) -> [{x, y, w, h}] // rects: [{x, y, w, h}] in real pixels
-
-1. **Seed.** Each rect is the window's real `at` and `size` from
- `lastIpcObject`, in global coordinates, so DP-3 windows start left of DP-1
- ones. Where windows sit on their desktop otherwise carries no meaning.
+ layout(rects, W, H) -> [{x, y, w, h}] // rects: [{w, h}] in real pixels
+
+1. **Seed.** Window k starts on a golden-angle spiral (radius 0.45 times
+ the tallest window times sqrt(k), angle k times 137.5°, x stretched by
+ the screen's aspect), so the most recent window sits at the centre.
+ Seeding from real positions was the first design and was dropped after
+ a prototype: every window here fills its monitor, so all start in one
+ pile, and pushing a pile apart made a line that still overlapped after
+ 300 passes and filled 8 to 15% of the screen. The spiral converged in 1
+ to 55 passes with no overlap. Where a window lives carries no meaning
+ in the scatter, by choice.
2. **Separate.** Repeated passes over all pairs: two rects overlapping, with
a 60px real gap counted as overlap, are each pushed by half the overlap
- along the axis of least overlap. Coincident centres, the normal case here
- because every window fills its monitor, have no direction to push along,
- so each rect of such a pair moves along its own direction, its index times
- the golden angle (137.5°). That is deterministic and spreads a pile in
- every direction rather than along a line. Stops when a pass moves
- nothing, or after 300 passes.
+ along the axis that costs less screen, overlap divided by the screen's
+ width or height. Compared in raw pixels, wide windows always separate
+ vertically and stack into a column. Stops when a pass moves nothing, or
+ after 300 passes.
3. **Fit.** One uniform scale fits the bounding box into 92% of W by H,
capped at 0.5 so a lone window is not a full-screen mirror, and the result
is centred. A uniform scale keeps rects apart and keeps their sizes
@@ -82,9 +86,8 @@ pointer stops there.
The input order is most recently used first, as `Windows.windows` already
returns it, so the most recent window keeps the lowest index.
-A window whose `lastIpcObject` has no `at` or `size` yet gets 1280x800 at the
-origin; the layout is a binding and repaints when the data arrives. A window
-appearing or closing while the overlay is open recomputes the layout, and the
+A window whose `lastIpcObject` has no `size` yet gets 1280x800; the layout
+is a binding and repaints when the data arrives. A window appearing or closing while the overlay is open recomputes the layout, and the
previews move.
Ceilings, documented with `ponytail:` comments: the pairwise loop is O(n²)
@@ -118,8 +121,8 @@ rule.
`node window-switcher/test_expose.js`, asserting:
-- seven identical 2560x1080 rects at the same position end with no two
- overlapping, all inside W by H;
+- seven identical 2556x1076 rects, and a mixed desk of fourteen, end with
+ no two overlapping, all inside W by H;
- two runs on the same input give the same output;
- a single window is scaled at most 0.5;
- a 1076x1916 rect and a 2556x1076 rect keep their width and height ratios