2019-11-07 22:10:58 +01:00
|
|
|
// Copyright (c) Microsoft Corporation.
|
|
|
|
// Licensed under the MIT license.
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "AppLogic.g.h"
|
Add support for naming windows with the `-w` parameter (#9300)
This finishes the implementation of `--window` to also accept a string
as the "name" of the window. So you can say
```sh
wt -w foo new-tab
wt -w foo split-pane
```
and have both those commands execute in the same window, the one named
"foo". This is just slightly more ergonomic than manually using the IDs
of windows. In the future, I'll be working on renaming windows, and
displaying these names.
> #### `--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 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 `windowingBehavior` when
> determining which window to run the command in.
Before this PR, I think we didn't actually properly support assigning
the id with `wt -w 12345`. If `12345` didn't exist, it would make a new
window, but just assign it the next id, not assign it 12345.
## References
* #4472, #8135
* https://github.com/microsoft/terminal/projects/5
## Validation Steps Performed
Ran tests
Messed with naming windows, working as expected.
Closes https://github.com/microsoft/terminal/projects/5#card-51431478
2021-03-17 20:28:01 +01:00
|
|
|
#include "FindTargetWindowResult.g.h"
|
2019-11-07 22:10:58 +01:00
|
|
|
#include "TerminalPage.h"
|
2020-09-04 01:35:41 +02:00
|
|
|
#include "Jumplist.h"
|
2019-11-07 22:10:58 +01:00
|
|
|
#include "../../cascadia/inc/cppwinrt_utils.h"
|
|
|
|
|
2021-02-22 19:50:39 +01:00
|
|
|
#ifdef UNIT_TESTING
|
|
|
|
// fwdecl unittest classes
|
|
|
|
namespace TerminalAppLocalTests
|
|
|
|
{
|
|
|
|
class CommandlineTest;
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
2019-11-07 22:10:58 +01:00
|
|
|
namespace winrt::TerminalApp::implementation
|
|
|
|
{
|
Add support for naming windows with the `-w` parameter (#9300)
This finishes the implementation of `--window` to also accept a string
as the "name" of the window. So you can say
```sh
wt -w foo new-tab
wt -w foo split-pane
```
and have both those commands execute in the same window, the one named
"foo". This is just slightly more ergonomic than manually using the IDs
of windows. In the future, I'll be working on renaming windows, and
displaying these names.
> #### `--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 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 `windowingBehavior` when
> determining which window to run the command in.
Before this PR, I think we didn't actually properly support assigning
the id with `wt -w 12345`. If `12345` didn't exist, it would make a new
window, but just assign it the next id, not assign it 12345.
## References
* #4472, #8135
* https://github.com/microsoft/terminal/projects/5
## Validation Steps Performed
Ran tests
Messed with naming windows, working as expected.
Closes https://github.com/microsoft/terminal/projects/5#card-51431478
2021-03-17 20:28:01 +01:00
|
|
|
struct FindTargetWindowResult : FindTargetWindowResultT<FindTargetWindowResult>
|
|
|
|
{
|
|
|
|
WINRT_PROPERTY(int32_t, WindowId, -1);
|
|
|
|
WINRT_PROPERTY(winrt::hstring, WindowName, L"");
|
|
|
|
|
|
|
|
public:
|
|
|
|
FindTargetWindowResult(const int32_t id, const winrt::hstring& name) :
|
|
|
|
_WindowId{ id }, _WindowName{ name } {};
|
|
|
|
|
|
|
|
FindTargetWindowResult(const int32_t id) :
|
|
|
|
FindTargetWindowResult(id, L""){};
|
|
|
|
};
|
|
|
|
|
2020-11-30 20:51:42 +01:00
|
|
|
struct AppLogic : AppLogicT<AppLogic, IInitializeWithWindow>
|
2019-11-07 22:10:58 +01:00
|
|
|
{
|
|
|
|
public:
|
2020-04-07 20:35:05 +02:00
|
|
|
static AppLogic* Current() noexcept;
|
2020-10-06 18:56:59 +02:00
|
|
|
static const Microsoft::Terminal::Settings::Model::CascadiaSettings CurrentAppSettings();
|
2020-04-07 20:35:05 +02:00
|
|
|
|
2019-11-07 22:10:58 +01:00
|
|
|
AppLogic();
|
|
|
|
~AppLogic() = default;
|
|
|
|
|
2020-11-30 20:51:42 +01:00
|
|
|
STDMETHODIMP Initialize(HWND hwnd);
|
|
|
|
|
2019-11-07 22:10:58 +01:00
|
|
|
void Create();
|
2019-12-09 20:07:08 +01:00
|
|
|
bool IsUwp() const noexcept;
|
2019-11-26 01:30:45 +01:00
|
|
|
void RunAsUwp();
|
2020-03-11 16:52:09 +01:00
|
|
|
bool IsElevated() const noexcept;
|
2019-11-07 22:10:58 +01:00
|
|
|
void LoadSettings();
|
2020-10-06 18:56:59 +02:00
|
|
|
[[nodiscard]] Microsoft::Terminal::Settings::Model::CascadiaSettings GetSettings() const noexcept;
|
2019-11-07 22:10:58 +01:00
|
|
|
|
2020-01-27 16:34:12 +01:00
|
|
|
int32_t SetStartupCommandline(array_view<const winrt::hstring> actions);
|
Add support for running a commandline in another WT window (#8898)
## 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.
2021-02-10 12:28:09 +01:00
|
|
|
int32_t ExecuteCommandline(array_view<const winrt::hstring> actions, const winrt::hstring& cwd);
|
Add support for naming windows with the `-w` parameter (#9300)
This finishes the implementation of `--window` to also accept a string
as the "name" of the window. So you can say
```sh
wt -w foo new-tab
wt -w foo split-pane
```
and have both those commands execute in the same window, the one named
"foo". This is just slightly more ergonomic than manually using the IDs
of windows. In the future, I'll be working on renaming windows, and
displaying these names.
> #### `--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 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 `windowingBehavior` when
> determining which window to run the command in.
Before this PR, I think we didn't actually properly support assigning
the id with `wt -w 12345`. If `12345` didn't exist, it would make a new
window, but just assign it the next id, not assign it 12345.
## References
* #4472, #8135
* https://github.com/microsoft/terminal/projects/5
## Validation Steps Performed
Ran tests
Messed with naming windows, working as expected.
Closes https://github.com/microsoft/terminal/projects/5#card-51431478
2021-03-17 20:28:01 +01:00
|
|
|
TerminalApp::FindTargetWindowResult FindTargetWindow(array_view<const winrt::hstring> actions);
|
2020-05-04 22:56:15 +02:00
|
|
|
winrt::hstring ParseCommandlineMessage();
|
|
|
|
bool ShouldExitEarly();
|
2020-01-27 16:34:12 +01:00
|
|
|
|
2020-07-14 23:02:18 +02:00
|
|
|
bool FocusMode() const;
|
|
|
|
bool Fullscreen() const;
|
|
|
|
bool AlwaysOnTop() const;
|
2020-04-07 20:35:05 +02:00
|
|
|
|
2021-03-30 18:08:03 +02:00
|
|
|
void IdentifyWindow();
|
Add support for renaming windows (#9662)
## Summary of the Pull Request
This PR adds support for renaming windows.
![window-renaming-000](https://user-images.githubusercontent.com/18356694/113034344-9a30be00-9157-11eb-9443-975f3c294f56.gif)
![window-renaming-001](https://user-images.githubusercontent.com/18356694/113034452-b5033280-9157-11eb-9e35-e5ac80fef0bc.gif)
It does so through two new actions:
* `renameWindow` takes a `name` parameter, and attempts to set the window's name
to the provided name. This is useful if you always want to hit <kbd>F3</kbd>
and rename a window to "foo" (READ: probably not that useful)
* `openWindowRenamer` is more interesting: it opens a `TeachingTip` with a
`TextBox`. When the user hits Ok, it'll request a rename for the provided
value. This lets the user pick a new name for the window at runtime.
In both cases, if there's already a window with that name, then the monarch will
reject the rename, and pop a `Toast` in the window informing the user that the
rename failed. Nifty!
## References
* Builds on the toasts from #9523
* #5000 - process model megathread
## PR Checklist
* [x] Closes https://github.com/microsoft/terminal/projects/5#card-50771747
* [x] I work here
* [x] Tests addded (and pass with the help of #9660)
* [ ] Requires documentation to be updated
## Detailed Description of the Pull Request / Additional comments
I'm sending this PR while finishing up the tests. I figured I'll have time to sneak them in before I get the necessary reviews.
> PAIN: We can't immediately focus the textbox in the TeachingTip. It's
> not technically focusable until it is opened. However, it doesn't
> provide an even tto tell us when it is opened. That's tracked in
> microsoft/microsoft-ui-xaml#1607. So for now, the user _needs_ to
> click on the text box manually.
> We're also not using a ContentDialog for this, because in Xaml
> Islands a text box in a ContentDialog won't recieve _any_ keypresses.
> Fun!
## Validation Steps Performed
I've been playing with
```json
{ "keys": "f1", "command": "identifyWindow" },
{ "keys": "f2", "command": "identifyWindows" },
{ "keys": "f3", "command": "openWindowRenamer" },
{ "keys": "f4", "command": { "action": "renameWindow", "name": "foo" } },
{ "keys": "f5", "command": { "action": "renameWindow", "name": "bar" } },
```
and they seem to work as expected
2021-04-02 18:00:04 +02:00
|
|
|
void RenameFailed();
|
2021-03-30 18:08:03 +02:00
|
|
|
winrt::hstring WindowName();
|
|
|
|
void WindowName(const winrt::hstring& name);
|
|
|
|
uint64_t WindowId();
|
|
|
|
void WindowId(const uint64_t& id);
|
2021-04-26 21:36:23 +02:00
|
|
|
bool IsQuakeWindow() const noexcept;
|
2021-03-30 18:08:03 +02:00
|
|
|
|
Add support for running a `wt` commandline in the curent window WITH A KEYBINDING (#6537)
## Summary of the Pull Request
Adds a execute commandline action (`wt`), which lets a user bind a key to a specific `wt` commandline. This commandline will get parsed and run _in the current window_.
## References
* Related to #4472
* Related to #5400 - I need this for the commandline mode of the Command Palette
* Related to #5970
## PR Checklist
* [x] Closes oh, there's not actually an issue for this.
* [x] I work here
* [x] Tests added/passed
* [ ] Requires documentation to be updated - yes it does
## Detailed Description of the Pull Request / Additional comments
One important part of this change concerns how panes are initialized at runtime. We've had some persistent trouble with initializing multiple panes, because they rely on knowing how big they'll actually be, to be able to determine if they can split again.
We previously worked around this by ignoring the size check when we were in "startup", processing an initial commandline. This PR however requires us to be able to know the initial size of a pane at runtime, but before the parents have necessarily been added to the tree, or had their renderer's set up.
This led to the development of `Pane::PreCalculateCanSplit`, which is very highly similar to `Pane::PreCalculateAutoSplit`. This method attempts to figure out how big a pane _will_ take, before the parent has necessarily laid out.
This also involves a small change to `TermControl`, because if its renderer hasn't been set up yet, it'll always think the font is `{0, fontHeight}`, which will let the Terminal keep splitting in the x direction. This change also makes the TermControl set up a renderer to get the real font size when it hasn't yet been initialized.
## Validation Steps Performed
This was what the json blob I was using for testing evolved into
```json
{
"command": {
"action":"wt",
"commandline": "new-tab cmd.exe /k #work 15 ; split-pane cmd.exe /k #work 15 ; split-pane cmd.exe /k media-commandline ; new-tab powershell dev\\symbols.ps1 ; new-tab -p \"Ubuntu\" ; new-tab -p \"haunter.gif\" ; focus-tab -t 0",
},
"keys": ["ctrl+shift+n"]
}
```
I also added some tests.
# TODO
* [x] Creating a `{ "command": "wt" }` action without a commandline will spawn a new `wt.exe` process?
- Probably should just do nothing for the empty string
2020-07-17 23:05:29 +02:00
|
|
|
Windows::Foundation::Size GetLaunchDimensions(uint32_t dpi);
|
Add `centerOnLaunch` setting (#9036)
This PR is a resurrection of #8414. @Hegunumo has apparently deleted
their account, but the contribution was still valuable. I'm just here to
get it across the finish line.
This PR adds new global setting `centerOnLaunch`. When set to `true`,
the Terminal window will be centered on the display it opens on.
So the interactions are like:
* `initialPos: x,y`, `centered: true`, `launchMode: default`
center on the monitor that x,y is on
* `initialPos: x,y`, `centered: true`, `launchMode: maximized`
maximized on the monitor that x,y is on (centered adds nothing)
* `initialPos: <omitted>`, `centered: true`, `launchMode: default`
center on the default monitor
* `initialPos: <omitted>`, `centered: true`, `launchMode: focus`
center, focus mode on the default monitor
* `initialPos: <omitted>`, `centered: true`, `launchMode: maximized`
maximized on the default monitor (centered adds nothing)
## Validation Steps Performed
I've played with it on multiple different monitors, and it seems to work
on all of them.
Closes #8414 (original PR)
Closes #7722
Co-authored-by: Kiminori Kaburagi <yukawa_hidenori@icloud.com>
2021-02-19 23:30:24 +01:00
|
|
|
bool CenterOnLaunch();
|
2020-08-28 05:49:16 +02:00
|
|
|
TerminalApp::InitialPosition GetInitialPosition(int64_t defaultInitialX, int64_t defaultInitialY);
|
2019-11-07 22:10:58 +01:00
|
|
|
winrt::Windows::UI::Xaml::ElementTheme GetRequestedTheme();
|
2020-10-06 18:56:59 +02:00
|
|
|
Microsoft::Terminal::Settings::Model::LaunchMode GetLaunchMode();
|
2019-11-07 22:10:58 +01:00
|
|
|
bool GetShowTabsInTitlebar();
|
2020-11-02 19:51:29 +01:00
|
|
|
bool GetInitialAlwaysOnTop();
|
2020-01-08 22:19:23 +01:00
|
|
|
float CalcSnappedDimension(const bool widthOrHeight, const float dimension) const;
|
2019-11-07 22:10:58 +01:00
|
|
|
|
|
|
|
Windows::UI::Xaml::UIElement GetRoot() noexcept;
|
|
|
|
|
2021-05-24 23:56:46 +02:00
|
|
|
void SetInboundListener();
|
|
|
|
|
2019-11-07 22:10:58 +01:00
|
|
|
hstring Title();
|
|
|
|
void TitlebarClicked();
|
2020-08-15 01:44:39 +02:00
|
|
|
bool OnDirectKeyEvent(const uint32_t vkey, const uint8_t scanCode, const bool down);
|
2019-11-07 22:10:58 +01:00
|
|
|
|
|
|
|
void WindowCloseButtonClicked();
|
|
|
|
|
2020-11-18 23:24:11 +01:00
|
|
|
size_t GetLastActiveControlTaskbarState();
|
|
|
|
size_t GetLastActiveControlTaskbarProgress();
|
|
|
|
|
2020-07-01 21:43:28 +02:00
|
|
|
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::UI::Xaml::Controls::ContentDialogResult> ShowDialog(winrt::Windows::UI::Xaml::Controls::ContentDialog dialog);
|
|
|
|
|
Introduce ActionMap to Terminal Settings Model (#9621)
This entirely removes `KeyMapping` from the settings model, and builds on the work done in #9543 to consolidate all actions (key bindings and commands) into a unified data structure (`ActionMap`).
## References
#9428 - Spec
#6900 - Actions page
Closes #7441
## Detailed Description of the Pull Request / Additional comments
The important thing here is to remember that we're shifting our philosophy of how to interact/represent actions. Prior to this, the actions arrays in the JSON would be deserialized twice: once for key bindings, and again for commands. By thinking of every entry in the relevant JSON as a `Command`, we can remove a lot of the context switching between working with a key binding vs a command palette item.
#9543 allows us to make that shift. Given the work in that PR, we can now deserialize all of the relevant information from each JSON action item. This allows us to simplify `ActionMap::FromJson` to simply iterate over each JSON action item, deserialize it, and add it to our `ActionMap`.
Internally, our `ActionMap` operates as discussed in #9428 by maintaining a `_KeyMap` that points to an action ID, and using that action ID to retrieve the `Command` from the `_ActionMap`. Adding actions to the `ActionMap` automatically accounts for name/key-chord collisions. A `NameMap` can be constructed when requested; this is for the Command Palette.
Querying the `ActionMap` is fairly straightforward. Helper functions were needed to be able to distinguish an explicit unbinding vs the command not being found in the current layer. Internally, we store explicitly unbound names/key-chords as `ShortcutAction::Invalid` commands. However, we return `nullptr` when a query points to an unbound command. This is done to hide this complexity away from any caller.
The command palette still needs special handling for nested and iterable commands. Thankfully, the expansion of iterable commands is performed on an `IMapView`, so we can just expose `NameMap` as a consolidation of `ActionMap`'s `NameMap` with its parents. The same can be said for exposing key chords in nested commands.
## Validation Steps Performed
All local tests pass.
2021-05-05 06:50:13 +02:00
|
|
|
Windows::Foundation::Collections::IMapView<Microsoft::Terminal::Control::KeyChord, Microsoft::Terminal::Settings::Model::Command> GlobalHotkeys();
|
2021-04-29 00:13:28 +02:00
|
|
|
|
2019-11-07 22:10:58 +01:00
|
|
|
// -------------------------------- WinRT Events ---------------------------------
|
2021-03-18 23:02:39 +01:00
|
|
|
TYPED_EVENT(RequestedThemeChanged, winrt::Windows::Foundation::IInspectable, winrt::Windows::UI::Xaml::ElementTheme);
|
2021-04-29 00:13:28 +02:00
|
|
|
TYPED_EVENT(SettingsChanged, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable);
|
2019-11-07 22:10:58 +01:00
|
|
|
|
|
|
|
private:
|
2019-11-26 01:30:45 +01:00
|
|
|
bool _isUwp{ false };
|
2020-03-11 16:52:09 +01:00
|
|
|
bool _isElevated{ false };
|
2019-11-26 01:30:45 +01:00
|
|
|
|
2019-11-07 22:10:58 +01:00
|
|
|
// If you add controls here, but forget to null them either here or in
|
|
|
|
// the ctor, you're going to have a bad time. It'll mysteriously fail to
|
|
|
|
// activate the AppLogic.
|
|
|
|
// ALSO: If you add any UIElements as roots here, make sure they're
|
2020-02-10 21:40:01 +01:00
|
|
|
// updated in _ApplyTheme. The root currently is _root.
|
2019-11-07 22:10:58 +01:00
|
|
|
winrt::com_ptr<TerminalPage> _root{ nullptr };
|
|
|
|
|
2020-10-06 18:56:59 +02:00
|
|
|
Microsoft::Terminal::Settings::Model::CascadiaSettings _settings{ nullptr };
|
2019-11-07 22:10:58 +01:00
|
|
|
|
|
|
|
HRESULT _settingsLoadedResult;
|
|
|
|
winrt::hstring _settingsLoadExceptionText{};
|
|
|
|
|
|
|
|
bool _loadedInitialSettings;
|
|
|
|
|
|
|
|
wil::unique_folder_change_reader_nothrow _reader;
|
|
|
|
|
|
|
|
std::shared_mutex _dialogLock;
|
|
|
|
|
|
|
|
std::atomic<bool> _settingsReloadQueued{ false };
|
|
|
|
|
2020-06-01 23:57:30 +02:00
|
|
|
::TerminalApp::AppCommandlineArgs _appArgs;
|
2021-01-15 19:30:11 +01:00
|
|
|
::TerminalApp::AppCommandlineArgs _settingsAppArgs;
|
2020-06-01 23:57:30 +02:00
|
|
|
int _ParseArgs(winrt::array_view<const hstring>& args);
|
Add support for naming windows with the `-w` parameter (#9300)
This finishes the implementation of `--window` to also accept a string
as the "name" of the window. So you can say
```sh
wt -w foo new-tab
wt -w foo split-pane
```
and have both those commands execute in the same window, the one named
"foo". This is just slightly more ergonomic than manually using the IDs
of windows. In the future, I'll be working on renaming windows, and
displaying these names.
> #### `--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 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 `windowingBehavior` when
> determining which window to run the command in.
Before this PR, I think we didn't actually properly support assigning
the id with `wt -w 12345`. If `12345` didn't exist, it would make a new
window, but just assign it the next id, not assign it 12345.
## References
* #4472, #8135
* https://github.com/microsoft/terminal/projects/5
## Validation Steps Performed
Ran tests
Messed with naming windows, working as expected.
Closes https://github.com/microsoft/terminal/projects/5#card-51431478
2021-03-17 20:28:01 +01:00
|
|
|
static TerminalApp::FindTargetWindowResult _doFindTargetWindow(winrt::array_view<const hstring> args,
|
|
|
|
const Microsoft::Terminal::Settings::Model::WindowingMode& windowingBehavior);
|
2020-06-01 23:57:30 +02:00
|
|
|
|
2019-11-07 22:10:58 +01:00
|
|
|
void _ShowLoadErrorsDialog(const winrt::hstring& titleKey, const winrt::hstring& contentKey, HRESULT settingsLoadedResult);
|
|
|
|
void _ShowLoadWarningsDialog();
|
2020-11-04 22:44:53 +01:00
|
|
|
bool _IsKeyboardServiceEnabled();
|
|
|
|
void _ShowKeyboardServiceDisabledDialog();
|
2019-11-07 22:10:58 +01:00
|
|
|
|
2021-06-11 01:24:21 +02:00
|
|
|
void _ApplyLanguageSettingChange();
|
Converts Dispatcher().RunAsync to WinRT Coroutines (#4051)
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? -->
## Summary of the Pull Request
This PR turns all* instances of `Dispatcher().RunAsync` to WinRT coroutines 👌.
This was good coding fodder to fill my plane ride ✈️. Enjoy your holidays everyone!
*With the exception of three functions whose signatures cannot be changed due to inheritance and function overriding in `TermControlAutomationPeer` [`L44`](https://github.com/microsoft/terminal/blob/master/src/cascadia/TerminalControl/TermControlAutomationPeer.cpp#L44), [`L58`](https://github.com/microsoft/terminal/blob/master/src/cascadia/TerminalControl/TermControlAutomationPeer.cpp#L58), [`L72`](https://github.com/microsoft/terminal/blob/master/src/cascadia/TerminalControl/TermControlAutomationPeer.cpp#L72).
<!-- Other than the issue solved, is this relevant to any other issues/existing PRs? -->
## References
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [x] Closes #3919
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed
* [ ] Requires documentation to be updated
* [x] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #3919
<!-- Provide a more detailed description of the PR, other things fixed or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
My thought pattern here was to minimally disturb the existing code where possible. So where I could, I converted existing functions into coroutine using functions (like in the [core example](https://github.com/microsoft/terminal/issues/3919#issue-536598706)). For ~the most part~ all instances, I used the format where [`this` is accessed safely within a locked scope](https://github.com/microsoft/terminal/issues/3919#issuecomment-564730620). Some function signatures were changed to take objects by value instead of reference, so the coroutines don't crash when the objects are accessed past their original lifetime. The [copy](https://github.com/microsoft/terminal/blob/master/src/cascadia/TerminalApp/TerminalPage.cpp#L1132) and [paste](https://github.com/microsoft/terminal/blob/master/src/cascadia/TerminalApp/TerminalPage.cpp#L1170) event handler entry points were originally set to a high priority; however, the WinRT coroutines don't appear to support a priority scheme so this priority setting was not preserved in the translation.
<!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
Compiles and runs, and for every event with a clear trigger repro, I triggered it to ensure crashes weren't introduced.
2020-01-10 04:29:49 +01:00
|
|
|
fire_and_forget _LoadErrorsDialogRoutine();
|
|
|
|
fire_and_forget _ShowLoadWarningsDialogRoutine();
|
|
|
|
fire_and_forget _RefreshThemeRoutine();
|
Add startup task, setting to launch application on login (#4908)
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? -->
## Summary of the Pull Request
This PR adds a new boolean global setting, startOnUserLogin, along with associated AppLogic to request enabling or disabling of the StartupTask. Added UAP5 extensions to AppX manifests.
<!-- Other than the issue solved, is this relevant to any other issues/existing PRs? -->
## References
#2189
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [x] Closes #2189
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [x] Tests added/passed
* [x] Requires documentation to be updated
* [x] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #2189
<!-- Provide a more detailed description of the PR, other things fixed or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
Please note, I'm a non-practicing C++ developer, there are a number of things I wasn't sure how to handle in the appropriate fashion, mostly around error handling and what probably looks like an incredibly naive (and messy) way to implement the async co_await behavior.
Error handling-wise, I found (don't ask me how!) that if you somehow mismatch the startup task's ID between the manifest and the call to `StartupTask::GetAsync(hstring taskId)`, you'll get a very opaque WinRT exception that boils down to a generic invalid argument message. This isn't likely to happen in the wild, but worth mentioning...
I had enough trouble getting myself familiarized with the project, environment, and C++/WinRT in general didn't want to try to tackle adding tests for this quite yet since (as I mentioned) I don't really know what I'm doing. I'm happy to give it a try with perhaps a bit of assistance in getting started 😃
Further work in this area of the application outside of this immediate PR might need to include adding an additional setting to contain launch args that the startup task can pass to the app so that users can specify a non-default profile to launch on start, window position (e.g., #653).
<!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
✔️ Default settings:
Given the user does not have the `startOnUserLogin` setting in their profile.json,
When the default settings are opened (via alt+click on Settings),
Then the global settings should contain the `"startOnUserLogin": false` token
✔️ Applying setting on application launch
Given the `startOnUserLogin` is `true` and
the `Windows Terminal` startup task is `disabled` and
the application is not running
When the application is launched
Then the `Windows Terminal` entry in the user's Startup list should be `enabled`
✔️ Applying setting on settings change
Given the `startOnUserLogin` is `true` and
the `Windows Terminal` startup task is `enabled` and
the application is running
When the `startOnUserLogin` setting is changed to `false` and
the settings file is saved to disk
Then the `Windows Terminal` startup task entry should be `disabled`
✔️ Setting is ignored when user has manually disabled startup
Given the `startOnUserLogin` is `true` and
the application is not running and
the `Windows Terminal` startup task has been set to `disabled` via user action
When the application is launched
Then the startup task should remain disabled and
the application should not throw an exception
#### note: Task Manager does not seem to re-scan startup task states after launch; the Settings -> Apps -> Startup page also requires closing or moving away to refresh the status of entries
2020-06-01 22:24:43 +02:00
|
|
|
fire_and_forget _ApplyStartupTaskStateChange();
|
Converts Dispatcher().RunAsync to WinRT Coroutines (#4051)
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? -->
## Summary of the Pull Request
This PR turns all* instances of `Dispatcher().RunAsync` to WinRT coroutines 👌.
This was good coding fodder to fill my plane ride ✈️. Enjoy your holidays everyone!
*With the exception of three functions whose signatures cannot be changed due to inheritance and function overriding in `TermControlAutomationPeer` [`L44`](https://github.com/microsoft/terminal/blob/master/src/cascadia/TerminalControl/TermControlAutomationPeer.cpp#L44), [`L58`](https://github.com/microsoft/terminal/blob/master/src/cascadia/TerminalControl/TermControlAutomationPeer.cpp#L58), [`L72`](https://github.com/microsoft/terminal/blob/master/src/cascadia/TerminalControl/TermControlAutomationPeer.cpp#L72).
<!-- Other than the issue solved, is this relevant to any other issues/existing PRs? -->
## References
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [x] Closes #3919
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed
* [ ] Requires documentation to be updated
* [x] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #3919
<!-- Provide a more detailed description of the PR, other things fixed or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
My thought pattern here was to minimally disturb the existing code where possible. So where I could, I converted existing functions into coroutine using functions (like in the [core example](https://github.com/microsoft/terminal/issues/3919#issue-536598706)). For ~the most part~ all instances, I used the format where [`this` is accessed safely within a locked scope](https://github.com/microsoft/terminal/issues/3919#issuecomment-564730620). Some function signatures were changed to take objects by value instead of reference, so the coroutines don't crash when the objects are accessed past their original lifetime. The [copy](https://github.com/microsoft/terminal/blob/master/src/cascadia/TerminalApp/TerminalPage.cpp#L1132) and [paste](https://github.com/microsoft/terminal/blob/master/src/cascadia/TerminalApp/TerminalPage.cpp#L1170) event handler entry points were originally set to a high priority; however, the WinRT coroutines don't appear to support a priority scheme so this priority setting was not preserved in the translation.
<!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
Compiles and runs, and for every event with a clear trigger repro, I triggered it to ensure crashes weren't introduced.
2020-01-10 04:29:49 +01:00
|
|
|
|
2019-11-07 22:10:58 +01:00
|
|
|
void _OnLoaded(const IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& eventArgs);
|
|
|
|
|
|
|
|
[[nodiscard]] HRESULT _TryLoadSettings() noexcept;
|
|
|
|
void _RegisterSettingsChange();
|
|
|
|
fire_and_forget _DispatchReloadSettings();
|
|
|
|
void _ReloadSettings();
|
|
|
|
|
|
|
|
void _ApplyTheme(const Windows::UI::Xaml::ElementTheme& newTheme);
|
|
|
|
|
2021-01-15 19:30:11 +01:00
|
|
|
bool _hasCommandLineArguments{ false };
|
|
|
|
bool _hasSettingsStartupActions{ false };
|
|
|
|
std::vector<Microsoft::Terminal::Settings::Model::SettingsLoadWarnings> _warnings;
|
|
|
|
|
2019-11-07 22:10:58 +01:00
|
|
|
// These are events that are handled by the TerminalPage, but are
|
|
|
|
// exposed through the AppLogic. This macro is used to forward the event
|
|
|
|
// directly to them.
|
|
|
|
FORWARDED_TYPED_EVENT(SetTitleBarContent, winrt::Windows::Foundation::IInspectable, winrt::Windows::UI::Xaml::UIElement, _root, SetTitleBarContent);
|
|
|
|
FORWARDED_TYPED_EVENT(TitleChanged, winrt::Windows::Foundation::IInspectable, winrt::hstring, _root, TitleChanged);
|
|
|
|
FORWARDED_TYPED_EVENT(LastTabClosed, winrt::Windows::Foundation::IInspectable, winrt::TerminalApp::LastTabClosedEventArgs, _root, LastTabClosed);
|
2020-07-14 23:02:18 +02:00
|
|
|
FORWARDED_TYPED_EVENT(FocusModeChanged, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable, _root, FocusModeChanged);
|
|
|
|
FORWARDED_TYPED_EVENT(FullscreenChanged, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable, _root, FullscreenChanged);
|
|
|
|
FORWARDED_TYPED_EVENT(AlwaysOnTopChanged, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable, _root, AlwaysOnTopChanged);
|
2020-11-18 23:55:10 +01:00
|
|
|
FORWARDED_TYPED_EVENT(RaiseVisualBell, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable, _root, RaiseVisualBell);
|
2020-11-18 23:24:11 +01:00
|
|
|
FORWARDED_TYPED_EVENT(SetTaskbarProgress, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable, _root, SetTaskbarProgress);
|
2021-03-30 18:08:03 +02:00
|
|
|
FORWARDED_TYPED_EVENT(IdentifyWindowsRequested, Windows::Foundation::IInspectable, Windows::Foundation::IInspectable, _root, IdentifyWindowsRequested);
|
Add support for renaming windows (#9662)
## Summary of the Pull Request
This PR adds support for renaming windows.
![window-renaming-000](https://user-images.githubusercontent.com/18356694/113034344-9a30be00-9157-11eb-9443-975f3c294f56.gif)
![window-renaming-001](https://user-images.githubusercontent.com/18356694/113034452-b5033280-9157-11eb-9e35-e5ac80fef0bc.gif)
It does so through two new actions:
* `renameWindow` takes a `name` parameter, and attempts to set the window's name
to the provided name. This is useful if you always want to hit <kbd>F3</kbd>
and rename a window to "foo" (READ: probably not that useful)
* `openWindowRenamer` is more interesting: it opens a `TeachingTip` with a
`TextBox`. When the user hits Ok, it'll request a rename for the provided
value. This lets the user pick a new name for the window at runtime.
In both cases, if there's already a window with that name, then the monarch will
reject the rename, and pop a `Toast` in the window informing the user that the
rename failed. Nifty!
## References
* Builds on the toasts from #9523
* #5000 - process model megathread
## PR Checklist
* [x] Closes https://github.com/microsoft/terminal/projects/5#card-50771747
* [x] I work here
* [x] Tests addded (and pass with the help of #9660)
* [ ] Requires documentation to be updated
## Detailed Description of the Pull Request / Additional comments
I'm sending this PR while finishing up the tests. I figured I'll have time to sneak them in before I get the necessary reviews.
> PAIN: We can't immediately focus the textbox in the TeachingTip. It's
> not technically focusable until it is opened. However, it doesn't
> provide an even tto tell us when it is opened. That's tracked in
> microsoft/microsoft-ui-xaml#1607. So for now, the user _needs_ to
> click on the text box manually.
> We're also not using a ContentDialog for this, because in Xaml
> Islands a text box in a ContentDialog won't recieve _any_ keypresses.
> Fun!
## Validation Steps Performed
I've been playing with
```json
{ "keys": "f1", "command": "identifyWindow" },
{ "keys": "f2", "command": "identifyWindows" },
{ "keys": "f3", "command": "openWindowRenamer" },
{ "keys": "f4", "command": { "action": "renameWindow", "name": "foo" } },
{ "keys": "f5", "command": { "action": "renameWindow", "name": "bar" } },
```
and they seem to work as expected
2021-04-02 18:00:04 +02:00
|
|
|
FORWARDED_TYPED_EVENT(RenameWindowRequested, Windows::Foundation::IInspectable, winrt::TerminalApp::RenameWindowRequestedArgs, _root, RenameWindowRequested);
|
2021-04-26 21:36:23 +02:00
|
|
|
FORWARDED_TYPED_EVENT(IsQuakeWindowChanged, Windows::Foundation::IInspectable, Windows::Foundation::IInspectable, _root, IsQuakeWindowChanged);
|
2021-05-27 19:14:12 +02:00
|
|
|
FORWARDED_TYPED_EVENT(SummonWindowRequested, Windows::Foundation::IInspectable, Windows::Foundation::IInspectable, _root, SummonWindowRequested);
|
2021-02-22 19:50:39 +01:00
|
|
|
|
|
|
|
#ifdef UNIT_TESTING
|
|
|
|
friend class TerminalAppLocalTests::CommandlineTest;
|
|
|
|
#endif
|
2019-11-07 22:10:58 +01:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace winrt::TerminalApp::factory_implementation
|
|
|
|
{
|
|
|
|
struct AppLogic : AppLogicT<AppLogic, implementation::AppLogic>
|
|
|
|
{
|
|
|
|
};
|
|
|
|
}
|