You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
perf: cut tab/workspace switch latency and background churn (#108)
* app: cut tab and workspace switch latency
Three sources of switching lag, measured against the live app (raw tmux
select-window is ~18ms; Mori took 110-160ms end to end before the tmux
window actually flipped):
- selectWindow/selectPane issued the tmux command in a main-actor Task,
which queued behind the selection-triggered UI re-render (~60-100ms).
The command is now Task.detached and fired before any state mutation.
- selectWorktree serialized terminal attach behind a git status, a
list-sessions round trip, and a full tmux rescan. When the last poll
(<=5s) saw the session alive, attach now happens immediately and the
reconcile chain runs behind it.
- The terminal surface cache held only 3 surfaces, so cycling through
more than three workspaces destroyed and respawned a login shell +
tmux attach on every switch. Raised to 10.
* tmux: collapse the runtime scan into a single list-panes -a
scanAll ran 1 + sessions + windows subprocess invocations every 5s poll
(dozens of SSH round trips for remote endpoints). A single list-panes -a
row per pane carries session and window context; parseScan groups rows
back into the session tree. tmux guarantees every session has >=1 window
and every window >=1 pane, so grouping loses no nodes. Window currentPath
keeps list-windows semantics by resolving from the active pane.
* ui: stop per-frame agent-pulse renders and redundant tab rebuilds
The sidebar's agent working icon used a SwiftUI repeatForever opacity
animation, which re-rendered the hosting view's display list every frame
for as long as any agent was working (~12% of the main thread at idle,
sampled). It now pulses via a repeating CABasicAnimation on the layer,
which runs on the render server.
TerminalTabsBarView's observation fires for any runtimeWindows change
(every poll); it tore down and recreated every tab NSView each time. It
now snapshots what it last rendered and skips rebuilds when the strip's
windows and selection are unchanged.
* docs: changelog entries for switching performance work
Copy file name to clipboardExpand all lines: CHANGELOG.md
+5Lines changed: 5 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -16,6 +16,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
16
16
-**iOS (MoriRemote)**: The workspace sidebar gains a bottom quick-filter field (cmd+p style) — type to narrow projects, sessions, branches, and windows by name, title, or path. Matching a session keeps its whole group; otherwise only matching windows are shown. Thumb-reachable at the bottom edge, and it rides above the keyboard.
17
17
-**iOS (MoriRemote)**: The keyboard-dismiss button is now pinned at the far left of the accessory key bar, outside the scrollable key row — it used to sit at the row's right end, forcing a swipe to the very end just to put the keyboard away.
18
18
19
+
### ⚡ Performance
20
+
21
+
-**macOS**: Tab and workspace switching is much snappier. The `tmux select-window` call no longer queues behind the selection-triggered UI re-render (~60–100ms saved per tab switch), switching to a workspace whose session was seen alive by the last poll attaches the terminal immediately instead of waiting for a git branch check plus a full tmux rescan, and the terminal surface cache grew from 3 to 10 so cycling through more than three workspaces stops destroying and respawning shells.
22
+
-**macOS**: Less background churn. The 5-second runtime scan is now a single `tmux list-panes -a` invocation instead of one subprocess per session and window (one SSH round trip instead of dozens for remote workspaces), the terminal tab strip only rebuilds when the windows it shows actually change, and the sidebar's agent "breathing" icon pulses via Core Animation instead of re-rendering the SwiftUI tree every frame while an agent is working.
23
+
19
24
### 🐛 Bug Fixes
20
25
21
26
-**iOS (MoriRemote)**: Switching to a tmux window no longer lands you in a stuck pane showing `(repeat) N` at the bottom. Panes that had been scrolled stay in tmux copy-mode across window switches, where digit keys hit tmux's default `(repeat)` command-prompt binding and swallow input; sidebar switches now cancel copy-mode on the target pane so it's immediately typeable.
0 commit comments