Machines Arrangement
Machines: free arrangement, more computers
Follow-up to docs/machines-tab.md, on the same branch. The user, after using
the first version: "now we need to move and rearrange the monitors. and add
more computers".
1. One arrangement canvas, like System Settings › Displays
Replace the four Left/Top/Right/Bottom slots with one canvas, drawn to scale:
- This Mac's displays: drag to rearrange, snapping edge to edge like
System Settings. This changes the real macOS arrangement
(
CGBeginDisplayConfiguration/CGConfigureDisplayOrigin/CGCompleteDisplayConfiguration(.permanently)), so a drag only moves the drawing. An Apply button commits it and a Revert button undoes it, and after applying it reverts automatically after 15 s unless kept. Never apply without the button. - Other machines: each one is a block made of its own monitors at their
real proportions, labelled with the machine's name. Ask the host for its
displays if it can tell you (look at what
host.describe/ the Linux host return: Archie has HDMI-A-1 3440×1440 and a virtual LATS-1 1920×1080). If it can't, draw one generic screen. Drag the block anywhere against this Mac's displays. Where it touches is where the cursor crosses. - Elsewhere displays: still drawn, dim, and you can drop a machine onto one ("this display shows arts-mini"). Store that, show it, and when the pointer is pushed off an elsewhere display that a machine is on, start a visit to that machine.
Fix from the first version:
- Only the real main display gets "This Mac". Number the others, and label an elsewhere display with the machine it shows if one is set.
- Draw elsewhere displays clearly dimmer.
- No green: the selected rail icon in this page (and wherever this tint is coming from) uses the app's normal selection, or coral if it has to be a hue.
2. Placement replaces side
Today a machine has one VisitTrust.Side and VisitController allows one
machine per side. Generalise:
- A machine's placement is a rect in global display coordinates (the same
space as
CGDisplayBounds), stored with the pairing. Its side and the span along it are derived from where it touches this Mac's displays. - Crossing: the exit point on an edge belongs to whichever machine's rect
touches that stretch of edge. So two machines can share a side (e.g. two on
the right, one per display).
enter'sedgeandatstay as they are indocs/visit.md; computeatalong the machine's touching span, not the whole display. - Migrate existing pairings: an old
sidebecomes a rect beside the outermost display on that side, vertically centred. Keepvisit.sideworking as a shortcut, and addvisit.place {name, x, y}. Mirror both inlats visit. - Keep the edge push threshold and quiet period exactly as they are.
Put the geometry (touching spans, snapping, migration, which machine owns an exit point) in pure functions with tests.
3. More computers
- An Add machine button opens a sheet. Fill in name and address, then pick
what it is:
- a Lattices host (writes
~/.lattices/hosts.json, likelats hosts addif that exists; add it if not); - a visit host to pair (the existing pairing flow);
- or both. The new machine appears on the canvas off to one side, unplaced, until it's dragged against a display.
- a Lattices host (writes
- Unplaced or unreachable machines still show, dimmed, so the user can arrange them before they're online.
- arts-mini (a Mac,
ssh arts-mini) is the next machine the user wants. A Mac has no visit host yet: the Linux one is inpackages/host-linuxand the protocol isdocs/visit.md. Build the Mac side of it in the app, behind a setting that's off by default ("Let other machines visit this Mac"). It should:- accept the signed
/visitupgrade on the existing bridge; - post the CGEvents;
- draw the visiting cursor (small rounded coral dart with a soft glow and a
name pill, like
visitor/shell.qml); - send
exitwhen the cursor leaves by the edge it came in. Unit test the message handling. Don't deploy it to arts-mini or ssh there.
- accept the signed
Constraints
Same as docs/machines-tab.md:
- Work only in this worktree. Don't launch, quit or restart the running app.
- No real display reconfiguration, pairing, arming or sharing while developing. Display reconfiguration only ever happens through Apply.
- Gitmoji on every commit, no co-author lines or footers, don't push. Bun only.
cd apps/mac && swift build -c releasemust pass, along with the tests.- Write the report to
~/.cache/machines-arrangement-report.md.