Skip to content

fix(ui): a click below a list's rows and on a welcome row acts at once - #79

Merged
hans-fischer merged 5 commits into
mainfrom
fix/table-tap-at-once
Oct 22, 2026
Merged

hans-fischer merged 5 commits into
mainfrom
fix/table-tap-at-once

Conversation

@hans-fischer

Copy link
Copy Markdown
Contributor

A click on the empty area below a list's rows (GW1) closed the drawer about a second after the click, while × and Escape closed it at once (the owner's alpha walk of 2026-10-22, AW12). A click on a cluster row of the welcome page waited the same way before it connected.

Cause

  • Fyne's GLFW driver holds every tap on a fyne.DoubleTappable for the double-click interval before it calls Tapped or DoubleTapped (v2.8.2, internal/driver/glfw/window.go, mouseClickedHandleTapDoubleTap and waitForDoubleTap).
  • On macOS that interval is NSEvent.doubleClickInterval, 0.5 s by default.
  • The list's table was such a widget, for the double click on a header separator that fits a column, so the click below the rows waited. Rows and headers were not held, since their cells take their own taps.
  • The welcome page's cluster rows were such widgets too, although their double click did the same as a click.

Fix

  • The table counts the separators' double click itself, as the tab bar and the navigator already do: two clicks on the same column's separator within doubleClickTime (500 ms). It is no longer a fyne.DoubleTappable, so every click on it acts when the button is released.
  • The welcome rows take clicks only. A second click before the engine answered, or on a cluster the window shows connecting, connects nothing. The page rebuilds its rows while connecting, so this guard lives in the page (welcome.go, pending).
  • Clicks still held, on purpose: the sync picker's rows and a log tab's "Load older lines" row, where a double click has its own meaning.
  • The cause and the choices are recorded in D-106's GW1 table. G16, ui-parity and architecture are updated.

Tests

  • TestListClicksAreNotHeld: a row, a header, a header separator (whose double click fits Name) and the area below the rows are each clicked as Fyne's driver finds the object under the pointer. A target that is a fyne.DoubleTappable fails the test. Fails before the change.
  • TestDoubleClickSeparatorFitsColumn: two taps instead of DoubleTapped. One click, or two clicks 500 ms apart, fit nothing. Fails before the change.
  • TestWelcomeRowConnectsOnce: the row is not held, a double click connects once, and a click on a cluster the window shows connecting connects nothing. Fails before the change.
  • make test-ui, lint, make cyclo and go run ./hack/parity pass. No render changed. Not seen in a real window.

…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.
The owner's alpha walk (AW12): a click below a list's rows closed the
drawer about a second later, × and Escape at once. Fyne's driver holds
every tap on a fyne.DoubleTappable for the double-click interval before
it calls Tapped (internal/driver/glfw/window.go,
mouseClickedHandleTapDoubleTap; NSEvent.doubleClickInterval on macOS,
0.5 s by default), and the list's table was one for its header
separators' double click, which fits a column.

The table now counts that double click itself, as the tab bar and the
navigator do (doubleClickTime and the tab bar's clock), and is no
DoubleTappable: every click on it acts at its release. Rows and headers
were not held: their cells take their own taps.

TestListClicksAreNotHeld clicks a row, a header, a header separator and
the area below the rows as the driver finds the object under the pointer
and fails on a DoubleTappable target; it and the reworked
TestDoubleClickSeparatorFitsColumn fail before the change. D-106's GW1
table records the cause and the lead's choice; G16, ui-parity and
architecture follow.
The welcome page's cluster rows were a fyne.DoubleTappable, their double
click doing what a click does, so Fyne's driver held every click on them
for the double-click interval (AW12's cause, found on the table first).
The row takes clicks only now.

Without the hold, a double click's second click reaches the row again,
which the page has rebuilt by then for the cluster connecting: a second
cluster.connect would join the run under way but end the first one's
wait with errConnectInBackground, an error toast naming another cluster,
and a login program not allowed yet would be reviewed twice. The page
therefore does nothing for a cluster whose connect it began and that has
not returned (pending, from before the review or the dispatch to the
engine's answer) or that the window shows connecting.

TestWelcomeRowConnectsOnce fails on the old row (held) and on a row
without the page's guard (connected twice). D-106 records the choice
and the clicks left held (the sync picker's rows, the log tab's head
row) with why; G16's AW12 entry follows.
@hans-fischer
hans-fischer force-pushed the fix/table-tap-at-once branch from 10540a5 to db5a47e Compare October 22, 2026 15:58
@hans-fischer
hans-fischer merged commit b684b5b into main Oct 22, 2026
3 of 25 checks passed
@hans-fischer
hans-fischer deleted the fix/table-tap-at-once 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