Skip to content

web UI: closing a modal sheet drops keyboard focus to <body> #1074

Description

@edwin-zvs

Closing a modal sheet in the web UI hides it but never returns keyboard focus to whatever opened it, so focus falls back to <body> and the next keystroke goes nowhere.

Repro

  1. Open the web UI, select a session.
  2. Open the Rename sheet (row context menu → Rename).
  3. Press Escape, or click Cancel, or click the backdrop.
  4. Inspect document.activeElement<body>.
  5. Type — nothing reaches the terminal, the composer, or the session list.

Same shape was observed after creating a session and after switching to the chat view: focus lands on <body> rather than the surface the user is now looking at.

Cause

closeRenameDialog() (crates/daemon/assets/index.html, ~line 14551 @ 4c1459b) resets the sheet's visibility, error, and dataset but has no focus-restore step. The close-session and settings sheets follow the same pattern. openRenameDialog() correctly moves focus into the sheet, so the focus round trip is one-way.

Expected

Every dismissible overlay records the element that had focus when it opened and restores it on close. Where the invoker is gone (row deleted, list re-rendered), fall back to focusActiveSurface() so the caret lands on the terminal or composer for the current view rather than on <body>.

Notes

  • focusActiveSurface() already exists and encodes the right per-mode target; the fix is mostly wiring, not new policy.
  • On touch devices, prefer restoring to the composer with a visible focus ring rather than silently focusing the terminal.

Acceptance criteria

  • After closing Rename / Settings / Close-session via Escape, Cancel, or backdrop click, document.activeElement is the invoking control (or the active surface if the invoker is gone) — never <body>.
  • After creating a session and after switching views, typing immediately reaches the expected surface with no intervening click.

Found during a power-user UX audit of the TUI and web UI.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions