Palette/sidebar channel switch doesn't focus the terminal (must click to type) #35

Closed
opened 2026-08-26 16:36:05 +01:00 by pedromcaraujo · 0 comments

Symptom

Switching channels via the command palette (Alt+K → Enter, or clicking an entry) leaves keyboard focus off the terminal — the next keystroke goes nowhere and you have to click the terminal before you can type. Switching by clicking the sidebar has the same underlying path.

Diagnosis

It is not a missing focus call — focusTerm() is invoked twice on a palette switch:

  1. closePalette() calls it immediately (web/index.html).
  2. The iframe load handler calls it when the new channel's document loads.

The problem is timing. activate() runs go(name), which sets frame.src and reloads the iframe. focusTerm() retries only at [0, 60, 200, 500] ms, then gives up (done never becomes true because frame.contentDocument.activeElement === ta is never satisfied). On a channel switch the new xterm textarea — and the ttyd websocket it needs — frequently isn't ready inside that 500 ms window, so every retry no-ops and focus is left on <body>. The immediate closePalette() call can also "succeed" against the outgoing document (setting done=true) a beat before navigation replaces it, so focus is then lost with no further retries.

Fix ideas

  • Extend/scale focusTerm()'s retry schedule past ttyd's connect (e.g. add ~900/1500 ms attempts), and don't let a focus that sticks on the old document before navigation count as done.
  • Or drive the focus purely from the new iframe's load (already wired) and make its retry window long enough for ttyd.

Desktop only — focusTerm() is intentionally a no-op on touch (focusing the textarea pops the Android soft keyboard).

Verification

Needs a browser: Alt+K → pick another channel → type immediately without clicking; the keystrokes should reach the shell. Check both an already-connected session and a cold one (slower ttyd connect).

## Symptom Switching channels via the command palette (Alt+K → Enter, or clicking an entry) leaves keyboard focus off the terminal — the next keystroke goes nowhere and you have to click the terminal before you can type. Switching by clicking the sidebar has the same underlying path. ## Diagnosis It is *not* a missing focus call — `focusTerm()` is invoked twice on a palette switch: 1. `closePalette()` calls it immediately (`web/index.html`). 2. The iframe `load` handler calls it when the new channel's document loads. The problem is timing. `activate()` runs `go(name)`, which sets `frame.src` and reloads the iframe. `focusTerm()` retries only at `[0, 60, 200, 500]` ms, then gives up (`done` never becomes true because `frame.contentDocument.activeElement === ta` is never satisfied). On a channel switch the new xterm textarea — and the ttyd websocket it needs — frequently isn't ready inside that 500 ms window, so every retry no-ops and focus is left on `<body>`. The immediate `closePalette()` call can also "succeed" against the *outgoing* document (setting `done=true`) a beat before navigation replaces it, so focus is then lost with no further retries. ## Fix ideas - Extend/scale `focusTerm()`'s retry schedule past ttyd's connect (e.g. add ~900/1500 ms attempts), and don't let a focus that sticks on the *old* document before navigation count as done. - Or drive the focus purely from the new iframe's `load` (already wired) and make its retry window long enough for ttyd. Desktop only — `focusTerm()` is intentionally a no-op on touch (focusing the textarea pops the Android soft keyboard). ## Verification Needs a browser: Alt+K → pick another channel → type immediately without clicking; the keystrokes should reach the shell. Check both an already-connected session and a cold one (slower ttyd connect).
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
pedromcaraujo/forge#35
No description provided.