terminal/src/cascadia/TerminalApp/TerminalTab.h

180 lines
7.1 KiB
C
Raw Normal View History

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#pragma once
#include "Pane.h"
#include "ColorPickupFlyout.h"
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
#include "TabBase.h"
#include "TerminalTab.g.h"
static constexpr double HeaderRenameBoxWidthDefault{ 165 };
static constexpr double HeaderRenameBoxWidthTitleLength{ std::numeric_limits<double>::infinity() };
Process actions sync. on startup; don't dupe nonexistent profile (#5090) This PR has evolved to encapsulate two related fixes that I can't really untie anymore. #2455 - Duplicating a tab that doesn't exist anymore This was the bug I was originally fixing in #4429. When the user tries to `duplicateTab` with a profile that doesn't exist anymore (like might happen after a settings reload), don't crash. As I was going about adding tests for this, got blocked by the fact that the Terminal couldn't open _any_ panes while the `TerminalPage` was size 0x0. This had two theoretical solutions: * Fake the `TerminalPage` into thinking it had a real size in the test - probably possible, though I'm unsure how it would work in practice. * Change `Pane`s to not require an `ActualWidth`, `ActualHeight` on initialization. Fortuately, the second option was something else that was already on my backlog of bugs. #4618 - `wt` command-line can't consistently parse more than one arg Presently, the Terminal just arbitrarily dispatches a bunch of handlers to try and handle all the commands provided on the commandline. That's lead to a bunch of reports that not all the commands will always get executed, nor will they all get executed in the same order. This PR also changes the `TerminalPage` to be able to dispatch all the commands sequentially, all at once in the startup. No longer will there be a hot second where the commands seem to execute themselves in from of the user - they'll all happen behind the scenes on startup. This involved a couple other changes areound the `TerminalPage` * I had to make sure that panes could be opened at a 0x0 size. Now they use a star sizing based off the percentage of the parent they're supposed to consume, so that when the parent _does_ get laid out, they'll take the appropriate size of that parent. * I had to do some math ahead of time to try and calculate what a `SplitState::Automatic` would be evaluated as, despite the fact that we don't actually know how big the pane will be. * I had to ensure that `focus-tab` commands appropriately mark a single tab as focused while we're in startup, without roundtripping to the Dispatcher thread and back ## References #4429 - the original PR for #2455 #5047 - a follow-up task from discussion in #4429 #4953 - a PR for making panes use star sizing, which was immensly helpful for this PR. ## Detailed Description of the Pull Request / Additional comments `CascadiaSettings::BuildSettings` can throw if the GUID doesn't exist. This wraps those calls up with a try/catch. It also adds a couple tests - a few `SettingsTests` for try/catching this state. It also adds a XAML-y test in `TabTests` that creates a `TerminalPage` and then performs som UI-like actions on it. This test required a minor change to how we generate the new tab dropdown - in the tests, `Application::Current()` is _not_ a `TerminalApp::App`, so it doesn't have a `Logic()` to query. So wrap that in a try/catch as well. While working on these tests, I found that we'd crash pretty agressively for mysterious reasons if the TestHostApp became focused while the test was running. This was due to a call in `TSFInputControl::NotifyFocusEnter` that would callback to `TSFInputControl::_layoutRequested`, which would crash on setting the `MaxSize` of the canvas to a negative value. This PR includes a hotfix for that bug as well. ## Validation Steps Performed * Manual testing with a _lot_ of commands in a commandline * run the tests * Team tested in selfhost Closes #2455 Closes #4618
2020-03-26 01:03:32 +01:00
// fwdecl unittest classes
namespace TerminalAppLocalTests
{
class TabTests;
};
namespace winrt::TerminalApp::implementation
{
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
struct TerminalTab : TerminalTabT<TerminalTab, TabBase>
{
public:
TerminalTab(const winrt::Microsoft::Terminal::Settings::Model::Profile& profile, const winrt::Microsoft::Terminal::Control::TermControl& control);
Move Pane to Tab (GH7075) (#10780) <!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Summary of the Pull Request Add functionality to move a pane to another tab. If the tab index is greater than the number of current tabs a new tab will be created with the pane as its root. Similarly, if the last pane on a tab is moved to another tab, the original tab will be closed. This is largely complete, but I know that I'm messing around with things that I am unfamiliar with, and would like to avoid footguns where possible. <!-- Other than the issue solved, is this relevant to any other issues/existing PRs? --> ## References #4587 <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist * [x] Closes #7075 * [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA * [ ] Tests added/passed * [x] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx * [x] Schema 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 --> ## Detailed Description of the Pull Request / Additional comments Things done: - Moving a pane to a new tab appears to work. Moving a pane to an existing tab mostly works. Moving a pane back to its original tab appears to work. - Set up {Attach,Detach}Pane methods to add or remove a pane from a pane. Detach is slightly different than Close in that we want to persist the tree structure and terminal controls. - Add `Detached` event on a pane that can be subscribed to to remove other event handlers if desired. - Added simple WalkTree abstraction for one-off recursion use cases that calls a provided function on each pane in order (and optionally terminates early). - Fixed an in-prod bug with closing panes. Specifically, if you have a tree (1; 2 3) and close the 1 pane, then 3 will lose its borders because of these lines clearing the border on both children https://github.com/microsoft/terminal/blob/main/src/cascadia/TerminalApp/Pane.cpp#L1197-L1201 . To do: - Right now I have `TerminalTab` as a friend class of `Pane` so I can access some extra properties in my `WalkTree` callbacks, but there is probably a better choice for the abstraction boundary. Next Steps: - In a future PR Drag & Drop handlers could be added that utilize the Attach/Detach infrastructure to provide a better UI. - Similarly once this is working, it should be possible to convert an entire tab into a pane on an existing tab (Tab::DetachRoot on original tab followed by Tab::AttachPane on the target tab). - Its been 10 years, I just really want to use concepts already. <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed Manual testing by creating pane(s), and moving them between tabs and creating new tabs and destroying tabs by moving the last remaining pane.
2021-08-12 18:41:17 +02:00
TerminalTab(std::shared_ptr<Pane> rootPane);
// Called after construction to perform the necessary setup, which relies on weak_ptr
Move Pane to Tab (GH7075) (#10780) <!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Summary of the Pull Request Add functionality to move a pane to another tab. If the tab index is greater than the number of current tabs a new tab will be created with the pane as its root. Similarly, if the last pane on a tab is moved to another tab, the original tab will be closed. This is largely complete, but I know that I'm messing around with things that I am unfamiliar with, and would like to avoid footguns where possible. <!-- Other than the issue solved, is this relevant to any other issues/existing PRs? --> ## References #4587 <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist * [x] Closes #7075 * [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA * [ ] Tests added/passed * [x] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx * [x] Schema 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 --> ## Detailed Description of the Pull Request / Additional comments Things done: - Moving a pane to a new tab appears to work. Moving a pane to an existing tab mostly works. Moving a pane back to its original tab appears to work. - Set up {Attach,Detach}Pane methods to add or remove a pane from a pane. Detach is slightly different than Close in that we want to persist the tree structure and terminal controls. - Add `Detached` event on a pane that can be subscribed to to remove other event handlers if desired. - Added simple WalkTree abstraction for one-off recursion use cases that calls a provided function on each pane in order (and optionally terminates early). - Fixed an in-prod bug with closing panes. Specifically, if you have a tree (1; 2 3) and close the 1 pane, then 3 will lose its borders because of these lines clearing the border on both children https://github.com/microsoft/terminal/blob/main/src/cascadia/TerminalApp/Pane.cpp#L1197-L1201 . To do: - Right now I have `TerminalTab` as a friend class of `Pane` so I can access some extra properties in my `WalkTree` callbacks, but there is probably a better choice for the abstraction boundary. Next Steps: - In a future PR Drag & Drop handlers could be added that utilize the Attach/Detach infrastructure to provide a better UI. - Similarly once this is working, it should be possible to convert an entire tab into a pane on an existing tab (Tab::DetachRoot on original tab followed by Tab::AttachPane on the target tab). - Its been 10 years, I just really want to use concepts already. <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed Manual testing by creating pane(s), and moving them between tabs and creating new tabs and destroying tabs by moving the last remaining pane.
2021-08-12 18:41:17 +02:00
void Initialize();
Fixed self reference capture in Tab and TerminalPage (#3835) <!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Summary of the Pull Request Every lambda capture in `Tab` and `TerminalPage` has been changed from capturing raw `this` to `std::weak_ptr<Tab>` or `winrt::weak_ref<TerminalPage>`. Lambda bodies have been changed to check the weak reference before use. Capturing raw `this` in `Tab`'s [title change event handler](https://github.com/microsoft/terminal/blob/master/src/cascadia/TerminalApp/Tab.cpp#L299) was the root cause of #3776, and is fixed in this PR among other instance of raw `this` capture. The lambda fixes to `TerminalPage` are unrelated to the core issue addressed in the PR checklist. Because I was already editing `TerminalPage`, figured I'd do a [weak_ref pass](https://github.com/microsoft/terminal/issues/3776#issuecomment-560575575). <!-- Other than the issue solved, is this relevant to any other issues/existing PRs? --> ## References <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist * [x] Closes #3776, potentially #2248, likely closes others * [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA * [ ] Tests added/passed * [ ] Requires documentation to be updated * [x] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #3776 <!-- Provide a more detailed description of the PR, other things fixed or any additional comments/features here --> ## Detailed Description of the Pull Request / Additional comments `Tab` now inherits from `enable_shared_from_this`, which enable accessing `Tab` objects as `std::weak_ptr<Tab>` objects. All instances of lambdas capturing `this` now capture `std::weak_ptr<Tab>` instead. `TerminalPage` is a WinRT type which supports `winrt::weak_ref<TerminalPage>`. All previous instance of `TerminalPage` lambdas capturing `this` has been replaced to capture `winrt::weak_ref<TerminalPage>`. These weak pointers/references can only be created after object construction necessitating for `Tab` a new function called after construction to bind lambdas. Any anomalous crash related to the following functionality during closing a tab or WT may be fixed by this PR: - Tab icon updating - Tab text updating - Tab dragging - Clicking new tab button - Changing active pane - Closing an active tab - Clicking on a tab - Creating the new tab flyout menu Sorry about all the commits. Will fix my fork after this PR! 😅 <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed Attempted to repro the steps indicated in issue #3776 with the new changes and failed. When before the changes, the issue could consistently be reproed.
2019-12-06 00:18:22 +01:00
Rename `Microsoft.Terminal.TerminalControl` to `.Control`; Split into dll & lib (#9472) **BE NOT AFRAID**. I know that there's 107 files in this PR, but almost all of it is just find/replacing `TerminalControl` with `Control`. This is the start of the work to move TermControl into multiple pieces, for #5000. The PR starts this work by: * Splits `TerminalControl` into separate lib and dll projects. We'll want control tests in the future, and for that, we'll need a lib. * Moves `ICoreSettings` back into the `Microsoft.Terminal.Core` namespace. We'll have other types in there soon too. * I could not tell you why this works suddenly. New VS versions? New cppwinrt version? Maybe we're just better at dealing with mdmerge bugs these days. * RENAMES `Microsoft.Terminal.TerminalControl` to `Microsoft.Terminal.Control`. This touches pretty much every file in the sln. Sorry about that (not sorry). An upcoming PR will move much of the logic in TermControl into a new `ControlCore` class that we'll add in `Microsoft.Terminal.Core`. `ControlCore` will then be unittest-able in the `UnitTests_TerminalCore`, which will help prevent regressions like #9455 ## Detailed Description of the Pull Request / Additional comments You're really gonna want to clean the sln first, then merge this into your branch, then rebuild. It's very likely that old winmds will get left behind. If you see something like ``` Error MDM2007 Cannot create type Microsoft.Terminal.TerminalControl.KeyModifiers in read-only metadata file Microsoft.Terminal.TerminalControl. ``` then that's what happened to you.
2021-03-17 21:47:24 +01:00
winrt::Microsoft::Terminal::Control::TermControl GetActiveTerminalControl() const;
winrt::Microsoft::Terminal::Settings::Model::Profile GetFocusedProfile() const noexcept;
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
void Focus(winrt::Windows::UI::Xaml::FocusState focusState) override;
winrt::fire_and_forget Scroll(const int delta);
Move Pane to Tab (GH7075) (#10780) <!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Summary of the Pull Request Add functionality to move a pane to another tab. If the tab index is greater than the number of current tabs a new tab will be created with the pane as its root. Similarly, if the last pane on a tab is moved to another tab, the original tab will be closed. This is largely complete, but I know that I'm messing around with things that I am unfamiliar with, and would like to avoid footguns where possible. <!-- Other than the issue solved, is this relevant to any other issues/existing PRs? --> ## References #4587 <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist * [x] Closes #7075 * [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA * [ ] Tests added/passed * [x] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx * [x] Schema 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 --> ## Detailed Description of the Pull Request / Additional comments Things done: - Moving a pane to a new tab appears to work. Moving a pane to an existing tab mostly works. Moving a pane back to its original tab appears to work. - Set up {Attach,Detach}Pane methods to add or remove a pane from a pane. Detach is slightly different than Close in that we want to persist the tree structure and terminal controls. - Add `Detached` event on a pane that can be subscribed to to remove other event handlers if desired. - Added simple WalkTree abstraction for one-off recursion use cases that calls a provided function on each pane in order (and optionally terminates early). - Fixed an in-prod bug with closing panes. Specifically, if you have a tree (1; 2 3) and close the 1 pane, then 3 will lose its borders because of these lines clearing the border on both children https://github.com/microsoft/terminal/blob/main/src/cascadia/TerminalApp/Pane.cpp#L1197-L1201 . To do: - Right now I have `TerminalTab` as a friend class of `Pane` so I can access some extra properties in my `WalkTree` callbacks, but there is probably a better choice for the abstraction boundary. Next Steps: - In a future PR Drag & Drop handlers could be added that utilize the Attach/Detach infrastructure to provide a better UI. - Similarly once this is working, it should be possible to convert an entire tab into a pane on an existing tab (Tab::DetachRoot on original tab followed by Tab::AttachPane on the target tab). - Its been 10 years, I just really want to use concepts already. <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed Manual testing by creating pane(s), and moving them between tabs and creating new tabs and destroying tabs by moving the last remaining pane.
2021-08-12 18:41:17 +02:00
std::shared_ptr<Pane> DetachRoot();
std::shared_ptr<Pane> DetachPane();
void AttachPane(std::shared_ptr<Pane> pane);
void SplitPane(winrt::Microsoft::Terminal::Settings::Model::SplitState splitType,
const float splitSize,
const winrt::Microsoft::Terminal::Settings::Model::Profile& profile,
Rename `Microsoft.Terminal.TerminalControl` to `.Control`; Split into dll & lib (#9472) **BE NOT AFRAID**. I know that there's 107 files in this PR, but almost all of it is just find/replacing `TerminalControl` with `Control`. This is the start of the work to move TermControl into multiple pieces, for #5000. The PR starts this work by: * Splits `TerminalControl` into separate lib and dll projects. We'll want control tests in the future, and for that, we'll need a lib. * Moves `ICoreSettings` back into the `Microsoft.Terminal.Core` namespace. We'll have other types in there soon too. * I could not tell you why this works suddenly. New VS versions? New cppwinrt version? Maybe we're just better at dealing with mdmerge bugs these days. * RENAMES `Microsoft.Terminal.TerminalControl` to `Microsoft.Terminal.Control`. This touches pretty much every file in the sln. Sorry about that (not sorry). An upcoming PR will move much of the logic in TermControl into a new `ControlCore` class that we'll add in `Microsoft.Terminal.Core`. `ControlCore` will then be unittest-able in the `UnitTests_TerminalCore`, which will help prevent regressions like #9455 ## Detailed Description of the Pull Request / Additional comments You're really gonna want to clean the sln first, then merge this into your branch, then rebuild. It's very likely that old winmds will get left behind. If you see something like ``` Error MDM2007 Cannot create type Microsoft.Terminal.TerminalControl.KeyModifiers in read-only metadata file Microsoft.Terminal.TerminalControl. ``` then that's what happened to you.
2021-03-17 21:47:24 +01:00
winrt::Microsoft::Terminal::Control::TermControl& control);
Add the ability to toggle a pane's split direction (#10713) <!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Summary of the Pull Request Add the ability to toggle a pane's split direction - Switch from horizontal to vertical split (and vice versa) - Propogate new borders through to children. <!-- Other than the issue solved, is this relevant to any other issues/existing PRs? --> ## References #10665 <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist * [x] Closes #10665 * [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA * [ ] Tests added/passed * [ ] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx * [x] Schema 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 --> ## Detailed Description of the Pull Request / Additional comments <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed Ran terminal, created multiple panes in different orientations, ran command through command palate and verified that they displayed properly in the new orientation.
2021-08-02 23:04:57 +02:00
void ToggleSplitOrientation();
winrt::fire_and_forget UpdateIcon(const winrt::hstring iconPath);
winrt::fire_and_forget HideIcon(const bool hide);
Snap to character grid when resizing window (#3181) When user resizes window, snap the size to align with the character grid (like e.g. putty, mintty and most unix terminals). Properly resolves arbitrary pane configuration (even with different font sizes and padding) trying to align each pane as close as possible. It also fixes terminal minimum size enforcement which was not quite well handled, especially with multiple panes. This PR does not however try to keep the terminals aligned at other user actions (e.g. font change or pane split). That is to be tracked by some other activity. Snapping is resolved in the pane tree, recursively, so it (hopefully) works for any possible layout. Along the way I had to clean up some things as so to make the resulting code not so cumbersome: 1. Pane.cpp: Replaced _firstPercent and _secondPercent with single _desiredSplitPosition to reduce invariants - these had to be kept in sync so their sum always gives 1 (and were not really a percent). The desired part refers to fact that since panes are aligned, there is usually some deviation from that ratio. 2. Pane.cpp: Fixed _GetMinSize() - it was improperly accounting for split direction 3. TerminalControl: Made dedicated member for padding instead of reading it from a control itself. This is because the winrt property functions turned out to be slow and this algorithm needs to access it many times. I also cached scrollbar width for the same reason. 4. AppHost: Moved window to client size resolution to virtual method, where IslandWindow and NonClientIslandWindow have their own implementations (as opposite to pointer casting). One problem with current implementation is I had to make a long call chain from the window that requests snapping to the (root) pane that implements it: IslandWindow -> AppHost's callback -> App -> TerminalPage -> Tab -> Pane. I don't know if this can be done better. ## Validation Steps Performed Spam split pane buttons, randomly change font sizes with ctrl+mouse wheel and drag the window back and forth. Closes #2834 Closes #2277
2020-01-08 22:19:23 +01:00
winrt::fire_and_forget ShowBellIndicator(const bool show);
winrt::fire_and_forget ActivateBellIndicatorTimer();
float CalcSnappedDimension(const bool widthOrHeight, const float dimension) const;
Introduce TerminalSettingsModel project (#7667) Introduces a new TerminalSettingsModel (TSM) project. This project is responsible for (de)serializing and exposing Windows Terminal's settings as WinRT objects. ## References #885: TSM epic #1564: Settings UI is dependent on this for data binding and settings access #6904: TSM Spec In the process of ripping out TSM from TerminalApp, a few other changes were made to make this possible: 1. AppLogic's `ApplicationDisplayName` and `ApplicationVersion` was moved to `CascadiaSettings` - These are defined as static functions. They also no longer check if `AppLogic::Current()` is nullptr. 2. `enum LaunchMode` was moved from TerminalApp to TSM 3. `AzureConnectionType` and `TelnetConnectionType` were moved from the profile generators to their respective TerminalConnections 4. CascadiaSettings' `SettingsPath` and `DefaultSettingsPath` are exposed as `hstring` instead of `std::filesystem::path` 5. `Command::ExpandCommands()` was exposed via the IDL - This required some of the warnings to be saved to an `IVector` instead of `std::vector`, among some other small changes. 6. The localization resources had to be split into two halves. - Resource file linked in init.cpp. Verified at runtime thanks to the StaticResourceLoader. 7. Added constructors to some `ActionArgs` 8. Utils.h/cpp were moved to `cascadia/inc`. `JsonKey()` was moved to `JsonUtils`. Both TermApp and TSM need access to Utils.h/cpp. A large amount of work includes moving to the new namespace (`TerminalApp` --> `Microsoft::Terminal::Settings::Model`). Fixing the tests had its own complications. Testing required us to split up TSM into a DLL and LIB, similar to TermApp. Discussion on creating a non-local test variant can be found in #7743. Closes #885
2020-10-06 18:56:59 +02:00
winrt::Microsoft::Terminal::Settings::Model::SplitState PreCalculateAutoSplit(winrt::Windows::Foundation::Size rootSize) const;
bool PreCalculateCanSplit(winrt::Microsoft::Terminal::Settings::Model::SplitState splitType,
const float splitSize,
winrt::Windows::Foundation::Size availableSpace) const;
void ResizeContent(const winrt::Windows::Foundation::Size& newSize);
void ResizePane(const winrt::Microsoft::Terminal::Settings::Model::ResizeDirection& direction);
Passing through moveFocus keys when moving to another pane failed (#10806) <!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Summary of the Pull Request Implementation of #6219 with a small tweak, not just passing the keys when no panes are present, but passing on the keys when there is no other pane to move to. This enables another usecase: 2 panes in terminal split vertically; in one of these panes running tmux with two panes that are split horizontally. This allows the user to still navigate between tmux panes even though they have terminal panes open. <!-- Other than the issue solved, is this relevant to any other issues/existing PRs? --> ## References Not that I know of <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist * [x] Closes #6219 * [x] CLA signed. * [x] Tests added/passed * [x] Documentation updated. I don't think that's necessary * [x] Schema updated. N/A * [ ] 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. <!-- Provide a more detailed description of the PR, other things fixed or any additional comments/features here --> ## Detailed Description of the Pull Request / Additional comments Implementation by propagating the boolean indicating success of moving focus all the way to the action handler, where this result will determine whether the action will be considered handled or not. When the action is not handled, the keychord will be propagated to the terminal. <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed Manual testing; all relevant unit tests still work
2021-07-29 00:05:32 +02:00
bool NavigateFocus(const winrt::Microsoft::Terminal::Settings::Model::FocusDirection& direction);
bool SwapPane(const winrt::Microsoft::Terminal::Settings::Model::FocusDirection& direction);
bool FocusPane(const uint32_t id);
void UpdateSettings();
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
winrt::fire_and_forget UpdateTitle();
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
void Shutdown() override;
void ClosePane();
void SetTabText(winrt::hstring title);
winrt::hstring GetTabText() const;
void ResetTabText();
void ActivateTabRenamer();
std::optional<winrt::Windows::UI::Color> GetTabColor();
void SetRuntimeTabColor(const winrt::Windows::UI::Color& color);
void ResetRuntimeTabColor();
void ActivateColorPicker();
void ToggleZoom();
bool IsZoomed();
void EnterZoom();
void ExitZoom();
int GetLeafPaneCount() const noexcept;
void TogglePaneReadOnly();
std::shared_ptr<Pane> GetActivePane() const;
Combine progress states in the tab, taskbar (#10755) ## Summary of the Pull Request ![background-progress-000](https://user-images.githubusercontent.com/18356694/126653006-3ad2fdae-67ae-4cdb-aa46-25d09217e365.gif) This PR causes the Terminal to combine taskbar states at the tab and window level, according to the [MSDN docs for `SetProgressState`](https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-itaskbarlist3-setprogressstate#how-the-taskbar-button-chooses-the-progress-indicator-for-a-group). This allows the Terminal's taskbar icon to continue showing progress information, even if you're in a pane/tab that _doesn't_ have progress state. This is helpful for cases where the user may be running a build in one tab, and working on something else in another. ## References * [`SetProgressState`](https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-itaskbarlist3-setprogressstate#how-the-taskbar-button-chooses-the-progress-indicator-for-a-group) * Progress mega: #6700 ## PR Checklist * [x] Closes #10090 * [x] I work here * [ ] Tests added/passed * [n/a] Requires documentation to be updated ## Detailed Description of the Pull Request / Additional comments This also fixes a related bug where transitioning from the "error" or "warning" state directly to the "indeterminate" state would cause the taskbar icon to get stuck in a bad state. ## Validation Steps Performed <details> <summary><code>progress.cmd</code></summary> ```cmd @echo off setlocal enabledelayedexpansion set _type=3 if (%1) == () ( set _type=3 ) else ( set _type=%1 ) if (%_type%) == (0) ( <NUL set /p =]9;4 echo Cleared progress ) if (%_type%) == (1) ( <NUL set /p =]9;4;1;25 echo Started progress (normal, 25^) ) if (%_type%) == (2) ( <NUL set /p =]9;4;2;50 echo Started progress (error, 50^) ) if (%_type%) == (3) ( @rem start indeterminate progress in the taskbar @rem this `<NUL set /p =` magic will output the text _without a newline_ <NUL set /p =]9;4;3 echo Started progress (indeterminate, {omitted}) ) if (%_type%) == (4) ( <NUL set /p =]9;4;4;75 echo Started progress (warning, 75^) ) ``` </details>
2021-08-10 13:16:17 +02:00
winrt::TerminalApp::TaskbarState GetCombinedTaskbarState() const;
std::shared_ptr<Pane> GetRootPane() const { return _rootPane; }
winrt::TerminalApp::TerminalTabStatus TabStatus()
{
return _tabStatus;
}
DECLARE_EVENT(ActivePaneChanged, _ActivePaneChangedHandlers, winrt::delegate<>);
DECLARE_EVENT(ColorSelected, _colorSelected, winrt::delegate<winrt::Windows::UI::Color>);
DECLARE_EVENT(ColorCleared, _colorCleared, winrt::delegate<>);
DECLARE_EVENT(TabRaiseVisualBell, _TabRaiseVisualBellHandlers, winrt::delegate<>);
DECLARE_EVENT(DuplicateRequested, _DuplicateRequestedHandlers, winrt::delegate<>);
Add Split Tab option to tab context menu (#10832) <!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Summary of the Pull Request Adds the Split Tab option to the tab context menu. Clicking this option will `auto` split the active pane of the tab into a duplicate pane. Clicking on an unfocused tab and splitting it will bring that tab into focus and split its active pane. We could make this a flyout from the context menu to let people choose horizontal/vertical split in the future if it's requested. I'm also wondering if this should be called Split Pane instead of Split Tab? <!-- Other than the issue solved, is this relevant to any other issues/existing PRs? --> ## References #1912 <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist * [x] Closes #5025 * [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA * [ ] Tests added/passed * [ ] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx * [ ] Schema 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 --> ## Detailed Description of the Pull Request / Additional comments https://user-images.githubusercontent.com/48369326/127691919-aae4683a-212a-4525-a0eb-a61c877461ed.mp4 <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed
2021-08-05 15:46:24 +02:00
DECLARE_EVENT(SplitTabRequested, _SplitTabRequestedHandlers, winrt::delegate<>);
Split `TermControl` into a Core, Interactivity, and Control layer (#9820) ## Summary of the Pull Request Brace yourselves, it's finally here. This PR does the dirty work of splitting the monolithic `TermControl` into three components. These components are: * `ControlCore`: This encapsulates the `Terminal` instance, the `DxEngine` and `Renderer`, and the `Connection`. This is intended to everything that someone might need to stand up a terminal instance in a control, but without any regard for how the UX works. * `ControlInteractivity`: This is a wrapper for the `ControlCore`, which holds the logic for things like double-click, right click copy/paste, selection, etc. This is intended to be a UI framework-independent abstraction. The methods this layer exposes can be called the same from both the WinUI TermControl and the WPF control. * `TermControl`: This is the UWP control. It's got a Core and Interactivity inside it, which it uses for the actual logic of the terminal itself. TermControl's main responsibility is now By splitting into smaller pieces, it will enable us to * write unit tests for the `Core` and `Interactivity` bits, which we desparately need * Combine `ControlCore` and `ControlInteractivity` in an out-of-proc core process in the future, to enable tab tearout. However, we're not doing that work quite yet. There's still lots of work to be done to enable that, thought this is likely the biggest portion. Ideally, this would just be methods moved wholesale from one file to another. Unfortunately, there are a bunch of cases where that didn't work as well as expected. Especially when trying to better enforce the boundary between the classes. We've got a couple tests here that I've added. These are partially examples, and partially things I ran into while implementing this. A bunch of things from #7001 can go in now that we have this. This PR is gonna be a huge pain to review - 38 files with 3,730 additions and 1,661 deletions is nothing to scoff at. It will also conflict 100% with anything that's targeting `TermControl`. I'm hoping we can review this over the course of the next week and just be done with it, and leave plenty of runway for 1.9 bugs in post. ## References * In pursuit of #1256 * Proc Model: #5000 * https://github.com/microsoft/terminal/projects/5 ## PR Checklist * [x] Closes #6842 * [x] Closes https://github.com/microsoft/terminal/projects/5#card-50760249 * [x] Closes https://github.com/microsoft/terminal/projects/5#card-50760258 * [x] I work here * [x] Tests added/passed * [n/a] Requires documentation to be updated ## Detailed Description of the Pull Request / Additional comments * I don't love the names `ControlCore` and `ControlInteractivity`. Open to other names. * I added a `ICoreState` interface for "properties that come from the `ControlCore`, but consumers of the `TermControl` need to know". In the future, these will all need to be handled specially, because they might involve an RPC call to retrieve the info from the core (or cache it) in the window process. * I've added more `EventArgs` to make more events proper `TypedEvent`s. * I've changed how the TerminalApp layer requests updated TaskbarProgress state. It doesn't need to pump TermControl to raise a new event anymore. * ~~Something that snuck into this branch in the very long history is the switch to `DCompositionCreateSurfaceHandle` for the `DxEngine`. @miniksa wrote this originally in 30b8335, I'm just finally committing it here. We'll need that in the future for the out-of-proc stuff.~~ * I reverted this in c113b65d9. We can revert _that_ commit when we want to come back to it. * I've changed the acrylic handler a decent amount. But added tests! * All the `ThrottledFunc` things are left in `TermControl`. Some might be able to move down into core/interactivity, but once we figure out how to use a different kind of Dispatcher (because a UI thread won't necessarily exist for those components). * I've undoubtably messed up the merging of the locking around the appearance config stuff recently ## Validation Steps Performed I've got a rolling list in https://github.com/microsoft/terminal/issues/6842#issuecomment-810990460 that I'm updating as I go.
2021-04-27 17:50:45 +02:00
TYPED_EVENT(TaskbarProgressChanged, IInspectable, IInspectable);
private:
std::shared_ptr<Pane> _rootPane{ nullptr };
std::shared_ptr<Pane> _activePane{ nullptr };
std::shared_ptr<Pane> _zoomedPane{ nullptr };
Move Pane to Tab (GH7075) (#10780) <!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Summary of the Pull Request Add functionality to move a pane to another tab. If the tab index is greater than the number of current tabs a new tab will be created with the pane as its root. Similarly, if the last pane on a tab is moved to another tab, the original tab will be closed. This is largely complete, but I know that I'm messing around with things that I am unfamiliar with, and would like to avoid footguns where possible. <!-- Other than the issue solved, is this relevant to any other issues/existing PRs? --> ## References #4587 <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist * [x] Closes #7075 * [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA * [ ] Tests added/passed * [x] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx * [x] Schema 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 --> ## Detailed Description of the Pull Request / Additional comments Things done: - Moving a pane to a new tab appears to work. Moving a pane to an existing tab mostly works. Moving a pane back to its original tab appears to work. - Set up {Attach,Detach}Pane methods to add or remove a pane from a pane. Detach is slightly different than Close in that we want to persist the tree structure and terminal controls. - Add `Detached` event on a pane that can be subscribed to to remove other event handlers if desired. - Added simple WalkTree abstraction for one-off recursion use cases that calls a provided function on each pane in order (and optionally terminates early). - Fixed an in-prod bug with closing panes. Specifically, if you have a tree (1; 2 3) and close the 1 pane, then 3 will lose its borders because of these lines clearing the border on both children https://github.com/microsoft/terminal/blob/main/src/cascadia/TerminalApp/Pane.cpp#L1197-L1201 . To do: - Right now I have `TerminalTab` as a friend class of `Pane` so I can access some extra properties in my `WalkTree` callbacks, but there is probably a better choice for the abstraction boundary. Next Steps: - In a future PR Drag & Drop handlers could be added that utilize the Attach/Detach infrastructure to provide a better UI. - Similarly once this is working, it should be possible to convert an entire tab into a pane on an existing tab (Tab::DetachRoot on original tab followed by Tab::AttachPane on the target tab). - Its been 10 years, I just really want to use concepts already. <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed Manual testing by creating pane(s), and moving them between tabs and creating new tabs and destroying tabs by moving the last remaining pane.
2021-08-12 18:41:17 +02:00
winrt::hstring _lastIconPath{};
winrt::TerminalApp::ColorPickupFlyout _tabColorPickup{};
std::optional<winrt::Windows::UI::Color> _themeTabColor{};
std::optional<winrt::Windows::UI::Color> _runtimeTabColor{};
winrt::TerminalApp::TabHeaderControl _headerControl{};
winrt::TerminalApp::TerminalTabStatus _tabStatus{};
Move Pane to Tab (GH7075) (#10780) <!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Summary of the Pull Request Add functionality to move a pane to another tab. If the tab index is greater than the number of current tabs a new tab will be created with the pane as its root. Similarly, if the last pane on a tab is moved to another tab, the original tab will be closed. This is largely complete, but I know that I'm messing around with things that I am unfamiliar with, and would like to avoid footguns where possible. <!-- Other than the issue solved, is this relevant to any other issues/existing PRs? --> ## References #4587 <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist * [x] Closes #7075 * [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA * [ ] Tests added/passed * [x] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx * [x] Schema 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 --> ## Detailed Description of the Pull Request / Additional comments Things done: - Moving a pane to a new tab appears to work. Moving a pane to an existing tab mostly works. Moving a pane back to its original tab appears to work. - Set up {Attach,Detach}Pane methods to add or remove a pane from a pane. Detach is slightly different than Close in that we want to persist the tree structure and terminal controls. - Add `Detached` event on a pane that can be subscribed to to remove other event handlers if desired. - Added simple WalkTree abstraction for one-off recursion use cases that calls a provided function on each pane in order (and optionally terminates early). - Fixed an in-prod bug with closing panes. Specifically, if you have a tree (1; 2 3) and close the 1 pane, then 3 will lose its borders because of these lines clearing the border on both children https://github.com/microsoft/terminal/blob/main/src/cascadia/TerminalApp/Pane.cpp#L1197-L1201 . To do: - Right now I have `TerminalTab` as a friend class of `Pane` so I can access some extra properties in my `WalkTree` callbacks, but there is probably a better choice for the abstraction boundary. Next Steps: - In a future PR Drag & Drop handlers could be added that utilize the Attach/Detach infrastructure to provide a better UI. - Similarly once this is working, it should be possible to convert an entire tab into a pane on an existing tab (Tab::DetachRoot on original tab followed by Tab::AttachPane on the target tab). - Its been 10 years, I just really want to use concepts already. <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed Manual testing by creating pane(s), and moving them between tabs and creating new tabs and destroying tabs by moving the last remaining pane.
2021-08-12 18:41:17 +02:00
struct ControlEventTokens
{
winrt::event_token titleToken;
winrt::event_token fontToken;
winrt::event_token colorToken;
winrt::event_token taskbarToken;
winrt::event_token readOnlyToken;
winrt::event_token focusToken;
};
std::unordered_map<uint32_t, ControlEventTokens> _controlEvents;
winrt::event_token _rootClosedToken{};
std::vector<uint32_t> _mruPanes;
uint32_t _nextPaneId{ 0 };
bool _receivedKeyDown{ false };
bool _iconHidden{ false };
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
Enable tab renaming at runtime from the UI (#5775) ## Summary of the Pull Request Adds support for setting, from the UI, a runtime override for the tab title text. The user can use this to effectively "rename" a tab. If set, the tab will _always_ use the runtime override string. If the user has multiple panes with different titles in a pane, then the tab's override text will be used _regardless_ of which pane was focused when the tab was renamed. The override text can be removed by just deleting the entire contents of the box. Then, the tab will revert to using the terminal's usual title. ## References * Wouldn't be possible without the context menu from #3789 * Focus doesn't return to the active terminal after hitting <kbd>enter</kbd>/<kbd>esc</kbd>, but that's tracked by #5750 ## PR Checklist * [x] Closes #1079 * [x] I work here * [ ] Tests added/passed * [ ] Requires documentation to be updated ## TODO * [x] `Tab::SetTabText` might be able to be greatly simplified/removed? * [x] I'm _pretty sure_ if they set an override title, we won't bubble that up to set the window title. * [x] I'm unsure how this behaves when the terminal's title changes _while_ the TextBox is visible. I don't think it should change the current contents of the box, but it might currently. * [ ] **for discussion**: If the user doesn't actually change the text of the tab, then we probably shouldn't set the override text, right? - EX: if they open the box and the text is "cmd", and immediately hit <kbd>enter</kbd>, then run `title foo`, should the text change to "foo" or stay "cmd"? ## Detailed Description of the Pull Request / Additional comments ![image](https://user-images.githubusercontent.com/18356694/81230615-713f9180-8fb7-11ea-8945-6681eec02a4f.png) ![image](https://user-images.githubusercontent.com/18356694/81230640-7ac8f980-8fb7-11ea-9e6b-22f0e0ed128a.png) ![image](https://user-images.githubusercontent.com/18356694/81230665-86b4bb80-8fb7-11ea-90f0-16d4ffb60d89.png) ![image](https://user-images.githubusercontent.com/18356694/81230686-9207e700-8fb7-11ea-94a9-f3f5a59be139.png) ![image](https://user-images.githubusercontent.com/18356694/81230732-a350f380-8fb7-11ea-9901-6dd4f36154f1.png) ![image](https://user-images.githubusercontent.com/18356694/81230746-a8ae3e00-8fb7-11ea-94fa-d2578f9241a7.png) ![image](https://user-images.githubusercontent.com/18356694/81230787-bc59a480-8fb7-11ea-8edf-2bd7fad343fc.png) ![image](https://user-images.githubusercontent.com/18356694/81230851-dc896380-8fb7-11ea-98c1-918b943543e4.png)
2020-05-28 23:06:17 +02:00
winrt::hstring _runtimeTabText{};
bool _inRename{ false };
winrt::Windows::UI::Xaml::Controls::TextBox::LayoutUpdated_revoker _tabRenameBoxLayoutUpdatedRevoker;
Add Close... option to Tab context menu (#7728) <!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Summary of the Pull Request Add a "Close..." option to the tab context menu, with nested entries to close tabs to the right and close other tabs (actions already available) ![immagine](https://user-images.githubusercontent.com/1140981/94178005-c7e03600-fe9a-11ea-9f87-c6f4895d4cf3.png) <!-- Other than the issue solved, is this relevant to any other issues/existing PRs? --> ## References #1912 <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist * [x] Closes #5524 * [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA * [ ] Tests added/passed * [ ] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx * [ ] Schema 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 --> ## Detailed Description of the Pull Request / Additional comments First contribution :slightly_smiling_face: Tried to follow some suggestions from https://github.com/microsoft/terminal/issues/1912#issuecomment-667079311 <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed
2020-10-15 13:40:44 +02:00
winrt::TerminalApp::ShortcutActionDispatch _dispatch;
Move Pane to Tab (GH7075) (#10780) <!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Summary of the Pull Request Add functionality to move a pane to another tab. If the tab index is greater than the number of current tabs a new tab will be created with the pane as its root. Similarly, if the last pane on a tab is moved to another tab, the original tab will be closed. This is largely complete, but I know that I'm messing around with things that I am unfamiliar with, and would like to avoid footguns where possible. <!-- Other than the issue solved, is this relevant to any other issues/existing PRs? --> ## References #4587 <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist * [x] Closes #7075 * [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA * [ ] Tests added/passed * [x] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx * [x] Schema 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 --> ## Detailed Description of the Pull Request / Additional comments Things done: - Moving a pane to a new tab appears to work. Moving a pane to an existing tab mostly works. Moving a pane back to its original tab appears to work. - Set up {Attach,Detach}Pane methods to add or remove a pane from a pane. Detach is slightly different than Close in that we want to persist the tree structure and terminal controls. - Add `Detached` event on a pane that can be subscribed to to remove other event handlers if desired. - Added simple WalkTree abstraction for one-off recursion use cases that calls a provided function on each pane in order (and optionally terminates early). - Fixed an in-prod bug with closing panes. Specifically, if you have a tree (1; 2 3) and close the 1 pane, then 3 will lose its borders because of these lines clearing the border on both children https://github.com/microsoft/terminal/blob/main/src/cascadia/TerminalApp/Pane.cpp#L1197-L1201 . To do: - Right now I have `TerminalTab` as a friend class of `Pane` so I can access some extra properties in my `WalkTree` callbacks, but there is probably a better choice for the abstraction boundary. Next Steps: - In a future PR Drag & Drop handlers could be added that utilize the Attach/Detach infrastructure to provide a better UI. - Similarly once this is working, it should be possible to convert an entire tab into a pane on an existing tab (Tab::DetachRoot on original tab followed by Tab::AttachPane on the target tab). - Its been 10 years, I just really want to use concepts already. <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed Manual testing by creating pane(s), and moving them between tabs and creating new tabs and destroying tabs by moving the last remaining pane.
2021-08-12 18:41:17 +02:00
void _Setup();
std::optional<Windows::UI::Xaml::DispatcherTimer> _bellIndicatorTimer;
void _BellIndicatorTimerTick(Windows::Foundation::IInspectable const& sender, Windows::Foundation::IInspectable const& e);
void _MakeTabViewItem() override;
winrt::fire_and_forget _UpdateHeaderControlMaxWidth();
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
void _CreateContextMenu() override;
virtual winrt::hstring _CreateToolTipTitle() override;
Add Close... option to Tab context menu (#7728) <!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Summary of the Pull Request Add a "Close..." option to the tab context menu, with nested entries to close tabs to the right and close other tabs (actions already available) ![immagine](https://user-images.githubusercontent.com/1140981/94178005-c7e03600-fe9a-11ea-9f87-c6f4895d4cf3.png) <!-- Other than the issue solved, is this relevant to any other issues/existing PRs? --> ## References #1912 <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist * [x] Closes #5524 * [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA * [ ] Tests added/passed * [ ] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx * [ ] Schema 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 --> ## Detailed Description of the Pull Request / Additional comments First contribution :slightly_smiling_face: Tried to follow some suggestions from https://github.com/microsoft/terminal/issues/1912#issuecomment-667079311 <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed
2020-10-15 13:40:44 +02:00
void _RefreshVisualState();
Move Pane to Tab (GH7075) (#10780) <!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Summary of the Pull Request Add functionality to move a pane to another tab. If the tab index is greater than the number of current tabs a new tab will be created with the pane as its root. Similarly, if the last pane on a tab is moved to another tab, the original tab will be closed. This is largely complete, but I know that I'm messing around with things that I am unfamiliar with, and would like to avoid footguns where possible. <!-- Other than the issue solved, is this relevant to any other issues/existing PRs? --> ## References #4587 <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist * [x] Closes #7075 * [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA * [ ] Tests added/passed * [x] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx * [x] Schema 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 --> ## Detailed Description of the Pull Request / Additional comments Things done: - Moving a pane to a new tab appears to work. Moving a pane to an existing tab mostly works. Moving a pane back to its original tab appears to work. - Set up {Attach,Detach}Pane methods to add or remove a pane from a pane. Detach is slightly different than Close in that we want to persist the tree structure and terminal controls. - Add `Detached` event on a pane that can be subscribed to to remove other event handlers if desired. - Added simple WalkTree abstraction for one-off recursion use cases that calls a provided function on each pane in order (and optionally terminates early). - Fixed an in-prod bug with closing panes. Specifically, if you have a tree (1; 2 3) and close the 1 pane, then 3 will lose its borders because of these lines clearing the border on both children https://github.com/microsoft/terminal/blob/main/src/cascadia/TerminalApp/Pane.cpp#L1197-L1201 . To do: - Right now I have `TerminalTab` as a friend class of `Pane` so I can access some extra properties in my `WalkTree` callbacks, but there is probably a better choice for the abstraction boundary. Next Steps: - In a future PR Drag & Drop handlers could be added that utilize the Attach/Detach infrastructure to provide a better UI. - Similarly once this is working, it should be possible to convert an entire tab into a pane on an existing tab (Tab::DetachRoot on original tab followed by Tab::AttachPane on the target tab). - Its been 10 years, I just really want to use concepts already. <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed Manual testing by creating pane(s), and moving them between tabs and creating new tabs and destroying tabs by moving the last remaining pane.
2021-08-12 18:41:17 +02:00
void _DetachEventHandlersFromControl(const uint32_t paneId, const winrt::Microsoft::Terminal::Control::TermControl& control);
void _AttachEventHandlersToControl(const uint32_t paneId, const winrt::Microsoft::Terminal::Control::TermControl& control);
void _AttachEventHandlersToPane(std::shared_ptr<Pane> pane);
Process actions sync. on startup; don't dupe nonexistent profile (#5090) This PR has evolved to encapsulate two related fixes that I can't really untie anymore. #2455 - Duplicating a tab that doesn't exist anymore This was the bug I was originally fixing in #4429. When the user tries to `duplicateTab` with a profile that doesn't exist anymore (like might happen after a settings reload), don't crash. As I was going about adding tests for this, got blocked by the fact that the Terminal couldn't open _any_ panes while the `TerminalPage` was size 0x0. This had two theoretical solutions: * Fake the `TerminalPage` into thinking it had a real size in the test - probably possible, though I'm unsure how it would work in practice. * Change `Pane`s to not require an `ActualWidth`, `ActualHeight` on initialization. Fortuately, the second option was something else that was already on my backlog of bugs. #4618 - `wt` command-line can't consistently parse more than one arg Presently, the Terminal just arbitrarily dispatches a bunch of handlers to try and handle all the commands provided on the commandline. That's lead to a bunch of reports that not all the commands will always get executed, nor will they all get executed in the same order. This PR also changes the `TerminalPage` to be able to dispatch all the commands sequentially, all at once in the startup. No longer will there be a hot second where the commands seem to execute themselves in from of the user - they'll all happen behind the scenes on startup. This involved a couple other changes areound the `TerminalPage` * I had to make sure that panes could be opened at a 0x0 size. Now they use a star sizing based off the percentage of the parent they're supposed to consume, so that when the parent _does_ get laid out, they'll take the appropriate size of that parent. * I had to do some math ahead of time to try and calculate what a `SplitState::Automatic` would be evaluated as, despite the fact that we don't actually know how big the pane will be. * I had to ensure that `focus-tab` commands appropriately mark a single tab as focused while we're in startup, without roundtripping to the Dispatcher thread and back ## References #4429 - the original PR for #2455 #5047 - a follow-up task from discussion in #4429 #4953 - a PR for making panes use star sizing, which was immensly helpful for this PR. ## Detailed Description of the Pull Request / Additional comments `CascadiaSettings::BuildSettings` can throw if the GUID doesn't exist. This wraps those calls up with a try/catch. It also adds a couple tests - a few `SettingsTests` for try/catching this state. It also adds a XAML-y test in `TabTests` that creates a `TerminalPage` and then performs som UI-like actions on it. This test required a minor change to how we generate the new tab dropdown - in the tests, `Application::Current()` is _not_ a `TerminalApp::App`, so it doesn't have a `Logic()` to query. So wrap that in a try/catch as well. While working on these tests, I found that we'd crash pretty agressively for mysterious reasons if the TestHostApp became focused while the test was running. This was due to a call in `TSFInputControl::NotifyFocusEnter` that would callback to `TSFInputControl::_layoutRequested`, which would crash on setting the `MaxSize` of the canvas to a negative value. This PR includes a hotfix for that bug as well. ## Validation Steps Performed * Manual testing with a _lot_ of commands in a commandline * run the tests * Team tested in selfhost Closes #2455 Closes #4618
2020-03-26 01:03:32 +01:00
void _UpdateActivePane(std::shared_ptr<Pane> pane);
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
winrt::hstring _GetActiveTitle() const;
Enable tab renaming at runtime from the UI (#5775) ## Summary of the Pull Request Adds support for setting, from the UI, a runtime override for the tab title text. The user can use this to effectively "rename" a tab. If set, the tab will _always_ use the runtime override string. If the user has multiple panes with different titles in a pane, then the tab's override text will be used _regardless_ of which pane was focused when the tab was renamed. The override text can be removed by just deleting the entire contents of the box. Then, the tab will revert to using the terminal's usual title. ## References * Wouldn't be possible without the context menu from #3789 * Focus doesn't return to the active terminal after hitting <kbd>enter</kbd>/<kbd>esc</kbd>, but that's tracked by #5750 ## PR Checklist * [x] Closes #1079 * [x] I work here * [ ] Tests added/passed * [ ] Requires documentation to be updated ## TODO * [x] `Tab::SetTabText` might be able to be greatly simplified/removed? * [x] I'm _pretty sure_ if they set an override title, we won't bubble that up to set the window title. * [x] I'm unsure how this behaves when the terminal's title changes _while_ the TextBox is visible. I don't think it should change the current contents of the box, but it might currently. * [ ] **for discussion**: If the user doesn't actually change the text of the tab, then we probably shouldn't set the override text, right? - EX: if they open the box and the text is "cmd", and immediately hit <kbd>enter</kbd>, then run `title foo`, should the text change to "foo" or stay "cmd"? ## Detailed Description of the Pull Request / Additional comments ![image](https://user-images.githubusercontent.com/18356694/81230615-713f9180-8fb7-11ea-8945-6681eec02a4f.png) ![image](https://user-images.githubusercontent.com/18356694/81230640-7ac8f980-8fb7-11ea-9e6b-22f0e0ed128a.png) ![image](https://user-images.githubusercontent.com/18356694/81230665-86b4bb80-8fb7-11ea-90f0-16d4ffb60d89.png) ![image](https://user-images.githubusercontent.com/18356694/81230686-9207e700-8fb7-11ea-94a9-f3f5a59be139.png) ![image](https://user-images.githubusercontent.com/18356694/81230732-a350f380-8fb7-11ea-9901-6dd4f36154f1.png) ![image](https://user-images.githubusercontent.com/18356694/81230746-a8ae3e00-8fb7-11ea-94fa-d2578f9241a7.png) ![image](https://user-images.githubusercontent.com/18356694/81230787-bc59a480-8fb7-11ea-8edf-2bd7fad343fc.png) ![image](https://user-images.githubusercontent.com/18356694/81230851-dc896380-8fb7-11ea-98c1-918b943543e4.png)
2020-05-28 23:06:17 +02:00
void _RecalculateAndApplyTabColor();
void _ApplyTabColor(const winrt::Windows::UI::Color& color);
void _ClearTabBackgroundColor();
void _RecalculateAndApplyReadOnly();
Split `TermControl` into a Core, Interactivity, and Control layer (#9820) ## Summary of the Pull Request Brace yourselves, it's finally here. This PR does the dirty work of splitting the monolithic `TermControl` into three components. These components are: * `ControlCore`: This encapsulates the `Terminal` instance, the `DxEngine` and `Renderer`, and the `Connection`. This is intended to everything that someone might need to stand up a terminal instance in a control, but without any regard for how the UX works. * `ControlInteractivity`: This is a wrapper for the `ControlCore`, which holds the logic for things like double-click, right click copy/paste, selection, etc. This is intended to be a UI framework-independent abstraction. The methods this layer exposes can be called the same from both the WinUI TermControl and the WPF control. * `TermControl`: This is the UWP control. It's got a Core and Interactivity inside it, which it uses for the actual logic of the terminal itself. TermControl's main responsibility is now By splitting into smaller pieces, it will enable us to * write unit tests for the `Core` and `Interactivity` bits, which we desparately need * Combine `ControlCore` and `ControlInteractivity` in an out-of-proc core process in the future, to enable tab tearout. However, we're not doing that work quite yet. There's still lots of work to be done to enable that, thought this is likely the biggest portion. Ideally, this would just be methods moved wholesale from one file to another. Unfortunately, there are a bunch of cases where that didn't work as well as expected. Especially when trying to better enforce the boundary between the classes. We've got a couple tests here that I've added. These are partially examples, and partially things I ran into while implementing this. A bunch of things from #7001 can go in now that we have this. This PR is gonna be a huge pain to review - 38 files with 3,730 additions and 1,661 deletions is nothing to scoff at. It will also conflict 100% with anything that's targeting `TermControl`. I'm hoping we can review this over the course of the next week and just be done with it, and leave plenty of runway for 1.9 bugs in post. ## References * In pursuit of #1256 * Proc Model: #5000 * https://github.com/microsoft/terminal/projects/5 ## PR Checklist * [x] Closes #6842 * [x] Closes https://github.com/microsoft/terminal/projects/5#card-50760249 * [x] Closes https://github.com/microsoft/terminal/projects/5#card-50760258 * [x] I work here * [x] Tests added/passed * [n/a] Requires documentation to be updated ## Detailed Description of the Pull Request / Additional comments * I don't love the names `ControlCore` and `ControlInteractivity`. Open to other names. * I added a `ICoreState` interface for "properties that come from the `ControlCore`, but consumers of the `TermControl` need to know". In the future, these will all need to be handled specially, because they might involve an RPC call to retrieve the info from the core (or cache it) in the window process. * I've added more `EventArgs` to make more events proper `TypedEvent`s. * I've changed how the TerminalApp layer requests updated TaskbarProgress state. It doesn't need to pump TermControl to raise a new event anymore. * ~~Something that snuck into this branch in the very long history is the switch to `DCompositionCreateSurfaceHandle` for the `DxEngine`. @miniksa wrote this originally in 30b8335, I'm just finally committing it here. We'll need that in the future for the out-of-proc stuff.~~ * I reverted this in c113b65d9. We can revert _that_ commit when we want to come back to it. * I've changed the acrylic handler a decent amount. But added tests! * All the `ThrottledFunc` things are left in `TermControl`. Some might be able to move down into core/interactivity, but once we figure out how to use a different kind of Dispatcher (because a UI thread won't necessarily exist for those components). * I've undoubtably messed up the merging of the locking around the appearance config stuff recently ## Validation Steps Performed I've got a rolling list in https://github.com/microsoft/terminal/issues/6842#issuecomment-810990460 that I'm updating as I go.
2021-04-27 17:50:45 +02:00
void _UpdateProgressState();
void _DuplicateTab();
Process actions sync. on startup; don't dupe nonexistent profile (#5090) This PR has evolved to encapsulate two related fixes that I can't really untie anymore. #2455 - Duplicating a tab that doesn't exist anymore This was the bug I was originally fixing in #4429. When the user tries to `duplicateTab` with a profile that doesn't exist anymore (like might happen after a settings reload), don't crash. As I was going about adding tests for this, got blocked by the fact that the Terminal couldn't open _any_ panes while the `TerminalPage` was size 0x0. This had two theoretical solutions: * Fake the `TerminalPage` into thinking it had a real size in the test - probably possible, though I'm unsure how it would work in practice. * Change `Pane`s to not require an `ActualWidth`, `ActualHeight` on initialization. Fortuately, the second option was something else that was already on my backlog of bugs. #4618 - `wt` command-line can't consistently parse more than one arg Presently, the Terminal just arbitrarily dispatches a bunch of handlers to try and handle all the commands provided on the commandline. That's lead to a bunch of reports that not all the commands will always get executed, nor will they all get executed in the same order. This PR also changes the `TerminalPage` to be able to dispatch all the commands sequentially, all at once in the startup. No longer will there be a hot second where the commands seem to execute themselves in from of the user - they'll all happen behind the scenes on startup. This involved a couple other changes areound the `TerminalPage` * I had to make sure that panes could be opened at a 0x0 size. Now they use a star sizing based off the percentage of the parent they're supposed to consume, so that when the parent _does_ get laid out, they'll take the appropriate size of that parent. * I had to do some math ahead of time to try and calculate what a `SplitState::Automatic` would be evaluated as, despite the fact that we don't actually know how big the pane will be. * I had to ensure that `focus-tab` commands appropriately mark a single tab as focused while we're in startup, without roundtripping to the Dispatcher thread and back ## References #4429 - the original PR for #2455 #5047 - a follow-up task from discussion in #4429 #4953 - a PR for making panes use star sizing, which was immensly helpful for this PR. ## Detailed Description of the Pull Request / Additional comments `CascadiaSettings::BuildSettings` can throw if the GUID doesn't exist. This wraps those calls up with a try/catch. It also adds a couple tests - a few `SettingsTests` for try/catching this state. It also adds a XAML-y test in `TabTests` that creates a `TerminalPage` and then performs som UI-like actions on it. This test required a minor change to how we generate the new tab dropdown - in the tests, `Application::Current()` is _not_ a `TerminalApp::App`, so it doesn't have a `Logic()` to query. So wrap that in a try/catch as well. While working on these tests, I found that we'd crash pretty agressively for mysterious reasons if the TestHostApp became focused while the test was running. This was due to a call in `TSFInputControl::NotifyFocusEnter` that would callback to `TSFInputControl::_layoutRequested`, which would crash on setting the `MaxSize` of the canvas to a negative value. This PR includes a hotfix for that bug as well. ## Validation Steps Performed * Manual testing with a _lot_ of commands in a commandline * run the tests * Team tested in selfhost Closes #2455 Closes #4618
2020-03-26 01:03:32 +01:00
friend class ::TerminalAppLocalTests::TabTests;
};
}