terminal/src/cascadia/TerminalApp/Pane.h

376 lines
16 KiB
C
Raw Normal View History

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
//
// Module Name:
// - Pane.h
//
// Abstract:
// - Panes are an abstraction by which the terminal can display multiple terminal
// instances simultaneously in a single terminal window. While tabs allow for
// a single terminal window to have many terminal sessions running
// simultaneously within a single window, only one tab can be visible at a
// time. Panes, on the other hand, allow a user to have many different
// terminal sessions visible to the user within the context of a single window
// at the same time. This can enable greater productivity from the user, as
// they can see the output of one terminal window while working in another.
// - See doc/cascadia/Panes.md for a detailed description.
//
// Author:
// - Mike Griese (zadjii-msft) 16-May-2019
#pragma once
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
#include "../../cascadia/inc/cppwinrt_utils.h"
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
#include "TaskbarState.h"
Preliminary work to add Swap Panes functionality (GH Issues 1000, 4922) (#10638) <!-- 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 swap a pane with an adjacent (Up/Down/Left/Right) neighbor. <!-- Other than the issue solved, is this relevant to any other issues/existing PRs? --> ## References This work potentially touches on: #1000 #2398 and #4922 <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist * [x] Closes a component of #1000 (partially, comment), #4922 (partially, `SwapPanes` function is added but not hooked up, no detach functionality) * [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA * [x] 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 Its been a while since I've written C++ code, and it is my first time working on a Windows application. I hope that I have not made too many mistakes. Work currently done: - Add boilerplate/infrastructure for argument parsing, hotkeys, event handling - Adds the `MovePane` function that finds the focused pane, and then tries to find a pane that is visually adjacent to according to direction. - First pass at the `SwapPanes` function that swaps the tree location of two panes - First working version of helpers `_FindFocusAndNeighbor` and `_FindNeighborFromFocus` that search the tree for the currently focused pane, and then climbs back up the tree to try to find a sibling pane that is adjacent to it. - An `_IsAdjacent' function that tests whether two panes, given their relative offsets, are adjacent to each other according to the direction. Next steps: - Once working these functions (`_FindFocusAndNeighbor`, etc) could be utilized to also solve #2398 by updating the `NavigateFocus` function. - Do we want default hotkeys for the new actions? <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed At this point, compilation and manual testing of functionality (with hotkeys) by creating panes, adding distinguishers to each pane, and then swapping them around to confirm they went to the right location.
2021-07-22 14:53:03 +02:00
// fwdecl unittest classes
namespace TerminalAppLocalTests
{
class TabTests;
};
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
namespace winrt::TerminalApp::implementation
{
struct TerminalTab;
}
Indicate which pane is focused with the Accent color on the pan… (#3060) ## Summary of the Pull Request Adds a small border with the accent color to indicate a pane is focused <img src="https://user-images.githubusercontent.com/18356694/66218711-560e4b80-e68f-11e9-85b0-1f387d35bb92.png" width="480"> <img src="https://user-images.githubusercontent.com/18356694/66218757-6f16fc80-e68f-11e9-8d39-db9ab748c4de.png" width="480"> <img src="https://user-images.githubusercontent.com/18356694/66219194-55c28000-e690-11e9-9835-8b5212e70e8a.png" width="480"> ## PR Checklist * [x] Closes #994 * [x] I work here * [😢] Tests added/passed * [n/a] Requires documentation to be updated ## Detailed Description of the Pull Request / Additional comments I've removed the simple Grid we were using as the pane separator, and replaced it with a Border that might appear on any side of a pane. When we add a split, we'll create each child with one of the `Border` flags set (each child with one of a pair of flags). E.g. creating a horizontal split creates one child with the `Top` border, and another with the `Bottom`. Then, if one of those panes is split, it will pass it's border flag to is new children, with the additional flag set. So adding another Vertical split to the above scenario would create a set of panes with either (`Top|Left`, `Top|Right`) or (`Bottom|Left`, `Bottom|Right`) borders set, depending on which pane was split. <hr> * start work on this by tracking border state * Colorize the border * Use the accent color for highlighting * Cleanup the accent color code * Don't buy any rural real estate when closing a pane * Closing panes works well now too * Cleanup for review * Update src/cascadia/TerminalApp/Pane.cpp * try some things that don't work to fix the resizing crash * Revert "try some things that don't work to fix the resizing crash" This reverts commit 3fc14da1130318add37a98d8de8d7ff440bbed59. * this _does_ work, but I think it's not semantically correct * This doesn't seem to work either. I tried adding the pane seperators to the Pane::_GetMinWidth calculation. That works for prevent the crash, but the resizing is wonky now. If you add a Vertical split, then a second, then resize the middle pane really small, you'll see that the _last_ resize doesn't work properly. The text seems to overhand into the border. Additionally, there's really weird behavior resizing panes to be small. They don't always seem to be resizable to the smallest size. * Revert "This doesn't seem to work either." This reverts commit 2fd8323e7ba84527963f051a4e70751e846be87a. * Merge the changes from the "this is the one" branch Again, no idea what I really did that worked, but it does * Cleanup from my mess of a commit This makes so much more sense now * Other PR feedback from @carlos-zamora * Fix a typo
2019-11-01 21:06:11 +01:00
enum class Borders : int
{
None = 0x0,
Top = 0x1,
Bottom = 0x2,
Left = 0x4,
Add the ability to interact with subtrees of panes (#11153) This commit adds the ability to interact with subtrees of panes. Have you ever thought that you don't have enough regression testing to do? Boy do I have the PR for you! This breaks all kinds of assumptions about what is or is not focused, largely complicated by the fact that a pane is not a proper control. I did my best to cover as many cases as I could, but I wouldn't be surprised if there are some things broken that I am unaware of. Done: - Add `parent` and `child` movement directions to move up and down the tree respectively - When a parent pane is selected it will have borders all around it in addition to any borders the children have. - Fix focus, swap, split, zoom, toggle orientation, resize, and move to all handle interacting with more than one pane. - Similarly the actions for font size changing, closing, read-only, clearing buffer, and changing color scheme will distribute to all children. - This technically leaves control focus on the original control in the focused subtree because panes aren't proper controls themselves. This is also used to make sure we go back down the same path with the `child` movement. - You can zoom a parent pane, and click between different zoomed sub-panes and it won't unzoom you until you use moveFocus or another action. This wasn't explicitly programmed behavior so it is probably buggy (I've quashed a couple at least). It is a natural consequence of showing multiple terminals and allowing you to focus a terminal and a parent separately, since changing the active pane directly does not unzoom. This also means there can be a disconnect between what pane is zoomed and what pane is active. ## Validation Steps Performed Tested focus movement, swapping, moving panes, and zooming. Closes #10733
2021-09-28 21:16:05 +02:00
Right = 0x8,
All = 0xF
Indicate which pane is focused with the Accent color on the pan… (#3060) ## Summary of the Pull Request Adds a small border with the accent color to indicate a pane is focused <img src="https://user-images.githubusercontent.com/18356694/66218711-560e4b80-e68f-11e9-85b0-1f387d35bb92.png" width="480"> <img src="https://user-images.githubusercontent.com/18356694/66218757-6f16fc80-e68f-11e9-8d39-db9ab748c4de.png" width="480"> <img src="https://user-images.githubusercontent.com/18356694/66219194-55c28000-e690-11e9-9835-8b5212e70e8a.png" width="480"> ## PR Checklist * [x] Closes #994 * [x] I work here * [😢] Tests added/passed * [n/a] Requires documentation to be updated ## Detailed Description of the Pull Request / Additional comments I've removed the simple Grid we were using as the pane separator, and replaced it with a Border that might appear on any side of a pane. When we add a split, we'll create each child with one of the `Border` flags set (each child with one of a pair of flags). E.g. creating a horizontal split creates one child with the `Top` border, and another with the `Bottom`. Then, if one of those panes is split, it will pass it's border flag to is new children, with the additional flag set. So adding another Vertical split to the above scenario would create a set of panes with either (`Top|Left`, `Top|Right`) or (`Bottom|Left`, `Bottom|Right`) borders set, depending on which pane was split. <hr> * start work on this by tracking border state * Colorize the border * Use the accent color for highlighting * Cleanup the accent color code * Don't buy any rural real estate when closing a pane * Closing panes works well now too * Cleanup for review * Update src/cascadia/TerminalApp/Pane.cpp * try some things that don't work to fix the resizing crash * Revert "try some things that don't work to fix the resizing crash" This reverts commit 3fc14da1130318add37a98d8de8d7ff440bbed59. * this _does_ work, but I think it's not semantically correct * This doesn't seem to work either. I tried adding the pane seperators to the Pane::_GetMinWidth calculation. That works for prevent the crash, but the resizing is wonky now. If you add a Vertical split, then a second, then resize the middle pane really small, you'll see that the _last_ resize doesn't work properly. The text seems to overhand into the border. Additionally, there's really weird behavior resizing panes to be small. They don't always seem to be resizable to the smallest size. * Revert "This doesn't seem to work either." This reverts commit 2fd8323e7ba84527963f051a4e70751e846be87a. * Merge the changes from the "this is the one" branch Again, no idea what I really did that worked, but it does * Cleanup from my mess of a commit This makes so much more sense now * Other PR feedback from @carlos-zamora * Fix a typo
2019-11-01 21:06:11 +01:00
};
DEFINE_ENUM_FLAG_OPERATORS(Borders);
Add the ability to split a pane and put the new pane first. (#11145) <!-- 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 directional modifiers for SplitState and convert those to the appropriate horizontal/vertical when splitting a pane. <!-- 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 #4340 * [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 "vertical" and "horizontal" splits were removed from `defaults.json`, but code was added to parse those as `right` and `down` respectively. It is also the case that if a user has a custom hotkey for `split: vertical` it will override the default for `split: right`. <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed Split the pane using each of the new directional movements
2021-09-15 22:14:57 +02:00
enum class SplitState : int
{
None = 0,
Horizontal = 1,
Vertical = 2
};
class Pane : public std::enable_shared_from_this<Pane>
{
public:
Pane(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
const winrt::Microsoft::Terminal::Control::TermControl& control,
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 bool lastFocused = false);
Add the ability to interact with subtrees of panes (#11153) This commit adds the ability to interact with subtrees of panes. Have you ever thought that you don't have enough regression testing to do? Boy do I have the PR for you! This breaks all kinds of assumptions about what is or is not focused, largely complicated by the fact that a pane is not a proper control. I did my best to cover as many cases as I could, but I wouldn't be surprised if there are some things broken that I am unaware of. Done: - Add `parent` and `child` movement directions to move up and down the tree respectively - When a parent pane is selected it will have borders all around it in addition to any borders the children have. - Fix focus, swap, split, zoom, toggle orientation, resize, and move to all handle interacting with more than one pane. - Similarly the actions for font size changing, closing, read-only, clearing buffer, and changing color scheme will distribute to all children. - This technically leaves control focus on the original control in the focused subtree because panes aren't proper controls themselves. This is also used to make sure we go back down the same path with the `child` movement. - You can zoom a parent pane, and click between different zoomed sub-panes and it won't unzoom you until you use moveFocus or another action. This wasn't explicitly programmed behavior so it is probably buggy (I've quashed a couple at least). It is a natural consequence of showing multiple terminals and allowing you to focus a terminal and a parent separately, since changing the active pane directly does not unzoom. This also means there can be a disconnect between what pane is zoomed and what pane is active. ## Validation Steps Performed Tested focus movement, swapping, moving panes, and zooming. Closes #10733
2021-09-28 21:16:05 +02:00
Pane(std::shared_ptr<Pane> first,
std::shared_ptr<Pane> second,
const SplitState splitType,
const float splitPosition,
const bool lastFocused = 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
std::shared_ptr<Pane> GetActivePane();
Add the ability to interact with subtrees of panes (#11153) This commit adds the ability to interact with subtrees of panes. Have you ever thought that you don't have enough regression testing to do? Boy do I have the PR for you! This breaks all kinds of assumptions about what is or is not focused, largely complicated by the fact that a pane is not a proper control. I did my best to cover as many cases as I could, but I wouldn't be surprised if there are some things broken that I am unaware of. Done: - Add `parent` and `child` movement directions to move up and down the tree respectively - When a parent pane is selected it will have borders all around it in addition to any borders the children have. - Fix focus, swap, split, zoom, toggle orientation, resize, and move to all handle interacting with more than one pane. - Similarly the actions for font size changing, closing, read-only, clearing buffer, and changing color scheme will distribute to all children. - This technically leaves control focus on the original control in the focused subtree because panes aren't proper controls themselves. This is also used to make sure we go back down the same path with the `child` movement. - You can zoom a parent pane, and click between different zoomed sub-panes and it won't unzoom you until you use moveFocus or another action. This wasn't explicitly programmed behavior so it is probably buggy (I've quashed a couple at least). It is a natural consequence of showing multiple terminals and allowing you to focus a terminal and a parent separately, since changing the active pane directly does not unzoom. This also means there can be a disconnect between what pane is zoomed and what pane is active. ## Validation Steps Performed Tested focus movement, swapping, moving panes, and zooming. Closes #10733
2021-09-28 21:16:05 +02:00
winrt::Microsoft::Terminal::Control::TermControl GetLastFocusedTerminalControl();
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 GetTerminalControl();
winrt::Microsoft::Terminal::Settings::Model::Profile GetFocusedProfile();
// Method Description:
// - If this is a leaf pane, return its profile.
// - If this is a branch/root pane, return nullptr.
winrt::Microsoft::Terminal::Settings::Model::Profile GetProfile() const
{
return _profile;
}
winrt::Windows::UI::Xaml::Controls::Grid GetRootElement();
bool WasLastFocused() const noexcept;
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
void UpdateVisuals();
void ClearActive();
void SetActive();
Persist window layout on window close (#10972) This commit adds initial support for saving window layout on application close. Done: - Add user setting for if tabs should be maintained. - Added events to track the number of open windows for the monarch, and then save if you are the last window closing. - Saves layout when the user explicitly hits the "Close Window" button. - If the user manually closed all of their tabs (through the tab x button or through closing all panes on the tab) then remove any saved state. - Saves in the ApplicationState file a list of actions the terminal can perform to restore its layout and the window size/position information. - This saves an action to focus the correct pane, but this won't actually work without #10978. Note that if you have a pane zoomed, it does still zoom the correct pane, but when you unzoom it will have a different pane selected. Todo: - multiple windows? Right now it can only handle loading/saving one window. - PR #11083 will save multiple windows. - This also sometimes runs into the existing bug where multiple tabs appear to be focused on opening. Next Steps: - The business logic of when the save is triggered can be adjusted as necessary. - Right now I am taking the pragmatic approach and just saving the state as an array of objects, but only ever populate it with 1, that way saving multiple windows in the future could be added without breaking schema compatibility. Selfishly I'm hoping that handling multiple windows could be spun off into another pr/feature for now. - One possible thing that can maybe be done is that the commandline can be augmented with a "--saved ##" attribute that would load from the nth saved state if it exists. e.g. if there are 3 saved windows, on first load it can spawn three wt --saved {0,1,2} that would reopen the windows? This way there also exists a way to load a copy of a previous window (if it is in the saved state). - Is the application state something that is planned to be public/user editable? In theory the user could since it is just json, but I don't know what it buys them over just modifying their settings and startupActions. Validation Steps Performed: - The happy path: open terminal -> set setting to true -> close terminal -> reopen and see tabs. Tested with powershell/cmd/wsl windows. - That closing all panes/tabs on their own will remove the saved session. - Open multiple windows, close windows and confirm that the last window closed saves its state. The generated file stores a sequence of actions that will be executed to restore the terminal to its saved form. References #8324 This is also one of the items on microsoft/terminal#5000 Closes #766
2021-09-09 00:44:53 +02:00
struct BuildStartupState
{
std::vector<winrt::Microsoft::Terminal::Settings::Model::ActionAndArgs> args;
std::shared_ptr<Pane> firstPane;
std::optional<uint32_t> focusedPaneId;
uint32_t panesCreated;
};
BuildStartupState BuildStartupActions(uint32_t currentId, uint32_t nextId);
winrt::Microsoft::Terminal::Settings::Model::NewTerminalArgs GetTerminalArgsForPane() const;
void UpdateSettings(const winrt::Microsoft::Terminal::Settings::Model::TerminalSettingsCreateResult& settings,
const winrt::Microsoft::Terminal::Settings::Model::Profile& profile);
void ResizeContent(const winrt::Windows::Foundation::Size& newSize);
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
void Relayout();
bool ResizePane(const winrt::Microsoft::Terminal::Settings::Model::ResizeDirection& direction);
Maintain zoom when moving focus (#11046) <!-- 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 Make it so you can navigate pane focus without unzooming. <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist * [x] Closes #7215 * [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 - Slight refactor to bring the MRU pane logic into the `NavigateDirection` function - The actual zoom behavior was not a problem, the only issue is that because most of the panes weren't in the UI tree I had to disable using the actual sizes. There is nothing wrong with that, since the synthetic sizing is required anyways, but I'm curious what other peoples' thoughts are. <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed ![output](https://user-images.githubusercontent.com/6185249/130901911-91676da2-db40-412d-b726-61a3f559ae17.gif)
2021-09-02 16:36:17 +02:00
std::shared_ptr<Pane> NavigateDirection(const std::shared_ptr<Pane> sourcePane,
const winrt::Microsoft::Terminal::Settings::Model::FocusDirection& direction,
const std::vector<uint32_t>& mruPanes);
Preliminary work to add Swap Panes functionality (GH Issues 1000, 4922) (#10638) <!-- 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 swap a pane with an adjacent (Up/Down/Left/Right) neighbor. <!-- Other than the issue solved, is this relevant to any other issues/existing PRs? --> ## References This work potentially touches on: #1000 #2398 and #4922 <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist * [x] Closes a component of #1000 (partially, comment), #4922 (partially, `SwapPanes` function is added but not hooked up, no detach functionality) * [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA * [x] 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 Its been a while since I've written C++ code, and it is my first time working on a Windows application. I hope that I have not made too many mistakes. Work currently done: - Add boilerplate/infrastructure for argument parsing, hotkeys, event handling - Adds the `MovePane` function that finds the focused pane, and then tries to find a pane that is visually adjacent to according to direction. - First pass at the `SwapPanes` function that swaps the tree location of two panes - First working version of helpers `_FindFocusAndNeighbor` and `_FindNeighborFromFocus` that search the tree for the currently focused pane, and then climbs back up the tree to try to find a sibling pane that is adjacent to it. - An `_IsAdjacent' function that tests whether two panes, given their relative offsets, are adjacent to each other according to the direction. Next steps: - Once working these functions (`_FindFocusAndNeighbor`, etc) could be utilized to also solve #2398 by updating the `NavigateFocus` function. - Do we want default hotkeys for the new actions? <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed At this point, compilation and manual testing of functionality (with hotkeys) by creating panes, adding distinguishers to each pane, and then swapping them around to confirm they went to the right location.
2021-07-22 14:53:03 +02:00
bool SwapPanes(std::shared_ptr<Pane> first, std::shared_ptr<Pane> second);
std::shared_ptr<Pane> NextPane(const std::shared_ptr<Pane> pane);
std::shared_ptr<Pane> PreviousPane(const std::shared_ptr<Pane> pane);
Add the ability to split a pane and put the new pane first. (#11145) <!-- 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 directional modifiers for SplitState and convert those to the appropriate horizontal/vertical when splitting a pane. <!-- 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 #4340 * [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 "vertical" and "horizontal" splits were removed from `defaults.json`, but code was added to parse those as `right` and `down` respectively. It is also the case that if a user has a custom hotkey for `split: vertical` it will override the default for `split: right`. <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed Split the pane using each of the new directional movements
2021-09-15 22:14:57 +02:00
std::pair<std::shared_ptr<Pane>, std::shared_ptr<Pane>> Split(winrt::Microsoft::Terminal::Settings::Model::SplitDirection splitType,
const float splitSize,
std::shared_ptr<Pane> pane);
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
bool ToggleSplitOrientation();
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
float CalcSnappedDimension(const bool widthOrHeight, const float dimension) const;
Add the ability to split a pane and put the new pane first. (#11145) <!-- 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 directional modifiers for SplitState and convert those to the appropriate horizontal/vertical when splitting a pane. <!-- 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 #4340 * [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 "vertical" and "horizontal" splits were removed from `defaults.json`, but code was added to parse those as `right` and `down` respectively. It is also the case that if a user has a custom hotkey for `split: vertical` it will override the default for `split: right`. <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed Split the pane using each of the new directional movements
2021-09-15 22:14:57 +02:00
std::optional<winrt::Microsoft::Terminal::Settings::Model::SplitDirection> PreCalculateAutoSplit(const std::shared_ptr<Pane> target,
const winrt::Windows::Foundation::Size parentSize) const;
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
std::optional<bool> PreCalculateCanSplit(const std::shared_ptr<Pane> target,
Add the ability to split a pane and put the new pane first. (#11145) <!-- 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 directional modifiers for SplitState and convert those to the appropriate horizontal/vertical when splitting a pane. <!-- 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 #4340 * [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 "vertical" and "horizontal" splits were removed from `defaults.json`, but code was added to parse those as `right` and `down` respectively. It is also the case that if a user has a custom hotkey for `split: vertical` it will override the default for `split: right`. <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed Split the pane using each of the new directional movements
2021-09-15 22:14:57 +02:00
winrt::Microsoft::Terminal::Settings::Model::SplitDirection splitType,
const float splitSize,
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
const winrt::Windows::Foundation::Size availableSpace) const;
void Shutdown();
void Close();
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> AttachPane(std::shared_ptr<Pane> pane,
Add the ability to split a pane and put the new pane first. (#11145) <!-- 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 directional modifiers for SplitState and convert those to the appropriate horizontal/vertical when splitting a pane. <!-- 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 #4340 * [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 "vertical" and "horizontal" splits were removed from `defaults.json`, but code was added to parse those as `right` and `down` respectively. It is also the case that if a user has a custom hotkey for `split: vertical` it will override the default for `split: right`. <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed Split the pane using each of the new directional movements
2021-09-15 22:14:57 +02:00
winrt::Microsoft::Terminal::Settings::Model::SplitDirection splitType);
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> DetachPane(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
int GetLeafPaneCount() const noexcept;
void Maximize(std::shared_ptr<Pane> zoomedPane);
void Restore(std::shared_ptr<Pane> zoomedPane);
std::optional<uint32_t> Id() noexcept;
void Id(uint32_t id) noexcept;
bool FocusPane(const uint32_t id);
bool FocusPane(const std::shared_ptr<Pane> pane);
Preliminary work to add Swap Panes functionality (GH Issues 1000, 4922) (#10638) <!-- 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 swap a pane with an adjacent (Up/Down/Left/Right) neighbor. <!-- Other than the issue solved, is this relevant to any other issues/existing PRs? --> ## References This work potentially touches on: #1000 #2398 and #4922 <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist * [x] Closes a component of #1000 (partially, comment), #4922 (partially, `SwapPanes` function is added but not hooked up, no detach functionality) * [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA * [x] 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 Its been a while since I've written C++ code, and it is my first time working on a Windows application. I hope that I have not made too many mistakes. Work currently done: - Add boilerplate/infrastructure for argument parsing, hotkeys, event handling - Adds the `MovePane` function that finds the focused pane, and then tries to find a pane that is visually adjacent to according to direction. - First pass at the `SwapPanes` function that swaps the tree location of two panes - First working version of helpers `_FindFocusAndNeighbor` and `_FindNeighborFromFocus` that search the tree for the currently focused pane, and then climbs back up the tree to try to find a sibling pane that is adjacent to it. - An `_IsAdjacent' function that tests whether two panes, given their relative offsets, are adjacent to each other according to the direction. Next steps: - Once working these functions (`_FindFocusAndNeighbor`, etc) could be utilized to also solve #2398 by updating the `NavigateFocus` function. - Do we want default hotkeys for the new actions? <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed At this point, compilation and manual testing of functionality (with hotkeys) by creating panes, adding distinguishers to each pane, and then swapping them around to confirm they went to the right location.
2021-07-22 14:53:03 +02:00
std::shared_ptr<Pane> FindPane(const uint32_t id);
bool ContainsReadOnly() const;
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
// Method Description:
// - A helper method for ad-hoc recursion on a pane tree. Walks the pane
// tree, calling a predicate on each pane in a depth-first pattern.
// - If the predicate returns true, recursion is stopped early.
// Arguments:
// - f: The function to be applied to each pane.
// Return Value:
// - true if the predicate returned true on any pane.
template<typename F>
//requires std::predicate<F, std::shared_ptr<Pane>>
Add the ability to interact with subtrees of panes (#11153) This commit adds the ability to interact with subtrees of panes. Have you ever thought that you don't have enough regression testing to do? Boy do I have the PR for you! This breaks all kinds of assumptions about what is or is not focused, largely complicated by the fact that a pane is not a proper control. I did my best to cover as many cases as I could, but I wouldn't be surprised if there are some things broken that I am unaware of. Done: - Add `parent` and `child` movement directions to move up and down the tree respectively - When a parent pane is selected it will have borders all around it in addition to any borders the children have. - Fix focus, swap, split, zoom, toggle orientation, resize, and move to all handle interacting with more than one pane. - Similarly the actions for font size changing, closing, read-only, clearing buffer, and changing color scheme will distribute to all children. - This technically leaves control focus on the original control in the focused subtree because panes aren't proper controls themselves. This is also used to make sure we go back down the same path with the `child` movement. - You can zoom a parent pane, and click between different zoomed sub-panes and it won't unzoom you until you use moveFocus or another action. This wasn't explicitly programmed behavior so it is probably buggy (I've quashed a couple at least). It is a natural consequence of showing multiple terminals and allowing you to focus a terminal and a parent separately, since changing the active pane directly does not unzoom. This also means there can be a disconnect between what pane is zoomed and what pane is active. ## Validation Steps Performed Tested focus movement, swapping, moving panes, and zooming. Closes #10733
2021-09-28 21:16:05 +02:00
auto WalkTree(F f) -> decltype(f(shared_from_this()))
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
{
Add the ability to interact with subtrees of panes (#11153) This commit adds the ability to interact with subtrees of panes. Have you ever thought that you don't have enough regression testing to do? Boy do I have the PR for you! This breaks all kinds of assumptions about what is or is not focused, largely complicated by the fact that a pane is not a proper control. I did my best to cover as many cases as I could, but I wouldn't be surprised if there are some things broken that I am unaware of. Done: - Add `parent` and `child` movement directions to move up and down the tree respectively - When a parent pane is selected it will have borders all around it in addition to any borders the children have. - Fix focus, swap, split, zoom, toggle orientation, resize, and move to all handle interacting with more than one pane. - Similarly the actions for font size changing, closing, read-only, clearing buffer, and changing color scheme will distribute to all children. - This technically leaves control focus on the original control in the focused subtree because panes aren't proper controls themselves. This is also used to make sure we go back down the same path with the `child` movement. - You can zoom a parent pane, and click between different zoomed sub-panes and it won't unzoom you until you use moveFocus or another action. This wasn't explicitly programmed behavior so it is probably buggy (I've quashed a couple at least). It is a natural consequence of showing multiple terminals and allowing you to focus a terminal and a parent separately, since changing the active pane directly does not unzoom. This also means there can be a disconnect between what pane is zoomed and what pane is active. ## Validation Steps Performed Tested focus movement, swapping, moving panes, and zooming. Closes #10733
2021-09-28 21:16:05 +02:00
using R = std::invoke_result_t<F, std::shared_ptr<Pane>>;
static constexpr auto IsVoid = std::is_void_v<R>;
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
Add the ability to interact with subtrees of panes (#11153) This commit adds the ability to interact with subtrees of panes. Have you ever thought that you don't have enough regression testing to do? Boy do I have the PR for you! This breaks all kinds of assumptions about what is or is not focused, largely complicated by the fact that a pane is not a proper control. I did my best to cover as many cases as I could, but I wouldn't be surprised if there are some things broken that I am unaware of. Done: - Add `parent` and `child` movement directions to move up and down the tree respectively - When a parent pane is selected it will have borders all around it in addition to any borders the children have. - Fix focus, swap, split, zoom, toggle orientation, resize, and move to all handle interacting with more than one pane. - Similarly the actions for font size changing, closing, read-only, clearing buffer, and changing color scheme will distribute to all children. - This technically leaves control focus on the original control in the focused subtree because panes aren't proper controls themselves. This is also used to make sure we go back down the same path with the `child` movement. - You can zoom a parent pane, and click between different zoomed sub-panes and it won't unzoom you until you use moveFocus or another action. This wasn't explicitly programmed behavior so it is probably buggy (I've quashed a couple at least). It is a natural consequence of showing multiple terminals and allowing you to focus a terminal and a parent separately, since changing the active pane directly does not unzoom. This also means there can be a disconnect between what pane is zoomed and what pane is active. ## Validation Steps Performed Tested focus movement, swapping, moving panes, and zooming. Closes #10733
2021-09-28 21:16:05 +02:00
if constexpr (IsVoid)
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
{
Add the ability to interact with subtrees of panes (#11153) This commit adds the ability to interact with subtrees of panes. Have you ever thought that you don't have enough regression testing to do? Boy do I have the PR for you! This breaks all kinds of assumptions about what is or is not focused, largely complicated by the fact that a pane is not a proper control. I did my best to cover as many cases as I could, but I wouldn't be surprised if there are some things broken that I am unaware of. Done: - Add `parent` and `child` movement directions to move up and down the tree respectively - When a parent pane is selected it will have borders all around it in addition to any borders the children have. - Fix focus, swap, split, zoom, toggle orientation, resize, and move to all handle interacting with more than one pane. - Similarly the actions for font size changing, closing, read-only, clearing buffer, and changing color scheme will distribute to all children. - This technically leaves control focus on the original control in the focused subtree because panes aren't proper controls themselves. This is also used to make sure we go back down the same path with the `child` movement. - You can zoom a parent pane, and click between different zoomed sub-panes and it won't unzoom you until you use moveFocus or another action. This wasn't explicitly programmed behavior so it is probably buggy (I've quashed a couple at least). It is a natural consequence of showing multiple terminals and allowing you to focus a terminal and a parent separately, since changing the active pane directly does not unzoom. This also means there can be a disconnect between what pane is zoomed and what pane is active. ## Validation Steps Performed Tested focus movement, swapping, moving panes, and zooming. Closes #10733
2021-09-28 21:16:05 +02:00
f(shared_from_this());
if (!_IsLeaf())
{
_firstChild->WalkTree(f);
_secondChild->WalkTree(f);
}
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
}
Add the ability to interact with subtrees of panes (#11153) This commit adds the ability to interact with subtrees of panes. Have you ever thought that you don't have enough regression testing to do? Boy do I have the PR for you! This breaks all kinds of assumptions about what is or is not focused, largely complicated by the fact that a pane is not a proper control. I did my best to cover as many cases as I could, but I wouldn't be surprised if there are some things broken that I am unaware of. Done: - Add `parent` and `child` movement directions to move up and down the tree respectively - When a parent pane is selected it will have borders all around it in addition to any borders the children have. - Fix focus, swap, split, zoom, toggle orientation, resize, and move to all handle interacting with more than one pane. - Similarly the actions for font size changing, closing, read-only, clearing buffer, and changing color scheme will distribute to all children. - This technically leaves control focus on the original control in the focused subtree because panes aren't proper controls themselves. This is also used to make sure we go back down the same path with the `child` movement. - You can zoom a parent pane, and click between different zoomed sub-panes and it won't unzoom you until you use moveFocus or another action. This wasn't explicitly programmed behavior so it is probably buggy (I've quashed a couple at least). It is a natural consequence of showing multiple terminals and allowing you to focus a terminal and a parent separately, since changing the active pane directly does not unzoom. This also means there can be a disconnect between what pane is zoomed and what pane is active. ## Validation Steps Performed Tested focus movement, swapping, moving panes, and zooming. Closes #10733
2021-09-28 21:16:05 +02:00
else
{
if (f(shared_from_this()))
{
return true;
}
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
Add the ability to interact with subtrees of panes (#11153) This commit adds the ability to interact with subtrees of panes. Have you ever thought that you don't have enough regression testing to do? Boy do I have the PR for you! This breaks all kinds of assumptions about what is or is not focused, largely complicated by the fact that a pane is not a proper control. I did my best to cover as many cases as I could, but I wouldn't be surprised if there are some things broken that I am unaware of. Done: - Add `parent` and `child` movement directions to move up and down the tree respectively - When a parent pane is selected it will have borders all around it in addition to any borders the children have. - Fix focus, swap, split, zoom, toggle orientation, resize, and move to all handle interacting with more than one pane. - Similarly the actions for font size changing, closing, read-only, clearing buffer, and changing color scheme will distribute to all children. - This technically leaves control focus on the original control in the focused subtree because panes aren't proper controls themselves. This is also used to make sure we go back down the same path with the `child` movement. - You can zoom a parent pane, and click between different zoomed sub-panes and it won't unzoom you until you use moveFocus or another action. This wasn't explicitly programmed behavior so it is probably buggy (I've quashed a couple at least). It is a natural consequence of showing multiple terminals and allowing you to focus a terminal and a parent separately, since changing the active pane directly does not unzoom. This also means there can be a disconnect between what pane is zoomed and what pane is active. ## Validation Steps Performed Tested focus movement, swapping, moving panes, and zooming. Closes #10733
2021-09-28 21:16:05 +02:00
if (!_IsLeaf())
{
return _firstChild->WalkTree(f) || _secondChild->WalkTree(f);
}
return false;
}
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
}
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
void CollectTaskbarStates(std::vector<winrt::TerminalApp::TaskbarState>& states);
WINRT_CALLBACK(Closed, winrt::Windows::Foundation::EventHandler<winrt::Windows::Foundation::IInspectable>);
Add the ability to interact with subtrees of panes (#11153) This commit adds the ability to interact with subtrees of panes. Have you ever thought that you don't have enough regression testing to do? Boy do I have the PR for you! This breaks all kinds of assumptions about what is or is not focused, largely complicated by the fact that a pane is not a proper control. I did my best to cover as many cases as I could, but I wouldn't be surprised if there are some things broken that I am unaware of. Done: - Add `parent` and `child` movement directions to move up and down the tree respectively - When a parent pane is selected it will have borders all around it in addition to any borders the children have. - Fix focus, swap, split, zoom, toggle orientation, resize, and move to all handle interacting with more than one pane. - Similarly the actions for font size changing, closing, read-only, clearing buffer, and changing color scheme will distribute to all children. - This technically leaves control focus on the original control in the focused subtree because panes aren't proper controls themselves. This is also used to make sure we go back down the same path with the `child` movement. - You can zoom a parent pane, and click between different zoomed sub-panes and it won't unzoom you until you use moveFocus or another action. This wasn't explicitly programmed behavior so it is probably buggy (I've quashed a couple at least). It is a natural consequence of showing multiple terminals and allowing you to focus a terminal and a parent separately, since changing the active pane directly does not unzoom. This also means there can be a disconnect between what pane is zoomed and what pane is active. ## Validation Steps Performed Tested focus movement, swapping, moving panes, and zooming. Closes #10733
2021-09-28 21:16:05 +02:00
using gotFocusArgs = winrt::delegate<std::shared_ptr<Pane>, winrt::Windows::UI::Xaml::FocusState>;
DECLARE_EVENT(GotFocus, _GotFocusHandlers, gotFocusArgs);
DECLARE_EVENT(LostFocus, _LostFocusHandlers, winrt::delegate<std::shared_ptr<Pane>>);
DECLARE_EVENT(PaneRaiseBell, _PaneRaiseBellHandlers, winrt::Windows::Foundation::EventHandler<bool>);
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
DECLARE_EVENT(Detached, _PaneDetachedHandlers, winrt::delegate<std::shared_ptr<Pane>>);
private:
Preliminary work to add Swap Panes functionality (GH Issues 1000, 4922) (#10638) <!-- 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 swap a pane with an adjacent (Up/Down/Left/Right) neighbor. <!-- Other than the issue solved, is this relevant to any other issues/existing PRs? --> ## References This work potentially touches on: #1000 #2398 and #4922 <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist * [x] Closes a component of #1000 (partially, comment), #4922 (partially, `SwapPanes` function is added but not hooked up, no detach functionality) * [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA * [x] 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 Its been a while since I've written C++ code, and it is my first time working on a Windows application. I hope that I have not made too many mistakes. Work currently done: - Add boilerplate/infrastructure for argument parsing, hotkeys, event handling - Adds the `MovePane` function that finds the focused pane, and then tries to find a pane that is visually adjacent to according to direction. - First pass at the `SwapPanes` function that swaps the tree location of two panes - First working version of helpers `_FindFocusAndNeighbor` and `_FindNeighborFromFocus` that search the tree for the currently focused pane, and then climbs back up the tree to try to find a sibling pane that is adjacent to it. - An `_IsAdjacent' function that tests whether two panes, given their relative offsets, are adjacent to each other according to the direction. Next steps: - Once working these functions (`_FindFocusAndNeighbor`, etc) could be utilized to also solve #2398 by updating the `NavigateFocus` function. - Do we want default hotkeys for the new actions? <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed At this point, compilation and manual testing of functionality (with hotkeys) by creating panes, adding distinguishers to each pane, and then swapping them around to confirm they went to the right location.
2021-07-22 14:53:03 +02:00
struct PanePoint;
struct PaneNeighborSearch;
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
struct SnapSizeResult;
struct SnapChildrenSizeResult;
struct LayoutSizeNode;
winrt::Windows::UI::Xaml::Controls::Grid _root{};
Add the ability to interact with subtrees of panes (#11153) This commit adds the ability to interact with subtrees of panes. Have you ever thought that you don't have enough regression testing to do? Boy do I have the PR for you! This breaks all kinds of assumptions about what is or is not focused, largely complicated by the fact that a pane is not a proper control. I did my best to cover as many cases as I could, but I wouldn't be surprised if there are some things broken that I am unaware of. Done: - Add `parent` and `child` movement directions to move up and down the tree respectively - When a parent pane is selected it will have borders all around it in addition to any borders the children have. - Fix focus, swap, split, zoom, toggle orientation, resize, and move to all handle interacting with more than one pane. - Similarly the actions for font size changing, closing, read-only, clearing buffer, and changing color scheme will distribute to all children. - This technically leaves control focus on the original control in the focused subtree because panes aren't proper controls themselves. This is also used to make sure we go back down the same path with the `child` movement. - You can zoom a parent pane, and click between different zoomed sub-panes and it won't unzoom you until you use moveFocus or another action. This wasn't explicitly programmed behavior so it is probably buggy (I've quashed a couple at least). It is a natural consequence of showing multiple terminals and allowing you to focus a terminal and a parent separately, since changing the active pane directly does not unzoom. This also means there can be a disconnect between what pane is zoomed and what pane is active. ## Validation Steps Performed Tested focus movement, swapping, moving panes, and zooming. Closes #10733
2021-09-28 21:16:05 +02:00
winrt::Windows::UI::Xaml::Controls::Border _borderFirst{};
winrt::Windows::UI::Xaml::Controls::Border _borderSecond{};
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{ nullptr };
winrt::Microsoft::Terminal::TerminalConnection::ConnectionState _connectionState{ winrt::Microsoft::Terminal::TerminalConnection::ConnectionState::NotConnected };
Indicate which pane is focused with the Accent color on the pan… (#3060) ## Summary of the Pull Request Adds a small border with the accent color to indicate a pane is focused <img src="https://user-images.githubusercontent.com/18356694/66218711-560e4b80-e68f-11e9-85b0-1f387d35bb92.png" width="480"> <img src="https://user-images.githubusercontent.com/18356694/66218757-6f16fc80-e68f-11e9-8d39-db9ab748c4de.png" width="480"> <img src="https://user-images.githubusercontent.com/18356694/66219194-55c28000-e690-11e9-9835-8b5212e70e8a.png" width="480"> ## PR Checklist * [x] Closes #994 * [x] I work here * [😢] Tests added/passed * [n/a] Requires documentation to be updated ## Detailed Description of the Pull Request / Additional comments I've removed the simple Grid we were using as the pane separator, and replaced it with a Border that might appear on any side of a pane. When we add a split, we'll create each child with one of the `Border` flags set (each child with one of a pair of flags). E.g. creating a horizontal split creates one child with the `Top` border, and another with the `Bottom`. Then, if one of those panes is split, it will pass it's border flag to is new children, with the additional flag set. So adding another Vertical split to the above scenario would create a set of panes with either (`Top|Left`, `Top|Right`) or (`Bottom|Left`, `Bottom|Right`) borders set, depending on which pane was split. <hr> * start work on this by tracking border state * Colorize the border * Use the accent color for highlighting * Cleanup the accent color code * Don't buy any rural real estate when closing a pane * Closing panes works well now too * Cleanup for review * Update src/cascadia/TerminalApp/Pane.cpp * try some things that don't work to fix the resizing crash * Revert "try some things that don't work to fix the resizing crash" This reverts commit 3fc14da1130318add37a98d8de8d7ff440bbed59. * this _does_ work, but I think it's not semantically correct * This doesn't seem to work either. I tried adding the pane seperators to the Pane::_GetMinWidth calculation. That works for prevent the crash, but the resizing is wonky now. If you add a Vertical split, then a second, then resize the middle pane really small, you'll see that the _last_ resize doesn't work properly. The text seems to overhand into the border. Additionally, there's really weird behavior resizing panes to be small. They don't always seem to be resizable to the smallest size. * Revert "This doesn't seem to work either." This reverts commit 2fd8323e7ba84527963f051a4e70751e846be87a. * Merge the changes from the "this is the one" branch Again, no idea what I really did that worked, but it does * Cleanup from my mess of a commit This makes so much more sense now * Other PR feedback from @carlos-zamora * Fix a typo
2019-11-01 21:06:11 +01:00
static winrt::Windows::UI::Xaml::Media::SolidColorBrush s_focusedBorderBrush;
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
static winrt::Windows::UI::Xaml::Media::SolidColorBrush s_unfocusedBorderBrush;
std::shared_ptr<Pane> _firstChild{ nullptr };
std::shared_ptr<Pane> _secondChild{ nullptr };
Add the ability to split a pane and put the new pane first. (#11145) <!-- 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 directional modifiers for SplitState and convert those to the appropriate horizontal/vertical when splitting a pane. <!-- 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 #4340 * [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 "vertical" and "horizontal" splits were removed from `defaults.json`, but code was added to parse those as `right` and `down` respectively. It is also the case that if a user has a custom hotkey for `split: vertical` it will override the default for `split: right`. <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed Split the pane using each of the new directional movements
2021-09-15 22:14:57 +02:00
SplitState _splitState{ SplitState::None };
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
float _desiredSplitPosition;
std::optional<uint32_t> _id;
Add the ability to interact with subtrees of panes (#11153) This commit adds the ability to interact with subtrees of panes. Have you ever thought that you don't have enough regression testing to do? Boy do I have the PR for you! This breaks all kinds of assumptions about what is or is not focused, largely complicated by the fact that a pane is not a proper control. I did my best to cover as many cases as I could, but I wouldn't be surprised if there are some things broken that I am unaware of. Done: - Add `parent` and `child` movement directions to move up and down the tree respectively - When a parent pane is selected it will have borders all around it in addition to any borders the children have. - Fix focus, swap, split, zoom, toggle orientation, resize, and move to all handle interacting with more than one pane. - Similarly the actions for font size changing, closing, read-only, clearing buffer, and changing color scheme will distribute to all children. - This technically leaves control focus on the original control in the focused subtree because panes aren't proper controls themselves. This is also used to make sure we go back down the same path with the `child` movement. - You can zoom a parent pane, and click between different zoomed sub-panes and it won't unzoom you until you use moveFocus or another action. This wasn't explicitly programmed behavior so it is probably buggy (I've quashed a couple at least). It is a natural consequence of showing multiple terminals and allowing you to focus a terminal and a parent separately, since changing the active pane directly does not unzoom. This also means there can be a disconnect between what pane is zoomed and what pane is active. ## Validation Steps Performed Tested focus movement, swapping, moving panes, and zooming. Closes #10733
2021-09-28 21:16:05 +02:00
std::weak_ptr<Pane> _parentChildPath{};
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
bool _lastActive{ false };
winrt::Microsoft::Terminal::Settings::Model::Profile _profile{ nullptr };
winrt::event_token _connectionStateChangedToken{ 0 };
winrt::event_token _firstClosedToken{ 0 };
winrt::event_token _secondClosedToken{ 0 };
winrt::event_token _warningBellToken{ 0 };
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
winrt::Windows::UI::Xaml::UIElement::GotFocus_revoker _gotFocusRevoker;
winrt::Windows::UI::Xaml::UIElement::LostFocus_revoker _lostFocusRevoker;
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
std::shared_mutex _createCloseLock{};
Indicate which pane is focused with the Accent color on the pan… (#3060) ## Summary of the Pull Request Adds a small border with the accent color to indicate a pane is focused <img src="https://user-images.githubusercontent.com/18356694/66218711-560e4b80-e68f-11e9-85b0-1f387d35bb92.png" width="480"> <img src="https://user-images.githubusercontent.com/18356694/66218757-6f16fc80-e68f-11e9-8d39-db9ab748c4de.png" width="480"> <img src="https://user-images.githubusercontent.com/18356694/66219194-55c28000-e690-11e9-9835-8b5212e70e8a.png" width="480"> ## PR Checklist * [x] Closes #994 * [x] I work here * [😢] Tests added/passed * [n/a] Requires documentation to be updated ## Detailed Description of the Pull Request / Additional comments I've removed the simple Grid we were using as the pane separator, and replaced it with a Border that might appear on any side of a pane. When we add a split, we'll create each child with one of the `Border` flags set (each child with one of a pair of flags). E.g. creating a horizontal split creates one child with the `Top` border, and another with the `Bottom`. Then, if one of those panes is split, it will pass it's border flag to is new children, with the additional flag set. So adding another Vertical split to the above scenario would create a set of panes with either (`Top|Left`, `Top|Right`) or (`Bottom|Left`, `Bottom|Right`) borders set, depending on which pane was split. <hr> * start work on this by tracking border state * Colorize the border * Use the accent color for highlighting * Cleanup the accent color code * Don't buy any rural real estate when closing a pane * Closing panes works well now too * Cleanup for review * Update src/cascadia/TerminalApp/Pane.cpp * try some things that don't work to fix the resizing crash * Revert "try some things that don't work to fix the resizing crash" This reverts commit 3fc14da1130318add37a98d8de8d7ff440bbed59. * this _does_ work, but I think it's not semantically correct * This doesn't seem to work either. I tried adding the pane seperators to the Pane::_GetMinWidth calculation. That works for prevent the crash, but the resizing is wonky now. If you add a Vertical split, then a second, then resize the middle pane really small, you'll see that the _last_ resize doesn't work properly. The text seems to overhand into the border. Additionally, there's really weird behavior resizing panes to be small. They don't always seem to be resizable to the smallest size. * Revert "This doesn't seem to work either." This reverts commit 2fd8323e7ba84527963f051a4e70751e846be87a. * Merge the changes from the "this is the one" branch Again, no idea what I really did that worked, but it does * Cleanup from my mess of a commit This makes so much more sense now * Other PR feedback from @carlos-zamora * Fix a typo
2019-11-01 21:06:11 +01:00
Borders _borders{ Borders::None };
bool _zoomed{ false };
bool _IsLeaf() const noexcept;
bool _HasFocusedChild() const noexcept;
void _SetupChildCloseHandlers();
Add the ability to interact with subtrees of panes (#11153) This commit adds the ability to interact with subtrees of panes. Have you ever thought that you don't have enough regression testing to do? Boy do I have the PR for you! This breaks all kinds of assumptions about what is or is not focused, largely complicated by the fact that a pane is not a proper control. I did my best to cover as many cases as I could, but I wouldn't be surprised if there are some things broken that I am unaware of. Done: - Add `parent` and `child` movement directions to move up and down the tree respectively - When a parent pane is selected it will have borders all around it in addition to any borders the children have. - Fix focus, swap, split, zoom, toggle orientation, resize, and move to all handle interacting with more than one pane. - Similarly the actions for font size changing, closing, read-only, clearing buffer, and changing color scheme will distribute to all children. - This technically leaves control focus on the original control in the focused subtree because panes aren't proper controls themselves. This is also used to make sure we go back down the same path with the `child` movement. - You can zoom a parent pane, and click between different zoomed sub-panes and it won't unzoom you until you use moveFocus or another action. This wasn't explicitly programmed behavior so it is probably buggy (I've quashed a couple at least). It is a natural consequence of showing multiple terminals and allowing you to focus a terminal and a parent separately, since changing the active pane directly does not unzoom. This also means there can be a disconnect between what pane is zoomed and what pane is active. ## Validation Steps Performed Tested focus movement, swapping, moving panes, and zooming. Closes #10733
2021-09-28 21:16:05 +02:00
bool _HasChild(const std::shared_ptr<Pane> child);
Add the ability to split a pane and put the new pane first. (#11145) <!-- 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 directional modifiers for SplitState and convert those to the appropriate horizontal/vertical when splitting a pane. <!-- 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 #4340 * [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 "vertical" and "horizontal" splits were removed from `defaults.json`, but code was added to parse those as `right` and `down` respectively. It is also the case that if a user has a custom hotkey for `split: vertical` it will override the default for `split: right`. <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed Split the pane using each of the new directional movements
2021-09-15 22:14:57 +02:00
std::pair<std::shared_ptr<Pane>, std::shared_ptr<Pane>> _Split(winrt::Microsoft::Terminal::Settings::Model::SplitDirection splitType,
const float splitSize,
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> newPane);
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
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 _CreateRowColDefinitions();
void _ApplySplitDefinitions();
void _SetupEntranceAnimation();
Indicate which pane is focused with the Accent color on the pan… (#3060) ## Summary of the Pull Request Adds a small border with the accent color to indicate a pane is focused <img src="https://user-images.githubusercontent.com/18356694/66218711-560e4b80-e68f-11e9-85b0-1f387d35bb92.png" width="480"> <img src="https://user-images.githubusercontent.com/18356694/66218757-6f16fc80-e68f-11e9-8d39-db9ab748c4de.png" width="480"> <img src="https://user-images.githubusercontent.com/18356694/66219194-55c28000-e690-11e9-9835-8b5212e70e8a.png" width="480"> ## PR Checklist * [x] Closes #994 * [x] I work here * [😢] Tests added/passed * [n/a] Requires documentation to be updated ## Detailed Description of the Pull Request / Additional comments I've removed the simple Grid we were using as the pane separator, and replaced it with a Border that might appear on any side of a pane. When we add a split, we'll create each child with one of the `Border` flags set (each child with one of a pair of flags). E.g. creating a horizontal split creates one child with the `Top` border, and another with the `Bottom`. Then, if one of those panes is split, it will pass it's border flag to is new children, with the additional flag set. So adding another Vertical split to the above scenario would create a set of panes with either (`Top|Left`, `Top|Right`) or (`Bottom|Left`, `Bottom|Right`) borders set, depending on which pane was split. <hr> * start work on this by tracking border state * Colorize the border * Use the accent color for highlighting * Cleanup the accent color code * Don't buy any rural real estate when closing a pane * Closing panes works well now too * Cleanup for review * Update src/cascadia/TerminalApp/Pane.cpp * try some things that don't work to fix the resizing crash * Revert "try some things that don't work to fix the resizing crash" This reverts commit 3fc14da1130318add37a98d8de8d7ff440bbed59. * this _does_ work, but I think it's not semantically correct * This doesn't seem to work either. I tried adding the pane seperators to the Pane::_GetMinWidth calculation. That works for prevent the crash, but the resizing is wonky now. If you add a Vertical split, then a second, then resize the middle pane really small, you'll see that the _last_ resize doesn't work properly. The text seems to overhand into the border. Additionally, there's really weird behavior resizing panes to be small. They don't always seem to be resizable to the smallest size. * Revert "This doesn't seem to work either." This reverts commit 2fd8323e7ba84527963f051a4e70751e846be87a. * Merge the changes from the "this is the one" branch Again, no idea what I really did that worked, but it does * Cleanup from my mess of a commit This makes so much more sense now * Other PR feedback from @carlos-zamora * Fix a typo
2019-11-01 21:06:11 +01:00
void _UpdateBorders();
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
Borders _GetCommonBorders();
bool _Resize(const winrt::Microsoft::Terminal::Settings::Model::ResizeDirection& direction);
Preliminary work to add Swap Panes functionality (GH Issues 1000, 4922) (#10638) <!-- 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 swap a pane with an adjacent (Up/Down/Left/Right) neighbor. <!-- Other than the issue solved, is this relevant to any other issues/existing PRs? --> ## References This work potentially touches on: #1000 #2398 and #4922 <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist * [x] Closes a component of #1000 (partially, comment), #4922 (partially, `SwapPanes` function is added but not hooked up, no detach functionality) * [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA * [x] 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 Its been a while since I've written C++ code, and it is my first time working on a Windows application. I hope that I have not made too many mistakes. Work currently done: - Add boilerplate/infrastructure for argument parsing, hotkeys, event handling - Adds the `MovePane` function that finds the focused pane, and then tries to find a pane that is visually adjacent to according to direction. - First pass at the `SwapPanes` function that swaps the tree location of two panes - First working version of helpers `_FindFocusAndNeighbor` and `_FindNeighborFromFocus` that search the tree for the currently focused pane, and then climbs back up the tree to try to find a sibling pane that is adjacent to it. - An `_IsAdjacent' function that tests whether two panes, given their relative offsets, are adjacent to each other according to the direction. Next steps: - Once working these functions (`_FindFocusAndNeighbor`, etc) could be utilized to also solve #2398 by updating the `NavigateFocus` function. - Do we want default hotkeys for the new actions? <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed At this point, compilation and manual testing of functionality (with hotkeys) by creating panes, adding distinguishers to each pane, and then swapping them around to confirm they went to the right location.
2021-07-22 14:53:03 +02:00
std::shared_ptr<Pane> _FindParentOfPane(const std::shared_ptr<Pane> pane);
std::pair<PanePoint, PanePoint> _GetOffsetsForPane(const PanePoint parentOffset) const;
Maintain zoom when moving focus (#11046) <!-- 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 Make it so you can navigate pane focus without unzooming. <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist * [x] Closes #7215 * [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 - Slight refactor to bring the MRU pane logic into the `NavigateDirection` function - The actual zoom behavior was not a problem, the only issue is that because most of the panes weren't in the UI tree I had to disable using the actual sizes. There is nothing wrong with that, since the synthetic sizing is required anyways, but I'm curious what other peoples' thoughts are. <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed ![output](https://user-images.githubusercontent.com/6185249/130901911-91676da2-db40-412d-b726-61a3f559ae17.gif)
2021-09-02 16:36:17 +02:00
bool _IsAdjacent(const PanePoint firstOffset, const PanePoint secondOffset, const winrt::Microsoft::Terminal::Settings::Model::FocusDirection& direction) const;
PaneNeighborSearch _FindNeighborForPane(const winrt::Microsoft::Terminal::Settings::Model::FocusDirection& direction,
PaneNeighborSearch searchResult,
const bool focusIsSecondSide,
const PanePoint offset);
PaneNeighborSearch _FindPaneAndNeighbor(const std::shared_ptr<Pane> sourcePane,
const winrt::Microsoft::Terminal::Settings::Model::FocusDirection& direction,
const PanePoint offset);
Preliminary work to add Swap Panes functionality (GH Issues 1000, 4922) (#10638) <!-- 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 swap a pane with an adjacent (Up/Down/Left/Right) neighbor. <!-- Other than the issue solved, is this relevant to any other issues/existing PRs? --> ## References This work potentially touches on: #1000 #2398 and #4922 <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist * [x] Closes a component of #1000 (partially, comment), #4922 (partially, `SwapPanes` function is added but not hooked up, no detach functionality) * [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA * [x] 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 Its been a while since I've written C++ code, and it is my first time working on a Windows application. I hope that I have not made too many mistakes. Work currently done: - Add boilerplate/infrastructure for argument parsing, hotkeys, event handling - Adds the `MovePane` function that finds the focused pane, and then tries to find a pane that is visually adjacent to according to direction. - First pass at the `SwapPanes` function that swaps the tree location of two panes - First working version of helpers `_FindFocusAndNeighbor` and `_FindNeighborFromFocus` that search the tree for the currently focused pane, and then climbs back up the tree to try to find a sibling pane that is adjacent to it. - An `_IsAdjacent' function that tests whether two panes, given their relative offsets, are adjacent to each other according to the direction. Next steps: - Once working these functions (`_FindFocusAndNeighbor`, etc) could be utilized to also solve #2398 by updating the `NavigateFocus` function. - Do we want default hotkeys for the new actions? <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed At this point, compilation and manual testing of functionality (with hotkeys) by creating panes, adding distinguishers to each pane, and then swapping them around to confirm they went to the right location.
2021-07-22 14:53:03 +02:00
void _CloseChild(const bool closeFirst, const bool isDetaching);
Converts Dispatcher().RunAsync to WinRT Coroutines (#4051) <!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Summary of the Pull Request This PR turns all* instances of `Dispatcher().RunAsync` to WinRT coroutines 👌. This was good coding fodder to fill my plane ride ✈️. Enjoy your holidays everyone! *With the exception of three functions whose signatures cannot be changed due to inheritance and function overriding in `TermControlAutomationPeer` [`L44`](https://github.com/microsoft/terminal/blob/master/src/cascadia/TerminalControl/TermControlAutomationPeer.cpp#L44), [`L58`](https://github.com/microsoft/terminal/blob/master/src/cascadia/TerminalControl/TermControlAutomationPeer.cpp#L58), [`L72`](https://github.com/microsoft/terminal/blob/master/src/cascadia/TerminalControl/TermControlAutomationPeer.cpp#L72). <!-- Other than the issue solved, is this relevant to any other issues/existing PRs? --> ## References <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist * [x] Closes #3919 * [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA * [ ] Tests added/passed * [ ] Requires documentation to be updated * [x] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #3919 <!-- Provide a more detailed description of the PR, other things fixed or any additional comments/features here --> ## Detailed Description of the Pull Request / Additional comments My thought pattern here was to minimally disturb the existing code where possible. So where I could, I converted existing functions into coroutine using functions (like in the [core example](https://github.com/microsoft/terminal/issues/3919#issue-536598706)). For ~the most part~ all instances, I used the format where [`this` is accessed safely within a locked scope](https://github.com/microsoft/terminal/issues/3919#issuecomment-564730620). Some function signatures were changed to take objects by value instead of reference, so the coroutines don't crash when the objects are accessed past their original lifetime. The [copy](https://github.com/microsoft/terminal/blob/master/src/cascadia/TerminalApp/TerminalPage.cpp#L1132) and [paste](https://github.com/microsoft/terminal/blob/master/src/cascadia/TerminalApp/TerminalPage.cpp#L1170) event handler entry points were originally set to a high priority; however, the WinRT coroutines don't appear to support a priority scheme so this priority setting was not preserved in the translation. <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed Compiles and runs, and for every event with a clear trigger repro, I triggered it to ensure crashes weren't introduced.
2020-01-10 04:29:49 +01:00
winrt::fire_and_forget _CloseChildRoutine(const bool closeFirst);
Add the ability to interact with subtrees of panes (#11153) This commit adds the ability to interact with subtrees of panes. Have you ever thought that you don't have enough regression testing to do? Boy do I have the PR for you! This breaks all kinds of assumptions about what is or is not focused, largely complicated by the fact that a pane is not a proper control. I did my best to cover as many cases as I could, but I wouldn't be surprised if there are some things broken that I am unaware of. Done: - Add `parent` and `child` movement directions to move up and down the tree respectively - When a parent pane is selected it will have borders all around it in addition to any borders the children have. - Fix focus, swap, split, zoom, toggle orientation, resize, and move to all handle interacting with more than one pane. - Similarly the actions for font size changing, closing, read-only, clearing buffer, and changing color scheme will distribute to all children. - This technically leaves control focus on the original control in the focused subtree because panes aren't proper controls themselves. This is also used to make sure we go back down the same path with the `child` movement. - You can zoom a parent pane, and click between different zoomed sub-panes and it won't unzoom you until you use moveFocus or another action. This wasn't explicitly programmed behavior so it is probably buggy (I've quashed a couple at least). It is a natural consequence of showing multiple terminals and allowing you to focus a terminal and a parent separately, since changing the active pane directly does not unzoom. This also means there can be a disconnect between what pane is zoomed and what pane is active. ## Validation Steps Performed Tested focus movement, swapping, moving panes, and zooming. Closes #10733
2021-09-28 21:16:05 +02:00
void _Focus();
void _FocusFirstChild();
void _ControlConnectionStateChangedHandler(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& /*args*/);
void _ControlWarningBellHandler(winrt::Windows::Foundation::IInspectable const& sender,
winrt::Windows::Foundation::IInspectable const& e);
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
void _ControlGotFocusHandler(winrt::Windows::Foundation::IInspectable const& sender,
winrt::Windows::UI::Xaml::RoutedEventArgs const& e);
void _ControlLostFocusHandler(winrt::Windows::Foundation::IInspectable const& sender,
winrt::Windows::UI::Xaml::RoutedEventArgs const& e);
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
std::pair<float, float> _CalcChildrenSizes(const float fullSize) const;
SnapChildrenSizeResult _CalcSnappedChildrenSizes(const bool widthOrHeight, const float fullSize) const;
SnapSizeResult _CalcSnappedDimension(const bool widthOrHeight, const float dimension) const;
void _AdvanceSnappedDimension(const bool widthOrHeight, LayoutSizeNode& sizeNode) const;
winrt::Windows::Foundation::Size _GetMinSize() const;
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
LayoutSizeNode _CreateMinSizeTree(const bool widthOrHeight) const;
float _ClampSplitPosition(const bool widthOrHeight, const float requestedValue, const float totalSize) const;
Add the ability to split a pane and put the new pane first. (#11145) <!-- 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 directional modifiers for SplitState and convert those to the appropriate horizontal/vertical when splitting a pane. <!-- 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 #4340 * [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 "vertical" and "horizontal" splits were removed from `defaults.json`, but code was added to parse those as `right` and `down` respectively. It is also the case that if a user has a custom hotkey for `split: vertical` it will override the default for `split: right`. <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed Split the pane using each of the new directional movements
2021-09-15 22:14:57 +02:00
SplitState _convertAutomaticOrDirectionalSplitState(const winrt::Microsoft::Terminal::Settings::Model::SplitDirection& splitType) const;
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
Add the ability to split a pane and put the new pane first. (#11145) <!-- 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 directional modifiers for SplitState and convert those to the appropriate horizontal/vertical when splitting a pane. <!-- 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 #4340 * [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 "vertical" and "horizontal" splits were removed from `defaults.json`, but code was added to parse those as `right` and `down` respectively. It is also the case that if a user has a custom hotkey for `split: vertical` it will override the default for `split: right`. <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed Split the pane using each of the new directional movements
2021-09-15 22:14:57 +02:00
std::optional<winrt::Microsoft::Terminal::Settings::Model::SplitDirection> _preCalculateAutoSplit(const std::shared_ptr<Pane> target, const winrt::Windows::Foundation::Size parentSize) const;
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
// Function Description:
// - Returns true if the given direction can be used with the given split
// type.
// - This is used for pane resizing (which will need a pane separator
// that's perpendicular to the direction to be able to move the separator
// in that direction).
// - Also used for moving focus between panes, which again happens _across_ a separator.
// Arguments:
// - direction: The Direction to compare
Add the ability to split a pane and put the new pane first. (#11145) <!-- 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 directional modifiers for SplitState and convert those to the appropriate horizontal/vertical when splitting a pane. <!-- 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 #4340 * [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 "vertical" and "horizontal" splits were removed from `defaults.json`, but code was added to parse those as `right` and `down` respectively. It is also the case that if a user has a custom hotkey for `split: vertical` it will override the default for `split: right`. <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed Split the pane using each of the new directional movements
2021-09-15 22:14:57 +02:00
// - splitType: The SplitState to compare
// Return Value:
// - true iff the direction is perpendicular to the splitType. False for
Add the ability to split a pane and put the new pane first. (#11145) <!-- 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 directional modifiers for SplitState and convert those to the appropriate horizontal/vertical when splitting a pane. <!-- 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 #4340 * [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 "vertical" and "horizontal" splits were removed from `defaults.json`, but code was added to parse those as `right` and `down` respectively. It is also the case that if a user has a custom hotkey for `split: vertical` it will override the default for `split: right`. <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed Split the pane using each of the new directional movements
2021-09-15 22:14:57 +02:00
// SplitState::None.
template<typename T>
static constexpr bool DirectionMatchesSplit(const T& direction,
Add the ability to split a pane and put the new pane first. (#11145) <!-- 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 directional modifiers for SplitState and convert those to the appropriate horizontal/vertical when splitting a pane. <!-- 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 #4340 * [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 "vertical" and "horizontal" splits were removed from `defaults.json`, but code was added to parse those as `right` and `down` respectively. It is also the case that if a user has a custom hotkey for `split: vertical` it will override the default for `split: right`. <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed Split the pane using each of the new directional movements
2021-09-15 22:14:57 +02:00
const SplitState& splitType)
{
Add the ability to split a pane and put the new pane first. (#11145) <!-- 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 directional modifiers for SplitState and convert those to the appropriate horizontal/vertical when splitting a pane. <!-- 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 #4340 * [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 "vertical" and "horizontal" splits were removed from `defaults.json`, but code was added to parse those as `right` and `down` respectively. It is also the case that if a user has a custom hotkey for `split: vertical` it will override the default for `split: right`. <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed Split the pane using each of the new directional movements
2021-09-15 22:14:57 +02:00
if (splitType == SplitState::None)
{
return false;
}
Add the ability to split a pane and put the new pane first. (#11145) <!-- 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 directional modifiers for SplitState and convert those to the appropriate horizontal/vertical when splitting a pane. <!-- 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 #4340 * [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 "vertical" and "horizontal" splits were removed from `defaults.json`, but code was added to parse those as `right` and `down` respectively. It is also the case that if a user has a custom hotkey for `split: vertical` it will override the default for `split: right`. <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed Split the pane using each of the new directional movements
2021-09-15 22:14:57 +02:00
else if (splitType == SplitState::Horizontal)
{
return direction == T::Up ||
direction == T::Down;
}
Add the ability to split a pane and put the new pane first. (#11145) <!-- 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 directional modifiers for SplitState and convert those to the appropriate horizontal/vertical when splitting a pane. <!-- 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 #4340 * [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 "vertical" and "horizontal" splits were removed from `defaults.json`, but code was added to parse those as `right` and `down` respectively. It is also the case that if a user has a custom hotkey for `split: vertical` it will override the default for `split: right`. <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed Split the pane using each of the new directional movements
2021-09-15 22:14:57 +02:00
else if (splitType == SplitState::Vertical)
{
return direction == T::Left ||
direction == T::Right;
}
return 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
static void _SetupResources();
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
Preliminary work to add Swap Panes functionality (GH Issues 1000, 4922) (#10638) <!-- 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 swap a pane with an adjacent (Up/Down/Left/Right) neighbor. <!-- Other than the issue solved, is this relevant to any other issues/existing PRs? --> ## References This work potentially touches on: #1000 #2398 and #4922 <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist * [x] Closes a component of #1000 (partially, comment), #4922 (partially, `SwapPanes` function is added but not hooked up, no detach functionality) * [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA * [x] 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 Its been a while since I've written C++ code, and it is my first time working on a Windows application. I hope that I have not made too many mistakes. Work currently done: - Add boilerplate/infrastructure for argument parsing, hotkeys, event handling - Adds the `MovePane` function that finds the focused pane, and then tries to find a pane that is visually adjacent to according to direction. - First pass at the `SwapPanes` function that swaps the tree location of two panes - First working version of helpers `_FindFocusAndNeighbor` and `_FindNeighborFromFocus` that search the tree for the currently focused pane, and then climbs back up the tree to try to find a sibling pane that is adjacent to it. - An `_IsAdjacent' function that tests whether two panes, given their relative offsets, are adjacent to each other according to the direction. Next steps: - Once working these functions (`_FindFocusAndNeighbor`, etc) could be utilized to also solve #2398 by updating the `NavigateFocus` function. - Do we want default hotkeys for the new actions? <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed At this point, compilation and manual testing of functionality (with hotkeys) by creating panes, adding distinguishers to each pane, and then swapping them around to confirm they went to the right location.
2021-07-22 14:53:03 +02:00
struct PanePoint
{
float x;
float y;
float scaleX;
float scaleY;
Preliminary work to add Swap Panes functionality (GH Issues 1000, 4922) (#10638) <!-- 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 swap a pane with an adjacent (Up/Down/Left/Right) neighbor. <!-- Other than the issue solved, is this relevant to any other issues/existing PRs? --> ## References This work potentially touches on: #1000 #2398 and #4922 <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist * [x] Closes a component of #1000 (partially, comment), #4922 (partially, `SwapPanes` function is added but not hooked up, no detach functionality) * [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA * [x] 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 Its been a while since I've written C++ code, and it is my first time working on a Windows application. I hope that I have not made too many mistakes. Work currently done: - Add boilerplate/infrastructure for argument parsing, hotkeys, event handling - Adds the `MovePane` function that finds the focused pane, and then tries to find a pane that is visually adjacent to according to direction. - First pass at the `SwapPanes` function that swaps the tree location of two panes - First working version of helpers `_FindFocusAndNeighbor` and `_FindNeighborFromFocus` that search the tree for the currently focused pane, and then climbs back up the tree to try to find a sibling pane that is adjacent to it. - An `_IsAdjacent' function that tests whether two panes, given their relative offsets, are adjacent to each other according to the direction. Next steps: - Once working these functions (`_FindFocusAndNeighbor`, etc) could be utilized to also solve #2398 by updating the `NavigateFocus` function. - Do we want default hotkeys for the new actions? <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed At this point, compilation and manual testing of functionality (with hotkeys) by creating panes, adding distinguishers to each pane, and then swapping them around to confirm they went to the right location.
2021-07-22 14:53:03 +02:00
};
struct PaneNeighborSearch
Preliminary work to add Swap Panes functionality (GH Issues 1000, 4922) (#10638) <!-- 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 swap a pane with an adjacent (Up/Down/Left/Right) neighbor. <!-- Other than the issue solved, is this relevant to any other issues/existing PRs? --> ## References This work potentially touches on: #1000 #2398 and #4922 <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist * [x] Closes a component of #1000 (partially, comment), #4922 (partially, `SwapPanes` function is added but not hooked up, no detach functionality) * [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA * [x] 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 Its been a while since I've written C++ code, and it is my first time working on a Windows application. I hope that I have not made too many mistakes. Work currently done: - Add boilerplate/infrastructure for argument parsing, hotkeys, event handling - Adds the `MovePane` function that finds the focused pane, and then tries to find a pane that is visually adjacent to according to direction. - First pass at the `SwapPanes` function that swaps the tree location of two panes - First working version of helpers `_FindFocusAndNeighbor` and `_FindNeighborFromFocus` that search the tree for the currently focused pane, and then climbs back up the tree to try to find a sibling pane that is adjacent to it. - An `_IsAdjacent' function that tests whether two panes, given their relative offsets, are adjacent to each other according to the direction. Next steps: - Once working these functions (`_FindFocusAndNeighbor`, etc) could be utilized to also solve #2398 by updating the `NavigateFocus` function. - Do we want default hotkeys for the new actions? <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed At this point, compilation and manual testing of functionality (with hotkeys) by creating panes, adding distinguishers to each pane, and then swapping them around to confirm they went to the right location.
2021-07-22 14:53:03 +02:00
{
std::shared_ptr<Pane> source;
Preliminary work to add Swap Panes functionality (GH Issues 1000, 4922) (#10638) <!-- 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 swap a pane with an adjacent (Up/Down/Left/Right) neighbor. <!-- Other than the issue solved, is this relevant to any other issues/existing PRs? --> ## References This work potentially touches on: #1000 #2398 and #4922 <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist * [x] Closes a component of #1000 (partially, comment), #4922 (partially, `SwapPanes` function is added but not hooked up, no detach functionality) * [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA * [x] 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 Its been a while since I've written C++ code, and it is my first time working on a Windows application. I hope that I have not made too many mistakes. Work currently done: - Add boilerplate/infrastructure for argument parsing, hotkeys, event handling - Adds the `MovePane` function that finds the focused pane, and then tries to find a pane that is visually adjacent to according to direction. - First pass at the `SwapPanes` function that swaps the tree location of two panes - First working version of helpers `_FindFocusAndNeighbor` and `_FindNeighborFromFocus` that search the tree for the currently focused pane, and then climbs back up the tree to try to find a sibling pane that is adjacent to it. - An `_IsAdjacent' function that tests whether two panes, given their relative offsets, are adjacent to each other according to the direction. Next steps: - Once working these functions (`_FindFocusAndNeighbor`, etc) could be utilized to also solve #2398 by updating the `NavigateFocus` function. - Do we want default hotkeys for the new actions? <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed At this point, compilation and manual testing of functionality (with hotkeys) by creating panes, adding distinguishers to each pane, and then swapping them around to confirm they went to the right location.
2021-07-22 14:53:03 +02:00
std::shared_ptr<Pane> neighbor;
PanePoint sourceOffset;
Preliminary work to add Swap Panes functionality (GH Issues 1000, 4922) (#10638) <!-- 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 swap a pane with an adjacent (Up/Down/Left/Right) neighbor. <!-- Other than the issue solved, is this relevant to any other issues/existing PRs? --> ## References This work potentially touches on: #1000 #2398 and #4922 <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist * [x] Closes a component of #1000 (partially, comment), #4922 (partially, `SwapPanes` function is added but not hooked up, no detach functionality) * [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA * [x] 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 Its been a while since I've written C++ code, and it is my first time working on a Windows application. I hope that I have not made too many mistakes. Work currently done: - Add boilerplate/infrastructure for argument parsing, hotkeys, event handling - Adds the `MovePane` function that finds the focused pane, and then tries to find a pane that is visually adjacent to according to direction. - First pass at the `SwapPanes` function that swaps the tree location of two panes - First working version of helpers `_FindFocusAndNeighbor` and `_FindNeighborFromFocus` that search the tree for the currently focused pane, and then climbs back up the tree to try to find a sibling pane that is adjacent to it. - An `_IsAdjacent' function that tests whether two panes, given their relative offsets, are adjacent to each other according to the direction. Next steps: - Once working these functions (`_FindFocusAndNeighbor`, etc) could be utilized to also solve #2398 by updating the `NavigateFocus` function. - Do we want default hotkeys for the new actions? <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed At this point, compilation and manual testing of functionality (with hotkeys) by creating panes, adding distinguishers to each pane, and then swapping them around to confirm they went to the right location.
2021-07-22 14:53:03 +02:00
};
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
struct SnapSizeResult
{
float lower;
float higher;
};
struct SnapChildrenSizeResult
{
std::pair<float, float> lower;
std::pair<float, float> higher;
};
// Helper structure that builds a (roughly) binary tree corresponding
// to the pane tree. Used for laying out panes with snapped sizes.
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
struct LayoutSizeNode
{
float size;
bool isMinimumSize;
std::unique_ptr<LayoutSizeNode> firstChild;
std::unique_ptr<LayoutSizeNode> secondChild;
// These two fields hold next possible snapped values of firstChild and
// secondChild. Although that could be calculated from these fields themselves,
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
// it would be wasteful as we have to know these values more often than for
// simple increment. Hence we cache that here.
std::unique_ptr<LayoutSizeNode> nextFirstChild;
std::unique_ptr<LayoutSizeNode> nextSecondChild;
explicit LayoutSizeNode(const float minSize);
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
LayoutSizeNode(const LayoutSizeNode& other);
LayoutSizeNode& operator=(const LayoutSizeNode& other);
private:
void _AssignChildNode(std::unique_ptr<LayoutSizeNode>& nodeField, const LayoutSizeNode* const newNode);
};
Preliminary work to add Swap Panes functionality (GH Issues 1000, 4922) (#10638) <!-- 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 swap a pane with an adjacent (Up/Down/Left/Right) neighbor. <!-- Other than the issue solved, is this relevant to any other issues/existing PRs? --> ## References This work potentially touches on: #1000 #2398 and #4922 <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist * [x] Closes a component of #1000 (partially, comment), #4922 (partially, `SwapPanes` function is added but not hooked up, no detach functionality) * [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA * [x] 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 Its been a while since I've written C++ code, and it is my first time working on a Windows application. I hope that I have not made too many mistakes. Work currently done: - Add boilerplate/infrastructure for argument parsing, hotkeys, event handling - Adds the `MovePane` function that finds the focused pane, and then tries to find a pane that is visually adjacent to according to direction. - First pass at the `SwapPanes` function that swaps the tree location of two panes - First working version of helpers `_FindFocusAndNeighbor` and `_FindNeighborFromFocus` that search the tree for the currently focused pane, and then climbs back up the tree to try to find a sibling pane that is adjacent to it. - An `_IsAdjacent' function that tests whether two panes, given their relative offsets, are adjacent to each other according to the direction. Next steps: - Once working these functions (`_FindFocusAndNeighbor`, etc) could be utilized to also solve #2398 by updating the `NavigateFocus` function. - Do we want default hotkeys for the new actions? <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed At this point, compilation and manual testing of functionality (with hotkeys) by creating panes, adding distinguishers to each pane, and then swapping them around to confirm they went to the right location.
2021-07-22 14:53:03 +02:00
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
friend struct winrt::TerminalApp::implementation::TerminalTab;
Preliminary work to add Swap Panes functionality (GH Issues 1000, 4922) (#10638) <!-- 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 swap a pane with an adjacent (Up/Down/Left/Right) neighbor. <!-- Other than the issue solved, is this relevant to any other issues/existing PRs? --> ## References This work potentially touches on: #1000 #2398 and #4922 <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist * [x] Closes a component of #1000 (partially, comment), #4922 (partially, `SwapPanes` function is added but not hooked up, no detach functionality) * [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA * [x] 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 Its been a while since I've written C++ code, and it is my first time working on a Windows application. I hope that I have not made too many mistakes. Work currently done: - Add boilerplate/infrastructure for argument parsing, hotkeys, event handling - Adds the `MovePane` function that finds the focused pane, and then tries to find a pane that is visually adjacent to according to direction. - First pass at the `SwapPanes` function that swaps the tree location of two panes - First working version of helpers `_FindFocusAndNeighbor` and `_FindNeighborFromFocus` that search the tree for the currently focused pane, and then climbs back up the tree to try to find a sibling pane that is adjacent to it. - An `_IsAdjacent' function that tests whether two panes, given their relative offsets, are adjacent to each other according to the direction. Next steps: - Once working these functions (`_FindFocusAndNeighbor`, etc) could be utilized to also solve #2398 by updating the `NavigateFocus` function. - Do we want default hotkeys for the new actions? <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed At this point, compilation and manual testing of functionality (with hotkeys) by creating panes, adding distinguishers to each pane, and then swapping them around to confirm they went to the right location.
2021-07-22 14:53:03 +02:00
friend class ::TerminalAppLocalTests::TabTests;
};