Drive the connection manager from the keyboard

The manager had only Esc and the scale keys: its list took one Tab stop
per row with no arrows, a stack's rename / delete / open-in-tabs buttons
existed only on hover, and no action had a key.

- Commands (the manager keymap scope, remappable like the rest): new
  connection with focus in Name, new stack, save, connect — or open the
  focused stack in tabs — delete the focused row, rename the focused
  stack, import from WinSCP, close the window.
- The list: up/down/Home/End move focus between rows (focus only:
  loading a connection would discard a half-edited form), Enter opens the
  focused connection, left/right collapse and expand a stack, and a
  stack's actions show while the keyboard is in its row.
- Enter in a form field connects; Esc leaves a field before it closes the
  window; Tab is walked by hand (WKWebView skips buttons and radios); focus
  comes back after a dialog and never stays lost on <body>.
- Tooltips show the keys; the Settings → Keyboard fixed-key list gains the
  manager's.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-10-05 14:59:37 +02:00
co-authored by Claude
parent 8f8f230711
commit e28314054f
12 changed files with 262 additions and 28 deletions
+14
View File
@@ -121,6 +121,20 @@ main's `ConnectionsService` reloads; a reload-retry in `App.findConnection`
covers the save→connect race. `setAlwaysOnTop` is deliberately NOT used (it
would float over editor windows).
Keyboard (the `manager` keymap scope): ⌘N new connection (focus lands in
Name), ⇧⌘N new stack, ⌘S save, ⌘↩ connect — or, on a focused stack row, open
it in tabs — ⌘⌫ / Del delete the focused row (with a confirm), F2 rename the
focused stack, ⌘O import, ⌘W close. The list's rows are real buttons
(`data-row`; `data-stack` / `data-conn` say what they are): ↑ ↓ Home End move
FOCUS only — loading a connection would replace a half-edited form without
asking — Enter opens the focused connection in the form, ← / → collapse and
expand a stack (← on a connection climbs to its stack), and a stack's
hover-only actions also show while the keyboard is in its row. Enter in a form
field = Connect; Esc leaves a field first, then closes the window. Focus
returns where it was after a dialog (`focusin` memory + the FocusService
tick) and falls back to the edited connection's row whenever it drops to
`<body>`.
### Settings window (`src/bun/settings-window.ts` + `ui/src/app/skins/shadlike/settings-window/`)
Single instance, centered over main, **not modal**: every control is a plain