Skip to content

✨ feat(connections): Escape closes the connection form (#118) - #140

Merged
Cemoche merged 5 commits into
mainfrom
issue-118-escape-form
Oct 21, 2026
Merged

Cemoche merged 5 commits into
mainfrom
issue-118-escape-form

Conversation

@Cemoche

@Cemoche Cemoche commented Oct 21, 2026

Copy link
Copy Markdown
Owner

Closes #118

Summary

Escape closes the connection form, like ←. It goes through App's existing closeForm, so a form with edits first asks "Discard changes to this connection?". When it closes, the focus goes back to the selected row, or to the search box if no row is selected.

  • Where it lives: a window keydown listener in ConnectionForm, registered only while the form is on screen. A form hidden behind a workspace has no listener. No keymap action is added: this is the form's own fixed Escape, like a dialog's.
  • When it acts: only when the focus is inside the form or on the body. It ignores the press when:
  • Fields with suggestions (Group, SSH host): after typing, ↓/↑ or a click, the first Escape is left to the list. WebKit gives no "list open" signal. At worst one extra Escape is needed, and an edited form always asks before discarding.
  • The connection dialogs take their Escape (preventDefault): Import from URL, the host-key and secret prompts, and Import. So one press never closes both a dialog and the form, whatever order the listeners run in.
  • ConfirmDialog ignores Escape repeats: a held key acts once. Holding Escape on an edited form opens the question and keeps it open.
  • Import from URL… puts the focus back on its button when it closes.
  • Tests:
    • each field type, the modifier / repeat / IME / handled cases, focus outside the form, an inactive form, each dialog, the tooltip first, the suggestion fields;
    • App-level: a clean form, a dirty form (Escape in the question, Cancel, Discard), a hidden form, and an app modal (Settings, palette) over the form;
    • dialogs: Escape is defaultPrevented;
    • ConfirmDialog: repeats.
  • Docs: amendment [Refonte UI] Escape closes the connection form #118 in spec §2.4, and the manual check note.

No Rust change.

How it was tested

$ pnpm exec vitest run --maxWorkers=1     # 109 files, 1394 tests passed
$ pnpm exec tsc --noEmit                  # clean

Manual check list

  1. Edit a saved connection without changing anything. Press Escape in Name: the list is back at once and the focus is on that connection's row.
  2. Press Ctrl+N with no row selected, then Escape: the list is back with the search focused.
  3. Escape from:
    • a closed select (Driver);
    • the Over SSH checkbox;
    • a colour swatch, pressed twice: the first Escape hides the swatch's tooltip shown by keyboard focus, the second closes the form;
    • after a click on the empty area beside the form.
      Each closes the clean form.
  4. Change the Name and press Escape. "Discard changes to this connection?" appears.
    • Escape in it: the question closes, the edit stays, the cursor is back in Name.
    • Escape again, then Discard: the list is back.
  5. Open the Driver select with the mouse, then press Escape: only the popup closes and the form stays.
  6. Import from URL…, then Escape: only the dialog closes, the focus is on Import from URL…, and the next Escape closes the form.
  7. Delete, then Escape: only the question closes, and the focus is on Delete.
  8. Test on an SSH connection with an unknown host key, then Escape at the prompt: only the prompt closes.
  9. In Group, with at least one other connection that has a group, type its first letter. The suggestions show.
    • The first Escape closes the suggestions.
    • The second asks to discard, since the form is now edited.
  10. Over SSH with ~/.ssh/config aliases: the same as step 9 in SSH host.
  11. CA… opens the native picker. Escape there closes only the picker.
  12. Leave an edited form for a workspace and press Escape there. Nothing about the form happens, and the edits are still there on return.
  13. With the focus on the toolbar or the open connections column while the form shows, press Escape: the form stays.
  14. Hold Escape down on an edited form: the discard question opens and stays open (a held key acts once).

Checklist

  • pnpm test green
  • pnpm lint green (tsc; no Rust change, clippy in CI)
  • pnpm test:rust green (not applicable: no src-tauri/ change)
  • No secret, token, real password or private key in the diff
  • User-visible strings in src/lib/strings.ts
  • Commits follow <emoji> <type>(<scope>): <description>

🤖 Generated with Claude Code

Cemoche and others added 5 commits October 21, 2026 05:47
Escape in the form, or with the focus on the page, returns to the list
through the same "Discard changes to this connection?" question as ←.
A dialog, a shown tooltip, an IME composition or a field's suggestion
list keeps its own Escape; the form hidden behind a workspace never
reacts. The URL import dialog gives the focus back to its button.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…e form (#118)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…e in a confirmation (#118)

The URL import, host key, secret and import dialogs prevent the default
of their Escape, as ConfirmDialog does: in WebKit a dialog unmounted
between listeners would otherwise let the connection form behind close
on the same press. ConfirmDialog ignores Escape's repeats, so a held key
no longer opens and cancels the discard question at once.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… app modals over the form (#118)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…118)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@Cemoche
Cemoche merged commit 49f6acd into main Oct 21, 2026
6 checks passed
@Cemoche
Cemoche deleted the issue-118-escape-form branch October 21, 2026 04:09
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.

[Refonte UI] Escape closes the connection form

1 participant