-
Notifications
You must be signed in to change notification settings - Fork 9k
Move ConPTY handoff logic into WindowEmperor #19088
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
Move ConPTY handoff logic into WindowEmperor #19088
Conversation
DHowett
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
11/16
| winrt::TerminalApp::CommandlineArgs c; | ||
| c.Commandline(args); | ||
| c.CurrentDirectory(currentDirectory); | ||
| c.CurrentEnvironment(envString); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
make sure to test env stuff. the double null terminated strings can be a pain
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW this doesn't actually change the code at all. The only difference is constructor VS property.
| const auto args = commandlineToArgArray(GetCommandLineW()); | ||
| if (_windows.empty() || args.size() != 1) | ||
|
|
||
| if (args.size() == 2 && args[1] == L"-Embedding") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just to confirm: wt -Embedding should result in a headless terminal, which can respond to ConPTY handoffs, but otherwise keeps running?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
e.g. it creates the toplevel hidden window to receive messages and all, and you can add new windows with wt nt?
does this cause any session restoration? how does that work
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just to confirm: wt -Embedding should result in a headless terminal, which can respond to ConPTY handoffs, but otherwise keeps running?
Yes
e.g. it creates the toplevel hidden window to receive messages and all, and you can add new windows with wt nt?
Yes
does this cause any session restoration?
Yes
how does that work
Session restoration is relatively simple nowadays, not like in the past. Check out line 338 right above this.
|
Does this make any dent in the incidence of "Terminal window opens without any tabs" problem? |
This was by design. It is rejected before handoff starts, because we thought that starting up minimized usually indicates non-foreground workloads. We didn't want to mess with those |
Yes, that's fixed now to my knowledge. |
| if (auto conn = args.Connection()) | ||
| { | ||
| _root->SetInboundListener(true); | ||
| _root->CreateTabFromConnection(std::move(conn)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
when will we get a connection in an Args versus in SetStartupCommandline where it will get moved into _startupConnection?
Is this a case where handoff (from cold start) is differnet from handoff (already running)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you meant what I think you meant, then the difference is "dispatch into a new window vs into an existing one". But I'm not sure I understand your question. Can you rephrase it if needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is one path through handoff which populates _startupConnection. There is a second path through handoff which populates an Args Connection property.
How are they different?
Is it that one is used during cold startup (handoff causes Terminal to start), and one is used when Terminal is already running (handoff causes a new tab or a new window in a running Terminal instance)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, so it's what I thought you meant. It's indeed "dispatch into a new window vs into an existing one". Put differently: _startupConnection is for when a window is created, WinUI has not yet finished initialization, and we're deferring the creation of a tab until after WinUI is done. The other path which uses the Connection property right here is for when the window already exists and we're simply creating another new tab in an existing window.
There is a second path through handoff which populates an Args Connection property.
To be clear, both populate the Connection property. WindowEmperor works "correctly" and makes no distinction between creating a new window with 1 tab and adding 1 tab to an existing window. In this spirit, there's only 1 place which populates the Connection property. It then goes through the same code inside WindowEmperor.
It's TerminalWindow which makes this distinction, and I don't think it should.
|
Can't backport to 1.22; too much architectural change |
This changes the ConPTY handoff COM server from `REGCLS_SINGLEUSE` to `REGCLS_MULTIPLEUSE`. The former causes a race condition, because handoff runs concurrently with the creation of WinUI windows. This can then result in the a window getting the wrong handoff. It then moves the "root" of ConPTY handoff from `TerminalPage` (WindowEmperor -> AppHost -> TerminalWindow -> TerminalPage) into `WindowEmperor` (WindowEmperor). Closes #19049 ## Validation Steps Performed * Launching cmd from the Start Menu shows a "Command Prompt" tab ✅ * Win+R -> `cmd` creates windows in the foreground ✅ * Win+R -> `cmd /c start /max cmd` creates a fullscreen tab ✅ * This even works for multiple windows, unlike with Canary ✅ * Win+R -> `cmd /c start /min cmd` does not work ❌ * It also doesn't work in Canary, so it's not a bug in this PR ✅ (cherry picked from commit a25d968) Service-Card-Id: PVTI_lADOAF3p4s4AxadtzgbpecU Service-Version: 1.23
This changes the ConPTY handoff COM server from
REGCLS_SINGLEUSEto
REGCLS_MULTIPLEUSE. The former causes a race condition, becausehandoff runs concurrently with the creation of WinUI windows.
This can then result in the a window getting the wrong handoff.
It then moves the "root" of ConPTY handoff from
TerminalPage(WindowEmperor -> AppHost -> TerminalWindow -> TerminalPage)
into
WindowEmperor(WindowEmperor).Closes #19049
Validation Steps Performed
cmdcreates windows in the foreground ✅cmd /c start /max cmdcreates a fullscreen tab ✅cmd /c start /min cmddoes not work ❌