Skip to content

fix(focus): keyboard focus follows the highlighted pane - #195

Open
AThraen wants to merge 1 commit into
mainfrom
fix/keyboard-focus-follows-active
Open

AThraen wants to merge 1 commit into
mainfrom
fix/keyboard-focus-follows-active

Conversation

@AThraen

@AThraen AThraen commented Nov 10, 2026

Copy link
Copy Markdown
Contributor

Problem

Sometimes typing in a pane makes the letters appear in a different pane. MainViewModel.ActiveSession drives the highlight, but keystrokes follow Win32 keyboard focus. Two paths let the two drift apart:

  1. Clicking a pane while CSM is in the background. OnWindowActivated BeginInvoked FocusTerminal() on the previous active session. Meanwhile the page's capture-phase mousedown posts activate, a cross-process message, which promotes the clicked pane. Whichever lands last wins. When the stale refocus won, the highlight moved to the clicked pane and the keystrokes kept going to the old one.
  2. Restart. The teardown hands ActiveSession to Sessions.LastOrDefault(). The wasActive restore then set ActiveSession back to the revived session but never focused it.

Fix

  • OnWindowActivated skips the refocus while any mouse button is down (GetAsyncKeyState, all three buttons, because swapped mouse buttons are physical). A click-to-activate is the user choosing the target. Alt+Tab and taskbar activation still refocus the active terminal as before.
  • PaneActivated (a click in a pane) now promotes and focuses that pane. This makes the result independent of the order in which the activation and the page message arrive. It is throttled to 300 ms on the page side.
  • The restart wasActive path calls FocusTerminal() on the revived session.
  • CLAUDE.md "What makes a session active" records the rule: setting ActiveSession moves the highlight, not the keyboard.

Testing

  • dotnet build passes and the unit tests pass (1183/1183).
  • Not covered by automated tests: the race needs a real focus change between processes and WebView2, which the headless suite can't drive. Manual checks:
    • With CSM in the background and pane A active, click directly into pane B and type. Text goes to B.
    • Alt+Tab back into CSM and type. Text goes to the highlighted pane.
    • Restart (↻) the active session, wait for it to come back, and type. Text goes to it.

🤖 Generated with Claude Code

Typing sometimes landed in a different pane than the highlighted one.
ActiveSession drives the highlight, but keystrokes follow Win32 focus,
and two paths let them drift apart:

- Clicking a pane while CSM was in the background: OnWindowActivated
  BeginInvoked FocusTerminal on the PREVIOUS active session, racing the
  page's cross-process `activate` message. When it landed last, the
  highlight moved to the clicked pane and focus stayed on the old one.
  It now skips the refocus when a mouse button is down (the click picks
  the target), and a pane click both promotes and focuses its pane.
- Restart restored ActiveSession to the revived session but never
  focused it, leaving focus wherever the teardown put it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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