2019-08-17 00:43:51 +02:00
|
|
|
// Copyright (c) Microsoft Corporation.
|
|
|
|
// Licensed under the MIT license.
|
|
|
|
|
|
|
|
#include "pch.h"
|
|
|
|
#include "App.h"
|
|
|
|
|
|
|
|
#include "TerminalPage.h"
|
2021-02-20 00:51:30 +01:00
|
|
|
#include "../WinRTUtils/inc/WtExeUtils.h"
|
|
|
|
#include "../../types/inc/utils.hpp"
|
2019-08-17 00:43:51 +02:00
|
|
|
#include "Utils.h"
|
|
|
|
|
|
|
|
using namespace winrt::Windows::ApplicationModel::DataTransfer;
|
|
|
|
using namespace winrt::Windows::UI::Xaml;
|
|
|
|
using namespace winrt::Windows::UI::Text;
|
|
|
|
using namespace winrt::Windows::UI::Core;
|
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
|
|
|
using namespace winrt::Windows::Foundation::Collections;
|
2019-08-17 00:43:51 +02:00
|
|
|
using namespace winrt::Windows::System;
|
|
|
|
using namespace winrt::Microsoft::Terminal;
|
2020-10-06 18:56:59 +02:00
|
|
|
using namespace winrt::Microsoft::Terminal::Settings::Model;
|
2021-03-17 21:47:24 +01:00
|
|
|
using namespace winrt::Microsoft::Terminal::Control;
|
2019-08-17 00:43:51 +02:00
|
|
|
using namespace winrt::Microsoft::Terminal::TerminalConnection;
|
|
|
|
using namespace ::TerminalApp;
|
|
|
|
|
|
|
|
namespace winrt
|
|
|
|
{
|
|
|
|
namespace MUX = Microsoft::UI::Xaml;
|
|
|
|
using IInspectable = Windows::Foundation::IInspectable;
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace winrt::TerminalApp::implementation
|
|
|
|
{
|
2019-09-04 23:34:06 +02:00
|
|
|
void TerminalPage::_HandleOpenNewTabDropdown(const IInspectable& /*sender*/,
|
2020-10-06 18:56:59 +02:00
|
|
|
const ActionEventArgs& args)
|
2019-08-17 00:43:51 +02:00
|
|
|
{
|
|
|
|
_OpenNewTabDropdown();
|
|
|
|
args.Handled(true);
|
|
|
|
}
|
|
|
|
|
2019-09-04 23:34:06 +02:00
|
|
|
void TerminalPage::_HandleDuplicateTab(const IInspectable& /*sender*/,
|
2020-10-06 18:56:59 +02:00
|
|
|
const ActionEventArgs& args)
|
2019-08-17 00:43:51 +02:00
|
|
|
{
|
2021-03-08 13:16:56 +01:00
|
|
|
_DuplicateFocusedTab();
|
2019-08-17 00:43:51 +02:00
|
|
|
args.Handled(true);
|
|
|
|
}
|
|
|
|
|
2019-09-04 23:34:06 +02:00
|
|
|
void TerminalPage::_HandleCloseTab(const IInspectable& /*sender*/,
|
2020-10-06 18:56:59 +02:00
|
|
|
const ActionEventArgs& args)
|
2019-08-17 00:43:51 +02:00
|
|
|
{
|
|
|
|
_CloseFocusedTab();
|
|
|
|
args.Handled(true);
|
|
|
|
}
|
|
|
|
|
2019-09-04 23:34:06 +02:00
|
|
|
void TerminalPage::_HandleClosePane(const IInspectable& /*sender*/,
|
2020-10-06 18:56:59 +02:00
|
|
|
const ActionEventArgs& args)
|
2019-08-17 00:43:51 +02:00
|
|
|
{
|
|
|
|
_CloseFocusedPane();
|
|
|
|
args.Handled(true);
|
|
|
|
}
|
|
|
|
|
2019-09-17 07:43:27 +02:00
|
|
|
void TerminalPage::_HandleCloseWindow(const IInspectable& /*sender*/,
|
2020-10-06 18:56:59 +02:00
|
|
|
const ActionEventArgs& args)
|
2019-09-17 07:43:27 +02:00
|
|
|
{
|
2019-10-11 02:09:07 +02:00
|
|
|
CloseWindow();
|
2019-09-17 07:43:27 +02:00
|
|
|
args.Handled(true);
|
|
|
|
}
|
|
|
|
|
2019-09-04 23:34:06 +02:00
|
|
|
void TerminalPage::_HandleScrollUp(const IInspectable& /*sender*/,
|
2020-10-06 18:56:59 +02:00
|
|
|
const ActionEventArgs& args)
|
2019-08-17 00:43:51 +02:00
|
|
|
{
|
2020-10-27 02:19:52 +01:00
|
|
|
const auto& realArgs = args.ActionArgs().try_as<ScrollUpArgs>();
|
|
|
|
if (realArgs)
|
|
|
|
{
|
|
|
|
_Scroll(ScrollUp, realArgs.RowsToScroll());
|
|
|
|
args.Handled(true);
|
|
|
|
}
|
2019-08-17 00:43:51 +02:00
|
|
|
}
|
|
|
|
|
2019-09-04 23:34:06 +02:00
|
|
|
void TerminalPage::_HandleScrollDown(const IInspectable& /*sender*/,
|
2020-10-06 18:56:59 +02:00
|
|
|
const ActionEventArgs& args)
|
2019-08-17 00:43:51 +02:00
|
|
|
{
|
2020-10-27 02:19:52 +01:00
|
|
|
const auto& realArgs = args.ActionArgs().try_as<ScrollDownArgs>();
|
|
|
|
if (realArgs)
|
|
|
|
{
|
|
|
|
_Scroll(ScrollDown, realArgs.RowsToScroll());
|
|
|
|
args.Handled(true);
|
|
|
|
}
|
2019-08-17 00:43:51 +02:00
|
|
|
}
|
|
|
|
|
2019-09-04 23:34:06 +02:00
|
|
|
void TerminalPage::_HandleNextTab(const IInspectable& /*sender*/,
|
2020-10-06 18:56:59 +02:00
|
|
|
const ActionEventArgs& args)
|
2019-08-17 00:43:51 +02:00
|
|
|
{
|
Allow overriding tab switcher mode on command level (#9507)
## Summary of the Pull Request
Currently, when the MRU is enabled we lose the keybinding allowing us to
go forward/backward (aka right/left in LTR) in the tab view.
To fix that, this PR introduces "tabSwitcherMode" optional parameter to
the prevTab / nextTab commands.
If it is not provided the global setting will be used.
So if you want to go to adjacent tabs, even if MRU is enabled on the
system level you can use:
```
{ "command": { "action": "prevTab", "tabSwitcherMode": "inOrder" }, "keys": "ctrl+f1"}
{ "command": { "action": "nextTab", "tabSwitcherMode": "inOrder" }, "keys": "ctrl+f2"}
```
or even
```
{"command": { "action": "prevTab", "tabSwitcherMode": "disabled" }, "keys": "ctrl+f1"}
{ "command": { "action": "nextTab", "tabSwitcherMode": "disabled" }, "keys": "ctrl+f2"}
```
if you don't want tab switcher to show up
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [x] Closes https://github.com/microsoft/terminal/issues/9330
* [x] CLA signed.
* [x] Tests added/passed
* [ ] Documentation updated - not yet. Waiting for approval.
* [x] Schema updated.
* [ ] I've discussed this with core contributors already.
2021-03-23 23:00:07 +01:00
|
|
|
const auto& realArgs = args.ActionArgs().try_as<NextTabArgs>();
|
|
|
|
if (realArgs)
|
|
|
|
{
|
|
|
|
_SelectNextTab(true, realArgs.SwitcherMode());
|
|
|
|
args.Handled(true);
|
|
|
|
}
|
2019-08-17 00:43:51 +02:00
|
|
|
}
|
|
|
|
|
2019-09-04 23:34:06 +02:00
|
|
|
void TerminalPage::_HandlePrevTab(const IInspectable& /*sender*/,
|
2020-10-06 18:56:59 +02:00
|
|
|
const ActionEventArgs& args)
|
2019-08-17 00:43:51 +02:00
|
|
|
{
|
Allow overriding tab switcher mode on command level (#9507)
## Summary of the Pull Request
Currently, when the MRU is enabled we lose the keybinding allowing us to
go forward/backward (aka right/left in LTR) in the tab view.
To fix that, this PR introduces "tabSwitcherMode" optional parameter to
the prevTab / nextTab commands.
If it is not provided the global setting will be used.
So if you want to go to adjacent tabs, even if MRU is enabled on the
system level you can use:
```
{ "command": { "action": "prevTab", "tabSwitcherMode": "inOrder" }, "keys": "ctrl+f1"}
{ "command": { "action": "nextTab", "tabSwitcherMode": "inOrder" }, "keys": "ctrl+f2"}
```
or even
```
{"command": { "action": "prevTab", "tabSwitcherMode": "disabled" }, "keys": "ctrl+f1"}
{ "command": { "action": "nextTab", "tabSwitcherMode": "disabled" }, "keys": "ctrl+f2"}
```
if you don't want tab switcher to show up
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [x] Closes https://github.com/microsoft/terminal/issues/9330
* [x] CLA signed.
* [x] Tests added/passed
* [ ] Documentation updated - not yet. Waiting for approval.
* [x] Schema updated.
* [ ] I've discussed this with core contributors already.
2021-03-23 23:00:07 +01:00
|
|
|
const auto& realArgs = args.ActionArgs().try_as<PrevTabArgs>();
|
|
|
|
if (realArgs)
|
|
|
|
{
|
|
|
|
_SelectNextTab(false, realArgs.SwitcherMode());
|
|
|
|
args.Handled(true);
|
|
|
|
}
|
2019-08-17 00:43:51 +02:00
|
|
|
}
|
|
|
|
|
2020-08-12 15:46:53 +02:00
|
|
|
void TerminalPage::_HandleSendInput(const IInspectable& /*sender*/,
|
2020-10-06 18:56:59 +02:00
|
|
|
const ActionEventArgs& args)
|
2020-08-12 15:46:53 +02:00
|
|
|
{
|
|
|
|
if (args == nullptr)
|
|
|
|
{
|
|
|
|
args.Handled(false);
|
|
|
|
}
|
2020-10-06 18:56:59 +02:00
|
|
|
else if (const auto& realArgs = args.ActionArgs().try_as<SendInputArgs>())
|
2020-08-12 15:46:53 +02:00
|
|
|
{
|
|
|
|
const auto termControl = _GetActiveControl();
|
|
|
|
termControl.SendInput(realArgs.Input());
|
|
|
|
args.Handled(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-28 14:42:15 +01:00
|
|
|
void TerminalPage::_HandleSplitPane(const IInspectable& /*sender*/,
|
2020-10-06 18:56:59 +02:00
|
|
|
const ActionEventArgs& args)
|
2019-08-17 00:43:51 +02:00
|
|
|
{
|
2019-11-28 14:42:15 +01:00
|
|
|
if (args == nullptr)
|
|
|
|
{
|
|
|
|
args.Handled(false);
|
|
|
|
}
|
2020-10-06 18:56:59 +02:00
|
|
|
else if (const auto& realArgs = args.ActionArgs().try_as<SplitPaneArgs>())
|
2019-11-28 14:42:15 +01:00
|
|
|
{
|
Add `size` param to `splitPane` action, `split-pane` subcommand (#8543)
## Summary of the Pull Request
Adds a `size` parameter to `splitPane`. This takes a `float`, and specifies the portion of the parent pane that should be used to create the new one.
This also adds the param to the `split-pane` subcommand.
### Examples
| commandline | result |
| -- | -- |
| `wt ; sp -s .25` | ![image](https://user-images.githubusercontent.com/18356694/101784317-fb595680-3ac0-11eb-8248-782dc61957cf.png) |
| `wt ; sp -s .8` | ![image](https://user-images.githubusercontent.com/18356694/101784442-20e66000-3ac1-11eb-8f9b-fb45a73c9334.png) |
| `wt ; sp -s .8 ; sp -H -s .3` | ![image](https://user-images.githubusercontent.com/18356694/101784552-470c0000-3ac1-11eb-9deb-df37aaa36f01.png) |
## PR Checklist
* [x] Closes #6298
* [x] I work here
* [x] Tests added/passed
* [x] Docs PR: MicrosoftDocs/terminal#208
## Detailed Description of the Pull Request / Additional comments
I went with `size`, `--size,-s` rather than `percent`, because the arg is the (0,1) version of the size, not the (0%,100%) version.
## Validation Steps Performed
Added actions, played with the commandline, ran tests
2020-12-18 04:51:53 +01:00
|
|
|
_SplitPane(realArgs.SplitStyle(),
|
|
|
|
realArgs.SplitMode(),
|
|
|
|
// This is safe, we're already filtering so the value is (0, 1)
|
|
|
|
::base::saturated_cast<float>(realArgs.SplitSize()),
|
|
|
|
realArgs.TerminalArgs());
|
2019-11-28 14:42:15 +01:00
|
|
|
args.Handled(true);
|
|
|
|
}
|
2019-08-17 00:43:51 +02:00
|
|
|
}
|
|
|
|
|
2020-08-08 01:11:44 +02:00
|
|
|
void TerminalPage::_HandleTogglePaneZoom(const IInspectable& /*sender*/,
|
2020-10-06 18:56:59 +02:00
|
|
|
const ActionEventArgs& args)
|
2020-08-08 01:11:44 +02:00
|
|
|
{
|
2021-01-04 20:32:53 +01:00
|
|
|
if (const auto activeTab{ _GetFocusedTabImpl() })
|
2020-08-08 01:11:44 +02:00
|
|
|
{
|
2021-01-04 20:32:53 +01:00
|
|
|
// Don't do anything if there's only one pane. It's already zoomed.
|
|
|
|
if (activeTab->GetLeafPaneCount() > 1)
|
Make Tab an unsealed runtimeclass (and rename it to TabBase) (#8153)
In preparation for the Settings UI, we needed to make some changes to
Tab to abstract out shared, common functionality between different types
of tab. This is the result of that work. All code references to the
settings have been removed or reverted.
Contains changes from #8053, #7802.
The messages below only make sense in the context of the Settings UI,
which this pull request does not bring in. They do, however, provide
valuable information.
From #7802 (@leonMSFT):
> This PR's goal was to add an option to the `OpenSettings` keybinding to
> open the Settings UI in a tab. In order to implement that, a couple of
> changes had to be made to `Tab`, specifically:
>
> - Introduce a tab interface named `ITab`
> - Create/Rename two new Tab classes that implement `ITab` called
> `SettingsTab` and `TerminalTab`
>
From #8053:
> `TerminalTab` and `SettingsTab` share some implementation details. The
> close submenu introduced in #7728 is a good example of functionality
> that is consistent across all tabs. This PR transforms `ITab` from an
> interface, into an [unsealed runtime class] to de-duplicate some
> functionality. Most of the logic from `SettingsTab` was moved there
> because I expect the default behavior of a tab to resemble the
> `SettingsTab` over a `TerminalTab`.
>
> ## References
> Verified that Close submenu work was transferred over (#7728, #7961, #8010).
>
> ## Validation Steps Performed
> Check close submenu on first/last tab when multiple tabs are open.
>
> Closes #7969
>
> [unsealed runtime class]: https://docs.microsoft.com/en-us/uwp/midl-3/intro#base-classes
Co-authored-by: Carlos Zamora <carlos.zamora@microsoft.com>
Co-authored-by: Leon Liang <lelian@microsoft.com>
Co-authored-by: Carlos Zamora <carlos.zamora@microsoft.com>
2020-11-04 19:15:05 +01:00
|
|
|
{
|
2021-01-04 20:32:53 +01:00
|
|
|
// First thing's first, remove the current content from the UI
|
|
|
|
// tree. This is important, because we might be leaving zoom, and if
|
|
|
|
// a pane is zoomed, then it's currently in the UI tree, and should
|
|
|
|
// be removed before it's re-added in Pane::Restore
|
|
|
|
_tabContent.Children().Clear();
|
|
|
|
|
|
|
|
// Togging the zoom on the tab will cause the tab to inform us of
|
|
|
|
// the new root Content for this tab.
|
|
|
|
activeTab->ToggleZoom();
|
Make Tab an unsealed runtimeclass (and rename it to TabBase) (#8153)
In preparation for the Settings UI, we needed to make some changes to
Tab to abstract out shared, common functionality between different types
of tab. This is the result of that work. All code references to the
settings have been removed or reverted.
Contains changes from #8053, #7802.
The messages below only make sense in the context of the Settings UI,
which this pull request does not bring in. They do, however, provide
valuable information.
From #7802 (@leonMSFT):
> This PR's goal was to add an option to the `OpenSettings` keybinding to
> open the Settings UI in a tab. In order to implement that, a couple of
> changes had to be made to `Tab`, specifically:
>
> - Introduce a tab interface named `ITab`
> - Create/Rename two new Tab classes that implement `ITab` called
> `SettingsTab` and `TerminalTab`
>
From #8053:
> `TerminalTab` and `SettingsTab` share some implementation details. The
> close submenu introduced in #7728 is a good example of functionality
> that is consistent across all tabs. This PR transforms `ITab` from an
> interface, into an [unsealed runtime class] to de-duplicate some
> functionality. Most of the logic from `SettingsTab` was moved there
> because I expect the default behavior of a tab to resemble the
> `SettingsTab` over a `TerminalTab`.
>
> ## References
> Verified that Close submenu work was transferred over (#7728, #7961, #8010).
>
> ## Validation Steps Performed
> Check close submenu on first/last tab when multiple tabs are open.
>
> Closes #7969
>
> [unsealed runtime class]: https://docs.microsoft.com/en-us/uwp/midl-3/intro#base-classes
Co-authored-by: Carlos Zamora <carlos.zamora@microsoft.com>
Co-authored-by: Leon Liang <lelian@microsoft.com>
Co-authored-by: Carlos Zamora <carlos.zamora@microsoft.com>
2020-11-04 19:15:05 +01:00
|
|
|
}
|
2020-08-08 01:11:44 +02:00
|
|
|
}
|
Make Tab an unsealed runtimeclass (and rename it to TabBase) (#8153)
In preparation for the Settings UI, we needed to make some changes to
Tab to abstract out shared, common functionality between different types
of tab. This is the result of that work. All code references to the
settings have been removed or reverted.
Contains changes from #8053, #7802.
The messages below only make sense in the context of the Settings UI,
which this pull request does not bring in. They do, however, provide
valuable information.
From #7802 (@leonMSFT):
> This PR's goal was to add an option to the `OpenSettings` keybinding to
> open the Settings UI in a tab. In order to implement that, a couple of
> changes had to be made to `Tab`, specifically:
>
> - Introduce a tab interface named `ITab`
> - Create/Rename two new Tab classes that implement `ITab` called
> `SettingsTab` and `TerminalTab`
>
From #8053:
> `TerminalTab` and `SettingsTab` share some implementation details. The
> close submenu introduced in #7728 is a good example of functionality
> that is consistent across all tabs. This PR transforms `ITab` from an
> interface, into an [unsealed runtime class] to de-duplicate some
> functionality. Most of the logic from `SettingsTab` was moved there
> because I expect the default behavior of a tab to resemble the
> `SettingsTab` over a `TerminalTab`.
>
> ## References
> Verified that Close submenu work was transferred over (#7728, #7961, #8010).
>
> ## Validation Steps Performed
> Check close submenu on first/last tab when multiple tabs are open.
>
> Closes #7969
>
> [unsealed runtime class]: https://docs.microsoft.com/en-us/uwp/midl-3/intro#base-classes
Co-authored-by: Carlos Zamora <carlos.zamora@microsoft.com>
Co-authored-by: Leon Liang <lelian@microsoft.com>
Co-authored-by: Carlos Zamora <carlos.zamora@microsoft.com>
2020-11-04 19:15:05 +01:00
|
|
|
|
2020-08-08 01:11:44 +02:00
|
|
|
args.Handled(true);
|
|
|
|
}
|
|
|
|
|
2021-02-08 19:03:55 +01:00
|
|
|
void TerminalPage::_HandleTogglePaneReadOnly(const IInspectable& /*sender*/,
|
|
|
|
const ActionEventArgs& args)
|
|
|
|
{
|
|
|
|
if (const auto activeTab{ _GetFocusedTabImpl() })
|
|
|
|
{
|
|
|
|
activeTab->TogglePaneReadOnly();
|
|
|
|
}
|
|
|
|
|
|
|
|
args.Handled(true);
|
|
|
|
}
|
|
|
|
|
2019-09-04 23:34:06 +02:00
|
|
|
void TerminalPage::_HandleScrollUpPage(const IInspectable& /*sender*/,
|
2020-10-06 18:56:59 +02:00
|
|
|
const ActionEventArgs& args)
|
2019-08-17 00:43:51 +02:00
|
|
|
{
|
2020-10-27 02:19:52 +01:00
|
|
|
_ScrollPage(ScrollUp);
|
2019-08-17 00:43:51 +02:00
|
|
|
args.Handled(true);
|
|
|
|
}
|
|
|
|
|
2019-09-04 23:34:06 +02:00
|
|
|
void TerminalPage::_HandleScrollDownPage(const IInspectable& /*sender*/,
|
2020-10-06 18:56:59 +02:00
|
|
|
const ActionEventArgs& args)
|
2019-08-17 00:43:51 +02:00
|
|
|
{
|
2020-10-27 02:19:52 +01:00
|
|
|
_ScrollPage(ScrollDown);
|
2019-08-17 00:43:51 +02:00
|
|
|
args.Handled(true);
|
|
|
|
}
|
|
|
|
|
2020-12-08 18:28:41 +01:00
|
|
|
void TerminalPage::_HandleScrollToTop(const IInspectable& /*sender*/,
|
|
|
|
const ActionEventArgs& args)
|
|
|
|
{
|
|
|
|
_ScrollToBufferEdge(ScrollUp);
|
|
|
|
args.Handled(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TerminalPage::_HandleScrollToBottom(const IInspectable& /*sender*/,
|
|
|
|
const ActionEventArgs& args)
|
|
|
|
{
|
|
|
|
_ScrollToBufferEdge(ScrollDown);
|
|
|
|
args.Handled(true);
|
|
|
|
}
|
|
|
|
|
Add `findNext`, `findPrev` actions (#8917)
This PR is a resurrection of #8522. @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 action for navigating to the next & previous search
results. These actions are unbound by default. These actions can be used
from directly within the search dialog also, to immediately navigate the
results.
Furthermore, if you have a search started, and close the search box,
then press this keybinding, _it will still perform the search_. So you
can just hit <kbd>F3</kbd> repeatedly with the dialog closed to keep
searching new results. Neat!
If you dispatch the action on the key down, then dismiss a selection on
a key up, we'll end up immediately destroying the selection when you
release the bound key. That's annoying. It also bothers @carlos-zamora
in #3758. However, I _think_ we can just only dismiss the selection on a
key up. I _think_ that's fine. It _seems_ fine so far. We've got an
entire release cycle to futz with it.
## Validation Steps Performed
I've played with it all day and it seems _crisp_.
Closes #7695
Co-authored-by: Kiminori Kaburagi <yukawa_hidenori@icloud.com>
2021-02-18 20:21:35 +01:00
|
|
|
void TerminalPage::_HandleFindMatch(const IInspectable& /*sender*/,
|
|
|
|
const ActionEventArgs& args)
|
|
|
|
{
|
|
|
|
if (const auto& realArgs = args.ActionArgs().try_as<FindMatchArgs>())
|
|
|
|
{
|
|
|
|
if (const auto& control{ _GetActiveControl() })
|
|
|
|
{
|
|
|
|
control.SearchMatch(realArgs.Direction() == FindMatchDirection::Next);
|
|
|
|
args.Handled(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-09-04 23:34:06 +02:00
|
|
|
void TerminalPage::_HandleOpenSettings(const IInspectable& /*sender*/,
|
2020-10-06 18:56:59 +02:00
|
|
|
const ActionEventArgs& args)
|
2019-08-17 00:43:51 +02:00
|
|
|
{
|
2020-10-06 18:56:59 +02:00
|
|
|
if (const auto& realArgs = args.ActionArgs().try_as<OpenSettingsArgs>())
|
Add keybinding arg to openSettings (#6299)
## Summary of the Pull Request
Adds the `target` keybinding arg to `openSettings`. Possible values include: `defaultsFile`, `settingsFile`, and `allFiles`.
## References
#5915 - mini-spec
## PR Checklist
* [x] Closes #2557
* [x] Tests added/passed
## Detailed Description of the Pull Request / Additional comments
Implemented as discussed in the attached spec. A new enum will be added for the SettingsUI when it becomes available.
## Validation Steps Performed
Added the following to my settings.json:
```json
{ "command": "openSettings", "keys":... },
{ "command": { "action": "openSettings" }, "keys":... },
{ "command": { "action": "openSettings", "target": "settingsFile" }, "keys":... },
{ "command": { "action": "openSettings", "target": "defaultsFile" }, "keys":... },
{ "command": { "action": "openSettings", "target": "allFiles" }, "keys":... }
```
2020-06-12 23:19:18 +02:00
|
|
|
{
|
|
|
|
_LaunchSettings(realArgs.Target());
|
|
|
|
args.Handled(true);
|
|
|
|
}
|
2019-08-17 00:43:51 +02:00
|
|
|
}
|
|
|
|
|
2019-09-04 23:34:06 +02:00
|
|
|
void TerminalPage::_HandlePasteText(const IInspectable& /*sender*/,
|
2020-10-06 18:56:59 +02:00
|
|
|
const ActionEventArgs& args)
|
2019-08-17 00:43:51 +02:00
|
|
|
{
|
|
|
|
_PasteText();
|
|
|
|
args.Handled(true);
|
|
|
|
}
|
|
|
|
|
Add support for arbitrary args in keybindings (#3391)
## Summary of the Pull Request
Enables the user to provide arbitrary argument values to shortcut actions through a new `args` member of keybindings. For some keybindings, like `NewTabWithProfile<N>`, we previously needed 9 different `ShortcutAction`s, one for each value of `Index`. If a user wanted to have a `NewTabWithProfile11` keybinding, that was simply impossible. Now that the args are in their own separate json object, each binding can accept any number of arbitrary argument values.
So instead of:
```json
{ "command": "newTab", "keys": ["ctrl+shift+t"] },
{ "command": "newTabProfile0", "keys": ["ctrl+shift+1"] },
{ "command": "newTabProfile1", "keys": ["ctrl+shift+2"] },
{ "command": "newTabProfile2", "keys": ["ctrl+shift+3"] },
{ "command": "newTabProfile3", "keys": ["ctrl+shift+4"] },
```
We can now use:
```json
{ "command": "newTab", "keys": ["ctrl+shift+t"] },
{ "command": { "action": "newTab", "index": 0 }, "keys": ["ctrl+shift+1"] },
{ "command": { "action": "newTab", "index": 1 }, "keys": ["ctrl+shift+2"] },
{ "command": { "action": "newTab", "index": 2 }, "keys": ["ctrl+shift+3"] },
```
Initially, this does seem more verbose. However, for cases where there are multiple args, or there's a large range of values for the args, this will quickly become a more powerful system of expressing keybindings.
The "legacy" keybindings are _left in_ in this PR. They have helper methods to generate appropriate `IActionArgs` values. Prior to releasing 1.0, I think we should remove them, if only to remove some code bloat.
## References
See [the spec](https://github.com/microsoft/terminal/blob/master/doc/specs/%231142%20-%20Keybinding%20Arguments.md) for more details.
This is part two of the implementation, part one was #2446
## PR Checklist
* [x] Closes #1142
* [x] I work here
* [x] Tests added/passed
* [x] Schema updated
## Validation Steps Performed
* Ran Tests
* Removed the legacy keybindings from the `defaults.json`, everything still works
* Tried leaving the legacy keybingings in my `profiles.json`, everything still works.
-------------------------------------------------
* this is a start, but there's a weird linker bug if I take the SetKeybinding(ShortcutAction, KeyChord) implementation out, which I don't totally understand
* a good old-fashioned clean will fix that right up
* all these things work
* hey this actually _functionally_ works
* Mostly cleanup and completion of implementation
* Hey I bet we could just make NewTab the handler for NewTabWithProfile
* Start writing tests for Keybinding args
* Add tests
* Revert a bad sln change, and clean out dead code
* Change to include "command" as a single object
This is a change to make @dhowett-msft happy. Changes the args to be a part
of the "command" object, as opposed to an object on their own.
EX:
```jsonc
// Old style
{ "command": "switchToTab0", "keys": ["ctrl+1"] },
{ "command": { "action": "switchToTab", "index": 0 }, "keys": ["ctrl+alt+1"] },
// new style
{ "command": "switchToTab0", "keys": ["ctrl+1"] },
{ "command": "switchToTab", "args": { "index": 0 } "keys": ["ctrl+alt+1"] },
```
* schemas are hard yo
* Fix the build?
* wonder why my -Wall settings are different than CI...
* this makes me hate things
* Comments from PR
* Add a `Direction::None`
* LOAD BEARING
* add some GH ids to TODOs
* add a comment
* PR nits from carlos
2019-11-14 23:23:40 +01:00
|
|
|
void TerminalPage::_HandleNewTab(const IInspectable& /*sender*/,
|
2020-10-06 18:56:59 +02:00
|
|
|
const ActionEventArgs& args)
|
2019-08-17 00:43:51 +02:00
|
|
|
{
|
Add support for arbitrary args in keybindings (#3391)
## Summary of the Pull Request
Enables the user to provide arbitrary argument values to shortcut actions through a new `args` member of keybindings. For some keybindings, like `NewTabWithProfile<N>`, we previously needed 9 different `ShortcutAction`s, one for each value of `Index`. If a user wanted to have a `NewTabWithProfile11` keybinding, that was simply impossible. Now that the args are in their own separate json object, each binding can accept any number of arbitrary argument values.
So instead of:
```json
{ "command": "newTab", "keys": ["ctrl+shift+t"] },
{ "command": "newTabProfile0", "keys": ["ctrl+shift+1"] },
{ "command": "newTabProfile1", "keys": ["ctrl+shift+2"] },
{ "command": "newTabProfile2", "keys": ["ctrl+shift+3"] },
{ "command": "newTabProfile3", "keys": ["ctrl+shift+4"] },
```
We can now use:
```json
{ "command": "newTab", "keys": ["ctrl+shift+t"] },
{ "command": { "action": "newTab", "index": 0 }, "keys": ["ctrl+shift+1"] },
{ "command": { "action": "newTab", "index": 1 }, "keys": ["ctrl+shift+2"] },
{ "command": { "action": "newTab", "index": 2 }, "keys": ["ctrl+shift+3"] },
```
Initially, this does seem more verbose. However, for cases where there are multiple args, or there's a large range of values for the args, this will quickly become a more powerful system of expressing keybindings.
The "legacy" keybindings are _left in_ in this PR. They have helper methods to generate appropriate `IActionArgs` values. Prior to releasing 1.0, I think we should remove them, if only to remove some code bloat.
## References
See [the spec](https://github.com/microsoft/terminal/blob/master/doc/specs/%231142%20-%20Keybinding%20Arguments.md) for more details.
This is part two of the implementation, part one was #2446
## PR Checklist
* [x] Closes #1142
* [x] I work here
* [x] Tests added/passed
* [x] Schema updated
## Validation Steps Performed
* Ran Tests
* Removed the legacy keybindings from the `defaults.json`, everything still works
* Tried leaving the legacy keybingings in my `profiles.json`, everything still works.
-------------------------------------------------
* this is a start, but there's a weird linker bug if I take the SetKeybinding(ShortcutAction, KeyChord) implementation out, which I don't totally understand
* a good old-fashioned clean will fix that right up
* all these things work
* hey this actually _functionally_ works
* Mostly cleanup and completion of implementation
* Hey I bet we could just make NewTab the handler for NewTabWithProfile
* Start writing tests for Keybinding args
* Add tests
* Revert a bad sln change, and clean out dead code
* Change to include "command" as a single object
This is a change to make @dhowett-msft happy. Changes the args to be a part
of the "command" object, as opposed to an object on their own.
EX:
```jsonc
// Old style
{ "command": "switchToTab0", "keys": ["ctrl+1"] },
{ "command": { "action": "switchToTab", "index": 0 }, "keys": ["ctrl+alt+1"] },
// new style
{ "command": "switchToTab0", "keys": ["ctrl+1"] },
{ "command": "switchToTab", "args": { "index": 0 } "keys": ["ctrl+alt+1"] },
```
* schemas are hard yo
* Fix the build?
* wonder why my -Wall settings are different than CI...
* this makes me hate things
* Comments from PR
* Add a `Direction::None`
* LOAD BEARING
* add some GH ids to TODOs
* add a comment
* PR nits from carlos
2019-11-14 23:23:40 +01:00
|
|
|
if (args == nullptr)
|
|
|
|
{
|
Add support for new panes with specifc profiles and other settings overrides (#3825)
## Summary of the Pull Request
This enables the user to set a number of extra settings in the `NewTab` and `SplitPane` `ShortcutAction`s, that enable customizing how a new terminal is created at runtime. The following four properties were added:
* `profile`
* `commandline`
* `tabTitle`
* `startingDirectory`
`profile` can be used with either a GUID or the name of a profile, and the action will launch that profile instead of the default.
`commandline`, `tabTitle`, and `startingDirectory` can all be used to override the profile's values of those settings. This will be more useful for #607.
With this PR, you can make bindings like the following:
```json
{ "keys": ["ctrl+a"], "command": { "action": "splitPane", "split": "vertical" } },
{ "keys": ["ctrl+b"], "command": { "action": "splitPane", "split": "vertical", "profile": "{6239a42c-1111-49a3-80bd-e8fdd045185c}" } },
{ "keys": ["ctrl+c"], "command": { "action": "splitPane", "split": "vertical", "profile": "profile1" } },
{ "keys": ["ctrl+d"], "command": { "action": "splitPane", "split": "vertical", "profile": "profile2" } },
{ "keys": ["ctrl+e"], "command": { "action": "splitPane", "split": "horizontal", "commandline": "foo.exe" } },
{ "keys": ["ctrl+f"], "command": { "action": "splitPane", "split": "horizontal", "profile": "profile1", "commandline": "foo.exe" } },
{ "keys": ["ctrl+g"], "command": { "action": "newTab" } },
{ "keys": ["ctrl+h"], "command": { "action": "newTab", "startingDirectory": "c:\\foo" } },
{ "keys": ["ctrl+i"], "command": { "action": "newTab", "profile": "profile2", "startingDirectory": "c:\\foo" } },
{ "keys": ["ctrl+j"], "command": { "action": "newTab", "tabTitle": "bar" } },
{ "keys": ["ctrl+k"], "command": { "action": "newTab", "profile": "profile2", "tabTitle": "bar" } },
{ "keys": ["ctrl+l"], "command": { "action": "newTab", "profile": "profile1", "tabTitle": "bar", "startingDirectory": "c:\\foo", "commandline":"foo.exe" } }
```
## References
This is a lot of work that was largely started in pursuit of #607. We want people to be able to override these properties straight from the commandline. While they may not make as much sense as keybindings like this, they'll make more sense as commandline arguments.
## PR Checklist
* [x] Closes #998
* [x] I work here
* [x] Tests added/passed
* [x] Requires documentation to be updated
## Validation Steps Performed
There are tests 🎉
Manually added some bindings, they opened the correct profiles in panes/tabs
2019-12-09 14:02:29 +01:00
|
|
|
_OpenNewTab(nullptr);
|
Add support for arbitrary args in keybindings (#3391)
## Summary of the Pull Request
Enables the user to provide arbitrary argument values to shortcut actions through a new `args` member of keybindings. For some keybindings, like `NewTabWithProfile<N>`, we previously needed 9 different `ShortcutAction`s, one for each value of `Index`. If a user wanted to have a `NewTabWithProfile11` keybinding, that was simply impossible. Now that the args are in their own separate json object, each binding can accept any number of arbitrary argument values.
So instead of:
```json
{ "command": "newTab", "keys": ["ctrl+shift+t"] },
{ "command": "newTabProfile0", "keys": ["ctrl+shift+1"] },
{ "command": "newTabProfile1", "keys": ["ctrl+shift+2"] },
{ "command": "newTabProfile2", "keys": ["ctrl+shift+3"] },
{ "command": "newTabProfile3", "keys": ["ctrl+shift+4"] },
```
We can now use:
```json
{ "command": "newTab", "keys": ["ctrl+shift+t"] },
{ "command": { "action": "newTab", "index": 0 }, "keys": ["ctrl+shift+1"] },
{ "command": { "action": "newTab", "index": 1 }, "keys": ["ctrl+shift+2"] },
{ "command": { "action": "newTab", "index": 2 }, "keys": ["ctrl+shift+3"] },
```
Initially, this does seem more verbose. However, for cases where there are multiple args, or there's a large range of values for the args, this will quickly become a more powerful system of expressing keybindings.
The "legacy" keybindings are _left in_ in this PR. They have helper methods to generate appropriate `IActionArgs` values. Prior to releasing 1.0, I think we should remove them, if only to remove some code bloat.
## References
See [the spec](https://github.com/microsoft/terminal/blob/master/doc/specs/%231142%20-%20Keybinding%20Arguments.md) for more details.
This is part two of the implementation, part one was #2446
## PR Checklist
* [x] Closes #1142
* [x] I work here
* [x] Tests added/passed
* [x] Schema updated
## Validation Steps Performed
* Ran Tests
* Removed the legacy keybindings from the `defaults.json`, everything still works
* Tried leaving the legacy keybingings in my `profiles.json`, everything still works.
-------------------------------------------------
* this is a start, but there's a weird linker bug if I take the SetKeybinding(ShortcutAction, KeyChord) implementation out, which I don't totally understand
* a good old-fashioned clean will fix that right up
* all these things work
* hey this actually _functionally_ works
* Mostly cleanup and completion of implementation
* Hey I bet we could just make NewTab the handler for NewTabWithProfile
* Start writing tests for Keybinding args
* Add tests
* Revert a bad sln change, and clean out dead code
* Change to include "command" as a single object
This is a change to make @dhowett-msft happy. Changes the args to be a part
of the "command" object, as opposed to an object on their own.
EX:
```jsonc
// Old style
{ "command": "switchToTab0", "keys": ["ctrl+1"] },
{ "command": { "action": "switchToTab", "index": 0 }, "keys": ["ctrl+alt+1"] },
// new style
{ "command": "switchToTab0", "keys": ["ctrl+1"] },
{ "command": "switchToTab", "args": { "index": 0 } "keys": ["ctrl+alt+1"] },
```
* schemas are hard yo
* Fix the build?
* wonder why my -Wall settings are different than CI...
* this makes me hate things
* Comments from PR
* Add a `Direction::None`
* LOAD BEARING
* add some GH ids to TODOs
* add a comment
* PR nits from carlos
2019-11-14 23:23:40 +01:00
|
|
|
args.Handled(true);
|
|
|
|
}
|
2020-10-06 18:56:59 +02:00
|
|
|
else if (const auto& realArgs = args.ActionArgs().try_as<NewTabArgs>())
|
2019-08-17 00:43:51 +02:00
|
|
|
{
|
Add support for new panes with specifc profiles and other settings overrides (#3825)
## Summary of the Pull Request
This enables the user to set a number of extra settings in the `NewTab` and `SplitPane` `ShortcutAction`s, that enable customizing how a new terminal is created at runtime. The following four properties were added:
* `profile`
* `commandline`
* `tabTitle`
* `startingDirectory`
`profile` can be used with either a GUID or the name of a profile, and the action will launch that profile instead of the default.
`commandline`, `tabTitle`, and `startingDirectory` can all be used to override the profile's values of those settings. This will be more useful for #607.
With this PR, you can make bindings like the following:
```json
{ "keys": ["ctrl+a"], "command": { "action": "splitPane", "split": "vertical" } },
{ "keys": ["ctrl+b"], "command": { "action": "splitPane", "split": "vertical", "profile": "{6239a42c-1111-49a3-80bd-e8fdd045185c}" } },
{ "keys": ["ctrl+c"], "command": { "action": "splitPane", "split": "vertical", "profile": "profile1" } },
{ "keys": ["ctrl+d"], "command": { "action": "splitPane", "split": "vertical", "profile": "profile2" } },
{ "keys": ["ctrl+e"], "command": { "action": "splitPane", "split": "horizontal", "commandline": "foo.exe" } },
{ "keys": ["ctrl+f"], "command": { "action": "splitPane", "split": "horizontal", "profile": "profile1", "commandline": "foo.exe" } },
{ "keys": ["ctrl+g"], "command": { "action": "newTab" } },
{ "keys": ["ctrl+h"], "command": { "action": "newTab", "startingDirectory": "c:\\foo" } },
{ "keys": ["ctrl+i"], "command": { "action": "newTab", "profile": "profile2", "startingDirectory": "c:\\foo" } },
{ "keys": ["ctrl+j"], "command": { "action": "newTab", "tabTitle": "bar" } },
{ "keys": ["ctrl+k"], "command": { "action": "newTab", "profile": "profile2", "tabTitle": "bar" } },
{ "keys": ["ctrl+l"], "command": { "action": "newTab", "profile": "profile1", "tabTitle": "bar", "startingDirectory": "c:\\foo", "commandline":"foo.exe" } }
```
## References
This is a lot of work that was largely started in pursuit of #607. We want people to be able to override these properties straight from the commandline. While they may not make as much sense as keybindings like this, they'll make more sense as commandline arguments.
## PR Checklist
* [x] Closes #998
* [x] I work here
* [x] Tests added/passed
* [x] Requires documentation to be updated
## Validation Steps Performed
There are tests 🎉
Manually added some bindings, they opened the correct profiles in panes/tabs
2019-12-09 14:02:29 +01:00
|
|
|
_OpenNewTab(realArgs.TerminalArgs());
|
2019-08-17 00:43:51 +02:00
|
|
|
args.Handled(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-04 23:34:06 +02:00
|
|
|
void TerminalPage::_HandleSwitchToTab(const IInspectable& /*sender*/,
|
2020-10-06 18:56:59 +02:00
|
|
|
const ActionEventArgs& args)
|
2019-08-17 00:43:51 +02:00
|
|
|
{
|
2020-10-06 18:56:59 +02:00
|
|
|
if (const auto& realArgs = args.ActionArgs().try_as<SwitchToTabArgs>())
|
2019-08-17 00:43:51 +02:00
|
|
|
{
|
|
|
|
const auto handled = _SelectTab({ realArgs.TabIndex() });
|
|
|
|
args.Handled(handled);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-04 23:34:06 +02:00
|
|
|
void TerminalPage::_HandleResizePane(const IInspectable& /*sender*/,
|
2020-10-06 18:56:59 +02:00
|
|
|
const ActionEventArgs& args)
|
2019-08-17 00:43:51 +02:00
|
|
|
{
|
2020-10-06 18:56:59 +02:00
|
|
|
if (const auto& realArgs = args.ActionArgs().try_as<ResizePaneArgs>())
|
2019-08-17 00:43:51 +02:00
|
|
|
{
|
Support for navigating panes by MRU (#8183)
Adds a "move to previous pane" and "move to next pane" keybinding, which
navigates to the last/first focused pane
We assign pane IDs on creation and maintain a vector of active pane IDs
in MRU order. Navigating panes by MRU then requires specifying which
pane ID we want to focus.
From our offline discussion (thanks @zadjii-msft for the concise
description):
> For the record, the full spec I'm imagining is:
>
> { command": { "action": "focus(Next|Prev)Pane", "order": "inOrder"|"mru", "useSwitcher": true|false } },
>
> and order defaults to mru, and useSwitcher will default to true, when
> there is a switcher. So
>
> { command": { "action": "focusNextPane" } },
> { command": { "action": "focusNextPane", "order": "mru" } },
>
> these are the same action. (but right now we don't support the order
> param)
>
> Then there'll be another PR for "focusPane(target=id)"
>
> Then a third PR for "focus(Next|Prev)Pane(order=inOrder)"
> for the record, I prefer this approach over the "one action to rule
> them all" version with both target and order/direction as params,
> because I don't like the confusion of what happens if there's both
> target and order/direction provided.
References #1000
Closes #2871
2020-12-11 19:36:05 +01:00
|
|
|
if (realArgs.ResizeDirection() == ResizeDirection::None)
|
Add support for arbitrary args in keybindings (#3391)
## Summary of the Pull Request
Enables the user to provide arbitrary argument values to shortcut actions through a new `args` member of keybindings. For some keybindings, like `NewTabWithProfile<N>`, we previously needed 9 different `ShortcutAction`s, one for each value of `Index`. If a user wanted to have a `NewTabWithProfile11` keybinding, that was simply impossible. Now that the args are in their own separate json object, each binding can accept any number of arbitrary argument values.
So instead of:
```json
{ "command": "newTab", "keys": ["ctrl+shift+t"] },
{ "command": "newTabProfile0", "keys": ["ctrl+shift+1"] },
{ "command": "newTabProfile1", "keys": ["ctrl+shift+2"] },
{ "command": "newTabProfile2", "keys": ["ctrl+shift+3"] },
{ "command": "newTabProfile3", "keys": ["ctrl+shift+4"] },
```
We can now use:
```json
{ "command": "newTab", "keys": ["ctrl+shift+t"] },
{ "command": { "action": "newTab", "index": 0 }, "keys": ["ctrl+shift+1"] },
{ "command": { "action": "newTab", "index": 1 }, "keys": ["ctrl+shift+2"] },
{ "command": { "action": "newTab", "index": 2 }, "keys": ["ctrl+shift+3"] },
```
Initially, this does seem more verbose. However, for cases where there are multiple args, or there's a large range of values for the args, this will quickly become a more powerful system of expressing keybindings.
The "legacy" keybindings are _left in_ in this PR. They have helper methods to generate appropriate `IActionArgs` values. Prior to releasing 1.0, I think we should remove them, if only to remove some code bloat.
## References
See [the spec](https://github.com/microsoft/terminal/blob/master/doc/specs/%231142%20-%20Keybinding%20Arguments.md) for more details.
This is part two of the implementation, part one was #2446
## PR Checklist
* [x] Closes #1142
* [x] I work here
* [x] Tests added/passed
* [x] Schema updated
## Validation Steps Performed
* Ran Tests
* Removed the legacy keybindings from the `defaults.json`, everything still works
* Tried leaving the legacy keybingings in my `profiles.json`, everything still works.
-------------------------------------------------
* this is a start, but there's a weird linker bug if I take the SetKeybinding(ShortcutAction, KeyChord) implementation out, which I don't totally understand
* a good old-fashioned clean will fix that right up
* all these things work
* hey this actually _functionally_ works
* Mostly cleanup and completion of implementation
* Hey I bet we could just make NewTab the handler for NewTabWithProfile
* Start writing tests for Keybinding args
* Add tests
* Revert a bad sln change, and clean out dead code
* Change to include "command" as a single object
This is a change to make @dhowett-msft happy. Changes the args to be a part
of the "command" object, as opposed to an object on their own.
EX:
```jsonc
// Old style
{ "command": "switchToTab0", "keys": ["ctrl+1"] },
{ "command": { "action": "switchToTab", "index": 0 }, "keys": ["ctrl+alt+1"] },
// new style
{ "command": "switchToTab0", "keys": ["ctrl+1"] },
{ "command": "switchToTab", "args": { "index": 0 } "keys": ["ctrl+alt+1"] },
```
* schemas are hard yo
* Fix the build?
* wonder why my -Wall settings are different than CI...
* this makes me hate things
* Comments from PR
* Add a `Direction::None`
* LOAD BEARING
* add some GH ids to TODOs
* add a comment
* PR nits from carlos
2019-11-14 23:23:40 +01:00
|
|
|
{
|
|
|
|
// Do nothing
|
|
|
|
args.Handled(false);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
Support for navigating panes by MRU (#8183)
Adds a "move to previous pane" and "move to next pane" keybinding, which
navigates to the last/first focused pane
We assign pane IDs on creation and maintain a vector of active pane IDs
in MRU order. Navigating panes by MRU then requires specifying which
pane ID we want to focus.
From our offline discussion (thanks @zadjii-msft for the concise
description):
> For the record, the full spec I'm imagining is:
>
> { command": { "action": "focus(Next|Prev)Pane", "order": "inOrder"|"mru", "useSwitcher": true|false } },
>
> and order defaults to mru, and useSwitcher will default to true, when
> there is a switcher. So
>
> { command": { "action": "focusNextPane" } },
> { command": { "action": "focusNextPane", "order": "mru" } },
>
> these are the same action. (but right now we don't support the order
> param)
>
> Then there'll be another PR for "focusPane(target=id)"
>
> Then a third PR for "focus(Next|Prev)Pane(order=inOrder)"
> for the record, I prefer this approach over the "one action to rule
> them all" version with both target and order/direction as params,
> because I don't like the confusion of what happens if there's both
> target and order/direction provided.
References #1000
Closes #2871
2020-12-11 19:36:05 +01:00
|
|
|
_ResizePane(realArgs.ResizeDirection());
|
Add support for arbitrary args in keybindings (#3391)
## Summary of the Pull Request
Enables the user to provide arbitrary argument values to shortcut actions through a new `args` member of keybindings. For some keybindings, like `NewTabWithProfile<N>`, we previously needed 9 different `ShortcutAction`s, one for each value of `Index`. If a user wanted to have a `NewTabWithProfile11` keybinding, that was simply impossible. Now that the args are in their own separate json object, each binding can accept any number of arbitrary argument values.
So instead of:
```json
{ "command": "newTab", "keys": ["ctrl+shift+t"] },
{ "command": "newTabProfile0", "keys": ["ctrl+shift+1"] },
{ "command": "newTabProfile1", "keys": ["ctrl+shift+2"] },
{ "command": "newTabProfile2", "keys": ["ctrl+shift+3"] },
{ "command": "newTabProfile3", "keys": ["ctrl+shift+4"] },
```
We can now use:
```json
{ "command": "newTab", "keys": ["ctrl+shift+t"] },
{ "command": { "action": "newTab", "index": 0 }, "keys": ["ctrl+shift+1"] },
{ "command": { "action": "newTab", "index": 1 }, "keys": ["ctrl+shift+2"] },
{ "command": { "action": "newTab", "index": 2 }, "keys": ["ctrl+shift+3"] },
```
Initially, this does seem more verbose. However, for cases where there are multiple args, or there's a large range of values for the args, this will quickly become a more powerful system of expressing keybindings.
The "legacy" keybindings are _left in_ in this PR. They have helper methods to generate appropriate `IActionArgs` values. Prior to releasing 1.0, I think we should remove them, if only to remove some code bloat.
## References
See [the spec](https://github.com/microsoft/terminal/blob/master/doc/specs/%231142%20-%20Keybinding%20Arguments.md) for more details.
This is part two of the implementation, part one was #2446
## PR Checklist
* [x] Closes #1142
* [x] I work here
* [x] Tests added/passed
* [x] Schema updated
## Validation Steps Performed
* Ran Tests
* Removed the legacy keybindings from the `defaults.json`, everything still works
* Tried leaving the legacy keybingings in my `profiles.json`, everything still works.
-------------------------------------------------
* this is a start, but there's a weird linker bug if I take the SetKeybinding(ShortcutAction, KeyChord) implementation out, which I don't totally understand
* a good old-fashioned clean will fix that right up
* all these things work
* hey this actually _functionally_ works
* Mostly cleanup and completion of implementation
* Hey I bet we could just make NewTab the handler for NewTabWithProfile
* Start writing tests for Keybinding args
* Add tests
* Revert a bad sln change, and clean out dead code
* Change to include "command" as a single object
This is a change to make @dhowett-msft happy. Changes the args to be a part
of the "command" object, as opposed to an object on their own.
EX:
```jsonc
// Old style
{ "command": "switchToTab0", "keys": ["ctrl+1"] },
{ "command": { "action": "switchToTab", "index": 0 }, "keys": ["ctrl+alt+1"] },
// new style
{ "command": "switchToTab0", "keys": ["ctrl+1"] },
{ "command": "switchToTab", "args": { "index": 0 } "keys": ["ctrl+alt+1"] },
```
* schemas are hard yo
* Fix the build?
* wonder why my -Wall settings are different than CI...
* this makes me hate things
* Comments from PR
* Add a `Direction::None`
* LOAD BEARING
* add some GH ids to TODOs
* add a comment
* PR nits from carlos
2019-11-14 23:23:40 +01:00
|
|
|
args.Handled(true);
|
|
|
|
}
|
2019-08-17 00:43:51 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-04 23:34:06 +02:00
|
|
|
void TerminalPage::_HandleMoveFocus(const IInspectable& /*sender*/,
|
2020-10-06 18:56:59 +02:00
|
|
|
const ActionEventArgs& args)
|
2019-08-17 00:43:51 +02:00
|
|
|
{
|
2020-10-06 18:56:59 +02:00
|
|
|
if (const auto& realArgs = args.ActionArgs().try_as<MoveFocusArgs>())
|
2019-08-17 00:43:51 +02:00
|
|
|
{
|
Support for navigating panes by MRU (#8183)
Adds a "move to previous pane" and "move to next pane" keybinding, which
navigates to the last/first focused pane
We assign pane IDs on creation and maintain a vector of active pane IDs
in MRU order. Navigating panes by MRU then requires specifying which
pane ID we want to focus.
From our offline discussion (thanks @zadjii-msft for the concise
description):
> For the record, the full spec I'm imagining is:
>
> { command": { "action": "focus(Next|Prev)Pane", "order": "inOrder"|"mru", "useSwitcher": true|false } },
>
> and order defaults to mru, and useSwitcher will default to true, when
> there is a switcher. So
>
> { command": { "action": "focusNextPane" } },
> { command": { "action": "focusNextPane", "order": "mru" } },
>
> these are the same action. (but right now we don't support the order
> param)
>
> Then there'll be another PR for "focusPane(target=id)"
>
> Then a third PR for "focus(Next|Prev)Pane(order=inOrder)"
> for the record, I prefer this approach over the "one action to rule
> them all" version with both target and order/direction as params,
> because I don't like the confusion of what happens if there's both
> target and order/direction provided.
References #1000
Closes #2871
2020-12-11 19:36:05 +01:00
|
|
|
if (realArgs.FocusDirection() == FocusDirection::None)
|
Add support for arbitrary args in keybindings (#3391)
## Summary of the Pull Request
Enables the user to provide arbitrary argument values to shortcut actions through a new `args` member of keybindings. For some keybindings, like `NewTabWithProfile<N>`, we previously needed 9 different `ShortcutAction`s, one for each value of `Index`. If a user wanted to have a `NewTabWithProfile11` keybinding, that was simply impossible. Now that the args are in their own separate json object, each binding can accept any number of arbitrary argument values.
So instead of:
```json
{ "command": "newTab", "keys": ["ctrl+shift+t"] },
{ "command": "newTabProfile0", "keys": ["ctrl+shift+1"] },
{ "command": "newTabProfile1", "keys": ["ctrl+shift+2"] },
{ "command": "newTabProfile2", "keys": ["ctrl+shift+3"] },
{ "command": "newTabProfile3", "keys": ["ctrl+shift+4"] },
```
We can now use:
```json
{ "command": "newTab", "keys": ["ctrl+shift+t"] },
{ "command": { "action": "newTab", "index": 0 }, "keys": ["ctrl+shift+1"] },
{ "command": { "action": "newTab", "index": 1 }, "keys": ["ctrl+shift+2"] },
{ "command": { "action": "newTab", "index": 2 }, "keys": ["ctrl+shift+3"] },
```
Initially, this does seem more verbose. However, for cases where there are multiple args, or there's a large range of values for the args, this will quickly become a more powerful system of expressing keybindings.
The "legacy" keybindings are _left in_ in this PR. They have helper methods to generate appropriate `IActionArgs` values. Prior to releasing 1.0, I think we should remove them, if only to remove some code bloat.
## References
See [the spec](https://github.com/microsoft/terminal/blob/master/doc/specs/%231142%20-%20Keybinding%20Arguments.md) for more details.
This is part two of the implementation, part one was #2446
## PR Checklist
* [x] Closes #1142
* [x] I work here
* [x] Tests added/passed
* [x] Schema updated
## Validation Steps Performed
* Ran Tests
* Removed the legacy keybindings from the `defaults.json`, everything still works
* Tried leaving the legacy keybingings in my `profiles.json`, everything still works.
-------------------------------------------------
* this is a start, but there's a weird linker bug if I take the SetKeybinding(ShortcutAction, KeyChord) implementation out, which I don't totally understand
* a good old-fashioned clean will fix that right up
* all these things work
* hey this actually _functionally_ works
* Mostly cleanup and completion of implementation
* Hey I bet we could just make NewTab the handler for NewTabWithProfile
* Start writing tests for Keybinding args
* Add tests
* Revert a bad sln change, and clean out dead code
* Change to include "command" as a single object
This is a change to make @dhowett-msft happy. Changes the args to be a part
of the "command" object, as opposed to an object on their own.
EX:
```jsonc
// Old style
{ "command": "switchToTab0", "keys": ["ctrl+1"] },
{ "command": { "action": "switchToTab", "index": 0 }, "keys": ["ctrl+alt+1"] },
// new style
{ "command": "switchToTab0", "keys": ["ctrl+1"] },
{ "command": "switchToTab", "args": { "index": 0 } "keys": ["ctrl+alt+1"] },
```
* schemas are hard yo
* Fix the build?
* wonder why my -Wall settings are different than CI...
* this makes me hate things
* Comments from PR
* Add a `Direction::None`
* LOAD BEARING
* add some GH ids to TODOs
* add a comment
* PR nits from carlos
2019-11-14 23:23:40 +01:00
|
|
|
{
|
|
|
|
// Do nothing
|
|
|
|
args.Handled(false);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
Support for navigating panes by MRU (#8183)
Adds a "move to previous pane" and "move to next pane" keybinding, which
navigates to the last/first focused pane
We assign pane IDs on creation and maintain a vector of active pane IDs
in MRU order. Navigating panes by MRU then requires specifying which
pane ID we want to focus.
From our offline discussion (thanks @zadjii-msft for the concise
description):
> For the record, the full spec I'm imagining is:
>
> { command": { "action": "focus(Next|Prev)Pane", "order": "inOrder"|"mru", "useSwitcher": true|false } },
>
> and order defaults to mru, and useSwitcher will default to true, when
> there is a switcher. So
>
> { command": { "action": "focusNextPane" } },
> { command": { "action": "focusNextPane", "order": "mru" } },
>
> these are the same action. (but right now we don't support the order
> param)
>
> Then there'll be another PR for "focusPane(target=id)"
>
> Then a third PR for "focus(Next|Prev)Pane(order=inOrder)"
> for the record, I prefer this approach over the "one action to rule
> them all" version with both target and order/direction as params,
> because I don't like the confusion of what happens if there's both
> target and order/direction provided.
References #1000
Closes #2871
2020-12-11 19:36:05 +01:00
|
|
|
_MoveFocus(realArgs.FocusDirection());
|
Add support for arbitrary args in keybindings (#3391)
## Summary of the Pull Request
Enables the user to provide arbitrary argument values to shortcut actions through a new `args` member of keybindings. For some keybindings, like `NewTabWithProfile<N>`, we previously needed 9 different `ShortcutAction`s, one for each value of `Index`. If a user wanted to have a `NewTabWithProfile11` keybinding, that was simply impossible. Now that the args are in their own separate json object, each binding can accept any number of arbitrary argument values.
So instead of:
```json
{ "command": "newTab", "keys": ["ctrl+shift+t"] },
{ "command": "newTabProfile0", "keys": ["ctrl+shift+1"] },
{ "command": "newTabProfile1", "keys": ["ctrl+shift+2"] },
{ "command": "newTabProfile2", "keys": ["ctrl+shift+3"] },
{ "command": "newTabProfile3", "keys": ["ctrl+shift+4"] },
```
We can now use:
```json
{ "command": "newTab", "keys": ["ctrl+shift+t"] },
{ "command": { "action": "newTab", "index": 0 }, "keys": ["ctrl+shift+1"] },
{ "command": { "action": "newTab", "index": 1 }, "keys": ["ctrl+shift+2"] },
{ "command": { "action": "newTab", "index": 2 }, "keys": ["ctrl+shift+3"] },
```
Initially, this does seem more verbose. However, for cases where there are multiple args, or there's a large range of values for the args, this will quickly become a more powerful system of expressing keybindings.
The "legacy" keybindings are _left in_ in this PR. They have helper methods to generate appropriate `IActionArgs` values. Prior to releasing 1.0, I think we should remove them, if only to remove some code bloat.
## References
See [the spec](https://github.com/microsoft/terminal/blob/master/doc/specs/%231142%20-%20Keybinding%20Arguments.md) for more details.
This is part two of the implementation, part one was #2446
## PR Checklist
* [x] Closes #1142
* [x] I work here
* [x] Tests added/passed
* [x] Schema updated
## Validation Steps Performed
* Ran Tests
* Removed the legacy keybindings from the `defaults.json`, everything still works
* Tried leaving the legacy keybingings in my `profiles.json`, everything still works.
-------------------------------------------------
* this is a start, but there's a weird linker bug if I take the SetKeybinding(ShortcutAction, KeyChord) implementation out, which I don't totally understand
* a good old-fashioned clean will fix that right up
* all these things work
* hey this actually _functionally_ works
* Mostly cleanup and completion of implementation
* Hey I bet we could just make NewTab the handler for NewTabWithProfile
* Start writing tests for Keybinding args
* Add tests
* Revert a bad sln change, and clean out dead code
* Change to include "command" as a single object
This is a change to make @dhowett-msft happy. Changes the args to be a part
of the "command" object, as opposed to an object on their own.
EX:
```jsonc
// Old style
{ "command": "switchToTab0", "keys": ["ctrl+1"] },
{ "command": { "action": "switchToTab", "index": 0 }, "keys": ["ctrl+alt+1"] },
// new style
{ "command": "switchToTab0", "keys": ["ctrl+1"] },
{ "command": "switchToTab", "args": { "index": 0 } "keys": ["ctrl+alt+1"] },
```
* schemas are hard yo
* Fix the build?
* wonder why my -Wall settings are different than CI...
* this makes me hate things
* Comments from PR
* Add a `Direction::None`
* LOAD BEARING
* add some GH ids to TODOs
* add a comment
* PR nits from carlos
2019-11-14 23:23:40 +01:00
|
|
|
args.Handled(true);
|
|
|
|
}
|
2019-08-17 00:43:51 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-04 23:34:06 +02:00
|
|
|
void TerminalPage::_HandleCopyText(const IInspectable& /*sender*/,
|
2020-10-06 18:56:59 +02:00
|
|
|
const ActionEventArgs& args)
|
2019-08-17 00:43:51 +02:00
|
|
|
{
|
2020-10-06 18:56:59 +02:00
|
|
|
if (const auto& realArgs = args.ActionArgs().try_as<CopyTextArgs>())
|
2019-08-17 00:43:51 +02:00
|
|
|
{
|
Add copyFormatting keybinding arg and array support (#6004)
Adds array support for the existing `copyFormatting` global setting.
This allows users to define which formats they would specifically like
to be copied.
A boolean value is still accepted and is translated to the following:
- `false` --> `"none"` or `[]`
- `true` --> `"all"` or `["html", "rtf"]`
This also adds `copyFormatting` as a keybinding arg for `copy`. As with
the global setting, a boolean value and array value is accepted.
CopyFormat is a WinRT enum where each accepted format is a flag.
Currently accepted formats include `html`, and `rtf`. A boolean value is
accepted and converted. `true` is a conjunction of all the formats.
`false` only includes plain text.
For the global setting, `null` is not accepted. We already have a
default value from before so no worries there.
For the keybinding arg, `null` (the default value) means that we just do
what the global arg says to do. Overall, the `copyFormatting` keybinding
arg is an override of the global setting **when using that keybinding**.
References #5212 - Spec for formatted copying
References #2690 - disable html copy
Validated behavior with every combination of values below:
- `copyFormatting` global: { `true`, `false`, `[]`, `["html"]` }
- `copyFormatting` copy arg:
{ `null`, `true`, `false`, `[]`, `[, "html"]`}
Closes #4191
Closes #5262
2020-08-15 03:02:24 +02:00
|
|
|
const auto handled = _CopyText(realArgs.SingleLine(), realArgs.CopyFormatting());
|
2019-08-17 00:43:51 +02:00
|
|
|
args.Handled(handled);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-30 15:18:05 +02:00
|
|
|
void TerminalPage::_HandleAdjustFontSize(const IInspectable& /*sender*/,
|
2020-10-06 18:56:59 +02:00
|
|
|
const ActionEventArgs& args)
|
2019-09-30 15:18:05 +02:00
|
|
|
{
|
2020-10-06 18:56:59 +02:00
|
|
|
if (const auto& realArgs = args.ActionArgs().try_as<AdjustFontSizeArgs>())
|
2019-09-30 15:18:05 +02:00
|
|
|
{
|
Decouple "Active Terminal" and "Focused Control" (#3540)
## Summary of the Pull Request
Unties the concept of "focused control" from "active control".
Previously, we were exclusively using the "Focused" state of `TermControl`s to determine which one was active. This was fraught with gotchas - if anything else became focused, then suddenly there was _no_ pane focused in the Tab. This happened especially frequently if the user clicked on a tab to focus the window. Furthermore, in experimental branches with more UI added to the Terminal (such as [dev/migrie/f/2046-command-palette](https://github.com/microsoft/terminal/tree/dev/migrie/f/2046-command-palette)), when these UIs were added to the Terminal, they'd take focus, which again meant that there was no focused pane.
This fixes these issue by having each Tab manually track which Pane is active in that tab. The Tab is now the arbiter of who in the tree is "active". Panes still track this state, for them to be able to MoveFocus appropriately.
It also contains a related fix to prevent the tab separator from stealing focus from the TermControl. This required us to set the color of the un-focused Pane border to some color other that Transparent, so I went with the TabViewBackground. Panes now look like the following:
![image](https://user-images.githubusercontent.com/18356694/68697343-41ea2380-0544-11ea-8218-601b57fdd835.png)
## References
See also: #2046
## PR Checklist
* [x] Closes #1205
* [x] Closes #522
* [x] Closes #999
* [x] I work here
* [😢] Tests added/passed
* [n/a] Requires documentation to be updated
## Validation Steps Performed
Tested manually opening panes, closing panes, clicking around panes, the whole dance.
---------------------------------------------------
* this is janky but is close for some reason?
* This is _almost_ right to solve #1205
If I want to double up and also fix #522 (which I do), then I need to also
* when a tab GetsFocus, send the focus instead to the Pane
* When the border is clicked on, focus that pane's control
And like a lot of cleanup, because this is horrifying
* hey this autorevoker is really nice
* Encapsulate Pane::pfnGotFocus
* Propogate the events back up on close
* Encapsulate Tab::pfnFocusChanged, and clean up TerminalPage a bit
* Mostly just code cleanup, commenting
* This works to hittest on the borders
If the border is `Transparent`, then it can't hittest for Tapped events, and it'll fall through (to someone)
THis at least works, but looks garish
* Match the pane border to the TabViewHeader
* Fix a bit of dead code and a bad copy-pasta
* This _works_ to use a winrt event, but it's dirty
* Clean up everything from the winrt::event debacle.
* This is dead code that shouldn't have been there
* Turn Tab's callback into a winrt::event as well
2019-11-18 22:41:25 +01:00
|
|
|
const auto termControl = _GetActiveControl();
|
2019-09-30 15:18:05 +02:00
|
|
|
termControl.AdjustFontSize(realArgs.Delta());
|
|
|
|
args.Handled(true);
|
|
|
|
}
|
|
|
|
}
|
Enable fullscreen mode (#3408)
## Summary of the Pull Request
Enables the `toggleFullscreen` action to be able to enter fullscreen mode, bound by default to <kbd>alt+enter</kbd>.
The action is bubbled up to the WindowsTerminal (Win32) layer, where the window resizes itself to take the entire size of the monitor.
This largely reuses code from conhost. Conhost already had a fullscreen mode, so I figured I might as well re-use that.
## References
Unfortunately there are still very thin borders around the window when the NonClientIslandWindow is fullscreened. I think I know where the problem is. However, that area of code is about to get a massive overhaul with #3064, so I didn't want to necessarily make it worse right now.
A follow up should be filed to add support for "Always show / reveal / never show tabs in fullscreen mode". Currently, the only mode is "never show tabs".
Additionally, some of this code (particularily re:drawing the nonclient area) could be re-used for #2238.
## PR Checklist
* [x] Closes #531, #3411
* [x] I work here
* [n/a] Tests added/passed 😭
* [x] Requires documentation to be updated
## Validation Steps Performed
* Manually tested both the NonClientIslandWindow and the IslandWindow.
* Cherry-pick commit 8e56bfe
* Don't draw the tab strip when maximized
(cherry picked from commit bac4be7c0f3ed1cdcd4f9ae8980fc98103538613)
* Fix the vista window flash for the NCIW
(cherry picked from commit 7d3a18a893c02bd2ed75026f2aac52e20321a1cf)
* Some code cleanup for review
(cherry picked from commit 9e22b7730bba426adcbfd9e7025f192dbf8efb32)
* A tad bit more notes and cleanup
* Update schema, docs
* Most of the PR comments
* I'm not sure this actually works, so I'm committing it to revert it and check
* Update some comments that were lost.
* Fix a build break?
* oh no
2019-11-05 20:40:29 +01:00
|
|
|
|
Search - add search box control and implement search experience (#3590)
<!-- 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)? -->
This is the PR for feature Search: #605
This PR includes the newly introduced SearchBoxControl in TermControl dir, which is the search bar for the search experience. And the codes that enable Search in Windows Terminal.
<!-- Other than the issue solved, is this relevant to any other issues/existing PRs? -->
The PR that migrates the Conhost search module: https://github.com/microsoft/terminal/pull/3279
Spec (still actively updating): https://github.com/microsoft/terminal/pull/3299
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [x] Closes #605
* [ ] 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
* [ ] 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: #xxx
<!-- Provide a more detailed description of the PR, other things fixed or any additional comments/features here -->
These functionalities are included in the search experience.
1. Search in Terminal text buffer.
2. Automatic wrap-around.
3. Search up or down switch by clicking different buttons.
4. Search case sensitively/insensitively by clicking a button. S. Move the search box to the top/bottom by clicking a button.
6. Close by clicking 'X'.
7. Open search by ctrl + F.
When the searchbox is open, the user could still interact with the terminal by clicking the terminal input area.
While I already have the search functionalities, currently there are still some known to-do works and I will keep updating my PR:
1. Optimize the search box UI, this includes:
1) Theme adaptation. The search box background and font color
should change according to the theme,
2) Add background. Currently the elements in search box are all
transparent. However, we need a background.
3) Move button should be highlighted once clicked.
2. Accessibility: search process should be able to performed without mouse. Once the search box is focused, the user should be able to navigate between all interactive elements on the searchbox using keyboard.
<!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well -->
To test:
1. checkout this branch.
2. Build the project.
3. Start Windows Terminal and press Ctrl+F
4. The search box should appear on the top right corner.
2019-12-17 16:52:37 +01:00
|
|
|
void TerminalPage::_HandleFind(const IInspectable& /*sender*/,
|
2020-10-06 18:56:59 +02:00
|
|
|
const ActionEventArgs& args)
|
Search - add search box control and implement search experience (#3590)
<!-- 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)? -->
This is the PR for feature Search: #605
This PR includes the newly introduced SearchBoxControl in TermControl dir, which is the search bar for the search experience. And the codes that enable Search in Windows Terminal.
<!-- Other than the issue solved, is this relevant to any other issues/existing PRs? -->
The PR that migrates the Conhost search module: https://github.com/microsoft/terminal/pull/3279
Spec (still actively updating): https://github.com/microsoft/terminal/pull/3299
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [x] Closes #605
* [ ] 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
* [ ] 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: #xxx
<!-- Provide a more detailed description of the PR, other things fixed or any additional comments/features here -->
These functionalities are included in the search experience.
1. Search in Terminal text buffer.
2. Automatic wrap-around.
3. Search up or down switch by clicking different buttons.
4. Search case sensitively/insensitively by clicking a button. S. Move the search box to the top/bottom by clicking a button.
6. Close by clicking 'X'.
7. Open search by ctrl + F.
When the searchbox is open, the user could still interact with the terminal by clicking the terminal input area.
While I already have the search functionalities, currently there are still some known to-do works and I will keep updating my PR:
1. Optimize the search box UI, this includes:
1) Theme adaptation. The search box background and font color
should change according to the theme,
2) Add background. Currently the elements in search box are all
transparent. However, we need a background.
3) Move button should be highlighted once clicked.
2. Accessibility: search process should be able to performed without mouse. Once the search box is focused, the user should be able to navigate between all interactive elements on the searchbox using keyboard.
<!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well -->
To test:
1. checkout this branch.
2. Build the project.
3. Start Windows Terminal and press Ctrl+F
4. The search box should appear on the top right corner.
2019-12-17 16:52:37 +01:00
|
|
|
{
|
|
|
|
_Find();
|
|
|
|
args.Handled(true);
|
|
|
|
}
|
|
|
|
|
2019-11-25 18:35:10 +01:00
|
|
|
void TerminalPage::_HandleResetFontSize(const IInspectable& /*sender*/,
|
2020-10-06 18:56:59 +02:00
|
|
|
const ActionEventArgs& args)
|
2019-11-25 18:35:10 +01:00
|
|
|
{
|
|
|
|
const auto termControl = _GetActiveControl();
|
|
|
|
termControl.ResetFontSize();
|
|
|
|
args.Handled(true);
|
|
|
|
}
|
|
|
|
|
Implement user-specified pixel shaders, redux (#8565)
Co-authored-by: mrange <marten_range@hotmail.com>
I loved the pixel shaders in #7058, but that PR needed a bit of polish
to be ready for ingestion. This PR is almost _exactly_ that PR, with
some small changes.
* It adds a new pre-profile setting `"experimental.pixelShaderPath"`,
which lets the user set a pixel shader to use with the Terminal.
- CHANGED FROM #7058: It does _not_ add any built-in shaders.
- CHANGED FROM #7058: it will _override_
`experimental.retroTerminalEffect`
* It adds a bunch of sample shaders in `samples/shaders`. Included:
- A NOP shader as a base to build from.
- An "invert" shader that inverts the colors, as a simple example
- An "grayscale" shader that converts all colors to grayscale, as a
simple example
- An "raster bars" shader that draws some colored bars on the screen
with a drop shadow, as a more involved example
- The original retro terminal effects, as a more involved example
- It also includes a broken shader, as an example of what heppens
when the shader fails to compile
- CHANGED FROM #7058: It does _not_ add the "retroII" shader we were
all worried about.
* When a shader fails to be found or fails to compile, we'll display an
error dialog to the user with a relevant error message.
- CHANGED FROM #7058: Originally, #7058 would display "error bars"
on the screen. I've removed that, and had the Terminal disable the
shader entirely then.
* Renames the `toggleRetroEffect` action to `toggleShaderEffect`.
(`toggleRetroEffect` is now an alias to `toggleShaderEffect`). This
action will turn the shader OR the retro effects on/off.
`toggleShaderEffect` works the way you'd expect it to, but the mental
math on _how_ is a little weird. The logic is basically:
```
useShader = shaderEffectsEnabled ?
(pixelShaderProvided ?
pixelShader :
(retroEffectEnabled ?
retroEffect : null
)
) :
null
```
and `toggleShaderEffect` toggles `shaderEffectsEnabled`.
* If you've got both a shader and retro enabled, `toggleShaderEffect`
will toggle between the shader on/off.
* If you've got a shader and retro disabled, `toggleShaderEffect` will
toggle between the shader on/off.
References #6191
References #7058
Closes #7013
Closes #3930 "Add setting to retro terminal shader to control blur
radius, color"
Closes #3929 "Add setting to retro terminal shader to enable drawing
scanlines"
- At this point, just roll your own version of the shader.
2020-12-15 21:40:22 +01:00
|
|
|
void TerminalPage::_HandleToggleShaderEffects(const IInspectable& /*sender*/,
|
|
|
|
const ActionEventArgs& args)
|
2020-07-02 01:17:43 +02:00
|
|
|
{
|
|
|
|
const auto termControl = _GetActiveControl();
|
Implement user-specified pixel shaders, redux (#8565)
Co-authored-by: mrange <marten_range@hotmail.com>
I loved the pixel shaders in #7058, but that PR needed a bit of polish
to be ready for ingestion. This PR is almost _exactly_ that PR, with
some small changes.
* It adds a new pre-profile setting `"experimental.pixelShaderPath"`,
which lets the user set a pixel shader to use with the Terminal.
- CHANGED FROM #7058: It does _not_ add any built-in shaders.
- CHANGED FROM #7058: it will _override_
`experimental.retroTerminalEffect`
* It adds a bunch of sample shaders in `samples/shaders`. Included:
- A NOP shader as a base to build from.
- An "invert" shader that inverts the colors, as a simple example
- An "grayscale" shader that converts all colors to grayscale, as a
simple example
- An "raster bars" shader that draws some colored bars on the screen
with a drop shadow, as a more involved example
- The original retro terminal effects, as a more involved example
- It also includes a broken shader, as an example of what heppens
when the shader fails to compile
- CHANGED FROM #7058: It does _not_ add the "retroII" shader we were
all worried about.
* When a shader fails to be found or fails to compile, we'll display an
error dialog to the user with a relevant error message.
- CHANGED FROM #7058: Originally, #7058 would display "error bars"
on the screen. I've removed that, and had the Terminal disable the
shader entirely then.
* Renames the `toggleRetroEffect` action to `toggleShaderEffect`.
(`toggleRetroEffect` is now an alias to `toggleShaderEffect`). This
action will turn the shader OR the retro effects on/off.
`toggleShaderEffect` works the way you'd expect it to, but the mental
math on _how_ is a little weird. The logic is basically:
```
useShader = shaderEffectsEnabled ?
(pixelShaderProvided ?
pixelShader :
(retroEffectEnabled ?
retroEffect : null
)
) :
null
```
and `toggleShaderEffect` toggles `shaderEffectsEnabled`.
* If you've got both a shader and retro enabled, `toggleShaderEffect`
will toggle between the shader on/off.
* If you've got a shader and retro disabled, `toggleShaderEffect` will
toggle between the shader on/off.
References #6191
References #7058
Closes #7013
Closes #3930 "Add setting to retro terminal shader to control blur
radius, color"
Closes #3929 "Add setting to retro terminal shader to enable drawing
scanlines"
- At this point, just roll your own version of the shader.
2020-12-15 21:40:22 +01:00
|
|
|
termControl.ToggleShaderEffects();
|
2020-07-02 01:17:43 +02:00
|
|
|
args.Handled(true);
|
|
|
|
}
|
|
|
|
|
2020-07-13 19:40:20 +02:00
|
|
|
void TerminalPage::_HandleToggleFocusMode(const IInspectable& /*sender*/,
|
2020-10-06 18:56:59 +02:00
|
|
|
const ActionEventArgs& args)
|
2020-07-13 19:40:20 +02:00
|
|
|
{
|
|
|
|
ToggleFocusMode();
|
|
|
|
args.Handled(true);
|
|
|
|
}
|
|
|
|
|
Enable fullscreen mode (#3408)
## Summary of the Pull Request
Enables the `toggleFullscreen` action to be able to enter fullscreen mode, bound by default to <kbd>alt+enter</kbd>.
The action is bubbled up to the WindowsTerminal (Win32) layer, where the window resizes itself to take the entire size of the monitor.
This largely reuses code from conhost. Conhost already had a fullscreen mode, so I figured I might as well re-use that.
## References
Unfortunately there are still very thin borders around the window when the NonClientIslandWindow is fullscreened. I think I know where the problem is. However, that area of code is about to get a massive overhaul with #3064, so I didn't want to necessarily make it worse right now.
A follow up should be filed to add support for "Always show / reveal / never show tabs in fullscreen mode". Currently, the only mode is "never show tabs".
Additionally, some of this code (particularily re:drawing the nonclient area) could be re-used for #2238.
## PR Checklist
* [x] Closes #531, #3411
* [x] I work here
* [n/a] Tests added/passed 😭
* [x] Requires documentation to be updated
## Validation Steps Performed
* Manually tested both the NonClientIslandWindow and the IslandWindow.
* Cherry-pick commit 8e56bfe
* Don't draw the tab strip when maximized
(cherry picked from commit bac4be7c0f3ed1cdcd4f9ae8980fc98103538613)
* Fix the vista window flash for the NCIW
(cherry picked from commit 7d3a18a893c02bd2ed75026f2aac52e20321a1cf)
* Some code cleanup for review
(cherry picked from commit 9e22b7730bba426adcbfd9e7025f192dbf8efb32)
* A tad bit more notes and cleanup
* Update schema, docs
* Most of the PR comments
* I'm not sure this actually works, so I'm committing it to revert it and check
* Update some comments that were lost.
* Fix a build break?
* oh no
2019-11-05 20:40:29 +01:00
|
|
|
void TerminalPage::_HandleToggleFullscreen(const IInspectable& /*sender*/,
|
2020-10-06 18:56:59 +02:00
|
|
|
const ActionEventArgs& args)
|
Enable fullscreen mode (#3408)
## Summary of the Pull Request
Enables the `toggleFullscreen` action to be able to enter fullscreen mode, bound by default to <kbd>alt+enter</kbd>.
The action is bubbled up to the WindowsTerminal (Win32) layer, where the window resizes itself to take the entire size of the monitor.
This largely reuses code from conhost. Conhost already had a fullscreen mode, so I figured I might as well re-use that.
## References
Unfortunately there are still very thin borders around the window when the NonClientIslandWindow is fullscreened. I think I know where the problem is. However, that area of code is about to get a massive overhaul with #3064, so I didn't want to necessarily make it worse right now.
A follow up should be filed to add support for "Always show / reveal / never show tabs in fullscreen mode". Currently, the only mode is "never show tabs".
Additionally, some of this code (particularily re:drawing the nonclient area) could be re-used for #2238.
## PR Checklist
* [x] Closes #531, #3411
* [x] I work here
* [n/a] Tests added/passed 😭
* [x] Requires documentation to be updated
## Validation Steps Performed
* Manually tested both the NonClientIslandWindow and the IslandWindow.
* Cherry-pick commit 8e56bfe
* Don't draw the tab strip when maximized
(cherry picked from commit bac4be7c0f3ed1cdcd4f9ae8980fc98103538613)
* Fix the vista window flash for the NCIW
(cherry picked from commit 7d3a18a893c02bd2ed75026f2aac52e20321a1cf)
* Some code cleanup for review
(cherry picked from commit 9e22b7730bba426adcbfd9e7025f192dbf8efb32)
* A tad bit more notes and cleanup
* Update schema, docs
* Most of the PR comments
* I'm not sure this actually works, so I'm committing it to revert it and check
* Update some comments that were lost.
* Fix a build break?
* oh no
2019-11-05 20:40:29 +01:00
|
|
|
{
|
2020-06-01 23:57:30 +02:00
|
|
|
ToggleFullscreen();
|
Enable fullscreen mode (#3408)
## Summary of the Pull Request
Enables the `toggleFullscreen` action to be able to enter fullscreen mode, bound by default to <kbd>alt+enter</kbd>.
The action is bubbled up to the WindowsTerminal (Win32) layer, where the window resizes itself to take the entire size of the monitor.
This largely reuses code from conhost. Conhost already had a fullscreen mode, so I figured I might as well re-use that.
## References
Unfortunately there are still very thin borders around the window when the NonClientIslandWindow is fullscreened. I think I know where the problem is. However, that area of code is about to get a massive overhaul with #3064, so I didn't want to necessarily make it worse right now.
A follow up should be filed to add support for "Always show / reveal / never show tabs in fullscreen mode". Currently, the only mode is "never show tabs".
Additionally, some of this code (particularily re:drawing the nonclient area) could be re-used for #2238.
## PR Checklist
* [x] Closes #531, #3411
* [x] I work here
* [n/a] Tests added/passed 😭
* [x] Requires documentation to be updated
## Validation Steps Performed
* Manually tested both the NonClientIslandWindow and the IslandWindow.
* Cherry-pick commit 8e56bfe
* Don't draw the tab strip when maximized
(cherry picked from commit bac4be7c0f3ed1cdcd4f9ae8980fc98103538613)
* Fix the vista window flash for the NCIW
(cherry picked from commit 7d3a18a893c02bd2ed75026f2aac52e20321a1cf)
* Some code cleanup for review
(cherry picked from commit 9e22b7730bba426adcbfd9e7025f192dbf8efb32)
* A tad bit more notes and cleanup
* Update schema, docs
* Most of the PR comments
* I'm not sure this actually works, so I'm committing it to revert it and check
* Update some comments that were lost.
* Fix a build break?
* oh no
2019-11-05 20:40:29 +01:00
|
|
|
args.Handled(true);
|
|
|
|
}
|
2020-06-24 22:07:41 +02:00
|
|
|
|
2020-07-14 23:02:18 +02:00
|
|
|
void TerminalPage::_HandleToggleAlwaysOnTop(const IInspectable& /*sender*/,
|
2020-10-06 18:56:59 +02:00
|
|
|
const ActionEventArgs& args)
|
2020-07-14 23:02:18 +02:00
|
|
|
{
|
|
|
|
ToggleAlwaysOnTop();
|
|
|
|
args.Handled(true);
|
|
|
|
}
|
|
|
|
|
2020-06-26 22:38:02 +02:00
|
|
|
void TerminalPage::_HandleToggleCommandPalette(const IInspectable& /*sender*/,
|
2020-10-06 18:56:59 +02:00
|
|
|
const ActionEventArgs& args)
|
2020-06-26 22:38:02 +02:00
|
|
|
{
|
2020-12-03 17:15:31 +01:00
|
|
|
if (const auto& realArgs = args.ActionArgs().try_as<ToggleCommandPaletteArgs>())
|
|
|
|
{
|
|
|
|
CommandPalette().EnableCommandPaletteMode(realArgs.LaunchMode());
|
|
|
|
CommandPalette().Visibility(CommandPalette().Visibility() == Visibility::Visible ?
|
|
|
|
Visibility::Collapsed :
|
|
|
|
Visibility::Visible);
|
|
|
|
args.Handled(true);
|
|
|
|
}
|
2020-06-26 22:38:02 +02:00
|
|
|
}
|
|
|
|
|
2020-08-10 18:21:56 +02:00
|
|
|
void TerminalPage::_HandleSetColorScheme(const IInspectable& /*sender*/,
|
2020-10-06 18:56:59 +02:00
|
|
|
const ActionEventArgs& args)
|
2020-08-10 18:21:56 +02:00
|
|
|
{
|
|
|
|
args.Handled(false);
|
2020-10-06 18:56:59 +02:00
|
|
|
if (const auto& realArgs = args.ActionArgs().try_as<SetColorSchemeArgs>())
|
2020-08-10 18:21:56 +02:00
|
|
|
{
|
2021-01-04 20:32:53 +01:00
|
|
|
if (const auto activeTab{ _GetFocusedTabImpl() })
|
2020-08-10 18:21:56 +02:00
|
|
|
{
|
2021-01-04 20:32:53 +01:00
|
|
|
if (auto activeControl = activeTab->GetActiveTerminalControl())
|
2020-08-10 18:21:56 +02:00
|
|
|
{
|
2021-01-04 20:32:53 +01:00
|
|
|
if (const auto scheme = _settings.GlobalSettings().ColorSchemes().TryLookup(realArgs.SchemeName()))
|
2020-08-10 18:21:56 +02:00
|
|
|
{
|
2021-01-04 20:32:53 +01:00
|
|
|
auto controlSettings = activeControl.Settings().as<TerminalSettings>();
|
2021-03-16 00:15:25 +01:00
|
|
|
controlSettings.ApplyColorScheme(scheme);
|
2021-02-08 23:01:40 +01:00
|
|
|
activeControl.UpdateSettings();
|
2021-01-04 20:32:53 +01:00
|
|
|
args.Handled(true);
|
2020-08-10 18:21:56 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Add `setTabColor` and `openTabColorPicker` actions (#6567)
## Summary of the Pull Request
Adds a pair of `ShortcutAction`s for setting the tab color.
* `setTabColor`: This changes the color of the current tab to the provided color, or can be used to clear the color.
* `openTabColorPicker`: This keybinding immediately activates the tab color picker for the currently focused tab.
## References
## PR Checklist
* [x] scratches my own itch
* [x] I work here
* [x] Tests added/passed
* [x] https://github.com/MicrosoftDocs/terminal/pull/69
## Detailed Description of the Pull Request / Additional comments
## Validation Steps Performed
* hey look there are tests
* Tested with the following:
```json
// { "command": "setTabColor", "keys": [ "alt+c" ] },
{ "keys": "ctrl+alt+c", "command": { "action": "setTabColor", "color": "#123456" } },
{ "keys": "alt+shift+c", "command": { "action": "setTabColor", "color": null} },
{ "keys": "alt+c", "command": "openTabColorPicker" },
```
2020-06-25 15:06:21 +02:00
|
|
|
void TerminalPage::_HandleSetTabColor(const IInspectable& /*sender*/,
|
2020-10-06 18:56:59 +02:00
|
|
|
const ActionEventArgs& args)
|
Add `setTabColor` and `openTabColorPicker` actions (#6567)
## Summary of the Pull Request
Adds a pair of `ShortcutAction`s for setting the tab color.
* `setTabColor`: This changes the color of the current tab to the provided color, or can be used to clear the color.
* `openTabColorPicker`: This keybinding immediately activates the tab color picker for the currently focused tab.
## References
## PR Checklist
* [x] scratches my own itch
* [x] I work here
* [x] Tests added/passed
* [x] https://github.com/MicrosoftDocs/terminal/pull/69
## Detailed Description of the Pull Request / Additional comments
## Validation Steps Performed
* hey look there are tests
* Tested with the following:
```json
// { "command": "setTabColor", "keys": [ "alt+c" ] },
{ "keys": "ctrl+alt+c", "command": { "action": "setTabColor", "color": "#123456" } },
{ "keys": "alt+shift+c", "command": { "action": "setTabColor", "color": null} },
{ "keys": "alt+c", "command": "openTabColorPicker" },
```
2020-06-25 15:06:21 +02:00
|
|
|
{
|
2020-11-20 05:36:18 +01:00
|
|
|
Windows::Foundation::IReference<Windows::UI::Color> tabColor;
|
Add `setTabColor` and `openTabColorPicker` actions (#6567)
## Summary of the Pull Request
Adds a pair of `ShortcutAction`s for setting the tab color.
* `setTabColor`: This changes the color of the current tab to the provided color, or can be used to clear the color.
* `openTabColorPicker`: This keybinding immediately activates the tab color picker for the currently focused tab.
## References
## PR Checklist
* [x] scratches my own itch
* [x] I work here
* [x] Tests added/passed
* [x] https://github.com/MicrosoftDocs/terminal/pull/69
## Detailed Description of the Pull Request / Additional comments
## Validation Steps Performed
* hey look there are tests
* Tested with the following:
```json
// { "command": "setTabColor", "keys": [ "alt+c" ] },
{ "keys": "ctrl+alt+c", "command": { "action": "setTabColor", "color": "#123456" } },
{ "keys": "alt+shift+c", "command": { "action": "setTabColor", "color": null} },
{ "keys": "alt+c", "command": "openTabColorPicker" },
```
2020-06-25 15:06:21 +02:00
|
|
|
|
2020-10-06 18:56:59 +02:00
|
|
|
if (const auto& realArgs = args.ActionArgs().try_as<SetTabColorArgs>())
|
Add `setTabColor` and `openTabColorPicker` actions (#6567)
## Summary of the Pull Request
Adds a pair of `ShortcutAction`s for setting the tab color.
* `setTabColor`: This changes the color of the current tab to the provided color, or can be used to clear the color.
* `openTabColorPicker`: This keybinding immediately activates the tab color picker for the currently focused tab.
## References
## PR Checklist
* [x] scratches my own itch
* [x] I work here
* [x] Tests added/passed
* [x] https://github.com/MicrosoftDocs/terminal/pull/69
## Detailed Description of the Pull Request / Additional comments
## Validation Steps Performed
* hey look there are tests
* Tested with the following:
```json
// { "command": "setTabColor", "keys": [ "alt+c" ] },
{ "keys": "ctrl+alt+c", "command": { "action": "setTabColor", "color": "#123456" } },
{ "keys": "alt+shift+c", "command": { "action": "setTabColor", "color": null} },
{ "keys": "alt+c", "command": "openTabColorPicker" },
```
2020-06-25 15:06:21 +02:00
|
|
|
{
|
2020-11-20 05:36:18 +01:00
|
|
|
tabColor = realArgs.TabColor();
|
Add `setTabColor` and `openTabColorPicker` actions (#6567)
## Summary of the Pull Request
Adds a pair of `ShortcutAction`s for setting the tab color.
* `setTabColor`: This changes the color of the current tab to the provided color, or can be used to clear the color.
* `openTabColorPicker`: This keybinding immediately activates the tab color picker for the currently focused tab.
## References
## PR Checklist
* [x] scratches my own itch
* [x] I work here
* [x] Tests added/passed
* [x] https://github.com/MicrosoftDocs/terminal/pull/69
## Detailed Description of the Pull Request / Additional comments
## Validation Steps Performed
* hey look there are tests
* Tested with the following:
```json
// { "command": "setTabColor", "keys": [ "alt+c" ] },
{ "keys": "ctrl+alt+c", "command": { "action": "setTabColor", "color": "#123456" } },
{ "keys": "alt+shift+c", "command": { "action": "setTabColor", "color": null} },
{ "keys": "alt+c", "command": "openTabColorPicker" },
```
2020-06-25 15:06:21 +02:00
|
|
|
}
|
|
|
|
|
2021-01-04 20:32:53 +01:00
|
|
|
if (const auto activeTab{ _GetFocusedTabImpl() })
|
Add `setTabColor` and `openTabColorPicker` actions (#6567)
## Summary of the Pull Request
Adds a pair of `ShortcutAction`s for setting the tab color.
* `setTabColor`: This changes the color of the current tab to the provided color, or can be used to clear the color.
* `openTabColorPicker`: This keybinding immediately activates the tab color picker for the currently focused tab.
## References
## PR Checklist
* [x] scratches my own itch
* [x] I work here
* [x] Tests added/passed
* [x] https://github.com/MicrosoftDocs/terminal/pull/69
## Detailed Description of the Pull Request / Additional comments
## Validation Steps Performed
* hey look there are tests
* Tested with the following:
```json
// { "command": "setTabColor", "keys": [ "alt+c" ] },
{ "keys": "ctrl+alt+c", "command": { "action": "setTabColor", "color": "#123456" } },
{ "keys": "alt+shift+c", "command": { "action": "setTabColor", "color": null} },
{ "keys": "alt+c", "command": "openTabColorPicker" },
```
2020-06-25 15:06:21 +02:00
|
|
|
{
|
2021-01-04 20:32:53 +01:00
|
|
|
if (tabColor)
|
Add `setTabColor` and `openTabColorPicker` actions (#6567)
## Summary of the Pull Request
Adds a pair of `ShortcutAction`s for setting the tab color.
* `setTabColor`: This changes the color of the current tab to the provided color, or can be used to clear the color.
* `openTabColorPicker`: This keybinding immediately activates the tab color picker for the currently focused tab.
## References
## PR Checklist
* [x] scratches my own itch
* [x] I work here
* [x] Tests added/passed
* [x] https://github.com/MicrosoftDocs/terminal/pull/69
## Detailed Description of the Pull Request / Additional comments
## Validation Steps Performed
* hey look there are tests
* Tested with the following:
```json
// { "command": "setTabColor", "keys": [ "alt+c" ] },
{ "keys": "ctrl+alt+c", "command": { "action": "setTabColor", "color": "#123456" } },
{ "keys": "alt+shift+c", "command": { "action": "setTabColor", "color": null} },
{ "keys": "alt+c", "command": "openTabColorPicker" },
```
2020-06-25 15:06:21 +02:00
|
|
|
{
|
2021-01-04 20:32:53 +01:00
|
|
|
activeTab->SetRuntimeTabColor(tabColor.Value());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
activeTab->ResetRuntimeTabColor();
|
Add `setTabColor` and `openTabColorPicker` actions (#6567)
## Summary of the Pull Request
Adds a pair of `ShortcutAction`s for setting the tab color.
* `setTabColor`: This changes the color of the current tab to the provided color, or can be used to clear the color.
* `openTabColorPicker`: This keybinding immediately activates the tab color picker for the currently focused tab.
## References
## PR Checklist
* [x] scratches my own itch
* [x] I work here
* [x] Tests added/passed
* [x] https://github.com/MicrosoftDocs/terminal/pull/69
## Detailed Description of the Pull Request / Additional comments
## Validation Steps Performed
* hey look there are tests
* Tested with the following:
```json
// { "command": "setTabColor", "keys": [ "alt+c" ] },
{ "keys": "ctrl+alt+c", "command": { "action": "setTabColor", "color": "#123456" } },
{ "keys": "alt+shift+c", "command": { "action": "setTabColor", "color": null} },
{ "keys": "alt+c", "command": "openTabColorPicker" },
```
2020-06-25 15:06:21 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
args.Handled(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TerminalPage::_HandleOpenTabColorPicker(const IInspectable& /*sender*/,
|
2020-10-06 18:56:59 +02:00
|
|
|
const ActionEventArgs& args)
|
Add `setTabColor` and `openTabColorPicker` actions (#6567)
## Summary of the Pull Request
Adds a pair of `ShortcutAction`s for setting the tab color.
* `setTabColor`: This changes the color of the current tab to the provided color, or can be used to clear the color.
* `openTabColorPicker`: This keybinding immediately activates the tab color picker for the currently focused tab.
## References
## PR Checklist
* [x] scratches my own itch
* [x] I work here
* [x] Tests added/passed
* [x] https://github.com/MicrosoftDocs/terminal/pull/69
## Detailed Description of the Pull Request / Additional comments
## Validation Steps Performed
* hey look there are tests
* Tested with the following:
```json
// { "command": "setTabColor", "keys": [ "alt+c" ] },
{ "keys": "ctrl+alt+c", "command": { "action": "setTabColor", "color": "#123456" } },
{ "keys": "alt+shift+c", "command": { "action": "setTabColor", "color": null} },
{ "keys": "alt+c", "command": "openTabColorPicker" },
```
2020-06-25 15:06:21 +02:00
|
|
|
{
|
2021-01-04 20:32:53 +01:00
|
|
|
if (const auto activeTab{ _GetFocusedTabImpl() })
|
Add `setTabColor` and `openTabColorPicker` actions (#6567)
## Summary of the Pull Request
Adds a pair of `ShortcutAction`s for setting the tab color.
* `setTabColor`: This changes the color of the current tab to the provided color, or can be used to clear the color.
* `openTabColorPicker`: This keybinding immediately activates the tab color picker for the currently focused tab.
## References
## PR Checklist
* [x] scratches my own itch
* [x] I work here
* [x] Tests added/passed
* [x] https://github.com/MicrosoftDocs/terminal/pull/69
## Detailed Description of the Pull Request / Additional comments
## Validation Steps Performed
* hey look there are tests
* Tested with the following:
```json
// { "command": "setTabColor", "keys": [ "alt+c" ] },
{ "keys": "ctrl+alt+c", "command": { "action": "setTabColor", "color": "#123456" } },
{ "keys": "alt+shift+c", "command": { "action": "setTabColor", "color": null} },
{ "keys": "alt+c", "command": "openTabColorPicker" },
```
2020-06-25 15:06:21 +02:00
|
|
|
{
|
2021-01-04 20:32:53 +01:00
|
|
|
activeTab->ActivateColorPicker();
|
Add `setTabColor` and `openTabColorPicker` actions (#6567)
## Summary of the Pull Request
Adds a pair of `ShortcutAction`s for setting the tab color.
* `setTabColor`: This changes the color of the current tab to the provided color, or can be used to clear the color.
* `openTabColorPicker`: This keybinding immediately activates the tab color picker for the currently focused tab.
## References
## PR Checklist
* [x] scratches my own itch
* [x] I work here
* [x] Tests added/passed
* [x] https://github.com/MicrosoftDocs/terminal/pull/69
## Detailed Description of the Pull Request / Additional comments
## Validation Steps Performed
* hey look there are tests
* Tested with the following:
```json
// { "command": "setTabColor", "keys": [ "alt+c" ] },
{ "keys": "ctrl+alt+c", "command": { "action": "setTabColor", "color": "#123456" } },
{ "keys": "alt+shift+c", "command": { "action": "setTabColor", "color": null} },
{ "keys": "alt+c", "command": "openTabColorPicker" },
```
2020-06-25 15:06:21 +02:00
|
|
|
}
|
|
|
|
args.Handled(true);
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:07:41 +02:00
|
|
|
void TerminalPage::_HandleRenameTab(const IInspectable& /*sender*/,
|
2020-10-06 18:56:59 +02:00
|
|
|
const ActionEventArgs& args)
|
2020-06-24 22:07:41 +02:00
|
|
|
{
|
|
|
|
std::optional<winrt::hstring> title;
|
|
|
|
|
2020-10-06 18:56:59 +02:00
|
|
|
if (const auto& realArgs = args.ActionArgs().try_as<RenameTabArgs>())
|
2020-06-24 22:07:41 +02:00
|
|
|
{
|
|
|
|
title = realArgs.Title();
|
|
|
|
}
|
|
|
|
|
2021-01-04 20:32:53 +01:00
|
|
|
if (const auto activeTab{ _GetFocusedTabImpl() })
|
2020-06-24 22:07:41 +02:00
|
|
|
{
|
2021-01-04 20:32:53 +01:00
|
|
|
if (title.has_value())
|
2020-06-24 22:07:41 +02:00
|
|
|
{
|
2021-01-04 20:32:53 +01:00
|
|
|
activeTab->SetTabText(title.value());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
activeTab->ResetTabText();
|
2020-06-24 22:07:41 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
args.Handled(true);
|
|
|
|
}
|
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
|
|
|
|
2020-10-28 20:36:30 +01:00
|
|
|
void TerminalPage::_HandleOpenTabRenamer(const IInspectable& /*sender*/,
|
|
|
|
const ActionEventArgs& args)
|
|
|
|
{
|
2021-01-04 20:32:53 +01:00
|
|
|
if (const auto activeTab{ _GetFocusedTabImpl() })
|
2020-10-28 20:36:30 +01:00
|
|
|
{
|
2021-01-04 20:32:53 +01:00
|
|
|
activeTab->ActivateTabRenamer();
|
2020-10-28 20:36:30 +01:00
|
|
|
}
|
|
|
|
args.Handled(true);
|
|
|
|
}
|
|
|
|
|
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
|
|
|
void TerminalPage::_HandleExecuteCommandline(const IInspectable& /*sender*/,
|
2020-10-06 18:56:59 +02:00
|
|
|
const ActionEventArgs& actionArgs)
|
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
|
|
|
{
|
2020-10-06 18:56:59 +02:00
|
|
|
if (const auto& realArgs = actionArgs.ActionArgs().try_as<ExecuteCommandlineArgs>())
|
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
|
|
|
{
|
2020-10-06 18:56:59 +02:00
|
|
|
auto actions = winrt::single_threaded_vector<ActionAndArgs>(std::move(
|
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
|
|
|
TerminalPage::ConvertExecuteCommandlineToActions(realArgs)));
|
|
|
|
|
|
|
|
if (_startupActions.Size() != 0)
|
|
|
|
{
|
|
|
|
actionArgs.Handled(true);
|
Add `Microsoft.Terminal.Remoting.dll` (#8607)
Adds a `Microsoft.Terminal.Remoting.dll` to our solution. This DLL will
be responsible for all the Monarch/Peasant work that's been described in
#7240 & #8135.
This PR does _not_ implement the Monarch/Peasant architecture in any
significant way. The goal of this PR is to just to establish the project
layout, and the most basic connections. This should make reviewing the
actual meat of the implementation (in a later PR) easier. It will also
give us the opportunity to include some of the basic weird things we're
doing (with `CoRegisterClass`) in the Terminal _now_, and get them
selfhosted, before building on them too much.
This PR does have windows registering the `Monarch` class with COM. When
windows are created, they'll as the Monarch if they should create a new
window or not. In this PR, the Monarch will always reply "yes, please
make a new window".
Similar to other projects in our solution, we're adding 3 projects here:
* `Microsoft.Terminal.Remoting.lib`: the actual implementation, as a
static lib.
* `Microsoft.Terminal.Remoting.dll`: The implementation linked as a DLL,
for use in `WindowsTerminal.exe`.
* `Remoting.UnitTests.dll`: A unit test dll that links with the static
lib.
There are plenty of TODOs scattered about the code. Clearly, most of
this isn't implemented yet, but I do have more WIP branches. I'm using
[`projects/5`](https://github.com/microsoft/terminal/projects/5) as my
notation for TODOs that are too small for an issue, but are part of the
whole Process Model 2.0 work.
## References
* #5000 - this is the process model megathread
* #7240 - The process model 2.0 spec.
* #8135 - the window management spec. (please review me, I have 0/3
signoffs even after the discussion we had 😢)
* #8171 - the Monarch/peasant sample. (please review me, I have 1/2)
## PR Checklist
* [x] Closes nothing, this is just infrastructure
* [x] I work here
* [x] Tests added/passed
* [n/a] Requires documentation to be updated
2021-01-07 23:59:37 +01:00
|
|
|
ProcessStartupActions(actions, false);
|
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
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-08-06 23:47:50 +02:00
|
|
|
|
|
|
|
void TerminalPage::_HandleCloseOtherTabs(const IInspectable& /*sender*/,
|
2020-10-06 18:56:59 +02:00
|
|
|
const ActionEventArgs& actionArgs)
|
2020-08-06 23:47:50 +02:00
|
|
|
{
|
2020-10-06 18:56:59 +02:00
|
|
|
if (const auto& realArgs = actionArgs.ActionArgs().try_as<CloseOtherTabsArgs>())
|
2020-08-06 23:47:50 +02:00
|
|
|
{
|
2020-08-25 21:25:25 +02:00
|
|
|
uint32_t index;
|
|
|
|
if (realArgs.Index())
|
|
|
|
{
|
|
|
|
index = realArgs.Index().Value();
|
|
|
|
}
|
|
|
|
else if (auto focusedTabIndex = _GetFocusedTabIndex())
|
|
|
|
{
|
|
|
|
index = *focusedTabIndex;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Do nothing
|
|
|
|
actionArgs.Handled(false);
|
|
|
|
return;
|
|
|
|
}
|
2020-08-06 23:47:50 +02:00
|
|
|
|
Separate between Close Tab Requested and Tab Closed flows (#9574)
## Summary of the Pull Request
Currently, both when the tab is already closed, and when there is a
request to close a tab (might be rejected), we go through the same flow
in TerminalPage.
This might leave the system in inconsistent state, as the side-effects
of closing will persist even if the closing was aborted.
This PR separates between the two flows, by introducing a CloseRequested
event to the TabBase.
This event is used to inform the upper tier (the terminal page) about
the request and to trigger the same logic that happens when the tab is
closed directly from the terminal page (e.g., by clicking close on the
tab view).
The Closed event will be used only to handle the actual closing of the
tab. It will ensure that the tab gets removed from the terminal page if
required.
As a result, it a read-only pane will be closed non-interactively (aka
connection exits), the tab closed flow will be invoked, and no user
prompt will be shown.
## References
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [x] Closes https://github.com/microsoft/terminal/issues/9572
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed
* [ ] Documentation updated.
* [ ] Schema updated.
* [ ] I've discussed this with core contributors already.
2021-03-30 17:58:35 +02:00
|
|
|
// Since _RemoveTabs is asynchronous, create a snapshot of the tabs we want to remove
|
2021-02-08 19:03:55 +01:00
|
|
|
std::vector<winrt::TerminalApp::TabBase> tabsToRemove;
|
|
|
|
if (index > 0)
|
2020-08-06 23:47:50 +02:00
|
|
|
{
|
2021-02-08 19:03:55 +01:00
|
|
|
std::copy(begin(_tabs), begin(_tabs) + index, std::back_inserter(tabsToRemove));
|
2020-08-06 23:47:50 +02:00
|
|
|
}
|
|
|
|
|
2021-02-08 19:03:55 +01:00
|
|
|
if (index + 1 < _tabs.Size())
|
2020-08-06 23:47:50 +02:00
|
|
|
{
|
2021-02-08 19:03:55 +01:00
|
|
|
std::copy(begin(_tabs) + index + 1, end(_tabs), std::back_inserter(tabsToRemove));
|
2020-08-06 23:47:50 +02:00
|
|
|
}
|
|
|
|
|
2021-02-08 19:03:55 +01:00
|
|
|
_RemoveTabs(tabsToRemove);
|
|
|
|
|
2020-08-06 23:47:50 +02:00
|
|
|
actionArgs.Handled(true);
|
|
|
|
}
|
|
|
|
}
|
2020-08-11 16:03:12 +02:00
|
|
|
|
2020-08-06 23:47:50 +02:00
|
|
|
void TerminalPage::_HandleCloseTabsAfter(const IInspectable& /*sender*/,
|
2020-10-06 18:56:59 +02:00
|
|
|
const ActionEventArgs& actionArgs)
|
2020-08-06 23:47:50 +02:00
|
|
|
{
|
2020-10-06 18:56:59 +02:00
|
|
|
if (const auto& realArgs = actionArgs.ActionArgs().try_as<CloseTabsAfterArgs>())
|
2020-08-06 23:47:50 +02:00
|
|
|
{
|
2020-08-25 21:25:25 +02:00
|
|
|
uint32_t index;
|
|
|
|
if (realArgs.Index())
|
|
|
|
{
|
|
|
|
index = realArgs.Index().Value();
|
|
|
|
}
|
|
|
|
else if (auto focusedTabIndex = _GetFocusedTabIndex())
|
|
|
|
{
|
|
|
|
index = *focusedTabIndex;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Do nothing
|
|
|
|
actionArgs.Handled(false);
|
|
|
|
return;
|
|
|
|
}
|
2020-08-06 23:47:50 +02:00
|
|
|
|
Separate between Close Tab Requested and Tab Closed flows (#9574)
## Summary of the Pull Request
Currently, both when the tab is already closed, and when there is a
request to close a tab (might be rejected), we go through the same flow
in TerminalPage.
This might leave the system in inconsistent state, as the side-effects
of closing will persist even if the closing was aborted.
This PR separates between the two flows, by introducing a CloseRequested
event to the TabBase.
This event is used to inform the upper tier (the terminal page) about
the request and to trigger the same logic that happens when the tab is
closed directly from the terminal page (e.g., by clicking close on the
tab view).
The Closed event will be used only to handle the actual closing of the
tab. It will ensure that the tab gets removed from the terminal page if
required.
As a result, it a read-only pane will be closed non-interactively (aka
connection exits), the tab closed flow will be invoked, and no user
prompt will be shown.
## References
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [x] Closes https://github.com/microsoft/terminal/issues/9572
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed
* [ ] Documentation updated.
* [ ] Schema updated.
* [ ] I've discussed this with core contributors already.
2021-03-30 17:58:35 +02:00
|
|
|
// Since _RemoveTabs is asynchronous, create a snapshot of the tabs we want to remove
|
2021-02-08 19:03:55 +01:00
|
|
|
std::vector<winrt::TerminalApp::TabBase> tabsToRemove;
|
|
|
|
std::copy(begin(_tabs) + index + 1, end(_tabs), std::back_inserter(tabsToRemove));
|
|
|
|
_RemoveTabs(tabsToRemove);
|
2020-08-06 23:47:50 +02:00
|
|
|
|
|
|
|
// TODO:GH#7182 For whatever reason, if you run this action
|
|
|
|
// when the tab that's currently focused is _before_ the `index`
|
|
|
|
// param, then the tabs will expand to fill the entire width of the
|
|
|
|
// tab row, until you mouse over them. Probably has something to do
|
|
|
|
// with tabs not resizing down until there's a mouse exit event.
|
|
|
|
|
|
|
|
actionArgs.Handled(true);
|
|
|
|
}
|
|
|
|
}
|
2020-08-11 16:03:12 +02:00
|
|
|
|
2021-03-30 18:08:03 +02:00
|
|
|
void TerminalPage::_HandleTabSearch(const IInspectable& /*sender*/,
|
|
|
|
const ActionEventArgs& args)
|
2020-08-11 16:03:12 +02:00
|
|
|
{
|
2021-01-19 23:18:10 +01:00
|
|
|
CommandPalette().SetTabs(_tabs, _mruTabs);
|
|
|
|
CommandPalette().EnableTabSearchMode();
|
2020-08-21 17:39:40 +02:00
|
|
|
CommandPalette().Visibility(Visibility::Visible);
|
2020-08-11 16:03:12 +02:00
|
|
|
|
|
|
|
args.Handled(true);
|
|
|
|
}
|
2020-11-25 23:09:27 +01:00
|
|
|
|
|
|
|
void TerminalPage::_HandleMoveTab(const IInspectable& /*sender*/,
|
|
|
|
const ActionEventArgs& actionArgs)
|
|
|
|
{
|
|
|
|
if (const auto& realArgs = actionArgs.ActionArgs().try_as<MoveTabArgs>())
|
|
|
|
{
|
|
|
|
auto direction = realArgs.Direction();
|
|
|
|
if (direction != MoveTabDirection::None)
|
|
|
|
{
|
|
|
|
if (auto focusedTabIndex = _GetFocusedTabIndex())
|
|
|
|
{
|
|
|
|
auto currentTabIndex = focusedTabIndex.value();
|
|
|
|
auto delta = direction == MoveTabDirection::Forward ? 1 : -1;
|
|
|
|
_TryMoveTab(currentTabIndex, currentTabIndex + delta);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
actionArgs.Handled(true);
|
|
|
|
}
|
|
|
|
}
|
2020-12-05 00:54:59 +01:00
|
|
|
|
|
|
|
void TerminalPage::_HandleBreakIntoDebugger(const IInspectable& /*sender*/,
|
|
|
|
const ActionEventArgs& actionArgs)
|
|
|
|
{
|
|
|
|
if (_settings.GlobalSettings().DebugFeaturesEnabled())
|
|
|
|
{
|
|
|
|
actionArgs.Handled(true);
|
|
|
|
DebugBreak();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-20 00:51:30 +01:00
|
|
|
// Function Description:
|
|
|
|
// - Helper to launch a new WT instance. It can either launch the instance
|
|
|
|
// elevated or unelevated.
|
|
|
|
// - To launch elevated, it will as the shell to elevate the process for us.
|
|
|
|
// This might cause a UAC prompt. The elevation is performed on a
|
|
|
|
// background thread, as to not block the UI thread.
|
|
|
|
// Arguments:
|
|
|
|
// - elevate: If true, launch the new Terminal elevated using `runas`
|
|
|
|
// - newTerminalArgs: A NewTerminalArgs describing the terminal instance
|
|
|
|
// that should be spawned. The Profile should be filled in with the GUID
|
|
|
|
// of the profile we want to launch.
|
|
|
|
// Return Value:
|
|
|
|
// - <none>
|
|
|
|
// Important: Don't take the param by reference, since we'll be doing work
|
|
|
|
// on another thread.
|
2021-03-10 19:32:54 +01:00
|
|
|
fire_and_forget TerminalPage::_OpenNewWindow(const bool elevate,
|
|
|
|
const NewTerminalArgs newTerminalArgs)
|
2021-02-20 00:51:30 +01:00
|
|
|
{
|
|
|
|
// Hop to the BG thread
|
|
|
|
co_await winrt::resume_background();
|
|
|
|
|
|
|
|
// This will get us the correct exe for dev/preview/release. If you
|
|
|
|
// don't stick this in a local, it'll get mangled by ShellExecute. I
|
|
|
|
// have no idea why.
|
|
|
|
const auto exePath{ GetWtExePath() };
|
|
|
|
|
|
|
|
// Build the commandline to pass to wt for this set of NewTerminalArgs
|
|
|
|
// `-w -1` will ensure a new window is created.
|
|
|
|
winrt::hstring cmdline{
|
|
|
|
fmt::format(L"-w -1 new-tab {}",
|
|
|
|
newTerminalArgs ? newTerminalArgs.ToCommandline().c_str() :
|
|
|
|
L"")
|
|
|
|
};
|
|
|
|
|
|
|
|
// Build the args to ShellExecuteEx. We need to use ShellExecuteEx so we
|
|
|
|
// can pass the SEE_MASK_NOASYNC flag. That flag allows us to safely
|
|
|
|
// call this on the background thread, and have ShellExecute _not_ call
|
|
|
|
// back to us on the main thread. Without this, if you close the
|
|
|
|
// Terminal quickly after the UAC prompt, the elevated WT will never
|
|
|
|
// actually spawn.
|
|
|
|
SHELLEXECUTEINFOW seInfo{ 0 };
|
|
|
|
seInfo.cbSize = sizeof(seInfo);
|
|
|
|
seInfo.fMask = SEE_MASK_NOASYNC;
|
|
|
|
// `runas` will cause the shell to launch this child process elevated.
|
|
|
|
// `open` will just run the executable normally.
|
|
|
|
seInfo.lpVerb = elevate ? L"runas" : L"open";
|
|
|
|
seInfo.lpFile = exePath.c_str();
|
|
|
|
seInfo.lpParameters = cmdline.c_str();
|
|
|
|
seInfo.nShow = SW_SHOWNORMAL;
|
|
|
|
LOG_IF_WIN32_BOOL_FALSE(ShellExecuteExW(&seInfo));
|
|
|
|
|
|
|
|
co_return;
|
|
|
|
}
|
|
|
|
|
|
|
|
void TerminalPage::_HandleNewWindow(const IInspectable& /*sender*/,
|
|
|
|
const ActionEventArgs& actionArgs)
|
|
|
|
{
|
|
|
|
NewTerminalArgs newTerminalArgs{ nullptr };
|
|
|
|
// If the caller provided NewTerminalArgs, then try to use those
|
|
|
|
if (actionArgs)
|
|
|
|
{
|
|
|
|
if (const auto& realArgs = actionArgs.ActionArgs().try_as<NewWindowArgs>())
|
|
|
|
{
|
|
|
|
newTerminalArgs = realArgs.TerminalArgs();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Otherwise, if no NewTerminalArgs were provided, then just use a
|
|
|
|
// default-constructed one. The default-constructed one implies that
|
|
|
|
// nothing about the launch should be modified (just use the default
|
|
|
|
// profile).
|
|
|
|
if (!newTerminalArgs)
|
|
|
|
{
|
|
|
|
newTerminalArgs = NewTerminalArgs();
|
|
|
|
}
|
|
|
|
|
2021-03-16 00:15:25 +01:00
|
|
|
const auto profileGuid{ _settings.GetProfileForArgs(newTerminalArgs) };
|
|
|
|
const auto settings{ TerminalSettings::CreateWithNewTerminalArgs(_settings, newTerminalArgs, *_bindings) };
|
2021-02-20 00:51:30 +01:00
|
|
|
|
|
|
|
// Manually fill in the evaluated profile.
|
|
|
|
newTerminalArgs.Profile(::Microsoft::Console::Utils::GuidToString(profileGuid));
|
|
|
|
_OpenNewWindow(false, newTerminalArgs);
|
|
|
|
actionArgs.Handled(true);
|
|
|
|
}
|
|
|
|
|
2021-03-30 18:08:03 +02:00
|
|
|
// Method Description:
|
|
|
|
// - Raise a IdentifyWindowsRequested event. This will bubble up to the
|
|
|
|
// AppLogic, to the AppHost, to the Peasant, to the Monarch, then get
|
|
|
|
// distributed down to _all_ the Peasants, as to display info about the
|
|
|
|
// window in _every_ Peasant window.
|
|
|
|
// - This action is also buggy right now, because TeachingTips behave
|
|
|
|
// weird in XAML Islands. See microsoft-ui-xaml#4382
|
|
|
|
// Arguments:
|
|
|
|
// - <unused>
|
|
|
|
// Return Value:
|
|
|
|
// - <none>
|
|
|
|
void TerminalPage::_HandleIdentifyWindows(const IInspectable& /*sender*/,
|
|
|
|
const ActionEventArgs& args)
|
|
|
|
{
|
|
|
|
_IdentifyWindowsRequestedHandlers(*this, nullptr);
|
|
|
|
args.Handled(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Method Description:
|
|
|
|
// - Display the "Toast" with the name and ID of this window.
|
|
|
|
// - Unlike _HandleIdentifyWindow**s**, this event just displays the window
|
|
|
|
// ID and name in the current window. It does not involve any bubbling
|
|
|
|
// up/down the page/logic/host/manager/peasant/monarch.
|
|
|
|
// Arguments:
|
|
|
|
// - <unused>
|
|
|
|
// Return Value:
|
|
|
|
// - <none>
|
|
|
|
void TerminalPage::_HandleIdentifyWindow(const IInspectable& /*sender*/,
|
|
|
|
const ActionEventArgs& args)
|
|
|
|
{
|
|
|
|
IdentifyWindow();
|
|
|
|
args.Handled(true);
|
|
|
|
}
|
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 TerminalPage::_HandleRenameWindow(const IInspectable& /*sender*/,
|
|
|
|
const ActionEventArgs& args)
|
|
|
|
{
|
|
|
|
if (args)
|
|
|
|
{
|
|
|
|
if (const auto& realArgs = args.ActionArgs().try_as<RenameWindowArgs>())
|
|
|
|
{
|
|
|
|
const auto newName = realArgs.Name();
|
|
|
|
const auto request = winrt::make_self<implementation::RenameWindowRequestedArgs>(newName);
|
|
|
|
_RenameWindowRequestedHandlers(*this, *request);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
args.Handled(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TerminalPage::_HandleOpenWindowRenamer(const IInspectable& /*sender*/,
|
|
|
|
const ActionEventArgs& args)
|
|
|
|
{
|
|
|
|
if (WindowRenamer() == nullptr)
|
|
|
|
{
|
|
|
|
// We need to use FindName to lazy-load this object
|
|
|
|
if (MUX::Controls::TeachingTip tip{ FindName(L"WindowRenamer").try_as<MUX::Controls::TeachingTip>() })
|
|
|
|
{
|
|
|
|
tip.Closed({ get_weak(), &TerminalPage::_FocusActiveControl });
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
WindowRenamer().IsOpen(true);
|
|
|
|
|
|
|
|
// 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 event to 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 receive _any_ keypresses.
|
|
|
|
// Fun!
|
|
|
|
// WindowRenamerTextBox().Focus(FocusState::Programmatic);
|
|
|
|
|
|
|
|
args.Handled(true);
|
|
|
|
}
|
2019-08-17 00:43:51 +02:00
|
|
|
}
|