Skip to content

fix(ui): Escape closes the innermost thing, and a closed dropdown is outlined - #75

Merged
hans-fischer merged 1 commit into
mainfrom
fix/escape-closes-innermost
Oct 22, 2026
Merged

hans-fischer merged 1 commit into
mainfrom
fix/escape-closes-innermost

Conversation

@hans-fischer

@hans-fischer hans-fischer commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Fixes the Escape findings and the dropdown field of the owner's alpha walk (2026-10-22, v0.38.0): AW1 (a closed dropdown has the background's colour), AW2 (an open dropdown's Escape leaves the field focused), AW3 (Escape over the Rollback confirmation closes the drawer instead), AW4 (Escape leaves neither the find bar nor a list's search) and AW19 (Connection Updates does not close with Escape). G16, D-116, D-104.

Cause

  • The window's Escape knew only the palette, the notifications, a settings page and the drawer. Over a dialog it closed the drawer behind it or did nothing. No dialog, framed or Fyne's, had an Escape of its own.
  • Fyne hands a key to the focused widget and calls the window's handler only while none has it. A field, check, slider or dropdown focused by a click kept every Escape.
  • The list's search and the find bar's field handed Escape to Fyne's Entry, which ignores it. D-57's "any other search: Escape clears and closes it" had been built for the navigator's searches only.
  • Fyne's Select draws one plate in the input background, which on a dialog is the dialog's own colour. The entries' outline stood at 1.3–1.45:1.

Fix

  • escape.go: every overlay registers what Escape does over it as it shows. The window's escape runs the top one's, else a settings page, else the drawer. An overlay without a registration takes the key, so nothing behind it closes.
  • Every Fyne dialog goes through sh.showDialog. Framed dialogs hide (their SetOnClosed answers no). Pop-ups, the palette, the notifications, the MCP details and the top bar's menus close.
  • Dialog fields pass Escape on to the dialog's Cancel: fieldEntry, fieldSelectEntry, fieldCheck, fieldSlider, secretEntry, selectField.
  • A list's search is cleared and the table gets the keys. The find bar closes from its fields and from the editor (yamlview.OnEscape); its text stays for the next ⌘F.
  • Escape on an open dropdown's list takes the keyboard off its field.
  • A closed dropdown draws an entry's outline. The field outline token is raised to 2:1 on every surface in both themes; the other hairlines keep the old value as colorHairline.
  • The lead's decisions, open to revision, in D-116 and D-104. G16, ui-parity, usage, architecture, conventions and the design language are updated.

Tests

  • New, each failing before the change: TestEscapeCancelsTheRollbackDialog, TestEscapeOnAnOpenDropdown, TestEscapeOnAnOpenDropdownInPreferences, TestEscapeClosesTheConnectionUpdates, TestEscapeClosesTheFindBar, TestEscapeLeavesTheListSearch, TestEscapeCancelsEveryDialog, TestClosedDropdownHasAnOutline, and the field outline in TestPaletteContrast.
  • TestEveryDialogTakesEscape is a source guard. It fails on a Fyne dialog shown with its own Show or a pop-up not shown through onShown; checked against a reverted connectlog.go and statusfilter.go.
  • Locally: go build ./..., go vet ./internal/ui/..., make test-ui (8 shards), yamlview tests, golangci-lint (0 issues), make cyclo (none above 56), go run ./hack/parity -check.
  • Not seen in a real window.

Renders

The outline token is shared chrome, so every render was drawn once more. 523 PNGs changed:

  • Each was checked in RGB against a fresh render of main, so run-to-run noise is not carried in.
  • Almost all of them change only the list header's search field outline.
  • 479 committed PNGs on main were already stale against main's own render; this brings them current.
  • The README pictures (make showcase) are not redrawn.

Before and after (offscreen render, dark)

Before After
Rollback dialog
Preferences
Create Namespace

…outlined

The owner's alpha walk of 2026-10-22 on v0.38.0 (G16):

- AW3, AW19: the window's Escape knew the palette, the notifications, a
  settings page and the drawer only, so over a dialog it closed the drawer
  behind it or did nothing. Every overlay now registers what Escape does
  over it as it shows (escape.go: onEscape, onShown); the window's escape
  runs the top one's, an overlay without one takes the key. Every Fyne
  dialog is shown through sh.showDialog (Escape is its Dismiss), a framed
  dialog hides (its SetOnClosed answers no), the pop-ups, the palette, the
  notifications, the MCP details and the top bar's menus close.
- Fyne hands a key to the focused widget only: the fields of Cogpit's
  dialogs are types that pass an Escape on (fieldEntry, fieldSelectEntry,
  fieldCheck, fieldSlider, secretEntry), so Escape cancels a dialog
  whatever field has the keyboard.
- AW4: a list's search is cleared and the table gets the keys; the find bar
  closes from its fields and from the editor (yamlview's OnEscape). D-57's
  "any other search" had been the navigator's only.
- AW2: Escape on an open dropdown's list takes the keyboard off the field,
  and a dropdown with the keyboard passes Escape on.
- AW1: a closed dropdown draws an entry's outline; the field outline token
  is raised to 2:1 on every surface in both themes, the wells' and cards'
  edges keep the old value as colorHairline.

TestEveryDialogTakesEscape reads the sources for a dialog or pop-up shown
past the mechanism. D-116 and D-104 record the lead's decisions; G16,
ui-parity, usage, architecture, conventions and the design language say so.
@hans-fischer
hans-fischer force-pushed the fix/escape-closes-innermost branch from 31d152a to 6592c95 Compare October 22, 2026 15:43
@hans-fischer
hans-fischer merged commit 950eaac into main Oct 22, 2026
11 of 25 checks passed
@hans-fischer
hans-fischer deleted the fix/escape-closes-innermost branch October 22, 2026 16:36
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