233 lines
18 KiB
Markdown
233 lines
18 KiB
Markdown
# Window workspace requirement audit — 2026-10-24
|
||
|
||
This audit follows the full conversation, including later corrections. Implementation completion and native evidence are different columns. No claim is made that Chrome was personally measured.
|
||
|
||
| Requirement | Implementation | Evidence / limits |
|
||
| --- | --- | --- |
|
||
| One top row with native macOS controls | Transparent/full-size native title bar; reserved control space; 40 px tab strip; native AppKit controls repositioned to its y=20 center | Actual Retina macOS windows viewed; native close/minimize/fullscreen controls retained |
|
||
| Continuous left/top chrome | One neutral background; 56 px left rail; inset content panel | Actual main and detached windows viewed; no Tools label or rail launchers |
|
||
| Compact symmetric round tabs, softer active state | 88–208 px width; 32 px pill with equal 4 px vertical insets; 13 px labels and matching 18 px icon/close slots; no hard active stroke | Native settled UI viewed; hover and selected use the same bounds |
|
||
| + and startup default page | One startup request guarded against duplicate resume; + release-inside; Cmd/Ctrl+T | Immediately after restart: pages().count = 1. Two native Cmd+T actions produced three tabs |
|
||
| New-tab motion, filled and unfilled | 220 ms cubic ease; insertion grows from the previous trailing edge; full-strip geometry and + interpolate; removed tabs shrink without remaining interactive | Real native new/close/fill operations completed; settled compression/overflow viewed. No frame-by-frame recording or Chrome timing comparison |
|
||
| Overflow and scrolling | Separate + reservation; no arrow buttons; logical-pixel wheel/trackpad scrolling and clipped offscreen tabs; invisible drag edge dwell retained | Native overflow reached; + in overflow increased VM count 7 → 8. Dragging out of + kept count at 7 |
|
||
| Close/activate/reorder/migrate/detach | Ordinary managed Page methods retained; animated hit bounds and drag anchors use current visual bounds | Native close and drag-out to Endor Window 2 succeeded. API detach/move-back preserved Page 1:135:0. Native cross-window drop, dwell and mixed-DPI were not re-run in this final build |
|
||
| Four developer tools separated | Independent Page instances; Console/Sources/Network/Settings modules and separate per-view state | Earlier native top-level Sources/Console activation and read-only copy/paste verified; no nested navigation remains |
|
||
| Four tools not default or permanently placed | No Tools menu, rail buttons or new-page tool directory; existing API/shortcut retained | Final default surfaces viewed without tool entries |
|
||
| Source reading/selection/copy | Grapheme-boundary selection, no gutter in copy, select-all/copy, Shift navigation, drag edge scrolling | Native single-line drag/copy/paste verified earlier in this change. Final keyboard copy was re-run after the chrome-focus fix: drag-copy matched the complete selected line; four Shift+Right operations copied the expected four characters; select-all copied multiline source without a gutter. Drag edge behavior compiled; exhaustive combinations remain untested |
|
||
| Clicking Console output must not jump to prompt/end | Input hit region restricted to actual prompt rows | Native reading/copy path verified earlier; no input hit over transcript-only area |
|
||
| Default page reflects Endor | Real Endor Page with creation, shared-object and composition actions; no persistence/model backend claims | Referenced chats read: 01a16819-28c3-7ce0-9423-0ffaa19402ce and 01a1689b-77d8-75a2-ba9e-b2fa3dce654e; actual native start surface viewed |
|
||
| Sensible source organization | Runtime/API tests separated; four page view modules; shared painter/selection; native tool Page factory; motion module | All-target Clippy compiled production and test sources. Runtime host reduced from ~7000 to ~1380 lines |
|
||
| Protect existing work | examples/README.md and examples/workspace.endor excluded; vendor/Aster untouched | git status checked before staging |
|
||
| Verification restrictions | fmt, all-target Clippy -D warnings, release build and manual native/API checks | No cargo test, smoke script, Docker, dependency test install or CI polling |
|
||
|
||
## Reference boundaries
|
||
|
||
The user's Chrome/Codex reference images supplied the single-row controls, capsules and continuous left/top chrome. The [Obsidian reading-view reference](https://forum.obsidian.md/t/make-button-to-switch-views-in-tab-title-bar-more-intuitive/89814/6) informed restrained contrast and pane separation.
|
||
|
||
The actual tools refused access to both Codex and Terminal. The available in-app browser exposes page content, not Chrome's native tab strip. No personal Chrome window/profile was operated. A Chromium source search was supplementary research, not an animation test; fetching the selected source page failed. Therefore the requested isolated Chrome comparison remains unverified.
|
||
|
||
## Manual request correction
|
||
|
||
One placement probe used unsupported == syntax and returned a parse error before execution. It was replaced with direct returned object-identity checks. Both the detached-window Page and moved-back Page returned 1:135:0. The failed expression is not counted as passing evidence.
|
||
|
||
## Remaining verification
|
||
|
||
Isolated Chrome timing/shape comparison, frame-by-frame animation capture, fresh native cross-window drop/dwell on the final build, mixed-DPI cross-screen interaction and exhaustive keyboard/source-selection combinations remain without new runtime evidence. These are not silently marked passed. The shipped Page lifetime/GC model was preserved; no new persistence or AI backend is claimed.
|
||
|
||
|
||
## Final focus regression fix
|
||
|
||
Final native retesting found a real regression: title-strip mouse events cleared the active editor focus. Window activation performed before automated key events exposed the same behavior. Chrome mouse presses now preserve content focus; developer pane hit testing ignores points outside the pane; frame publication updates the keyboard route according to the active Page. No source, tab geometry or selection state is logged by the shipped build.
|
||
|
||
After the fix, direct system clipboard comparisons (without printing clipboard contents) confirmed selected-line equality (28 characters), Shift+Right selection equality (4 characters), and multiline select-all with no line-number gutter. The temporary Sources Page was closed afterwards. All-target Clippy, formatting and release building passed again.
|
||
|
||
## Local delivery state
|
||
|
||
Implementation commits: 3220544 (runtime test-source separation), 656522e (managed workspace/chrome implementation), d3165b1 (behavior and requirement audit), followed by the chrome-focus fix commit. A push to origin/main was attempted once and rejected by automatic approval review because explicit authorization for this default-branch remote mutation was required. No alternative push route was attempted. The remote remains unchanged pending the user's approval.
|
||
|
||
|
||
## Functional start-page revision
|
||
|
||
The previous Rust-painted introduction was removed. `ui_bridge/start_page.endor`
|
||
now defines a managed Page subclass with native layout alignment, real buttons,
|
||
a shared-state counter and a composed-Blocks example. Its private module globals
|
||
do not overwrite user REPL bindings. The same factory is available as `ui.newTab()`;
|
||
legacy `ui.developerTools("New tab")` delegates to it. No developer-tool entry is
|
||
shown on the start page.
|
||
|
||
Native startup checks caught unsupported comparison syntax and unimplemented
|
||
arithmetic bytecode in initial layout drafts. Those drafts were replaced with
|
||
existing Page/Row measurement and native `mainAlign`, without changing Aster.
|
||
A subsequent layout check caught unbounded child-height centering; sizing now
|
||
belongs to the root Page, which receives the actual content constraints.
|
||
These failures were corrected locally, and are not counted as passing checks.
|
||
|
||
|
||
Final native checks for this revision: all three start-page buttons opened their
|
||
corresponding managed Pages; the blank-page return action activated its original
|
||
home Page; one native counter click changed both views from 0 to 1. Overflow
|
||
navigation was visible while these Pages were added. A direct `ui.newTab()` call
|
||
increased the live Page count from 4 to 5, confirming one Page per factory call.
|
||
The final window was also being operated by the user (reported by the UI tool),
|
||
so the pre-existing four tabs are not treated as a clean-start count measurement.
|
||
No additional restart was done after that interaction. The earlier isolated
|
||
startup count of one remains evidence for the guarded startup path; the new
|
||
factory's single-call count was checked separately.
|
||
|
||
Formatting, all-target offline Clippy with warnings denied, the release macOS
|
||
bundle and diff whitespace checks passed. No test suite or smoke script was run.
|
||
All earlier requirements were reviewed against the table above; isolated Chrome
|
||
motion comparison and the explicitly listed cross-window/DPI verification gaps
|
||
remain unverified, rather than being marked complete.
|
||
|
||
|
||
## Chrome contrast correction
|
||
|
||
The continuous top/left chrome now uses #E6E9ED instead of #F5F5F5,
|
||
separating it visibly from the #F7F7F5 content canvas. Selected tabs retain
|
||
white fill and dark text; inactive titles use muted text. Geometry and borderless
|
||
selection are unchanged. After rebuilding and restarting, the native window
|
||
showed one startup tab; a + click added a second tab and the two states were
|
||
visually checked. Formatting, all-target offline Clippy and release bundling passed.
|
||
|
||
## Start-page visual redesign
|
||
|
||
Reviewed the four user-supplied Codex/Chrome/Obsidian/VS Code references and
|
||
Anthropic's frontend-design skill. Reference decisions and tokens are recorded in
|
||
`docs/start-page-design.md`. The default page now uses one 28 px wordmark, a short
|
||
14 px hint, aligned action rows and separate shortcut rows. A first pass with
|
||
white outlined buttons was rejected by the user; the action fill and border were
|
||
removed in the final pass. The Endor Button subclass keeps a 360 × 40 hit target
|
||
but returns an empty background display list; its label and native focus indicator
|
||
still render through the existing tree.
|
||
|
||
Native screenshot review confirmed the final text-row treatment. Clicking the
|
||
shared-object action opened its Page; Tab focused the first action with a visible
|
||
outline. Startup displayed one default Page. Formatting, all-target offline Clippy,
|
||
release bundling and diff whitespace checks passed. No automated test suite was run.
|
||
The design skill was read from a temporary download only; no global skill, hooks
|
||
or new application dependency was installed.
|
||
|
||
|
||
## Tab motion, density and macOS alignment correction — 2026-10-25
|
||
|
||
Reviewed the user-provided 60 fps reference recording by extracting insertion,
|
||
full-strip and closing frames. The reference's unfilled strip expands the new tab
|
||
from the previous trailing edge and moves + with it; overflow scrolls the strip
|
||
and permits a partial tab at the edge. This is analysis of the supplied recording,
|
||
not an independently measured live Chrome/Codex session.
|
||
|
||
The strip now retains geometry for every tab ID, including offscreen tabs. Moving
|
||
an existing tab into the viewport no longer treats it as a new zero-width tab.
|
||
Geometry retargets from its sampled position during repeated operations; closed
|
||
tabs shrink visually and are excluded from hit testing. New selection reveals only
|
||
the required portion of the strip rather than centering the selected tab.
|
||
|
||
The former 160 px minimum is reduced to 88 px, and arrow controls plus their
|
||
reserved margins are removed. Horizontal trackpad deltas and vertical mouse-wheel
|
||
deltas over the strip both change a clamped floating-point scroll offset. Gesture
|
||
scrolling follows input directly, while insertion, closure and automatic reveal
|
||
use the 220 ms transition. OS momentum remains ordinary subsequent wheel input.
|
||
No touchscreen hardware verification is claimed.
|
||
|
||
The initial 28 px row was too shallow. The revised 40 px row centers tabs at
|
||
y=20 and repositions the retained native AppKit controls onto the same center
|
||
line. Pills are 32 px high, with 4 px top/bottom margins and 13 px labels. A 1 × 12 px divider separates adjacent inactive tabs; it is hidden beside
|
||
an active or hovered tab. Hover and selection retain the same pill geometry.
|
||
|
||
Manual native checks covered startup, + and repeated Cmd+T, dense overflow,
|
||
vertical wheel movement to either end, hover divider suppression, tab selection
|
||
and Cmd+W closure. Native screenshots confirmed alignment, density and absence
|
||
of arrow controls. Physical trackpad feel, mixed-DPI cross-window drag and an
|
||
exact frame-timing match remain unverified. A capture attempt around an insertion
|
||
returned only one usable frame, so it is not presented as animation timing proof.
|
||
|
||
Formatting, all-target offline Clippy with warnings denied, release app bundling
|
||
and whitespace checks passed. Existing geometry test fixtures were updated for
|
||
pixel offsets and the denser layout; they were type-checked by Clippy but no
|
||
cargo test, automated smoke script or Docker task was run.
|
||
|
||
|
||
### Comfortable row height with native alignment — 2026-10-25
|
||
|
||
The current Chromium [layout constants](https://github.com/chromium/chromium/blob/main/chrome/browser/ui/layout_constants.cc)
|
||
define a 35 px tab (34 + 1 px toolbar overlap) and 6 px strip padding, totaling
|
||
41 px. Tessera uses a 40 px row with a symmetric 32 px capsule, retaining its
|
||
88–208 px width range, separators, gesture scrolling and insertion motion.
|
||
Only the in-app web view is available for agent-owned browser access, so this
|
||
is a source/reference-image comparison, not a live measurement of Chrome.
|
||
|
||
A macOS-only adapter obtains the winit-owned content NSView and positions the
|
||
three real standard window buttons at the row's center. It preserves their
|
||
native sizes, horizontal positions and actions, and reapplies alignment before
|
||
drawing after native layout changes. Fullscreen floating controls stay under
|
||
AppKit management. Native bindings were already cached transitively; direct
|
||
macOS-only dependencies now declare this use explicitly.
|
||
|
||
Manual resizing followed by repeated tab creation exposed a renderer panic:
|
||
rounding at large absolute x positions could invert a rounded rectangle's
|
||
clamp bounds while a tab grew from almost zero width. Rounded hit coverage now
|
||
clamps in local coordinates with a radius bounded by half the rectangle size.
|
||
|
||
Final native checks passed for 18 consecutive Cmd+T insertions, dense overflow,
|
||
wheel scrolling, five consecutive Cmd+W closures and native window zoom. The
|
||
final process stayed running without stderr errors. Initial native screenshots
|
||
showed the traffic lights, tab capsules and + centered at the same y position.
|
||
Subsequent computer-control captures can display macOS's capture badge over the
|
||
traffic lights. Fullscreen floating controls and mixed-DPI moves were not tested.
|
||
Offline all-target Clippy with warnings denied, formatting, release app bundling
|
||
and git whitespace checks passed; no cargo test or automated smoke script ran.
|
||
|
||
|
||
### Hover fades with immediate selection — 2026-10-25
|
||
|
||
Tab bodies, the + button and close-button hover backgrounds now use the same
|
||
160 ms cubic ease-out for entering and leaving. Each tab is tracked by its
|
||
stable ID; reversing a fade starts from the current sampled intensity. Adjacent
|
||
inactive dividers fade with the tab hover instead of disappearing abruptly.
|
||
Close-button colors interpolate from the tab's actual current background,
|
||
including the selected white surface.
|
||
|
||
Hover state runs separately from geometry animation. The event loop schedules
|
||
frames until either transition finishes, including after the pointer stops or
|
||
leaves the window. Selected backgrounds and label colors still read the current
|
||
active flag directly, so selection has no color fade or animation delay.
|
||
Existing insertion/closure movement and native control alignment are retained.
|
||
|
||
Native manual checks covered an inactive tab hover, leaving that tab, the +
|
||
hover, selecting a different tab and moving back into page content. Settled
|
||
screenshots confirmed hover does not select the tab, + has its hover surface,
|
||
selection changes to the clicked tab and idle separators return after leaving.
|
||
The capture API does not establish frame-accurate 160 ms timing. Offline
|
||
all-target Clippy, formatting, release bundling and whitespace checks passed;
|
||
no cargo test, automated smoke script or Docker task was run.
|
||
|
||
|
||
### Native toolbar double-click — 2026-10-25
|
||
|
||
The custom row previously called only winit's native window-drag operation;
|
||
a manual double-click in its empty area did not resize the window. The same
|
||
empty-area hit test now consults AppKit's current NSEvent clickCount before
|
||
starting a drag. On the second press it calls NSWindow.performZoom, preserving
|
||
AppKit's standard/user frame toggle and avoiding a hand-built resize animation.
|
||
Tabs, close buttons and + remain excluded from this handler.
|
||
|
||
The adapter reads AppleActionOnDoubleClick without changing system preferences:
|
||
Minimize calls performMiniaturize; absent/Maximize calls performZoom; disabled
|
||
or unknown values do nothing. Fill also uses the public performZoom action,
|
||
whose standard frame fills this application's available screen in the checked
|
||
configuration. It does not invoke the private _zoomFill selector used by Chrome.
|
||
Consequently Fill is not claimed to reproduce every macOS tiling margin rule.
|
||
Native fullscreen uses a different window state and is left to AppKit.
|
||
|
||
References: Apple's [performZoom](https://developer.apple.com/documentation/appkit/nswindow/performzoom(_:))
|
||
and Chromium's [custom draggable-area handling](https://github.com/chromium/chromium/blob/main/components/remote_cocoa/app_shim/native_widget_mac_nswindow.mm).
|
||
|
||
Manual native verification: an empty-row double-click changed the Retina window
|
||
from 2560×1600 to 3024×1888; a second double-click restored 2560×1600. Clicking
|
||
+ and double-clicking a tab did not zoom the window. Dragging empty toolbar
|
||
space continued to move the window. The user's double-click preference was
|
||
absent (default zoom); other preference branches were not changed or manually
|
||
tested. Offline all-target Clippy, formatting, release bundling and whitespace
|
||
checks passed. No cargo test or automated smoke script was run.
|