From 03a69c3187c77969c88e689facfd1c29821f492a Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Fri, 31 Jul 2020 12:30:23 -0500 Subject: [PATCH 01/39] start drafting this beast of a doc --- .../#5000 - Process Model 2.0.md | 162 ++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md diff --git a/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md b/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md new file mode 100644 index 00000000000..5b8edeba788 --- /dev/null +++ b/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md @@ -0,0 +1,162 @@ +--- +author: Mike Griese @zadjii-msft +created on: 2020-07-31 +last updated: 2020-07-31 +issue id: #5000 +--- + +# Windows Terminal Process Model 2.0 + +## Abstract + +The Windows Terminal currently exists as a single process per window, with one +connection per terminal pane (which could be an additional conpty process and +associated client processes). This model has proven effective for the simple +windowing we've done so far. However, in order to support scenarios like +dragging tabs into other windows, or having one top-level window with different +elevation levels within it, this single process model will not be sufficient. + +This spec outlines changes to the Terminal process model in order to enable the +following scenarios: + +* Tab Tearoff/ Reattach ([#1256]) +* Run `wt` in the current window ([#4472]) +* Single Instance Mode ([#2227]) +* Quake Mode ([#653]) +* Mixed Elevation ([#1032] & [#632]) + +## Inspiration + +Much of the design for this feature was inspired by (what I believe is) the web +browser process model. For a web browser, there's often a seperate process for +each of the tabs within the browser, to help isolate the actual tabs from one +another. + +## Solution Design + +The primary concept introduced by this spec is the idea of two types of process, +which will work together to create a single Terminal window. These processes +will be referred to as the "Window Process" and the "Content Process". +* A **Window Process** is a process which is responsible for drawing a window to + the desktop, and accepting input from the user. This is a window which hosts + our XAML content, and the window which the user interacts with. +* A **Content Process** is a process which hosts a single terminal instance. + This is the process that hosts the terminal buffer, state machine, connection, + and is also responsible for the `Renderer` and `DxEngine`. + +These two types of processes will work together to present both the UI of the +Windows Terminal app, as well as the contents of the terminal buffers. A single +WP may be in communication with multiple CPs - one per terminal instance. That +means that each and every `TermControl` in a WP will be hosted in a seperate +process. + +The WP will be full of "thin" `TermControl`s - controls which are only the XAML +layer and a WinRT object which is hosted by the CP. These thin `TermControl`s +will recieve input, and have all the UI elements (including the +`SwapChainPanel`) of the `TermControl` today, but the actual _rendering_ to the +swap chain, and the handling of those inputs will be done by the content +process. + +As a broad outline, whenever the window wants to create a terminal, the flow +will be something like the following: + +1. A WP will spawn a new CP, with a unique ID. +2. The WP will attach itself to the CP, indicating that it (the WP) is the CP's + hosting window. +3. When the CP creates it's swap chain, it will raise an event which the WP will + use to connect that swap chain to the WP's `SwapChainPanel`. + +### Tab Tearoff/ Reattach + +### Single Instance Mode + +Monarch/Servant architecture + +### Run `wt` in the current window + +We should reserve the session id `0` to always refer to "The current window", if +there is one. So `wt -s 0 new-tab` will run `new-tab` in the current window (if +we're being run from WT), otherwise it will create a new window. + +In Single-Instance mode, running `wt -s 0` outside a WT window will still cause +the commandline to glom to the existing single terminal instance, if there is +one. + +### Quake Mode +### Mixed Elevation + + +## UI/UX Design + + +## Capabilities + + + + + + + + + + + + + + + + + + + + + + +
Accessibility +TODO: This is _very_ applicable +
Security +TODO: This is _very_ applicable +
Reliability +TODO: This is _very_ applicable +
Compatibility +TODO: This is _very_ applicable +
Performance, Power, and Efficiency +TODO: This is _very_ applicable +
+ +## Potential Issues + +TODO: These are _very_ expected + +## Footnotes + +[1]: + +## Future considerations + +* Yea add these + + + +## TODOs + +* Prove that a elevated window can host an unelevated content +* Prove that I can toss CP IDs from one window to another +* come up with a commandline mechanism for starting one `wt.exe` process either + as a window process, or as a content process +* What about handling XAML input events? The "thin" term control will need to do + that in-proc, so it can reply on the UI thread if a particular keystroke was + handled or not. + - I'm almost certain that the `Terminal::HandleKey()` stuff is going to need + to be handled in the thin control, and the core will need to raise events to + the control? oof + + + +[#5000]: https://github.com/microsoft/terminal/issues/5000 +[#1256]: https://github.com/microsoft/terminal/issues/1256 +[#4472]: https://github.com/microsoft/terminal/issues/4472 +[#2227]: https://github.com/microsoft/terminal/issues/2227 +[#653]: https://github.com/microsoft/terminal/issues/653 +[#1032]: https://github.com/microsoft/terminal/issues/1032 +[#632]: https://github.com/microsoft/terminal/issues/632 From 69abf3cec83e0f1fdc13ba2473ae8290d8546fba Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Fri, 31 Jul 2020 14:01:28 -0500 Subject: [PATCH 02/39] Pushing changes for the end of the day --- .../#5000 - Process Model 2.0.md | 117 +++++++++++++++++- 1 file changed, 111 insertions(+), 6 deletions(-) diff --git a/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md b/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md index 5b8edeba788..04021b5f64a 100644 --- a/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md +++ b/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md @@ -34,6 +34,8 @@ another. ## Solution Design +### Window and Content Processes + The primary concept introduced by this spec is the idea of two types of process, which will work together to create a single Terminal window. These processes will be referred to as the "Window Process" and the "Content Process". @@ -65,14 +67,92 @@ will be something like the following: hosting window. 3. When the CP creates it's swap chain, it will raise an event which the WP will use to connect that swap chain to the WP's `SwapChainPanel`. +4. The will process output from the connection and draw to the swap chain. The + contents that are rendered to the swap chain will be visible in the WP's + `SwapChainPanel`, because they share the same underlying kernel object. + +The CP will be responsible for the terminal buffer and other terminal state (the +core `Terminal` object), as well as the `Renderer`, `DxEngine`, and +`TerminalConnection`. These are all being combined in the CP, as to maximize +performance. We don't want to have to hop across the process boundary multiple +times per frame, so the renderer must be in the same process as the buffer. +Similarly, we want to be able to read data off of the connection as quickly as +possible, and the best way to do this will be to have the connection in the same +process as the `Terminal` core. + + +#### Technical Details + +Much of the above is powered by the magic of WinRT (which is powered by the +magic of COM). Whenever we create WinRT types, WinRT provides metadata about +these types that not only enables us to use them in-proc (via the +implementation), but also enables using these types _across process boundaries_. + +Typically, these classes are given a unique GUID for the class. A process that +wants to implement one of these out-of-proc WinRT objects can register with the +system to say "I make `MyClass`'s, and their GUID is `{foo}`". these are called +WinRT _servers_. Then, consumers (_clients_) of that class can ask the system +"I'd like to instantiate a `{foo}` please", which will cause the server to +create a new instance of that object (in the server process), and the client +will be given a winrt object which can interact with the classes WinRT +projection. + +A server can register the types it produces with `CoRegisterClassObject`, like so: + +```c++ +CoRegisterClassObject(MyClassGUID, + winrt::make().get(), + CLSCTX_LOCAL_SERVER, + REGCLS_MULTIPLEUSE, + &dwRegistration); + +``` + +And a client can attempt to get an instance of `MyClass` with + +```c++ +auto myClass = create_instance(MyClassGUID, CLSCTX_LOCAL_SERVER); +``` + +We're going to be using that system a little differently here. Instead of using +a GUID to represent a single _Class_, we're going to use the GUID to uniquely +identify _CPs_. Each CP will recieve a unique GUID when it is created, and it +will register as the server for that GUID. Then, any WP will be able to connect +to that specific CP strictly by GUID. Because each GUID is unique to each +content process, any time any client calls `create_instance<>(theGuid, ...)`, it +will uniquely attempt to connect to the content process hosting `theGuid`. + +This means that if we wanted to have a second WP connect to the _same_ CP as +another window, all it needs is the CP's GUID. + +#### Scenario: Tab Tearoff/ Reattach + +Oh the flow between these sections is less than stellar. I need to introduce why moving object is hard first, then talk about just moving guids + +#### Scenario: Mixed Elevation -### Tab Tearoff/ Reattach +### Monarch and Servant Processes -### Single Instance Mode +With the current design, it's easy to connect many CPs to a WP, and move those +CPs easily between windows. However, we want to make sure that it's also +possible to communicate between these processes. What if we want to have only a +single WT instance, so that whenever Wt is run, it creates a tab in the existing +window? What if you want to run a commandline in a given WT window? -Monarch/Servant architecture +In addition to the concept of Window and Content Processes, we'll also be +introducing another type of categorization for WPs. These are "Monarch" and +"Servant" processes. This will allow for the coordination across the various windows by the Monarch. -### Run `wt` in the current window + + + + + +#### Scenario: Single Instance Mode + +In Single Instance mode, the monarch _is_ the single instance. When `wt` is run, and it determines that it is not the monarch, it'll as the monarch if it's in single instance mode. If it is, then the servant that's starting up will instead pass it's commandline arguments to the monarch process, and let the monarch handle them, then exit. + +#### Scenario: Run `wt` in the current window We should reserve the session id `0` to always refer to "The current window", if there is one. So `wt -s 0 new-tab` will run `new-tab` in the current window (if @@ -82,8 +162,7 @@ In Single-Instance mode, running `wt -s 0` outside a WT window will still cause the commandline to glom to the existing single terminal instance, if there is one. -### Quake Mode -### Mixed Elevation +#### Scenario: Quake Mode ## UI/UX Design @@ -128,6 +207,25 @@ TODO: This is _very_ applicable TODO: These are _very_ expected +Extensions & non-terminal content. + +## Implementation Plan + +Obviously, everything that's discussed here represents an _enormous_ amount of +work. It's important that as we move towards this new model, that we do so in +safe, incremental chunks, such that each step is still a viable Terminal +application, but no single step is too large to review. As such, I'll attempt to +break down the work required into atomic pieces, and provide a relative ordering +for the work described above. + + +1. Add Monarch/Servant capabilities to `wt` WPs. + - This does not need to involve any actual UX functionality, simply have the + WT instances communicate with one another to see who is the Monarch. + - The monarch will track and assign IDs to servants. +2. (Dependant on 1): Add support for running a `wt` commandline in an existing window +3. (Dependant on 1, maybe on 2): Add support for "single instance mode" + ## Footnotes [1]: @@ -151,6 +249,11 @@ TODO: These are _very_ expected to be handled in the thin control, and the core will need to raise events to the control? oof + +## Resources + +* [Tab Tearout in the community toolkit] + [#5000]: https://github.com/microsoft/terminal/issues/5000 @@ -160,3 +263,5 @@ TODO: These are _very_ expected [#653]: https://github.com/microsoft/terminal/issues/653 [#1032]: https://github.com/microsoft/terminal/issues/1032 [#632]: https://github.com/microsoft/terminal/issues/632 + +[Tab Tearout in the community toolkit]: https://github.com/windows-toolkit/Sample-TabView-TearOff From 3f7688d5a45dd2a4376cfc9f94692b9c2e2a5f9e Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Wed, 5 Aug 2020 16:49:10 -0500 Subject: [PATCH 03/39] Okay I think I've gotten through window/content processes --- .../#5000 - Process Model 2.0.md | 184 +++++++++++++----- 1 file changed, 140 insertions(+), 44 deletions(-) diff --git a/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md b/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md index 04021b5f64a..58772572bd1 100644 --- a/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md +++ b/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md @@ -32,6 +32,59 @@ browser process model. For a web browser, there's often a seperate process for each of the tabs within the browser, to help isolate the actual tabs from one another. +## Background + +In order to better understand some of the following technical solutions, it's +important to understand some of the technical hurdles that need to be overcome. + +### Mixed admin and unelevated clients in a single window + +Let's presume that you're a user who wants to be able to open an elevated tab +within an otherwise unelevated Terminal window. We call this scenario "mixed +elevation" - the tabs within the Terminal can be running either unelevated _or_ +elevated client applications. + +It wouldn't be terribly difficult for the unelevated Terminal to request the +permission of the user to spawn an elevated client application. The user would +see a UAC prompt, they'd accept, and then they'd be able to have an elevated +shell alongside their unelevated tabs. + +However, this creates an escalation of priviledge vector. Now, there's an +unelevated window which is connected directly to an elevated process. At this +point, any other unelevated application could send input to the Terminal's +`HWND`, making it possible for another unelevated process to "drive" the +Terminal window and send commands to the elevated client application. + +### Drag and drop tabs to create new windows + +Another important scenario we're targeting is the ability to drag a tab out of +the Terminal window and create a new Terminal window. Obviously, when we do +this, we want the newly created window to be able to persist all the same state +that the original window had for that tab. For us, that primarily means the +buffer contents and connection state. + +However, _how_ do we move the terminal state to another window? The terminal +state is all located in-memory of the thread that created the `TermControl` +hosting the terminal buffer. It's fairly challenging to re-create this state in +another process. + +Take a look at [this +document](https://github.com/windows-toolkit/Sample-TabView-TearOff) for more +background on how the scenario might work. + +There's really only a limited selection of things that a process could transfer +to another with a drag and drop operation. If we wanted to use a string to +transfer the data, we'd somehow need to serialize then entire state of the tab, +it's tree of panes, and the state of each of the buffers in the tab, into some +sort of string, and then have the new window deserialize that string to +re-create the tab state. Consider that each bufer might include 32000 rows of +80+ characters each, each with possibly RGB attributes, and you're looking at +30MB+ of raw data to serialize and de-serialize per buffer, minimum. This sounds +extremely fragile, if not impossible to do robustly. + +What we need is a more effective way for seperate Terminal windows to to be able +to connect to and display content that's being hosted in another process. + ## Solution Design ### Window and Content Processes @@ -48,37 +101,39 @@ will be referred to as the "Window Process" and the "Content Process". These two types of processes will work together to present both the UI of the Windows Terminal app, as well as the contents of the terminal buffers. A single -WP may be in communication with multiple CPs - one per terminal instance. That -means that each and every `TermControl` in a WP will be hosted in a seperate -process. +window process may be in communication with multiple content processes - one per +terminal instance. That means that each and every `TermControl` in a window +process will be hosted in a seperate process. -The WP will be full of "thin" `TermControl`s - controls which are only the XAML -layer and a WinRT object which is hosted by the CP. These thin `TermControl`s -will recieve input, and have all the UI elements (including the -`SwapChainPanel`) of the `TermControl` today, but the actual _rendering_ to the -swap chain, and the handling of those inputs will be done by the content -process. +The window process will be full of "thin" `TermControl`s - controls which are +only the XAML layer and a WinRT object which is hosted by the content process. +These thin `TermControl`s will recieve input, and have all the UI elements +(including the `SwapChainPanel`) of the `TermControl` today, but the actual +_rendering_ to the swap chain, and the handling of those inputs will be done by +the content process. As a broad outline, whenever the window wants to create a terminal, the flow will be something like the following: -1. A WP will spawn a new CP, with a unique ID. -2. The WP will attach itself to the CP, indicating that it (the WP) is the CP's - hosting window. -3. When the CP creates it's swap chain, it will raise an event which the WP will - use to connect that swap chain to the WP's `SwapChainPanel`. +1. A window process will spawn a new content process, with a unique ID. +2. The window process will attach itself to the content process, indicating that + it (the window process) is the content process's hosting window. +3. When the content process creates it's swap chain, it will raise an event + which the window process will use to connect that swap chain to the window + process's `SwapChainPanel`. 4. The will process output from the connection and draw to the swap chain. The - contents that are rendered to the swap chain will be visible in the WP's - `SwapChainPanel`, because they share the same underlying kernel object. + contents that are rendered to the swap chain will be visible in the window + process's `SwapChainPanel`, because they share the same underlying kernel + object. -The CP will be responsible for the terminal buffer and other terminal state (the -core `Terminal` object), as well as the `Renderer`, `DxEngine`, and -`TerminalConnection`. These are all being combined in the CP, as to maximize -performance. We don't want to have to hop across the process boundary multiple -times per frame, so the renderer must be in the same process as the buffer. -Similarly, we want to be able to read data off of the connection as quickly as -possible, and the best way to do this will be to have the connection in the same -process as the `Terminal` core. +The content process will be responsible for the terminal buffer and other +terminal state (the core `Terminal` object), as well as the `Renderer`, +`DxEngine`, and `TerminalConnection`. These are all being combined in the +content process, as to maximize performance. We don't want to have to hop across +the process boundary multiple times per frame, so the renderer must be in the +same process as the buffer. Similarly, we want to be able to read data off of +the connection as quickly as possible, and the best way to do this will be to +have the connection in the same process as the `Terminal` core. #### Technical Details @@ -116,32 +171,49 @@ auto myClass = create_instance(MyClassGUID, CLSCTX_LOCAL_SERVER) We're going to be using that system a little differently here. Instead of using a GUID to represent a single _Class_, we're going to use the GUID to uniquely -identify _CPs_. Each CP will recieve a unique GUID when it is created, and it -will register as the server for that GUID. Then, any WP will be able to connect -to that specific CP strictly by GUID. Because each GUID is unique to each -content process, any time any client calls `create_instance<>(theGuid, ...)`, it -will uniquely attempt to connect to the content process hosting `theGuid`. +identify _content processes_. Each content process will recieve a unique GUID +when it is created, and it will register as the server for that GUID. Then, any +window process will be able to connect to that specific content process strictly +by GUID. Because each GUID is unique to each content process, any time any +client calls `create_instance<>(theGuid, ...)`, it will uniquely attempt to +connect to the content process hosting `theGuid`. -This means that if we wanted to have a second WP connect to the _same_ CP as -another window, all it needs is the CP's GUID. +This means that if we wanted to have a second window process connect to the +_same_ content process as another window, all it needs is the content process's +GUID. #### Scenario: Tab Tearoff/ Reattach -Oh the flow between these sections is less than stellar. I need to introduce why moving object is hard first, then talk about just moving guids +Because all that's needed to uniquely identify an individual terminal instance +is the GUID of the content process, it becomes fairly trivial to be able to +"move" a terminal instance from one window to another. + +When a drag/drop operation happens, the payload of the event will simply contain +the structure of the tree of panes, and the GUIDs of the content processes that +make up the leaf nodes of the tree. The recieving window process will then be +able to use that tree to be able to re-create a similar pane structure in its +window, and use the GUIDs to be able to connect to the content processes for the +terminals in that tab. + +The terminal buffer never needs to move from one process to another - it always +stays in just a single content process. The only thing that changes is the +window process which is rendering the content process's swapchain. #### Scenario: Mixed Elevation ### Monarch and Servant Processes -With the current design, it's easy to connect many CPs to a WP, and move those -CPs easily between windows. However, we want to make sure that it's also -possible to communicate between these processes. What if we want to have only a -single WT instance, so that whenever Wt is run, it creates a tab in the existing -window? What if you want to run a commandline in a given WT window? +With the current design, it's easy to connect many content processes to a window +process, and move those content processes easily between windows. However, we +want to make sure that it's also possible to communicate between these +processes. What if we want to have only a single WT instance, so that whenever +Wt is run, it creates a tab in the existing window? What if you want to run a +commandline in a given WT window? In addition to the concept of Window and Content Processes, we'll also be -introducing another type of categorization for WPs. These are "Monarch" and -"Servant" processes. This will allow for the coordination across the various windows by the Monarch. +introducing another type of categorization for window processes. These are +"Monarch" and "Servant" processes. This will allow for the coordination across +the various windows by the Monarch. @@ -150,7 +222,11 @@ introducing another type of categorization for WPs. These are "Monarch" and #### Scenario: Single Instance Mode -In Single Instance mode, the monarch _is_ the single instance. When `wt` is run, and it determines that it is not the monarch, it'll as the monarch if it's in single instance mode. If it is, then the servant that's starting up will instead pass it's commandline arguments to the monarch process, and let the monarch handle them, then exit. +In Single Instance mode, the monarch _is_ the single instance. When `wt` is run, +and it determines that it is not the monarch, it'll as the monarch if it's in +single instance mode. If it is, then the servant that's starting up will instead +pass it's commandline arguments to the monarch process, and let the monarch +handle them, then exit. #### Scenario: Run `wt` in the current window @@ -219,7 +295,7 @@ break down the work required into atomic pieces, and provide a relative ordering for the work described above. -1. Add Monarch/Servant capabilities to `wt` WPs. +1. Add Monarch/Servant capabilities to `wt` window processes. - This does not need to involve any actual UX functionality, simply have the WT instances communicate with one another to see who is the Monarch. - The monarch will track and assign IDs to servants. @@ -234,12 +310,31 @@ for the work described above. * Yea add these - +* Non-terminal content in the Terminal. We've now created a _very_ + terminal-specific IPC mechanism for transfering _terminal_ state from one + thread to another. When we start to plan on having panes that contain + non-terminal content in them, they won't be able to move across-process like + this. Options available here include: + - Passing some well-defined string / JSON blob from the source process to the + target process, such that the extension could use that JSON to recreate + whatever state the pane was last in. The extension would be able to control + this content entirely. + - Maybe they want to pass a GUID that the new process will be able to user + to `CreateInstance` the singleton for their UI and then dupe their swap + chain to the new thread... + - Preventing tabs with non-terminal content open in them from being dragged + out entirely. They're stuck in their window until the non-terminal content + is removed. +* A previous discussion with someone on the input team brought up the following + idea: When a tab is being torn out, move all the _other_ tabs to a new window, + and continue dragging the current window. This should make the drag/drop + experience feel more seamless, and might be able to allow us to render the tab + content as we're drag/dropping. ## TODOs * Prove that a elevated window can host an unelevated content -* Prove that I can toss CP IDs from one window to another +* Prove that I can toss content process IDs from one window to another * come up with a commandline mechanism for starting one `wt.exe` process either as a window process, or as a content process * What about handling XAML input events? The "thin" term control will need to do @@ -252,7 +347,8 @@ for the work described above. ## Resources -* [Tab Tearout in the community toolkit] +* [Tab Tearout in the community toolkit] - this document proved invaluable to + the background of tearing a tab out of an application to create a new window. From 93d4803cb67ee5d3cb81360f92ea0e23e917482d Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Thu, 6 Aug 2020 10:49:40 -0500 Subject: [PATCH 04/39] Add lots of notes about how we'll actually implement all this --- .../#5000 - Process Model 2.0.md | 176 +++++++++++++++++- 1 file changed, 167 insertions(+), 9 deletions(-) diff --git a/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md b/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md index 58772572bd1..5bbb24a995a 100644 --- a/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md +++ b/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md @@ -1,7 +1,7 @@ --- author: Mike Griese @zadjii-msft created on: 2020-07-31 -last updated: 2020-07-31 +last updated: 2020-08-06 issue id: #5000 --- @@ -201,6 +201,58 @@ window process which is rendering the content process's swapchain. #### Scenario: Mixed Elevation +With the ability for window processes to connect to other pre-existing content +processes, we can now also support mixed elevation scenarios as well. + +If a user requests a new elevated tab from an otherwise unelevated window, we +can use UAC to create a new, elevated WP, and "move" all the current tabs to +that WP, as well as the new elevated client. Now, the WP is elevated, preventing +it from input injection, but still contains all the previously existing tabs. +The original WP can now be discarded, as the new elevated WP will pretend to be +the original window. + +We would probably want to provide some additional configuration options here as +well: +* Users will most likely want to be able to specify that a given profile should + always run elevated. + - We should also provide some argument to the `NewTerminalArgs` (used by the + `new-tab` and `split-pane` actions) to allow a user to elevate an otherwise + unelevated profile. +* We'll probably want to create new CPs in a medium-IL context by default, + unless the profile or launch args otherwise indicates launching elevated. So a + WP running elevated would still create unelevated profiles by default. +* Currently, if a user launches the terminal as an administrator, then _all_ of + their tabs run elevated. We'll probably want to provide a similar + configuration as well. Maybe if a WP is initially launched as elevated (rather + than inheriting from an existing session), then it could either: + - default all future connections it creates to elevated connections + - assume the _first_ tab (or all the terminals created by the startup + commandline) should be elevated, but then subsequent connections would + default to unelevated processes. + +It's a long-standing platform bug that you cannot use drag-and-drop in elevated +scenarios. This unfortunately means that elevated WPs will _not_ be able to tear +tabs out into their own windows. Even tabs that only contain unelevated CPs in +them will not be able to be torn out, because the drag-and-drop service is +fundamentally incapable of connecting to elevated windows. + +We should probably have a discussion about what happens when the last elevated +CP in an elevated WP is closed. If an elevated WP doesn't have any remaining +elevated CPs, then it should be able to revert to an unelevated WP. Should we do +this? There's likely some visual flickering that will happen as we re-create the +new window process, so maybe it would be unappealing to users. However, there's +also the negative side effect that come from elevated windows (the aformentioned +lack of drag/drop), so maybe users will want to return to the more permissive +unelevated WP. + +This is one section where unfortunately I don't have a working prototype yet. +From my research, an elevated process cannot simply `create_instance` a class +that's hosted by an unelevated process. However, after proposing this idea to +the broad C++/WinRT discussion alias, no one on that thread immediately shot +down the idea as being impossible or terrible from a security perspective, so I +believe that it _will_ be possible. We still need to do some research on the +actual mechanisms for some token impersonation. + ### Monarch and Servant Processes With the current design, it's easy to connect many content processes to a window @@ -269,6 +321,8 @@ TODO: This is _very_ applicable Compatibility TODO: This is _very_ applicable + +TODO: Concerns with the Universal App version of the Terminal? @@ -295,12 +349,111 @@ break down the work required into atomic pieces, and provide a relative ordering for the work described above. +
+ 1. Add Monarch/Servant capabilities to `wt` window processes. - - This does not need to involve any actual UX functionality, simply have the + - This does not need to involve any actual UX functionality, simply have the WT instances communicate with one another to see who is the Monarch. - - The monarch will track and assign IDs to servants. -2. (Dependant on 1): Add support for running a `wt` commandline in an existing window -3. (Dependant on 1, maybe on 2): Add support for "single instance mode" + - The monarch will track and assign IDs to servants. +2. (Dependent on 1): Add support for running a `wt` commandline in an existing + window + - Monarch should assign simple IDs for use with the `wt` commandline + - `0` should be reserved as an alias for "the current window" +3. (Dependent on 1, maybe on 2): Add support for "single instance mode". New + servant windows will first ask the monarch if it's in single instance mode, + and pass the servant's commandline to the monarch if it is. +4. (Dependent on 1): Monarch registers for the global quake hotkey, and uses + that to activate _the monarch_. + - Pressing the key when a window is currently focused should minimize? Do nothing? +5. (Dependent on 4): any othe quake mode improvements: + - Summon the nearest window + - make the window "drop down" from the top + - Summon the MRU window + - It would need to track a the MRU for windows, so pressing the shortcut when + no window is active summons the MRU one. + +
+ +6. Change `TermControl`/`DxEngine` to create its own swap chain using + `DCompositionCreateSurfaceHandle` and + `CreateSwapChainForCompositionSurfaceHandle`. This is something that's + already done in commit TODO:`ffffff`. + +7. (Dependent on 6) Refactor `TermControl` to allow it to have a WinUI layer and + a Core layer. The WinUI layer will be only responsible for interacting with + XAML, processing input, etc, and sending it to the core layer, which handles + all the logic concerning input. The core will expose these methods that the + UI layer calls as projected methods + +8. (Dependent on 7): Expose the methods the UI layer calls on the core as + projected methods. The control is still fundamentally in-proc, and the UI + layer calls directly into the implementation of the control core, but the + methods _could_ be used x-proc. + +9. (Dependent on 8): Enable a `TermControl` to have an out-of proc core. + - The core will need to be able to accept a PID using some method, and be able + to `DuplicateHandle` the swapchain to that PID. It'll also need to raise the + `SwapChainHandleChanged` event. + - The Control UI layer would need to recieve a GUID in the ctor, and use that + connect to the out-of-proc core. It'll pass the UI's PID to the core, and + attach to the core's swap chain handle. + - The UI layer will be smart enough to call either the implementation method + (if it's hosting in-proc) or the projected method (if it's out-of-proc). + +10. (Dependent on 9?) The core layer needs to be able to construct connections + itself, rather than have one passed in to it. + - In the future we'll probably want this to be more extensible, but for now + we can probably just pass an enum for connection type, and an + `IConnectionSettings` object to the core, and use the `ConnectionType` and + setting to build the limited types of connection we currently have. + +11. (Dependent on 9, 10) `wt.exe` needs to be able to spawn as a content + process, accepting a GUID for its ID, and spawning a single control core. + - When the content process is first spawned, it won't create the core or + connection, nor will it have any settings. The first client to connect to + the content process should make sure to set up the settings before + initializing the control. + - A scratch XAML Island application might be a useful tool at this point, to + test hosting the content in another process (that's not a full-blown + terminal instance). + +12. (Dependent on 11) TerminalApp creates new content processes for each and + every terminal instance it spawns. At this point, there's no tearout, but + the terminal instances are all out-of-proc from the window process. + +13. (Dependent on 12) Terminal can drop tabs onto another WT window process by + communicating the structure of the tab's panes and their content GUIDs. + - At this point, the tabs can't be torn out to create new windows, only move + between existing windows + - It might be hard to have the tab "attach" to the tab row of the other window. + - It might be easiest to do this after 1, and communicate to the new WP the + GUID of the old WP and the tab within the original WP, and just have the + new WP ask the old WP what the structure of the tab is + - Though, the tab won't be in the original process's list of tabs anymore, + so that might not be helpful. + +14. `wt` accepts an initial position, size on the commandline. + +15. (Dependent on 13, 14) Tearing out a tab and dropping it _not_ on another WT + window creates a new window for the tab. + - This will require and additional argument to `wt` for it to be able to + inherit the structure of a given set of tabs. Either this will need to be + passed on the cmdline, or the newly spawned process will need to be able to + communicate with the original process to ask it what structure it should be + building. + - Doing this after 1 might be helpful. + - Needs 14 to be able to specify the location of the new window. + +
+ +16. Add support for a `NewWindow` action +17. `wt` accepts a commandline arg to force it to auto-elevate itself if it + isn't already elevated. +18. (Dependent on 16, 17) Users can mark a profile as `"elevated": true`, to + always force a new elevated window to be created for elevated profiles. +19. (Dependent on 18, 13) When a user creates an elevated profile, we'll + automatically create an elevated version of the current window, and move all + the current tabs to that new window. ## Footnotes @@ -330,14 +483,19 @@ for the work described above. and continue dragging the current window. This should make the drag/drop experience feel more seamless, and might be able to allow us to render the tab content as we're drag/dropping. +* We could definitely do a `NewWindowFromTab(index:int?)` action that creates a + new window from a current tab once this all lands. + - Or it could be `NewWindowFromTab(index:union(int,int[])?)` to specify the + current tab, a specific tab, or many tabs. + ## TODOs -* Prove that a elevated window can host an unelevated content -* Prove that I can toss content process IDs from one window to another -* come up with a commandline mechanism for starting one `wt.exe` process either +* [ ] Prove that a elevated window can host an unelevated content +* [ ] Prove that I can toss content process IDs from one window to another +* [ ] come up with a commandline mechanism for starting one `wt.exe` process either as a window process, or as a content process -* What about handling XAML input events? The "thin" term control will need to do +* [ ] What about handling XAML input events? The "thin" term control will need to do that in-proc, so it can reply on the UI thread if a particular keystroke was handled or not. - I'm almost certain that the `Terminal::HandleKey()` stuff is going to need From e8d25790e07049555e3236063c699552477b1e01 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Thu, 6 Aug 2020 16:42:17 -0500 Subject: [PATCH 05/39] I think I'm done with the main body of the spec. All the concerns still need to be filled in, but the fundamental idea is done --- .../#5000 - Process Model 2.0.md | 182 +++++++++++++++++- 1 file changed, 175 insertions(+), 7 deletions(-) diff --git a/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md b/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md index 5bbb24a995a..f590867b1d7 100644 --- a/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md +++ b/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md @@ -267,24 +267,113 @@ introducing another type of categorization for window processes. These are "Monarch" and "Servant" processes. This will allow for the coordination across the various windows by the Monarch. - - - +There will only ever be one monarch process at a given time, and every other WT +WP is a servant process. However, we want this system to be redundant, so that +if the monarch ever dies, one of the remaining servant processes can take over +for it. The new monarch will be chosen at random, so we'll call this a +probabalistic elective monarchy. + +Essentially, the probabalistic elective monarchy will work in the following way: + +1. We'll introduce a WinRT class (for the puspose of this doc we'll call it + `Monarch`), with a unique GUID. +2. When any WP starts up, it'll first try to register as the server for the + `Monarch` WinRT class. + - The OS will allow subsequent processes to successfully register as the + server for `Monarch` objects, but when someone tries to `create_instance` a + `Monarch`, the OS will always create the `Monarch` from the first process to + register. +3. After registering as a server for `Monarch`s, attempt to create a `Monarch` + using `winrt::create_instance`. +4. Using that `Monarch`, ask it for it's PID. + - If that PID is the same as the PID of the current process, then the WP + knows that it is the monarch. + - If that PID is some other process, then we know that we're not currently + the monarch. + - If we don't currently have an ID assigned to us, then ask the `Monarch` + to assign one to us. + - If we do have an ID (from a previous monarch), then let the new monarch + know that we exist. +5. If we're a servant process, then `WaitForSingleObject` on a handle to the + monarch process. When the current monarch dies, go back to 3. At this point, + we might be appointed the new monarch (by whatever process the OS uses to + choose who the new server for `Monarch`s is.) + - We're suggesting `WaitForSingleObject` here as opposed to having the + monarch raise a WinRT event when it's closed, because it's possible that + the monarch closes unexpectedly, before it has an + opprotunity to notify the servants. + +By this mechanism, the processes will be able to communicate with the Monarch, +who'll be responsible for managing any inter-process communication between +windows we might need. #### Scenario: Single Instance Mode -In Single Instance mode, the monarch _is_ the single instance. When `wt` is run, -and it determines that it is not the monarch, it'll as the monarch if it's in +In "Single Instance Mode", the monarch _is_ the single instance. When `wt` is run, +and it determines that it is not the monarch, it'll ask the monarch if it's in single instance mode. If it is, then the servant that's starting up will instead pass it's commandline arguments to the monarch process, and let the monarch handle them, then exit. +So, this will make it seem like new starting a new `wt.exe` will just create a +new tab in the existing window. If someone does `wt -d .` in explorer, + #### Scenario: Run `wt` in the current window +One often requested scenario is the ability to run a `wt.exe` commandline in the +current window, as opposed to always creating a new window. With the ability to +communicate between different window processes, one could imagine a logical +extension of this scenario being "run a `wt` commandline in _any_ given WT +window". + +This spec by no means attempts to fully document how this functionality should +work. This scenarios deserves it's own spec to discuss various differnt naming +schemes for the commandline parameters. The following is given as an example of +how these arguments _might_ be authored and implemented to satisfy some of these +scenarios. + +Since each WP will have it's own unique ID assigned to it by the monarch, then +running a command in a given window with ID `N` should be as easy as something +like: + +``` +wt.exe --session N new-tab ; split-pane +``` + +(or for shorthand, `wt -s N new-tab ; split-pane`). + +This would create a new servant, who could then ask the monarch if there is a +servant with ID `N`. If there is, then the servant can connect to that other +servant, dispatch the current commandline to that other servant, and exit, +before ever creating a window. If this commandline instead creates a new monarch +process, then there was _no_ other monarch, and so there must logically not be +any other existing WT windows, and the `--session N` argument could be safely +ignored, and the command run in the current window. + We should reserve the session id `0` to always refer to "The current window", if there is one. So `wt -s 0 new-tab` will run `new-tab` in the current window (if -we're being run from WT), otherwise it will create a new window. +we're being run from WT). + +If `wt -s 0 ` is run _outside_ a WT instance, it could attempt to glom +onto _the most recent WT window_ instead. This seems more logical than something +like `wt --session last` or some other special value indicating "run this in the +MRU window". + +That might be a simple, but **wrong**, implementation for "the current window". +If the servants always raise an event when their window is focused, and the +monarch keeps track of the MRU order for servants, then one could naively assume +that the execution of `wt -s 0 ` would always return the window the +user was typing in, the current one. However, if someone were to do something +like `sleep 10 ; wt -s 0 `, then the user could easily focus another +WT window during the sleep, which would cause the MRU window to not be the same +as the window executing the command. + +I'm not sure that there is a better solution for the `-s 0` scenario other than +atempting to use the `WT_SESSION` environment variable. If a `wt.exe` process is +spawned and that's in it's environment variables, it could try and ask the +monarch for the servant who's hosting the session corresponding to that GUID. +This is more of a theoretical solution than anything else. In Single-Instance mode, running `wt -s 0` outside a WT window will still cause the commandline to glom to the existing single terminal instance, if there is @@ -292,9 +381,78 @@ one. #### Scenario: Quake Mode +"Quake mode" has a variety of different scenarios[[1]](#footnote-1) +that have all been requested, more than what fits cleanly into this spec. +However, there's one key aspect of quake mode that is specifically relevant and +worth mentioning here. + +One of the biggest challenges with registering a global shortcut handler is +_what happens when multiple windows try to register for the same shortcut at the +same time_? From my initial research, it seems that only the first process to +register for the shortcut will succeed. This makes it hard for multiple windows +to handle the global shortcut key gracefully. If a second window is created, and +it fails to register the global hotkey, then the first window is closed, there's +no way for the second process to track that and re-register as the handler for +that key. + +With the addition of monarch/servant processes, this problem becomes much easier +to solve. Now, the monarch process will _always_ be the process to register the +shortcut key, whnever it's elected. If it dies and another servant is elected +monarch, then the new monarch will register as the global hotkey handler. + +Then, the monarch can use it's pre-established channels of communication with +the other window processes to actuall drive the response we're looking for. + +#### Rough interface design + +This is by no means definitive, but one could imagine the `Monarch` and +`Servant` classes exposing the following WinRT projections: + +```c# +class Servant +{ + void AssignID(UInt64 id); // Should only be called by the monarch + UInt64 GetID(); + UInt64 GetPID(); + Boolean ExecuteCommandline(String[] args, Sting currentDirectory); + event TypedEventHandler WindowActivated; +} + +class Monarch : Servant +{ + UInt64 AddServant(Servant servant); + Boolean IsInSingleInstanceMode(); + Servant GetServant(UInt64 servantID); + Servant GetMostRecentServant(); +} +``` + +The servant process can instantiate the `Servant` object itself, in it's process +space. Initially, the `Servant` object won't have an ID assigned, and the call +to `AddServant` on the `Monarch` will both cause the Monarch to assign the +`Servant` an ID, and add it to the Monarch process's list of processes. If the +`Servant` already had an ID assigned by a previous monarch, then the new onarch +will simply re-use the value already existing in the `Servant`. Now, the monarch +can call methods on the `Servant` object directly to trigger changes in the +servant process. + +Note that the monarch also needs to have a servant ID, because the monarch is +really just a servant with the added responsibility of keeping track of the +other servants as well. + +It's important that `ExecuteCommandline` takes a `currentDirectory` parameter. +Consider the scenario `wt -s 0 -d .` - in this scenario, the process that's +executing the provided commandline should first change its working directory to +the provided `currentDirectory` so that something like `.` actually refers to +the directory where the command was executed. ## UI/UX Design +TODO: Is there really all that much UX for this scenario? Ideally, all this will +happen behind the scenes. + +I suppose at the very least, we will be able to have resizes happen off of the +UI thread, so that's nice. ## Capabilities @@ -348,6 +506,10 @@ application, but no single step is too large to review. As such, I'll attempt to break down the work required into atomic pieces, and provide a relative ordering for the work described above. +These tasks are broken into sections, because it seems that there's roughly +three tracks of work to be done here, which can be done relatively independently +of each other. +
@@ -457,7 +619,8 @@ for the work described above. ## Footnotes -
[1]: +[1]: See [Quake mode scenarios] for a longer enumeration +of possible scenarios. ## Future considerations @@ -483,6 +646,10 @@ for the work described above. and continue dragging the current window. This should make the drag/drop experience feel more seamless, and might be able to allow us to render the tab content as we're drag/dropping. + - If we pursue this, then we'll need to make sure that we re-assign the window + ID's as appropriate. the _new_ window (with the tabs that are being left + behind) should still have the same servant ID as the original window, which + will now get a new ID (as to ) * We could definitely do a `NewWindowFromTab(index:int?)` action that creates a new window from a current tab once this all lands. - Or it could be `NewWindowFromTab(index:union(int,int[])?)` to specify the @@ -519,3 +686,4 @@ for the work described above. [#632]: https://github.com/microsoft/terminal/issues/632 [Tab Tearout in the community toolkit]: https://github.com/windows-toolkit/Sample-TabView-TearOff +[Quake mode scenarios]: https://github.com/microsoft/terminal/issues/653#issuecomment-661370107 From cb54f3b259e4b91ee44c15b1c286d3892818f2da Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Mon, 10 Aug 2020 10:42:51 -0500 Subject: [PATCH 06/39] stashing real quick before I start the 'Capabilities' sections --- .../#5000 - Process Model 2.0.md | 183 +++++++++++++----- 1 file changed, 139 insertions(+), 44 deletions(-) diff --git a/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md b/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md index f590867b1d7..d4b9bd2d107 100644 --- a/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md +++ b/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md @@ -1,7 +1,7 @@ --- author: Mike Griese @zadjii-msft created on: 2020-07-31 -last updated: 2020-08-06 +last updated: 2020-08-07 issue id: #5000 --- @@ -205,11 +205,11 @@ With the ability for window processes to connect to other pre-existing content processes, we can now also support mixed elevation scenarios as well. If a user requests a new elevated tab from an otherwise unelevated window, we -can use UAC to create a new, elevated WP, and "move" all the current tabs to -that WP, as well as the new elevated client. Now, the WP is elevated, preventing -it from input injection, but still contains all the previously existing tabs. -The original WP can now be discarded, as the new elevated WP will pretend to be -the original window. +can use UAC to create a new, elevated window process, and "move" all the current +tabs to that window process, as well as the new elevated client. Now, the window +process is elevated, preventing it from input injection, but still contains all +the previously existing tabs. The original window process can now be discarded, +as the new elevated window process will pretend to be the original window. We would probably want to provide some additional configuration options here as well: @@ -218,32 +218,36 @@ well: - We should also provide some argument to the `NewTerminalArgs` (used by the `new-tab` and `split-pane` actions) to allow a user to elevate an otherwise unelevated profile. -* We'll probably want to create new CPs in a medium-IL context by default, - unless the profile or launch args otherwise indicates launching elevated. So a - WP running elevated would still create unelevated profiles by default. +* We'll probably want to create new content processes in a medium-IL context by + default, unless the profile or launch args otherwise indicates launching + elevated. So a window process running elevated would still create unelevated + profiles by default. * Currently, if a user launches the terminal as an administrator, then _all_ of their tabs run elevated. We'll probably want to provide a similar - configuration as well. Maybe if a WP is initially launched as elevated (rather - than inheriting from an existing session), then it could either: + configuration as well. Maybe if a window process is initially launched as + elevated (rather than inheriting from an existing session), then it could + either: - default all future connections it creates to elevated connections - assume the _first_ tab (or all the terminals created by the startup commandline) should be elevated, but then subsequent connections would default to unelevated processes. It's a long-standing platform bug that you cannot use drag-and-drop in elevated -scenarios. This unfortunately means that elevated WPs will _not_ be able to tear -tabs out into their own windows. Even tabs that only contain unelevated CPs in -them will not be able to be torn out, because the drag-and-drop service is -fundamentally incapable of connecting to elevated windows. +scenarios. This unfortunately means that elevated window processes will _not_ be +able to tear tabs out into their own windows. Even tabs that only contain +unelevated content processes in them will not be able to be torn out, because +the drag-and-drop service is fundamentally incapable of connecting to elevated +windows. We should probably have a discussion about what happens when the last elevated -CP in an elevated WP is closed. If an elevated WP doesn't have any remaining -elevated CPs, then it should be able to revert to an unelevated WP. Should we do -this? There's likely some visual flickering that will happen as we re-create the -new window process, so maybe it would be unappealing to users. However, there's -also the negative side effect that come from elevated windows (the aformentioned -lack of drag/drop), so maybe users will want to return to the more permissive -unelevated WP. +content process in an elevated window process is closed. If an elevated window +process doesn't have any remaining elevated content processes, then it should be +able to revert to an unelevated window process. Should we do this? There's +likely some visual flickering that will happen as we re-create the new window +process, so maybe it would be unappealing to users. However, there's also the +negative side effect that come from elevated windows (the aformentioned lack of +drag/drop), so maybe users will want to return to the more permissive unelevated +window process. This is one section where unfortunately I don't have a working prototype yet. From my research, an elevated process cannot simply `create_instance` a class @@ -268,17 +272,17 @@ introducing another type of categorization for window processes. These are the various windows by the Monarch. There will only ever be one monarch process at a given time, and every other WT -WP is a servant process. However, we want this system to be redundant, so that -if the monarch ever dies, one of the remaining servant processes can take over -for it. The new monarch will be chosen at random, so we'll call this a -probabalistic elective monarchy. +window process is a servant process. However, we want this system to be +redundant, so that if the monarch ever dies, one of the remaining servant +processes can take over for it. The new monarch will be chosen at random, so +we'll call this a probabalistic elective monarchy. Essentially, the probabalistic elective monarchy will work in the following way: 1. We'll introduce a WinRT class (for the puspose of this doc we'll call it `Monarch`), with a unique GUID. -2. When any WP starts up, it'll first try to register as the server for the - `Monarch` WinRT class. +2. When any window process starts up, it'll first try to register as the server + for the `Monarch` WinRT class. - The OS will allow subsequent processes to successfully register as the server for `Monarch` objects, but when someone tries to `create_instance` a `Monarch`, the OS will always create the `Monarch` from the first process to @@ -286,8 +290,8 @@ Essentially, the probabalistic elective monarchy will work in the following way: 3. After registering as a server for `Monarch`s, attempt to create a `Monarch` using `winrt::create_instance`. 4. Using that `Monarch`, ask it for it's PID. - - If that PID is the same as the PID of the current process, then the WP - knows that it is the monarch. + - If that PID is the same as the PID of the current process, then the window + process knows that it is the monarch. - If that PID is some other process, then we know that we're not currently the monarch. - If we don't currently have an ID assigned to us, then ask the `Monarch` @@ -333,9 +337,9 @@ schemes for the commandline parameters. The following is given as an example of how these arguments _might_ be authored and implemented to satisfy some of these scenarios. -Since each WP will have it's own unique ID assigned to it by the monarch, then -running a command in a given window with ID `N` should be as easy as something -like: +Since each window process will have it's own unique ID assigned to it by the +monarch, then running a command in a given window with ID `N` should be as easy +as something like: ``` wt.exe --session N new-tab ; split-pane @@ -446,13 +450,94 @@ executing the provided commandline should first change its working directory to the provided `currentDirectory` so that something like `.` actually refers to the directory where the command was executed. + +### Default Terminal + +In parallel to the above scenarios, the team is also investigating ways of +supporting a "default terminal application" on Windows (refer to [#492]). The +vision for default terminals is that when a commandline application is started +on Windows, instead of booting into `conhost.exe` as a default terminal, the +system will instead boot up whatever application the user has set as their +"default terminal application", whether that be the Windows Terminal or some +other terminal app (ConEmu, mintty, Hyper, etc). + +This is another scenario that deserves its own full spec, though it warrants a +special callout in this document as well. + +If we break down how the "defterm" scenario works, it's a bit of an inversion +from the normal way that the Terminal is started. Instead of the Terminal +creating a new connection, the connection already exists, it just needs to be +attached to a window of some sort. + +Considering all the changes proposed above, we can also support defterm with the +following mechanism: + +1. When `wt` is started as the target of a "defterm" invocation, the system will + somehow pass us a `HANDLE` (or pair of `HANDLE`s) to indicate that we're + being started to be the terminal for that commandline client. + - The details of the connection information aren't really important at this time. + +Then we have two paths forward: + +2a. The `wt` that's spawned in this way should become the _content process_ for +this connection, because it has the direct connection to the client that's +attempting to start. + +3a. This new content process will need a window. Depending on the configuration of the +Terminal, the following could happen: + - the content process could discover that there's no existing Monarch process, + and that a new monarch should be created, with a reference to this content + process (as a first tab) + - The content process connects to the monarch, who then creates a new window + process who attaches to the content process. (A new window is created.) + - The content process connects to the monarch, who then tells an existing + window process to attaches to the content process. (The client opens as a + new tab either in the single instance or the most recent window, if glomming + is enabled.) + +**OR** + +2b. The `wt` that's spawned by the defterm connection is a new window process. +It should create a new content process to handle this connection. + - the content process will need a way of being invoked by passing it handles + to the new client. This way, the content process can dupe these handles into + it's own process space, to be able to create the `ITerminalConnection` in + its own process space. + +3b. If this new window process is the monarch, then great! There are no other +windows to glom onto, so create the tab in this window process. + +4b. It'll ask the monarch if it's in single instance mode, or if the monarch is +configured to glom tabs onto the most recent window, instead of spawning new +ones. If it is configured in such a way, the new servant window process will +pass the content process's GUID to the Servant\* that _should_ be the window for +that new client + - \*: note that this servant could just be the monarch (in single instance + mode, for example). + +
+ +This area is left intentionally vague, because we're not exactly sure what the +API surface exposed for default terminal invocations will look like. Hopefully, +it shows that however we do end up implementing support for default terminal +apps, the proposed Window/Content/Monarch/Servant architecture will still be a +compatible solution. + ## UI/UX Design -TODO: Is there really all that much UX for this scenario? Ideally, all this will -happen behind the scenes. +There's not really all that much UI for this scenario. Ideally, all this will +happen behind the scenes, without the user really being exposed to the inner +machinations of the Terminal processes. -I suppose at the very least, we will be able to have resizes happen off of the -UI thread, so that's nice. +At the very least, resizes will occur off of the UI thread, which will help that +scenario feel better. While resizes happen fairly responsively in Release +builds, Debug builds used for development have fairly painful resizes occuring +on the UI thread, blocking all input until they're finished. + +Ideally, we'll want the tab that's being dragged to be able to show the contents +of the tab as we're dragging it, similar to the way that Edgium currently does. +However, this is expected to be challenging and something that won't be a part +of the initial release of tab tearout. ## Capabilities @@ -497,6 +582,8 @@ TODO: These are _very_ expected Extensions & non-terminal content. +Mixed elevation & Monarch / Peasant issues + ## Implementation Plan Obviously, everything that's discussed here represents an _enormous_ amount of @@ -510,7 +597,6 @@ These tasks are broken into sections, because it seems that there's roughly three tracks of work to be done here, which can be done relatively independently of each other. -
1. Add Monarch/Servant capabilities to `wt` window processes. @@ -588,9 +674,10 @@ of each other. - At this point, the tabs can't be torn out to create new windows, only move between existing windows - It might be hard to have the tab "attach" to the tab row of the other window. - - It might be easiest to do this after 1, and communicate to the new WP the - GUID of the old WP and the tab within the original WP, and just have the - new WP ask the old WP what the structure of the tab is + - It might be easiest to do this after 1, and communicate to the new window + process the GUID of the old window process and the tab within the original + window process, and just have the new window process ask the old window + process what the structure of the tab is - Though, the tab won't be in the original process's list of tabs anymore, so that might not be helpful. @@ -658,17 +745,24 @@ of possible scenarios. ## TODOs -* [ ] Prove that a elevated window can host an unelevated content -* [ ] Prove that I can toss content process IDs from one window to another +* [ ] Experimentally prove that a elevated window can host an unelevated content +* [ ] Experimentally prove that I can toss content process IDs from one window + to another + - I don't have any doubt that this will work, but I want to have a + proof-of-concept just in case. * [ ] come up with a commandline mechanism for starting one `wt.exe` process either as a window process, or as a content process + - `wt --content {guid}` seems reasonable to me. If there's a `--content + {guid}` as the only two args, I think that's a distinct enough way to + identify "you should be a content process". * [ ] What about handling XAML input events? The "thin" term control will need to do that in-proc, so it can reply on the UI thread if a particular keystroke was handled or not. - I'm almost certain that the `Terminal::HandleKey()` stuff is going to need to be handled in the thin control, and the core will need to raise events to the control? oof - +* [ ] Make sure I can pass the UiaProvider for the control core out to the + Window Process, so the window process can use it to query buffer info. ## Resources @@ -684,6 +778,7 @@ of possible scenarios. [#653]: https://github.com/microsoft/terminal/issues/653 [#1032]: https://github.com/microsoft/terminal/issues/1032 [#632]: https://github.com/microsoft/terminal/issues/632 +[#492]: https://github.com/microsoft/terminal/issues/492 [Tab Tearout in the community toolkit]: https://github.com/windows-toolkit/Sample-TabView-TearOff [Quake mode scenarios]: https://github.com/microsoft/terminal/issues/653#issuecomment-661370107 From 985248052910fcf5a601eebcf697b5750d156e29 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Mon, 10 Aug 2020 16:53:08 -0500 Subject: [PATCH 07/39] prepare for review --- .../#5000 - Process Model 2.0.md | 113 ++++++++++++++++-- .../#5000 - Process Model 2.0/figure-001.png | Bin 0 -> 25511 bytes .../#5000 - Process Model 2.0/figure-002.png | Bin 0 -> 37651 bytes .../#5000 - Process Model 2.0/figure-003.png | Bin 0 -> 53618 bytes 4 files changed, 105 insertions(+), 8 deletions(-) create mode 100644 doc/specs/#5000 - Process Model 2.0/figure-001.png create mode 100644 doc/specs/#5000 - Process Model 2.0/figure-002.png create mode 100644 doc/specs/#5000 - Process Model 2.0/figure-003.png diff --git a/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md b/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md index d4b9bd2d107..cb48577c663 100644 --- a/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md +++ b/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md @@ -1,7 +1,7 @@ --- author: Mike Griese @zadjii-msft created on: 2020-07-31 -last updated: 2020-08-07 +last updated: 2020-08-10 issue id: #5000 --- @@ -89,6 +89,17 @@ to connect to and display content that's being hosted in another process. ### Window and Content Processes +To begin, let's first take a look at a rough diagram of how the Windows Terminal +process looks today: + +![figure-001](figure-001.png) + +Currently, the entire Windows Terminal exists as a single process composed of +many parts. it has a top Win32 layer responsible for the window, which includes +a UWP XAML-like App layer, which embeds many `TermControl`s, each of which +contains the buffer and renderer, and communicates with a connection to another +process. + The primary concept introduced by this spec is the idea of two types of process, which will work together to create a single Terminal window. These processes will be referred to as the "Window Process" and the "Content Process". @@ -112,6 +123,8 @@ These thin `TermControl`s will recieve input, and have all the UI elements _rendering_ to the swap chain, and the handling of those inputs will be done by the content process. +![figure-002](figure-002.png) + As a broad outline, whenever the window wants to create a terminal, the flow will be something like the following: @@ -126,6 +139,8 @@ will be something like the following: process's `SwapChainPanel`, because they share the same underlying kernel object. +![figure-003](figure-003.png) + The content process will be responsible for the terminal buffer and other terminal state (the core `Terminal` object), as well as the `Renderer`, `DxEngine`, and `TerminalConnection`. These are all being combined in the @@ -136,6 +151,7 @@ the connection as quickly as possible, and the best way to do this will be to have the connection in the same process as the `Terminal` core. + #### Technical Details Much of the above is powered by the magic of WinRT (which is powered by the @@ -182,7 +198,7 @@ This means that if we wanted to have a second window process connect to the _same_ content process as another window, all it needs is the content process's GUID. -#### Scenario: Tab Tearoff/ Reattach +#### Scenario: Tab Tear-off and Reattach Because all that's needed to uniquely identify an individual terminal instance is the GUID of the content process, it becomes fairly trivial to be able to @@ -545,33 +561,114 @@ of the initial release of tab tearout. Accessibility -TODO: This is _very_ applicable + +When working on the implementation of the window/content process split, we'll +need to ensure that the contents of the buffer are still readable by +accessibility tools like Narrator and NVDA. We'll be moving the actual buffer +out of the window process into the content process, so we'll need to make sure +that we can hook up the `TermControlAutomationPeer` across the process boundary. +Presumably, this is possible trivially because it's already implemented as a +WinRT type. + +I'll be especially curious to make sure that +`TermControl::OnCreateAutomationPeer` can occur off the window process's UI +thread, because all cross-process calls will need to happen off the UI thread. + Security -TODO: This is _very_ applicable + +As we'll be introducing a mechanism for crossing elevation boundaries, we'll +want to be especially careful as we make these changes. + +Our biggest concern regarding mixed elevation was regarding the ability for a +non-elevated process to send input to another unelevated WT window, which was +connected to an elevated client process. With these proposed changes, we won't +have any unelevated windows connected to unelevated processes, so that concern +should be mitigated. + +Additionally, we'll probably want to make sure that the user is visually +prompted when a connection to an elevated client is initiated. Typically, this +is done with a UAC prompt, which seems reasonable in this scenario as well. + +We'll likely want to default elevated windows to spawning unelevated +connections, as to prevent accidentally running connections as an administrator. +This is in contrast to existing behavior, where all connections in an elevated +WT window are elevated. + +Furthermore, we'll want to ensure that there's nothing that an unelevated client +process could do to trigger any sort of input callback in the parent window. If +the parent window is an elevated window, with other elevated connections, then +we don't want the uelevated content process to act as a vector by which +malicious software could hijack the elevated window. + Reliability -TODO: This is _very_ applicable + +This is probably the biggest concern in this section. Because there will now be +many, many more processes in the process tree, it is imperitive that whenever +we're doing cross-process operations, we do them safely. + +Whenever we're working with an object that's hosted by another process, we'll +need to make sure that we work with it in a try/catch, because at _any_ time, +the other process could be killed. At any point, a content process could be +killed, without the window being closed. The window will need to be redundant to +such a scenario, and if the content process is killed, display an appropriate +error message, but _continue running_. + +When the monarch process dies, we'll need to be able to reliably elect a new +monarch. While we're electing a new monarch, and updating the new monarch, +there's always the chance that the _new_ monarch is also killed (This is the +"Pope Stephen II" scenario). In this sccenario, if at any point a servant +notices that the monarch has died, the servant will need to begin checking who +the new monarch is again. + +There is certain to be a long tail of edge cases we'll discover as a product of +this change. We'll need to be prepared to see an inevitable decrease in initial +reliability numbers, and increased bug reports for a time. Additionally, these +bug will likely be fairly difficult to track down. + +In the long run, this may end up _increasing_ reliability, as crashes in the +buffer should no longer cause the _entire_ terminal application to crash. + + Compatibility -TODO: This is _very_ applicable -TODO: Concerns with the Universal App version of the Terminal? +The biggest concern regarding compatibility will be ensuring that the Universal +app version of the Windows Terminal will still work as before. Although that +application isn't used by any customer-facing scenarios currently, it still +represents some long term goals for the Terminal. We'll probably need to +disable tearout _entirely_ on the universal app, at least to begin with. +Additionally, we'll need to ensure that all the controls in the universal +application are in-proc controls, not using the window/content split process +model. + +I'm also concerned that each individual atomic step along the path towards this +goal still works. For more on this topic, see [Implementation +Plan](#implementation-plan). + Performance, Power, and Efficiency -TODO: This is _very_ applicable + +There's no dramatic change expected here. There may be a minor delay in the +spawning of new terminal instances, due to requiring cross-process hops for the +instantiation of the content process. + +Additionally, minor delays are expected to be introduced during startup for the +initial setup of the monarch/servant relationship. + diff --git a/doc/specs/#5000 - Process Model 2.0/figure-001.png b/doc/specs/#5000 - Process Model 2.0/figure-001.png new file mode 100644 index 0000000000000000000000000000000000000000..088a95457a86b7ed387693ddc96fc019173120e0 GIT binary patch literal 25511 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 literal 0 HcmV?d00001 diff --git a/doc/specs/#5000 - Process Model 2.0/figure-002.png b/doc/specs/#5000 - Process Model 2.0/figure-002.png new file mode 100644 index 0000000000000000000000000000000000000000..5b8120bba1156ee23c90985fbf842c757e526311 GIT binary patch literal 37651 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

HCSx*!MerTDcNu8!|8zh!%4*7*n1=>2-Gn=3J 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

GK1L~w+58Hf8e=0< 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 literal 0 HcmV?d00001 From ecc2b9d074165561b425fd27d7b33e303ec1c4d8 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Mon, 10 Aug 2020 17:07:05 -0500 Subject: [PATCH 08/39] good bot --- .../actions/spell-check/dictionary/apis.txt | 3 ++ .github/actions/spell-check/expect/expect.txt | 3 ++ .../#5000 - Process Model 2.0.md | 42 +++++++++---------- 3 files changed, 27 insertions(+), 21 deletions(-) diff --git a/.github/actions/spell-check/dictionary/apis.txt b/.github/actions/spell-check/dictionary/apis.txt index 1e33da10d7e..3f27ab015f0 100644 --- a/.github/actions/spell-check/dictionary/apis.txt +++ b/.github/actions/spell-check/dictionary/apis.txt @@ -13,6 +13,7 @@ IAsync IBind IBox IClass +IConnection IComparable ICustom IDialog @@ -25,6 +26,7 @@ llabs LCID lround LSHIFT +MULTIPLEUSE NCHITTEST NCLBUTTONDBLCLK NCRBUTTONDBLCLK @@ -35,6 +37,7 @@ ocidl otms OUTLINETEXTMETRICW PAGESCROLL +REGCLS RETURNCMD rfind roundf diff --git a/.github/actions/spell-check/expect/expect.txt b/.github/actions/spell-check/expect/expect.txt index 5a74915444a..d388d073133 100644 --- a/.github/actions/spell-check/expect/expect.txt +++ b/.github/actions/spell-check/expect/expect.txt @@ -497,6 +497,7 @@ DCOLORVALUE dcommon DCompile dcompiler +DComposition dde DDESHARE DDevice @@ -664,6 +665,7 @@ ECH echokey ecount ECpp +Edgium EDITKEYS EDITTEXT EDITUPDATE @@ -2388,6 +2390,7 @@ typename typeof typeparam TYUI +UAC uap uapadmin UAX diff --git a/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md b/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md index cb48577c663..a2b807eeef8 100644 --- a/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md +++ b/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md @@ -28,7 +28,7 @@ following scenarios: ## Inspiration Much of the design for this feature was inspired by (what I believe is) the web -browser process model. For a web browser, there's often a seperate process for +browser process model. For a web browser, there's often a separate process for each of the tabs within the browser, to help isolate the actual tabs from one another. @@ -77,12 +77,12 @@ to another with a drag and drop operation. If we wanted to use a string to transfer the data, we'd somehow need to serialize then entire state of the tab, it's tree of panes, and the state of each of the buffers in the tab, into some sort of string, and then have the new window deserialize that string to -re-create the tab state. Consider that each bufer might include 32000 rows of +re-create the tab state. Consider that each buffer might include 32000 rows of 80+ characters each, each with possibly RGB attributes, and you're looking at 30MB+ of raw data to serialize and de-serialize per buffer, minimum. This sounds extremely fragile, if not impossible to do robustly. -What we need is a more effective way for seperate Terminal windows to to be able +What we need is a more effective way for separate Terminal windows to to be able to connect to and display content that's being hosted in another process. ## Solution Design @@ -114,11 +114,11 @@ These two types of processes will work together to present both the UI of the Windows Terminal app, as well as the contents of the terminal buffers. A single window process may be in communication with multiple content processes - one per terminal instance. That means that each and every `TermControl` in a window -process will be hosted in a seperate process. +process will be hosted in a separate process. The window process will be full of "thin" `TermControl`s - controls which are only the XAML layer and a WinRT object which is hosted by the content process. -These thin `TermControl`s will recieve input, and have all the UI elements +These thin `TermControl`s will receive input, and have all the UI elements (including the `SwapChainPanel`) of the `TermControl` today, but the actual _rendering_ to the swap chain, and the handling of those inputs will be done by the content process. @@ -187,7 +187,7 @@ auto myClass = create_instance(MyClassGUID, CLSCTX_LOCAL_SERVER) We're going to be using that system a little differently here. Instead of using a GUID to represent a single _Class_, we're going to use the GUID to uniquely -identify _content processes_. Each content process will recieve a unique GUID +identify _content processes_. Each content process will receive a unique GUID when it is created, and it will register as the server for that GUID. Then, any window process will be able to connect to that specific content process strictly by GUID. Because each GUID is unique to each content process, any time any @@ -261,7 +261,7 @@ process doesn't have any remaining elevated content processes, then it should be able to revert to an unelevated window process. Should we do this? There's likely some visual flickering that will happen as we re-create the new window process, so maybe it would be unappealing to users. However, there's also the -negative side effect that come from elevated windows (the aformentioned lack of +negative side effect that come from elevated windows (the aforementioned lack of drag/drop), so maybe users will want to return to the more permissive unelevated window process. @@ -291,11 +291,11 @@ There will only ever be one monarch process at a given time, and every other WT window process is a servant process. However, we want this system to be redundant, so that if the monarch ever dies, one of the remaining servant processes can take over for it. The new monarch will be chosen at random, so -we'll call this a probabalistic elective monarchy. +we'll call this a probabilistic elective monarchy. -Essentially, the probabalistic elective monarchy will work in the following way: +Essentially, the probabilistic elective monarchy will work in the following way: -1. We'll introduce a WinRT class (for the puspose of this doc we'll call it +1. We'll introduce a WinRT class (for the purpose of this doc we'll call it `Monarch`), with a unique GUID. 2. When any window process starts up, it'll first try to register as the server for the `Monarch` WinRT class. @@ -320,8 +320,8 @@ Essentially, the probabalistic elective monarchy will work in the following way: choose who the new server for `Monarch`s is.) - We're suggesting `WaitForSingleObject` here as opposed to having the monarch raise a WinRT event when it's closed, because it's possible that - the monarch closes unexpectedly, before it has an - opprotunity to notify the servants. + the monarch closes unexpectedly, before it has an + opportunity to notify the servants. By this mechanism, the processes will be able to communicate with the Monarch, who'll be responsible for managing any inter-process communication between @@ -390,7 +390,7 @@ WT window during the sleep, which would cause the MRU window to not be the same as the window executing the command. I'm not sure that there is a better solution for the `-s 0` scenario other than -atempting to use the `WT_SESSION` environment variable. If a `wt.exe` process is +attempting to use the `WT_SESSION` environment variable. If a `wt.exe` process is spawned and that's in it's environment variables, it could try and ask the monarch for the servant who's hosting the session corresponding to that GUID. This is more of a theoretical solution than anything else. @@ -417,7 +417,7 @@ that key. With the addition of monarch/servant processes, this problem becomes much easier to solve. Now, the monarch process will _always_ be the process to register the -shortcut key, whnever it's elected. If it dies and another servant is elected +shortcut key, whenever it's elected. If it dies and another servant is elected monarch, then the new monarch will register as the global hotkey handler. Then, the monarch can use it's pre-established channels of communication with @@ -451,7 +451,7 @@ The servant process can instantiate the `Servant` object itself, in it's process space. Initially, the `Servant` object won't have an ID assigned, and the call to `AddServant` on the `Monarch` will both cause the Monarch to assign the `Servant` an ID, and add it to the Monarch process's list of processes. If the -`Servant` already had an ID assigned by a previous monarch, then the new onarch +`Servant` already had an ID assigned by a previous monarch, then the new monarch will simply re-use the value already existing in the `Servant`. Now, the monarch can call methods on the `Servant` object directly to trigger changes in the servant process. @@ -553,7 +553,7 @@ on the UI thread, blocking all input until they're finished. Ideally, we'll want the tab that's being dragged to be able to show the contents of the tab as we're dragging it, similar to the way that Edgium currently does. However, this is expected to be challenging and something that won't be a part -of the initial release of tab tearout. +of the initial release of tab tear-out. ## Capabilities @@ -647,7 +647,7 @@ The biggest concern regarding compatibility will be ensuring that the Universal app version of the Windows Terminal will still work as before. Although that application isn't used by any customer-facing scenarios currently, it still represents some long term goals for the Terminal. We'll probably need to -disable tearout _entirely_ on the universal app, at least to begin with. +disable tear-out _entirely_ on the universal app, at least to begin with. Additionally, we'll need to ensure that all the controls in the universal application are in-proc controls, not using the window/content split process model. @@ -710,7 +710,7 @@ of each other. 4. (Dependent on 1): Monarch registers for the global quake hotkey, and uses that to activate _the monarch_. - Pressing the key when a window is currently focused should minimize? Do nothing? -5. (Dependent on 4): any othe quake mode improvements: +5. (Dependent on 4): any other quake mode improvements: - Summon the nearest window - make the window "drop down" from the top - Summon the MRU window @@ -739,7 +739,7 @@ of each other. - The core will need to be able to accept a PID using some method, and be able to `DuplicateHandle` the swapchain to that PID. It'll also need to raise the `SwapChainHandleChanged` event. - - The Control UI layer would need to recieve a GUID in the ctor, and use that + - The Control UI layer would need to receive a GUID in the ctor, and use that connect to the out-of-proc core. It'll pass the UI's PID to the core, and attach to the core's swap chain handle. - The UI layer will be smart enough to call either the implementation method @@ -763,7 +763,7 @@ of each other. terminal instance). 12. (Dependent on 11) TerminalApp creates new content processes for each and - every terminal instance it spawns. At this point, there's no tearout, but + every terminal instance it spawns. At this point, there's no tear-out, but the terminal instances are all out-of-proc from the window process. 13. (Dependent on 12) Terminal can drop tabs onto another WT window process by @@ -811,7 +811,7 @@ of possible scenarios. * Yea add these * Non-terminal content in the Terminal. We've now created a _very_ - terminal-specific IPC mechanism for transfering _terminal_ state from one + terminal-specific IPC mechanism for transferring _terminal_ state from one thread to another. When we start to plan on having panes that contain non-terminal content in them, they won't be able to move across-process like this. Options available here include: From bba6048fa4890b12a81c3cd356e1fac9b7301a5d Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Tue, 11 Aug 2020 15:32:12 -0500 Subject: [PATCH 09/39] Apply suggestions from code review Co-authored-by: Carlos Zamora --- .../#5000 - Process Model 2.0.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md b/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md index a2b807eeef8..e3a44b4ab16 100644 --- a/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md +++ b/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md @@ -49,7 +49,7 @@ permission of the user to spawn an elevated client application. The user would see a UAC prompt, they'd accept, and then they'd be able to have an elevated shell alongside their unelevated tabs. -However, this creates an escalation of priviledge vector. Now, there's an +However, this creates an escalation of privilege vector. Now, there's an unelevated window which is connected directly to an elevated process. At this point, any other unelevated application could send input to the Terminal's `HWND`, making it possible for another unelevated process to "drive" the @@ -134,7 +134,7 @@ will be something like the following: 3. When the content process creates it's swap chain, it will raise an event which the window process will use to connect that swap chain to the window process's `SwapChainPanel`. -4. The will process output from the connection and draw to the swap chain. The +4. The content process will read output from the connection and draw to the swap chain. The contents that are rendered to the swap chain will be visible in the window process's `SwapChainPanel`, because they share the same underlying kernel object. @@ -206,7 +206,7 @@ is the GUID of the content process, it becomes fairly trivial to be able to When a drag/drop operation happens, the payload of the event will simply contain the structure of the tree of panes, and the GUIDs of the content processes that -make up the leaf nodes of the tree. The recieving window process will then be +make up the leaf nodes of the tree. The receiving window process will then be able to use that tree to be able to re-create a similar pane structure in its window, and use the GUIDs to be able to connect to the content processes for the terminals in that tab. @@ -348,7 +348,8 @@ extension of this scenario being "run a `wt` commandline in _any_ given WT window". This spec by no means attempts to fully document how this functionality should -work. This scenarios deserves it's own spec to discuss various differnt naming +work. This scenarios deserves it's own spec to discuss various different naming + schemes for the commandline parameters. The following is given as an example of how these arguments _might_ be authored and implemented to satisfy some of these scenarios. @@ -421,7 +422,7 @@ shortcut key, whenever it's elected. If it dies and another servant is elected monarch, then the new monarch will register as the global hotkey handler. Then, the monarch can use it's pre-established channels of communication with -the other window processes to actuall drive the response we're looking for. +the other window processes to actually drive the response we're looking for. #### Rough interface design @@ -434,7 +435,7 @@ class Servant void AssignID(UInt64 id); // Should only be called by the monarch UInt64 GetID(); UInt64 GetPID(); - Boolean ExecuteCommandline(String[] args, Sting currentDirectory); + Boolean ExecuteCommandline(String[] args, String currentDirectory); event TypedEventHandler WindowActivated; } @@ -624,14 +625,14 @@ error message, but _continue running_. When the monarch process dies, we'll need to be able to reliably elect a new monarch. While we're electing a new monarch, and updating the new monarch, there's always the chance that the _new_ monarch is also killed (This is the -"Pope Stephen II" scenario). In this sccenario, if at any point a servant +"Pope Stephen II" scenario). In this scenario, if at any point a servant notices that the monarch has died, the servant will need to begin checking who the new monarch is again. There is certain to be a long tail of edge cases we'll discover as a product of this change. We'll need to be prepared to see an inevitable decrease in initial reliability numbers, and increased bug reports for a time. Additionally, these -bug will likely be fairly difficult to track down. +bugs will likely be fairly difficult to track down. In the long run, this may end up _increasing_ reliability, as crashes in the buffer should no longer cause the _entire_ terminal application to crash. From e35e72b3503fe904814e616db46f10bb5f7f14d8 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Wed, 12 Aug 2020 12:04:05 -0500 Subject: [PATCH 10/39] a whole bunch of added text, diagrams --- .../#5000 - Process Model 2.0.md | 277 ++++++++++++++++-- .../auto-glom-wt-exe.png | Bin 0 -> 84952 bytes .../drop-tab-on-existing-window.png | Bin 0 -> 55763 bytes .../mixed-elevation.png | Bin 0 -> 45395 bytes .../single-instance-mode-cwd.png | Bin 0 -> 54075 bytes .../tear-out-tab.png | Bin 0 -> 47615 bytes .../wt-session-0.png | Bin 0 -> 94992 bytes 7 files changed, 246 insertions(+), 31 deletions(-) create mode 100644 doc/specs/#5000 - Process Model 2.0/auto-glom-wt-exe.png create mode 100644 doc/specs/#5000 - Process Model 2.0/drop-tab-on-existing-window.png create mode 100644 doc/specs/#5000 - Process Model 2.0/mixed-elevation.png create mode 100644 doc/specs/#5000 - Process Model 2.0/single-instance-mode-cwd.png create mode 100644 doc/specs/#5000 - Process Model 2.0/tear-out-tab.png create mode 100644 doc/specs/#5000 - Process Model 2.0/wt-session-0.png diff --git a/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md b/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md index e3a44b4ab16..cbbf0573ad6 100644 --- a/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md +++ b/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md @@ -1,7 +1,7 @@ --- author: Mike Griese @zadjii-msft created on: 2020-07-31 -last updated: 2020-08-10 +last updated: 2020-08-12 issue id: #5000 --- @@ -150,8 +150,6 @@ same process as the buffer. Similarly, we want to be able to read data off of the connection as quickly as possible, and the best way to do this will be to have the connection in the same process as the `Terminal` core. - - #### Technical Details Much of the above is powered by the magic of WinRT (which is powered by the @@ -204,6 +202,8 @@ Because all that's needed to uniquely identify an individual terminal instance is the GUID of the content process, it becomes fairly trivial to be able to "move" a terminal instance from one window to another. +![drop-tab-on-existing-window](drop-tab-on-existing-window.png) + When a drag/drop operation happens, the payload of the event will simply contain the structure of the tree of panes, and the GUIDs of the content processes that make up the leaf nodes of the tree. The receiving window process will then be @@ -215,6 +215,19 @@ The terminal buffer never needs to move from one process to another - it always stays in just a single content process. The only thing that changes is the window process which is rendering the content process's swapchain. +Similar to dragging a tab from one window to another window, we can also detect +when the tab was dropped somewhere outside the bounds of a tab strip. When that +happens, we'll create a new WT window, and use the data package from the +drag-drop to initialize the structure of the window. + +![tear-out-tab](tear-out-tab.png) + +For our own sanity, we'll want to ensure that tabs cannot be torn out from a +"Preview" Windows Terminal window and dropped into a "Release" window. I'm not +positive that the system will prevent that on our behalf, so I think it's +important to call out that if this _is_ possible, we should expressely disallow +it. + #### Scenario: Mixed Elevation With the ability for window processes to connect to other pre-existing content @@ -227,6 +240,8 @@ process is elevated, preventing it from input injection, but still contains all the previously existing tabs. The original window process can now be discarded, as the new elevated window process will pretend to be the original window. +![mixed-elevation](mixed-elevation.png) + We would probably want to provide some additional configuration options here as well: * Users will most likely want to be able to specify that a given profile should @@ -325,19 +340,80 @@ Essentially, the probabilistic elective monarchy will work in the following way: By this mechanism, the processes will be able to communicate with the Monarch, who'll be responsible for managing any inter-process communication between -windows we might need. +windows we might need. In addition, the monarch might need to track some global +state that it can use to enable some of the following scenarios. An example of +such global state might be "which window process was the most recently focused +one?" + +#### Scenario: Open new tabs in most recently used window + +A common feature of many browsers is that when a web URL is clicked somewhere, +the web page is opened as a new tab in the most recently used window of the +browser. This functionality is often referred to as "glomming", as the new tab +"gloms" onto the existing window. + +Currently, the terminal does not support such a feature - every `wt` invocation +creates a new window. With the monarch/servant architecture, it'll now be +possible to enable such a scenario. +As each window is activated, it will call a method on the `Monarch` object +(hosted by the monarch process) which will indicate that "I am servant N, and +I've been focused". The monarch will use those method calls to update its own +internal stack of the most recently used windows. + +When tab glomming is enabled, and a new `wt.exe` process is launched, that +process will _first_ ask the monarch if it should run the commandline in an +existing window, or create its own window. + +![auto-glom-wt-exe](auto-glom-wt-exe.png) + +Depending on which window was the last focused, the monarch will dispatch the +commandline to the appropriate window for them to handle instead. To the user, +it'll seem as if the tab just opened in the most recent window. + +Users should certainly be able to specify if they want new instances to glom +onto the MRU window or not. You could imagine that currently, we default to the +hypothetical value `"glomToLastWindow": false`, meaning that each new wt gets +it's own new window. #### Scenario: Single Instance Mode -In "Single Instance Mode", the monarch _is_ the single instance. When `wt` is run, -and it determines that it is not the monarch, it'll ask the monarch if it's in -single instance mode. If it is, then the servant that's starting up will instead -pass it's commandline arguments to the monarch process, and let the monarch -handle them, then exit. +"Single Instance Mode" is a scenario in which there is only ever one single WT +window. When Single Instance Mode is active, and the user runs a new `wt.exe` +commandline, it will always end up running in the existing window, if there is +one. + +In "Single Instance Mode", the monarch _is_ the single instance. When `wt` is +run, and it determines that it is not the monarch, it'll ask the monarch if it's +in single instance mode. If it is, then the servant that's starting up will +instead pass it's commandline arguments to the monarch process, and let the +monarch handle them, then exit. In single instance mode the window will still be +composed from a combination of a window process and multiple different content +processes, just the same as it would be outside single instance mode. So, this will make it seem like new starting a new `wt.exe` will just create a -new tab in the existing window. If someone does `wt -d .` in explorer, +new tab in the existing window. There are some tricky scenarios involving single +instance mode. Consider if If someone does `wt -d .` in explorer. For clarity, +let's label the existing window WT[1], and the second `wt.exe` process WT[2]. + +An example of this scenario is given in the following diagram: + +![single-instance-mode-cwd](single-instance-mode-cwd.png) + +In this scenario, we'd want the new tab to be spawned in the current working +directory of WT[2], not WT[1]. So when WT[1] is about to run the commands that +were passed to WT[2], WT[1] will need to: + +* First, stash it's own CWD +* Change to the CWD of WT[2] +* Run the commands from WT[2] +* Then return to it's original CWD. + +One could imagine that single instance mode is the combination of two properties: +* The user wants new invocation of `wt` to "glom" onto the most recently used + window (the hypothetical `"glomToLastWindow": true` setting) +* The user wants to prevent tab tear-out, or the ability for a `newWindow` + action to work. (hypothetically `"allowTabTearout": false`) #### Scenario: Run `wt` in the current window @@ -424,6 +500,21 @@ monarch, then the new monarch will register as the global hotkey handler. Then, the monarch can use it's pre-established channels of communication with the other window processes to actually drive the response we're looking for. +**Alternatively**, we could use an entirely other process to be in charge of the +registration of the global keybinding. This process would be some sort of +long-running service that's started on boot. When it detects the global hotkey, +it could attmept to instantiate a `Monarch` object. + + * If it can't make one, then it can simply run a new instance of `wt.exe`, + because there's not yet a running Terminal window. + * Otherwise, it can communicate to the monarch that the global hotkey was + pressed, and the monarch will take care of delegating the activation to the + appropriate servant window. + +This would mitigate the need to have at least one copy of WT running already, +and the user could press that keybinding at any time to start the terminal. + + #### Rough interface design This is by no means definitive, but one could imagine the `Monarch` and @@ -632,7 +723,18 @@ the new monarch is again. There is certain to be a long tail of edge cases we'll discover as a product of this change. We'll need to be prepared to see an inevitable decrease in initial reliability numbers, and increased bug reports for a time. Additionally, these -bugs will likely be fairly difficult to track down. +bugs will likely be fairly difficult to track down. Initially, it may help us to +track these bugs down if we add additional tracing around each of the +inter-process calls we might make. Some example situations might include: +* When a process creates a new content process +* When a content process is attached by a window +* When a monarch is elected +* when a servant receives its new ID from a monarch +* when either a window or content process _safely_ exits + +In any and all of these situations, we'll want to try and be as verbose as +possible in the logging, to try and make tracking which process had the error +occur easier. In the long run, this may end up _increasing_ reliability, as crashes in the buffer should no longer cause the _entire_ terminal application to crash. @@ -676,11 +778,134 @@ initial setup of the monarch/servant relationship. ## Potential Issues -TODO: These are _very_ expected -Extensions & non-terminal content. +#### Extensions & non-terminal content. + +We've now created a _very_ terminal-specific IPC mechanism for transferring +_terminal_ state from one thread to another. However, what happens when we start +to have panes that contain non-terminal content in them? This is a scenario +that's most often associated with the concept of extensions in the Terminal, but +perhaps more relevantly could affect the Settings UI. + +The Settings UI is something we intend on shipping in the Terminal as a part of +2.0, in the same timefram much of the above work is expected to be done. We also +plan on hopefully making the Settings UI appear as its own tab within the +Terminal. This would be the first example of having non-terminal content +directly in the application. How would we support tearing out the Settings UI +tab into it's own window? + +Options available here include: + +We could prevent tabs with non-terminal content open in them from being dragged +out entirely. They're stuck in their window until the non-terminal content is +removed. This seems like it would not be a good long-term solution. Users will +want to be able to tear their non-terminal content out of the window. -Mixed elevation & Monarch / Peasant issues +Alternatively, we could pass some well-defined string / JSON blob from the +source process to the target process, such that the extension could use that +JSON to recreate whatever state the pane was last in. The extension would be +able to control this content entirely. + - Maybe they want to pass a GUID that the new process will be able to user to + `CreateInstance` the singleton for their UI and then dupe their swap chain + to the new thread... + +We'll need to define a syntax for the tear-out and drag/drop scenarios anyways, +so we should define that structure in a way that will allow future +extensibility. + + +Lets examine some sample JSON[[2]](#footnote-2) + +```json +{ + "tabs": [ + { + "runtimeTitle": "foo", + "runtimeColor": null, + "panes": [ + { + "split": "horizontal", + "children": [ + { + "size": 0.30, + "contentType": "Microsoft.Terminal.TerminalControl", + "payload": { + "contentGuid": "{1-1-1-1}" + } + }, + { + "size": 0.70, + "contentType": "Microsoft.Terminal.TerminalControl", + "payload": { + "contentGuid": "{2-2-2-2}" + } + } + ] + } + ] + }, + { + "runtimeTitle": null, + "runtimeColor": null, + "panes": [ + { + "size": 1.0, + "contentType": "Microsoft.Terminal.SettingsPage", + "payload": { + "currentPage": "globals" + } + } + ] + } + ] +} +``` + +Here, we've got two tabs that have been serialized. +* The first has two panes, seperated with a horizontal split. It has also been + renamed to "foo". + - The first pane takes up 30% of the parent, and contains a `TermControl`. The + content process for that control is identified by the content GUID + `{1-1-1-1}` + - The second pane is also a `TermControl`, takes up 70% of the parent, and is + attached to the content process `{2-2-2-2}` +* The second tab has a single pane, with a SettingsPage. The settings page has + also specified in it's `payload` that its current page is the "globals" page. + +When we send this serialized state to another window, it can use the content +GUIDs to initialize new `TermControl`s connected to the appropriate content +processes. It can also pass the `payload` to a new `SettingsPage`, so the +settings page can recreate whatever state it was in. + +It would be at the discretion of each type of content to specify exactly what +would go into the `payload`, and how to best deserialize it. In the future, we'd +also need to consider how the content types should be identified and +instantiated, but that's a questions that's deferred to a future "extensions" +spec. + +#### Mixed elevation & Monarch / Peasant issues + +[TODO]: # TODO ================================================================= + +#### What happens to the content if the monarch dies unexpectedly? + +What happens if you only have one window process, the monarch, and it +throws an exception for whatever reason? Will the content processes also attempt +to be servants here? Or perhaps is there another mechanism by which the content +processes can realize all the windows are gone and start a new window process +who becomes the instant-monarch for all the still-living and remaining content +processes? + +I suppose we _could_ have a content process try to auto-create a new window for +itself if it detects that it's window is gone, but it didn't receive a clean +close. Like, the window process would _need_ to call +`Content::WindowIsClosing()` to indicate that it's a clean close manually. I'm +not sure from and end user perspective if all the panes in a window exploding +out into their own windows is totally a great idea, but it's worth noting as a +possibility. + +This is left unanswered for now - we can certainly experiment with the content +processes auto-recreating a window for themselves in the future. ## Implementation Plan @@ -807,25 +1032,15 @@ of each other. [1]: See [Quake mode scenarios] for a longer enumeration of possible scenarios. +[2]: I'm not prescribing that this solution _must_ +involve JSON. In this scenario, I'm using JSON merely as an example +serialization that we can quickly examine and discuss. If we did use JSON, we'd +almost certainly want to use a string as the payload type, so we can just pass +that string into some WinRT method projected by whatever type corresponds to the +provided `type`. + ## Future considerations -* Yea add these - -* Non-terminal content in the Terminal. We've now created a _very_ - terminal-specific IPC mechanism for transferring _terminal_ state from one - thread to another. When we start to plan on having panes that contain - non-terminal content in them, they won't be able to move across-process like - this. Options available here include: - - Passing some well-defined string / JSON blob from the source process to the - target process, such that the extension could use that JSON to recreate - whatever state the pane was last in. The extension would be able to control - this content entirely. - - Maybe they want to pass a GUID that the new process will be able to user - to `CreateInstance` the singleton for their UI and then dupe their swap - chain to the new thread... - - Preventing tabs with non-terminal content open in them from being dragged - out entirely. They're stuck in their window until the non-terminal content - is removed. * A previous discussion with someone on the input team brought up the following idea: When a tab is being torn out, move all the _other_ tabs to a new window, and continue dragging the current window. This should make the drag/drop diff --git a/doc/specs/#5000 - Process Model 2.0/auto-glom-wt-exe.png b/doc/specs/#5000 - Process Model 2.0/auto-glom-wt-exe.png new file mode 100644 index 0000000000000000000000000000000000000000..9d21367e754e236019961ed10b2bba984138f375 GIT binary patch literal 84952 zcmeFZ2{2pj|2M4dt-VWeccWEH`)f;8Ll;Z!Ek#kaFHMl5YNwW1f~1>jt7xkzYTrdH zC5bK4QWUjIVv7_d2ttVk~4pLb-Z5A*5_ly__|Rfp#`KTDy~q?v#67Ne(Vy zgx1YP%Rc}fZRg1Tw7>hWU!NaZ#&n(d_4&2%(~;k&`%W%%hRZp!_hu;m{fX>B`1)5>YuZPZCxR~GrCC!e&6Ms zj_tD%0+P8+zW3*^zq)p5MrK*Pg2wWqVl5ChT9kdievy6*CIt76)=%=Enc6qN{(aLU zrpOFdQrg;Rx;o-DUf}m#PQi}C8Is4n3w*v@gp)GC7&pKrnX zq~4r#z*G76`L#Z$DYg6(@p}>fo(+dS!zug{MTk-->RsI-I#gAscBNNtcDQ?O8ZL4z zY;D$AgFc9Hr%iUGoG|<~G_WP*>BvBjMA((HhTlF}_7Ac@w#h7AzuRLN6E=Q=`hZR@ ziJ9CBE=f@d)N%a#%ddsyr*(zE%m=e$#P1Dkf>7cuuPSyEHYQ}V%EqV57zkF4*N?An z)Hi-Fjk%HS(~%*PtbfD`o>3j>Q|yd$ak#;f-|VV0MAVUf6xYoAHb;xLjgZg~nizcQ zlz32NJps;gb(l3L=;3(#bt}cJ&2qlF+sFZXpYZ|`c(h!QqV*;m8(9J^e!noyF zBlYR#@p-~FLNWN~4-eh<=TB$8Jy)e%KRbjgNi&L}=LUNwrK$wZ54&{S8^U?BmY$Xr z&`{y)k+OBi+KFE$FG1OZcJnzqL+BXb6UUxDn&3?uoMNRJI{5jS&={d&huk zx)5E;LuEuieYM*Tbl0JSGG>Zu#dAgubktn$(p<1`Q<_=FrNe5u!S!J!KB6(%G*>XF zbIo*;;~%)VTzCgX&B~_#B|2EsJr~N#nX-e`mM?qZLV6D=y5;-j@xPLgSltw)k!r_n zI%6ejGGZ^=`(T#UoeJrFVK@Cte0frD$m6{Un*kcB2F1Zgt)<@CRQneYkkdH{>!aRC zHiY$gpLnHu*m@;&d!0OARNnEkHwt7lVRq!6+sIWAy&y03<-EMww&r@pj-V4h>>B#vi+WPd04JMQfXVS@?)Pw~ktVdi#cld4! zIq1^M0a@j}S`qxrNA^AAh0VotQN0`I&0-BOF>&>SyfT%aVj|ex9ej5xA7mse`Q?f$ zDyLPHl+?^CvzB{}6oc^#8)nB)kwR5Z+pta}KFy+t#DKbI718eGVozV2r81`(*w&=? zmIUoG?_BTdrQp$Uq2V=J8l$;Q?LNiK<~mwbbQWeJ{c$?nQHeoQDy{6*m(=whh!a^G%j> zeVfLrrWZ%%-kYk+r7yzhByF=8(IKqoP#I?vXejvp`0CeK*zC7(Wn-L-Qv$ugZ zy;9FByE?5C;~osZ)ez1rq!S~eg7p~qIJ-V2sD6L8%w|Xgn9K~e&X6-g1(15DIVISQUYgcx~0Z4BALFdk1P-wemv;LCnkS8LG z7EUu9&PlLKvd#4Z2X-qD!ReS;AGB6z$XLk4joobn&D_9F7x*${g8z`(+474ku|T@_Un zvM4)2efxNR6*L{(I8uQC8$q1WNc6d&mdrkVjkR(J$fl?#K8C-J5Xb=GfWn%|mqo8O@*@@&O`a zpL6!7oe(JSgcmfQPg`J)c|d0bp+d3#>XT+JiG#8^7mVtinpn6go6=?jwe6f?N5R`h z;F8M8t2Bc|p`ArfN1v<7Wqn;D&?W3xALy4BL;`>0`-#u`6#MDYI*yr)ppWTwN>Ao8 zd)8gmLim-NOK>ED-JR(t2D13RsAJuwyDps%zw30!ve;%i!bd=T^}A2b@f$hE?{#Nt zBV5G7mQ6Hj*Cvw>L(RM@NB3&j;Ji{~myCHJTSA0YZH-su9}oX*I^li8G4YU8=4Byb zzR8CQz{SWc2i5#f^~hSIkUq`+P{fh&-6!!=A2 zWV6)zy!YFRZ?3($YZ)Ni5%B$Pn zia7De?dnDqHfk?#p~USEQxOiQ^4#Pk(Ggzo3u&opAv%tReB$b=!tSk_E!pW^uS8W8 zg#G3L*B;sQ(y?v3I|lKtQmy)IqFM-6;Hm|A4cOEy%zKOGN}H;cNU7zZsfh&WiWVAL z%*&nm+T7Rn+&QN8@wt6Os%5_id!Y@w<-6?SMf>1)TaILYtTy`i6$xSK+a-4R%(C2P z2c!s=h+?Ogw#x&h_D{r{qE0Bv2)h@)bzEtcE?Lb`&bXlSU&ft*J0AQwkfKCZqrv%; zrdGrr%oB+nc+4euY4{WqBNnovLU!y@LTpx~HX2*U`9sPawB>Y}){u4MMj32yTB6BRq^oFvMr@OOs<>G@4VdwHK8H4v>>R0XS{}4Y$GN^RkU9W&}^rBl>QVb z?3vA!1eDOnr@`PyQgQ2BC6nIFFdO>(Go})2-D+d~D82s@l)h0ploB{{yxm09NPX>| zT)dRip*&YT`oR&e+QlZ9`59}Bn}u9Jt=m%uuQ0-oZ6DvQ}hYRq>60?bg1hs9lv zo6nr>Do^6UR3n*0tE{paW4c#(@}L0VZ_=o;ScYBDXt+ypYhMEbq_fKV!qnXNn=eMD zGlxVA#S=9C_NYk^qNewipBpN`{HoL7`9#*%r01{a?ON|ch0Iqq3s`7eJ%GRP)xAR) zZ`pAQS}Gb(IG3C2^EIB}PL|QQ5CImaBG_|YbAuQ}T7eV26S=iC)jb*5bliD0gLE2N z>4Gkity^`_DC%R?vD7p+*2#ohgO(aT*HJR+Kj{V|_X$K=v|K9R zti9KANaI3wRp%N!s9#hCgNQWq-A z7lv-7C=&&a*2-HM7}DiTU~PWkbAi+_oOt2sFO}KxGp8VR`ab6RqQR*FgRb59c)yWg znzo~ib7ekh!|joD_=-u{k^3*XD>EoHZOB+DISjwZI4!$7IAnX1rOR?N7)A7Gzh7W( ze;3#~2^jX-=5NXqeQZ-vhbC9shNX`=9c%F5f1Wt$>4*-xNYaiap1AYKx$Ee-6xAp(l-Yxl7+mxw?&Uxwh7fOa6<*J zKPn{2UchIP$#U+Sg&j-2CV63kNfDpZK~Vcll8RUny>6vlv2HQSMgKlhsx~t4WFfQc z=aC%jGFl=$GI01!RcY4X;CU4XA*l*A9_JFm790s}zGPRQX%pae?ma&%D>@NxS5>!^ z!dT6a`FidVqX+JUwn=vySISrPL zJ3LV4s4JJVLJO5z+P!056;jPfEfCpZpV~T0vXXg@$$KDYC7dFz-PfVQ^sCzPPAwSR9SPd!5jJfeumdSSbF)p9`P{OotrPO|Uq zS>^P3a3C}(>y>tzdf0{|X)S$*F_|ft8!05aBHC-1B-eubXi0}qDh^;QF^3ME!s}du zv*tyk>o zCmEas+KPqIkn=9X#N~7$q*y-aEYdiT$tcfP(t)JMr(MWuzN|-f7vL7SsfX^MGceE_ zY$)wkagU&0vuX<`vnNB?15eqi!|@IYcV@BAI+SQ4&@^x}HPxGznJY=WEISE1uXG;{ z9aM5H$;p_Pg#Dp=Q}pNJD5|#h8LbFqc-M{N`Vfv zI{x7GU&!oCs^m|tl7JHzJU zO24DU0J$S3Bc80UUvKnK!rJ`309@CGNFEuiZUI(JJ4$?Ue2;-FBl&B5)`Z*IuRnN* zMGt6tW17@gx(|}`BK&NXwGaFCmkn_uXhUd)2*{`{2c!6!zcCjhTFdL6{osW{$O~)=G$>8bXHlSSACw4j@j=z z*wduE0w{VJVd6ms#XS;rFcwmN?+D%~afVZ~R)NEYepZCy`F}lO`kY&Q*N}e9fvLIS z7or<3hutWfgTl0x`M_dY`U|fy*!HLdVnth{FU*iUo&;1ty}sdxB!6Apg_Sp$!mqX8 z+8586nt0+omP8R}Kk=??A5x16D^1y{c)ESiw5)MSR`(1x`DG*hcM+oDFI66MT zhJAQYUdr>WCnfAtmDm%BYQJK(fTF`pV5V+zkH6Z;QnnsqD+uKc!iBK|wqVQfeHya|5+~RPlhf zeqr#dI1jWRWj$?l>${QF>Te9-AvPyBgEh|*syVx~^(m!4BZclib_tqvqpv#T$68Cy zE&a0j9Petr?ch9d#t0@w#eelZd*QiXtn+3bU1?QSL-hBQ2J}_bw#4W6eT~q){3wu9 zvb{(Pt2_S)_v*vCC_xnz$k@8|9kf#Y&m?fZIF}d$q>3a;tj6}x$JWFjSre{R;JW?L zzjIkGuC9Q-3(F&AqppE2oeb1SwTcjk3J#;g0&6$@mw(sZ>FE4Bh785jEnadNJv}Lc zqDR878U_Y!-&YK1+J2S$>l?WSA18&6s3_KbhYJ*VNyVDZhT=w#CX+r^mbCJ5j2 zdpyH#gKy6MzO?z^+&ee!>A&GmmLgku>u|F4Arv+$p&>i_(N zWKqiYb_Y@3tAzx}?d5WzPku{09QAjII-+Cn?+x4sGhi%^Hv_Zc!@_|=PN#vJDr8gdQ zd{9F4znx_qdiayr5ON$ar)xvk{$ts?dQRkPk$OTtEwmv1tayq(5x;s0gkP)q!#p!} zq>Zx)2ls;i&-cwWafz3mUM9=C$JeY3x@Spo2F5vJtGhzJe|n^TgygwA)!p59k8I-? zmF5i?dH1_};Aqg5Y%cgC)cxzo4d-!yW>eys^GA&-lR@e{-=;tWeda)m!$o?uz->zio7V2)Z zOwvw*>z)ZgL(8_2J6UA5;dw0v2itUP#!V?uY64je028sEftidxq2!w_UTDFZA)+>~ z0ycy>_gzfh4M6LX`nSyr3k(uu4A=K6O=rgr_Z66JhH<9$X6(wg(G!cX*0QV#HEoC2HvIk06w~IVWw^6 zgm>*hL(h9dZ|OdBZEdoIVS-LE^ZK+M+%Zi&fS$6!`$xLcEH!bh_We2)oO?EZ-Q~4` zOw|_wh-nTop*7n}hT7aL?et?xc9%IeOCUqK;M3cG3I=)imww)+Uf-rY-%dMo z8~KE})wO-JDO!|ni3T54dwXk}(Y1XxV77l0&YYQe;=L&@IlZkxG&f>6ac0s}>pTP= z$-PT2#T+bkn7Cy*<%y|chF|KKc|0V9eT|8KSw6k~ui(a`R;!=-^|POo^sf7viu!DR zTP;Kt|9qs=Kh~Doi}R+sv@Xt8!SO+AeiX95n%LI6wK*JhrNJiWuE+NDVs`X(PhnX5 zn*gJ4Yn36B^9A!WynA)cUb1pfy7$tMo#?oP3tg8hE`XMXkO3PsL9k+&Al*A+Hv_P8 z#WnV+byX`~Teae~x9Z8=)%{eDO~MZj&bO^-avT#nn~B+ko+5ASjaAG}v?bJ_Avhhg z58E0$bwswFo0d0=Q<8of$)1>*M6y+pB6aHY)y{oOBiJX1JK)LYX6A%- z&hsrhTmNotLm8Wy%uMx$x%(;dk&`IxIU2Y-+zKU05iZz^B@P!iHa^q5j+=tbjRl=m z@E#F~l7BYOS?kw=1$_91i;7|-@N4($SRykTIb9C_&Lh&w2g7*|O{RwaY?)mm*6VAW zj?b1&bi+%+Q^6qvLU&>DRS!n%KY$9EXZ!0zK^nl=*#Ifhxt9u$Dz(6Q64arY2J8dym%(l_|y8QIofKM|Fx3n?!H@_V(I z4TTKz`Psp!>j~p+e@u@xY~l&GjaxtQ!R{L$?I6j)jG1GZ%wF0@ z8T~<8u{r~mv0T%~<>CaXngZrtk93W@O$qNalfQyN4D$MIzG;g_t zna6Irhz44<#_t%0>zlzY$lH1wUSEsOp~o(~9^+?Ki;kAh1Se=cYV0-A5T&>u!3ql) zd~g|l{LrZ_e$D>oDJ^vqou#FOLc#r1zP%Xz!{x zz&*laee?liB=C#c));$!opAxyOIUx)Zq-0PAi$kaKxubc96{ESc5vS;x_k<4NXrio zDi$0GShWB0-D}JG-PqlROK%^A2^*Zs2r41O)j-4J{}QN83!XfV%#eGrC3cRB!;^h< zDtzrVlc&WT)*fALjgzKiYDaGDc*tvJ1^jr>N&bf6(o~$uT~w)cz2)eNs&t%bVU}(T zfU-~UJa34n<~;j4^ID%@L(-EfAoFQS( zZ+#0-TneQZH_XQ)ttYn@yO~}~`w|^%9X7qFZ&!K!pv)NZ9{0^*;RcE(y(m)PXR?LL zusjt!+Z^cx!keTbL)KaIx#Ac62sS;|lNmWvna-<<-!Wu6>B7Enb#g=JgY1M&3W+;x z^JnDvPSmK%QC>!j1F>s2DRc1gY*3^t@8>xm_k+c+uUZ+@xS^UlBhl)?03hz;ezfFv z@2lO%hPD72<&zPwI4%t1MN!tcL0?F)iup>)OI`XtOfW%Lu11-GJ-nFtsRFew4{5+-7<-Ym|5s?Goj}ubzQmt?dGhpQZ^xc zQJ4hIO$}+6C*KqA{YgBe^kNdTrm4{Gl_V~QHkiBNugMNRA4rrPTcB7!*x;EPU#ficXu@{ILxVj@?zS*6aR-1}@ zk+51SNDbHg;db7zPDeiST@ zwvw3}a-JD?&!4N92xs3I%Jl5n`uKqAKil6=yRN>XoYRV7jJptbv=xm8uqhBJ6Owba zK3&01{fq~?=o5MO^VLvH1t(-*=zUv!gft^!6ROEvdS=838x~tdRygO7P zJIFIJ=Tmd;F6dLY^0^I+=_zSaoKTQ-k)>op;dM_?lXi;z`FECKGeKW3C@`R*zLm*K zLgS(M2g$jx9zUciTLeix_Z}Gt8810(z654%dWQ5uK~LMr>jMF9{dvtV5H_v0+xl}F z?``J)WagZ$X9T&^-Tp|PSup-w95zX3q}Kbx5Cs{we+h=;h3tat{bd!ISMv4)G?(7m{QJN^OYT11>35wK^0|PJkkUV=tcq zBW?RIksX83MJ95SNiL@!^P)fFJMpm>2C1#A_<2J|=x-c_NPNGV{SKo^O0aRqA0;g* z@I-l5@21#*>fQCAb?xsjIcApWfRPwC0|!vqQGMEa)%tPg52F!!XCd`-8gmuBADPt+ zbGSq2;I&W!0x@hSgw{H?^~~P4tWMqiod8OknN6I|Q6`v6?${Od{LQVgJoQPMoj zW5p(J^|jf0plgrMWE2%T>Ggie&A+qC;zR(OT|HfP23$uPA897BC#Y-QC`z036(K@l z*;dX>kV7t$HbWKPu6nXg{4k0OOVvMC7;k`-E^5#+xvGNP3Z+hGC=>b?IBvf;N@jV| z9Rv~-l=k3H$a4xu@{WOWV2kERzcFMWXF`P%kA8u;ln`Qg1uraouAC%>@4{~Z)awuN zglt0csm-toUMf7b^{LAyakOH$J8zvlv{H7N)lIrIi_#J*^sM%p*qV{@@Ue>;-!Vm( z(;2w1H<(XX?K+2M2Qh5|L{mfPE9OMG5(G|<#BlF(Tg!=u>p(vd$J%#4yvohB;mIUFyxl}(tgzX9?pDQOFx zq&beVs!zvK-Z-|T5#o3>$bPVgHZOg~o3tGhAFcygR`k4l&h#kti33`xT+0P2pdCEi_GXLr0J?uk;@o>`h_|0rpk3=EX zpnJ(0&23YDJI=~(It>NS6AYpogcWoBK;uS!YPrJ%sR-#u4lzRr?V)tReoOuzNcA_N zV(0rY3-G>z7Ul$UMVzsIQn>@1Dj@o<=7!NFJDV~!pEV+Q+o8a`joE9&Y%}{4%F9E? zXfTDTtK;3xaS;X2HdUy8+s$8akRJ*K3b%D7ECS+>b=gd;2p?>_ik8~8w^y$ugGu%y z`pRy+sF<{{&Pd8yKOQJEC~NO>kcvPjB}JLRA=_)dQq)k>n$$VjD% z_{WHSFvGPgB zC-yEdHFK(Fg>=Hb(4bP{I@s2en;I9u1uoowSOTCEU{dD%JNY!2SJOK^%7o9wWEItO ztm@ofgl+8pd3yQfl>EV^A6JA@fRu%qm%!Ifs<&I7vD7GfR(ipp3hcX?<4#-YJ~q=R z-gy-x)A~N2Si+P%by_zb%AfZkzGH4kF*SJHU)`sKHSl^1B3nnyY>^DuI9m;4cO5g0(_a_3GmuTxO z2BR9*Rxu`PQ7ICqFI6FexxjCb)K^{d%t4D;TDOvZ{Yhq7yj5i6?$OK1<+ZP(!y@<- zmk7p^Ih=Lr8U#29&n`|rwfEB=ILx0@;i#>)>&++D4Bvq&Du&uR`e?;NmBi~=i% zUR~OX4b4%lhaJCo_nI8(XFdNpX*9tLTxd20kk>bMl%lWIpN?ERk#k#+5$1sxz!C>C zyDM|2FNKev!o;UC=g!VA3Q;wRe>|UeuNE^Zlnt9&(CxNHM5wDG)VUdiJDAfoso?nV zmE89eip}eLCXB7|KzNz5lQ71Qy_ELd+rU$kXP7)GL)h?D3|(Dtanq^%z=5>%VkNX$ zNv77t%02f7K00+ahu!ch#wVO$kb2gnt)@Ahqfb?lR0#s17B_lO#5ghxvo+_#ma03u}5m8pLmQ8M_ zw!WT@xxu=8!IR*(&hb`CAHr7}^H_uA=7Uh1KBxSWIR8GA#``5+iBy zXUS{ZzO{R%y!W~1>~EF`Qry(go~DU0d1(k`_?g2FX@Mib1BXQ5p#Zt>wKUnZzOlK^ z^y2_#m;(7Ug&EbX50j63D`*G2)o)bL|&-i@G}bUB#Yxa?)QH06KI4Of*Tqt=#a zx-svX>=dc$r10qMcs924Z0+|`g+w&(pL+UA*to(x)@5L}9%3H>5PH`Ec%a55VN_~| z=oRr%hDUL2mQmln@H(D!bl;2oj`GKbHR1MHO>$$TkSmzO+FFR4^Jws^xK;%jL3d>+)*|vy=wsl`g*|LFn1A zKUMxfbK`IKfQ}%Gsvrao7kCX1$iN>8gE{^|M5QQ#y*TR^N}ts)=rsh_t;q z7s`=qvNn}no&fH(kGy!%>N*Fr9OmS8kkiu7qs(+)1CU>~w-5TY!pN?y_>2iU>?ik# zJs({&!*?}kwe~fMp6HyqNI%k1!n^}$nfy!MVCMjZ>d()$lX`&HCb+qamcOU{Z9#^PViyQ^{yPABmWZY%Ua6- z!3V$yOdB8JT#kd|J>4c< zTv^YY>TbYI*_GbCE{A#Zc>cv<$@N7myWmE&9eyyzDDiS5pkN&K9KyCIXeu#kmp-CD zD|!z85CnmLG`9mt`SAD8Pd43;<0sibW{AuB_Gr((Y9N@d(qJ=vEk?adSa0gQ9b(N1 zsUhdlf058}z9lo=jt3t-DGmVT$Y>FO7VxB06VJ@OfXib?yYte{PUyn5K@`TZ{FgR0GNVBC5E$HSqay83TW4 zFEeOW#BVauxjIs&`YV$`)i@CpnVR=$b1YIeI``f=>ojFpVcPaocb57r&_01&f!+W1 z{$TsS%}$g2lD{BJGfHzqxInFE2b8?Fev8hz9>PfyTHf5DmX()ioh%SpJY@C~RnxYlZ?>&7>6;f{>}CL-cMy2|PHGW<HMPDbW$wa;38(F}F8 zXVOau^AS4q+-Oy;oNv54_Qb`-ya1Ft`VYS)$xDZ*jK8|_@ewOY-aV;egufsc1Gbkm znF1wATB*$`QbVr@`*}@uWpuyy1HcWYR(QYQJD@;=AB&CvfZW*#tf5Xub^ZnYQ~z=E zqIS%(r7`-`9jBW=VRFI1mj0084=7qU7Ct@NgLr=fR0q1nzsL0i6(0hSM_CB=?U)jLI9J4rZ^RDw46<_8B@u9680mjMht<;& zr_zs-Ynq;M`^xzLg`UUe%VU;j2YLmT$~rD;gG$?S;NRUSUh=I(Wz`EQhyG&-ikwU1 zyLdAFxa(&wnwbaOW6lr}Hbq4*z$TJ${E2|}ey2yksz|V&lMTWe+r{EgrO_h1qR2{hH%G+3-5$ z*CO(6?+D)Yw&B^Tr??^vXqHce@?-O380>)!yJE!GNpPO5is)4fy)MOBO&Yz!V_1;_5-fa-D@{f;j`5#`k zQ|rP)G)go*D9|cjr`W%0{yn`TIoKRUu5=hG?-!My&P>n!-!*{!&$IXcmMUPyqs28w z1llgamt7Qn#=cD1HA$D$j#-x2iBb#_e#M8=)wE%NyP`P8s0mW`JR~_czC4P!>f9ls z!6^#?%2dZqivjGpDo&yc$Vw~s?Bic`<-}N^%LXehuHf-L8F0DcoDQ3hy*Ut^*Zj{m z*+762ex57$al(^YN8$7fc>(jTT?5A6oQh?Bsj0fD%*aq_5AHrA4M4qi)2U*fhm019gqi9YFt80^xWF;> z0f9&HrJS5UJ0}pvNivQy*En~QQv}1U?gAUT&QEWeN+2+}%7y#hsupSdmP4N7&j<{! ze*gxx{r+N5L|2XG2}Q40O&@?hJE+{`Fu-ci@3$ve^cl+URH~f0iaWhr+yxNmKt1Um z@>}}`25uIm`t$4Qy3;KVUYw|yx>Lpgf1m#c=X*M&(Pjpm%Yoxs+sWl(n1T<999qO3#fy@zUu%5}RxmYy6$UuP1&OuRCQc z!9CKOXT&k81$1o!2qLKV_WJ+hIs;AuqUh9mByhkfp$eeB*Ij|(1p*1&;`p!IKaAI! zviWYARr{CjiT#16l>|Q9KZ_N{#ImLTl z|H1(Vh`amwv5VV!l$hEe?zRw-SC=jqh{(0+csLrn`IpOnh~kCChM|(qK39~BnNWjjufW0!*Q$lv=D$PtBs_*dgUJyu*f#)CAIeCG;VY!qU9il_v5$o*cS z!PLHIBgu;1D-A$0y2^hN29$;gY4JJ$@3=D5k8!s`BDc3T|7l$G1juLxP&~4eNTZb2P4HNwqZtbCI!o4ng8nNl4v#)ukF^~u;)S8@j6!)K&CeMS*B zV~!N(T+{Oua2F4i!$7FJG>?U?|M8bGibE;4=5qrcSUTNU34g-T8W%yCKG z?{wVa(1N2^oI5;v&fB1|@`f=JODjX(Y^M^NsveH0#fVNNXrOmGd$ak0X5S;DFOdw!{ih@7*yw`Uf%0bj#?Lk{AkcH1BO=KpJ#1|vfh{-+Bp+VCA87i+S0M-Y z0gk@~CMYWRDquvfT@LJw`BB#imxlj7YrlCBenu;%6Ypvh>v(Z{h_>c<5pko_r8swF zD40z(RxK$jCTA!4$GdgxXO?B={k6JVv*s+=xN> zacp^(^jZ9g67o_<#F!5?8P_CB$6!=8!$h?z5N@MkfV4q=zkK}Xx$_F}QMWQT>>c$Iv&+t?NS^R(m?F&FhbN2A&n!^!? z1k){vE%%+x>@xQ!{*l7XM=TBizl${=raL??TgNEg?l4u{M9Ef_Z1nQ5P*&J#tq6^u zpWW3e{$<(bjCp8zb9m4{8vMK&64drdJtZ{Ka}GHdIENICpcV~|ijx=DP)0G!<9hrG zBB#53yVe``Fo0drl#qEdQ}8p7YFfy=5;X7lv?9PGi9Y}oR%erXZqlB#Wt@7D0KVq}`qFSa zuEULq791Mf9%N*Wr%$^bml<5iCXG07IBzm_@Msi971PRRaH|%OhXoth9^+0g>^v}K z^QQr|OX)1Iln=2*o7=q{#T{XtShDe;EB!j4my?&pzu8|?%`8S3;7i(tC!Ps(Y`ohn z5nq+XZEZHCeTi5RRh^mKZVs7m4_whP19zm^01ZltUTWVFn}Z4(Bf}n|@wIE$_1HfO zdH2?&+8SL5rW}n=Q~H=74qdCEyeKJ%UyW^E_6b=L_ld!;BIGde6-H>MK;9NEet&0? zHl35mM-W#wBdEUH>~I#K{2#39y*({vXlO|%7`RP%PFx0hS|;tnm=+p#QXH~8p^%M^ z{;N4goZ$`RH2$0}T~He!4iak*QzfD;X)oX%K$|ZG2qYVq0S7cAaqIo}4t2K2cK^a? zgKcN38YP6`)REZr>iCt771z4g=t#<50kK)2n_Nh3@EwU_$Jn9M+)n_W^B&UYB$fLy zQ21B3#7fqf8L1J`wlyT9-k%jvkFw;wTn8AYni4~ zYnfp-dTn90s%0?M(A82%`TZzyqs-f;7(UZ!x}Yh22O8u0(%o~y#j%O6(?7a$Ycp(s z)R<%163g~Z{;qA$QmRn7y3b9l4zUCmb9AacP)&ho<>NyWYP-gtu`3wO|QM6-%WkxtcH4ls3> ztm#1i!z2ajb}Rs%U&;dN|5x)93IVg$gj@R)grJtH5AA@~a>i>j+-t+~P4Wx|9M3YnB%Vonl)YjVx(Nkn@mb|(L)Ab% zHtSCjl(iF4GZnUdmmh!es}#%ybSq^W zJBY8n+c;6nm(a`RP!TluQ3_G&G)>I#G8NXI>qR-Oz=8?W;t14PZSaQ;62vrW?~vTALp$Ze!IO zjjwuxh{&~};m;^QK?V`xb?a8fgWNk7R4xo0d{#IitmtJU7r#FriddVNvNKC6zBq8C zcg*^FRsCe;#ZXI^qH1bf*An_iBsfU=!|lxUf!%>~&6;TZ(I5?GpII|^->7f4H?^+Y zdafY8s^CmMzpR1_WK8Jb*pWU+m&V;sTswu=!wQ$3o*u>fovCvXq_V>tVRPDk>AeTi zW+RB1NyPJ`r`-12>i>lj>_5-@FSk=EC}x?Pi*%_)Y0<@@d@ro(>Nf^u8$PpoSJz3m zj|T$kY9LV@Iyc)3Mdu;gZ--4jv@dZ27o%OJZVAgFPuYe!;3GQH-?qiKLsA5&kr@l? zSo&=isKa99tW{({*4<4rv%PHC?ZLpf{%ZRd^g;HIB>()u!DS`;@)M*j`M{OLW^!st zUxjP$$4BM6?JzFIUw{{_05wD^5Mygc^Xex`{XVa5oX2NYQ!{-}x{0Q=9ksG~3xbZgyL4%UK zj;o+yGWW}DUY^E3SqYD40eV@`qL&RIfh(|X?V+Nutd1KfTY=DjlIR_x6P%T!*!9fg zKR9LI6GH*cb`9Y3&2u9xdpS~H2fn4(AP)8FCWb_?=BYKvxh-b_)_#O*O$wzy`teX> zxo@o9tMk#fx?Xq7n$sQsg@n)L<;PT}$bYn|h^yk88ET<~PBe#pr)1dXT6n1O(x0Hr zbuvhGaMcS1-FZf7F0(;@V^tPc&H;t+Vt>9M4l7MY11Gyb7^WqhvHA|ON3p=YaOt}x zI^WTPBZ5I3Krm8W5N_y+d+Zy&RvmQrvj)dqRNUw6i$kQv`2loUU7*y3BOOjl(LbLs zC%bIuCE(G*6U7S~CF*LIlai9_XOOF?E9Dc$h-C($E#9exR-D|lRtf?2S|r!Lr=?%y ztzocR|6onKO5$FAg4C~fHOA}jr}3si&r8RdcorHJpHv`&ilBBc+;CnUGyo~?wsz_> zg{FiF$H}*l&#S)xFGSF;p`%Z8o=i@XPQj_hMOrxH4<8f zeiZK75y+r9bnLTpM=VlYj$f*T=;d4_;S+*W^}Ww|v^Q!_1S%+E&zI~2VYV#c_m&H) z8g3DMI`jP7il;mOd#nNgCV@ zL6^YN3%=L%^Itm}WR#|^7V<{(5lm^q1jr@+igF_57%S}n_AVe!im4-?u02|!@AxD0 z+Q!z9L?y@9Gln>H^w~g<{M$#-f-9L;xOIE^r%rcTiErt$wko)orlh2y2M78d|Lf6#ZkTjN_D0E{Ow5WFMdy?OgXyj!5t@lNwADBPAoB0@tww;<2nqvSxJzkN9e$w6y4W(|D z9ZWcbaV`ZDXa`EgS}@Z19|dxxk)b zKwYTq2r3a2;;wfRG_$)81Q3h;wXj*VoPNe_eNL8;jsb|D!E^}YPAcC+3*B`fnpE#2 zD7C2hvCK7U0oih0V|o1|GSnZRW;DMw4eg4Jl)pz=1W|Zg^b|A5U z4b6CT1C7he@9P&|gAF>@R}N9nE7|!1Z!xlskt8Nq;%6L0))!XSj?`}7Cq~c0-R=ku zCOgDaMF444wx{+`b}1Z?eRtz;rNe50O8{pA_$8p|?0m+Wxo2YUeJZX`Q?~j0=bX*KY*XbC`|tRm zMF;)2oUMJ0A9#h<^Co%|P|Dv&#yKq>6n6jsnDTJ<37-Zkz*-ahFA zh2|r(o3+aCxBqNV3t6e;<`rCBd`)tl=_}~Qe+!*?UI74-Tk?~gY2rZc7DBOMUsdJL z6drDTcc!}z*r&Dc93cg8xGV=lb2;HM&BxWA9>_Wjyk=s0_|nqBt&Yi7mGv88##1P+ zLH(5HGm6r;u#jW-rTr};sg>H1f@?tOecX+Rrn$R3!r4h$eYfT1yl)`(r!>#1XYz$% zg_-YWL-*xNFda!&*U^+C>F&qjUX`70+VmswcHMCIlnQ?Ph;*W0i90}glt88w+{|-N zJ8+iG#T|HKS^6_Ud^J&^nV&w200g8|o&f3voaw=a(8*mYG)J+uQ}PBa9(Vnm>L z+`jnnykW9J74SlV7MzadUnlaEJO6j|wSlOtTT1;JMjd5|25hVcs|KV%>hH;_dThGrBQi%mz)mtU`>MKj7xfQn>~sWlSptC9zuD_R za6$BC3t2TgX}mdW7@jN8ZQ;B@#HgU`6dH|3vJWB?j19tDllyj07;*-ieH;V~wyEzR zP11S0$#8qd;OM@QOedE+;QQ#^-dydnc4IkJ?}py)IOPAu+j~YemA-A?mcardj)EwN z=!}SnfJ&1V6hx#+FNQz{5$T=K12#ZKKt(`lp|=oh=G*5pqSKCG4zUvTJ#^(uh1S-wdAbh564>kfx+{a_Q z%A(NkoCCHS$Ya~VA`*$AR&*#!CYz`=Me;7ULO`~S6YAQMLp{~rZn*1FM%W01qOFOuwAmpkH zBEelS@NUe3CQ9R!LV0pGqTNBrc%GAUY$d*U&k0{&g%Zlay_1k=ds4mlSB@biB7b|4EJuxqn&s7vL7`<-*%{{&Gn z)}#aVaU%X{S(nc~&BUK{ee=(mb=6dU>9WSwk*c#x4Ee}4e$UP-ba8Y(X!<|kJtwu{ zyECJ+?-v1c&ED0Mqa)br0k1Ew=(2x~!L-{>dX=rF2hgcuHFLlqUI# z7_MX+I3=GvqMQ2no>wV7_cUoa7Gq~g!zusPW zy0<&+{QAPjmmY?ll+h>=Z7tLLBOnR!J!)GWlp*FeTK198lW;FXQ~@s_d09~6mkLN? ztM<1HxqsuteaN6A5g%1H!%0*MtI+A0ueiTgiKiiX&#DwHu`~hSt*X;0HJyj(RTje3 z;vQ@_2hJtCpyvUOL;0lbRPaxhB5|T=oWc0>miN5J*44A=BMl`<8w~CwxD9nAoyqcu z?ooEKxv(%sq+Z4&-`o6}hk$*$o z*0q;pS;kQhJOVn^y`z-V(%ynZ6%XS6c8j~J#M%3W#+3W+d7r&Ctbp)vDlN?#H&D&o z%N)IzN$hcje#0P!6#kNa@K5@#@`Z(PaO* z>cy%MyZY+}QFUNpScNe%N7SPH6M%O*j!|Aw*sFq~;OHpILI3La$d&F(_)QUVVyWw! zuq(-#&noq$tV=T+F9x@}^OhnDmV>(g5o_E}eD$o$8ls$;Lh5In#n;l?=dEf>JSclz zo{o0Z+*z z*gx_`52ysJ-;~olz5C;sz&eMx4KV8}8gcba_=MSnBWHuQG4i%%l}gA=_4|Ll?&` z$-0m4B->i|4&I((mGq7dgauSz`hkKS8n1jnYM9iAitl9YV0$F@cr z94rHpBfS!fUt%%uky*Y8zAFAIbmOQn4@Z~ya6Ohpw;Ss{Fo;M=vyxp(WRY%&} zhS*zU`-A2RhS@j|R!O*2{l5(Xl5-vm2@CkJ!TM<5(h?6cj_Nl*xL<9gWGsBvpU%o+ z6xcYj10_~cLHf8+W->d{!TD`z-4I9wB?pbzZY$Ej1$8a;2n34;4)M_e&}>G#W#ogj z=?HG8FSE=98p&C^7&pD6&v)w6LN6{S|9v;_CnhC#)iS%?=RY=~nd_IZ9rMiQ0tAkR zcz3??f~$N9@x>87%v$NcV@Xiq{(4N?&Afwjn})~$%=+dx-cq~O4-)?lRja4vGXq+7 zM~|l4DpsW-8-B*(Xrcxfk@`puS(EtBy{oJZnd?h{C(0poNgCNc>Xhv?D!Ax?0+dUz-;3_&I8oC|4o~{ zYFGJRtlAqkxPO1hIPo8U_lP>5yNQ7$|Q_0)Sac<0~yxl%U;E{I3bVCqM%BgeNFK|#RS4Xuur6G zJu|P@ZL2G)1=ezq3M0o-ZOFI8*X@#G-`eFLG4vAmzXB9n;~faMV?-mm;q%CrQBSK| zTZ^&XUDMPq)^Eg;G+%MKkzx7gm7d4GjC3BTm=v#?Dfb@=l8qBn2Qh~X{_U*h4kIn@ z{D6687j=xCNvdE!;VYJ^8VfijwC9@tbl5!zwrYN$x}GwY`v_E9Cm+8zAMp7x(bx%N zmvl?${QKC4)Svb-laD`v<6*Ytjyvw3fNajZAz^7xNLYFq3Cn&$8ogL@HH6p@nIftH zxkv9mT;qs8VpHlNvel(QDY^DWX#uuQb)r-u7a%F>U`K8h0pW-7st@9O$M5y#1$vla)BEMv;#B&+k<@Hm6ZwYp>M&Y z5>1bmbiN9D!1bMUTqI*otQ=l?s|4N|%i9!N;@Npb_>)RCONi#3Md{7X=BpKO0^?Bz z;@72gxfDG5WT0}eMoRPqcVyJabQ&){l2P;)^KE$VklJNUVR~=Ky4uY{efSFDzI@ZBvWbCJhaivM^SM#t2Al=r@AqW z=+#>Vbr)rR*0S>_>sP6jp+(hm?dp1;ieK;K^bSR6X-z;paQx3VIOAkN$r^2JoHjtf z%N+3`;K%F7FS>vHGCK0)11~7;sfm+65Or|wyGk5q9+E5!9z;e7xG7g#Z_~#hc>nAO zlF)pBh)U)1#9B+}=h6PC(I&$=AvMlfIt3v_g5x;ipq)G1J2`9b7vQ!ex8#XLjm(YH zywT%BDI)2hfJhkO!YAq$uD_H1&7*`*LU*ACTI1M2gjwdmRk!l|O zk)vV5Gp4n*-I^g)#zN`CO$b`gm?5WkgB}45?W)ZmKr}rEU9BCRUq#f8JX;MB`V>$d zzlrc?y9XKud};|+I1o}5FFemVN9U^mqg|i}?!D3R{z+S$e-d8}LM1m`Fks+w`h45V zdT>o>VFz8X>5E%ntNS(A!4A1fe(MF+?}GC~9NKT;SK8A`G#UOLjn4HWk9$L^D{id$ z)Yl&I0msj9=RB!CF>qez+(45Z^|bH^kSQIR*iG}jvFa0lgYF%#P4{oQH7C^05m8i1 ziC@2?(X8OIVzpE z+s@UrUQgL@knE&m!h@PdFOtpi{*$%=Qyb#7;izSAMaFXWNW_uNTIsZ5ZC}pCyK^2V zct7*Uf&)+t(Pd&anovEcR^b<2`>ic(zMGaxVbMC%=kwCLiP-3A&MsZQ6jKGV>~gmh z#%7$wM&f9FNa{@3O1PodI5V0(oo6UCqg+WQEP$=ALbl>K9F&411gp9sX7e~o-?43ijir>tOZK0d! zS!1KoLeo6KEuiLR*h%N7`aBbzA193SX|-~MXu_B8J`v_reh7fwZ?1{9;;IQ@-+1Zm z>c^=NrKudJ^F4PMYt(t+@%2a*P`L^yZ`3XKr5|7BC!$1SrwbZ@&RU%Tekfmpv6H(?IV;oxckn#Jfp+?< zS7vqY5Z!fIafnKeCYh8yT%AJ$I^CdHBMb(v8vp5Rtu$LZ{5T2B+F;$5F7a25~=v zVU)Y2U{t<8DHRwLU;BNsZ{b!&S$F%B-~Y@iU$Tn!4*P?*vJQlufixf-oH4DQZo4M? zL1-R(7Hbs_k+hBi(k3yX>;rIw;GT>-(tuoqJ5+1^SUb#mV%i(niUhVc*r@#o%c`S`1b_ zKnH+Ycl9=N?oVr|lZM=*98d~4-BNNCmYkLdC)+Hl;t0jk7D z{sU!lQ8lji{{dx^ojyHTeBk++elTndIXF}kltd|IVir1TmcX7e_+O-t`qrp#LGd}h*- zS+x$qGL75bRYHPoNZM(;eK>xd>Clz^f}uD{0)wqf=Q_;uh4<^e2PVp+dUByIQA#>c^M^ZjKJOuheIA zHBX)_sj`@)g|Z_~;EfEkI{!;m>sM+#=%RYTJIkBrEl`h6N1cus98gy47_cTeU@_mv zLYLc}iktF%tpj4clr6Y<8YJxd5!6j; z5~ge*08-706SZ`La4F9{VMnQN+2J}c;6ZW=b93o&|GqM1x$JU$ViP>cl{XC+lhCh) zzDy*o=0MA!@Q6Jq#t1q2H_5DJeF`Iu7Al_Xqe_C0Gv@6}mqsDNS=R2z!w8geMf7)u^fGwaQVv8)JGC ztX}0~q<}ewS+OHm|l{ate+hF*<3ts@V~mQ+fI%3x3sJ*=^Kd`c3Vc<0wDm=U(o3SWB=>!dbcLy-<>5ebmn zVAsZ8tLwL%Sw;a3qFzNhfM(Mj;MT2_-u$?5efS$a_YW|ha3(Q4jh7eLln|ct5-oeb z^M*Ws2p<2iG*vRB1ZT}Ksto127*SB1vlcyrSlt8`3^x8sQ~U5V4rbZIw63Dh<%D7c zBv^EqGOM(fEHu|JhOW7}T7hD=b@sxF%8|ngJVBLeYoTef%4^EE)|hl4Nc##Y2{Kq$ zt#!7|e*d{+Cx)!ar}jF{kW##SI#m7WB$2>EtZkfSDP@yHncbpVaVHJQrBro{W}tp< z7pE~Kw{$#RK;|I@=h=Zy7Js*fg)6Gk6CpOF!zU*>ZNV9J7CCknyXPSLq|5khH4dWe zSP6mNGI6-C0Wd)6Za0fppP?S%!h%thzaRcr%pTJ#BSPFI=w{YAu6ea_3zQh+piZE!8~CAufJU} zA#!KeRqTJ&@b2h>aqJE~(4pI()R~Tpyn% z;SPVTp%%q`LVIhgt7e9ga_)-NySqWSbb{w8iND0Ugnp-x0)Ku-T@std&0Imp!D#IZSIElR&xZ1q1)Dmp+mFa_p?PGF zhMxDcJZdU643WQ8N5zp2tM>v$@M-rJ)mc@{fMcb^)bgpVw*Kmz#dZI4ulpUZH6UT! z09Ad6S5U?_bOf@0oYd^*nAv$5`H96Kuo>R1-HYAL`*_N=P_B!}7b^kZfn|)Fk90&h zS!0pC`=h#gJZk`Zuh3%_<8#VlcL+xWd#se~{#^`G+>A%~44o(z@E2>06^{os1!BM- z0-8u^|HHz+83z}Qyb~AYaAz9{a6d6W2tj^_?Njs}qKjR8ov@c>zEVlIr-g=Pr zuoFhg`PQMKN!q)5omA-lnLc*FIyq`8$fx_#t>OG(?W4ob9)1ke`{A|0EsWNYqOQJu zNs%?62+l|O=oa)nTZ^Zv)Q`vS^6ZvF9=)xQ3-qc;DoBH#74l{Io|#qUV@DRT>wK&x zZH=#{@uyO-h%G<6&#DXWcXwNPY?4F?frrDx^;8#**56y-*qF%%$gkNKb6^nu__V}7 z;+lJ1=o6d%LtG6%Prt&N}YAafe}b_f1U2_npu86Ana;hdhVc4f}EZp#$GESdX8-)0hcW z0`(2q<@)aH3$oP&FRf!J{8Fv2%Eg-sAuB(1IC!=V=wS!m*=g%)k`SVY#cacc{4Ry`r*`Y zJ~VNx_N<$T^n~kek&S6N4o9H4;W0ypMh|Vd&VX#Wg#rX*R(VgvY73@F0|vClV5|bt z<$kB)z{So%4GhDxY9i9`F641Q=o(st6{-Q32b?O zI^vUp%>$2;qZ8PiSAT+T?NYbZpBRGf^E2g%gWS1I9hWp6Q@tZa&(|GnEx%dC+8af96JMxBo?o%3j;OJ{-1zGg&KUbT-&U_VD-}vHm0q>Q*&f>u<&JK(; zcD`G9cvE^pt1gG9Ka+FMT9%OhQG&<8d-|*u)(fuO^S;{ECSd83}Hv4rWVR8c}HDvCCuasnx5q1+(JjX2BOaW>?=3gt?mF>bT2sT>UC})uxloX z-)?Asf^km-91APS(U0ohDCUt?CLoIaN}@=|2ck>F?QG`D91zkIsuRA5)F!Gy%@lV7 z&=~+H1%Z1`6I?NOA_Rqsn?^#v(^{dn{5rK}0e78?<8_yRR&<_?92yA9-LK-VZ$gc| zpmhz)sz~Jbki0vP($4zxFzu%a1toJ#Fk-HHZe8L8;m0eztdJJZ@WD$3Kdg_QmkkJ8 zwsG6ZUCm7H`6^|ur-rzDeBiI$M(MZ_2`Q1=3O$0GgpCx!mpx}(7IQiWgWacW+@fp; zGNF3@cW)OwDho|>YgTDKpBRhMXfgqVTke~KUHl6lRalqjUd&6vH+187eAxBUMB??c z0I#Fc=q?;T`n5e2GimYl(n}4plY|Iy%Gv_ksmIj`wXGAYl1`oRG&3Q)=gtdv`bx9>c`WyFAw*-nO)F6^wGI1UvG}h#ydb$(r*e5}FVN zR)Z98si4){*$sP^>OFnBl}c`@@L&%r=+HV%IyUZ%QJTX}K5nV#B1e8yZ>7F*5n-1bPgA?l0+;Yj#qfCw&YIeHOlbaJrz0sqcSOy34^jHnN62;@jy^`j=RJ zq*#fkIs7ui<>`xthFu4075s!$-_ zd{e`tCBF;P_rCTh|E+U3`vL^}70my-%kP6^Eu-S*MGQ}0?eP~IT~WI*wpo&1iJP=2 za&bdJT=_T8RrYZG&PceA{c7>TjF-C-AZ;n(qglRf=T=M#EHH^v?bjZBBSYxbZb0Gs zm3!zr@XzQ7&bH_T6s={!& znSJ2XwOt_M8s>ENd{h2W7+;sfL z7|nYFLRf*kgB$-Ku{268+v#Z%YZWG9w=eAL2!KqJ_)NY+q*m3$&f8@MQR}mL0_}!k zHCC$gdH7#>ibhcqE7gmb$8CO+1Iw3>V_#b){8soQwI@QP|C`K;USy8Nx6Dwob|LD| zO*d||`44N`2Bi5{M#&)E)V25QFXr`C*F!in4{1B*Q0SBh`t(mLw1r5KgdeYFbD1xz ztT~m7A7hSf$kG>aZTogf7*RvyFxfPERc5WCXP0L?{M=0`i%j~p!61in@(XF)xhfp>-Kw<3 zx>7(Bui|z4T=bfwU-?vM<3`wGH2k`Kwc6sxBVg8p98A!Qxy&EvN|3xdK)yCO2eT`e zPMx!KnPLr#tL_b3t3YXijY0i!x7GBjG2~b3tKf)Bf>Sbj`TQ!+UH;#QONjo{4POMy z&Tkc-d2J!8r^63@tR6w6R9bMJWW)~a4GYTqGu)ef$>lG~vT*>F0})b5hyG6Pg^?W^ zI#imL3tsIgOI04rT-eC1WVs(ymf^;jN(~T_Q3)`0w(a5qTd^iK&ZFM$Ks!}RAMuU+pW=5%URjZvPGHagj|Kzo1ImB zq%=<_HhzWKSyb_z$I#GpgUqgCXd}X4Q}x|))@zF|SSxlYDq(_b&_i)a{%ZYNgSOi} zU@NqDW05nv1^P-QVZyg=yeAy4apvh-KG&DrfvSV*SSGcfJeH1yA6d~ zCq}@k&0HCMFEiB?L(^kRxo}W&pg6*1!rzXe@Fnr^!!Zt!xJG8aw@PAj!P=%E*vlG(o<5sV{l3!yKvL zQvVZ~Wp%+`^qgng})=RLbNw9R~3v_JT3r%;$GN z&v}2T`=yx3ZQQ-hKcM<#(}A6@8?Gdg-X?Ynx*&hQ#r=w3C}P5>Dl9^o)pHrcWmi&q zKbXq#P#fCdz75PmcW-s>H!&i_{C&={3Vg5Y4ZE_hTviz;^1tam zh{a(+Uyef?q0LAN*w4>f>7gN*P#Vc-u+XJ&DQ$Uix#A7IR$^r%*Y^*&RS{AUH`2Kp zoLd}z=^3;5!t~&|W0vjr+T&f-2O<5F!34BcK#9XNBIu1mg%+_#M=4lNs4;`OIx`-i|Z-R8Y^7KJS~2t~G<=uC8#|!u17$2Ys~Q zR@6U=_Y)=HxA&AIc#@7gmezYsXow2UMhD!SNX(PWFnRNq!V`39MVWgCRzI6)s>H*! zi+fK~?14#AKGC+;9|ISpro7;Q);jUAoKOIt6t=W!^$;dHG22UT`3#rOgz}V%x~}op zOY)#=9VQRcheanYSBmOVKO0Q#0o8Cn>F}xxnCJn`IA=AE0b@RKsjko8xuyfNaD^fd zV!xz3G6ma2b`hym4Utjn#-26x*T&wQq~Tw#H?%C2kH%pj*^~(3*X0V8`C~|}d zB^0F=ELDGR3kmdK6{`|a9Wo64XacRW1S&&yCBZi!_UD<;4?2gug7Cb;nG!yJSsgk# z|0l3^q`OHpz9)4=E#$54Bihg=T}!Gz#YH^}>I7xot4em{?31RW3>Z0%pAqm!XdA@U zw;ZuQE*Q>X6_Sgs9!u-=xS zSb^cclAf-61**~eDMWE&^itWL4S-(Dy3{B8YqSHygL@CaZ)ca^EoyO>uQlh+dBZx| zwe(9O1O8fh+)gS8aiDN>j6NO?fD%0(=Yz6huZV-1mG&W=-Wpb6JAKO;XNC_Ts?f22 zVvcBIe>BYIrHpV1!d}!DPSg3q*EQKy)21znIwHc^kY7TL9rv@IpHS-IlRCHS{=giF zQx;o;M#5JC$^v^PA;guS{MlgG^6!Co>A$}q;~a<0uHygm4TP3KhH*r8S-_B8T_PalT`5%Y~Z;%tLI;j@C zesmOIfS=?km~^Rmf4{EI0-l~#92UbOC`+y4*k}M^*M`ZtZPJeXItMAofvHy+N41p-`)-;uNW3!NO+1#s%y2C{%u1}n@7urtHb%wK6;tLG0E zX;=68ag%*Q3FNv-H3)PFYlF;W8c8f?t^MC?jxE+FQk8tS%EZhkX@|Qk`hmhCSO4Ge zCFeT(pegRNB9VRD#XgD78&bfa0|8JTo+hlEZDIYrEsi^b$eqa6!`pTYkd{<{uA0w^ zmi7T0kj_10S!4+>PT(|K;yCvJrxcs44uE%jwRGAz3Ym6X_TF`0g&tr2ImwR$b-}kl zc7624Y0cOa0*Bjkb#>Nr@n7!5CP4!``;fumog|fJvIs9%*!-Mx1Ps@^GZ>k`|3B$p z@I=i&Z#-YnRMQ4TvN+YHCvd#ih6#talu^U)Me#%ip049m09vhbVu*|Y8%>)*q85U4 zx;Il41Odc37wRSXB9Y@1Vt1Hp4Aiq!0;_Kn;kJkuSGUEU>z$TLht;IHyUY)NeCUbH zG;2MdeYAfwtFUYn5Cy+ToAMV)dJVWH1H9!%=75;(+I6wpWb`b%34BLfFI%b7&E~GOY1?81FHXO?sa>XmR= zrprR@5_z)WB&A>QKx`gA4Zu`CL)huok}|h5IOQGFc($9HoPcvCPcHXG#7naWcej>p z!ij#@%;Q`eE?(54{&ihNUH4Xc>q)qJqb{QeDMX%_=qodf7wlP z^cYQ{jTWKyEwQT;H@5O-b&9!acOAj*0jWl4{82Kv!CEy3=6b(G(i~>#LGyJlvHPf7(CA zFC;!dDsTK^c?`3a4+45^lX}VIa>v$+E=A`ruENROX09=?6_9Twch^Au)bZe zmJ3g@D>s5{!_i^T*R#F~b;mXVSA9wfVaI=edM;&`yI}+T&CZ*G2nBel!!=;h>v@+L zv$SLOa?sMm84FlH)}Hn9Lc8zJ{jnnb2>aOLP@3c+i>S9*7M6B; zYK*7Px50YG+U5ZNvogu8+Ba<2=X^U?*O~Wb>xY%iRmBl zi5{|uhAQ?CSnNk@2+H?EuYfx9);{09vz zrQqBnjn3Y!HN5%%u;UPUIt=VM)STUOJ$Jmmk-OiZK7p%S#*BArXHWCyN0ZsTeQ}&y zP`7*wXl^cr^RVOg?C8G^9w@e`;^HQUN&$8m%y$CP48EZ8Geid5i_HR$!#oLIt!Ssd1C3bgs@GeD^3ohMnztWPDp z^${;42bWZL(OKQ zOB)Zg+b=^iN~Ufbbb&sflD|OIjVQLVwEc!DgQme^kBvx??!e3Pmp-zf#dP@W_C9&*p zK>KjTKGI?HfYH;pFwCN{8V744qim54`|?`CbcV9+|p} zHAy7E+N=l{Zk%dP65z||-@J)oH717N0W=TH>*tMs^()~Co|_@L1Qc-lII+5UgMyfT zyP+~>9>{@KIVRx&&<`v{t=%zMSi*NoDQcSZKhP#j-qP1=39;1^p4*ynT*;+HowwQA zvOD8>qs@PIK3MHt1_+0f^ayw-QP3H=)587dnWHSCLU+su2uHmN4C7_j;WS2 zIDKCkfBAg=on`dY+i7!2g;7hRL;n2602#?_Tu?j^AH53V?x9vvMdBj<4Fw&?`ZsbP z{s>Kz8D5qrs1fHZQ9T5`_*hxbE!JiD@^JBR8EKqo5GU5Xggwcry_R8jgj=V%OW4G$ z%9yttk;SN6vKy*U^rGDAhe1@Hjcx+FgRff^`p4Eh2cnla`~IDYOCbRCEC5(|s=0Ra zrYdoqo0o%oRUa)7Kr{^W+_5WXSwyt2SG};{24mh2vskVTUhsmxHyHc%@Mi!B z>zGfm@X!%rgh)4^2)8*?p7Jn^S##mQGUCEIiMKBjq6lFOb=LIWQjxN*fXe%EB%g3g zYZTAMOf}G*O#|`iS|@(Wc?dt^qqjy(KW$L4!4ZOKnWl;2XZ`hp8)h`p6FuecQ}Yl; zQuDA*$?GJ$)=dzpK5l@Rf5;>4w4^-TpiwDG?noouRd;2s2sQWkJB2h-`^tM7WE_;L z!AvZ#-&DpSO&Vml&_<`(8Du?EJ>i z3a>uCk++I-h(v{CQE?7u`dNm`>V6}WEs{jW1;KV#RCA3pv$D+x!Z;r!qd;y*^im2& z?R3`yBC`6Icc4-+Yf_+uZ#d_!MwG%UM|I{6%VE!Ql!LRjjkDGtI#K-M|q7_sQFr65K%jN za%=jGXd61Ac2@`{T$+0s>&Ep1>y$Q@DDSxL{-NY`aHhhSD(}gxa{a3!?B3tt92Wr%kz5FyE6k7ODQKFynJIIs zUoOyVGNJ)QY{Z51@-EsE+TNvX@^zQCR#Lg!5ar55F8UQF6`v9Q{{GIeeW%_w{uUur z^M0il#p>fIh=b3V?lC$|Gf*7;aZ8=KQkVHyC}Gg3)$HO@btke!=Vq}3dm&1Fg+>oN zWTuP!nG+-stpDcX2N`u1^BQG=qeG@&vO5ivc!rT|u-9h2a^F0d#Vk0bKGF$Qr=sud zQjIVgKIm>(m8NW=90rYDLz=v>x**9epbmJSzn4Z;?Wy#tmn$J3t+>Vg)6c^RG_v2N zv|B6$g;tWQ6B8&SN31^uG%Tk%=}y?+dzRMum|XA)+YuZ$1nGkeTzZZM&5Ys%}ca#3AFtZQm#bDKBnaY z??!Q<-94qFmsU?0Ic@`gCR^g@ni-h4D(b!8y*aL=pewtLIeaoJu`Aclr0`$n&&etm zCv?t}hYk@#HxLz59~{GIETU=4UKN+o;xfzs&iq-56pgD03S0eZL9Y*bdsrj$7xZT* zuF)xCgFP8u+IrkpvY7QrR6O8p0b(6x==Rw<#OA|he%^sKN@^wTd^tdn5`jHWi8akM zOTyg}bwr`o4w%b0qJl!H8@d1vASHZ-qQ2S;^J~`@t7rol)f9YNM59B(m&=PA{mE7n zMdxz5lj>k*CtIOX6v6A;(4Ste0azn43oaW0-!aMWXHD+rUYy(+RAtLe_Qifah?ggN zpSvdxnz-uhCl1*fQno;PrQi#z zZZcM7Yw?{udIQ+<00F0Wcj(+VnWxe>&gsifKuqoz*dLo0S4-soF7dd+m)xT#g8<2B zG-XJ(mmDYkgyQ*TWe%!N@y_+dm>Z4urOe+;;#m-9 zkeG;UDS);pj_f_$kl(ayQ2IMxOw;O7OcTgc=@9r<*@xtxRM;1hU2p3!#E42czACdL zU6c_Zo9wP1J|Spxtinr_z=6I z+&nn-Yvu@|x5`b4Kf$HYg4Ziz%!eVLfE|{y#5{UOnzxy?g(ndlhBF${M)GB@3^Av_ zh}HneN#75eiM%H5BENYn9JzS@x`+zY`FY?AVQCo&qk|DUU2-!6j!8>C*Ks**Z+7z2 z*XlD=g4gX0TT?`NKOwSDc_lWA*!{Bs&!fX!GD2~CZ*rgIcX^ztZ*tKt6W<-WId$*YE_5?l9J2V-ZRVBa$NjsrYv*fP zN5dG@FjbvnUFW(s=;3Von>3a9y>_h<9bX zj2DX4I-TS))S-x;>@{gZ9@%pEXw=w`7&Qe^bUo0d33lhzS0(iviK zOHZwttTk^SFZIdtxCv5u{2`tE>Rw-sxRpZAGX%-0v}(+WFzp-t6+P5`mUCF)|k|j=*-}8m~cR?i9nXYZaJx>a@hdQ3F%7Qv09WVoS`+H~2edzMIu)Rn4Qd@(Vv{opUuh11e|! zx^pu>!vJ$rpzbXv&K2XWGam4iRd)4&~qfytUqmz_;sU=(aku$Fo@hvN`FT%hX>x^EKMXb?Y8~C9!rN>qHhQAL+lm`<-aIB?k!~@hT>(f$FYyaIK*1_Y&s2b=kXK{ zgp^m)u{cA)>wbSO+_2vEbK16#GPkAvWT~lW*?-|bI#4kU3-9N()br#Tx7(Z6Y}D#i zdoweUtkZXX1R98DDLx38`fe9MmyTJ*xi-7h>564mSVdE}y`(H=^c?Dqc-*kc_>SxS zJy5AB$;>Xu0a-KadZQTM1iZ2Hv3B%(*p$0Z|NXtgS!L$9hmT>WQ_dB0H${r42mS%( zFGt4~@3&f2@6qAb(9PV@-*|}YLPTS%ut(KtAy=p#PU+lwtH3E|c*KLc1jN1wjGAx6 z%dAPKYj><3W}FC?!YGmd9gy$WZMa72`!W16UP@ydbsEG(6UNcJlxz(!D2OMXU;X@Hw zbEk~?bBg3{lyAezpeH5&H&|K7!O)qgY(vb2HhrIAiMJPF6IUJtI6(jSsbHrKxy&IT z7yBjPdU$uQ2WMXXgZoKzH5T{Yg5oOTbbh_0a<>t7)50hHa}2s)KvBe`gPE+tX)sIp3iTq6@_^=Sm#RBrNnPSFE*zOPlQe^Yl#Uqny3OR z&1ybdbNlM_*Z}E-6XWX*1=o8hk@zx5nAo$8pM`k~#8U%3gPiGtqulfsSA1EnPvGKp zwkXy9XiV{B-8B5I_G7-^)Mmwu%Ppmsiw>|#iVqojm5|evOvCh$7O;1YDgpVRh z2Yz0))rv98q&p-r<&*3MOUF%~BTKF03VYTH($&+wU7{mLGt1;(D8Dhue>Sx*DceLM zA~8F$*-j_kN9EoHi}K81E4X!<+(0xG#=kG=cFfXco0_}2Cv_SU*~)7JK~tdEl6mN= zX#!x`&0F+Tn+e@Ho4|eZh>cUpz1B@=L1m8C*2ZSS2f*1*>5C<96y4&&s`pLU)W23M zG}~H_WMuWcyVKmm6$#R3*Xhu`4D%-}_;H*^*h;rH(+CqQ0Q|A3SXM*bN{=4!7O3f+ zd!r~-#I)sKlQ**F02TcxYONJJ7w!Yw1b~4?@P+xl;y8nc1%k*tGTJd>lD+OUnUq@_ zzG;E$FMl{Gx;3@_)0f5gxD%4oKRF(JDqyt6=K@l;q68{#-DzF&mF@fP3}6dxq#}bo z2~s$ln%Tgas?VjiLvvvAp1|D8^M&K-79BNuL;ZhI_om@cxAEVwa;YmVx(bPqtHr)l zb`3=lvhRDStb<}KgVBZ}R6=3w>oCSPW2Xp3c4K6iNwUq@$JmGGoa*}D_lxH~p6588 zSI@i>9sJhw{C+>*&vFm<$oTr*GKWu`?vV~TgVqG)D{n*8*557(SD4?=PHZ;+yr~oP zjC%Rbhexi(li~b^=GI|jrZn}ZjXYMbB!Pg^3m9sac1t|En^14ioL*U#qkb=zy>R`S z;)@P*%SdRrm-}mnMagr~(D5`~EbAkOn*~*W$AJX#8mc8|QZFkxs8?{7ZR-qneVW=sAxJ z9Mj-X2Pr|?9)=5g7FFELX4m0D*i5!8?`)v9jXZo<6!@IiA0o-`veZ-^@J5 zgRYOq8hdGv*Sg!V^V34&2;lnXf$M(`uq9j%G}NW@0HgTnf~kPUJN)QqYY&k}$DVrP zgUqjaR+Sbv#9mKCQWUR2F57l-L|^&*Fk!@TMhNA*i+chDZ3TF zh(t~z)v=K^?6ph{xk{N8NGNkUbQtzmVcM8O&?J{&f1Apk!ON8)4f>6HqmgpOhr>I@ zC&p>&*3#J9eahi9k5F^8`xfxECItPz_QHK(BII1?hDy&_;C|(J`wvvsC_`6Q7&*BnCS`rOHDJHx7 z@1~{+9#9?e+7=DHfB+IqEobcdALeAe&PeyGSewkmWcrUH2ZlQ^OplDOQ73~LDw*(8 zzG}?hMmF(Mz=Caxl?-d9n4f?1LFL56!9>8c}cz2Kk$; zM&2f^$EpO((G1!vU%5A&(&#F~&`I9Fq=rhY!tBMeRC3M776ybXXRE1RM(hNt{WX$Y zL%SlmdVpy!?K%cxE&dMpR`WDO>pcq3k4dmc1$#jTB4<#nyOa@R;o;wUbt&dIu>USST}irR6Ls~9gD(jr%F}!Pg2$2 zpUl`#O;5Rpx?s!kr|pLe-&yaYI3b%~D2B(FCujCr$b_HFdZf{*o3+&Z#6Mhso#sD3 zGWnD*{33U~c&`#;b)bS4l^FcM^vTUr*SSWACq^`}|4Jy78fVBlHb0xOpYWK4`HdUW zv-PUO7Ma@2?fI(h<@4-N&dXoGz~hyr*jWKv(IpE}5s#0>wba^c1&MD*w8HJLBss;# zJ!`*8P}Z%6)(nZ-CeGLn)D-wwx7$r;CMX}r&%`=Z|Lvf)t=V+n5a~Fd#MJ(DrFAMF z1eEsR(V*h9i+L$tQ49AHGZPtG;qSYvO0R+tv@^kA3oW`v1hTH1MLFx0YfqK4j?6Zk zh!|HsSkkyfxkyhlOKVPyr=AgAJ0o^q&5Tz4Z1Bm|tNAz9Cr;6SV59>^A4Jvx1N7|R zcJWn2$(oDC&O4%NdC%9StX!mXO`=)Mx|6NsI(B&TVtBXGSv_N7zm3Dx>V?boZr0X? zC9c(IN9hkN)`{-nHeCxktloW>nXYE$j};zGoswSex1ITV__N;QNQ9dsT7~PSNU!0C ztdwwPr|as*z;e{_Rj$tsYIb6{wHD(0p_#T{qj@dK*tJ>rMzLB_Yw-8t;4 z@-j==NTmTM%jt%^{W{?;wS}y%=;&~VaO*1sz)$=stePq}a)94kWr6$MtZf%p`Rp02 zuhq8ZcFUSB&no52E#){fobc7S$|DVpu@BI3XjAG2C6w1ot3TL!dmPB{Rwsn!34!_P z>_Sj}zr#t{Z|-8vizZH_d1v)R2L3JXsC#eVOep&8kMzCGbjB7Rkek0RoG9#p-xCct zooL`mVlM9SgApVE!K`R7Os)222PAiD=%tP=<@?IoG{$OSH2$04CdTy!xMYfG5?vOD z0e@<>ljEr;wOY)=2O}OeqPhLW*OCkj$OfCN8BPDbV5n*TnDl0m&E0!igr@>7_OwRJ zt0#xp>fQgb6j{P8bvBoWc&3Fse*c6sT-I?omu@7&!-0l{eR*?1^^p-!ct33e!83(G zGWfX4NU?C}z2oN``pYWCquYfdoYx}bB734uqTBCvCT>og0E(2Y86NjB*`62$5)Z^U z`S-&*_m{NPs65O%^~Q9f^=Yc@04{vnywXlt3sy44{>{(R7uh*Z^F^{+A4E>W8B1sS zedjG6w2Dm*N1`5tVENY&pQ{8{Nd{Srq6`zv$*{(?=)Bp`f_0aYl~b*08m)8r?gB}# zElAU(R0k$Pd##sjsOb9YI zoN8}?^vIBXt8g8XQLlZjBPAno^}JNBbEwDm(5Zr@pOFJPEfq0CH)LX&~8oY6X8`t>ttS%Al{lF#>RYx`>>*z56Mn3gas zIY%=C-mk_xvkk0GUYg6SHzx&Vm$lR;Qs#g)j%m7-7d5Mj(X4wt5DWcQ-UbQ;Mup^!wW^EWH1~ zEkx!*P!3H9kkd%84@RfRd6*kj0rT%GaB~FZQOC1f{r~>+>1QM^W2m=Dr!tYf-c0@G z;IipP?Vle$I-z?l-T#Sz}(6mFpAw+2DHl>rYG}*-v`Qa&G8wD?RKhSnKomd$pk1rhg62GNY-1F z*jnKehk;m9q!W$^c3 z^x{CCo-fn6o0%N@iz=E&27#xcR6nBzpGtk;z1=Z+YAW6Y<_(BrMbf8^L4O^OY?$o4Zxech2w_%{gbpp3u~ z+do-dCCm_)WAbjZV{j{7?+k(7{<`JG6M&`Pp910$`zHa3Fo4NBo%nA+!U#kcJ2a8N z%prII#D4e#{^Rq!EJ>yh(r7J=Itr*WV}P>5r6(EF?QHfpkBWaWu;g)&#lnb

@H4 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 literal 0 HcmV?d00001 diff --git a/doc/specs/#5000 - Process Model 2.0/drop-tab-on-existing-window.png b/doc/specs/#5000 - Process Model 2.0/drop-tab-on-existing-window.png new file mode 100644 index 0000000000000000000000000000000000000000..7d5e7885e3768ceecfc873a1240af64fa5a6482f GIT binary patch literal 55763 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 soTP& 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 bbzS4p+UBEozc)lC{l%Yk&*hx4y7NB(uNnSV literal 0 HcmV?d00001 diff --git a/doc/specs/#5000 - Process Model 2.0/mixed-elevation.png b/doc/specs/#5000 - Process Model 2.0/mixed-elevation.png new file mode 100644 index 0000000000000000000000000000000000000000..030552415f9a2a36a778292d842a08fda947fd31 GIT binary patch literal 45395 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%0DTEjB>>a1mYH53bXc4zlMzXLbCfLs|& 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

IWs@C&LfX3v(lD+*@hiQ2g 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

8s2%hutDaPKI<~ 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 `F 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%0ADqY`C0X5fslPuvi~g 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üji1y2)SV67i|{;v1Z zP+;I}m3D%rhpDQSxYZG?*L-G3SM%#nrx*Fw!aCEca2`a*oTQ$N)_ko0$Qoy$x|bwW zO=UhW9Xdi?CW55nar+hj{3gPU!A;ZlKz`q~;>ksdn;zJZ;ls9vDk9yv^}6RG(Z*3q ztECd>aW7y0NL%q;%CUT(iShkjH_$GY{P+U`OtF=R$&K_6WA14DQr%3fa}=9EM!^z; zR)CT4gRaOxAn$DzHsXBUczSsA;B9ak(dHEjlFho!qOR+#9TzAqciKS0G&QXs{!~#vBRWom6Hs_uzI5rHSg=|n06vF#0KLML9Ip?mS zElT#nx5mg}ylP0sIT}0l&q_7DSd=^{O*;SlIK(!1Asdi;)NuDpf$vN&il(4(RV zVVbSCr)P}wu9Me;K~*h(c&g9)LXn@ZvmG!u+<55Bsgf^lqwMYEi?9n@tT1YdnR%KP z{+-Qk7!NwP7-!4y3y{x)xS-S15rfUw=L1s14#@60>9hS>yOe8uw8$lnR;xqyHF4gF z@Y8i}Z7~aj3P#~!r*d?USznTtdbkRDB5hIA!tr8@q=x-;ZHcP0z!6t1$w~JltLplL z>fslnFZgbOJ~k6B^U>f;?p|2X@eZSQH%TVCU<%!3p)%{;rN*3t?McxR%Jw&oTDLpZ zfBlH1#jVNj8eGR^b(7_*&B1lmO4$C>D;Up7 z;m`COgnxNWk^3#=ABpYwjz13`DdaUqeOU$CBRFvHFEMdJRDvGvg{2fkT_EGMsB( zpe|)c>eweql`7S?wY=+UiUlIopLfrL>j~5BZ<#u39>2@$)cq!*$u^sPgddJ0gmt;*ccz#CeZBFnQtqpo$10Pm(?O>&T@_b=4?0gSAzxxL-4lj&gB3Tw<@wl`_aa zwczf!%7!Z41=HOFJqADDV*O@5Wy6%nDig$_h^$%PrsCZb3wd_ogfmj_>?*1dg(-w_ zy;E<_NATH99|iaBHFQJdT^qhey17si27Bw}ux^w$ii%4p{Ir9Z4SgxQd%4`cvD;na zfz6&iqekh~krx+~n!|4`EzBt*i0~JY_ByXVk<#6?5H=;FuFRVJRn!;j$?VM~*Zm8U}zpLH!(beS~$ zWZr8v>G&LKb^lQLj6SDQ^*^OeC}xtBlM-3T;NtxSVaJ7BoHVX8O4hb1^iOSl6TLCu zePxt5Wqq(SLsvL>)`(NvD&taq=Y;P7k$vN#4GD*vUSg*-2h3ApL2sgAD~(l{L77n-thna;{V0 Date: Wed, 12 Aug 2020 12:56:52 -0500 Subject: [PATCH 11/39] more technical details. MORE --- .../#5000 - Process Model 2.0.md | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md b/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md index cbbf0573ad6..bab7a1f0126 100644 --- a/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md +++ b/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md @@ -196,6 +196,41 @@ This means that if we wanted to have a second window process connect to the _same_ content process as another window, all it needs is the content process's GUID. +Now that we have a WinRT object that the content process hosts, we can have the +window and content process interact using that interface. The next important +thing to communicate between these processes is the swapchain. The swapchain +will need to be created by the content process, but also we need to be able to +communicate the `HANDLE` to that swapchain out to the window process, so the +window process can attach that swapchain to the `SwapChainPanel` in the window. + +This is a little tricky, because WinRT does not natively expose a `HANDLE` type +which would allow us to easily pass the `HANDLE` between these processes. +Instead we'll need to manually cast the `HANDLE` to `uint64_t` at the winRT +boundary, and cast it back to a `HANDLE` when we want to use it. + +We can't just have the content process duplicate the handle to the window +process directly. If the content process is unelevated, and the window process +is elevated (in a mixed elevation scenario), then the content process won't have +permission to `DuplicateHandle` the `HANDLE` to the swapchain into the window's +process. (more on mixed elevation below). + +Instead, the window will always need to be the one responsible for calling +`DuplicateHandle`. Fortunately, the `DuplicateHandle` function does allow a +caller to duplicate from another process into your own process. + +So when the content process needs to create a new swapchain, it'll raise an +event that the window process can listen for to indicate that the swapchain +changed. The window will then query for the content process's PID (which it will +use to create a handle to the content process), and the window will query the +current value of the content process's `HANDLE` to the swapchain. The window +will then duplicate that `HANDLE` into it's own process space. Now that the +window has a handle to the swapchain, it can use +[`ISwapChainPanelNative2::SetSwapChainHandle`] to set the SwapChainPanel to use +the same swapchain. + +This will allow the content process to draw to the swapchain, and the window +process to render that same swapchain. + #### Scenario: Tab Tear-off and Reattach Because all that's needed to uniquely identify an individual terminal instance @@ -887,6 +922,18 @@ spec. [TODO]: # TODO ================================================================= +#### Duplicating HANDLEs from content process to elevated window process + +We can't just have the content process dupe the handle to the window process. If +the content process is unelevated, and the window process is elevated (in a +mixed elevation scenario), then the content process won't have permission to +`DuplicateHandle` the `HANDLE` to the swapchain into the window's process. + +Instead, the window will always need to be the one responsible for calling +duplicate handle. Fortunately, the `DuplicateHandle` function does allow a +caller to duplicate from another process into your own process. + + #### What happens to the content if the monarch dies unexpectedly? What happens if you only have one window process, the monarch, and it @@ -1095,3 +1142,4 @@ provided `type`. [Tab Tearout in the community toolkit]: https://github.com/windows-toolkit/Sample-TabView-TearOff [Quake mode scenarios]: https://github.com/microsoft/terminal/issues/653#issuecomment-661370107 +[`ISwapChainPanelNative2::SetSwapChainHandle`]: https://docs.microsoft.com/en-us/windows/win32/api/windows.ui.xaml.media.dxinterop/nf-windows-ui-xaml-media-dxinterop-iswapchainpanelnative2-setswapchainhandle From 30e0ea4414b2cd120fc7803dc45df4f113a60e9f Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Mon, 19 Oct 2020 09:39:03 -0500 Subject: [PATCH 12/39] s/servant/peasant/g --- .github/actions/spell-check/expect/expect.txt | 2 + .../#5000 - Process Model 2.0.md | 132 ++++++++++-------- 2 files changed, 73 insertions(+), 61 deletions(-) diff --git a/.github/actions/spell-check/expect/expect.txt b/.github/actions/spell-check/expect/expect.txt index 29aef243f25..9bea308a92b 100644 --- a/.github/actions/spell-check/expect/expect.txt +++ b/.github/actions/spell-check/expect/expect.txt @@ -1403,6 +1403,7 @@ mindbogglingly mingw minimizeall minkernel +mintty minwin minwindef Mip @@ -1594,6 +1595,7 @@ numlock numpad NUMSCROLL nupkg +NVDA NVIDIA NVR Nx diff --git a/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md b/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md index bab7a1f0126..bfec52874bd 100644 --- a/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md +++ b/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md @@ -1,7 +1,7 @@ --- author: Mike Griese @zadjii-msft created on: 2020-07-31 -last updated: 2020-08-12 +last updated: 2020-10-19 issue id: #5000 --- @@ -260,7 +260,7 @@ drag-drop to initialize the structure of the window. For our own sanity, we'll want to ensure that tabs cannot be torn out from a "Preview" Windows Terminal window and dropped into a "Release" window. I'm not positive that the system will prevent that on our behalf, so I think it's -important to call out that if this _is_ possible, we should expressely disallow +important to call out that if this _is_ possible, we should expressly disallow it. #### Scenario: Mixed Elevation @@ -323,7 +323,7 @@ down the idea as being impossible or terrible from a security perspective, so I believe that it _will_ be possible. We still need to do some research on the actual mechanisms for some token impersonation. -### Monarch and Servant Processes +### Monarch and Peasant Processes With the current design, it's easy to connect many content processes to a window process, and move those content processes easily between windows. However, we @@ -334,12 +334,12 @@ commandline in a given WT window? In addition to the concept of Window and Content Processes, we'll also be introducing another type of categorization for window processes. These are -"Monarch" and "Servant" processes. This will allow for the coordination across +"Monarch" and "Peasant" processes. This will allow for the coordination across the various windows by the Monarch. There will only ever be one monarch process at a given time, and every other WT -window process is a servant process. However, we want this system to be -redundant, so that if the monarch ever dies, one of the remaining servant +window process is a peasant process. However, we want this system to be +redundant, so that if the monarch ever dies, one of the remaining peasant processes can take over for it. The new monarch will be chosen at random, so we'll call this a probabilistic elective monarchy. @@ -364,14 +364,14 @@ Essentially, the probabilistic elective monarchy will work in the following way: to assign one to us. - If we do have an ID (from a previous monarch), then let the new monarch know that we exist. -5. If we're a servant process, then `WaitForSingleObject` on a handle to the +5. If we're a peasant process, then `WaitForSingleObject` on a handle to the monarch process. When the current monarch dies, go back to 3. At this point, we might be appointed the new monarch (by whatever process the OS uses to choose who the new server for `Monarch`s is.) - We're suggesting `WaitForSingleObject` here as opposed to having the monarch raise a WinRT event when it's closed, because it's possible that the monarch closes unexpectedly, before it has an - opportunity to notify the servants. + opportunity to notify the peasants. By this mechanism, the processes will be able to communicate with the Monarch, who'll be responsible for managing any inter-process communication between @@ -388,11 +388,11 @@ browser. This functionality is often referred to as "glomming", as the new tab "gloms" onto the existing window. Currently, the terminal does not support such a feature - every `wt` invocation -creates a new window. With the monarch/servant architecture, it'll now be +creates a new window. With the monarch/peasant architecture, it'll now be possible to enable such a scenario. As each window is activated, it will call a method on the `Monarch` object -(hosted by the monarch process) which will indicate that "I am servant N, and +(hosted by the monarch process) which will indicate that "I am peasant N, and I've been focused". The monarch will use those method calls to update its own internal stack of the most recently used windows. @@ -420,7 +420,7 @@ one. In "Single Instance Mode", the monarch _is_ the single instance. When `wt` is run, and it determines that it is not the monarch, it'll ask the monarch if it's -in single instance mode. If it is, then the servant that's starting up will +in single instance mode. If it is, then the peasant that's starting up will instead pass it's commandline arguments to the monarch process, and let the monarch handle them, then exit. In single instance mode the window will still be composed from a combination of a window process and multiple different content @@ -475,9 +475,9 @@ wt.exe --session N new-tab ; split-pane (or for shorthand, `wt -s N new-tab ; split-pane`). -This would create a new servant, who could then ask the monarch if there is a -servant with ID `N`. If there is, then the servant can connect to that other -servant, dispatch the current commandline to that other servant, and exit, +This would create a new peasant, who could then ask the monarch if there is a +peasant with ID `N`. If there is, then the peasant can connect to that other +peasant, dispatch the current commandline to that other peasant, and exit, before ever creating a window. If this commandline instead creates a new monarch process, then there was _no_ other monarch, and so there must logically not be any other existing WT windows, and the `--session N` argument could be safely @@ -493,8 +493,8 @@ like `wt --session last` or some other special value indicating "run this in the MRU window". That might be a simple, but **wrong**, implementation for "the current window". -If the servants always raise an event when their window is focused, and the -monarch keeps track of the MRU order for servants, then one could naively assume +If the peasants always raise an event when their window is focused, and the +monarch keeps track of the MRU order for peasants, then one could naively assume that the execution of `wt -s 0 ` would always return the window the user was typing in, the current one. However, if someone were to do something like `sleep 10 ; wt -s 0 `, then the user could easily focus another @@ -504,7 +504,7 @@ as the window executing the command. I'm not sure that there is a better solution for the `-s 0` scenario other than attempting to use the `WT_SESSION` environment variable. If a `wt.exe` process is spawned and that's in it's environment variables, it could try and ask the -monarch for the servant who's hosting the session corresponding to that GUID. +monarch for the peasant who's hosting the session corresponding to that GUID. This is more of a theoretical solution than anything else. In Single-Instance mode, running `wt -s 0` outside a WT window will still cause @@ -527,9 +527,9 @@ it fails to register the global hotkey, then the first window is closed, there's no way for the second process to track that and re-register as the handler for that key. -With the addition of monarch/servant processes, this problem becomes much easier +With the addition of monarch/peasant processes, this problem becomes much easier to solve. Now, the monarch process will _always_ be the process to register the -shortcut key, whenever it's elected. If it dies and another servant is elected +shortcut key, whenever it's elected. If it dies and another peasant is elected monarch, then the new monarch will register as the global hotkey handler. Then, the monarch can use it's pre-established channels of communication with @@ -538,13 +538,13 @@ the other window processes to actually drive the response we're looking for. **Alternatively**, we could use an entirely other process to be in charge of the registration of the global keybinding. This process would be some sort of long-running service that's started on boot. When it detects the global hotkey, -it could attmept to instantiate a `Monarch` object. +it could attempt to instantiate a `Monarch` object. * If it can't make one, then it can simply run a new instance of `wt.exe`, because there's not yet a running Terminal window. * Otherwise, it can communicate to the monarch that the global hotkey was pressed, and the monarch will take care of delegating the activation to the - appropriate servant window. + appropriate peasant window. This would mitigate the need to have at least one copy of WT running already, and the user could press that keybinding at any time to start the terminal. @@ -553,10 +553,10 @@ and the user could press that keybinding at any time to start the terminal. #### Rough interface design This is by no means definitive, but one could imagine the `Monarch` and -`Servant` classes exposing the following WinRT projections: +`Peasant` classes exposing the following WinRT projections: ```c# -class Servant +class Peasant { void AssignID(UInt64 id); // Should only be called by the monarch UInt64 GetID(); @@ -565,27 +565,27 @@ class Servant event TypedEventHandler WindowActivated; } -class Monarch : Servant +class Monarch : Peasant { - UInt64 AddServant(Servant servant); + UInt64 AddPeasant(Peasant peasant); Boolean IsInSingleInstanceMode(); - Servant GetServant(UInt64 servantID); - Servant GetMostRecentServant(); + Peasant GetPeasant(UInt64 peasantID); + Peasant GetMostRecentPeasant(); } ``` -The servant process can instantiate the `Servant` object itself, in it's process -space. Initially, the `Servant` object won't have an ID assigned, and the call -to `AddServant` on the `Monarch` will both cause the Monarch to assign the -`Servant` an ID, and add it to the Monarch process's list of processes. If the -`Servant` already had an ID assigned by a previous monarch, then the new monarch -will simply re-use the value already existing in the `Servant`. Now, the monarch -can call methods on the `Servant` object directly to trigger changes in the -servant process. +The peasant process can instantiate the `Peasant` object itself, in it's process +space. Initially, the `Peasant` object won't have an ID assigned, and the call +to `AddPeasant` on the `Monarch` will both cause the Monarch to assign the +`Peasant` an ID, and add it to the Monarch process's list of processes. If the +`Peasant` already had an ID assigned by a previous monarch, then the new monarch +will simply re-use the value already existing in the `Peasant`. Now, the monarch +can call methods on the `Peasant` object directly to trigger changes in the +peasant process. -Note that the monarch also needs to have a servant ID, because the monarch is -really just a servant with the added responsibility of keeping track of the -other servants as well. +Note that the monarch also needs to have a peasant ID, because the monarch is +really just a peasant with the added responsibility of keeping track of the +other peasants as well. It's important that `ExecuteCommandline` takes a `currentDirectory` parameter. Consider the scenario `wt -s 0 -d .` - in this scenario, the process that's @@ -602,7 +602,7 @@ vision for default terminals is that when a commandline application is started on Windows, instead of booting into `conhost.exe` as a default terminal, the system will instead boot up whatever application the user has set as their "default terminal application", whether that be the Windows Terminal or some -other terminal app (ConEmu, mintty, Hyper, etc). +other terminal app (ConEmu, MinTTY, Hyper, etc). This is another scenario that deserves its own full spec, though it warrants a special callout in this document as well. @@ -652,10 +652,10 @@ windows to glom onto, so create the tab in this window process. 4b. It'll ask the monarch if it's in single instance mode, or if the monarch is configured to glom tabs onto the most recent window, instead of spawning new -ones. If it is configured in such a way, the new servant window process will -pass the content process's GUID to the Servant\* that _should_ be the window for +ones. If it is configured in such a way, the new peasant window process will +pass the content process's GUID to the Peasant\* that _should_ be the window for that new client - - \*: note that this servant could just be the monarch (in single instance + - \*: note that this peasant could just be the monarch (in single instance mode, for example).


@@ -663,7 +663,7 @@ that new client This area is left intentionally vague, because we're not exactly sure what the API surface exposed for default terminal invocations will look like. Hopefully, it shows that however we do end up implementing support for default terminal -apps, the proposed Window/Content/Monarch/Servant architecture will still be a +apps, the proposed Window/Content/Monarch/Peasant architecture will still be a compatible solution. ## UI/UX Design @@ -674,7 +674,7 @@ machinations of the Terminal processes. At the very least, resizes will occur off of the UI thread, which will help that scenario feel better. While resizes happen fairly responsively in Release -builds, Debug builds used for development have fairly painful resizes occuring +builds, Debug builds used for development have fairly painful resizes occurring on the UI thread, blocking all input until they're finished. Ideally, we'll want the tab that's being dragged to be able to show the contents @@ -728,7 +728,7 @@ WT window are elevated. Furthermore, we'll want to ensure that there's nothing that an unelevated client process could do to trigger any sort of input callback in the parent window. If the parent window is an elevated window, with other elevated connections, then -we don't want the uelevated content process to act as a vector by which +we don't want the unelevated content process to act as a vector by which malicious software could hijack the elevated window. @@ -738,7 +738,7 @@ malicious software could hijack the elevated window. This is probably the biggest concern in this section. Because there will now be -many, many more processes in the process tree, it is imperitive that whenever +many, many more processes in the process tree, it is imperative that whenever we're doing cross-process operations, we do them safely. Whenever we're working with an object that's hosted by another process, we'll @@ -751,8 +751,8 @@ error message, but _continue running_. When the monarch process dies, we'll need to be able to reliably elect a new monarch. While we're electing a new monarch, and updating the new monarch, there's always the chance that the _new_ monarch is also killed (This is the -"Pope Stephen II" scenario). In this scenario, if at any point a servant -notices that the monarch has died, the servant will need to begin checking who +"Pope Stephen II" scenario). In this scenario, if at any point a peasant +notices that the monarch has died, the peasant will need to begin checking who the new monarch is again. There is certain to be a long tail of edge cases we'll discover as a product of @@ -764,7 +764,7 @@ inter-process calls we might make. Some example situations might include: * When a process creates a new content process * When a content process is attached by a window * When a monarch is elected -* when a servant receives its new ID from a monarch +* when a peasant receives its new ID from a monarch * when either a window or content process _safely_ exits In any and all of these situations, we'll want to try and be as verbose as @@ -805,7 +805,7 @@ spawning of new terminal instances, due to requiring cross-process hops for the instantiation of the content process. Additionally, minor delays are expected to be introduced during startup for the -initial setup of the monarch/servant relationship. +initial setup of the monarch/peasant relationship. @@ -823,8 +823,8 @@ that's most often associated with the concept of extensions in the Terminal, but perhaps more relevantly could affect the Settings UI. The Settings UI is something we intend on shipping in the Terminal as a part of -2.0, in the same timefram much of the above work is expected to be done. We also -plan on hopefully making the Settings UI appear as its own tab within the +2.0, in the same timeframe much of the above work is expected to be done. We +also plan on hopefully making the Settings UI appear as its own tab within the Terminal. This would be the first example of having non-terminal content directly in the application. How would we support tearing out the Settings UI tab into it's own window? @@ -897,7 +897,7 @@ Lets examine some sample JSON[[2]](#footnote-2) ``` Here, we've got two tabs that have been serialized. -* The first has two panes, seperated with a horizontal split. It has also been +* The first has two panes, separated with a horizontal split. It has also been renamed to "foo". - The first pane takes up 30% of the parent, and contains a `TermControl`. The content process for that control is identified by the content GUID @@ -934,11 +934,21 @@ duplicate handle. Fortunately, the `DuplicateHandle` function does allow a caller to duplicate from another process into your own process. +#### Elevation and Extensions + +[TODO]: # TODO ================================================================= + +showerthought (to make sure I don't forget): extensions should be disabled by default in elevated windows. The user can chose to enable them in elevated windows if they want. That setting needs to be hidden in a file that only admins can write to. + +I suppose some extensions might be fine to run in unelevated content processes, but would probably be impossible to entirely prevent them from triggering code in the parent process. + +~~Like an extension running in the content process could try to trigger the "enable broadcast input" mode and then have its keystrokes sent to the elevated content procs~~ Actually, maybe not. The content process doesn't actually handle any keybindings, does it? That's all in the window process, so that's not terribly a concern. + #### What happens to the content if the monarch dies unexpectedly? What happens if you only have one window process, the monarch, and it throws an exception for whatever reason? Will the content processes also attempt -to be servants here? Or perhaps is there another mechanism by which the content +to be peasants here? Or perhaps is there another mechanism by which the content processes can realize all the windows are gone and start a new window process who becomes the instant-monarch for all the still-living and remaining content processes? @@ -969,17 +979,17 @@ of each other.
-1. Add Monarch/Servant capabilities to `wt` window processes. +1. Add Monarch/Peasant capabilities to `wt` window processes. - This does not need to involve any actual UX functionality, simply have the WT instances communicate with one another to see who is the Monarch. - - The monarch will track and assign IDs to servants. + - The monarch will track and assign IDs to peasants. 2. (Dependent on 1): Add support for running a `wt` commandline in an existing window - Monarch should assign simple IDs for use with the `wt` commandline - `0` should be reserved as an alias for "the current window" 3. (Dependent on 1, maybe on 2): Add support for "single instance mode". New - servant windows will first ask the monarch if it's in single instance mode, - and pass the servant's commandline to the monarch if it is. + peasant windows will first ask the monarch if it's in single instance mode, + and pass the peasant's commandline to the monarch if it is. 4. (Dependent on 1): Monarch registers for the global quake hotkey, and uses that to activate _the monarch_. - Pressing the key when a window is currently focused should minimize? Do nothing? @@ -1095,7 +1105,7 @@ provided `type`. content as we're drag/dropping. - If we pursue this, then we'll need to make sure that we re-assign the window ID's as appropriate. the _new_ window (with the tabs that are being left - behind) should still have the same servant ID as the original window, which + behind) should still have the same peasant ID as the original window, which will now get a new ID (as to ) * We could definitely do a `NewWindowFromTab(index:int?)` action that creates a new window from a current tab once this all lands. @@ -1126,7 +1136,7 @@ provided `type`. ## Resources -* [Tab Tearout in the community toolkit] - this document proved invaluable to +* [Tab Tear-out in the community toolkit] - this document proved invaluable to the background of tearing a tab out of an application to create a new window. @@ -1140,6 +1150,6 @@ provided `type`. [#632]: https://github.com/microsoft/terminal/issues/632 [#492]: https://github.com/microsoft/terminal/issues/492 -[Tab Tearout in the community toolkit]: https://github.com/windows-toolkit/Sample-TabView-TearOff +[Tab Tear-out in the community toolkit]: https://github.com/windows-toolkit/Sample-TabView-TearOff [Quake mode scenarios]: https://github.com/microsoft/terminal/issues/653#issuecomment-661370107 [`ISwapChainPanelNative2::SetSwapChainHandle`]: https://docs.microsoft.com/en-us/windows/win32/api/windows.ui.xaml.media.dxinterop/nf-windows-ui-xaml-media-dxinterop-iswapchainpanelnative2-setswapchainhandle From 29aab9c40ad22069b8dd85c74794584246359baf Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Mon, 19 Oct 2020 12:02:58 -0500 Subject: [PATCH 13/39] spellcheck and linter fixes --- .../#5000 - Process Model 2.0.md | 126 ++++++++++-------- 1 file changed, 69 insertions(+), 57 deletions(-) diff --git a/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md b/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md index bfec52874bd..c01f62b3c83 100644 --- a/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md +++ b/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md @@ -448,7 +448,7 @@ One could imagine that single instance mode is the combination of two properties * The user wants new invocation of `wt` to "glom" onto the most recently used window (the hypothetical `"glomToLastWindow": true` setting) * The user wants to prevent tab tear-out, or the ability for a `newWindow` - action to work. (hypothetically `"allowTabTearout": false`) + action to work. (hypothetically `"allowTabTearOut": false`) #### Scenario: Run `wt` in the current window @@ -469,7 +469,7 @@ Since each window process will have it's own unique ID assigned to it by the monarch, then running a command in a given window with ID `N` should be as easy as something like: -``` +```sh wt.exe --session N new-tab ; split-pane ``` @@ -540,11 +540,11 @@ registration of the global keybinding. This process would be some sort of long-running service that's started on boot. When it detects the global hotkey, it could attempt to instantiate a `Monarch` object. - * If it can't make one, then it can simply run a new instance of `wt.exe`, - because there's not yet a running Terminal window. - * Otherwise, it can communicate to the monarch that the global hotkey was - pressed, and the monarch will take care of delegating the activation to the - appropriate peasant window. +* If it can't make one, then it can simply run a new instance of `wt.exe`, + because there's not yet a running Terminal window. +* Otherwise, it can communicate to the monarch that the global hotkey was + pressed, and the monarch will take care of delegating the activation to the + appropriate peasant window. This would mitigate the need to have at least one copy of WT running already, and the user could press that keybinding at any time to start the terminal. @@ -618,45 +618,48 @@ following mechanism: 1. When `wt` is started as the target of a "defterm" invocation, the system will somehow pass us a `HANDLE` (or pair of `HANDLE`s) to indicate that we're being started to be the terminal for that commandline client. - - The details of the connection information aren't really important at this time. + - The details of the connection information aren't really important at this + time. Then we have two paths forward: -2a. The `wt` that's spawned in this way should become the _content process_ for -this connection, because it has the direct connection to the client that's -attempting to start. - -3a. This new content process will need a window. Depending on the configuration of the -Terminal, the following could happen: - - the content process could discover that there's no existing Monarch process, - and that a new monarch should be created, with a reference to this content - process (as a first tab) - - The content process connects to the monarch, who then creates a new window - process who attaches to the content process. (A new window is created.) - - The content process connects to the monarch, who then tells an existing - window process to attaches to the content process. (The client opens as a - new tab either in the single instance or the most recent window, if glomming - is enabled.) +#### Option A + +2. The `wt` that's spawned in this way should become the _content process_ for + this connection, because it has the direct connection to the client that's + attempting to start. + +3. This new content process will need a window. Depending on the configuration + of the Terminal, the following could happen: + - the content process could discover that there's no existing Monarch process, + and that a new monarch should be created, with a reference to this content + process (as a first tab) + - The content process connects to the monarch, who then creates a new window + process who attaches to the content process. (A new window is created.) + - The content process connects to the monarch, who then tells an existing + window process to attaches to the content process. (The client opens as a + new tab either in the single instance or the most recent window, if glomming + is enabled.) **OR** -2b. The `wt` that's spawned by the defterm connection is a new window process. -It should create a new content process to handle this connection. - - the content process will need a way of being invoked by passing it handles - to the new client. This way, the content process can dupe these handles into - it's own process space, to be able to create the `ITerminalConnection` in - its own process space. +2. The `wt` that's spawned by the defterm connection is a new window process. + It should create a new content process to handle this connection. + - the content process will need a way of being invoked by passing it handles + to the new client. This way, the content process can dupe these handles into + it's own process space, to be able to create the `ITerminalConnection` in + its own process space. -3b. If this new window process is the monarch, then great! There are no other +3. If this new window process is the monarch, then great! There are no other windows to glom onto, so create the tab in this window process. -4b. It'll ask the monarch if it's in single instance mode, or if the monarch is -configured to glom tabs onto the most recent window, instead of spawning new -ones. If it is configured in such a way, the new peasant window process will -pass the content process's GUID to the Peasant\* that _should_ be the window for -that new client - - \*: note that this peasant could just be the monarch (in single instance - mode, for example). +4. It'll ask the monarch if it's in single instance mode, or if the monarch is + configured to glom tabs onto the most recent window, instead of spawning new + ones. If it is configured in such a way, the new peasant window process will + pass the content process's GUID to the Peasant\* that _should_ be the window for + that new client + - \*: note that this peasant could just be the monarch (in single instance + mode, for example).
@@ -814,7 +817,7 @@ initial setup of the monarch/peasant relationship. ## Potential Issues -#### Extensions & non-terminal content. +### Extensions & non-terminal content We've now created a _very_ terminal-specific IPC mechanism for transferring _terminal_ state from one thread to another. However, what happens when we start @@ -823,7 +826,7 @@ that's most often associated with the concept of extensions in the Terminal, but perhaps more relevantly could affect the Settings UI. The Settings UI is something we intend on shipping in the Terminal as a part of -2.0, in the same timeframe much of the above work is expected to be done. We +2.0, in the same time frame much of the above work is expected to be done. We also plan on hopefully making the Settings UI appear as its own tab within the Terminal. This would be the first example of having non-terminal content directly in the application. How would we support tearing out the Settings UI @@ -840,7 +843,7 @@ Alternatively, we could pass some well-defined string / JSON blob from the source process to the target process, such that the extension could use that JSON to recreate whatever state the pane was last in. The extension would be able to control this content entirely. - - Maybe they want to pass a GUID that the new process will be able to user to +- Maybe they want to pass a GUID that the new process will be able to user to `CreateInstance` the singleton for their UI and then dupe their swap chain to the new thread... @@ -918,11 +921,11 @@ also need to consider how the content types should be identified and instantiated, but that's a questions that's deferred to a future "extensions" spec. -#### Mixed elevation & Monarch / Peasant issues +### Mixed elevation & Monarch / Peasant issues [TODO]: # TODO ================================================================= -#### Duplicating HANDLEs from content process to elevated window process +### Duplicating HANDLEs from content process to elevated window process We can't just have the content process dupe the handle to the window process. If the content process is unelevated, and the window process is elevated (in a @@ -934,17 +937,26 @@ duplicate handle. Fortunately, the `DuplicateHandle` function does allow a caller to duplicate from another process into your own process. -#### Elevation and Extensions +### Elevation and Extensions [TODO]: # TODO ================================================================= -showerthought (to make sure I don't forget): extensions should be disabled by default in elevated windows. The user can chose to enable them in elevated windows if they want. That setting needs to be hidden in a file that only admins can write to. +Shower thought (to make sure I don't forget): extensions should be disabled by +default in elevated windows. The user can chose to enable them in elevated +windows if they want. That setting needs to be hidden in a file that only admins +can write to. -I suppose some extensions might be fine to run in unelevated content processes, but would probably be impossible to entirely prevent them from triggering code in the parent process. +I suppose some extensions might be fine to run in unelevated content processes, +but would probably be impossible to entirely prevent them from triggering code +in the parent process. -~~Like an extension running in the content process could try to trigger the "enable broadcast input" mode and then have its keystrokes sent to the elevated content procs~~ Actually, maybe not. The content process doesn't actually handle any keybindings, does it? That's all in the window process, so that's not terribly a concern. +~~Like an extension running in the content process could try to trigger the +"enable broadcast input" mode and then have its keystrokes sent to the elevated +content procs~~ Actually, maybe not. The content process doesn't actually handle +any keybindings, does it? That's all in the window process, so that's not +terribly a concern. -#### What happens to the content if the monarch dies unexpectedly? +### What happens to the content if the monarch dies unexpectedly? What happens if you only have one window process, the monarch, and it throws an exception for whatever reason? Will the content processes also attempt @@ -1030,18 +1042,18 @@ of each other. 10. (Dependent on 9?) The core layer needs to be able to construct connections itself, rather than have one passed in to it. - - In the future we'll probably want this to be more extensible, but for now +- In the future we'll probably want this to be more extensible, but for now we can probably just pass an enum for connection type, and an `IConnectionSettings` object to the core, and use the `ConnectionType` and setting to build the limited types of connection we currently have. 11. (Dependent on 9, 10) `wt.exe` needs to be able to spawn as a content process, accepting a GUID for its ID, and spawning a single control core. - - When the content process is first spawned, it won't create the core or +- When the content process is first spawned, it won't create the core or connection, nor will it have any settings. The first client to connect to the content process should make sure to set up the settings before initializing the control. - - A scratch XAML Island application might be a useful tool at this point, to +- A scratch XAML Island application might be a useful tool at this point, to test hosting the content in another process (that's not a full-blown terminal instance). @@ -1051,27 +1063,27 @@ of each other. 13. (Dependent on 12) Terminal can drop tabs onto another WT window process by communicating the structure of the tab's panes and their content GUIDs. - - At this point, the tabs can't be torn out to create new windows, only move +- At this point, the tabs can't be torn out to create new windows, only move between existing windows - - It might be hard to have the tab "attach" to the tab row of the other window. - - It might be easiest to do this after 1, and communicate to the new window +- It might be hard to have the tab "attach" to the tab row of the other window. +- It might be easiest to do this after 1, and communicate to the new window process the GUID of the old window process and the tab within the original window process, and just have the new window process ask the old window process what the structure of the tab is - - Though, the tab won't be in the original process's list of tabs anymore, + - Though, the tab won't be in the original process's list of tabs anymore, so that might not be helpful. 14. `wt` accepts an initial position, size on the commandline. 15. (Dependent on 13, 14) Tearing out a tab and dropping it _not_ on another WT window creates a new window for the tab. - - This will require and additional argument to `wt` for it to be able to +- This will require and additional argument to `wt` for it to be able to inherit the structure of a given set of tabs. Either this will need to be passed on the cmdline, or the newly spawned process will need to be able to communicate with the original process to ask it what structure it should be building. - - Doing this after 1 might be helpful. - - Needs 14 to be able to specify the location of the new window. +- Doing this after 1 might be helpful. +- Needs 14 to be able to specify the location of the new window.
From aa7ec60bbcf17aad82f0de739481fe2919ceeb6e Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Fri, 30 Oct 2020 06:06:18 -0500 Subject: [PATCH 14/39] This is some brainstorming --- .../#5000 - Process Model 2.0.md | 51 ++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md b/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md index c01f62b3c83..dfd1a0b54b1 100644 --- a/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md +++ b/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md @@ -1,7 +1,7 @@ --- author: Mike Griese @zadjii-msft created on: 2020-07-31 -last updated: 2020-10-19 +last updated: 2020-10-21 issue id: #5000 --- @@ -925,6 +925,55 @@ spec. [TODO]: # TODO ================================================================= +\ + +Initially, I thought that maybe we shoudn't have elevated windows involved in +the M/P game at all. However, what happens when the monarch's window needs to +silently elevate? That window should be able to retain its original ID, because +we want commands like `wt -s 1 new-tab` to still work in the original window. + +However, the elevate window absolutely cannot become the monarch process. If it +is, then unelevated windows won't be able to connect to the monarch at all. + +So if the monarch is going to enter a mixed-elevation state, the new process for +the elevated window shouldn't try to register as the monarch, and instead rely +on another process being the monarch. + +What if there's only one window, and it becomes elevated? In that case, there is +no other monarch to rely on. We'll need a way for us to start `wt` as a +"headless monarch". This headless monarch process will _not_ display its own +window, but will act as the monarch. The old monarch (who's now a different +process altogether, and is elevated), should treat that medium-IL headless +monarch the same as the other monarchs, and attempt to find a new monarch as +soon as it goes away. The headless monarch will attempt to register to ne the +monarch - if it turns out that another process is the current monarch, then the +headless monarch will immediately kill itself, causing the old monarch to +immediately attempt to find a new monarch. If the headless monarch dies +unexpectedly, and the elevated process is unable to create a connection to the +existing monarch, it'll need to spawn a new headless monarch. + +If there are only a bunch of elevated monarchs, then they'll each attempt to +spawn a headless monarch. Only one will succeed - the others will all connect to +the first headless monarch, and immedaitely die. + + +We need to be especially careful about the commands that can be run in an +existing window. Opening a new tab, split, these are relatively safe. The new +terminal that's created in the elevated window will still be unelevated by +default. + +What we _absolutely cannot do_, under any circumstance, is allow for the sending +of input to another window across elevation boundary. I don't think it's +entirely out of the realm of possiblity to add a `send-input` command to write +input to the terminal using the `SendInputAction`. However, we must absolutely +make sure that the input isn't allowed to cross the elevation boundary. To make +this easier, we should have the `send-input` command just fail if the targeted +window is both: +- Is elevated. +- Is not this window. Sending input within the same window seems like it would + be safe enough - you're already inside the airtight hatch. +\ + ### Duplicating HANDLEs from content process to elevated window process We can't just have the content process dupe the handle to the window process. If From 3c4556db2cd7adec941cb24cb17bedba685ec9c0 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Fri, 30 Oct 2020 06:46:54 -0500 Subject: [PATCH 15/39] Lots more polish, ready to review --- .../#5000 - Process Model 2.0.md | 101 ++++++++++-------- 1 file changed, 57 insertions(+), 44 deletions(-) diff --git a/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md b/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md index dfd1a0b54b1..7b0eed9dae4 100644 --- a/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md +++ b/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md @@ -1,7 +1,7 @@ --- author: Mike Griese @zadjii-msft created on: 2020-07-31 -last updated: 2020-10-21 +last updated: 2020-10-30 issue id: #5000 --- @@ -661,13 +661,11 @@ windows to glom onto, so create the tab in this window process. - \*: note that this peasant could just be the monarch (in single instance mode, for example). -
- -This area is left intentionally vague, because we're not exactly sure what the -API surface exposed for default terminal invocations will look like. Hopefully, -it shows that however we do end up implementing support for default terminal -apps, the proposed Window/Content/Monarch/Peasant architecture will still be a -compatible solution. +> 👉 NOTE: This area is left intentionally vague, because we're not exactly sure +> what the API surface exposed for default terminal invocations will look like. +> Hopefully, it shows that however we do end up implementing support for default +> terminal apps, the proposed Window/Content/Monarch/Peasant architecture will +> still be a compatible solution. ## UI/UX Design @@ -852,7 +850,7 @@ so we should define that structure in a way that will allow future extensibility. -Lets examine some sample JSON[[2]](#footnote-2) +Lets examine some sample JSON[[2]](#footnote-2)[[3]](#footnote-3) ```json { @@ -923,29 +921,32 @@ spec. ### Mixed elevation & Monarch / Peasant issues -[TODO]: # TODO ================================================================= - -\ - -Initially, I thought that maybe we shoudn't have elevated windows involved in -the M/P game at all. However, what happens when the monarch's window needs to -silently elevate? That window should be able to retain its original ID, because -we want commands like `wt -s 1 new-tab` to still work in the original window. - -However, the elevate window absolutely cannot become the monarch process. If it -is, then unelevated windows won't be able to connect to the monarch at all. +Previously, we've mentioned that windows who wish to have a tab open elevated +will re-open as an elevated process, connected to all the content processes the +window was previously connected to. However, what happens when the window that +needs to re-open as an elevated window is the monarch process? If the elevated +window were to retain its monarch status, then all the other (unelevated) window +processes would be unable to connect to it and call methods and trigger +callbacks on it. So if the monarch is going to enter a mixed-elevation state, the new process for the elevated window shouldn't try to register as the monarch, and instead rely on another process being the monarch. +This comes with a variety of other edge cases as well. + +When a process does re-open as an elevated window, it will need a mechanism to +retain its original ID as assigned by the monarch. This is so that commands like +`wt -s 2 split-pane` will continue to refer to the same logical window, even if +there's a new process hosting it now. + What if there's only one window, and it becomes elevated? In that case, there is no other monarch to rely on. We'll need a way for us to start `wt` as a "headless monarch". This headless monarch process will _not_ display its own window, but will act as the monarch. The old monarch (who's now a different process altogether, and is elevated), should treat that medium-IL headless monarch the same as the other monarchs, and attempt to find a new monarch as -soon as it goes away. The headless monarch will attempt to register to ne the +soon as it goes away. The headless monarch will attempt to register to be the monarch - if it turns out that another process is the current monarch, then the headless monarch will immediately kill itself, causing the old monarch to immediately attempt to find a new monarch. If the headless monarch dies @@ -956,7 +957,6 @@ If there are only a bunch of elevated monarchs, then they'll each attempt to spawn a headless monarch. Only one will succeed - the others will all connect to the first headless monarch, and immedaitely die. - We need to be especially careful about the commands that can be run in an existing window. Opening a new tab, split, these are relatively safe. The new terminal that's created in the elevated window will still be unelevated by @@ -972,9 +972,8 @@ window is both: - Is elevated. - Is not this window. Sending input within the same window seems like it would be safe enough - you're already inside the airtight hatch. -\ -### Duplicating HANDLEs from content process to elevated window process +### Duplicating `HANDLE`s from content process to elevated window process We can't just have the content process dupe the handle to the window process. If the content process is unelevated, and the window process is elevated (in a @@ -986,25 +985,6 @@ duplicate handle. Fortunately, the `DuplicateHandle` function does allow a caller to duplicate from another process into your own process. -### Elevation and Extensions - -[TODO]: # TODO ================================================================= - -Shower thought (to make sure I don't forget): extensions should be disabled by -default in elevated windows. The user can chose to enable them in elevated -windows if they want. That setting needs to be hidden in a file that only admins -can write to. - -I suppose some extensions might be fine to run in unelevated content processes, -but would probably be impossible to entirely prevent them from triggering code -in the parent process. - -~~Like an extension running in the content process could try to trigger the -"enable broadcast input" mode and then have its keystrokes sent to the elevated -content procs~~ Actually, maybe not. The content process doesn't actually handle -any keybindings, does it? That's all in the window process, so that's not -terribly a concern. - ### What happens to the content if the monarch dies unexpectedly? What happens if you only have one window process, the monarch, and it @@ -1066,7 +1046,7 @@ of each other. 6. Change `TermControl`/`DxEngine` to create its own swap chain using `DCompositionCreateSurfaceHandle` and `CreateSwapChainForCompositionSurfaceHandle`. This is something that's - already done in commit TODO:`ffffff`. + already done in commit [`30b8335`]. 7. (Dependent on 6) Refactor `TermControl` to allow it to have a WinUI layer and a Core layer. The WinUI layer will be only responsible for interacting with @@ -1157,6 +1137,12 @@ almost certainly want to use a string as the payload type, so we can just pass that string into some WinRT method projected by whatever type corresponds to the provided `type`. +
[3]: The state that's serialized here for the contents +of a window might also be convinient to re-use for the restoration of terminal +window state across reboots. If we already know how to serialize the entire +state of a Terminal window, then storing that somewhere for a future terminal +launch to use seems like an obvious next step. See also [#961]. + ## Future considerations * A previous discussion with someone on the input team brought up the following @@ -1173,6 +1159,29 @@ provided `type`. - Or it could be `NewWindowFromTab(index:union(int,int[])?)` to specify the current tab, a specific tab, or many tabs. +### Elevation and Extensions + +In [#4000], we're tracking adding support for 3rd party extensions to the +Terminal. These extensions will be code that runs either in-proc or out-of-proc, +and can interact with the Terminal in some way. As examples, they might provide +settings (profiles), or add UI elements, or parse the contents of the buffer. + +Because the Terminal will be executing 3rd party code, I believe extensions that +run code should probably be disabled by default for elevated windows. This would +help reduce the attack surface for and attacker to leverage the Terminal as an +opportunity to have a user elevate the attacker's code. + +Of course, the user might want to be able to use a well-behaved extension in +elevated windows, when they trust the extension. We could have an additional set +of settings the user could use to enable certain extensions in elevated windows. +However, this setting cannot live in the normal `settings.json` or even +`state.json` (see [#7972], since those files are writable by any medium-IL +process. Instead, this setting would ned to live in a separate file that's +protected to only be writable by elevated processes. This would ensure that an +attacker could not just add their extension to the list of whitelisted +extensions. When the settings UI wants to modify that setting, it'll need to +prompt the user for permission, but that's an acceptable user experience. + ## TODOs @@ -1210,6 +1219,10 @@ provided `type`. [#1032]: https://github.com/microsoft/terminal/issues/1032 [#632]: https://github.com/microsoft/terminal/issues/632 [#492]: https://github.com/microsoft/terminal/issues/492 +[#4000]: https://github.com/microsoft/terminal/issues/4000 +[#7972]: https://github.com/microsoft/terminal/pull/7972 +[#961]: https://github.com/microsoft/terminal/issues/961 +[`30b8335`]: https://github.com/microsoft/terminal/commit/30b833547928d6dcbf88d49df0dbd5b3f6a7c879 [Tab Tear-out in the community toolkit]: https://github.com/windows-toolkit/Sample-TabView-TearOff [Quake mode scenarios]: https://github.com/microsoft/terminal/issues/653#issuecomment-661370107 From a9d2e8225ad309232f86d1403519500f7daa5953 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Fri, 30 Oct 2020 08:52:43 -0500 Subject: [PATCH 16/39] spellchecks --- .github/actions/spell-check/patterns/patterns.txt | 1 + .../#5000 - Process Model 2.0.md | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/actions/spell-check/patterns/patterns.txt b/.github/actions/spell-check/patterns/patterns.txt index 394ae60f9af..a787203a81c 100644 --- a/.github/actions/spell-check/patterns/patterns.txt +++ b/.github/actions/spell-check/patterns/patterns.txt @@ -5,6 +5,7 @@ https://www\.vt100\.net/docs/[-a-zA-Z0-9#_\/.]* https://www.w3.org/[-a-zA-Z0-9?&=\/_#]* https://(?:(?:www\.|)youtube\.com|youtu.be)/[-a-zA-Z0-9?&=]* https://[a-z-]+\.githubusercontent\.com/[-a-zA-Z0-9?&=_\/.]* +https://(www\.)*github\.com/microsoft/terminal/commit/([a-fA-F0-9])* [Pp]ublicKeyToken="?[0-9a-fA-F]{16}"? (?:[{"]|UniqueIdentifier>)[0-9a-fA-F]{8}-(?:[0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}(?:[}"]|[3]: The state that's serialized here for the contents -of a window might also be convinient to re-use for the restoration of terminal +of a window might also be convenient to re-use for the restoration of terminal window state across reboots. If we already know how to serialize the entire state of a Terminal window, then storing that somewhere for a future terminal launch to use seems like an obvious next step. See also [#961]. @@ -1178,7 +1178,7 @@ However, this setting cannot live in the normal `settings.json` or even `state.json` (see [#7972], since those files are writable by any medium-IL process. Instead, this setting would ned to live in a separate file that's protected to only be writable by elevated processes. This would ensure that an -attacker could not just add their extension to the list of whitelisted +attacker could not just add their extension to the list of white-listed extensions. When the settings UI wants to modify that setting, it'll need to prompt the user for permission, but that's an acceptable user experience. From 899a5066b8e40066a92f9e1914f843a51b660e12 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Fri, 30 Oct 2020 09:01:55 -0500 Subject: [PATCH 17/39] note about glomming to the same desktop --- .../#5000 - Process Model 2.0.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md b/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md index 94f6ce3d222..30f4d304a4d 100644 --- a/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md +++ b/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md @@ -1158,6 +1158,23 @@ launch to use seems like an obvious next step. See also [#961]. new window from a current tab once this all lands. - Or it could be `NewWindowFromTab(index:union(int,int[])?)` to specify the current tab, a specific tab, or many tabs. +* During + [review](https://github.com/microsoft/terminal/pull/7240#issuecomment-716022646), + it was mentioned that when links are opened in the new Edge browser, they will + only glom onto an existing window if that window is open in the current + virtual desktop. This seems like a good idea of a feature for the Terminal to + follow as well. Since Edge is able to do it, there must be some way for an + application to determine which virtual desktop it is open on. We could use + that information to have the monarch track the last active window per-desktop, + and only glom when there's one on the current desktop. + - We could even imagine changing the `glomToLastWindow` property to accept a + combined `bool`/enum value: + - `true` or `"always"`: always glom to the most recent window, regardless of + desktop + - `"sameDesktop"`: Only glom if there's an existing window on this virtual + desktop, otherwise create a new window + - `false` or `"never"`: Never glom, always create a new window. + ### Elevation and Extensions From 82d34e463fd7b76f7e64babc6bafa435665392f9 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Fri, 30 Oct 2020 09:05:53 -0500 Subject: [PATCH 18/39] because after all, the name is a joke --- .../#5000 - Process Model 2.0/#5000 - Process Model 2.0.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md b/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md index 30f4d304a4d..d4b1806b21c 100644 --- a/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md +++ b/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md @@ -380,6 +380,13 @@ state that it can use to enable some of the following scenarios. An example of such global state might be "which window process was the most recently focused one?" +> _Author's note_: The terms "monarch" and "peasant" were chosen to +> intentionally be a bit silly. Any relationship to an existing software model +> is purely coincidence. The metaphor is what is really important here, the +> naming just so happens to bring a bit of levity to what is otherwise a fairly +> dense spec. As this terminology is only intended to be used within the code +> itself, we're not terribly concerned about the actual choice of words here. + #### Scenario: Open new tabs in most recently used window A common feature of many browsers is that when a web URL is clicked somewhere, From 390e44b15e955b37a59c07a7781b5ea4a15be66b Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Fri, 30 Oct 2020 09:16:55 -0500 Subject: [PATCH 19/39] regex is hard --- .github/actions/spell-check/patterns/patterns.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/actions/spell-check/patterns/patterns.txt b/.github/actions/spell-check/patterns/patterns.txt index a787203a81c..597e0114bfa 100644 --- a/.github/actions/spell-check/patterns/patterns.txt +++ b/.github/actions/spell-check/patterns/patterns.txt @@ -4,8 +4,7 @@ https://www\.itscj\.ipsj\.or\.jp/iso-ir/[-0-9]+\.pdf https://www\.vt100\.net/docs/[-a-zA-Z0-9#_\/.]* https://www.w3.org/[-a-zA-Z0-9?&=\/_#]* https://(?:(?:www\.|)youtube\.com|youtu.be)/[-a-zA-Z0-9?&=]* -https://[a-z-]+\.githubusercontent\.com/[-a-zA-Z0-9?&=_\/.]* -https://(www\.)*github\.com/microsoft/terminal/commit/([a-fA-F0-9])* +https://[a-z-]+\.github(?:usercontent|)\.com/[-a-zA-Z0-9?&=_\/.]* [Pp]ublicKeyToken="?[0-9a-fA-F]{16}"? (?:[{"]|UniqueIdentifier>)[0-9a-fA-F]{8}-(?:[0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}(?:[}"]| Date: Fri, 30 Oct 2020 15:47:43 -0500 Subject: [PATCH 20/39] Start working on the details of this spec --- ...2 - Windows Terminal Session Management.md | 384 ++++++++++++++++++ 1 file changed, 384 insertions(+) create mode 100644 doc/specs/#5000 - Process Model 2.0/#4472 - Windows Terminal Session Management.md diff --git a/doc/specs/#5000 - Process Model 2.0/#4472 - Windows Terminal Session Management.md b/doc/specs/#5000 - Process Model 2.0/#4472 - Windows Terminal Session Management.md new file mode 100644 index 00000000000..8f496e1829d --- /dev/null +++ b/doc/specs/#5000 - Process Model 2.0/#4472 - Windows Terminal Session Management.md @@ -0,0 +1,384 @@ +--- +author: Mike Griese @zadjii-msft +created on: 2020-10-30 +last updated: 2020-10-30 +issue id: #4472 +--- + +# Windows Terminal Session Management + +## Abstract +This document is intended to serve as an addition to the [Windows Terminal +Process Model 2.0 Spec]. That document provides a big-picture overview of +changes to the entirety of the Windows Terminal process architecture, including +both the split of window/content processes, as well as the introduction of +monarch/peasant processes. The focus of that document was to identify solutions +to a set of scenarios that were closely intertwined, and establish these +solutions would work together, without preventing any one scenario from working. +What that docuement did not do was prescribe specific solutions to the given +scenarios. + +This document offers a deeper dive on a subset of the issues in [#5000], to +describe specifics for managing multiple windows with the Windows Terminal. This +includes features such as: + +* Run `wt` in the current window ([#4472]) +* Single Instance Mode ([#2227]) +* Quake Mode ([#653]) + +## Inspiration + +[TODO]: # TODO + +## Background + +[TODO]: # TODO? + +## Solution Design + +### Monarch and Peasant Processes + +This document assumes the reader is already familiar with the "Monarch and +Peasant" architecture as detailed in the [Windows Terminal Process Model 2.0 +Spec]. As a quick summary: + +* Every Windows Terminal window is a "Peasant" process. +* One of the Windows Terminal window processes is also the "Monarch" process. + The Monarch is picked randomly from the Terminal windows, and there is only + ever one Monarch process at a time. +* Peasants can communicate with the monarch when certain state changes (such as + their window being activated), and the monarch can send commands to any of hte + peasants. + +This architecture will be used to enable each of the following scenarios. + +### Scenario: Open new tabs in most recently used window + +A common feature of many browsers is that when a web URL is clicked somewhere, +the web page is opened as a new tab in the most recently used window of the +browser. This functionality is often referred to as "glomming", as the new tab +"gloms" onto the existing window. + +Currently, the terminal does not support such a feature - every `wt` invocation +creates a new window. With the monarch/peasant architecture, it'll now be +possible to enable such a scenario. + +As each window is activated, it will call a method on the `Monarch` object +(hosted by the monarch process) which will indicate that "I am peasant N, and +I've been focused". The monarch will use those method calls to update its own +internal stack of the most recently used windows. + +Whenever a new `wt.exe` process is launched, that process will _first_ ask the +monarch if it should run the commandline in an existing window, or create its +own window. + +![auto-glom-wt-exe](auto-glom-wt-exe.png) + +If glomming is disabled, then the Monarch will call back to the peasant and tell +it to run the provided commandline. + +If glomming is enabled, the monarch will dispatch the +commandline to the appropriate window for them to handle instead. To the user, +it'll seem as if the tab just opened in the most recent window. + +Users should certainly be able to specify if they want new instances to glom +onto the MRU window or not. You could imagine that currently, we default to the +hypothetical value `"glomToLastWindow": false`, meaning that each new wt gets +it's own new window. + +#### Glomming within the same virtual desktop + +When links are opened in the new Edge browser, they will only glom onto an +existing window if that window is open in the current virtual desktop. This +seems like a good idea of a feature for the Terminal to follow as well. + +There must be some way for an application to determine which virtual desktop it +is open on. We could use that information to have the monarch track the last +active window _per-desktop_, and only glom when there's one on the current +desktop. + +We could make the `glomToLastWindow` property even more powerful by accepting a +combined `bool`/enum value: +- `true` or `"always"`: always glom to the most recent window, regardless of + desktop +- `"sameDesktop"`: Only glom if there's an existing window on this virtual + desktop, otherwise create a new window +- `false` or `"never"`: Never glom, always create a new window. + +### Handling the current working directory + +Consider the following scenario: the user runs `wt -d .` in the address bar of +explorer, and the monarch determines that this new tab should be created in an +existing window. For clarity during this example, we will label the existing +window WT[1], and the second `wt.exe` process WT[2]. + +An example of this scenario is given in the following diagram: + +![single-instance-mode-cwd](single-instance-mode-cwd.png) + +In this scenario, we want the new tab to be spawned in the current working +directory of WT[2], not WT[1]. So when WT[1] is about to run the commands that +were passed to WT[2], WT[1] will need to: + +* First, stash it's own CWD +* Change to the CWD of WT[2] +* Run the commands from WT[2] +* Then return to it's original CWD. + +So, as a part of the interface that a peasant uses to communicate the startup +commandline to the monarch, we should also include the current working +directory. + +### Scenario: Run `wt` in the current window + +One often requested scenario is the ability to run a `wt.exe` commandline in the +current window, as opposed to always creating a new window. With the ability to +communicate between different window processes, one could imagine a logical +extension of this scenario being "run a `wt` commandline in _any_ given WT +window". + +Since each window process will have it's own unique ID assigned to it by the +monarch, then running a command in a given window with ID `N` should be as easy +as something like: + +```sh +wt.exe --session N new-tab ; split-pane +``` + +(or for shorthand, `wt -s N new-tab ; split-pane`). + +> ❗ TODO: In the remainder of this spec, I'll continue to use the parameters +> `--session,-s session-id` as the parameter to identify the window that a +> command should be run in. These arguments could just as easily be `--window,-w +> window-id`, and mean the same thing. I leave it as an exercise for the +> reviewers to pick one naming that they like best. + +_Whenever_ `wt.exe` is started, it must _always_ pass the provided commandline +first to the monarch process for handling. This is important for glomming +scenarios (as noted above) + +If the `--session` parameter is omitted, or is passed the special value `0`, the +monarch will then call back to whatever the last active Terminal window + +#### `--session` in subcommands + +Will we allow `wt -s 2 new-tab ; -s 3 split-pane`? + +\ + +This would create a new peasant, who could then ask the monarch if there is a +peasant with ID `N`. If there is, then the peasant can connect to that other +peasant, dispatch the current commandline to that other peasant, and exit, +before ever creating a window. If this commandline instead creates a new monarch +process, then there was _no_ other monarch, and so there must logically not be +any other existing WT windows, and the `--session N` argument could be safely +ignored, and the command run in the current window. + +We should reserve the session id `0` to always refer to "The current window", if +there is one. So `wt -s 0 new-tab` will run `new-tab` in the current window (if +we're being run from WT). + +If `wt -s 0 ` is run _outside_ a WT instance, it could attempt to glom +onto _the most recent WT window_ instead. This seems more logical than something +like `wt --session last` or some other special value indicating "run this in the +MRU window". + +That might be a simple, but **wrong**, implementation for "the current window". +If the peasants always raise an event when their window is focused, and the +monarch keeps track of the MRU order for peasants, then one could naively assume +that the execution of `wt -s 0 ` would always return the window the +user was typing in, the current one. However, if someone were to do something +like `sleep 10 ; wt -s 0 `, then the user could easily focus another +WT window during the sleep, which would cause the MRU window to not be the same +as the window executing the command. + +I'm not sure that there is a better solution for the `-s 0` scenario other than +attempting to use the `WT_SESSION` environment variable. If a `wt.exe` process is +spawned and that's in it's environment variables, it could try and ask the +monarch for the peasant who's hosting the session corresponding to that GUID. +This is more of a theoretical solution than anything else. + +In Single-Instance mode, running `wt -s 0` outside a WT window will still cause +the commandline to glom to the existing single terminal instance, if there is +one. + + +#### Scenario: Single Instance Mode + +"Single Instance Mode" is a scenario in which there is only ever one single WT +window. When Single Instance Mode is active, and the user runs a new `wt.exe` +commandline, it will always end up running in the existing window, if there is +one. + +In "Single Instance Mode", the monarch _is_ the single instance. When `wt` is +run, and it determines that it is not the monarch, it'll ask the monarch if it's +in single instance mode. If it is, then the peasant that's starting up will +instead pass it's commandline arguments to the monarch process, and let the +monarch handle them, then exit. In single instance mode the window will still be +composed from a combination of a window process and multiple different content +processes, just the same as it would be outside single instance mode. + +So, this will make it seem like new starting a new `wt.exe` will just create a +new tab in the existing window. + +One could imagine that single instance mode is the combination of two properties: +* The user wants new invocation of `wt` to "glom" onto the most recently used + window (the hypothetical `"glomToLastWindow": true` setting) +* The user wants to prevent tab tear-out, or the ability for a `newWindow` + action to work. (hypothetically `"allowTabTearOut": false`) + +#### Scenario: Quake Mode + +"Quake mode" has a variety of different scenarios[[1]](#footnote-1) +that have all been requested, more than what fits cleanly into this spec. +However, there's one key aspect of quake mode that is specifically relevant and +worth mentioning here. + +One of the biggest challenges with registering a global shortcut handler is +_what happens when multiple windows try to register for the same shortcut at the +same time_? From my initial research, it seems that only the first process to +register for the shortcut will succeed. This makes it hard for multiple windows +to handle the global shortcut key gracefully. If a second window is created, and +it fails to register the global hotkey, then the first window is closed, there's +no way for the second process to track that and re-register as the handler for +that key. + +With the addition of monarch/peasant processes, this problem becomes much easier +to solve. Now, the monarch process will _always_ be the process to register the +shortcut key, whenever it's elected. If it dies and another peasant is elected +monarch, then the new monarch will register as the global hotkey handler. + +Then, the monarch can use it's pre-established channels of communication with +the other window processes to actually drive the response we're looking for. + +**Alternatively**, we could use an entirely other process to be in charge of the +registration of the global keybinding. This process would be some sort of +long-running service that's started on boot. When it detects the global hotkey, +it could attempt to instantiate a `Monarch` object. + +* If it can't make one, then it can simply run a new instance of `wt.exe`, + because there's not yet a running Terminal window. +* Otherwise, it can communicate to the monarch that the global hotkey was + pressed, and the monarch will take care of delegating the activation to the + appropriate peasant window. + +This would mitigate the need to have at least one copy of WT running already, +and the user could press that keybinding at any time to start the terminal. + +\ + +## UI/UX Design + +[TODO]: # TODO + +## Capabilities + + + + + + + + + + + + + + + + + + + + + + +
Accessibility + +[TODO]: # TODO + +
Security + +[TODO]: # TODO +
Reliability + +[TODO]: # TODO + +
Compatibility + +[TODO]: # TODO + +
Performance, Power, and Efficiency + +[TODO]: # TODO + +
+ +## Potential Issues + +[TODO]: # TODO + +## Implementation Plan + +[TODO]: # TODO? Or just leave this in the PM2.0 spec? + +This is a list of actionable tasks generated as described by this spec: + +* [ ] Add support for `wt.exe` processes to be Monarchs and Peasants, and communicate that state between themselves. This task does not otherwise add any user-facing features, merely an architectural update. +* [ ] Add support for the `glomToLastWindow` setting as a boolean. Opening new WT windows will conditionally glom to existing windows. +* [ ] Add support for per-desktop `glomToLastWindow`, by adding the support for the enum values `"always"`, `"sameDesktop"` and `"never"`. + +## Footnotes + +
[1]: TODO + +## Future considerations + + +[TODO]: # TODO + +* During + [review](https://github.com/microsoft/terminal/pull/7240#issuecomment-716022646), + it was mentioned that when links are opened in the new Edge browser, they will + only glom onto an existing window if that window is open in the current + virtual desktop. This seems like a good idea of a feature for the Terminal to + follow as well. Since Edge is able to do it, there must be some way for an + application to determine which virtual desktop it is open on. We could use + that information to have the monarch track the last active window per-desktop, + and only glom when there's one on the current desktop. + - We could even imagine changing the `glomToLastWindow` property to accept a + combined `bool`/enum value: + - `true` or `"always"`: always glom to the most recent window, regardless of + desktop + - `"sameDesktop"`: Only glom if there's an existing window on this virtual + desktop, otherwise create a new window + - `false` or `"never"`: Never glom, always create a new window. + + +## Resources + +* [Tab Tear-out in the community toolkit] - this document proved invaluable to + the background of tearing a tab out of an application to create a new window. + + + +[#5000]: https://github.com/microsoft/terminal/issues/5000 +[#1256]: https://github.com/microsoft/terminal/issues/1256 +[#4472]: https://github.com/microsoft/terminal/issues/4472 +[#2227]: https://github.com/microsoft/terminal/issues/2227 +[#653]: https://github.com/microsoft/terminal/issues/653 +[#1032]: https://github.com/microsoft/terminal/issues/1032 +[#632]: https://github.com/microsoft/terminal/issues/632 +[#492]: https://github.com/microsoft/terminal/issues/492 +[#4000]: https://github.com/microsoft/terminal/issues/4000 +[#7972]: https://github.com/microsoft/terminal/pull/7972 +[#961]: https://github.com/microsoft/terminal/issues/961 +[`30b8335`]: https://github.com/microsoft/terminal/commit/30b833547928d6dcbf88d49df0dbd5b3f6a7c879 + +[Tab Tear-out in the community toolkit]: https://github.com/windows-toolkit/Sample-TabView-TearOff +[Quake mode scenarios]: https://github.com/microsoft/terminal/issues/653#issuecomment-661370107 +[`ISwapChainPanelNative2::SetSwapChainHandle`]: https://docs.microsoft.com/en-us/windows/win32/api/windows.ui.xaml.media.dxinterop/nf-windows-ui-xaml-media-dxinterop-iswapchainpanelnative2-setswapchainhandle + + +[Windows Terminal Process Model 2.0 Spec]: https://github.com/microsoft/terminal/blob/main/doc/specs/%235000%20-%20Process%20Model%202.0.md From 53e54cbf8daa0c8d22fd0907582ca4511237ce32 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Mon, 2 Nov 2020 11:32:47 -0600 Subject: [PATCH 21/39] Much brainstorming over how to implement single instance vs tab glomming vs no glomming --- ...2 - Windows Terminal Session Management.md | 156 +++++++++++++----- 1 file changed, 118 insertions(+), 38 deletions(-) diff --git a/doc/specs/#5000 - Process Model 2.0/#4472 - Windows Terminal Session Management.md b/doc/specs/#5000 - Process Model 2.0/#4472 - Windows Terminal Session Management.md index 8f496e1829d..5642a917789 100644 --- a/doc/specs/#5000 - Process Model 2.0/#4472 - Windows Terminal Session Management.md +++ b/doc/specs/#5000 - Process Model 2.0/#4472 - Windows Terminal Session Management.md @@ -1,7 +1,7 @@ --- author: Mike Griese @zadjii-msft created on: 2020-10-30 -last updated: 2020-10-30 +last updated: 2020-11-02 issue id: #4472 --- @@ -147,36 +147,30 @@ wt.exe --session N new-tab ; split-pane (or for shorthand, `wt -s N new-tab ; split-pane`). -> ❗ TODO: In the remainder of this spec, I'll continue to use the parameters -> `--session,-s session-id` as the parameter to identify the window that a -> command should be run in. These arguments could just as easily be `--window,-w -> window-id`, and mean the same thing. I leave it as an exercise for the -> reviewers to pick one naming that they like best. +> ❗ TODO for discussion: In the remainder of this spec, I'll continue to use the +> parameters `--session,-s session-id` as the parameter to identify the window +> that a command should be run in. These arguments could just as easily be +> `--window,-w window-id`, and mean the same thing. I leave it as an exercise +> for the reviewers to pick one naming that they like best. -_Whenever_ `wt.exe` is started, it must _always_ pass the provided commandline -first to the monarch process for handling. This is important for glomming -scenarios (as noted above) - -If the `--session` parameter is omitted, or is passed the special value `0`, the -monarch will then call back to whatever the last active Terminal window +More formally, we'll add the following parameter to the top-level `wt` command: -#### `--session` in subcommands - -Will we allow `wt -s 2 new-tab ; -s 3 split-pane`? +#### `--session,-s session-id` +Run these commands in the given Windows Terminal session. This enables opening +new tabs, splits, etc. in already running Windows Terminal windows. +* If `session-id` is `0`, run the given commands in _the current window_ +* If `session-id` is not the ID of any exsiting window, then run the commands in + a _new_ Terminal window. +* If `session-id` is ommitted, then obey the value of `glomToLastWindow` when + determining which window to run the command in. -\ - -This would create a new peasant, who could then ask the monarch if there is a -peasant with ID `N`. If there is, then the peasant can connect to that other -peasant, dispatch the current commandline to that other peasant, and exit, -before ever creating a window. If this commandline instead creates a new monarch -process, then there was _no_ other monarch, and so there must logically not be -any other existing WT windows, and the `--session N` argument could be safely -ignored, and the command run in the current window. +_Whenever_ `wt.exe` is started, it must _always_ pass the provided commandline +first to the monarch process for handling. This is important for glomming +scenarios (as noted above). The monarch will parse the commandline, determine +which window the commandline is destined for, then call `ExecuteCommandline` on +that peasant, who will then run the command. -We should reserve the session id `0` to always refer to "The current window", if -there is one. So `wt -s 0 new-tab` will run `new-tab` in the current window (if -we're being run from WT). +#### Running commands in the current window:`--session-id 0` If `wt -s 0 ` is run _outside_ a WT instance, it could attempt to glom onto _the most recent WT window_ instead. This seems more logical than something @@ -202,6 +196,23 @@ In Single-Instance mode, running `wt -s 0` outside a WT window will still cause the commandline to glom to the existing single terminal instance, if there is one. +#### Running commands in a new window:`--session-id -1` + +If the user passes an invalid ID to the `--session` parameter, then we'll always +create a new window for that commandline, regardless of the value of +`glomToLastWindow`. This will allow users to do something like `wt -s -1 +new-tab` to _always_ create a new window. Since window IDs are only ever +positive integers, then `-1` would be a convenient value for something that's +_never_ an existing window ID. + + +#### `--session` in subcommands + +Will we allow `wt -s 2 new-tab ; -s 3 split-pane`? + + + +\ #### Scenario: Single Instance Mode @@ -211,21 +222,90 @@ commandline, it will always end up running in the existing window, if there is one. In "Single Instance Mode", the monarch _is_ the single instance. When `wt` is -run, and it determines that it is not the monarch, it'll ask the monarch if it's -in single instance mode. If it is, then the peasant that's starting up will -instead pass it's commandline arguments to the monarch process, and let the -monarch handle them, then exit. In single instance mode the window will still be -composed from a combination of a window process and multiple different content -processes, just the same as it would be outside single instance mode. - -So, this will make it seem like new starting a new `wt.exe` will just create a -new tab in the existing window. +run, and it determines that it is not the monarch, it'll pass the commandline to +the monarch. At this point, the monarch will determine that it is in Single +Instance Mode, and consume the commands itself. One could imagine that single instance mode is the combination of two properties: * The user wants new invocation of `wt` to "glom" onto the most recently used - window (the hypothetical `"glomToLastWindow": true` setting) + window (the aforementioned `"glomToLastWindow": true` setting) * The user wants to prevent tab tear-out, or the ability for a `newWindow` - action to work. (hypothetically `"allowTabTearOut": false`) + action to work. This will be controlled by a proposed `"allowMultipleWindows"` setting, where: + - `"allowMultipleWindows": false`: new windows are always created in the current window, and tab tear-out is disabled. This overrides any behavior from `glomToLastWindow`. + - `"allowMultipleWindows": true`: `newWindow` actions will always create a new window, `-s ID` + +[TODO]: # TODO ################################################################ +This is weird - why two settings? what value do we really get from that? Preventing people from tearing out tabs, but allowing `wt nt` to open in new windows? + +Let's look at the old proposal, which had two properties: + +* `"glomToLastWindow": true|false` +* `"allowTabTearOut": true|false` + +Which gives us these cases: + +* `"glomToLastWindow": true`, `"allowTabTearOut": true`: + - New instances open in the current window by default. + - `newWindow` opens a new window. + - Tabs can be torn out to create new windows. + - `wt -s -1` opens a new window. +* `"glomToLastWindow": true`, `"allowTabTearOut": false`: + - New instances open in the current window by default. + - `newWindow` opens in the existing window. + - Tabs cannot be torn out to create new windows. + - `wt -s -1` opens in the existing window. +* `"glomToLastWindow": false`, `"allowTabTearOut": true`: + - New instances open in new windows by default + - `newWindow` opens a new window + - Tabs can be torn out to create new windows. + - `wt -s -1` opens a new window. +* `"glomToLastWindow": false`, `"allowTabTearOut": false`: + - New instances open in the current window by default. (unexpected?) + - `newWindow` opens in the existing window. + - Tabs cannot be torn out to create new windows. + - `wt -s -1` opens in the existing window. + +The fourth case is actually exactly the same as the second case. So that would +imply there's really only 3 values here, not a matrix of 2 options by 2 options. + +Perhaps the `glomToLastWindow` setting doesn't make exact sense? Maybe we need a few other values. + +(for this mental experiment, `"glomToLastWindow"` and `"glomToLastWindowSameDesktop"` are being treated as one property) + +What actual user stories do we have? + + +* Scenario 1: Browser-like glomming + - + - New instances open in the current window by default. + - `newWindow` opens a new window. + - Tabs can be torn out to create new windows. + - `wt -s -1` opens a new window. +* Scenario 2: Single Instance Mode + - + - New instances open in the current window by default. + - `newWindow` opens in the existing window. + - Tabs cannot be torn out to create new windows. + - `wt -s -1` opens in the existing window. +* Scenario 3: No auto-glomming + - + - New instances open in new windows by default + - `newWindow` opens a new window + - Tabs can be torn out to create new windows. + - `wt -s -1` opens a new window. + +So this kinda reads as + +`"glomTolastWindow": ("never"|false)|"sameDesktop"|("lastWindow"|true)|"always"` + +[/TODO]: # /TODO ############################################################## + + + +While tear-out is a separate track of work from session management in general, this setting could be implemented along with this set of features, and later used to control tear out as well. #### Scenario: Quake Mode From f591213a18e8597eea97752bdf537ed1db086485 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Mon, 2 Nov 2020 13:05:57 -0600 Subject: [PATCH 22/39] Almost done --- ...2 - Windows Terminal Session Management.md | 358 +++++++++--------- 1 file changed, 185 insertions(+), 173 deletions(-) diff --git a/doc/specs/#5000 - Process Model 2.0/#4472 - Windows Terminal Session Management.md b/doc/specs/#5000 - Process Model 2.0/#4472 - Windows Terminal Session Management.md index 5642a917789..0dd59dca3a4 100644 --- a/doc/specs/#5000 - Process Model 2.0/#4472 - Windows Terminal Session Management.md +++ b/doc/specs/#5000 - Process Model 2.0/#4472 - Windows Terminal Session Management.md @@ -8,15 +8,14 @@ issue id: #4472 # Windows Terminal Session Management ## Abstract -This document is intended to serve as an addition to the [Windows Terminal -Process Model 2.0 Spec]. That document provides a big-picture overview of -changes to the entirety of the Windows Terminal process architecture, including -both the split of window/content processes, as well as the introduction of -monarch/peasant processes. The focus of that document was to identify solutions -to a set of scenarios that were closely intertwined, and establish these -solutions would work together, without preventing any one scenario from working. -What that docuement did not do was prescribe specific solutions to the given -scenarios. +This document is intended to serve as an addition to the [Process Model 2.0 +Spec]. That document provides a big-picture overview of changes to the entirety +of the Windows Terminal process architecture, including both the split of +window/content processes, as well as the introduction of monarch/peasant +processes. The focus of that document was to identify solutions to a set of +scenarios that were closely intertwined, and establish these solutions would +work together, without preventing any one scenario from working. What that +docuement did not do was prescribe specific solutions to the given scenarios. This document offers a deeper dive on a subset of the issues in [#5000], to describe specifics for managing multiple windows with the Windows Terminal. This @@ -24,15 +23,6 @@ includes features such as: * Run `wt` in the current window ([#4472]) * Single Instance Mode ([#2227]) -* Quake Mode ([#653]) - -## Inspiration - -[TODO]: # TODO - -## Background - -[TODO]: # TODO? ## Solution Design @@ -86,6 +76,17 @@ onto the MRU window or not. You could imagine that currently, we default to the hypothetical value `"glomToLastWindow": false`, meaning that each new wt gets it's own new window. +[TODO]: # todo + +Make sure to discuss that when the monarch determines that a new `wt` instance +actually _should_ host the new terminal, it can reply back to it appropriately. +Does that mean the Peasant has to be created, and registered with the monarch, +first? Or can the Monarch reply, "No, you can take care of this", which _then_ +causes the WT process to create and register the peasant? + +[/TODO]: # todo + + #### Glomming within the same virtual desktop When links are opened in the new Edge browser, they will only glom onto an @@ -99,11 +100,17 @@ desktop. We could make the `glomToLastWindow` property even more powerful by accepting a combined `bool`/enum value: -- `true` or `"always"`: always glom to the most recent window, regardless of - desktop -- `"sameDesktop"`: Only glom if there's an existing window on this virtual - desktop, otherwise create a new window -- `false` or `"never"`: Never glom, always create a new window. +- `"always"`: always glom to the most recent window, regardless of desktop. This + also suppresses the creation of new windows, including tearing out tabs, or + windows created by `newWindow` actions. See [Single Instance + Mode](#scenario-single-instance-mode) for more details. +- `"lastWindow"`: always glom to the most recent window, regardless of + desktop. +- `true` or `"sameDesktop"`: Only glom if there's an existing window on this + virtual desktop, otherwise create a new window. This will be the new default + value. +- `false` or `"never"`: Never glom, always create a new window. This is + technically the current behavior of the Terminal. ### Handling the current working directory @@ -170,7 +177,7 @@ scenarios (as noted above). The monarch will parse the commandline, determine which window the commandline is destined for, then call `ExecuteCommandline` on that peasant, who will then run the command. -#### Running commands in the current window:`--session-id 0` +#### Running commands in the current window:`wt --session 0` If `wt -s 0 ` is run _outside_ a WT instance, it could attempt to glom onto _the most recent WT window_ instead. This seems more logical than something @@ -187,8 +194,8 @@ WT window during the sleep, which would cause the MRU window to not be the same as the window executing the command. I'm not sure that there is a better solution for the `-s 0` scenario other than -attempting to use the `WT_SESSION` environment variable. If a `wt.exe` process is -spawned and that's in it's environment variables, it could try and ask the +attempting to use the `WT_SESSION` environment variable. If a `wt.exe` process +is spawned and that's in it's environment variables, it could try and ask the monarch for the peasant who's hosting the session corresponding to that GUID. This is more of a theoretical solution than anything else. @@ -196,7 +203,7 @@ In Single-Instance mode, running `wt -s 0` outside a WT window will still cause the commandline to glom to the existing single terminal instance, if there is one. -#### Running commands in a new window:`--session-id -1` +#### Running commands in a new window:`wt --session -1` If the user passes an invalid ID to the `--session` parameter, then we'll always create a new window for that commandline, regardless of the value of @@ -205,160 +212,93 @@ new-tab` to _always_ create a new window. Since window IDs are only ever positive integers, then `-1` would be a convenient value for something that's _never_ an existing window ID. - #### `--session` in subcommands -Will we allow `wt -s 2 new-tab ; -s 3 split-pane`? +The `--session` parameter is a setting to `wt.exe` itself, not to one of its +subcommands (like `new-tab` or `split-pane`). This means that all of the +subcommands in a particular `wt` commandline will all be handled by the same +session. For example, let us consider a user who wants to open a new tab in +window 2, and split a new pane in window 3, all at once. The user _cannot_ do +something like: + +```cmd +wt -s 2 new-tab ; -s 3 split-pane +``` + +Instead, the user will need to separate the commands (by whatever their shell's +own command delimiter is) and run two different `wt.exe` instances: +```cmd +wt -s 2 new-tab & wt -s 3 split-pane +``` +This is done to make the parsing of the subcommands easier, and for the internal +passing of arguments simpler. If the `--session` parameter were a part of each +subcommand, then each individual subcommand's parser would need to be +enlightened about that parameter, and then it would need to be possible for any +single part of the commandline to call out to another process. It would be +especially tricky then to coordinate the work being done across process here. +The source process would need some sort of way to wait for the other process to +notify the source that a particular subcommand completed, before allowing the +source to dispatch the next part of the commandline. -\ +Overall, this is seen as unnecessarily complex, and dispatching whole sets of +commands as a simpler solution. -#### Scenario: Single Instance Mode +### Scenario: Single Instance Mode "Single Instance Mode" is a scenario in which there is only ever one single WT -window. When Single Instance Mode is active, and the user runs a new `wt.exe` -commandline, it will always end up running in the existing window, if there is -one. +window. A user might want this functionality to only ever allow a single +terminal window to be open on their desktop. This is especially frequently +requested in combination with "quake mode", as discussed in +[#653]. When Single Instance Mode is active, and the user +runs a new `wt.exe` commandline, it will always end up running in the existing +window, if there is one. In "Single Instance Mode", the monarch _is_ the single instance. When `wt` is run, and it determines that it is not the monarch, it'll pass the commandline to the monarch. At this point, the monarch will determine that it is in Single Instance Mode, and consume the commands itself. -One could imagine that single instance mode is the combination of two properties: -* The user wants new invocation of `wt` to "glom" onto the most recently used - window (the aforementioned `"glomToLastWindow": true` setting) -* The user wants to prevent tab tear-out, or the ability for a `newWindow` - action to work. This will be controlled by a proposed `"allowMultipleWindows"` setting, where: - - `"allowMultipleWindows": false`: new windows are always created in the current window, and tab tear-out is disabled. This overrides any behavior from `glomToLastWindow`. - - `"allowMultipleWindows": true`: `newWindow` actions will always create a new window, `-s ID` - -[TODO]: # TODO ################################################################ -This is weird - why two settings? what value do we really get from that? Preventing people from tearing out tabs, but allowing `wt nt` to open in new windows? - -Let's look at the old proposal, which had two properties: - -* `"glomToLastWindow": true|false` -* `"allowTabTearOut": true|false` - -Which gives us these cases: - -* `"glomToLastWindow": true`, `"allowTabTearOut": true`: - - New instances open in the current window by default. - - `newWindow` opens a new window. - - Tabs can be torn out to create new windows. - - `wt -s -1` opens a new window. -* `"glomToLastWindow": true`, `"allowTabTearOut": false`: - - New instances open in the current window by default. - - `newWindow` opens in the existing window. - - Tabs cannot be torn out to create new windows. - - `wt -s -1` opens in the existing window. -* `"glomToLastWindow": false`, `"allowTabTearOut": true`: - - New instances open in new windows by default - - `newWindow` opens a new window - - Tabs can be torn out to create new windows. - - `wt -s -1` opens a new window. -* `"glomToLastWindow": false`, `"allowTabTearOut": false`: - - New instances open in the current window by default. (unexpected?) - - `newWindow` opens in the existing window. - - Tabs cannot be torn out to create new windows. - - `wt -s -1` opens in the existing window. - -The fourth case is actually exactly the same as the second case. So that would -imply there's really only 3 values here, not a matrix of 2 options by 2 options. - -Perhaps the `glomToLastWindow` setting doesn't make exact sense? Maybe we need a few other values. +Single instance mode is enabled with the `"glomToLastWindow": "always"` setting. +This value disables tab tearout[[1]](#footnote-1) , as well as the +ability for `newWindow` and `wt -s -1` to create new windows. In those cases, +the commandline will _always_ be handled by the current window, the monarch +window. -(for this mental experiment, `"glomToLastWindow"` and `"glomToLastWindowSameDesktop"` are being treated as one property) +## UI/UX Design -What actual user stories do we have? +### `glomToLastWindow` details +The following list gives greater breakdown of the values of `glomToLastWindow`, +and how they operate: -* Scenario 1: Browser-like glomming - - +* `"glomToLastWindow": "lastWindow", "sameDesktop"|true`: Browser-like glomming - New instances open in the current window by default. - `newWindow` opens a new window. - Tabs can be torn out to create new windows. - `wt -s -1` opens a new window. -* Scenario 2: Single Instance Mode - - +* `"glomToLastWindow": "always"`: Single Instance Mode. - New instances open in the current window by default. - `newWindow` opens in the existing window. - Tabs cannot be torn out to create new windows. - `wt -s -1` opens in the existing window. -* Scenario 3: No auto-glomming - - +* `"glomToLastWindow": "never"`: No auto-glomming. This is the current behavior + of the Terminal. - New instances open in new windows by default - `newWindow` opens a new window - Tabs can be torn out to create new windows. - `wt -s -1` opens a new window. -So this kinda reads as - -`"glomTolastWindow": ("never"|false)|"sameDesktop"|("lastWindow"|true)|"always"` - -[/TODO]: # /TODO ############################################################## - - - -While tear-out is a separate track of work from session management in general, this setting could be implemented along with this set of features, and later used to control tear out as well. - -#### Scenario: Quake Mode - -"Quake mode" has a variety of different scenarios[[1]](#footnote-1) -that have all been requested, more than what fits cleanly into this spec. -However, there's one key aspect of quake mode that is specifically relevant and -worth mentioning here. - -One of the biggest challenges with registering a global shortcut handler is -_what happens when multiple windows try to register for the same shortcut at the -same time_? From my initial research, it seems that only the first process to -register for the shortcut will succeed. This makes it hard for multiple windows -to handle the global shortcut key gracefully. If a second window is created, and -it fails to register the global hotkey, then the first window is closed, there's -no way for the second process to track that and re-register as the handler for -that key. - -With the addition of monarch/peasant processes, this problem becomes much easier -to solve. Now, the monarch process will _always_ be the process to register the -shortcut key, whenever it's elected. If it dies and another peasant is elected -monarch, then the new monarch will register as the global hotkey handler. - -Then, the monarch can use it's pre-established channels of communication with -the other window processes to actually drive the response we're looking for. - -**Alternatively**, we could use an entirely other process to be in charge of the -registration of the global keybinding. This process would be some sort of -long-running service that's started on boot. When it detects the global hotkey, -it could attempt to instantiate a `Monarch` object. - -* If it can't make one, then it can simply run a new instance of `wt.exe`, - because there's not yet a running Terminal window. -* Otherwise, it can communicate to the monarch that the global hotkey was - pressed, and the monarch will take care of delegating the activation to the - appropriate peasant window. - -This would mitigate the need to have at least one copy of WT running already, -and the user could press that keybinding at any time to start the terminal. - -\ - -## UI/UX Design - -[TODO]: # TODO - -## Capabilities +## Concerns @@ -366,14 +306,26 @@ and the user could press that keybinding at any time to start the terminal. @@ -381,7 +333,13 @@ and the user could press that keybinding at any time to start the terminal. @@ -389,7 +347,9 @@ and the user could press that keybinding at any time to start the terminal. @@ -397,44 +357,96 @@ and the user could press that keybinding at any time to start the terminal. ## Potential Issues -[TODO]: # TODO +### Mixed elevation & Monarch / Peasant issues + +_This section was originally authored in the [Process Model 2.0 Spec]. Please +refer to it there for its original context._ + +Previously, we've mentioned that windows who wish to have a tab open elevated +will re-open as an elevated process, connected to all the content processes the +window was previously connected to. However, what happens when the window that +needs to re-open as an elevated window is the monarch process? If the elevated +window were to retain its monarch status, then all the other (unelevated) window +processes would be unable to connect to it and call methods and trigger +callbacks on it. + +So if the monarch is going to enter a mixed-elevation state, the new process for +the elevated window shouldn't try to register as the monarch, and instead rely +on another process being the monarch. + +This comes with a variety of other edge cases as well. + +When a process does re-open as an elevated window, it will need a mechanism to +retain its original ID as assigned by the monarch. This is so that commands like +`wt -s 2 split-pane` will continue to refer to the same logical window, even if +there's a new process hosting it now. + +What if there's only one window, and it becomes elevated? In that case, there is +no other monarch to rely on. We'll need a way for us to start `wt` as a +"headless monarch". This headless monarch process will _not_ display its own +window, but will act as the monarch. The old monarch (who's now a different +process altogether, and is elevated), should treat that medium-IL headless +monarch the same as the other monarchs, and attempt to find a new monarch as +soon as it goes away. The headless monarch will attempt to register to be the +monarch - if it turns out that another process is the current monarch, then the +headless monarch will immediately kill itself, causing the old monarch to +immediately attempt to find a new monarch. If the headless monarch dies +unexpectedly, and the elevated process is unable to create a connection to the +existing monarch, it'll need to spawn a new headless monarch. + +If there are only a bunch of elevated monarchs, then they'll each attempt to +spawn a headless monarch. Only one will succeed - the others will all connect to +the first headless monarch, and immediately die. + +We need to be especially careful about the commands that can be run in an +existing window. Opening a new tab, split, these are relatively safe. The new +terminal that's created in the elevated window will still be unelevated by +default. + +What we _absolutely cannot do_, under any circumstance, is allow for the sending +of input to another window across elevation boundary. I don't think it's +entirely out of the realm of possibility to add a `send-input` command to write +input to the terminal using the `SendInputAction`. However, we must absolutely +make sure that the input isn't allowed to cross the elevation boundary. To make +this easier, we should have the `send-input` command just fail if the targeted +window is both: +- Is elevated. +- Is not this window. Sending input within the same window seems like it would + be safe enough - you're already inside the airtight hatch. ## Implementation Plan -[TODO]: # TODO? Or just leave this in the PM2.0 spec? - This is a list of actionable tasks generated as described by this spec: -* [ ] Add support for `wt.exe` processes to be Monarchs and Peasants, and communicate that state between themselves. This task does not otherwise add any user-facing features, merely an architectural update. -* [ ] Add support for the `glomToLastWindow` setting as a boolean. Opening new WT windows will conditionally glom to existing windows. -* [ ] Add support for per-desktop `glomToLastWindow`, by adding the support for the enum values `"always"`, `"sameDesktop"` and `"never"`. +* [ ] Add support for `wt.exe` processes to be Monarchs and Peasants, and + communicate that state between themselves. This task does not otherwise add + any user-facing features, merely an architectural update. +* [ ] Add support for the `glomToLastWindow` setting as a boolean. Opening new + WT windows will conditionally glom to existing windows. +* [ ] Add support for per-desktop `glomToLastWindow`, by adding the support for + the enum values `"lastWindow"`, `"sameDesktop"` and `"never"`. +* [ ] Add support for `wt.exe` to pass commandlines intended for another window + to the monarch, then to the intended window, with the `--session,-s + session-id` commandline parameter. +* [ ] Add support for single instance mode, by adding the enum value `"always"` + to `"glomToLastWindow"` ## Footnotes -[1]: TODO +[1]: While tear-out is a separate track of work from +session management in general, this setting could be implemented along with this +set of features, and later used to control tear out as well. ## Future considerations [TODO]: # TODO -* During - [review](https://github.com/microsoft/terminal/pull/7240#issuecomment-716022646), - it was mentioned that when links are opened in the new Edge browser, they will - only glom onto an existing window if that window is open in the current - virtual desktop. This seems like a good idea of a feature for the Terminal to - follow as well. Since Edge is able to do it, there must be some way for an - application to determine which virtual desktop it is open on. We could use - that information to have the monarch track the last active window per-desktop, - and only glom when there's one on the current desktop. - - We could even imagine changing the `glomToLastWindow` property to accept a - combined `bool`/enum value: - - `true` or `"always"`: always glom to the most recent window, regardless of - desktop - - `"sameDesktop"`: Only glom if there's an existing window on this virtual - desktop, otherwise create a new window - - `false` or `"never"`: Never glom, always create a new window. - +* Pipe a command to a pane in an existing window? + ```sh + man ping > wt -s 0 split-pane cat + ``` + Is there some way for WT to pass it's stdin/out handles to the child process it's creting? This is _not_ related to the current spec at hand, just something the author considered while writing the spec. This likely belongs over in [#492]. ## Resources @@ -461,4 +473,4 @@ This is a list of actionable tasks generated as described by this spec: [`ISwapChainPanelNative2::SetSwapChainHandle`]: https://docs.microsoft.com/en-us/windows/win32/api/windows.ui.xaml.media.dxinterop/nf-windows-ui-xaml-media-dxinterop-iswapchainpanelnative2-setswapchainhandle -[Windows Terminal Process Model 2.0 Spec]: https://github.com/microsoft/terminal/blob/main/doc/specs/%235000%20-%20Process%20Model%202.0.md +[Process Model 2.0 Spec]: https://github.com/microsoft/terminal/blob/main/doc/specs/%235000%20-%20Process%20Model%202.0.md From cbe7f657562b00f921149670d721662f3036be5a Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Mon, 2 Nov 2020 14:26:08 -0600 Subject: [PATCH 23/39] ready for review --- ...2 - Windows Terminal Session Management.md | 53 ++++++++----------- .../#5000 - Process Model 2.0.md | 7 +++ 2 files changed, 28 insertions(+), 32 deletions(-) diff --git a/doc/specs/#5000 - Process Model 2.0/#4472 - Windows Terminal Session Management.md b/doc/specs/#5000 - Process Model 2.0/#4472 - Windows Terminal Session Management.md index 0dd59dca3a4..351c8a52ff0 100644 --- a/doc/specs/#5000 - Process Model 2.0/#4472 - Windows Terminal Session Management.md +++ b/doc/specs/#5000 - Process Model 2.0/#4472 - Windows Terminal Session Management.md @@ -15,7 +15,7 @@ window/content processes, as well as the introduction of monarch/peasant processes. The focus of that document was to identify solutions to a set of scenarios that were closely intertwined, and establish these solutions would work together, without preventing any one scenario from working. What that -docuement did not do was prescribe specific solutions to the given scenarios. +document did not do was prescribe specific solutions to the given scenarios. This document offers a deeper dive on a subset of the issues in [#5000], to describe specifics for managing multiple windows with the Windows Terminal. This @@ -64,9 +64,6 @@ own window. ![auto-glom-wt-exe](auto-glom-wt-exe.png) -If glomming is disabled, then the Monarch will call back to the peasant and tell -it to run the provided commandline. - If glomming is enabled, the monarch will dispatch the commandline to the appropriate window for them to handle instead. To the user, it'll seem as if the tab just opened in the most recent window. @@ -76,16 +73,10 @@ onto the MRU window or not. You could imagine that currently, we default to the hypothetical value `"glomToLastWindow": false`, meaning that each new wt gets it's own new window. -[TODO]: # todo - -Make sure to discuss that when the monarch determines that a new `wt` instance -actually _should_ host the new terminal, it can reply back to it appropriately. -Does that mean the Peasant has to be created, and registered with the monarch, -first? Or can the Monarch reply, "No, you can take care of this", which _then_ -causes the WT process to create and register the peasant? - -[/TODO]: # todo - +If glomming is disabled, then the Monarch will call back to the peasant and tell +it to run the provided commandline. The monarch will use the return value of +`ExecuteCommandline` to indicate that the calling process should create a window +and become a peasant process, and run the commandline itself. #### Glomming within the same virtual desktop @@ -160,7 +151,8 @@ wt.exe --session N new-tab ; split-pane > `--window,-w window-id`, and mean the same thing. I leave it as an exercise > for the reviewers to pick one naming that they like best. -More formally, we'll add the following parameter to the top-level `wt` command: +More formally, we will add the following parameter to the top-level `wt` +command: #### `--session,-s session-id` Run these commands in the given Windows Terminal session. This enables opening @@ -205,8 +197,8 @@ one. #### Running commands in a new window:`wt --session -1` -If the user passes an invalid ID to the `--session` parameter, then we'll always -create a new window for that commandline, regardless of the value of +If the user passes an invalid ID to the `--session` parameter, then we will +always create a new window for that commandline, regardless of the value of `glomToLastWindow`. This will allow users to do something like `wt -s -1 new-tab` to _always_ create a new window. Since window IDs are only ever positive integers, then `-1` would be a convenient value for something that's @@ -261,7 +253,7 @@ the monarch. At this point, the monarch will determine that it is in Single Instance Mode, and consume the commands itself. Single instance mode is enabled with the `"glomToLastWindow": "always"` setting. -This value disables tab tearout[[1]](#footnote-1) , as well as the +This value disables tab tear out[[1]](#footnote-1) , as well as the ability for `newWindow` and `wt -s -1` to create new windows. In those cases, the commandline will _always_ be handled by the current window, the monarch window. @@ -316,14 +308,14 @@ elevation & Monarch / Peasant issues"](#mixed-elevation--monarch--peasant-issues @@ -349,62 +352,37 @@ communication between monarch and peasant processes. ## Potential Issues -### Mixed elevation & Monarch / Peasant issues - -_This section was originally authored in the [Process Model 2.0 Spec]. Please -refer to it there for its original context._ - -Previously, we have mentioned that windows who wish to have a tab open elevated -will re-open as an elevated process, connected to all the content processes the -window was previously connected to. However, what happens when the window that -needs to re-open as an elevated window is the monarch process? If the elevated -window were to retain its monarch status, then all the other (unelevated) window -processes would be unable to connect to it and call methods and trigger -callbacks on it. - -So if the monarch is going to enter a mixed-elevation state, the new process for -the elevated window shouldn't try to register as the monarch, and instead rely -on another process being the monarch. - -This comes with a variety of other edge cases as well. - -When a process does re-open as an elevated window, it will need a mechanism to -retain its original ID as assigned by the monarch. This is so that commands like -`wt -s 2 split-pane` will continue to refer to the same logical window, even if -there's a new process hosting it now. - -What if there's only one window, and it becomes elevated? In that case, there is -no other monarch to rely on. We will need a way for us to start `wt` as a -"headless monarch". This headless monarch process will _not_ display its own -window, but will act as the monarch. The old monarch (who's now a different -process altogether, and is elevated), should treat that medium-IL headless -monarch the same as the other monarchs, and attempt to find a new monarch as -soon as it goes away. The headless monarch will attempt to register to be the -monarch - if it turns out that another process is the current monarch, then the -headless monarch will immediately kill itself, causing the old monarch to -immediately attempt to find a new monarch. If the headless monarch dies -unexpectedly, and the elevated process is unable to create a connection to the -existing monarch, it'll need to spawn a new headless monarch. - -If there are only a bunch of elevated monarchs, then they will each attempt to -spawn a headless monarch. Only one will succeed - the others will all connect to -the first headless monarch, and immediately die. - -We need to be especially careful about the commands that can be run in an -existing window. Opening a new tab, split, these are relatively safe. The new -terminal that's created in the elevated window will still be unelevated by -default. - -What we _absolutely cannot do_, under any circumstance, is allow for the sending -of input to another window across elevation boundary. I don't think it's -entirely out of the realm of possibility to add a `send-input` command to write -input to the terminal using the `SendInputAction`. However, we must absolutely -make sure that the input isn't allowed to cross the elevation boundary. To make -this easier, we should have the `send-input` command just fail if the targeted -window is both: -- Is elevated. -- Is not this window. Sending input within the same window seems like it would - be safe enough - you're already inside the airtight hatch. +### Mixed Elevation Levels + +As of December 2020, we're no longer pursuing a "mixed-elevation" scenario for +the Terminal. This makes many of the cross-elevation scenarios simpler. Elevated +and unelevated `wt` instances will always remain separate. The different +elevation levels will maintain separate lists of window IDs. If the user is +running both an elevated and unelevated window, then there will be two monarchs. +One elevated, and the other unelevated. + +This does mean that single instance mode won't _really_ work for users in +mixed-elevation scenarios. There'll be a monarch for the unelevated window, and +a separatemonarch for the elevated one. This is acceptable, given the assumption +that windows cannot mix elevation levels. + +There will also be some edge cases when handling the commandline that will need +special care. Say the user wanted to open a new tab in the elevated window, from +and unelevated `explorer.exe`. That would be a commandline like: + +```sh +wt -s 0 new-tab -d . --elevated +``` + +Typically we first determine which window the commandline is intended for, then +dispatch it to that window. In this case, the `-s 0` will cause us to pass the +commandline to the current unelevated window. Then, that window will try to open +an elevated tab, fail, and create a new `wt.exe` process. This second `wt.exe` +process will lose the `-s 0` context. It won't inform the elevated monarch that +this commandline should be run in the active session. + +We will need to make sure that special care is taken when creating elevated +instances that we maintain the `--session-id` parameter passed to the Terminal. ## Implementation Plan @@ -439,6 +417,9 @@ set of features, and later used to control tear out as well. it's creating? This is _not_ related to the current spec at hand, just something the author considered while writing the spec. This likely belongs over in [#492], or in its own spec. + - Or I suppose, with less confusion, someone could run `wt -s 0 split-pane -- + man ping > cat`. That's certainly more sensible, and wouldn't require any + extra work. ## Resources From 94ebaad1696e4ad5f68e2f2e5287ec2de6aa7642 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Wed, 2 Dec 2020 10:37:10 -0600 Subject: [PATCH 30/39] Address some outstanding TODOs I had with this spec --- ...2 - Windows Terminal Session Management.md | 84 +++++++++++++++---- 1 file changed, 66 insertions(+), 18 deletions(-) diff --git a/doc/specs/#5000 - Process Model 2.0/#4472 - Windows Terminal Session Management.md b/doc/specs/#5000 - Process Model 2.0/#4472 - Windows Terminal Session Management.md index 3696cb66f6c..ed1c6ea2299 100644 --- a/doc/specs/#5000 - Process Model 2.0/#4472 - Windows Terminal Session Management.md +++ b/doc/specs/#5000 - Process Model 2.0/#4472 - Windows Terminal Session Management.md @@ -64,9 +64,9 @@ own window. ![auto-glom-wt-exe](auto-glom-wt-exe.png) -If glomming is enabled, the monarch will dispatch the -commandline to the appropriate window for them to handle instead. To the user, -it'll seem as if the tab just opened in the most recent window. +If glomming is enabled, the monarch will dispatch the commandline to the +appropriate window for them to handle instead. To the user, it'll seem as if the +tab just opened in the most recent window. Users should certainly be able to specify if they want new instances to glom onto the MRU window or not. You could imagine that currently, we default to the @@ -130,14 +130,13 @@ directory. ### Scenario: Run `wt` in the current window One often requested scenario is the ability to run a `wt.exe` commandline in the -current window, as opposed to always creating a new window. With the ability to -communicate between different window processes, one could imagine a logical -extension of this scenario being "run a `wt` commandline in _any_ given WT -window". +current window, as opposed to always creating a new window. Presume we have the +ability to communicate between different window processes. The logical extension +of this scenario would be "run a `wt` commandline in _any_ given WT window". -Since each window process will have it's own unique ID assigned to it by the -monarch, then running a command in a given window with ID `N` should be as easy -as something like: +Each window process will have it's own unique ID assigned to it by the monarch. +Running a command in a given window with ID N should be as easy as something +like: ```sh wt.exe --session N new-tab ; split-pane @@ -311,15 +310,15 @@ unelevated peasants connecting to the elevated Monarch, or vice-versa. @@ -384,6 +383,54 @@ this commandline should be run in the active session. We will need to make sure that special care is taken when creating elevated instances that we maintain the `--session-id` parameter passed to the Terminal. +### `wt` Startup Commandline Options + +There are a few commandline options which can be provided to `wt.exe` which +don't make sense to pass to another session. These options include (but are not +limited to): + +* `--initialSize r,c` +* `--initialPosition x,y` +* `--fullscreen`, `--maximized`, etc. + +When we're passing a commandline to another instance to handle, these arguments +will be ignored. they only apply to the initial creation of a window. +`--initialSize 32, 120` doesn't make sense if the window already has a size. + +On startup of a new window, we currently assume that the first command is always +`new-tab`. When passing commandlines to existing windows, we won't need to make +that assumption anymore. There will already be existing tabs. + +### Monarch MRU Window Tracking + +As stated above, the monarch is responsible for tracking the MRU window stack. +However, when the monarch is closed, this state will be lost. The new monarch +will be elected, but it will be unable to ask the old monarch for the MRU +order of the windows. + +We had previously considered an _acceptable_ UX when this would occur. We would +randomize the order (with the new monarch becoming the MRU window). If someone +noticed this bug and complained, then we had a theoretical solution prepared. +The peasants could inform not only the monarch, but _all other peasants_ when +they become activated. This would mean all peasants are simultaneously tracking +the MRU stack. This would mean that any given peasant would be prepared always +to become the monarch. + +A simpler solution though would be to not track the MRU stack in the Monarch at +all. Instead, each peasant could just track internally when they were last +activated. The Monarch wouldn't track any state itself. It would be distributed +across all the peasants. The Monarch could then iterate over the list of +peasants and find the one with the newest `LastActivated` timestamp. + +Now, when a Monarch dies, the new Peasant doesn't have to come up with the stack +itself. All the other Peasants keep their state. The new Monarch can query them +and get the same answer the old Monarch would have. + +We could further optimize this by having the Monarch also track the stack. Then, +the monarch could query the MRU window quickly. The `LastActivated` timestamps +would only be used by a new Monarch when it is elected, to reconstruct the MRU +stack. + ## Implementation Plan This is a list of actionable tasks generated as described by this spec: @@ -420,6 +467,7 @@ set of features, and later used to control tear out as well. - Or I suppose, with less confusion, someone could run `wt -s 0 split-pane -- man ping > cat`. That's certainly more sensible, and wouldn't require any extra work. +* ## Resources From 2a941f16801b149e3d8758ee4d88e38585617bfb Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Wed, 2 Dec 2020 11:09:31 -0600 Subject: [PATCH 31/39] spel --- .github/actions/spell-check/expect/expect.txt | 1 + .../#4472 - Windows Terminal Session Management.md | 12 ++++++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.github/actions/spell-check/expect/expect.txt b/.github/actions/spell-check/expect/expect.txt index 12536850574..5b8aa15d0a3 100644 --- a/.github/actions/spell-check/expect/expect.txt +++ b/.github/actions/spell-check/expect/expect.txt @@ -1872,6 +1872,7 @@ pythonw qi QJ qo +QOL qsort queryable QUESTIONMARK diff --git a/doc/specs/#5000 - Process Model 2.0/#4472 - Windows Terminal Session Management.md b/doc/specs/#5000 - Process Model 2.0/#4472 - Windows Terminal Session Management.md index ed1c6ea2299..4aead527097 100644 --- a/doc/specs/#5000 - Process Model 2.0/#4472 - Windows Terminal Session Management.md +++ b/doc/specs/#5000 - Process Model 2.0/#4472 - Windows Terminal Session Management.md @@ -1,7 +1,7 @@ --- author: Mike Griese @zadjii-msft created on: 2020-10-30 -last updated: 2020-11-02 +last updated: 2020-12-02 issue id: #4472 --- @@ -37,7 +37,7 @@ Spec]. As a quick summary: The Monarch is picked randomly from the Terminal windows, and there is only ever one Monarch process at a time. * Peasants can communicate with the monarch when certain state changes (such as - their window being activated), and the monarch can send commands to any of hte + their window being activated), and the monarch can send commands to any of the peasants. This architecture will be used to enable each of the following scenarios. @@ -157,9 +157,9 @@ command: Run these commands in the given Windows Terminal session. This enables opening new tabs, splits, etc. in already running Windows Terminal windows. * If `session-id` is `0`, run the given commands in _the current window_ -* If `session-id` is not the ID of any exsiting window, then run the commands in +* If `session-id` is not the ID of any existing window, then run the commands in a _new_ Terminal window. -* If `session-id` is ommitted, then obey the value of `glomToLastWindow` when +* If `session-id` is omitted, then obey the value of `glomToLastWindow` when determining which window to run the command in. _Whenever_ `wt.exe` is started, it must _always_ pass the provided commandline @@ -362,8 +362,8 @@ One elevated, and the other unelevated. This does mean that single instance mode won't _really_ work for users in mixed-elevation scenarios. There'll be a monarch for the unelevated window, and -a separatemonarch for the elevated one. This is acceptable, given the assumption -that windows cannot mix elevation levels. +a separate monarch for the elevated one. This is acceptable, given the +assumption that windows cannot mix elevation levels. There will also be some edge cases when handling the commandline that will need special care. Say the user wanted to open a new tab in the elevated window, from From 527685855f11f084c0d3294f3f5c6d7be632f4ed Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Tue, 8 Dec 2020 17:07:10 -0600 Subject: [PATCH 32/39] lots of discussion notes --- ...2 - Windows Terminal Session Management.md | 196 ++++++++++-------- 1 file changed, 114 insertions(+), 82 deletions(-) diff --git a/doc/specs/#5000 - Process Model 2.0/#4472 - Windows Terminal Session Management.md b/doc/specs/#5000 - Process Model 2.0/#4472 - Windows Terminal Session Management.md index 4aead527097..d46bc075352 100644 --- a/doc/specs/#5000 - Process Model 2.0/#4472 - Windows Terminal Session Management.md +++ b/doc/specs/#5000 - Process Model 2.0/#4472 - Windows Terminal Session Management.md @@ -1,7 +1,7 @@ --- author: Mike Griese @zadjii-msft created on: 2020-10-30 -last updated: 2020-12-02 +last updated: 2020-12-08 issue id: #4472 --- @@ -135,31 +135,32 @@ ability to communicate between different window processes. The logical extension of this scenario would be "run a `wt` commandline in _any_ given WT window". Each window process will have it's own unique ID assigned to it by the monarch. -Running a command in a given window with ID N should be as easy as something -like: +This ID will be a positive number. Windows can also have names assigned to them. +These names are strings that the user specifies. A window will always have an +ID, but not necessarily a name. Running a command in a given window with ID N +should be as easy as something like: ```sh -wt.exe --session N new-tab ; split-pane +wt.exe --window N new-tab ; split-pane ``` -(or for shorthand, `wt -s N new-tab ; split-pane`). - -> ❗ TODO for discussion: In the remainder of this spec, I'll continue to use the -> parameters `--session,-s session-id` as the parameter to identify the window -> that a command should be run in. These arguments could just as easily be -> `--window,-w window-id`, and mean the same thing. I leave it as an exercise -> for the reviewers to pick one naming that they like best. +(or for shorthand, `wt -w N new-tab ; split-pane`). More formally, we will add the following parameter to the top-level `wt` command: -#### `--session,-s session-id` +#### `--window,-w window-id` Run these commands in the given Windows Terminal session. This enables opening new tabs, splits, etc. in already running Windows Terminal windows. -* If `session-id` is `0`, run the given commands in _the current window_ -* If `session-id` is not the ID of any existing window, then run the commands in - a _new_ Terminal window. -* If `session-id` is omitted, then obey the value of `glomToLastWindow` when +* If `window-id` is `0`, run the given commands in _the current window_ +* If `window-id` is a negative number, or the reserved name `new`, run the + commands in a _new_ Terminal window. +* If `window-id` is the ID or name of an existing window, then run the + commandline in that window. +* If `window-id` is _not_ the ID or name of an existing window, create a new + window. That window will be assigned the ID or name provided in the + commandline. The provided subcommands will be run in that new window. +* If `window-id` is omitted, then obey the value of `glomToLastWindow` when determining which window to run the command in. _Whenever_ `wt.exe` is started, it must _always_ pass the provided commandline @@ -168,44 +169,42 @@ scenarios (as noted above). The monarch will parse the commandline, determine which window the commandline is destined for, then call `ExecuteCommandline` on that peasant, who will then run the command. -#### Running commands in the current window:`wt --session 0` +#### Running commands in the current window:`wt --window 0` -If `wt -s 0 ` is run _outside_ a WT instance, it could attempt to glom +If `wt -w 0 ` is run _outside_ a WT instance, it could attempt to glom onto _the most recent WT window_ instead. This seems more logical than something -like `wt --session last` or some other special value indicating "run this in the -MRU window". +like `wt --window last` or some other special value indicating "run this in the +MRU window".[[2]](#footnote-2) That might be a simple, but **wrong**, implementation for "the current window". If the peasants always raise an event when their window is focused, and the monarch keeps track of the MRU order for peasants, then one could naively assume -that the execution of `wt -s 0 ` would always return the window the +that the execution of `wt -w 0 ` would always return the window the user was typing in, the current one. However, if someone were to do something -like `sleep 10 ; wt -s 0 `, then the user could easily focus another +like `sleep 10 ; wt -w 0 `, then the user could easily focus another WT window during the sleep, which would cause the MRU window to not be the same as the window executing the command. -I'm not sure that there is a better solution for the `-s 0` scenario other than +I'm not sure that there is a better solution for the `-w 0` scenario other than attempting to use the `WT_SESSION` environment variable. If a `wt.exe` process is spawned and that's in it's environment variables, it could try and ask the monarch for the peasant who's hosting the session corresponding to that GUID. This is more of a theoretical solution than anything else. -In Single-Instance mode, running `wt -s 0` outside a WT window will still cause +In Single-Instance mode, running `wt -w 0` outside a WT window will still cause the commandline to glom to the existing single terminal instance, if there is one. -#### Running commands in a new window:`wt --session -1` +#### Running commands in a new window:`wt --window -1` / `wt --window new` -If the user passes an invalid ID to the `--session` parameter, then we will -always create a new window for that commandline, regardless of the value of -`glomToLastWindow`. This will allow users to do something like `wt -s -1 -new-tab` to _always_ create a new window. Since window IDs are only ever -positive integers, then `-1` would be a convenient value for something that's -_never_ an existing window ID. +If the user passes a negative number, or the reserved name `new` to the +`--window` parameter, then we will always create a new window for that +commandline, regardless of the value of `glomToLastWindow`. This will allow +users to do something like `wt -w -1 new-tab` to _always_ create a new window. -#### `--session` in subcommands +#### `--window` in subcommands -The `--session` parameter is a setting to `wt.exe` itself, not to one of its +The `--window` parameter is a setting to `wt.exe` itself, not to one of its subcommands (like `new-tab` or `split-pane`). This means that all of the subcommands in a particular `wt` commandline will all be handled by the same session. For example, let us consider a user who wants to open a new tab in @@ -213,14 +212,14 @@ window 2, and split a new pane in window 3, all at once. The user _cannot_ do something like: ```cmd -wt -s 2 new-tab ; -s 3 split-pane +wt -w 2 new-tab ; -w 3 split-pane ``` Instead, the user will need to separate the commands (by whatever their shell's own command delimiter is) and run two different `wt.exe` instances: ```cmd -wt -s 2 new-tab & wt -s 3 split-pane +wt -w 2 new-tab & wt -w 3 split-pane ``` This is done to make the parsing of the subcommands easier, and for the internal @@ -236,26 +235,18 @@ source to dispatch the next part of the commandline. Overall, this is seen as unnecessarily complex, and dispatching whole sets of commands as a simpler solution. -### Scenario: Single Instance Mode - -"Single Instance Mode" is a scenario in which there is only ever one single WT -window. A user might want this functionality to only ever allow a single -terminal window to be open on their desktop. This is especially frequently -requested in combination with "quake mode", as discussed in -[#653]. When Single Instance Mode is active, and the user -runs a new `wt.exe` commandline, it will always end up running in the existing -window, if there is one. +### Naming Windows -In "Single Instance Mode", the monarch _is_ the single instance. When `wt` is -run, and it determines that it is not the monarch, it'll pass the commandline to -the monarch. At this point, the monarch will determine that it is in Single -Instance Mode, and consume the commands itself. +It's not user-friendly to rely on automatically generated, invisible numbers to +identify windows. There's not a great way of identifying which window is which. +The user would need to track the IDs in their head manually. Instead, we'll +allow the user to provide a string name for the window. This name can be used to +address a window in addition to the ID. -Single instance mode is enabled with the `"glomToLastWindow": "always"` setting. -This value disables tab tear out[[1]](#footnote-1) , as well as the -ability for `newWindow` and `wt -s -1` to create new windows. In those cases, -the commandline will _always_ be handled by the current window, the monarch -window. +Names can be provided on the commandline, in the original commandline. For +example, `wt -w foo nt` would name the new window "foo". Names can also be set +with a new action, `NameWindow`. `name-window` could also be used as a +subcommand. For example, `wt -w 4 name-window bar` would name window 4 "bar". ## UI/UX Design @@ -264,22 +255,17 @@ window. The following list gives greater breakdown of the values of `glomToLastWindow`, and how they operate: -* `"glomToLastWindow": "lastWindow", "sameDesktop"|true`: Browser-like glomming +* `"glomToLastWindow": "lastWindow", "sameDesktop"|true`: **Browser-like glomming** - New instances open in the current window by default. - `newWindow` opens a new window. - Tabs can be torn out to create new windows. - - `wt -s -1` opens a new window. -* `"glomToLastWindow": "always"`: Single Instance Mode. - - New instances open in the current window by default. - - `newWindow` opens in the existing window. - - Tabs cannot be torn out to create new windows. - - `wt -s -1` opens in the existing window. -* `"glomToLastWindow": "never"`: No auto-glomming. This is the current behavior + - `wt -w -1` opens a new window. +* `"glomToLastWindow": "never"|false`: No auto-glomming. This is **the current behavior** of the Terminal. - New instances open in new windows by default - `newWindow` opens a new window - Tabs can be torn out to create new windows. - - `wt -s -1` opens a new window. + - `wt -w -1` opens a new window. ## Concerns @@ -327,14 +313,23 @@ occur easier. @@ -370,18 +365,18 @@ special care. Say the user wanted to open a new tab in the elevated window, from and unelevated `explorer.exe`. That would be a commandline like: ```sh -wt -s 0 new-tab -d . --elevated +wt -w 0 new-tab -d . --elevated ``` Typically we first determine which window the commandline is intended for, then -dispatch it to that window. In this case, the `-s 0` will cause us to pass the +dispatch it to that window. In this case, the `-w 0` will cause us to pass the commandline to the current unelevated window. Then, that window will try to open an elevated tab, fail, and create a new `wt.exe` process. This second `wt.exe` -process will lose the `-s 0` context. It won't inform the elevated monarch that +process will lose the `-w 0` context. It won't inform the elevated monarch that this commandline should be run in the active session. We will need to make sure that special care is taken when creating elevated -instances that we maintain the `--session-id` parameter passed to the Terminal. +instances that we maintain the `--window` parameter passed to the Terminal. ### `wt` Startup Commandline Options @@ -443,31 +438,68 @@ This is a list of actionable tasks generated as described by this spec: * [ ] Add support for per-desktop `glomToLastWindow`, by adding the support for the enum values `"lastWindow"`, `"sameDesktop"` and `"never"`. * [ ] Add support for `wt.exe` to pass commandlines intended for another window - to the monarch, then to the intended window, with the `--session,-s - session-id` commandline parameter. -* [ ] Add support for single instance mode, by adding the enum value `"always"` - to `"glomToLastWindow"` - -## Footnotes - -[1]: While tear-out is a separate track of work from -session management in general, this setting could be implemented along with this -set of features, and later used to control tear out as well. + to the monarch, then to the intended window, with the `--window,-w + window-id` commandline parameter. +* [ ] Add support for targeting and naming windows via the `-w` parameter on the + commandline +* [ ] Add a `NameWindow` action, subcommand that allows the user to set the name + for the window. +* [ ] Add an action that will cause all windows to breifly display a overlay + with the current window ID and name ## Future considerations * What if the user wanted to pipe a command to a pane in an existing window? ```sh - man ping > wt -s 0 split-pane cat + man ping > wt -w 0 split-pane cat ``` Is there some way for WT to pass it's stdin/out handles to the child process it's creating? This is _not_ related to the current spec at hand, just something the author considered while writing the spec. This likely belongs over in [#492], or in its own spec. - - Or I suppose, with less confusion, someone could run `wt -s 0 split-pane -- + - Or I suppose, with less confusion, someone could run `wt -w 0 split-pane -- man ping > cat`. That's certainly more sensible, and wouldn't require any extra work. -* +* "Single Instance Mode" is a scenario in which there is only ever one single WT + window. A user might want this functionality to only ever allow a single + terminal window to be open on their desktop. This is especially frequently + requested in combination with "quake mode", as discussed in [#653]. When Single + Instance Mode is active, and the user runs a new `wt.exe` commandline, it will + always end up running in the existing window, if there is one. + + An earlier version of this spec proposed a new value of `glomToLastWindow`. The + `always` value would disable tab tear out[[1]](#footnote-1). It would + additionally disable the `newWindow` action, and prevent `wt -w new` from + opening a new window. + + In discussion, it was concluded that this setting didn't make sense. Why did the + `glomToLastWindow` setting change the behavior of tear out? Single Instance Mode + is most frequently requested in regards to quake mode. We're leaving the + implementation of true single instance mode to that spec. +* It was suggested in review that we could auto-generate names for windows, from + some list of words. Prior art could be the URLS for gyfcat.com, which use + three random words. I believe `docker` also assigns names from a random + selection of `adjective`+`name`. This is an interesting idea, and something + that could be pursued in the future. +* We will _need_ to provide a commandline tool to list windows and their IDs & + names. We're thinking a list of windows, their IDs, names, PIDs, and the title + of the window. + + Currently we're stuck with `wt.exe` which is a GUI application, and cannot + print to the console. Our need is now fairly high for the ability to print + info to the console. To remedy this, we'll need to ship another helper exe as + a commandline tool for working with the terminal. The design for this is left + for the future. + +## Footnotes + +[1]: While tear-out is a separate track of work from +session management in general, this setting could be implemented along with this +set of features, and later used to control tear out as well. + +[2]: Since we're reserving the keyword `new` to mean "a +new window", then we could also reserve `last` or `current` as an alias for "the +current window". ## Resources From 71be82aaf4b3bd6c0bac296f5051ead2f078832d Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Wed, 9 Dec 2020 07:23:16 -0600 Subject: [PATCH 33/39] the last bits of our discussion Tuesday --- ...2 - Windows Terminal Session Management.md | 62 ++++++++++--------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/doc/specs/#5000 - Process Model 2.0/#4472 - Windows Terminal Session Management.md b/doc/specs/#5000 - Process Model 2.0/#4472 - Windows Terminal Session Management.md index d46bc075352..27f77e866f5 100644 --- a/doc/specs/#5000 - Process Model 2.0/#4472 - Windows Terminal Session Management.md +++ b/doc/specs/#5000 - Process Model 2.0/#4472 - Windows Terminal Session Management.md @@ -1,7 +1,7 @@ --- author: Mike Griese @zadjii-msft created on: 2020-10-30 -last updated: 2020-12-08 +last updated: 2020-12-09 issue id: #4472 --- @@ -70,7 +70,7 @@ tab just opened in the most recent window. Users should certainly be able to specify if they want new instances to glom onto the MRU window or not. You could imagine that currently, we default to the -hypothetical value `"glomToLastWindow": false`, meaning that each new wt gets +hypothetical value `"windowingBehavior": "useNew"`, meaning that each new wt gets it's own new window. If glomming is disabled, then the Monarch will call back to the peasant and tell @@ -89,19 +89,15 @@ is open on. We could use that information to have the monarch track the last active window _per-desktop_, and only glom when there's one on the current desktop. -We could make the `glomToLastWindow` property even more powerful by accepting a -combined `bool`/enum value: -- `"always"`: always glom to the most recent window, regardless of desktop. This - also suppresses the creation of new windows, including tearing out tabs, or - windows created by `newWindow` actions. See [Single Instance - Mode](#scenario-single-instance-mode) for more details. -- `"lastWindow"`: always glom to the most recent window, regardless of - desktop. -- `true` or `"sameDesktop"`: Only glom if there's an existing window on this +We could make the `windowingBehavior` property accept a variety of +configurations: + +- `"useExisting"`: always glom to the most recent window, regardless of desktop. +- `"useExistingOnSameDesktop"`: Only glom if there's an existing window on this virtual desktop, otherwise create a new window. This will be the new default value. -- `false` or `"never"`: Never glom, always create a new window. This is - technically the current behavior of the Terminal. +- `"useNew"`: Never glom, always create a new window. This is technically the + current behavior of the Terminal. ### Handling the current working directory @@ -223,7 +219,7 @@ wt -w 2 new-tab & wt -w 3 split-pane ``` This is done to make the parsing of the subcommands easier, and for the internal -passing of arguments simpler. If the `--session` parameter were a part of each +passing of arguments simpler. If the `--window` parameter were a part of each subcommand, then each individual subcommand's parser would need to be enlightened about that parameter, and then it would need to be possible for any single part of the commandline to call out to another process. It would be @@ -250,23 +246,28 @@ subcommand. For example, `wt -w 4 name-window bar` would name window 4 "bar". ## UI/UX Design -### `glomToLastWindow` details +### `windowingBehavior` details -The following list gives greater breakdown of the values of `glomToLastWindow`, +The following list gives greater breakdown of the values of `windowingBehavior`, and how they operate: -* `"glomToLastWindow": "lastWindow", "sameDesktop"|true`: **Browser-like glomming** +* `"windowingBehavior": "useExisting", "useExistingOnSameDesktop"`: + **Browser-like glomming** - New instances open in the current window by default. - `newWindow` opens a new window. - Tabs can be torn out to create new windows. - `wt -w -1` opens a new window. -* `"glomToLastWindow": "never"|false`: No auto-glomming. This is **the current behavior** - of the Terminal. +* `"windowingBehavior": "useNew"`: No auto-glomming. This is **the current + behavior** of the Terminal. - New instances open in new windows by default - `newWindow` opens a new window - Tabs can be torn out to create new windows. - `wt -w -1` opens a new window. +We'll be changing the default behavior from `useNew` to +`useExistingOnSameDesktop`. This will be more consistent with other tabbed +applications. + ## Concerns
Accessibility -[TODO]: # TODO +There is no expected accessibility impact from this feature. Each window will +handle UIA access as it normally does.
Security -[TODO]: # TODO +Many security concerns have already be covered in greater detail in the parent +spec, [Process Model 2.0 Spec]. I'd refer specifically to the section ["Mixed +elevation & Monarch / Peasant issues"](#mixed-elevation--monarch--peasant-issues). +
Reliability -[TODO]: # TODO +Whenever we're working with an object that's hosted by another process, we'll +need to make sure that we work with it in a try/catch, because at _any_ time, +the other process could be killed. At any point, a window process could be +killed. Both the monarch and peasant code will need to be redundant to such a +scenario, and if the other process is killed, make sure to display an +appropriate error and either recover or exit gracefully. + +In any and all of these situations, we'll want to try and be as verbose as +possible in the logging, to try and make tracking which process had the error +occur easier.
Compatibility -[TODO]: # TODO +There are not any serious comptibility concerns with this specific set of +features. + +We will be changing the default behavior of the Terminal to auto-glom to the +most-recently used window on the same desktop in the course of this work, which +will be a breaking UX change. This is behavior that can be reverted with the +`"glomToLastWindow": "never"` setting.
Performance, Power, and Efficiency -[TODO]: # TODO +There's no dramatic change expected here. There may be a minor delay in the +spawning of new terminal instances, due to requiring cross-process hops for the +communication between monarch and peasant processes.
Reliability -Whenever we're working with an object that's hosted by another process, we'll +Whenever we are working with an object that's hosted by another process, we will need to make sure that we work with it in a try/catch, because at _any_ time, the other process could be killed. At any point, a window process could be killed. Both the monarch and peasant code will need to be redundant to such a scenario, and if the other process is killed, make sure to display an appropriate error and either recover or exit gracefully. -In any and all of these situations, we'll want to try and be as verbose as +In any and all of these situations, we will want to try and be as verbose as possible in the logging, to try and make tracking which process had the error occur easier. @@ -333,7 +325,7 @@ occur easier. Compatibility -There are not any serious comptibility concerns with this specific set of +There are not any serious compatibility concerns with this specific set of features. We will be changing the default behavior of the Terminal to auto-glom to the @@ -362,7 +354,7 @@ communication between monarch and peasant processes. _This section was originally authored in the [Process Model 2.0 Spec]. Please refer to it there for its original context._ -Previously, we've mentioned that windows who wish to have a tab open elevated +Previously, we have mentioned that windows who wish to have a tab open elevated will re-open as an elevated process, connected to all the content processes the window was previously connected to. However, what happens when the window that needs to re-open as an elevated window is the monarch process? If the elevated @@ -382,7 +374,7 @@ retain its original ID as assigned by the monarch. This is so that commands like there's a new process hosting it now. What if there's only one window, and it becomes elevated? In that case, there is -no other monarch to rely on. We'll need a way for us to start `wt` as a +no other monarch to rely on. We will need a way for us to start `wt` as a "headless monarch". This headless monarch process will _not_ display its own window, but will act as the monarch. The old monarch (who's now a different process altogether, and is elevated), should treat that medium-IL headless @@ -394,7 +386,7 @@ immediately attempt to find a new monarch. If the headless monarch dies unexpectedly, and the elevated process is unable to create a connection to the existing monarch, it'll need to spawn a new headless monarch. -If there are only a bunch of elevated monarchs, then they'll each attempt to +If there are only a bunch of elevated monarchs, then they will each attempt to spawn a headless monarch. Only one will succeed - the others will all connect to the first headless monarch, and immediately die. @@ -439,14 +431,14 @@ set of features, and later used to control tear out as well. ## Future considerations - -[TODO]: # TODO - -* Pipe a command to a pane in an existing window? +* What if the user wanted to pipe a command to a pane in an existing window? ```sh man ping > wt -s 0 split-pane cat ``` - Is there some way for WT to pass it's stdin/out handles to the child process it's creting? This is _not_ related to the current spec at hand, just something the author considered while writing the spec. This likely belongs over in [#492]. + Is there some way for WT to pass it's stdin/out handles to the child process + it's creating? This is _not_ related to the current spec at hand, just + something the author considered while writing the spec. This likely belongs + over in [#492], or in its own spec. ## Resources @@ -467,10 +459,7 @@ set of features, and later used to control tear out as well. [#7972]: https://github.com/microsoft/terminal/pull/7972 [#961]: https://github.com/microsoft/terminal/issues/961 [`30b8335`]: https://github.com/microsoft/terminal/commit/30b833547928d6dcbf88d49df0dbd5b3f6a7c879 - [Tab Tear-out in the community toolkit]: https://github.com/windows-toolkit/Sample-TabView-TearOff [Quake mode scenarios]: https://github.com/microsoft/terminal/issues/653#issuecomment-661370107 [`ISwapChainPanelNative2::SetSwapChainHandle`]: https://docs.microsoft.com/en-us/windows/win32/api/windows.ui.xaml.media.dxinterop/nf-windows-ui-xaml-media-dxinterop-iswapchainpanelnative2-setswapchainhandle - - [Process Model 2.0 Spec]: https://github.com/microsoft/terminal/blob/main/doc/specs/%235000%20-%20Process%20Model%202.0.md diff --git a/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md b/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md index d4b1806b21c..5e20b857b08 100644 --- a/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md +++ b/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md @@ -1228,6 +1228,13 @@ prompt the user for permission, but that's an acceptable user experience. * [ ] Make sure I can pass the UiaProvider for the control core out to the Window Process, so the window process can use it to query buffer info. +## Addenda + +This spec also has a follow-up spec which introduces further changes upon this +original draft. Please also refer to: + +* Novermber 2020: Windows Terminal Session Management + ## Resources * [Tab Tear-out in the community toolkit] - this document proved invaluable to From 09eef6cb2c305a4aa910e095d83f73a93aca53e4 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Mon, 2 Nov 2020 14:32:46 -0600 Subject: [PATCH 24/39] good bot --- .../#5000 - Process Model 2.0/#5000 - Process Model 2.0.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md b/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md index 5e20b857b08..0e5cf8e3549 100644 --- a/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md +++ b/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md @@ -1233,7 +1233,7 @@ prompt the user for permission, but that's an acceptable user experience. This spec also has a follow-up spec which introduces further changes upon this original draft. Please also refer to: -* Novermber 2020: Windows Terminal Session Management +* November 2020: Windows Terminal Session Management ## Resources From ef4001ecdba682f2a2874a8aa6c51c338c525376 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Fri, 20 Nov 2020 17:09:54 -0600 Subject: [PATCH 25/39] Some doc updates regarding M/E --- .../#5000 - Process Model 2.0.md | 260 +++++++----------- 1 file changed, 107 insertions(+), 153 deletions(-) diff --git a/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md b/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md index d4b1806b21c..24afa3c1104 100644 --- a/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md +++ b/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md @@ -1,7 +1,7 @@ --- author: Mike Griese @zadjii-msft created on: 2020-07-31 -last updated: 2020-10-30 +last updated: 2020-11-20 issue id: #5000 --- @@ -23,38 +23,29 @@ following scenarios: * Run `wt` in the current window ([#4472]) * Single Instance Mode ([#2227]) * Quake Mode ([#653]) -* Mixed Elevation ([#1032] & [#632]) + +Also discussed as a part of this spec is the "mixed elevation" ([#1032] & +[#632]) scenario, which is closely related to the above scenarios, and was +investigated as a part of this re-architecture. ## Inspiration -Much of the design for this feature was inspired by (what I believe is) the web -browser process model. For a web browser, there's often a separate process for -each of the tabs within the browser, to help isolate the actual tabs from one -another. +Much of the design for this feature was inspired by an older web browser process +model. For a time, web browsers, would use a separate process for each of the +tabs within the browser, to help isolate the actual tabs from one another. +(Nowadays, browsers will have multiple tabs all hosted in a single process, to +attempt to reuse some resources between tabs. They do still break out the tab +content from the actual window's process). + +Aditionally, the rxvt-unicode terminal emulator uses a similar client/server +architecture, where the terminal "content" is hosted by a server process, and +windows act as a "client" for that content. ## Background In order to better understand some of the following technical solutions, it's important to understand some of the technical hurdles that need to be overcome. -### Mixed admin and unelevated clients in a single window - -Let's presume that you're a user who wants to be able to open an elevated tab -within an otherwise unelevated Terminal window. We call this scenario "mixed -elevation" - the tabs within the Terminal can be running either unelevated _or_ -elevated client applications. - -It wouldn't be terribly difficult for the unelevated Terminal to request the -permission of the user to spawn an elevated client application. The user would -see a UAC prompt, they'd accept, and then they'd be able to have an elevated -shell alongside their unelevated tabs. - -However, this creates an escalation of privilege vector. Now, there's an -unelevated window which is connected directly to an elevated process. At this -point, any other unelevated application could send input to the Terminal's -`HWND`, making it possible for another unelevated process to "drive" the -Terminal window and send commands to the elevated client application. - ### Drag and drop tabs to create new windows Another important scenario we're targeting is the ability to drag a tab out of @@ -85,6 +76,24 @@ extremely fragile, if not impossible to do robustly. What we need is a more effective way for separate Terminal windows to to be able to connect to and display content that's being hosted in another process. +### Mixed admin and unelevated clients in a single window + +Let's presume that you're a user who wants to be able to open an elevated tab +within an otherwise unelevated Terminal window. We call this scenario "mixed +elevation" - the tabs within the Terminal can be running either unelevated _or_ +elevated client applications. + +It wouldn't be terribly difficult for the unelevated Terminal to request the +permission of the user to spawn an elevated client application. The user would +see a UAC prompt, they'd accept, and then they'd be able to have an elevated +shell alongside their unelevated tabs. + +However, this creates an escalation of privilege vector. Now, there's an +unelevated window which is connected directly to an elevated process. At this +point, any other unelevated application could send input to the Terminal's +`HWND`, making it possible for another unelevated process to "drive" the +Terminal window and send commands to the elevated client application. + ## Solution Design ### Window and Content Processes @@ -208,12 +217,6 @@ which would allow us to easily pass the `HANDLE` between these processes. Instead we'll need to manually cast the `HANDLE` to `uint64_t` at the winRT boundary, and cast it back to a `HANDLE` when we want to use it. -We can't just have the content process duplicate the handle to the window -process directly. If the content process is unelevated, and the window process -is elevated (in a mixed elevation scenario), then the content process won't have -permission to `DuplicateHandle` the `HANDLE` to the swapchain into the window's -process. (more on mixed elevation below). - Instead, the window will always need to be the one responsible for calling `DuplicateHandle`. Fortunately, the `DuplicateHandle` function does allow a caller to duplicate from another process into your own process. @@ -250,6 +253,11 @@ The terminal buffer never needs to move from one process to another - it always stays in just a single content process. The only thing that changes is the window process which is rendering the content process's swapchain. +When a new window is created from a torn-out tab in this manner, we will want to +ensure that the created window maintains the same maximized state as the origin +window. If the user tries to tera out a tab from a maximized window, the window +we create should _also_ be maximized. + Similar to dragging a tab from one window to another window, we can also detect when the tab was dropped somewhere outside the bounds of a tab strip. When that happens, we'll create a new WT window, and use the data package from the @@ -265,63 +273,57 @@ it. #### Scenario: Mixed Elevation -With the ability for window processes to connect to other pre-existing content -processes, we can now also support mixed elevation scenarios as well. - -If a user requests a new elevated tab from an otherwise unelevated window, we -can use UAC to create a new, elevated window process, and "move" all the current -tabs to that window process, as well as the new elevated client. Now, the window -process is elevated, preventing it from input injection, but still contains all -the previously existing tabs. The original window process can now be discarded, -as the new elevated window process will pretend to be the original window. - -![mixed-elevation](mixed-elevation.png) - -We would probably want to provide some additional configuration options here as -well: -* Users will most likely want to be able to specify that a given profile should - always run elevated. - - We should also provide some argument to the `NewTerminalArgs` (used by the - `new-tab` and `split-pane` actions) to allow a user to elevate an otherwise - unelevated profile. -* We'll probably want to create new content processes in a medium-IL context by - default, unless the profile or launch args otherwise indicates launching - elevated. So a window process running elevated would still create unelevated - profiles by default. -* Currently, if a user launches the terminal as an administrator, then _all_ of - their tabs run elevated. We'll probably want to provide a similar - configuration as well. Maybe if a window process is initially launched as - elevated (rather than inheriting from an existing session), then it could - either: - - default all future connections it creates to elevated connections - - assume the _first_ tab (or all the terminals created by the startup - commandline) should be elevated, but then subsequent connections would - default to unelevated processes. - -It's a long-standing platform bug that you cannot use drag-and-drop in elevated -scenarios. This unfortunately means that elevated window processes will _not_ be -able to tear tabs out into their own windows. Even tabs that only contain -unelevated content processes in them will not be able to be torn out, because -the drag-and-drop service is fundamentally incapable of connecting to elevated -windows. - -We should probably have a discussion about what happens when the last elevated -content process in an elevated window process is closed. If an elevated window -process doesn't have any remaining elevated content processes, then it should be -able to revert to an unelevated window process. Should we do this? There's -likely some visual flickering that will happen as we re-create the new window -process, so maybe it would be unappealing to users. However, there's also the -negative side effect that come from elevated windows (the aforementioned lack of -drag/drop), so maybe users will want to return to the more permissive unelevated -window process. - -This is one section where unfortunately I don't have a working prototype yet. -From my research, an elevated process cannot simply `create_instance` a class -that's hosted by an unelevated process. However, after proposing this idea to -the broad C++/WinRT discussion alias, no one on that thread immediately shot -down the idea as being impossible or terrible from a security perspective, so I -believe that it _will_ be possible. We still need to do some research on the -actual mechanisms for some token impersonation. +It was initially theorized that this window/content model architecture would +also help enable "mixed elevation", where there are tabs running at different +integrity levels (read: elevated and unelevated) within the same terminal +window. However, after investigation and research, it has become apparent that +this scenario is not possible to do safely after all. There are numerous +technical difficulties involved, and each with their own security risks. At the +end of the day, the team wouldn't be comfortable shipping a mixed-elevation +solution, because there's simply no way for us to be confident that we haven't +introduced an escalation-of-privledge vector utilizing the Terminal. No matter +how small the attack surface might be, we wouldn't be confident that there are +_no_ vectors for an attack. + +For the time being we'll continue with the current model of having one window +for unelevated processes, and another for elevated windows. We can revisit mixed +elevation in the future if we can get the focus and attention from some security +experts that could back up a technical solution. + +Instead of supporting mixed elevation in a single window, we'll introduce a +number of new properties to profiles and various actions, to improve the user +experience of running elevated instances. These are detailed in the spec at +[TODO!](FILL THIS LINK IN!!!! !) + +Some things we considered during this investigation: + +* If a user requests a new elevated tab from an otherwise unelevated window, we + could use UAC to create a new, elevated window process, and "move" all the + current tabs to that window process, as well as the new elevated client. Now, + the window process would be elevated, preventing it from input injection, and + it would still contains all the previously existing tabs. The original window + process could now be discarded, as the new elevated window process will + pretend to be the original window. + - However, it is unfortunately not possible with COM to have an elevated + client attach to an unelevated server that's registered at runtime. Even in + a packaged environment, the OS will reject the attempt to `CoCreateInstance` + the content process object. this will prevent elevated windows from + re-connecting to unelevated client processes. + - We could theoretically build an RPC tunnel between content and window + processes, and use the RPC connection to marshal the content process to the + elevated window. However, then _we_ would need to be responsible for + securing access the the RPC endpoint, and we feel even less confident doing + that. + - Attempts were also made to use a window-broker-content architecture, with + the broker process having a static CLSID in the registry, and having the + window and content processes at mixed elevation levels `CoCreateInstance` + that broker. This however _also_ did not work across elevation levels. This + may be due to a lack of Packaged COM support for mixed elevation levels. + Even if this approach did end up working, we would still need to be + responsible for securing the elevated windows so that an unelevated attacker + couldn't hijack a content process and trigger unexepected code in the window + process. We didn't feel confident that we could properly secure this channel + either. ### Monarch and Peasant Processes @@ -928,69 +930,18 @@ spec. ### Mixed elevation & Monarch / Peasant issues -Previously, we've mentioned that windows who wish to have a tab open elevated -will re-open as an elevated process, connected to all the content processes the -window was previously connected to. However, what happens when the window that -needs to re-open as an elevated window is the monarch process? If the elevated -window were to retain its monarch status, then all the other (unelevated) window -processes would be unable to connect to it and call methods and trigger -callbacks on it. - -So if the monarch is going to enter a mixed-elevation state, the new process for -the elevated window shouldn't try to register as the monarch, and instead rely -on another process being the monarch. - -This comes with a variety of other edge cases as well. - -When a process does re-open as an elevated window, it will need a mechanism to -retain its original ID as assigned by the monarch. This is so that commands like -`wt -s 2 split-pane` will continue to refer to the same logical window, even if -there's a new process hosting it now. - -What if there's only one window, and it becomes elevated? In that case, there is -no other monarch to rely on. We'll need a way for us to start `wt` as a -"headless monarch". This headless monarch process will _not_ display its own -window, but will act as the monarch. The old monarch (who's now a different -process altogether, and is elevated), should treat that medium-IL headless -monarch the same as the other monarchs, and attempt to find a new monarch as -soon as it goes away. The headless monarch will attempt to register to be the -monarch - if it turns out that another process is the current monarch, then the -headless monarch will immediately kill itself, causing the old monarch to -immediately attempt to find a new monarch. If the headless monarch dies -unexpectedly, and the elevated process is unable to create a connection to the -existing monarch, it'll need to spawn a new headless monarch. - -If there are only a bunch of elevated monarchs, then they'll each attempt to -spawn a headless monarch. Only one will succeed - the others will all connect to -the first headless monarch, and immediately die. - -We need to be especially careful about the commands that can be run in an -existing window. Opening a new tab, split, these are relatively safe. The new -terminal that's created in the elevated window will still be unelevated by -default. - -What we _absolutely cannot do_, under any circumstance, is allow for the sending -of input to another window across elevation boundary. I don't think it's -entirely out of the realm of possibility to add a `send-input` command to write -input to the terminal using the `SendInputAction`. However, we must absolutely -make sure that the input isn't allowed to cross the elevation boundary. To make -this easier, we should have the `send-input` command just fail if the targeted -window is both: -- Is elevated. -- Is not this window. Sending input within the same window seems like it would - be safe enough - you're already inside the airtight hatch. - -### Duplicating `HANDLE`s from content process to elevated window process - -We can't just have the content process dupe the handle to the window process. If -the content process is unelevated, and the window process is elevated (in a -mixed elevation scenario), then the content process won't have permission to -`DuplicateHandle` the `HANDLE` to the swapchain into the window's process. - -Instead, the window will always need to be the one responsible for calling -duplicate handle. Fortunately, the `DuplicateHandle` function does allow a -caller to duplicate from another process into your own process. +Because we won't be able to `CoCreateInstance` across different elevation +levels, we won't be able to have elevated window processes communicate with +unelevated ones. This means that we'll end up having one monarch per elevation +level. This may end up a little confusing, as window IDs will be tracked +per-elevation level. That means there could be two different windows that share +the same ID - one elevated window, and one unelevated window. Only the windows +running at the same integrity level will be addressable via the commandline. +This might be a little confusing to the end user, but is seen as an acceptable +experience to the alternative of just completely disallowing running commands in +other elevated windows. If a user is running in an elevated window, they +probably will still want `wt -s 0 new-tab` to open in the current window. ### What happens to the content if the monarch dies unexpectedly? @@ -1128,9 +1079,10 @@ of each other. isn't already elevated. 18. (Dependent on 16, 17) Users can mark a profile as `"elevated": true`, to always force a new elevated window to be created for elevated profiles. -19. (Dependent on 18, 13) When a user creates an elevated profile, we'll - automatically create an elevated version of the current window, and move all - the current tabs to that new window. +19. (Dependent on 18) Add an `elevated` parameter to `NewTerminalArgs` that will + allow a newTab or splitPane action to use that value of `elevated`, rather + than the value from the profile. +20. Add a UAC shield to elevated terminal windows ## Footnotes @@ -1209,7 +1161,8 @@ prompt the user for permission, but that's an acceptable user experience. ## TODOs -* [ ] Experimentally prove that a elevated window can host an unelevated content +* [x] Experimentally prove that a elevated window can host an unelevated content + - Research proved the opposite actually. * [ ] Experimentally prove that I can toss content process IDs from one window to another - I don't have any doubt that this will work, but I want to have a @@ -1247,6 +1200,7 @@ prompt the user for permission, but that's an acceptable user experience. [#7972]: https://github.com/microsoft/terminal/pull/7972 [#961]: https://github.com/microsoft/terminal/issues/961 [`30b8335`]: https://github.com/microsoft/terminal/commit/30b833547928d6dcbf88d49df0dbd5b3f6a7c879 +[#8135]: https://github.com/microsoft/terminal/pull/8135 [Tab Tear-out in the community toolkit]: https://github.com/windows-toolkit/Sample-TabView-TearOff [Quake mode scenarios]: https://github.com/microsoft/terminal/issues/653#issuecomment-661370107 From 674aa330d6e04dc0dde7b7bd87b2dda12122afb4 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Wed, 2 Dec 2020 05:59:15 -0600 Subject: [PATCH 26/39] update this doc link --- .../#5000 - Process Model 2.0/#5000 - Process Model 2.0.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md b/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md index 24afa3c1104..2aa508ff511 100644 --- a/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md +++ b/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md @@ -1,7 +1,7 @@ --- author: Mike Griese @zadjii-msft created on: 2020-07-31 -last updated: 2020-11-20 +last updated: 2020-12-02 issue id: #5000 --- @@ -293,7 +293,7 @@ experts that could back up a technical solution. Instead of supporting mixed elevation in a single window, we'll introduce a number of new properties to profiles and various actions, to improve the user experience of running elevated instances. These are detailed in the spec at -[TODO!](FILL THIS LINK IN!!!! !) +[Elevation QOL Improvements]. Some things we considered during this investigation: @@ -1205,3 +1205,4 @@ prompt the user for permission, but that's an acceptable user experience. [Tab Tear-out in the community toolkit]: https://github.com/windows-toolkit/Sample-TabView-TearOff [Quake mode scenarios]: https://github.com/microsoft/terminal/issues/653#issuecomment-661370107 [`ISwapChainPanelNative2::SetSwapChainHandle`]: https://docs.microsoft.com/en-us/windows/win32/api/windows.ui.xaml.media.dxinterop/nf-windows-ui-xaml-media-dxinterop-iswapchainpanelnative2-setswapchainhandle +[Elevation QOL Improvements]: https://github.com/microsoft/terminal/blob/dev/migrie/s/1032-elevation-qol/doc/specs/%235000%20-%20Process%20Model%202.0/%231032%20-%20Elevation%20Quality%20of%20Life%20Improvements.md?rgh-link-date=2020-12-01T22%3A50%3A26Z From 7a7fe5cb2ee13273db91f9234627e4dc8986c05a Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Wed, 2 Dec 2020 06:34:45 -0600 Subject: [PATCH 27/39] spellcheck and some editorializing to make it less punishing a read --- .github/actions/spell-check/expect/expect.txt | 1 + .../#5000 - Process Model 2.0.md | 150 +++++++++--------- 2 files changed, 74 insertions(+), 77 deletions(-) diff --git a/.github/actions/spell-check/expect/expect.txt b/.github/actions/spell-check/expect/expect.txt index c089da15ba8..12536850574 100644 --- a/.github/actions/spell-check/expect/expect.txt +++ b/.github/actions/spell-check/expect/expect.txt @@ -2017,6 +2017,7 @@ runuia runut rvalue RVERTICAL +rxvt RWIN safearray SAFECAST diff --git a/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md b/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md index 2aa508ff511..4a5cdc860fd 100644 --- a/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md +++ b/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md @@ -9,12 +9,11 @@ issue id: #5000 ## Abstract -The Windows Terminal currently exists as a single process per window, with one -connection per terminal pane (which could be an additional conpty process and -associated client processes). This model has proven effective for the simple -windowing we've done so far. However, in order to support scenarios like -dragging tabs into other windows, or having one top-level window with different -elevation levels within it, this single process model will not be sufficient. +The Windows Terminal currently exists as a single process per window. It has one +connection per terminal pan, which could be an additional conpty process and +associated client processes. This model has proven effective for the simple +windowing we've done so far. However, this single process model will not be +enough for more complex scenarios, like dragging tabs into other windows. This spec outlines changes to the Terminal process model in order to enable the following scenarios: @@ -24,9 +23,8 @@ following scenarios: * Single Instance Mode ([#2227]) * Quake Mode ([#653]) -Also discussed as a part of this spec is the "mixed elevation" ([#1032] & -[#632]) scenario, which is closely related to the above scenarios, and was -investigated as a part of this re-architecture. +Also discussed is "mixed elevation" ([#1032] & [#632]), which is closely related +to the above scenarios, and was investigated as a part of this re-architecture. ## Inspiration @@ -37,9 +35,9 @@ tabs within the browser, to help isolate the actual tabs from one another. attempt to reuse some resources between tabs. They do still break out the tab content from the actual window's process). -Aditionally, the rxvt-unicode terminal emulator uses a similar client/server -architecture, where the terminal "content" is hosted by a server process, and -windows act as a "client" for that content. +The rxvt-unicode terminal emulator uses a similar client/server architecture. In +this model, the terminal "content" is hosted by a server process, and windows +act as a "client" for that content. ## Background @@ -48,11 +46,10 @@ important to understand some of the technical hurdles that need to be overcome. ### Drag and drop tabs to create new windows -Another important scenario we're targeting is the ability to drag a tab out of -the Terminal window and create a new Terminal window. Obviously, when we do -this, we want the newly created window to be able to persist all the same state -that the original window had for that tab. For us, that primarily means the -buffer contents and connection state. +An important scenario we're targeting is the ability to drag a tab out of the +window, and create a new Terminal window. When we do this, we want the new +window to be able to persist all the same state that the original window had for +that tab. For us, that primarily means the buffer contents and connection state. However, _how_ do we move the terminal state to another window? The terminal state is all located in-memory of the thread that created the `TermControl` @@ -65,13 +62,13 @@ background on how the scenario might work. There's really only a limited selection of things that a process could transfer to another with a drag and drop operation. If we wanted to use a string to -transfer the data, we'd somehow need to serialize then entire state of the tab, -it's tree of panes, and the state of each of the buffers in the tab, into some -sort of string, and then have the new window deserialize that string to -re-create the tab state. Consider that each buffer might include 32000 rows of -80+ characters each, each with possibly RGB attributes, and you're looking at -30MB+ of raw data to serialize and de-serialize per buffer, minimum. This sounds -extremely fragile, if not impossible to do robustly. +transfer the data, we'd somehow need to serialize then entire state of the tab. +That would mean turning its tree of panes, and the state of each of the buffers +in the tab, into some sort of string. Then, we would have the new window +deserialize that string to re-create the tab state. Consider that each buffer +might include 32000 rows of 80+ characters each, each with RGB attributes. You +are looking at 30MB+ of raw data to serialize and de-serialize per buffer, +minimum. This sounds extremely fragile, if not impossible to do robustly. What we need is a more effective way for separate Terminal windows to to be able to connect to and display content that's being hosted in another process. @@ -104,10 +101,10 @@ process looks today: ![figure-001](figure-001.png) Currently, the entire Windows Terminal exists as a single process composed of -many parts. it has a top Win32 layer responsible for the window, which includes -a UWP XAML-like App layer, which embeds many `TermControl`s, each of which -contains the buffer and renderer, and communicates with a connection to another -process. +many parts. It has a top Win32 layer responsible for the window. This window +includes a UWP XAML-like App layer, which embeds many `TermControl`s. Each of +these contains the buffer and renderer, and communicates with a connection to +another process. The primary concept introduced by this spec is the idea of two types of process, which will work together to create a single Terminal window. These processes @@ -116,14 +113,14 @@ will be referred to as the "Window Process" and the "Content Process". the desktop, and accepting input from the user. This is a window which hosts our XAML content, and the window which the user interacts with. * A **Content Process** is a process which hosts a single terminal instance. - This is the process that hosts the terminal buffer, state machine, connection, - and is also responsible for the `Renderer` and `DxEngine`. + This is the process that hosts the terminal buffer, state machine, and + connection. It is also responsible for the `Renderer` and `DxEngine`. These two types of processes will work together to present both the UI of the Windows Terminal app, as well as the contents of the terminal buffers. A single -window process may be in communication with multiple content processes - one per -terminal instance. That means that each and every `TermControl` in a window -process will be hosted in a separate process. +window process may be in communication with many content processes - one per +terminal instance. That means that each `TermControl` in a window process will +be hosted in a separate process. The window process will be full of "thin" `TermControl`s - controls which are only the XAML layer and a WinRT object which is hosted by the content process. @@ -138,15 +135,16 @@ As a broad outline, whenever the window wants to create a terminal, the flow will be something like the following: 1. A window process will spawn a new content process, with a unique ID. -2. The window process will attach itself to the content process, indicating that - it (the window process) is the content process's hosting window. -3. When the content process creates it's swap chain, it will raise an event - which the window process will use to connect that swap chain to the window - process's `SwapChainPanel`. -4. The content process will read output from the connection and draw to the swap chain. The - contents that are rendered to the swap chain will be visible in the window - process's `SwapChainPanel`, because they share the same underlying kernel - object. +2. The window process will attach itself to the content process. It will + indicate that it (the window process) is the content process's hosting + window. +3. When the content process creates its swap chain, it will raise an event. The + window process will use to connect that swap chain to the window process's + `SwapChainPanel`. +4. The content process will read output from the connection and draw to the swap + chain. The contents that are rendered to the swap chain will be visible in + the window process's `SwapChainPanel`. This is because they share the same + underlying kernel object. ![figure-003](figure-003.png) @@ -194,42 +192,40 @@ auto myClass = create_instance(MyClassGUID, CLSCTX_LOCAL_SERVER) We're going to be using that system a little differently here. Instead of using a GUID to represent a single _Class_, we're going to use the GUID to uniquely -identify _content processes_. Each content process will receive a unique GUID -when it is created, and it will register as the server for that GUID. Then, any -window process will be able to connect to that specific content process strictly -by GUID. Because each GUID is unique to each content process, any time any -client calls `create_instance<>(theGuid, ...)`, it will uniquely attempt to -connect to the content process hosting `theGuid`. - -This means that if we wanted to have a second window process connect to the +identify _content processes_. Each content process will receive a unique GUID on +creation. It will register as the server for that GUID. Any window process will +be able to connect to that specific content process strictly by GUID. Because +each GUID is unique to each content process, any time any client calls +`create_instance<>(theGuid, ...)`, it will uniquely attempt to connect to the +content process hosting `theGuid`. + +If we wanted to have a second window process connect to the _same_ content process as another window, all it needs is the content process's GUID. Now that we have a WinRT object that the content process hosts, we can have the window and content process interact using that interface. The next important thing to communicate between these processes is the swapchain. The swapchain -will need to be created by the content process, but also we need to be able to -communicate the `HANDLE` to that swapchain out to the window process, so the -window process can attach that swapchain to the `SwapChainPanel` in the window. +will need to be created by the content process. We also need to be able to +communicate the `HANDLE` to that swapchain out to the window process. The window process needs to be able to attach that swapchain to the `SwapChainPanel` in the window. -This is a little tricky, because WinRT does not natively expose a `HANDLE` type -which would allow us to easily pass the `HANDLE` between these processes. -Instead we'll need to manually cast the `HANDLE` to `uint64_t` at the winRT -boundary, and cast it back to a `HANDLE` when we want to use it. +This is tricky, because WinRT does not natively expose a `HANDLE` type. That +would allow us to easily pass the `HANDLE` between these processes. Instead +we'll need to manually cast the `HANDLE` to `uint64_t` at the winRT boundary, +and cast it back to a `HANDLE` when we want to use it. Instead, the window will always need to be the one responsible for calling `DuplicateHandle`. Fortunately, the `DuplicateHandle` function does allow a caller to duplicate from another process into your own process. -So when the content process needs to create a new swapchain, it'll raise an -event that the window process can listen for to indicate that the swapchain -changed. The window will then query for the content process's PID (which it will -use to create a handle to the content process), and the window will query the -current value of the content process's `HANDLE` to the swapchain. The window -will then duplicate that `HANDLE` into it's own process space. Now that the -window has a handle to the swapchain, it can use -[`ISwapChainPanelNative2::SetSwapChainHandle`] to set the SwapChainPanel to use -the same swapchain. +When the content process needs to create a new swapchain, it'll raise an event. +The window process can listen for that event to indicate that the swapchain +changed. The window will then query for the content process's PID and create a +handle to the content process. The window will query the current value of the +content process's `HANDLE` to the swapchain. The window will then duplicate that +`HANDLE` into it's own process space. Now that the window has a handle to the +swapchain, it can use [`ISwapChainPanelNative2::SetSwapChainHandle`] to set the +SwapChainPanel to use the same swapchain. This will allow the content process to draw to the swapchain, and the window process to render that same swapchain. @@ -242,16 +238,16 @@ is the GUID of the content process, it becomes fairly trivial to be able to ![drop-tab-on-existing-window](drop-tab-on-existing-window.png) -When a drag/drop operation happens, the payload of the event will simply contain -the structure of the tree of panes, and the GUIDs of the content processes that -make up the leaf nodes of the tree. The receiving window process will then be -able to use that tree to be able to re-create a similar pane structure in its -window, and use the GUIDs to be able to connect to the content processes for the -terminals in that tab. +When a drag/drop operation happens, the payload of the event will contain the +structure of the tree of panes. This tree will contain the GUIDs of the content +processes that make up the leaf nodes of the tree. The receiving window process +will then be able to use that tree to be able to re-create a similar pane +structure in its window. It will use the GUIDs to be able to connect to the +content processes for the terminals in that tab. -The terminal buffer never needs to move from one process to another - it always -stays in just a single content process. The only thing that changes is the -window process which is rendering the content process's swapchain. +The terminal buffer never needs to move from one process to another. It always +stays in a single content process. The only thing that changes is which window +process is rendering the content process's swapchain. When a new window is created from a torn-out tab in this manner, we will want to ensure that the created window maintains the same maximized state as the origin @@ -281,7 +277,7 @@ this scenario is not possible to do safely after all. There are numerous technical difficulties involved, and each with their own security risks. At the end of the day, the team wouldn't be comfortable shipping a mixed-elevation solution, because there's simply no way for us to be confident that we haven't -introduced an escalation-of-privledge vector utilizing the Terminal. No matter +introduced an escalation-of-privlege vector utilizing the Terminal. No matter how small the attack surface might be, we wouldn't be confident that there are _no_ vectors for an attack. @@ -321,7 +317,7 @@ Some things we considered during this investigation: may be due to a lack of Packaged COM support for mixed elevation levels. Even if this approach did end up working, we would still need to be responsible for securing the elevated windows so that an unelevated attacker - couldn't hijack a content process and trigger unexepected code in the window + couldn't hijack a content process and trigger unexpected code in the window process. We didn't feel confident that we could properly secure this channel either. From 9d7bd18b754aa7d94a47107c035f5efd1d84dc36 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Wed, 2 Dec 2020 06:51:23 -0600 Subject: [PATCH 28/39] you'd think I could spell privilege by now --- .github/actions/spell-check/patterns/patterns.txt | 2 +- .../#5000 - Process Model 2.0/#5000 - Process Model 2.0.md | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/actions/spell-check/patterns/patterns.txt b/.github/actions/spell-check/patterns/patterns.txt index 597e0114bfa..4a8ca355dd6 100644 --- a/.github/actions/spell-check/patterns/patterns.txt +++ b/.github/actions/spell-check/patterns/patterns.txt @@ -4,7 +4,7 @@ https://www\.itscj\.ipsj\.or\.jp/iso-ir/[-0-9]+\.pdf https://www\.vt100\.net/docs/[-a-zA-Z0-9#_\/.]* https://www.w3.org/[-a-zA-Z0-9?&=\/_#]* https://(?:(?:www\.|)youtube\.com|youtu.be)/[-a-zA-Z0-9?&=]* -https://[a-z-]+\.github(?:usercontent|)\.com/[-a-zA-Z0-9?&=_\/.]* +https://(?:[a-z-]+\.|)github(?:usercontent|)\.com/[-a-zA-Z0-9?%&=_\/.]* [Pp]ublicKeyToken="?[0-9a-fA-F]{16}"? (?:[{"]|UniqueIdentifier>)[0-9a-fA-F]{8}-(?:[0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}(?:[}"]| Date: Wed, 2 Dec 2020 10:00:18 -0600 Subject: [PATCH 29/39] Update notes on elevation --- ...2 - Windows Terminal Session Management.md | 97 ++++++++----------- 1 file changed, 39 insertions(+), 58 deletions(-) diff --git a/doc/specs/#5000 - Process Model 2.0/#4472 - Windows Terminal Session Management.md b/doc/specs/#5000 - Process Model 2.0/#4472 - Windows Terminal Session Management.md index 351c8a52ff0..3696cb66f6c 100644 --- a/doc/specs/#5000 - Process Model 2.0/#4472 - Windows Terminal Session Management.md +++ b/doc/specs/#5000 - Process Model 2.0/#4472 - Windows Terminal Session Management.md @@ -299,8 +299,11 @@ handle UIA access as it normally does. Many security concerns have already be covered in greater detail in the parent -spec, [Process Model 2.0 Spec]. I'd refer specifically to the section ["Mixed -elevation & Monarch / Peasant issues"](#mixed-elevation--monarch--peasant-issues). +spec, [Process Model 2.0 Spec]. + +When attempting to instantiate the Monarch, COM will only return the object from +a server running at the same elevation level. We don't need to worry about +unelevated peasants connecting to the elevated Monarch, or vice-versa.
Reliability -Whenever we are working with an object that's hosted by another process, we will -need to make sure that we work with it in a try/catch, because at _any_ time, -the other process could be killed. At any point, a window process could be -killed. Both the monarch and peasant code will need to be redundant to such a -scenario, and if the other process is killed, make sure to display an -appropriate error and either recover or exit gracefully. +We will need to be careful when working with objects hosted by another process. +Any work we do with it MUST be in a try/catch, because at _any_ time, the other +process could be killed. At any point, a window process could be killed. Both +the monarch and peasant code will need to be redundant to such a scenario, and +if the other process is killed, make sure to display an appropriate error and +either recover or exit gracefully. -In any and all of these situations, we will want to try and be as verbose as -possible in the logging, to try and make tracking which process had the error +In any and all these situations, we will want to try and be as verbose as +possible in the logging. This will make tracking which process had the error occur easier. Compatibility -There are not any serious compatibility concerns with this specific set of -features. - We will be changing the default behavior of the Terminal to auto-glom to the most-recently used window on the same desktop in the course of this work, which will be a breaking UX change. This is behavior that can be reverted with the `"glomToLastWindow": "never"` setting. +We acknowledge that this is a pretty massive change to the default experience of +the Terminal. We're planning on doing some polling of users to determine which +behavior they want by default. Additionally, we'll be staging the rollout of +this feature, using the Preview builds of the Terminal. The release notes that +first include it will call extra attention to this feature. We'll ask that users +provide their feedback in a dedicated thread, so we have time to collect +opinions from users before rolling the change out to all users. + +We may choose to only change the default to `sameDesktop` once tab tear out is +available, so users who are particularily unhappy about this change can still +tear out the tab (if they can't be bothered to change the setting). +
@@ -316,7 +317,7 @@ occur easier. We will be changing the default behavior of the Terminal to auto-glom to the most-recently used window on the same desktop in the course of this work, which will be a breaking UX change. This is behavior that can be reverted with the -`"glomToLastWindow": "never"` setting. +`"windowingBehavior": "useNew"` setting. We acknowledge that this is a pretty massive change to the default experience of the Terminal. We're planning on doing some polling of users to determine which @@ -326,9 +327,9 @@ first include it will call extra attention to this feature. We'll ask that users provide their feedback in a dedicated thread, so we have time to collect opinions from users before rolling the change out to all users. -We may choose to only change the default to `sameDesktop` once tab tear out is -available, so users who are particularily unhappy about this change can still -tear out the tab (if they can't be bothered to change the setting). +We may choose to only change the default to `useExistingOnSameDesktop` once tab +tear out is available, so users who are particularily unhappy about this change +can still tear out the tab (if they can't be bothered to change the setting). @@ -433,10 +434,10 @@ This is a list of actionable tasks generated as described by this spec: * [ ] Add support for `wt.exe` processes to be Monarchs and Peasants, and communicate that state between themselves. This task does not otherwise add any user-facing features, merely an architectural update. -* [ ] Add support for the `glomToLastWindow` setting as a boolean. Opening new +* [ ] Add support for the `windowingBehavior` setting as a boolean. Opening new WT windows will conditionally glom to existing windows. -* [ ] Add support for per-desktop `glomToLastWindow`, by adding the support for - the enum values `"lastWindow"`, `"sameDesktop"` and `"never"`. +* [ ] Add support for per-desktop `windowingBehavior`, by adding the support for + the enum values `"useExisting"`, `"useExistingOnSameDesktop"` and `"useNew"`. * [ ] Add support for `wt.exe` to pass commandlines intended for another window to the monarch, then to the intended window, with the `--window,-w window-id` commandline parameter. @@ -467,10 +468,11 @@ This is a list of actionable tasks generated as described by this spec: Instance Mode is active, and the user runs a new `wt.exe` commandline, it will always end up running in the existing window, if there is one. - An earlier version of this spec proposed a new value of `glomToLastWindow`. The - `always` value would disable tab tear out[[1]](#footnote-1). It would - additionally disable the `newWindow` action, and prevent `wt -w new` from - opening a new window. + An earlier version of this spec proposed a new value of `glomToLastWindow`. + (`glomToLastWindow` was later renamed `windowingBehavior`). The `always` value + would disable tab tear out[[1]](#footnote-1). It would additionally + disable the `newWindow` action, and prevent `wt -w new` from opening a new + window. In discussion, it was concluded that this setting didn't make sense. Why did the `glomToLastWindow` setting change the behavior of tear out? Single Instance Mode From 542ec1c8c481e9b790f762b4be7b0e45f94b5dbe Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Thu, 10 Dec 2020 08:37:02 -0600 Subject: [PATCH 34/39] notes from review --- .github/actions/spell-check/expect/web.txt | 2 + ...2 - Windows Terminal Session Management.md | 72 +++++++++++++------ 2 files changed, 54 insertions(+), 20 deletions(-) diff --git a/.github/actions/spell-check/expect/web.txt b/.github/actions/spell-check/expect/web.txt index c0c237ed13c..f0e69317384 100644 --- a/.github/actions/spell-check/expect/web.txt +++ b/.github/actions/spell-check/expect/web.txt @@ -13,3 +13,5 @@ fixterms uk winui appshellintegration +gfycat +what3words diff --git a/doc/specs/#5000 - Process Model 2.0/#4472 - Windows Terminal Session Management.md b/doc/specs/#5000 - Process Model 2.0/#4472 - Windows Terminal Session Management.md index 27f77e866f5..d9691ebc26a 100644 --- a/doc/specs/#5000 - Process Model 2.0/#4472 - Windows Terminal Session Management.md +++ b/doc/specs/#5000 - Process Model 2.0/#4472 - Windows Terminal Session Management.md @@ -1,7 +1,7 @@ --- author: Mike Griese @zadjii-msft created on: 2020-10-30 -last updated: 2020-12-09 +last updated: 2020-12-10 issue id: #4472 --- @@ -148,7 +148,7 @@ command: #### `--window,-w window-id` Run these commands in the given Windows Terminal session. This enables opening new tabs, splits, etc. in already running Windows Terminal windows. -* If `window-id` is `0`, run the given commands in _the current window_ +* If `window-id` is `0`, run the given commands in _the current window_. * If `window-id` is a negative number, or the reserved name `new`, run the commands in a _new_ Terminal window. * If `window-id` is the ID or name of an existing window, then run the @@ -156,7 +156,7 @@ new tabs, splits, etc. in already running Windows Terminal windows. * If `window-id` is _not_ the ID or name of an existing window, create a new window. That window will be assigned the ID or name provided in the commandline. The provided subcommands will be run in that new window. -* If `window-id` is omitted, then obey the value of `glomToLastWindow` when +* If `window-id` is omitted, then obey the value of `windowingBehavior` when determining which window to run the command in. _Whenever_ `wt.exe` is started, it must _always_ pass the provided commandline @@ -181,21 +181,30 @@ like `sleep 10 ; wt -w 0 `, then the user could easily focus another WT window during the sleep, which would cause the MRU window to not be the same as the window executing the command. -I'm not sure that there is a better solution for the `-w 0` scenario other than +To solve this issue, we'll other than attempting to use the `WT_SESSION` environment variable. If a `wt.exe` process is spawned and that's in it's environment variables, it could try and ask the monarch for the peasant who's hosting the session corresponding to that GUID. This is more of a theoretical solution than anything else. -In Single-Instance mode, running `wt -w 0` outside a WT window will still cause -the commandline to glom to the existing single terminal instance, if there is -one. +In the past we've been reluctant to rely too heavily on `WT_SESSION`. However, +an environment variable does seem to be the only reliable way to be confident +where the window was created from. We could introduce another environment +variable instead - `WT_WINDOW_ID`. That would allow us to shortcut the session +ID lookup. However, I worry about exposing the window ID as an environment +variable. If we do that, users will inevetably use that instead of the `wt -0` +alias, which should take care of the work for them. + +Both solutions are prone to the user changing the value of the variable to some +garbage value. If they do that, this lookup will most certainly not work as +expected. Using the session ID (a GUID) instead of the window ID (an int) makes +it less likely that they guess the ID of an existing instance. #### Running commands in a new window:`wt --window -1` / `wt --window new` If the user passes a negative number, or the reserved name `new` to the `--window` parameter, then we will always create a new window for that -commandline, regardless of the value of `glomToLastWindow`. This will allow +commandline, regardless of the value of `windowingBehavior`. This will allow users to do something like `wt -w -1 new-tab` to _always_ create a new window. #### `--window` in subcommands @@ -241,8 +250,24 @@ address a window in addition to the ID. Names can be provided on the commandline, in the original commandline. For example, `wt -w foo nt` would name the new window "foo". Names can also be set -with a new action, `NameWindow`. `name-window` could also be used as a -subcommand. For example, `wt -w 4 name-window bar` would name window 4 "bar". +with a new action, `NameWindow`[[3]](#footnote-3). `name-window` +could also be used as a subcommand. For example, `wt -w 4 name-window bar` would +name window 4 "bar". + +To keep identities mentally distinct, we will disallow names that are integers +(positive or negative). This will prevent users from renaming a window to `2`, +then having `wt -w 2` be ambiguous as to which window it refers to. + +Names must also be unique. If a user attempts to set the name of the window to +an already-used name, we'll need to ignore the name change. We could also +display a "toast" or some other type of low-impact message to the user. That +message would have some text like: "Unable to rename window. Another window with +that name already exists". + +The Terminal will reserve the name `new`. It will also reserve any names +starting with the character `_`. The user will not be allowed to set the window +name to any of these reserved names. Reserving `_*` allows us to add other +keywords in the future, without introducing a breaking change. ## UI/UX Design @@ -278,6 +303,8 @@ applications. There is no expected accessibility impact from this feature. Each window will handle UIA access as it normally does. +In the future, we could consider exposing the window IDs and/or names via UIA. + @@ -356,11 +383,6 @@ elevation levels will maintain separate lists of window IDs. If the user is running both an elevated and unelevated window, then there will be two monarchs. One elevated, and the other unelevated. -This does mean that single instance mode won't _really_ work for users in -mixed-elevation scenarios. There'll be a monarch for the unelevated window, and -a separate monarch for the elevated one. This is acceptable, given the -assumption that windows cannot mix elevation levels. - There will also be some edge cases when handling the commandline that will need special care. Say the user wanted to open a new tab in the elevated window, from and unelevated `explorer.exe`. That would be a commandline like: @@ -446,7 +468,8 @@ This is a list of actionable tasks generated as described by this spec: * [ ] Add a `NameWindow` action, subcommand that allows the user to set the name for the window. * [ ] Add an action that will cause all windows to breifly display a overlay - with the current window ID and name + with the current window ID and name. This would be something like the + "identify" feature of the Windows "Display" settings. ## Future considerations @@ -479,10 +502,12 @@ This is a list of actionable tasks generated as described by this spec: is most frequently requested in regards to quake mode. We're leaving the implementation of true single instance mode to that spec. * It was suggested in review that we could auto-generate names for windows, from - some list of words. Prior art could be the URLS for gyfcat.com, which use - three random words. I believe `docker` also assigns names from a random - selection of `adjective`+`name`. This is an interesting idea, and something - that could be pursued in the future. + some list of words. Prior art could be the URLS for gfycat.com or + what3words.com, which use three random words. I believe `docker` also assigns + names from a random selection of `adjective`+`name`. This is an interesting + idea, and something that could be pursued in the future. + - This would be a massive pain to localize though, hence why this is left as + a future consideration. * We will _need_ to provide a commandline tool to list windows and their IDs & names. We're thinking a list of windows, their IDs, names, PIDs, and the title of the window. @@ -503,6 +528,13 @@ set of features, and later used to control tear out as well. new window", then we could also reserve `last` or `current` as an alias for "the current window". +[3]: We currently have two actions for renaming _tabs_ +in the Terminal: `renameTab(name)`, and `openTabRenamer()`. We will likely +similarly need `nameWindow(name)` and `openWindowNamer()`. `openWindowNamer` +could display a dialog to allow the user to rename the current window at +runtime. + + ## Resources * [Tab Tear-out in the community toolkit] - this document proved invaluable to From 5d23f750119cc8d9a474d00088eb2a72811ea2b7 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Thu, 10 Dec 2020 08:37:52 -0600 Subject: [PATCH 35/39] lets hope I can spell --- .../#4472 - Windows Terminal Session Management.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/specs/#5000 - Process Model 2.0/#4472 - Windows Terminal Session Management.md b/doc/specs/#5000 - Process Model 2.0/#4472 - Windows Terminal Session Management.md index d9691ebc26a..1178588a755 100644 --- a/doc/specs/#5000 - Process Model 2.0/#4472 - Windows Terminal Session Management.md +++ b/doc/specs/#5000 - Process Model 2.0/#4472 - Windows Terminal Session Management.md @@ -355,7 +355,7 @@ provide their feedback in a dedicated thread, so we have time to collect opinions from users before rolling the change out to all users. We may choose to only change the default to `useExistingOnSameDesktop` once tab -tear out is available, so users who are particularily unhappy about this change +tear out is available, so users who are particularly unhappy about this change can still tear out the tab (if they can't be bothered to change the setting). @@ -467,7 +467,7 @@ This is a list of actionable tasks generated as described by this spec: commandline * [ ] Add a `NameWindow` action, subcommand that allows the user to set the name for the window. -* [ ] Add an action that will cause all windows to breifly display a overlay +* [ ] Add an action that will cause all windows to briefly display a overlay with the current window ID and name. This would be something like the "identify" feature of the Windows "Display" settings. From 6329b167b58a3ace8558f06a38075773025bd6fb Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Tue, 2 Feb 2021 16:54:00 -0600 Subject: [PATCH 36/39] updates from two months --- .../#5000 - Process Model 2.0.md | 104 ++++++------------ 1 file changed, 35 insertions(+), 69 deletions(-) diff --git a/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md b/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md index c3eb52b7996..d1dd42369a6 100644 --- a/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md +++ b/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md @@ -1,7 +1,7 @@ --- author: Mike Griese @zadjii-msft created on: 2020-07-31 -last updated: 2020-12-02 +last updated: 2021-02-01 issue id: #5000 --- @@ -10,7 +10,7 @@ issue id: #5000 ## Abstract The Windows Terminal currently exists as a single process per window. It has one -connection per terminal pan, which could be an additional conpty process and +connection per terminal pane, which could be an additional conpty process and associated client processes. This model has proven effective for the simple windowing we've done so far. However, this single process model will not be enough for more complex scenarios, like dragging tabs into other windows. @@ -166,11 +166,11 @@ implementation), but also enables using these types _across process boundaries_. Typically, these classes are given a unique GUID for the class. A process that wants to implement one of these out-of-proc WinRT objects can register with the -system to say "I make `MyClass`'s, and their GUID is `{foo}`". these are called +system to say "I make `MyClass`'s, and their GUID is `{foo}`". These are called WinRT _servers_. Then, consumers (_clients_) of that class can ask the system "I'd like to instantiate a `{foo}` please", which will cause the server to create a new instance of that object (in the server process), and the client -will be given a winrt object which can interact with the classes WinRT +will be given a WinRT object which can interact with the classes WinRT projection. A server can register the types it produces with `CoRegisterClassObject`, like so: @@ -211,7 +211,7 @@ communicate the `HANDLE` to that swapchain out to the window process. The window This is tricky, because WinRT does not natively expose a `HANDLE` type. That would allow us to easily pass the `HANDLE` between these processes. Instead -we'll need to manually cast the `HANDLE` to `uint64_t` at the winRT boundary, +we'll need to manually cast the `HANDLE` to `uint64_t` at the WinRT boundary, and cast it back to a `HANDLE` when we want to use it. Instead, the window will always need to be the one responsible for calling @@ -251,7 +251,7 @@ process is rendering the content process's swapchain. When a new window is created from a torn-out tab in this manner, we will want to ensure that the created window maintains the same maximized state as the origin -window. If the user tries to tera out a tab from a maximized window, the window +window. If the user tries to tear out a tab from a maximized window, the window we create should _also_ be maximized. Similar to dragging a tab from one window to another window, we can also detect @@ -303,7 +303,7 @@ Some things we considered during this investigation: - However, it is unfortunately not possible with COM to have an elevated client attach to an unelevated server that's registered at runtime. Even in a packaged environment, the OS will reject the attempt to `CoCreateInstance` - the content process object. this will prevent elevated windows from + the content process object. This will prevent elevated windows from re-connecting to unelevated client processes. - We could theoretically build an RPC tunnel between content and window processes, and use the RPC connection to marshal the content process to the @@ -327,7 +327,7 @@ With the current design, it's easy to connect many content processes to a window process, and move those content processes easily between windows. However, we want to make sure that it's also possible to communicate between these processes. What if we want to have only a single WT instance, so that whenever -Wt is run, it creates a tab in the existing window? What if you want to run a +WT is run, it creates a tab in the existing window? What if you want to run a commandline in a given WT window? In addition to the concept of Window and Content Processes, we'll also be @@ -387,6 +387,11 @@ one?" #### Scenario: Open new tabs in most recently used window +> 👉 **Note**: This scenario is covered in depth in the spec titled "Windows +> Terminal Session Management". This section is intended to be an overview of +> the scenario. It should help show how window management fits in the larger +> picture of the other process model changes. + A common feature of many browsers is that when a web URL is clicked somewhere, the web page is opened as a new tab in the most recently used window of the browser. This functionality is often referred to as "glomming", as the new tab @@ -413,50 +418,16 @@ it'll seem as if the tab just opened in the most recent window. Users should certainly be able to specify if they want new instances to glom onto the MRU window or not. You could imagine that currently, we default to the -hypothetical value `"glomToLastWindow": false`, meaning that each new wt gets -it's own new window. - -#### Scenario: Single Instance Mode - -"Single Instance Mode" is a scenario in which there is only ever one single WT -window. When Single Instance Mode is active, and the user runs a new `wt.exe` -commandline, it will always end up running in the existing window, if there is -one. - -In "Single Instance Mode", the monarch _is_ the single instance. When `wt` is -run, and it determines that it is not the monarch, it'll ask the monarch if it's -in single instance mode. If it is, then the peasant that's starting up will -instead pass it's commandline arguments to the monarch process, and let the -monarch handle them, then exit. In single instance mode the window will still be -composed from a combination of a window process and multiple different content -processes, just the same as it would be outside single instance mode. - -So, this will make it seem like new starting a new `wt.exe` will just create a -new tab in the existing window. There are some tricky scenarios involving single -instance mode. Consider if If someone does `wt -d .` in explorer. For clarity, -let's label the existing window WT[1], and the second `wt.exe` process WT[2]. - -An example of this scenario is given in the following diagram: - -![single-instance-mode-cwd](single-instance-mode-cwd.png) - -In this scenario, we'd want the new tab to be spawned in the current working -directory of WT[2], not WT[1]. So when WT[1] is about to run the commands that -were passed to WT[2], WT[1] will need to: - -* First, stash it's own CWD -* Change to the CWD of WT[2] -* Run the commands from WT[2] -* Then return to it's original CWD. - -One could imagine that single instance mode is the combination of two properties: -* The user wants new invocation of `wt` to "glom" onto the most recently used - window (the hypothetical `"glomToLastWindow": true` setting) -* The user wants to prevent tab tear-out, or the ability for a `newWindow` - action to work. (hypothetically `"allowTabTearOut": false`) +value `"windowingBehavior": "useNew"`, meaning that each new wt gets its own +new window. #### Scenario: Run `wt` in the current window +> 👉 **Note**: This scenario is covered in depth in the spec titled "Windows +> Terminal Session Management". This section is intended to be an overview of +> the scenario. It should help show how window management fits in the larger +> picture of the other process model changes. + One often requested scenario is the ability to run a `wt.exe` commandline in the current window, as opposed to always creating a new window. With the ability to communicate between different window processes, one could imagine a logical @@ -464,8 +435,7 @@ extension of this scenario being "run a `wt` commandline in _any_ given WT window". This spec by no means attempts to fully document how this functionality should -work. This scenarios deserves it's own spec to discuss various different naming - +work. This scenario deserves its own spec to discuss various different naming schemes for the commandline parameters. The following is given as an example of how these arguments _might_ be authored and implemented to satisfy some of these scenarios. @@ -475,53 +445,49 @@ monarch, then running a command in a given window with ID `N` should be as easy as something like: ```sh -wt.exe --session N new-tab ; split-pane +wt.exe --window N new-tab ; split-pane ``` -(or for shorthand, `wt -s N new-tab ; split-pane`). +(or for shorthand, `wt -w N new-tab ; split-pane`). This would create a new peasant, who could then ask the monarch if there is a peasant with ID `N`. If there is, then the peasant can connect to that other peasant, dispatch the current commandline to that other peasant, and exit, before ever creating a window. If this commandline instead creates a new monarch process, then there was _no_ other monarch, and so there must logically not be -any other existing WT windows, and the `--session N` argument could be safely +any other existing WT windows, and the `--window N` argument could be safely ignored, and the command run in the current window. We should reserve the session id `0` to always refer to "The current window", if -there is one. So `wt -s 0 new-tab` will run `new-tab` in the current window (if +there is one. So `wt -w 0 new-tab` will run `new-tab` in the current window (if we're being run from WT). -If `wt -s 0 ` is run _outside_ a WT instance, it could attempt to glom +If `wt -w 0 ` is run _outside_ a WT instance, it could attempt to glom onto _the most recent WT window_ instead. This seems more logical than something -like `wt --session last` or some other special value indicating "run this in the +like `wt --window last` or some other special value indicating "run this in the MRU window". That might be a simple, but **wrong**, implementation for "the current window". If the peasants always raise an event when their window is focused, and the monarch keeps track of the MRU order for peasants, then one could naively assume -that the execution of `wt -s 0 ` would always return the window the +that the execution of `wt -w 0 ` would always return the window the user was typing in, the current one. However, if someone were to do something -like `sleep 10 ; wt -s 0 `, then the user could easily focus another +like `sleep 10 ; wt -w 0 `, then the user could easily focus another WT window during the sleep, which would cause the MRU window to not be the same as the window executing the command. -I'm not sure that there is a better solution for the `-s 0` scenario other than +I'm not sure that there is a better solution for the `-w 0` scenario other than attempting to use the `WT_SESSION` environment variable. If a `wt.exe` process is spawned and that's in it's environment variables, it could try and ask the monarch for the peasant who's hosting the session corresponding to that GUID. This is more of a theoretical solution than anything else. -In Single-Instance mode, running `wt -s 0` outside a WT window will still cause -the commandline to glom to the existing single terminal instance, if there is -one. - #### Scenario: Quake Mode "Quake mode" has a variety of different scenarios[[1]](#footnote-1) -that have all been requested, more than what fits cleanly into this spec. -However, there's one key aspect of quake mode that is specifically relevant and -worth mentioning here. +that have all been requested, more than what fits cleanly into this spec. **This +section is not intended to be comprehensive.** However, there's one key aspect +of quake mode that is specifically relevant and worth mentioning here. One of the biggest challenges with registering a global shortcut handler is _what happens when multiple windows try to register for the same shortcut at the @@ -593,7 +559,7 @@ really just a peasant with the added responsibility of keeping track of the other peasants as well. It's important that `ExecuteCommandline` takes a `currentDirectory` parameter. -Consider the scenario `wt -s 0 -d .` - in this scenario, the process that's +Consider the scenario `wt -w 0 -d .` - in this scenario, the process that's executing the provided commandline should first change its working directory to the provided `currentDirectory` so that something like `.` actually refers to the directory where the command was executed. @@ -937,7 +903,7 @@ running at the same integrity level will be addressable via the commandline. This might be a little confusing to the end user, but is seen as an acceptable experience to the alternative of just completely disallowing running commands in other elevated windows. If a user is running in an elevated window, they -probably will still want `wt -s 0 new-tab` to open in the current window. +probably will still want `wt -w 0 new-tab` to open in the current window. ### What happens to the content if the monarch dies unexpectedly? From a6b75d714f84f7e49b4b178cc63fd73e4503546b Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Fri, 5 Feb 2021 06:11:15 -0600 Subject: [PATCH 37/39] Last few notes from review --- .../#5000 - Process Model 2.0.md | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md b/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md index d1dd42369a6..1298acc1306 100644 --- a/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md +++ b/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md @@ -207,7 +207,9 @@ Now that we have a WinRT object that the content process hosts, we can have the window and content process interact using that interface. The next important thing to communicate between these processes is the swapchain. The swapchain will need to be created by the content process. We also need to be able to -communicate the `HANDLE` to that swapchain out to the window process. The window process needs to be able to attach that swapchain to the `SwapChainPanel` in the window. +communicate the `HANDLE` to that swapchain out to the window process. The window +process needs to be able to attach that swapchain to the `SwapChainPanel` in the +window. This is tricky, because WinRT does not natively expose a `HANDLE` type. That would allow us to easily pass the `HANDLE` between these processes. Instead @@ -230,6 +232,13 @@ SwapChainPanel to use the same swapchain. This will allow the content process to draw to the swapchain, and the window process to render that same swapchain. +> _author's note_: There's some internal work that's going on in parallel that +> will make this `DUplicateHandle` business more structured. Unfortunately, that +> work isn't public quite yet. It should be noted that in the version of this we +> end up shipping, we'll probably need a split COM & WinRT interface between the +> window and content processes. The COM interface will handle the passing of the +> swapchain handle, and the WinRT interface will do everything else. + #### Scenario: Tab Tear-off and Reattach Because all that's needed to uniquely identify an individual terminal instance @@ -478,7 +487,7 @@ as the window executing the command. I'm not sure that there is a better solution for the `-w 0` scenario other than attempting to use the `WT_SESSION` environment variable. If a `wt.exe` process is -spawned and that's in it's environment variables, it could try and ask the +spawned and that's in its environment variables, it could try and ask the monarch for the peasant who's hosting the session corresponding to that GUID. This is more of a theoretical solution than anything else. @@ -545,7 +554,7 @@ class Monarch : Peasant } ``` -The peasant process can instantiate the `Peasant` object itself, in it's process +The peasant process can instantiate the `Peasant` object itself, in its process space. Initially, the `Peasant` object won't have an ID assigned, and the call to `AddPeasant` on the `Monarch` will both cause the Monarch to assign the `Peasant` an ID, and add it to the Monarch process's list of processes. If the @@ -1074,7 +1083,7 @@ launch to use seems like an obvious next step. See also [#961]. - If we pursue this, then we'll need to make sure that we re-assign the window ID's as appropriate. the _new_ window (with the tabs that are being left behind) should still have the same peasant ID as the original window, which - will now get a new ID (as to ) + will now get a new ID (as to not conflict) * We could definitely do a `NewWindowFromTab(index:int?)` action that creates a new window from a current tab once this all lands. - Or it could be `NewWindowFromTab(index:union(int,int[])?)` to specify the From 9919f145fd959b06eca680848ff97e7e8ab67745 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Fri, 5 Feb 2021 06:13:16 -0600 Subject: [PATCH 38/39] spellcheck doesn't like that --- .../#5000 - Process Model 2.0/#5000 - Process Model 2.0.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md b/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md index 1298acc1306..a6f8490ae3a 100644 --- a/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md +++ b/doc/specs/#5000 - Process Model 2.0/#5000 - Process Model 2.0.md @@ -1,7 +1,7 @@ --- author: Mike Griese @zadjii-msft created on: 2020-07-31 -last updated: 2021-02-01 +last updated: 2021-02-05 issue id: #5000 --- @@ -298,7 +298,7 @@ experts that could back up a technical solution. Instead of supporting mixed elevation in a single window, we'll introduce a number of new properties to profiles and various actions, to improve the user experience of running elevated instances. These are detailed in the spec at -[Elevation QOL Improvements]. +[Elevation Quality of Life Improvements]. Some things we considered during this investigation: @@ -1176,4 +1176,4 @@ prompt the user for permission, but that's an acceptable user experience. [Tab Tear-out in the community toolkit]: https://github.com/windows-toolkit/Sample-TabView-TearOff [Quake mode scenarios]: https://github.com/microsoft/terminal/issues/653#issuecomment-661370107 [`ISwapChainPanelNative2::SetSwapChainHandle`]: https://docs.microsoft.com/en-us/windows/win32/api/windows.ui.xaml.media.dxinterop/nf-windows-ui-xaml-media-dxinterop-iswapchainpanelnative2-setswapchainhandle -[Elevation QOL Improvements]: https://www.github.com/microsoft/terminal/blob/dev/migrie/s/1032-elevation-qol/doc/specs/%235000%20-%20Process%20Model%202.0/%231032%20-%20Elevation%20Quality%20of%20Life%20Improvements.md +[Elevation Quality of Life Improvements]: https://www.github.com/microsoft/terminal/blob/dev/migrie/s/1032-elevation-qol/doc/specs/%235000%20-%20Process%20Model%202.0/%231032%20-%20Elevation%20Quality%20of%20Life%20Improvements.md From a866a8bfa81b3d8b1c0043b2fb0c45a84b23d2e5 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Fri, 5 Feb 2021 06:18:29 -0600 Subject: [PATCH 39/39] its --- .../#4472 - Windows Terminal Session Management.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/doc/specs/#5000 - Process Model 2.0/#4472 - Windows Terminal Session Management.md b/doc/specs/#5000 - Process Model 2.0/#4472 - Windows Terminal Session Management.md index 1178588a755..20c095757b4 100644 --- a/doc/specs/#5000 - Process Model 2.0/#4472 - Windows Terminal Session Management.md +++ b/doc/specs/#5000 - Process Model 2.0/#4472 - Windows Terminal Session Management.md @@ -71,7 +71,7 @@ tab just opened in the most recent window. Users should certainly be able to specify if they want new instances to glom onto the MRU window or not. You could imagine that currently, we default to the hypothetical value `"windowingBehavior": "useNew"`, meaning that each new wt gets -it's own new window. +its own new window. If glomming is disabled, then the Monarch will call back to the peasant and tell it to run the provided commandline. The monarch will use the return value of @@ -114,10 +114,10 @@ In this scenario, we want the new tab to be spawned in the current working directory of WT[2], not WT[1]. So when WT[1] is about to run the commands that were passed to WT[2], WT[1] will need to: -* First, stash it's own CWD +* First, stash its own CWD * Change to the CWD of WT[2] * Run the commands from WT[2] -* Then return to it's original CWD. +* Then return to its original CWD. So, as a part of the interface that a peasant uses to communicate the startup commandline to the monarch, we should also include the current working @@ -130,7 +130,7 @@ current window, as opposed to always creating a new window. Presume we have the ability to communicate between different window processes. The logical extension of this scenario would be "run a `wt` commandline in _any_ given WT window". -Each window process will have it's own unique ID assigned to it by the monarch. +Each window process will have its own unique ID assigned to it by the monarch. This ID will be a positive number. Windows can also have names assigned to them. These names are strings that the user specifies. A window will always have an ID, but not necessarily a name. Running a command in a given window with ID N @@ -145,7 +145,7 @@ wt.exe --window N new-tab ; split-pane More formally, we will add the following parameter to the top-level `wt` command: -#### `--window,-w window-id` +#### `--window,-w ` Run these commands in the given Windows Terminal session. This enables opening new tabs, splits, etc. in already running Windows Terminal windows. * If `window-id` is `0`, run the given commands in _the current window_. @@ -183,7 +183,7 @@ as the window executing the command. To solve this issue, we'll other than attempting to use the `WT_SESSION` environment variable. If a `wt.exe` process -is spawned and that's in it's environment variables, it could try and ask the +is spawned and that's in its environment variables, it could try and ask the monarch for the peasant who's hosting the session corresponding to that GUID. This is more of a theoretical solution than anything else. @@ -477,7 +477,7 @@ This is a list of actionable tasks generated as described by this spec: ```sh man ping > wt -w 0 split-pane cat ``` - Is there some way for WT to pass it's stdin/out handles to the child process + Is there some way for WT to pass its stdin/out handles to the child process it's creating? This is _not_ related to the current spec at hand, just something the author considered while writing the spec. This likely belongs over in [#492], or in its own spec.