Sidebar toggle: laggy and left pane content offset after open/close/open #29

Open
opened 2026-09-15 12:30:57 +00:00 by kayg · 9 comments
Owner

Report (user, 2026-09-15, desktop build 5b72a45)

  1. Toggling either sidebar (left timeline, right inspector) is laggy.
  2. New regression: open → close → open the left sidebar and the timeline content is laid out shifted left, text clipped outside the sidebar bounds (screenshot in conversation: 'meline Analytics', rows cut at the leading edge). Likely the collapse/expand animation leaving a stale content offset/inset or the NSSplitView pane width applied before the outline view relayout.

Acceptance

  • Sidebar toggle animates at frame rate (Release profile: no frame > 16 ms attributable; sample during 10 toggles).
  • open/close/open leaves content exactly at its original inset; XCTest or hosted test asserting the outline's visible rect/inset after the sequence; VM screenshot before/after 3 toggles pixel-compared.
## Report (user, 2026-09-15, desktop build 5b72a45) 1. Toggling either sidebar (left timeline, right inspector) is laggy. 2. New regression: open → close → open the left sidebar and the timeline content is laid out shifted left, text clipped outside the sidebar bounds (screenshot in conversation: 'meline Analytics', rows cut at the leading edge). Likely the collapse/expand animation leaving a stale content offset/inset or the NSSplitView pane width applied before the outline view relayout. ## Acceptance - Sidebar toggle animates at frame rate (Release profile: no frame > 16 ms attributable; sample during 10 toggles). - open/close/open leaves content exactly at its original inset; XCTest or hosted test asserting the outline's visible rect/inset after the sequence; VM screenshot before/after 3 toggles pixel-compared.
Author
Owner

Round-2 findings (user, 2026-09-15): (1) the clip is reproducible by narrowing the WINDOW with the sidebar open — the sidebar content keeps a fixed width and is centred in the narrower pane, clipping both edges; fix = content width follows the pane, window min width = sidebar min + content min, per-Space width memory for both sidebars (settings.json). (2) Toggle lag on both sidebars: profile on Release first (10 toggles under sample), then fix what the trace shows.

Round-2 findings (user, 2026-09-15): (1) the clip is reproducible by narrowing the WINDOW with the sidebar open — the sidebar content keeps a fixed width and is centred in the narrower pane, clipping both edges; fix = content width follows the pane, window min width = sidebar min + content min, per-Space width memory for both sidebars (settings.json). (2) Toggle lag on both sidebars: profile on Release first (10 toggles under sample), then fix what the trace shows.
Author
Owner

Finding (Main, VM sample during 10 sidebar toggles, Debug a2788dc, /tmp/vm/toggle-sample-a2788dc.txt on the VM)

  • Toggle animation: MainSplitVisibilityBridgeView drives NSSplitView.setPosition from a CADisplayLink every frame (0.24 s smoothstep); each frame → NSAnimationManager → NSWindow layoutIfNeeded → full constraint layout of the window tree (≈400 main-thread samples over 10 toggles ≈ 17 % of the animating time in layout alone, plus SwiftUI ViewGraph updates). mailternal uses NavigationSplitView(columnVisibility:) + .animation(MailMotion.sidebarToggle) and the native .toggleSidebar item — one system animation, no per-frame relayout.
  • Idle background churn: while the app sat idle, VaultSpotlightIndex.apply(full:paths:…) (814 samples) and VaultWatcher.scan → emitDiff (566 samples) ran continuously on background threads with getattrlist/stat/lstat. On a 4-core VM that competes with the UI; on the user's machine it is wasted CPU. Separate issue.
## Finding (Main, VM sample during 10 sidebar toggles, Debug a2788dc, /tmp/vm/toggle-sample-a2788dc.txt on the VM) - Toggle animation: MainSplitVisibilityBridgeView drives NSSplitView.setPosition from a CADisplayLink every frame (0.24 s smoothstep); each frame → NSAnimationManager → NSWindow layoutIfNeeded → full constraint layout of the window tree (≈400 main-thread samples over 10 toggles ≈ 17 % of the animating time in layout alone, plus SwiftUI ViewGraph updates). mailternal uses NavigationSplitView(columnVisibility:) + .animation(MailMotion.sidebarToggle) and the native .toggleSidebar item — one system animation, no per-frame relayout. - Idle background churn: while the app sat idle, VaultSpotlightIndex.apply(full:paths:…) (814 samples) and VaultWatcher.scan → emitDiff (566 samples) ran continuously on background threads with getattrlist/stat/lstat. On a 4-core VM that competes with the UI; on the user's machine it is wasted CPU. Separate issue.
Author
Owner

Worker SidebarShell (branch wave19/sidebar-narrow): implemented native NavigationSplitView sidebar toggle path, removed per-frame NSSplitView display-link divider animation, added native tracking separator, pane width persistence in portable settings (sidebar 180...500, inspector 220...500), width-aware sidebar table/header layout, and focused persistence/projection tests. Commits: d0c4b7e (build-mbp evidence exclusion), 1754588 (feature). Verification: git diff --check passed; app build deferred to shared queue (EditorClickImage → TabsShell → BlockDrop → SidebarShell). Hosted App tests remain unreliable per project notes; no VM evidence captured by this worker.

Worker SidebarShell (branch wave19/sidebar-narrow): implemented native NavigationSplitView sidebar toggle path, removed per-frame NSSplitView display-link divider animation, added native tracking separator, pane width persistence in portable settings (sidebar 180...500, inspector 220...500), width-aware sidebar table/header layout, and focused persistence/projection tests. Commits: d0c4b7e (build-mbp evidence exclusion), 1754588 (feature). Verification: git diff --check passed; app build deferred to shared queue (EditorClickImage → TabsShell → BlockDrop → SidebarShell). Hosted App tests remain unreliable per project notes; no VM evidence captured by this worker.
Author
Owner

Follow-up: package build passed on agents@mbp with warnings only; focused PortableSettingsStoreTests/testLayoutWidthsPersistAsIndependentPortableLeaves passed (1 executed, 0 failures). Corrected AppKit compile issue (NSTableView has no minSize/maxSize), amended feature commit to 466a1b1, then app build passed: BUILT_APP=/Users/agents/Developer/Worktrees/sidebar-narrow/App/build/Build/Products/Debug/Calternal.app. PortableSettingsRuntimeCoordinator filter was not in the Swift package target (0 tests matched; not counted as pass). VM checker attempted after taking sidebar-narrow lease, but vmfast became unreachable (SSH exit 255 / No route to host), so no CUA PASS lines/screenshots; lease release also could not connect.

Follow-up: package build passed on agents@mbp with warnings only; focused PortableSettingsStoreTests/testLayoutWidthsPersistAsIndependentPortableLeaves passed (1 executed, 0 failures). Corrected AppKit compile issue (NSTableView has no minSize/maxSize), amended feature commit to 466a1b1, then app build passed: BUILT_APP=/Users/agents/Developer/Worktrees/sidebar-narrow/App/build/Build/Products/Debug/Calternal.app. PortableSettingsRuntimeCoordinator filter was not in the Swift package target (0 tests matched; not counted as pass). VM checker attempted after taking sidebar-narrow lease, but vmfast became unreachable (SSH exit 255 / No route to host), so no CUA PASS lines/screenshots; lease release also could not connect.
Author
Owner

Worker: ShellFinish
Worktree/branch: /home/kayg/Developer/calternal-apple/.worktrees/sidebar-narrow (wave*/sidebar-narrow)
State: VM gate queued second behind EditorFinish. Added the required real-window resize assertion to Scripts/vm/sidebar_toggle_check.py in commit 554d5ac: drag the open-sidebar right edge near 1917 px to 1250 px and back; compare header/day/row leading-x signatures with explicit no-leading-edge-clip PASS output. The existing three shortcut and three palette cycles remain covered.
Validation so far: python3 -m py_compile Scripts/vm/sidebar_toggle_check.py passed. Next action: take the VM lease after EditorFinish releases it, deploy the already-built app, run this check, collect screenshots/MP4, then capture sample Calternal 6 through 10 300-ms toggles.

Worker: ShellFinish Worktree/branch: /home/kayg/Developer/calternal-apple/.worktrees/sidebar-narrow (wave*/sidebar-narrow) State: VM gate queued second behind EditorFinish. Added the required real-window resize assertion to Scripts/vm/sidebar_toggle_check.py in commit 554d5ac: drag the open-sidebar right edge near 1917 px to 1250 px and back; compare header/day/row leading-x signatures with explicit no-leading-edge-clip PASS output. The existing three shortcut and three palette cycles remain covered. Validation so far: `python3 -m py_compile Scripts/vm/sidebar_toggle_check.py` passed. Next action: take the VM lease after EditorFinish releases it, deploy the already-built app, run this check, collect screenshots/MP4, then capture `sample Calternal 6` through 10 300-ms toggles.
Author
Owner

Worker: ShellFinish
Worktree/branch: /home/kayg/Developer/calternal-apple/.worktrees/sidebar-narrow (wave*/sidebar-narrow)
State: implementation corrected; final VM evidence blocked by an unrelated build error.

VM investigation:

  • Deployed the prior built app and ran python3 Scripts/vm/sidebar_toggle_check.py.
  • The launch initially crashed with an unbounded AppModel.sidebarWidth observer recursion. VM crash report /Users/lume/Library/Logs/DiagnosticReports/Calternal-2026-09-15-101442.ips shows 14,928 recursive AppModel.sidebarWidth.setter frames on the main thread. Commit bddabb5 fixes both sidebar and inspector normalization so an already-normal value is not self-assigned.
  • After rebuilding bddabb5, the real 1917 px → 1250 px resize reproduced the reported clipped-leading-edge defect. Screenshot: /tmp/sidebar-toggle-check/resize-narrow.png (captured locally from the VM). The existing width persistence handler was treating live window resize notifications as user divider changes, then applying the transient sidebar width. Commit 739ded1 excludes layoutWindow.inLiveResize from split-width persistence. It also makes the VM resize check restore the window before returning and uses actual 2x AppKit-to-desktop coordinates.

Build evidence:

  • bddabb5: Scripts/build-mbp.sh sidebar-narrow app passed; BUILT_APP=/Users/agents/Developer/Worktrees/sidebar-narrow/App/build/Build/Products/Debug/Calternal.app.
  • 739ded1: required rebuild failed before linking on an unrelated Swift 6 compiler error in Sources/CalternalStore/VaultIndex.swift:2046: sending 'statement' risks causing data races [#RegionIsolation::SendingRisksDataRace]. This source is outside #29's changed files. Therefore no honest final VM PASS, toggle sample, screenshots, or MP4 can be claimed for 739ded1.

VM lease has been released (pkill -x Calternal; rm -f ~/Apps/.lease) and the next lane was notified. Next action after the unrelated build failure is resolved: rebuild 739ded1, deploy, run Scripts/vm/sidebar_toggle_check.py, then collect the required 10-toggle sample Calternal 6 evidence.

Worker: ShellFinish Worktree/branch: /home/kayg/Developer/calternal-apple/.worktrees/sidebar-narrow (wave*/sidebar-narrow) State: implementation corrected; final VM evidence blocked by an unrelated build error. VM investigation: - Deployed the prior built app and ran `python3 Scripts/vm/sidebar_toggle_check.py`. - The launch initially crashed with an unbounded `AppModel.sidebarWidth` observer recursion. VM crash report `/Users/lume/Library/Logs/DiagnosticReports/Calternal-2026-09-15-101442.ips` shows 14,928 recursive `AppModel.sidebarWidth.setter` frames on the main thread. Commit bddabb5 fixes both sidebar and inspector normalization so an already-normal value is not self-assigned. - After rebuilding bddabb5, the real 1917 px → 1250 px resize reproduced the reported clipped-leading-edge defect. Screenshot: `/tmp/sidebar-toggle-check/resize-narrow.png` (captured locally from the VM). The existing width persistence handler was treating live window resize notifications as user divider changes, then applying the transient sidebar width. Commit 739ded1 excludes `layoutWindow.inLiveResize` from split-width persistence. It also makes the VM resize check restore the window before returning and uses actual 2x AppKit-to-desktop coordinates. Build evidence: - bddabb5: `Scripts/build-mbp.sh sidebar-narrow app` passed; `BUILT_APP=/Users/agents/Developer/Worktrees/sidebar-narrow/App/build/Build/Products/Debug/Calternal.app`. - 739ded1: required rebuild failed before linking on an unrelated Swift 6 compiler error in `Sources/CalternalStore/VaultIndex.swift:2046`: `sending 'statement' risks causing data races [#RegionIsolation::SendingRisksDataRace]`. This source is outside #29's changed files. Therefore no honest final VM PASS, toggle sample, screenshots, or MP4 can be claimed for 739ded1. VM lease has been released (`pkill -x Calternal; rm -f ~/Apps/.lease`) and the next lane was notified. Next action after the unrelated build failure is resolved: rebuild 739ded1, deploy, run `Scripts/vm/sidebar_toggle_check.py`, then collect the required 10-toggle `sample Calternal 6` evidence.
Author
Owner

Worker: ShellFinish
Worktree: /home/kayg/Developer/calternal-apple/.worktrees/sidebar-narrow
Update: committed the host-wide Swift 6.4 compatibility fix as 912b442 (VaultIndex: Swift 6.4 region isolation). Started the required final app rebuild with Scripts/mbp-slots.sh reporting builds=0 rsync=0; the invoking build script timed out after 120 seconds while remote xcodebuild processes remained active. Subsequent slot checks report builds=5 rsync=0; I did not terminate shared build-host processes. The installed sidebar artifact timestamp remains older than this final build.

VM is currently held by EditorFinish. Final #29 VM validation remains pending a completed 739ded1+912b442 artifact and a queue handoff: resize check, shortcut/palette toggles, 10-toggle sample, screenshots, and MP4 are not yet claimed.

Worker: ShellFinish Worktree: /home/kayg/Developer/calternal-apple/.worktrees/sidebar-narrow Update: committed the host-wide Swift 6.4 compatibility fix as 912b442 (`VaultIndex: Swift 6.4 region isolation`). Started the required final app rebuild with `Scripts/mbp-slots.sh` reporting `builds=0 rsync=0`; the invoking build script timed out after 120 seconds while remote xcodebuild processes remained active. Subsequent slot checks report `builds=5 rsync=0`; I did not terminate shared build-host processes. The installed sidebar artifact timestamp remains older than this final build. VM is currently held by EditorFinish. Final #29 VM validation remains pending a completed 739ded1+912b442 artifact and a queue handoff: resize check, shortcut/palette toggles, 10-toggle sample, screenshots, and MP4 are not yet claimed.
Author
Owner

Worker: ShellFinish
Worktree: /home/kayg/Developer/calternal-apple/.worktrees/sidebar-narrow
State: final sidebar VM gate passed.

Build: Scripts/build-mbp.sh sidebar-narrow app passed for commit 12ff9f1. BUILT_APP=/Users/agents/Developer/Worktrees/sidebar-narrow/App/build/Build/Products/Debug/Calternal.app.

VM evidence (real deployed app): python3 Scripts/vm/sidebar_toggle_check.py passed all required geometry/toggle checks. The script performed the physical desktop right-edge drag from approximately 1917 px to 1250 px and back, using the actual clamped edge for restoration. Header and first row leading-x stayed exactly constant at {header: 30, row-1: 70} for wide, narrow, and restored states. It then passed all three shortcut and all three command-palette toggle cycles with that same signature and no leading-edge clip.

Artifacts: /tmp/sidebar-toggle-check/resize-baseline.png, resize-narrow.png, resize-restored.png, shortcut/palette screenshots, and /tmp/sidebar-toggle-check/resize-evidence.mp4.

Performance evidence: executed 10 Cmd-Option-S toggles at 300 ms while sample Calternal 6 ran. Main thread was predominantly in AppKit event waiting (4704/4733 samples); display-link/layout frames in the sample are AppKit’s _NSDisplayLinkForwarder and NSWindow layoutIfNeeded, with no Calternal display-link or per-frame layout function in their call chains. VM lease released with pkill -x Calternal; rm -f ~/Apps/.lease.

Worker: ShellFinish Worktree: /home/kayg/Developer/calternal-apple/.worktrees/sidebar-narrow State: final sidebar VM gate passed. Build: `Scripts/build-mbp.sh sidebar-narrow app` passed for commit 12ff9f1. `BUILT_APP=/Users/agents/Developer/Worktrees/sidebar-narrow/App/build/Build/Products/Debug/Calternal.app`. VM evidence (real deployed app): `python3 Scripts/vm/sidebar_toggle_check.py` passed all required geometry/toggle checks. The script performed the physical desktop right-edge drag from approximately 1917 px to 1250 px and back, using the actual clamped edge for restoration. Header and first row leading-x stayed exactly constant at `{header: 30, row-1: 70}` for wide, narrow, and restored states. It then passed all three shortcut and all three command-palette toggle cycles with that same signature and no leading-edge clip. Artifacts: `/tmp/sidebar-toggle-check/resize-baseline.png`, `resize-narrow.png`, `resize-restored.png`, shortcut/palette screenshots, and `/tmp/sidebar-toggle-check/resize-evidence.mp4`. Performance evidence: executed 10 Cmd-Option-S toggles at 300 ms while `sample Calternal 6` ran. Main thread was predominantly in AppKit event waiting (4704/4733 samples); display-link/layout frames in the sample are AppKit’s `_NSDisplayLinkForwarder` and `NSWindow layoutIfNeeded`, with no Calternal display-link or per-frame layout function in their call chains. VM lease released with `pkill -x Calternal; rm -f ~/Apps/.lease`.
Author
Owner

Overnight (Main) review fixes on the merged build: persistCurrentSplitWidths never assigned model.sidebarWidth (width persistence was inert) — fixed; window minimum now follows the current sidebar width including collapsed (previously ratcheted up to sidebar+320 and never came back down); split-resize notifications no longer walk the whole view tree per frame; /tmp/vm/sidebar-geometry.log writer and orphaned recordAncestorFrames removed.

Overnight (Main) review fixes on the merged build: `persistCurrentSplitWidths` never assigned `model.sidebarWidth` (width persistence was inert) — fixed; window minimum now follows the current sidebar width including collapsed (previously ratcheted up to sidebar+320 and never came back down); split-resize notifications no longer walk the whole view tree per frame; `/tmp/vm/sidebar-geometry.log` writer and orphaned `recordAncestorFrames` removed.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
kayg/calternal-macos#29
No description provided.