diff options
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/superpowers/specs/2026-10-15-expose-design.md | 35 |
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 |
