Skip to content

Commit

Permalink
Add support for running a commandline in another WT window (#8898)
Browse files Browse the repository at this point in the history
## Summary of the Pull Request

**If you're reading this PR and haven't signed off on #8135, go there first.**

![window-management-000](https://user-images.githubusercontent.com/18356694/103932910-25199380-50e8-11eb-97e3-594a31da62d2.gif)

This provides the basic parts of the implementation of #4472. Namely:
* We add support for the `--window,-w <window-id>` argument to `wt.exe`, to allow a commandline to be given to another window.
    * If `window-id` is `0`, run the given commands in _the current window_.
    * If `window-id` is a negative number, run the commands in a _new_ Terminal window.
    * If `window-id` is the ID of an existing window, then run the commandline in that window.
    * If `window-id` is _not_ the ID of an existing window, create a new window. That window will be assigned the ID provided in the commandline. The provided subcommands will be run in that new window.
    * If `window-id` is omitted, then create a new window.


## References
* Spec: #8135
* Megathread: #5000
* Project: projects/5

## PR Checklist
* [x] Closes #4472
* [x] I work here
* [x] Tests added/passed
* [ ] Requires documentation to be updated - **sure does**

## Detailed Description of the Pull Request / Additional comments

Note that `wt -w 1 -d c:\foo cmd.exe` does work, by causing window 1 to change 

There are limitations, and there are plenty of things to work on in the future:
* [ ] We don't support names for windows yet
* [ ] We don't support window glomming by default, or a setting to configure what happens when `-w` is omitted. I thought it best to lay the groundwork first, then come back to that.
* [ ] `-w 0` currently just uses the "last activated" window, not "the current". There's more follow-up work to try and smartly find the actual window we're being called from.
* [ ] Basically anything else that's listed in projects/5.

I'm cutting this PR where it currently is, because this is already a huge PR. I believe the remaining tasks will all be easier to land, once this is in. 

## Validation Steps Performed

I've been creating windows, and closing them, and running cmdlines for a while now. I'm gonna keep doing that while the PR is open, till no bugs remain.

# TODOs
* [x] There are a bunch of `GetID`, `GetPID` calls that aren't try/caught 😬 
  -  [x] `Monarch.cpp`
  -  [x] `Peasant.cpp`
  -  [x] `WindowManager.cpp`
  -  [x] `AppHost.cpp`
* [x] If the monarch gets hung, then _you can't launch any Terminals_ 😨 We should handle this gracefully.
  - Proposed idea: give the Monarch some time to respond to a proposal for a commandline. If there's no response in that timeframe, this window is now a _hermit_, outside of society entirely. It can't be elected Monarch. It can't receive command lines. It has no ID.  
  	- Could we gracefully recover from such a state? maybe, probably not though.
    -  Same deal if a peasant hangs, it could end up hanging the monarch, right? Like if you do `wt -w 2`, and `2` is hung, then does the monarch get hung waiting on the hung peasant?
  - After talking with @miniksa, **we're gonna punt this from the initial implementation**. If people legit hit this in the wild, we'll fix it then.
  • Loading branch information
zadjii-msft authored Feb 10, 2021
1 parent 8b2cdfd commit 03ebe51
Show file tree
Hide file tree
Showing 37 changed files with 1,585 additions and 92 deletions.
1 change: 1 addition & 0 deletions .github/actions/spelling/expect/web.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ fixterms
uk
winui
appshellintegration
cppreference
gfycat
what3words
11 changes: 7 additions & 4 deletions OpenConsole.sln
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UnitTests_Remoting", "src\c
{27B5AAEB-A548-44CF-9777-F8BAA32AF7AE} = {27B5AAEB-A548-44CF-9777-F8BAA32AF7AE}
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "wpf", "wpf", "{4DAF0299-495E-4CD1-A982-9BAC16A45932}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
AuditMode|Any CPU = AuditMode|Any CPU
Expand Down Expand Up @@ -2475,7 +2477,7 @@ Global
{43CE4CE5-0010-4B99-9569-672670D26E26}.AuditMode|DotNet_x64Test.ActiveCfg = AuditMode|Win32
{43CE4CE5-0010-4B99-9569-672670D26E26}.AuditMode|DotNet_x86Test.ActiveCfg = AuditMode|Win32
{43CE4CE5-0010-4B99-9569-672670D26E26}.AuditMode|x64.ActiveCfg = Release|x64
{43CE4CE5-0010-4B99-9569-672670D26E26}.AuditMode|x64.Build.0 = AuditMode|x64
{43CE4CE5-0010-4B99-9569-672670D26E26}.AuditMode|x64.Build.0 = Release|x64
{43CE4CE5-0010-4B99-9569-672670D26E26}.AuditMode|x86.ActiveCfg = AuditMode|Win32
{43CE4CE5-0010-4B99-9569-672670D26E26}.AuditMode|x86.Build.0 = AuditMode|Win32
{43CE4CE5-0010-4B99-9569-672670D26E26}.Debug|Any CPU.ActiveCfg = Debug|Win32
Expand Down Expand Up @@ -2613,8 +2615,8 @@ Global
{05500DEF-2294-41E3-AF9A-24E580B82836} = {89CDCC5C-9F53-4054-97A4-639D99F169CD}
{1E4A062E-293B-4817-B20D-BF16B979E350} = {89CDCC5C-9F53-4054-97A4-639D99F169CD}
{34DE34D3-1CD6-4EE3-8BD9-A26B5B27EC73} = {89CDCC5C-9F53-4054-97A4-639D99F169CD}
{84848BFA-931D-42CE-9ADF-01EE54DE7890} = {59840756-302F-44DF-AA47-441A9D673202}
{376FE273-6B84-4EB5-8B30-8DE9D21B022C} = {59840756-302F-44DF-AA47-441A9D673202}
{84848BFA-931D-42CE-9ADF-01EE54DE7890} = {4DAF0299-495E-4CD1-A982-9BAC16A45932}
{376FE273-6B84-4EB5-8B30-8DE9D21B022C} = {4DAF0299-495E-4CD1-A982-9BAC16A45932}
{CA5CAD1A-9333-4D05-B12A-1905CBF112F9} = {BDB237B6-1D1D-400F-84CC-40A58FA59C8E}
{CA5CAD1A-9A12-429C-B551-8562EC954746} = {59840756-302F-44DF-AA47-441A9D673202}
{CA5CAD1A-B11C-4DDB-A4FE-C3AFAE9B5506} = {BDB237B6-1D1D-400F-84CC-40A58FA59C8E}
Expand All @@ -2634,7 +2636,7 @@ Global
{024052DE-83FB-4653-AEA4-90790D29D5BD} = {E8F24881-5E37-4362-B191-A3BA0ED7F4EB}
{067F0A06-FCB7-472C-96E9-B03B54E8E18D} = {59840756-302F-44DF-AA47-441A9D673202}
{6BAE5851-50D5-4934-8D5E-30361A8A40F3} = {81C352DB-1818-45B7-A284-18E259F1CC87}
{1588FD7C-241E-4E7D-9113-43735F3E6BAD} = {59840756-302F-44DF-AA47-441A9D673202}
{1588FD7C-241E-4E7D-9113-43735F3E6BAD} = {4DAF0299-495E-4CD1-A982-9BAC16A45932}
{506FD703-BAA7-4F6E-9361-64F550EC8FCA} = {59840756-302F-44DF-AA47-441A9D673202}
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32} = {59840756-302F-44DF-AA47-441A9D673202}
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907} = {59840756-302F-44DF-AA47-441A9D673202}
Expand All @@ -2645,6 +2647,7 @@ Global
{43CE4CE5-0010-4B99-9569-672670D26E26} = {59840756-302F-44DF-AA47-441A9D673202}
{27B5AAEB-A548-44CF-9777-F8BAA32AF7AE} = {59840756-302F-44DF-AA47-441A9D673202}
{68A10CD3-AA64-465B-AF5F-ED4E9700543C} = {BDB237B6-1D1D-400F-84CC-40A58FA59C8E}
{4DAF0299-495E-4CD1-A982-9BAC16A45932} = {59840756-302F-44DF-AA47-441A9D673202}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {3140B1B7-C8EE-43D1-A772-D82A7061A271}
Expand Down
1 change: 0 additions & 1 deletion src/cascadia/CascadiaPackage/CascadiaPackage.wapproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
<Import Project="..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
<Import Project="$(OpenConsoleDir)src\wap-common.build.pre.props" />
<PropertyGroup Label="Configuration">

<TargetPlatformVersion>10.0.18362.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.18362.0</TargetPlatformMinVersion>
<!--
Expand Down
4 changes: 2 additions & 2 deletions src/cascadia/Remoting/CommandlineArgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
// It must be defined after CommandlineArgs.g.cpp, otherwise the compiler
// will give you just the most impossible template errors to try and
// decipher.
void CommandlineArgs::Args(winrt::array_view<const winrt::hstring> const& value)
void CommandlineArgs::Commandline(winrt::array_view<const winrt::hstring> const& value)
{
_args = { value.begin(), value.end() };
}

winrt::com_array<winrt::hstring> CommandlineArgs::Args()
winrt::com_array<winrt::hstring> CommandlineArgs::Commandline()
{
return winrt::com_array<winrt::hstring>{ _args.begin(), _args.end() };
}
Expand Down
4 changes: 2 additions & 2 deletions src/cascadia/Remoting/CommandlineArgs.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation

winrt::hstring CurrentDirectory() { return _cwd; };

void Args(winrt::array_view<const winrt::hstring> const& value);
winrt::com_array<winrt::hstring> Args();
void Commandline(winrt::array_view<const winrt::hstring> const& value);
winrt::com_array<winrt::hstring> Commandline();

private:
winrt::com_array<winrt::hstring> _args;
Expand Down
5 changes: 5 additions & 0 deletions src/cascadia/Remoting/FindTargetWindowArgs.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "pch.h"
#include "FindTargetWindowArgs.h"
#include "FindTargetWindowArgs.g.cpp"
35 changes: 35 additions & 0 deletions src/cascadia/Remoting/FindTargetWindowArgs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*++
Copyright (c) Microsoft Corporation
Licensed under the MIT license.
Class Name:
- FindTargetWindowArgs.h
Abstract:
- This is a helper class for determining which window a specific commandline is
intended for. The Monarch will create one of these, then toss it over to
TerminalApp. TerminalApp actually contains the logic for parsing a
commandline, as well as settings like the windowing behavior. Once the
TerminalApp determines the correct window, it'll fill in the
ResultTargetWindow property. The monarch will then read that value out to
invoke the commandline in the appropriate window.
--*/

#pragma once

#include "FindTargetWindowArgs.g.h"
#include "../cascadia/inc/cppwinrt_utils.h"

namespace winrt::Microsoft::Terminal::Remoting::implementation
{
struct FindTargetWindowArgs : public FindTargetWindowArgsT<FindTargetWindowArgs>
{
GETSET_PROPERTY(winrt::Microsoft::Terminal::Remoting::CommandlineArgs, Args, nullptr);
GETSET_PROPERTY(int, ResultTargetWindow, -1);

public:
FindTargetWindowArgs(winrt::Microsoft::Terminal::Remoting::CommandlineArgs args) :
_Args{ args } {};
};
}
19 changes: 19 additions & 0 deletions src/cascadia/Remoting/Microsoft.Terminal.RemotingLib.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,15 @@
<ClInclude Include="Monarch.h">
<DependentUpon>Monarch.idl</DependentUpon>
</ClInclude>
<ClInclude Include="FindTargetWindowArgs.h">
<DependentUpon>Monarch.idl</DependentUpon>
</ClInclude>
<ClInclude Include="ProposeCommandlineResult.h">
<DependentUpon>Monarch.idl</DependentUpon>
</ClInclude>
<ClInclude Include="WindowActivatedArgs.h">
<DependentUpon>Peasant.idl</DependentUpon>
</ClInclude>
<ClInclude Include="pch.h" />
<ClInclude Include="MonarchFactory.h" />
<ClInclude Include="Peasant.h">
Expand All @@ -36,6 +45,15 @@
<ClCompile Include="Monarch.cpp">
<DependentUpon>Monarch.idl</DependentUpon>
</ClCompile>
<ClCompile Include="FindTargetWindowArgs.cpp">
<DependentUpon>Monarch.idl</DependentUpon>
</ClCompile>
<ClCompile Include="ProposeCommandlineResult.cpp">
<DependentUpon>Monarch.idl</DependentUpon>
</ClCompile>
<ClCompile Include="WindowActivatedArgs.cpp">
<DependentUpon>Peasant.idl</DependentUpon>
</ClCompile>
<ClCompile Include="pch.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
Expand All @@ -49,6 +67,7 @@
<DependentUpon>Peasant.idl</DependentUpon>
</ClCompile>
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
<ClCompile Include="init.cpp" />
</ItemGroup>
<!-- ========================= idl Files ======================== -->
<ItemGroup>
Expand Down
Loading

0 comments on commit 03ebe51

Please sign in to comment.