Other applications open behind the Terminal window - (ConPTY window handle z-order shenanigans with GetConsoleWindow) #4173

Closed
opened 2026-01-30 23:40:04 +00:00 by claunia · 30 comments
Owner

Originally created by @amithegde on GitHub (Sep 30, 2019).

Originally assigned to: @zadjii-msft on GitHub.

Description of the new feature/enhancement

When I open File explorer from terminal using command such as start . control should shift to explorer window but it remains in terminal.

Proposed technical implementation details (optional)

when file explorer starts control should shift to explorer and any further keyboard interaction should be targeted to explorer window.
You can verify how ConEmu or cmd works to validate this.

Originally created by @amithegde on GitHub (Sep 30, 2019). Originally assigned to: @zadjii-msft on GitHub. <!-- 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 I ACKNOWLEDGE THE FOLLOWING BEFORE PROCEEDING: 1. If I delete this entire template and go my own path, the core team may close my issue without further explanation or engagement. 2. If I list multiple bugs/concerns in this one issue, the core team may close my issue without further explanation or engagement. 3. If I write an issue that has many duplicates, the core team may close my issue without further explanation or engagement (and without necessarily spending time to find the exact duplicate ID number). 4. If I leave the title incomplete when filing the issue, the core team may close my issue without further explanation or engagement. 5. If I file something completely blank in the body, the core team may close my issue without further explanation or engagement. All good? Then proceed! --> # Description of the new feature/enhancement When I open File explorer from terminal using command such as `start .` control should shift to explorer window but it remains in terminal. # Proposed technical implementation details (optional) when file explorer starts control should shift to explorer and any further keyboard interaction should be targeted to explorer window. You can verify how `ConEmu` or `cmd` works to validate this.
Author
Owner

@amithegde commented on GitHub (Sep 30, 2019):

I noticed it does shift control some times. So I guess it's a bug? Some times control doesn't shift and some times it shifts?

@amithegde commented on GitHub (Sep 30, 2019): I noticed it does shift control some times. So I guess it's a bug? Some times control doesn't shift and some times it shifts?
Author
Owner

@zadjii-msft commented on GitHub (Sep 30, 2019):

This might not be possible. This repros for any conpty session.

I (believe) that traditionally, start uses GetConsoleWindow to get the HWND of the console, to place explorer (or any application really) in the z-order above the conhost.exe window.

For something running in conpty however, the console doesn't actually have a window. The Terminal does, but the console doesn't. So there's no way for start to place something above the console window, since there is no console window.

@zadjii-msft commented on GitHub (Sep 30, 2019): This might not be possible. This repros for any conpty session. I (believe) that traditionally, `start` uses `GetConsoleWindow` to get the `HWND` of the console, to place explorer (or any application really) in the z-order above the conhost.exe window. For something running in conpty however, the console doesn't actually have a window. The Terminal does, but the console doesn't. So there's no way for `start` to place something above the console window, since there _is no console window_.
Author
Owner

@fpqc commented on GitHub (Sep 30, 2019):

I can't imagine it would be hard for a motivated person to write a small Windows program that launches a program and then sets it at the top of the Z-order without comparing against the current window.

@fpqc commented on GitHub (Sep 30, 2019): I can't imagine it would be hard for a motivated person to write a small Windows program that launches a program and then sets it at the top of the Z-order without comparing against the current window.
Author
Owner

@amithegde commented on GitHub (Sep 30, 2019):

This might not be possible. This repros for any conpty session.

I (believe) that traditionally, start uses GetConsoleWindow to get the HWND of the console, to place explorer (or any application really) in the z-order above the conhost.exe window.

For something running in conpty however, the console doesn't actually have a window. The Terminal does, but the console doesn't. So there's no way for start to place something above the console window, since there is no console window.

I will be demotivated to use Terminal in that case since it doesn't behave consistently with existing tools like cmd😒

@amithegde commented on GitHub (Sep 30, 2019): > This might not be possible. This repros for any conpty session. > > I (believe) that traditionally, `start` uses `GetConsoleWindow` to get the `HWND` of the console, to place explorer (or any application really) in the z-order above the conhost.exe window. > > For something running in conpty however, the console doesn't actually have a window. The Terminal does, but the console doesn't. So there's no way for `start` to place something above the console window, since there _is no console window_. I will be demotivated to use Terminal in that case since it doesn't behave consistently with existing tools like `cmd`😒
Author
Owner

@dracan commented on GitHub (Feb 22, 2020):

Not sure if this information is useful or not, but I had created a similar issue #3636 which got closed as a duplicate of this current issue. In my case, it was git difftool that was causing winmerge to not appear in the foreground. I've just discovered that whilst it happens when I do a normal git difftool, which triggers a Launch 'winmerge' [Y/n]? prompt - if instead I do git difftool -y, which suppresses that prompt - it works as expected.

@dracan commented on GitHub (Feb 22, 2020): Not sure if this information is useful or not, but I had created a similar issue #3636 which got closed as a duplicate of this current issue. In my case, it was `git difftool` that was causing winmerge to not appear in the foreground. I've just discovered that whilst it happens when I do a normal `git difftool`, which triggers a `Launch 'winmerge' [Y/n]?` prompt - if instead I do `git difftool -y`, which suppresses that prompt - it works as expected.
Author
Owner

@dracan commented on GitHub (Feb 22, 2020):

Although, if more than one file has differences - the first launch of winmerge is in the foreground (when specifying the -y mentioned in my previous post), however any subsequent ones have the issue where the winmerge window is right at the back of all other windows.

I've also just noticed that the same issue happens from the vscode terminal. It doesn't happen when using the native Powershell terminal window though.

@dracan commented on GitHub (Feb 22, 2020): Although, if more than one file has differences - the first launch of winmerge is in the foreground (when specifying the `-y` mentioned in my previous post), however any subsequent ones have the issue where the winmerge window is right at the back of all other windows. I've also just noticed that the same issue happens from the vscode terminal. It doesn't happen when using the native Powershell terminal window though.
Author
Owner

@zadjii-msft commented on GitHub (Jun 1, 2020):

showerthought: what if we had a conpty api to set a HWND that the virtual console window should be on top of? Since conpty has to maintain a fake HWND to make the GetConsoleWindow API work correctly, but we think it's a bad idea to just use the terminal's HWND as that value, is there win32 trickery we could do to make that virtual HWND appear at the top of the z-order? It can't be hit tested or receive input, but maybe that would make the shell spawn new windows on top of the Terminal

@zadjii-msft commented on GitHub (Jun 1, 2020): showerthought: what if we had a conpty api to set a HWND that the virtual console window should be on top of? Since conpty has to maintain a fake HWND to make the GetConsoleWindow API work correctly, but we think it's a bad idea to just use the terminal's HWND as that value, is there win32 trickery we could do to make that virtual HWND appear at the top of the z-order? It can't be hit tested or receive input, but maybe that would make the shell spawn new windows on top of the Terminal
Author
Owner

@OMA2k commented on GitHub (Nov 8, 2020):

Whatever the reason for Explorer windows not appearing on top, this should be fixed! I doesn't make sense having to hunt down a recently opened Window below several other windows, instead of having it open on top of everything as it's been the case for the past 25 years (since Windows 95!)

@OMA2k commented on GitHub (Nov 8, 2020): Whatever the reason for Explorer windows not appearing on top, this should be fixed! I doesn't make sense having to hunt down a recently opened Window below several other windows, instead of having it open on top of everything as it's been the case for the past 25 years (since Windows 95!)
Author
Owner

@OMA2k commented on GitHub (Jan 3, 2021):

Please, take some minutes to look into this bug! This was reported back in September 2019, and now we're in 2021 still with this same really annoying bug. It drives me nuts!

@OMA2k commented on GitHub (Jan 3, 2021): Please, take some minutes to look into this bug! This was reported back in September 2019, and now we're in 2021 still with this same really annoying bug. It drives me nuts!
Author
Owner

@zadjii-msft commented on GitHub (Jan 3, 2021):

@OMA2k This is not a bug that would take "a few minutes" to look into. The assumption here is that ShellExecute is using the console's HWND to find the z-order to place the new window. However, in conpty (which is what the Terminal uses), there is no HWND. And there's no good way to fake that value, without also just plumbing the Terminal's HWND all the way through to the conpty. However, if the conpty were running on another machine, all of a sudden the Terminal's HWND isn't a reliable value to use! So it's a complicated bug.

You'll note that we have plenty of issues that are even older that this one that are still open. We can only fix bugs so fast. As it turns out, the community files bugs and feature requests faster than we can resolve 😅.

@zadjii-msft commented on GitHub (Jan 3, 2021): @OMA2k This is not a bug that would take "a few minutes" to look into. The assumption here is that ShellExecute is using the console's HWND to find the z-order to place the new window. However, in conpty (which is what the Terminal uses), there is no HWND. And there's no good way to fake that value, without also just plumbing the Terminal's HWND all the way through to the conpty. However, if the conpty were running on another machine, all of a sudden the Terminal's HWND isn't a reliable value to use! So it's a complicated bug. You'll note that we have plenty of issues that are even older that this one that are still open. We can only fix bugs so fast. As it turns out, the community files bugs and feature requests faster than we can resolve 😅.
Author
Owner

@cactusbash commented on GitHub (Mar 5, 2021):

referencing #8679;

MFA authentication window, along with any Windows.MessageBox pop up in the background. Has this been fixed or being worked on?

@cactusbash commented on GitHub (Mar 5, 2021): referencing #8679; MFA authentication window, along with any **Windows.MessageBox** pop up in the background. Has this been fixed or being worked on?
Author
Owner

@SpitFire-666 commented on GitHub (Apr 20, 2021):

Could the title of this issue be updated to be more "generic"? That way people like me might be able to find it easier instead of raising duplicate tickets?

@SpitFire-666 commented on GitHub (Apr 20, 2021): Could the title of this issue be updated to be more "generic"? That way people like me might be able to find it easier instead of raising duplicate tickets?
Author
Owner

@KalleOlaviNiemitalo commented on GitHub (Apr 21, 2021):

However, if the conpty were running on another machine, all of a sudden the Terminal's HWND isn't a reliable value to use! So it's a complicated bug.

What's the scenario in which the conpty is running on another machine but hosts GUI applications whose windows need to be correctly stacked?

I mean, you can have a conpty on another machine, if you run an SSH client in Windows Terminal and the SSH server on another machine then uses a conpty. But if you then start e.g. winver.exe over that connection, I wouldn't expect its window to be visible on either machine, so it hardly matters whether the window is active and where it is in the Z-order.

Well, I imagine you could have a visible window if you ran the SSH server interactively and not as a service. If that is an important scenario, the SSH server could create its own window and pass the HWND to the conpty. No need to send the HWND of Windows Terminal over the wire.

Did you have something else in mind?

@KalleOlaviNiemitalo commented on GitHub (Apr 21, 2021): > However, if the conpty were running on another machine, all of a sudden the Terminal's HWND isn't a reliable value to use! So it's a complicated bug. What's the scenario in which the conpty is running on another machine but hosts GUI applications whose windows need to be correctly stacked? I mean, you can have a conpty on another machine, if you run an SSH client in Windows Terminal and the SSH server on another machine then uses a conpty. But if you then start e.g. winver.exe over that connection, I wouldn't expect its window to be visible on either machine, so it hardly matters whether the window is active and where it is in the Z-order. Well, I imagine you could have a visible window if you ran the SSH server interactively and not as a service. If that is an important scenario, the SSH server could create its own window and pass the HWND to the conpty. No need to send the HWND of Windows Terminal over the wire. Did you have something else in mind?
Author
Owner

@DHowett commented on GitHub (Apr 21, 2021):

there's no good way to fake that value, without also just plumbing the Terminal's HWND all the way through to the conpty

Oh boy, and Cygwin uses the window handle of the console as a global identifier to disambiguate its fake tty devices. Without each console session being hosted in a unique window with a unique HWND, it will believe that all open windows are connected to the same tty device.

@DHowett commented on GitHub (Apr 21, 2021): > there's no good way to fake that value, without also just plumbing the Terminal's HWND all the way through to the conpty Oh boy, and Cygwin uses the _window handle of the console_ as a global identifier to disambiguate its fake `tty` devices. Without each console session being hosted in a unique window with a unique HWND, it will believe that all open windows are connected to the same `tty` device.
Author
Owner

@DHowett commented on GitHub (Apr 21, 2021):

OpenSSH (client) uses the window handle of the console to replace the title of the window, which won't work in multi-hosting scenarios like Terminal.

Vim for Windows uses the window handle to set/reset the icon, which ... well, will also not work properly in multi-hosting scenarios. It would also cause people to file bugs like "Terminal's icon changed to Vim when I ran Vim, and it sticks when I switch tabs" which looks and smells and tastes like a Terminal bug but ... isn't.

The license we'd given app developers to futz with "our" window (while calling it "their" window) really sucks.

@DHowett commented on GitHub (Apr 21, 2021): OpenSSH (client) uses the window handle of the console to replace the title of the window, which won't work in multi-hosting scenarios like Terminal. Vim for Windows uses the window handle to set/reset the icon, which ... well, will also not work properly in multi-hosting scenarios. It would also cause people to file bugs like "Terminal's icon changed to Vim when I ran Vim, and it sticks when I switch tabs" which _looks and smells and tastes_ like a Terminal bug but ... isn't. The license we'd given app developers to futz with "our" window (while calling it "their" window) _really sucks._
Author
Owner

@zadjii-msft commented on GitHub (Apr 21, 2021):

Cygwin uses the window handle of the console as a global identifier to disambiguate its fake tty devices.

God I forgot about that bug. That one was just the worst, and agressively throws a wrench in the "just plumb WT's HWND through" solution.

I wonder if we could fake conpty's pseudo-HWND into being "always on top". That would give us the opposite problem. Instead of apps opening behind the Terminal sometimes, they'd open on top of all other apps always, but maybe that's not a bad idea? Presumably opening on top of a TOPMOST HWND would put you at the top of the z-order, but not in the TOPMOST group.

@zadjii-msft commented on GitHub (Apr 21, 2021): > Cygwin uses the _window handle of the console_ as a global identifier to disambiguate its fake `tty` devices. God I forgot about that bug. That one was just the worst, and agressively throws a wrench in the "just plumb WT's HWND through" solution. I wonder if we could fake conpty's pseudo-HWND into being "always on top". That would give us the opposite problem. Instead of apps opening behind the Terminal sometimes, they'd open on top of all other apps _always_, but maybe that's not a bad idea? Presumably opening on top of a TOPMOST HWND would put you at the top of the z-order, but not in the TOPMOST group.
Author
Owner

@Fred-Vatin commented on GitHub (Jun 5, 2021):

For me, as explain in #10345, only cmdlet using GUI like Show-Command Get-ChildItem or Get-ChildItem | Out-GridView open behind the terminal. For now no issue while opening external app like code $Profile or start .

What apps are still causing problem if any ?

@Fred-Vatin commented on GitHub (Jun 5, 2021): For me, as explain in #10345, only cmdlet using GUI like `Show-Command Get-ChildItem` or `Get-ChildItem | Out-GridView` open behind the terminal. For now no issue while opening external app like `code $Profile` or `start .` What apps are still causing problem if any ?
Author
Owner

@arkrumbe commented on GitHub (Jul 21, 2021):

Just want to +1 this. I'm hitting this with Get-ChildItem | Out-GridView and it's pretty disruptive to my workflow.

@arkrumbe commented on GitHub (Jul 21, 2021): Just want to +1 this. I'm hitting this with `Get-ChildItem | Out-GridView` and it's pretty disruptive to my workflow.
Author
Owner

@zadjii-msft commented on GitHub (Jul 21, 2021):

@arkrumbe If you'd like to "+1" this feature, the best way to do that is by hitting the 👍 button on this issue

image

That way, you avoid unnecessarily pinging everyone following this thread. Thanks!

@zadjii-msft commented on GitHub (Jul 21, 2021): @arkrumbe If you'd like to "+1" this feature, the best way to do that is by hitting the 👍 button on this issue ![image](https://user-images.githubusercontent.com/18356694/96140789-ef3c8880-0ec5-11eb-82e0-30ce4977b9a7.png) That way, you avoid unnecessarily pinging everyone following this thread. Thanks!
Author
Owner

@zadjii-msft commented on GitHub (Jul 28, 2021):

Guh. Neither

  • passing WS_EX_TOPMOST to CreateWindow nor
  • SetWindowPos(... HWND_TOPMOST)

worked to hackily fix this. I wonder what exactly Out-GridView is doing to place the window. Maybe we can trick it just right...

EDIT:
Uhg. Looks like they're just making a Window, which is totally useless. Must be something lower in the stack that checks if the parent is a console and calls GetConsoleWindow(). barf.

It would be unbelievably wack to have Terminal create fake HWNDs for each terminal instance within it, and plumb those HWNDs into conpty. I'm not even sure that if those hwnds were at the right z depth relative to the Terminal's actual hwnd that this would work right. If the window is hidden, does it appear in the z-order? I'm assuming not.

  • HWND_MESSAGE also didn't work.
  • calling BringWindowToTop on the fake hwnd whenever GetConsoleWindow is called didn't work
  • furthermore, ShowWindow(hwnd, SW_SHOW); BringWindowToTop(hwnd); ShowWindow(hwnd, SW_HIDE); didn't work either.
@zadjii-msft commented on GitHub (Jul 28, 2021): Guh. Neither * [x] passing `WS_EX_TOPMOST` to `CreateWindow` nor * [x] `SetWindowPos(... HWND_TOPMOST)` worked to hackily fix this. I wonder what exactly `Out-GridView` is doing to place the window. Maybe we can trick it _just right_... EDIT: Uhg. Looks like they're just [making a Window](https://github.com/PowerShell/PowerShell/blob/7ead1374072c2664f5830fceb6b281a500196d0a/src/Microsoft.Management.UI.Internal/commandHelpers/OutGridView.cs#L136), which is totally useless. Must be something lower in the stack that checks if the parent is a console and calls `GetConsoleWindow()`. barf. It would be unbelievably wack to have Terminal create fake `HWND`s for each terminal instance within it, and plumb _those_ `HWND`s into conpty. I'm not even sure that if _those_ hwnds were at the right z depth relative to the Terminal's actual hwnd that this would work right. If the window is hidden, does it appear in the z-order? I'm assuming _not_. * [x] `HWND_MESSAGE` also didn't work. * [x] calling `BringWindowToTop` on the fake hwnd whenever `GetConsoleWindow` is called didn't work * [x] furthermore, ` ShowWindow(hwnd, SW_SHOW); BringWindowToTop(hwnd); ShowWindow(hwnd, SW_HIDE);` didn't work either.
Author
Owner

@zadjii-msft commented on GitHub (Jul 28, 2021):

Interesting. I tried the following, and even this didn't work:

  • Open a terminal window.
  • Grab it's HWND.
  • Leave that terminal window open.
  • Manually edit GetConsoleWindowImpl to return that HWND, and recompile the Terminal.
  • Launch a dev build of the Terminal, and run sleep 1 ; Get-ChildItem | Out-GridView.
  • quickly focus the original Terminal window, so it's at the top of the z-order.
  • The window still appears beneath the Terminal window!

This convoluted example is a proof-of-concept for just having GetConsoleWindow return the HWND of the hosting terminal. Even in that case, the spawned child process doesn't open above the Terminal. I'm a little shocked that the original scenario worked at all...

@zadjii-msft commented on GitHub (Jul 28, 2021): Interesting. I tried the following, and even this didn't work: * Open a terminal window. * Grab it's HWND. * Leave that terminal window open. * Manually edit `GetConsoleWindowImpl` to return that HWND, and recompile the Terminal. * Launch a dev build of the Terminal, and run `sleep 1 ; Get-ChildItem | Out-GridView`. * quickly focus the original Terminal window, so it's at the top of the z-order. * ❌ The window still appears _beneath_ the Terminal window! This convoluted example is a proof-of-concept for just having `GetConsoleWindow` return the HWND of the hosting terminal. Even in that case, the spawned child process doesn't open above the Terminal. I'm a little shocked that the original scenario worked at all...
Author
Owner

@IanMoroney commented on GitHub (Dec 14, 2021):

@zadjii-msft , instead can the class name of window be grabbed and used to bring it to the foreground?
https://stackoverflow.com/questions/10898560/how-to-set-focus-to-another-window
(Pardon my ignorance in this area, i'm by no means experienced, just offering suggestions 👍 )

In my testing on Out-GridView, the window's class name appears as:
In Powershell ISE:
HwndWrapper[powershell_ise.exe;;6b8576b7-1fb6-4618-9b70-961b680290da]
HwndWrapper[powershell_ise.exe;;7e4e5f2c-ad6b-445b-9793-4f84e6c95169]

In Powershell 5.1 through Windows Terminal:
HwndWrapper[DefaultDomain;;f66a3055-9651-461e-a5ee-debf0b069573] (maybe the class name could be improved here?)

@IanMoroney commented on GitHub (Dec 14, 2021): @zadjii-msft , instead can the class name of window be grabbed and used to bring it to the foreground? https://stackoverflow.com/questions/10898560/how-to-set-focus-to-another-window (Pardon my ignorance in this area, i'm by no means experienced, just offering suggestions 👍 ) In my testing on `Out-GridView`, the window's class name appears as: In Powershell ISE: `HwndWrapper[powershell_ise.exe;;6b8576b7-1fb6-4618-9b70-961b680290da]` `HwndWrapper[powershell_ise.exe;;7e4e5f2c-ad6b-445b-9793-4f84e6c95169]` In Powershell 5.1 through Windows Terminal: `HwndWrapper[DefaultDomain;;f66a3055-9651-461e-a5ee-debf0b069573]` (maybe the class name could be improved here?)
Author
Owner

@KalleOlaviNiemitalo commented on GitHub (Dec 15, 2021):

@IanMoroney, do you mean Windows Terminal should detect that a process opened a window, and bring that window to the foreground? The user can have e.g. cmd.exe running in WT and start powershell_ise.exe from there. WT could perhaps detect the new process via JOB_OBJECT_MSG_NEW_PROCESS, and detect the new window by hooking HSHELL_WINDOWCREATED or some WinEvent, but I don't know how WT could decide whether the new window belongs to the foreground or not. The "HwndWrapper" class names are not very useful for this, because those are generated (source) by the Windows Presentation Foundation (WPF) library, which is not used by all applications.

@zadjii-msft, AllowSetForegroundWindow may be relevant to your July experiment.

@KalleOlaviNiemitalo commented on GitHub (Dec 15, 2021): @IanMoroney, do you mean Windows Terminal should detect that a process opened a window, and bring that window to the foreground? The user can have e.g. cmd.exe running in WT and start powershell_ise.exe from there. WT could perhaps detect the new process via JOB_OBJECT_MSG_NEW_PROCESS, and detect the new window by hooking HSHELL_WINDOWCREATED or some WinEvent, but I don't know how WT could decide whether the new window belongs to the foreground or not. The "HwndWrapper" class names are not very useful for this, because those are generated ([source](https://github.com/dotnet/wpf/blob/v6.0.1/src/Microsoft.DotNet.Wpf/src/Shared/MS/Win32/HwndWrapper.cs#L94-L112)) by the Windows Presentation Foundation (WPF) library, which is not used by all applications. @zadjii-msft, AllowSetForegroundWindow may be relevant to your July experiment.
Author
Owner

@grossag commented on GitHub (Jan 6, 2022):

This issue happens consistently for me if I am in Maximized mode. Unfortunately I do use Settings > Startup > Launch mode > Maximized so I regularly run into this issue. It reproduces in two ways:

  1. Basic case: start . entered from terminal runs in the background (mentioned in earlier comments).
  2. Other case (not mentioned in earlier comments):
    • Run: echo https://www.google.com
    • Click the hyperlink from that echo message.
    • My default browser (Google Chrome) launches in the background, when I would expect it to launch above the terminal app in the z-order.

This issue happens for me with both the GA version (1.11.3471.0) and the preview version (1.12.3472.0).

@grossag commented on GitHub (Jan 6, 2022): This issue happens consistently for me if I am in Maximized mode. Unfortunately I do use Settings > Startup > Launch mode > Maximized so I regularly run into this issue. It reproduces in two ways: 1. Basic case: `start .` entered from terminal runs in the background (mentioned in earlier comments). 2. Other case (not mentioned in earlier comments): - Run: `echo https://www.google.com` - Click the hyperlink from that echo message. - My default browser (Google Chrome) launches in the background, when I would expect it to launch above the terminal app in the z-order. This issue happens for me with both the GA version (1.11.3471.0) and the preview version (1.12.3472.0).
Author
Owner

@zadjii-msft commented on GitHub (Jan 11, 2022):

Internally, MSFT:37697992

@zadjii-msft commented on GitHub (Jan 11, 2022): Internally, MSFT:37697992
Author
Owner

@zadjii-msft commented on GitHub (Jan 12, 2022):

Notes:

  • we're the murderer in the start case. Technically, we own cmd.exe, and start, the cmd intrinsic, uses GetConsoleWindow to place the HWND. Ruh roh. That case seems like it'll be hard to fix, and likely that we'll definitely mess it up and have to revert the fix anyways.
  • I should refer to queue.cxx and xxxConsoleControl, alongside SetConsoleWindowOwner in conhost. That hwnd might be the one that the OS thinks is the owner for console applications, so we may be able to fudge the Terminal hwnd into that.
@zadjii-msft commented on GitHub (Jan 12, 2022): Notes: * we're the murderer in the `start` case. Technically, we own `cmd.exe`, and `start`, the `cmd` intrinsic, uses `GetConsoleWindow` to place the HWND. Ruh roh. That case seems like it'll be hard to fix, and likely that we'll definitely mess it up and have to revert the fix anyways. * I should refer to `queue.cxx` and `xxxConsoleControl`, alongside `SetConsoleWindowOwner` in conhost. That hwnd _might_ be the one that the OS thinks is the owner for console applications, so we may be able to fudge the Terminal hwnd into that.
Author
Owner

@zadjii-msft commented on GitHub (Feb 18, 2022):

I have nowhere else for good notes, so sorry for the kinda random ping here folks:

b2575819b status

As of b2575819b, this is starting to work a little better
image

Turns out there's piles of edge cases. Seemingly different things zorder in different ways, which is complicating this. Duping everything to this thread may not have been the most wise ;___;


Changed the reparenting to the root terminal HWND instead of the xaml island, and we get:

image

so GetAncestor(GetConsoleWindow(), GA_ROOT) can work the same for WT and conhost

See also:

Scenarios:

@zadjii-msft commented on GitHub (Feb 18, 2022): I have nowhere else for good notes, so sorry for the kinda random ping here folks: <details> <summary>b2575819b status</summary> As of b2575819b, this is starting to work a little better ![image](https://user-images.githubusercontent.com/18356694/154688034-602c4807-2f27-4ef6-9a11-6dd36ff18663.png) </details> Turns out there's piles of edge cases. Seemingly different things zorder in different ways, which is complicating this. Duping everything to this thread may not have been the most wise ;___; ---------- Changed the reparenting to the root terminal HWND instead of the xaml island, and we get: <!-- ![image](https://user-images.githubusercontent.com/18356694/154689263-67722097-6c64-40a4-9180-5d2c0d81a839.png) --> ![image](https://user-images.githubusercontent.com/18356694/154729652-65daa6c4-58d0-4320-86b3-633c0157dcc8.png) so `GetAncestor(GetConsoleWindow(), GA_ROOT)` can work the same for WT and conhost See also: * https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/issues/2469 * https://github.com/GitCredentialManager/git-credential-manager/issues/469#issuecomment-932228305 ## Scenarios: * [x] ExchangeOnlineMangement , [Azure Az Powershell](https://docs.microsoft.com/en-us/powershell/azure/new-azureps-module-az?view=azps-7.2.0&viewFallbackFrom=azps-5.2.0) login popup opens in background. `Connect-AzAccount` * #11776 * #6084 * #11464 * The `Connect-AzAccount` looks to be the same as well. * #6053 * #8679 * `Import-Module -Name ExchangeOnlineManagement ; Connect-ExchangeOnline` * This seemingly opens an Edge window to do the auth. Hmm. * PowerShell 5 opens a dialog of some sort * ❌ Does not work in 5d96691 + always use `WS_OVERLAPPED` * In both preview and dev, it does open on the correct monitor, but beneath the Terminal. Presumably tries to parent the window to an invisible or a child window and that doesn't work. * In conhost this dialog isn't a child, it's just before it in the ordering. I wonder if it's just trying to insert it BEFORE the GetConsoleWindow? * Mail out. * ⁉️ SOMETIMES JUST WORKS * ✅ PowerShell 7 opens the prompt in Edge / default browser. * [x] `get-credential` does not work with powershell 5, works with powershell 7, * #11847 * ✅ This one is seemingly already fixed in `main`. I don't think we did anything here, but I certainly can't repro this anymore. `Get-credential` consistently acts as a proper dialog in the Terminal, and you can't focus the Terminal without focusing the dialog * [x] Print Dialog via `:hardcopy` in `vim.exe` * #10693 * Seems to work well enough with 5d96691 + always use `WS_OVERLAPPED`. In that version, the dialog always appears "on" the terminal hwnd, but doesn't block input like a dialog usually does (and does for conhost). ~This might be the "it sometimes works just fine" case, where things appear at the top of the z ~ * ✅ Actually, yea this is MUCH better than the preview version, where it appears centered on 0,0 😨 * [x] Powershell `show-command Get-ChildItem`, `Out-GridView`, `Get-Help -ShowWindow` * #10345 * #3665 * #9888 * #10161 * "Powershell script that opens a Windows Dialog" - this isn't very clear, but sounds the same * ❌ Not fixed as of 5d96691b0 * See: https://github.com/PowerShell/PowerShell/blob/7dc4587014bfa22919c933607bf564f0ba53db2e/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ShowCommand/ShowCommand.cs#L226, https://github.com/PowerShell/PowerShell/tree/7dc4587014bfa22919c933607bf564f0ba53db2e/src/Microsoft.Management.UI.Internal * https://github.com/PowerShell/PowerShell/blob/7dc4587014bfa22919c933607bf564f0ba53db2e/src/Microsoft.Management.UI.Internal/commandHelpers/ShowCommandHelper.cs#L961 seems to be where the window is created. * `SetupWindow` - not helpful * `CommonHelper.SetStartingPositionAndSize` - not helpful * Window.Activate is defined here: https://github.dev/dotnet/wpf/blob/91fb2e1bc4bf6520d1039056d3dcde8236ce7b58/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Window.cs#L513. It's just doing `SetForegroundWindow`. Ruh roh. * * [ ] missing dll popup from `NtRaiseHardError` * #9788 * [x] `cmd.exe`'s `start` (which is what this thread was originally about) * #7415 - `START "ms-settings:"`. * ❌ Not fixed as of 5d96691b0 * Might only apply to URI activation though. Needs more investigation. * [x] The WT window always appears behind the active Explorer window. * This actually isn't a dupe at all. * #7036 * [ ] WinForms dialog not popping up on top of Windows Terminal * #6633 * [ ] Maybe related: #11185
Author
Owner

@zadjii-msft commented on GitHub (Mar 28, 2022):

Misc notes:

    gci.ProcessHandleList.ModifyConsoleProcessFocus(WI_IsFlagSet(gci.Flags, CONSOLE_HAS_FOCUS));

    ...

    // ModifyConsoleProcessFocus calls _ModifyProcessForegroundRights

    ...

void ConsoleProcessList::_ModifyProcessForegroundRights(const HANDLE hProcess, const bool fForeground) const
{
    LOG_IF_NTSTATUS_FAILED(ServiceLocator::LocateConsoleControl()->SetForeground(hProcess, fForeground));
}

FocusIn/FocusOut

FocusIn/FocusOut can be combined with any of the mouse events since it
uses a different protocol. When set, it causes xterm to send CSI I
when the terminal gains focus, and CSI O when it loses focus.

The easiest prototype may just be always passing true here in conpty mode.


graph TD
    id1[ \u2705Allow windows created by console <br> apps to appear above the Terminal #12799] --> id3[ \u2705Check if FG window is owner #12899]
    id2[ \u2705 Enable the Terminal to tell ConPTY <br> who the owner is #12526] --> id3
    id3 --> id4[ \u2705FocusEvents in conhost, terminal, #12900]  --> id6
    id5[ \u2705 Propagate show/hide window calls against <br> the ConPTY pseudo window to the Terminal #12515] --> id6{{Terminal v1.14}}
    click id1 "http://www.github.com/microsoft/terminal/issues/12799"
    click id2 "http://www.github.com/microsoft/terminal/issues/12526"
    click id3 "http://www.github.com/microsoft/terminal/issues/12899"
    click id4 "http://www.github.com/microsoft/terminal/issues/12900"
    click id5 "http://www.github.com/microsoft/terminal/issues/12515"

April 7 status update: flowchart above has dependency tree. Gonna stack the PRs in the bubbles on top of #12799, once #12526 merges. We won't have time to review that this week though.

April 27th update: all the above PRs have signoffs &/|| are merged. Should all be available in 1.14.

@zadjii-msft commented on GitHub (Mar 28, 2022): Misc notes: ```c++ gci.ProcessHandleList.ModifyConsoleProcessFocus(WI_IsFlagSet(gci.Flags, CONSOLE_HAS_FOCUS)); ... // ModifyConsoleProcessFocus calls _ModifyProcessForegroundRights ... void ConsoleProcessList::_ModifyProcessForegroundRights(const HANDLE hProcess, const bool fForeground) const { LOG_IF_NTSTATUS_FAILED(ServiceLocator::LocateConsoleControl()->SetForeground(hProcess, fForeground)); } ``` > ### [FocusIn/FocusOut](https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-FocusIn_FocusOut) > FocusIn/FocusOut can be combined with any of the mouse events since it > uses a different protocol. When set, it causes xterm to send CSI I > when the terminal gains focus, and CSI O when it loses focus. The easiest prototype may just be always passing `true` here in conpty mode. <hr> ```mermaid graph TD id1[ \u2705Allow windows created by console <br> apps to appear above the Terminal #12799] --> id3[ \u2705Check if FG window is owner #12899] id2[ \u2705 Enable the Terminal to tell ConPTY <br> who the owner is #12526] --> id3 id3 --> id4[ \u2705FocusEvents in conhost, terminal, #12900] --> id6 id5[ \u2705 Propagate show/hide window calls against <br> the ConPTY pseudo window to the Terminal #12515] --> id6{{Terminal v1.14}} click id1 "http://www.github.com/microsoft/terminal/issues/12799" click id2 "http://www.github.com/microsoft/terminal/issues/12526" click id3 "http://www.github.com/microsoft/terminal/issues/12899" click id4 "http://www.github.com/microsoft/terminal/issues/12900" click id5 "http://www.github.com/microsoft/terminal/issues/12515" ``` April 7 status update: flowchart above has dependency tree. Gonna stack the PRs in the bubbles on top of #12799, once #12526 merges. We won't have time to review that this week though. April 27th update: all the above PRs have signoffs &/|| are merged. Should all be available in 1.14.
Author
Owner

@zadjii-msft commented on GitHub (Apr 28, 2022):

Alrighty. With #12515, #12526, #12799, #12899, #12900 all merged, I think this one's done. Everything I found linked to this thread seems to work in main. At this point, any new issues we discover in 1.14+ will be something else entirely, so we should give them new threads.

Thanks for the patience here folks!

@zadjii-msft commented on GitHub (Apr 28, 2022): Alrighty. With #12515, #12526, #12799, #12899, #12900 all merged, I think this one's done. Everything I found linked to this thread seems to work in `main`. At this point, any new issues we discover in 1.14+ will be something else entirely, so we should give them new threads. Thanks for the patience here folks!
Author
Owner

@zaaj commented on GitHub (May 28, 2024):

Terminal version 1.19 on Windows 11 here almost half way through 2024 and this is still a problem - Microsoft Graph login-prompt windows usually show up behind the Terminal window that launches them, I also have intermittent issues with Get-Credential in windows powershell 5.1 (pwsh 7 not having all the functionality I use on a day-to-day basis, I'm still feeling stuck on 5 - plus, writing my scripts for 5 makes them more sharable with my less-powershell-savvy colleagues, and is easier to run them on servers where we don't want to install any software not needed, including Pwsh 7).

From a technical programming standpoint, I can understand a ConPTY process not having a console window, but it is obviously being show IN a window, which DOES have a window handle. With 5 PRs all trying to attempt to resolve this, it would appear to be a hard-to-fully-resolve issue. I appreciate that work had been done towards resolving this issue, but it does not appear to be resolved yet. Please keep working on this issue.

@zaaj commented on GitHub (May 28, 2024): Terminal version 1.19 on Windows 11 here almost half way through 2024 and this is still a problem - Microsoft Graph login-prompt windows usually show up behind the Terminal window that launches them, I also have intermittent issues with Get-Credential in windows powershell 5.1 (pwsh 7 not having all the functionality I use on a day-to-day basis, I'm still feeling stuck on 5 - plus, writing my scripts for 5 makes them more sharable with my less-powershell-savvy colleagues, and is easier to run them on servers where we don't want to install any software not needed, including Pwsh 7). From a technical programming standpoint, I can understand a ConPTY process not having a console window, but it is obviously being show IN a window, which DOES have a window handle. With 5 PRs all trying to attempt to resolve this, it would appear to be a hard-to-fully-resolve issue. I appreciate that work had been done towards resolving this issue, but it does not appear to be resolved yet. Please keep working on this issue.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#4173