Skip to content

fix(renderer): focus, status and shortcut correctness - #308

Merged
maxthomas95 merged 2 commits into
mainfrom
fix/renderer-workflow-20261109
Nov 10, 2026
Merged

maxthomas95 merged 2 commits into
mainfrom
fix/renderer-workflow-20261109

Conversation

@maxthomas95

Copy link
Copy Markdown
Owner

Summary

Seven session-workflow fixes from the 2026-11-09 review. Renderer and docs only: no main-process, IPC, persistence-schema or PTY changes.

  • Focus can no longer rest on a hidden pane. The split-layout reducer drops a maximize whenever focus moves to a pane it hides, and maximizing a pane focuses it (Canvas already behaved this way). Previously a sidebar click, a notification click, Ctrl+1..9 or Ctrl+Up/Down could leave the active session pointing at an invisible pane, so keystrokes went to the visible session while Ctrl+W and Session → Stop/Remove acted on the hidden one.
  • Resume previous conversation keeps launch settings. It now passes the source session's launch snapshot (profile, env, flags) and Helm setting, as Duplicate does. Before, a session launched under an API-key or model profile resumed under defaults.
  • Stopped and dead are distinct. A clean stop is dim gray; a failure is red and reads "Failed". Applies to the sidebar dot and label, the pane header, the session switcher and the ended-pane overlay ("Session ended" vs "Session exited with an error"). This is what sessions.md already documented.
  • Stop asks first when work would be lost. Ctrl+W and Session → Stop Session show the existing confirm dialog when the active session is starting, running or blocked on a permission prompt. A session resting at its prompt stops at once. The default chord is unchanged, and the sidebar's per-session Stop stays immediate.
  • Ctrl+1..9 select the Nth session in sidebar order, through the same path as a Ctrl+P pick. They used to index visible layout leaves, so Ctrl+5..9 could never work and Ctrl+2 did nothing in a single pane. Sessions inside collapsed groups still count.
  • Sidebar width has one definition. The drag handle and the rendered sidebar share 180–400 px bounds (the CSS used to cap at 320 while the handle allowed 400). A dragged width is saved under the config key sidebarWidth (one write per drag) and wins over the density default.
  • Docs drift. Settings opens from File, not View; GIF and Pip are sidebar panels opened from View, not Appearance settings; diagnostics export is not listed under Integrations; the sidebar footer list is complete; the README no longer claims regex terminal search.

Supporting changes: the sidebar ordering rules moved into pure functions (utils/sidebar-order.ts) used by both the render path and the switch shortcut; a repeated SET_FOCUS on the focused pane is now a no-op, so a terminal mousedown no longer re-renders the app.

Test plan

  • npx tsc --noEmit
  • npx eslint on every touched file
  • npx vitest run — 201 files / 2333 tests pass. One failure, src/main/usage/remote-command.test.ts "runs the quoted probe through a real POSIX shell", is the known Windows-host real-shell case and is unrelated.
  • New unit tests: layout reducer focus/maximize rules, sidebar ordering, sidebar width, ended-state presentation, isSessionWorking, pane header and overlay for stopped vs dead
  • Manual: maximize a pane in a 2+ pane split, then click another session in the sidebar, click a desktop notification, and press Ctrl+ArrowDown; each should restore the split and focus the target
  • Manual: Ctrl+W on a running session asks; on a session waiting at its prompt it stops at once; pressing Ctrl+W again while the dialog is open does nothing
  • Manual: Ctrl+1..9 open sessions in sidebar order in single, split and Canvas layouts, including a session not currently in any pane
  • Manual: stop one session cleanly and kill another (non-zero exit); compare dots and labels in the sidebar, pane header and Ctrl+P
  • Manual: drag the sidebar to its widest, restart Tether, confirm the width is kept; switch density and confirm it is still kept
  • Manual: right-click a session launched with a profile → Resume previous conversation...; the new session uses the same profile

Out of scope

  • Changing the default Ctrl+W chord. It still never reaches the terminal, where it means "delete previous word".
  • Confirming the sidebar's per-session Stop.
  • Persisting group collapse state.
  • Remove/restart/undo safety: stacked PR on top of this one.

🤖 Generated with Claude Code

Seven session-workflow fixes from the 2026-11-09 review. None touches
the PTY stream or the main process.

Focus and maximize
- The split-layout reducer now keeps the focused pane on screen: a focus
  that lands on a pane hidden behind a maximized one drops the maximize,
  and maximizing a pane focuses it (as Canvas already does). Before,
  a sidebar click, a notification click, Ctrl+1..9 or Ctrl+Up/Down could
  leave the active session pointing at a hidden pane, so keystrokes went
  to the visible session while Ctrl+W and Session > Stop/Remove acted on
  the hidden one.
- A repeated SET_FOCUS on the already-focused pane is a no-op, so a
  terminal mousedown no longer re-renders the app.

Sessions
- Resume previous conversation keeps the source session's launch
  snapshot (profile, env, flags) and Helm setting, like Duplicate.
- Stopped and dead are distinct again, as the docs describe: a clean
  stop is dim gray, a failure is red and labelled "Failed", in the
  sidebar, the pane header, the session switcher and the ended-pane
  overlay.
- Ctrl+W and Session > Stop Session ask before stopping a session that
  is starting, running or blocked on a permission prompt. A session
  resting at its prompt stops at once, and the default chord is
  unchanged. The sidebar's per-session Stop stays immediate.
- Ctrl+1..9 open the Nth session in sidebar order through the same path
  as a Ctrl+P pick, which is what the action label and docs already
  said. They used to index visible layout leaves, so Ctrl+5..9 could
  never work and Ctrl+2 did nothing in a single pane.

Sidebar
- One definition of the width bounds (180-400 px) for both the drag
  handle and the rendered sidebar; the CSS no longer caps it at 320.
  A dragged width is saved (config key sidebarWidth, one write per
  drag) and wins over the density default.
- The sidebar ordering rules moved into pure functions that the render
  path and the switch shortcut both use.

Docs: Settings opens from File, not View; GIF and Pip are sidebar panels
rather than Appearance settings; diagnostics export is not listed under
Integrations; the sidebar footer list is complete; the README no longer
claims regex terminal search.

Tests: npx tsc --noEmit clean; eslint clean on touched files; vitest
201 files / 2333 tests pass. The one failure,
src/main/usage/remote-command.test.ts "runs the quoted probe through a
real POSIX shell", is the known Windows-host real-shell case and is
unrelated to this change.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
@maxthomas95
maxthomas95 merged commit b2032d1 into main Nov 10, 2026
10 checks passed
@maxthomas95
maxthomas95 deleted the fix/renderer-workflow-20261109 branch November 10, 2026 03:14
@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
66.4% Coverage on New Code (required ≥ 80%)

See analysis details on SonarQube Cloud

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.

1 participant