Skip to content

client: a click made during the Settings exit keeps its focus - #2274

Draft
HugoXK wants to merge 1 commit into
ThinkFlowLab:mainfrom
HugoXK:dev/4-p472-settings-focus-restore
Draft

HugoXK wants to merge 1 commit into
ThinkFlowLab:mainfrom
HugoXK:dev/4-p472-settings-focus-restore

Conversation

@HugoXK

@HugoXK HugoXK commented Nov 3, 2026

Copy link
Copy Markdown
Contributor

Fixes #2270
Written-by: Dev4
Owner: Dev4
Reviewer: Birfy
Claim-Id: a603143791a442c5a147c232dc187b76
Branch: dev/4-p472-settings-focus-restore
Base: 5008116
Tree: 1a6fa3be9ebeadc91c31141a463439fb5c81c5cc
Verified commit: 3762107
Pushed head: 3762107

Scope

#2262 made the Settings dialog hand focus back to its opener in useDialogFocus's unmount cleanup, unconditionally. The dialog stays mounted for DIALOG_EXIT_MS (160 ms) with data-leaving and pointer-events: none on the layer, so a click in that window passes through to the page behind it — usually the composer — and the cleanup then took focus away from it.

The cleanup in core/src/client/overlay-hooks.js now restores focus only while the dialog still holds it (document.activeElement is the dialog node or inside it), or while nothing does (no active element, document.body, or a node the browser has disconnected). A quiet close still hands focus back to the opener exactly as #2262 shipped; a close the user has already walked away from leaves focus where the user put it.

core/test/dialog-focus.test.js gains the case that was missing: open, move focus to a composer node during the exit, unmount, and assert the composer still holds focus and the opener received no focus call. The existing unmount case (a quiet close returns focus to the opener) stays as it is, so the guard cannot turn into a deletion.

docs/subsystems/core-client.md changes one line because arch-docs treats core/src/client/** as this subsystem's owned path.

Files

  • core/src/client/overlay-hooks.js — the guard in the cleanup.
  • core/test/dialog-focus.test.js — the new case, and the existing case kept.
  • docs/subsystems/core-client.md — one line, the focus hand-back rule.
  • changelog.d/2270-settings-focus-restore.fixed.md — the changelog fragment.
  • core/client.js — generated by npm run build.
  • patches/ds-bot/0003-flybot-api-client.patch, patches/ds-bot/0008-client-bundle.patch, patches/ds-bot/files/test/dialog-focus.test.js — generated by node scripts/ds-bot-patches.mjs generate.

Readings attached at the final tip; this draft reserves the issue and requests no review.

The dialog lingers for DIALOG_EXIT_MS (160 ms) with `pointer-events: none` on the
leaving layer, so a click there reaches the page behind it. The unmount then put
focus back on the opener unconditionally, taking it away from the element the user
had just focused. Restore only while the dialog still holds focus (or nothing does).

Fixes ThinkFlowLab#2270
Owner: Dev-4
Written-by: Dev-4
Reviewer: Birfy
Base: 5008116
@github-actions github-actions Bot added the risk:T1 Risk tier T1 (client, tests, generated files), set by the controller from the diff label Nov 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk:T1 Risk tier T1 (client, tests, generated files), set by the controller from the diff

Projects

None yet

Development

Successfully merging this pull request may close these issues.

client: closing Settings pulls focus back 160 ms later, over a click the user made

1 participant