[PR #17828] Fix two ConPTY HWND focus issues #31381

Open
opened 2026-01-31 09:46:53 +00:00 by claunia · 0 comments
Owner

Original Pull Request: https://github.com/microsoft/terminal/pull/17828

State: closed
Merged: Yes


Worked with @ekoschik on this one.

Bug the first: the MSAL window ixptools spawns

The auth prompt in pwsh.exe is disabling the terminal window while its opened and re-enabling it when the window closes. BUT it is enabling Terminal after dismissing itself, instead of before, which means terminal is disabled when activated.

Terminal wants focus on the ISLAND window (a grandchild; island is parented to bridge, which is parented to terminal’s TLW). When it is activated, it gets a WM_SETFOCUS (in response to DefWindowProc WM_ACTIVATE). From WM_SETFOCUS it calls SetFocus on the bridge window, and similarly the bridge calls SetFocus on the island.

If the TLW is disabled, these SetFocus calls fail (see this check in SetFocus). In the case above, this leaves Terminal’s TLW as focus, and it doesn’t handle keyboard input. Note that the window IS foreground/active, but because focus is not on the island it doesn’t see the keyboard input. Another thing to note is that clicking on the space to the right of the tabs does NOT revive keyboard input, but clicking on the tabs or main area does.

I recommend having the TLW handle WM_ENABLE and call SetFocus on the island window.

And guess what, that works!

Bug the second: When sublime text is the git EDITOR, it doesn't toss focus back to the Terminal

In this case, Sublime is calling SFW on the pseudo console window. I don’t have its code, but it is presumably doing something like SetForegroundWindow(GetConsoleWindow()). This queues an event to the pseudo window, and when that event is processed the pseudo window becomes the active and focus window on the queue (which is shared with Terminal).

The sublime window dismisses itself and does the above SFW call. Dismissing immediately activates the Terminal TLW, which does the triple-focus dance (TLW sets focus on itself, then bridge, then island). This completes but is overwritten immediately when the pseudo window activates itself. Note that the pseudo window is active at this point (not the terminal window).

I recommend having the Pseudo console window handle WM_ACTIVATE by calling SetFocus on the island window (and not passing the message to DefWindowProc).

And guess what, that works!


Closes #15956 (I did test this)
This might be related to #13388, we'll have folks try canary and check

**Original Pull Request:** https://github.com/microsoft/terminal/pull/17828 **State:** closed **Merged:** Yes --- Worked with @ekoschik on this one. ## Bug the first: the MSAL window `ixptools` spawns > The auth prompt in pwsh.exe is disabling the terminal window while its opened and re-enabling it when the window closes. BUT it is enabling Terminal after dismissing itself, instead of before, which means terminal is disabled when activated. > > Terminal wants focus on the ISLAND window (a grandchild; island is parented to bridge, which is parented to terminal’s TLW). When it is activated, it gets a `WM_SETFOCUS` (in response to DefWindowProc `WM_ACTIVATE`). From `WM_SETFOCUS` it calls `SetFocus` on the bridge window, and similarly the bridge calls `SetFocus` on the island. > > If the TLW is disabled, these `SetFocus` calls fail (see [this check](#internal-link-redacted) in `SetFocus`). In the case above, this leaves Terminal’s TLW as focus, and it doesn’t handle keyboard input. Note that the window IS foreground/active, but because focus is not on the island it doesn’t see the keyboard input. Another thing to note is that clicking on the space to the right of the tabs does NOT revive keyboard input, but clicking on the tabs or main area does. > **I recommend having the TLW handle WM_ENABLE and call SetFocus on the island window.** And guess what, that works! ## Bug the second: When sublime text is the git `EDITOR`, it doesn't toss focus back to the Terminal > In this case, Sublime is calling SFW on the pseudo console window. I don’t have its code, but it is presumably doing something like SetForegroundWindow(GetConsoleWindow()). This queues an event to the pseudo window, and when that event is processed the pseudo window becomes the active and focus window on the queue (which is shared with Terminal). > > The sublime window dismisses itself and does the above SFW call. Dismissing immediately activates the Terminal TLW, which does the triple-focus dance (TLW sets focus on itself, then bridge, then island). This completes but is overwritten immediately when the pseudo window activates itself. Note that the pseudo window is active at this point (not the terminal window). > **I recommend having the Pseudo console window handle WM_ACTIVATE by calling SetFocus on the island window (and not passing the message to DefWindowProc).** And guess what, that works! ---- Closes #15956 (I did test this) This might be related to #13388, we'll have folks try canary and check
claunia added the pull-request label 2026-01-31 09:46:53 +00:00
Sign in to join this conversation.
No Label pull-request
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#31381