Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix two ConPTY HWND focus issues #17828

Merged
merged 6 commits into from
Aug 29, 2024
Merged

Fix two ConPTY HWND focus issues #17828

merged 6 commits into from
Aug 29, 2024

Conversation

zadjii-msft
Copy link
Member

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

@microsoft-github-policy-service microsoft-github-policy-service bot added Issue-Bug It either shouldn't be doing this or needs an investigation. Area-Windowing Window frame, quake mode, tearout Product-Conpty For console issues specifically related to conpty labels Aug 29, 2024
src/interactivity/base/InteractivityFactory.cpp Outdated Show resolved Hide resolved
Copy link
Member

@carlos-zamora carlos-zamora left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really just want resolution on Leonard's comment before ✅

@@ -171,6 +171,7 @@ LRESULT NonClientIslandWindow::_InputSinkMessageHandler(UINT const message,
// is absolutely critical to making sure Snap Layouts (GH#9443) works!
return _dragBarNcHitTest({ GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam) });
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: can undo this change

Suggested change

@zadjii-msft zadjii-msft enabled auto-merge (squash) August 29, 2024 20:45
@zadjii-msft zadjii-msft merged commit 17a55da into main Aug 29, 2024
18 of 20 checks passed
@zadjii-msft zadjii-msft deleted the dev/migrie/a-focus-thing branch August 29, 2024 21:19
@DHowett
Copy link
Member

DHowett commented Sep 4, 2024

Marking up for 1.21 (consider) and 1.22 (pick)

DHowett pushed a commit that referenced this pull request Sep 4, 2024
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

(cherry picked from commit 17a55da)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmQzgSwIkE
Service-Version: 1.22
DHowett pushed a commit that referenced this pull request Sep 24, 2024
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

(cherry picked from commit 17a55da)
Service-Card-Id: PVTI_lADOAF3p4s4AmhmszgSwIkA
Service-Version: 1.21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Windowing Window frame, quake mode, tearout Issue-Bug It either shouldn't be doing this or needs an investigation. Product-Conpty For console issues specifically related to conpty
Projects
Development

Successfully merging this pull request may close these issues.

After GUI Error Message keyboards events ignored?
4 participants