Skip to content

fix(tray): scale auto-fit measure by active zoom + clamp proof anchor (#265) - #266

Merged
Finesssee merged 1 commit into
mainfrom
fix/tray-zoom-autofit-265
Aug 6, 2026
Merged

fix(tray): scale auto-fit measure by active zoom + clamp proof anchor (#265)#266
Finesssee merged 1 commit into
mainfrom
fix/tray-zoom-autofit-265

Conversation

@Finesssee

@Finesssee Finesssee commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

Fixes the two tray-layout bugs from #265 (surfaced by the #261 repro rig).

1. useTrayPanelLayout measure vs CSS zoom

TrayPanel renders the surface with zoom: trayScale, but every DOM metric the auto-fit pass reads — scrollHeight and bounding rects — is reported in the surface's local, pre-zoom px (measured identical at 100/150/200% in the 261 probes). The WIN32 window was sized to the pre-zoom height, so at >100% tall cards clipped below the fold.

  • New exported helper scaledContentHeight(rawHeight, zoom) in useTrayPanelLayout.ts: identity for zoom invalid/≤0/1, else Math.round(raw * zoom). Applied at both measure derivations — the scrollHeight/rect-height seed and the bottom-edge walk — before the existing [minHeight, maxHeight] clamp. The +4px fudge, clamp semantics, and the 2px shouldResize threshold are unchanged.
  • useTrayPanelController passes the already-computed trayScale as the hook's new zoom option; layoutKey already includes trayScaleDraft, so zoom changes re-trigger the layout pass.
  • Horizontal-scrollbar follow-up: .menu-surface's min-width: 260px is interpreted in zoom-local px (renders 390px at 150% inside the 328px window → document-level h-scrollbar + right-clipped content). Re-asserted min-width: 0 in the existing cascade-order .menu-surface--tray override block (the tray window's own 300px min covers the floor).

Test (TrayPanel.test.tsx, "scales the auto-fit measure by the active tray zoom before clamping (#265)"): pinned scrollHeight 505 at trayScalePercent: 150 commits 328×762 (round(505×1.5)+4); 700 clamps to the mocked work-area cap 884. Mutation-checked (fails without scaling).

2. Proof-harness anchor overflows work area

The harness anchored the panel once at the default initial size (y=252 on 1920×1080) and never re-anchors; a tall auto-fit settle pushed the bottom edge below the 1040px work bottom. (set_max_size was tried first and is ignored by Win32 for programmatic setSize.)

  • proof_harness.rs: proof_window_position now wraps the raw anchor with proof_anchor_y(anchor, work_bottom, max_settle) = anchor.min(work_bottom - 8 - max_settle), where max settle mirrors the frontend's 920px auto-fit cap. Anchors that already fit are unchanged; overflowing ones move up just enough that even the capped settle's bottom edge stays at work_bottom - 8.

Test (proof_harness::tests::tall_panel_bottom_edge_never_passes_work_bottom_minus_inset): 252 → justified 112 on the 1080 rig; settled 920 bottoms exactly at 1032; short settles stay on screen; tall-display anchors unchanged.

Gates (run against the committed tree in a pristine worktree)

  • pnpm --dir apps/desktop-tauri exec tsc --noEmit ok; pnpm --dir apps/desktop-tauri test — 227 passed
  • cargo test --manifest-path apps/desktop-tauri/src-tauri/Cargo.toml — 332 passed; cargo clippy --all-targets -- -D warnings ok; cargo fmt --all ok

Live CUA verification (150% zoom, seeded tall Codex card)

Tray zoom driven to 150% through the panel footer Zoom slider via CDP (UIA ValuePattern is ignored by WebView2; the slider's real React onChange path was dispatched) — persisted trayScalePercent: 150 confirmed via get_settings_snapshot, applied CSS zoom: 1.5 confirmed. Relaunched CODEXBAR_PROOF_MODE=trayPanel with CODEXBAR_SEED_USAGE_JSON (proof-261-seed/full shape, timestamps freshened).

Observed (1920×1080, work area 1920×1040):

  • Settled window rect (1580, 112, 328, 920) → bottom edge 1032 = workBottom 1040 − 8 inset (pre-fix: anchored at y=252, short or overflowing).
  • DOM: bodyScrollWidth == clientWidth == 328no horizontal overflow/scrollbar; footer (Quit row) fully visible (footer.bottom 841 ≤ innerHeight 920) — the card's bottom content is on screen (previously clipped).
  • Artifacts: proof-265/zoom150-tallcard-fixed.png, proof-265/zoom150-tallcard-fixed-rects.json, proof-265/zoom150-tallcard-fixed-observation.json.

Closes #265


View with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is enabled.

@Finesssee
Finesssee merged commit 02971a7 into main Aug 6, 2026
3 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Tray layout: zoom<->auto-fit scrollHeight mismatch (tall cards clipped at zoom >100%) + proof-harness anchor overflow

1 participant