Repository navigation
Everything merged in #1 since v0.4.0. Three epics' worth of overlay work: VRT-cne0 (frame selection + X close), VRT-mijf (tree navigation + frame anchoring), VRT-dp47 (Escape, pill visibility, inline icon actions).
Selection
- Frame selection tool. Draw a rectangle around what you mean instead of hunting for the pixel that hit-tests to it; the drawn frame resolves to the most likely element inside it, and degrades to a region note anchored at the frame's centre when nothing there is annotatable. It is an explicit tool, chosen in the pill — a click in frame mode does nothing by design, so a wobbly hand can never silently plant a framed note. The persisted
regionRectlocator ("a 320x48 band 40pt down inside#Settings.Models") travels with the note. - Select Parent / Select Child replace the one-way "Widen". Both directions are always visible and dim to show where you are in the tree, and a Parent→Child round trip returns to the rung you came from rather than to whatever the live UI now considers most likely.
- Frame mode no longer hover-highlights. A highlight there promised a click-selection the mode cannot make.
Keyboard
- Escape backs out one level at a time — card, then in-flight frame drag, then annotate mode — through a local key monitor that works whether or not the overlay panel is key. A handled Escape is consumed so the host app never double-acts on the same keystroke; an unhandled one is passed through untouched.
The pill
- The toolbar now lives in its own window. It was drawn inside the catcher overlay, so its position was a function of a frame that resizes on every open/close, gets clamped to the visible screen, and is dragged around by AppKit when the host moves. It is now permanently mounted, fixed size, pinned to the host's bottom-right: always visible, always in the same place, and the menu is genuinely just open or closed.
- Placement is clamped to the screen's
visibleFrame, so a host window whose bottom hangs below the display no longer puts the pill under the Dock — and the clamp is re-asserted after AppKit's parent-follow repositioning, which used to silently undo it a runloop turn later. - Scrolling the host while annotating works. The overlay drives the host's clip directly rather than handing the event across windows, which used to wedge the panel's rendering and hit-testing — observed as "the toolbar vanishes after I scroll, then hover on and off it".
AXEnhancedUserInterfaceis written once per process, not per hover, ending a relayout storm that made the pill flicker.
Cards and icons
- One inline row of icon actions on both the composer and the pin editor —
arrow-up,arrow-down,undo-2,send,trash— each with a tooltip and a matching accessibility label, and the commit action carrying its prominence in accent colour. - Real elliptical arcs in the Lucide path parser (SVG 1.1 F.6.5 endpoint→centre, emitted as cubic beziers). The old parser drew a straight line to each arc endpoint, which collapsed
undo-2's loop into a vertical stroke;pencil's corner rounds have quietly been wrong all along and are now correct too.
Verification
191 tests, 11/11 AnnotKitOverlayProbe phases, swift build -Xswiftc -warnings-as-errors clean, iOS simulator cross-compile clean.
Full changelog: v0.4.0...v0.5.0