From 06794aac905c0d7b63b42bd9ffcb21a265b8d5e0 Mon Sep 17 00:00:00 2001 From: AnuthaDev Date: Fri, 19 Jun 2020 00:57:12 +0530 Subject: [PATCH 001/266] mobile attempt --- .github/actions/spell-check/expect/expect.txt | 1 + .../TerminalApp/MinMaxCloseControl.cpp | 9 ++++++ .../TerminalApp/MinMaxCloseControl.xaml | 12 ++++++++ src/cascadia/TerminalApp/TitlebarControl.idl | 4 ++- .../WindowsTerminal/NonClientIslandWindow.cpp | 30 +++++++++++++++++++ .../WindowsTerminal/NonClientIslandWindow.h | 2 ++ 6 files changed, 57 insertions(+), 1 deletion(-) diff --git a/.github/actions/spell-check/expect/expect.txt b/.github/actions/spell-check/expect/expect.txt index 01b64c42d78..276d9778fae 100644 --- a/.github/actions/spell-check/expect/expect.txt +++ b/.github/actions/spell-check/expect/expect.txt @@ -1457,6 +1457,7 @@ natvis naws nbsp Nc +NCACTIVATE NCCALCSIZE NCCREATE NCLBUTTONDOWN diff --git a/src/cascadia/TerminalApp/MinMaxCloseControl.cpp b/src/cascadia/TerminalApp/MinMaxCloseControl.cpp index ee5f3e0d9b7..9eda3f8f143 100644 --- a/src/cascadia/TerminalApp/MinMaxCloseControl.cpp +++ b/src/cascadia/TerminalApp/MinMaxCloseControl.cpp @@ -78,11 +78,20 @@ namespace winrt::TerminalApp::implementation MaximizeButton().Height(maximizedHeight); CloseButton().Height(maximizedHeight); break; + case WindowVisualState::WindowVisualStateUnfocused: + VisualStateManager::GoToState(MaximizeButton(), L"WindowStateUnfocused", false); + VisualStateManager::GoToState(MinimizeButton(), L"WindowStateUnfocused", false); + VisualStateManager::GoToState(CloseButton(), L"WindowStateUnfocused", false); + break; + case WindowVisualState::WindowVisualStateFocused: case WindowVisualState::WindowVisualStateNormal: case WindowVisualState::WindowVisualStateIconified: default: VisualStateManager::GoToState(MaximizeButton(), L"WindowStateNormal", false); + VisualStateManager::GoToState(MaximizeButton(), L"WindowStateFocused", false); + VisualStateManager::GoToState(MinimizeButton(), L"WindowStateFocused", false); + VisualStateManager::GoToState(CloseButton(), L"WindowStateFocused", false); MinimizeButton().Height(windowedHeight); MaximizeButton().Height(windowedHeight); diff --git a/src/cascadia/TerminalApp/MinMaxCloseControl.xaml b/src/cascadia/TerminalApp/MinMaxCloseControl.xaml index 701c8720935..a9ce3e321ad 100644 --- a/src/cascadia/TerminalApp/MinMaxCloseControl.xaml +++ b/src/cascadia/TerminalApp/MinMaxCloseControl.xaml @@ -25,6 +25,7 @@ the MIT License. See LICENSE in the project root for license information. --> + @@ -38,6 +39,7 @@ the MIT License. See LICENSE in the project root for license information. --> + @@ -125,6 +127,16 @@ the MIT License. See LICENSE in the project root for license information. --> + + + + + + + + + + diff --git a/src/cascadia/TerminalApp/TitlebarControl.idl b/src/cascadia/TerminalApp/TitlebarControl.idl index 104f7a2f26f..e0c522e3427 100644 --- a/src/cascadia/TerminalApp/TitlebarControl.idl +++ b/src/cascadia/TerminalApp/TitlebarControl.idl @@ -7,7 +7,9 @@ namespace TerminalApp { WindowVisualStateNormal = 0, WindowVisualStateMaximized, - WindowVisualStateIconified + WindowVisualStateIconified, + WindowVisualStateFocused, + WindowVisualStateUnfocused }; [default_interface] runtimeclass TitlebarControl : Windows.UI.Xaml.Controls.Grid diff --git a/src/cascadia/WindowsTerminal/NonClientIslandWindow.cpp b/src/cascadia/WindowsTerminal/NonClientIslandWindow.cpp index d8e67e7dec7..03531d29971 100644 --- a/src/cascadia/WindowsTerminal/NonClientIslandWindow.cpp +++ b/src/cascadia/WindowsTerminal/NonClientIslandWindow.cpp @@ -516,6 +516,34 @@ int NonClientIslandWindow::_GetResizeHandleHeight() const noexcept return 0; } +// Method Description: +// - Responds to the WM_NCACTIVATE message by changing the focus state of +// the window. +[[nodiscard]] LRESULT NonClientIslandWindow::_OnFocusChanged(const WPARAM wParam, const LPARAM lParam) noexcept +{ + const auto windowStyle = GetWindowStyle(_window.get()); + const auto isIconified = WI_IsFlagSet(windowStyle, WS_ICONIC); + + if (isIconified) + { + return DefWindowProc(_window.get(), WM_NCACTIVATE, wParam, lParam); + } + + if (_titlebar) + { + _isFocused = wParam; + const auto state = _isFocused ? winrt::TerminalApp::WindowVisualState::WindowVisualStateFocused : + winrt::TerminalApp::WindowVisualState::WindowVisualStateUnfocused; + try + { + _titlebar.SetWindowVisualState(state); + } + CATCH_LOG(); + } + + return TRUE; +} + // Method Description: // - Hit test the frame for resizing and moving. // Arguments: @@ -689,6 +717,8 @@ void NonClientIslandWindow::_UpdateFrameMargins() const noexcept return 0; case WM_NCCALCSIZE: return _OnNcCalcSize(wParam, lParam); + case WM_NCACTIVATE: + return _OnFocusChanged(wParam, lParam); case WM_NCHITTEST: return _OnNcHitTest({ GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }); case WM_PAINT: diff --git a/src/cascadia/WindowsTerminal/NonClientIslandWindow.h b/src/cascadia/WindowsTerminal/NonClientIslandWindow.h index 10a39b4fcb1..b510611f106 100644 --- a/src/cascadia/WindowsTerminal/NonClientIslandWindow.h +++ b/src/cascadia/WindowsTerminal/NonClientIslandWindow.h @@ -61,6 +61,7 @@ class NonClientIslandWindow : public IslandWindow winrt::Windows::UI::Xaml::ElementTheme _theme; bool _isMaximized; + bool _isFocused; [[nodiscard]] static LRESULT __stdcall _StaticInputSinkWndProc(HWND const window, UINT const message, WPARAM const wparam, LPARAM const lparam) noexcept; [[nodiscard]] LRESULT _InputSinkMessageHandler(UINT const message, WPARAM const wparam, LPARAM const lparam) noexcept; @@ -73,6 +74,7 @@ class NonClientIslandWindow : public IslandWindow [[nodiscard]] LRESULT _OnNcCreate(WPARAM wParam, LPARAM lParam) noexcept override; [[nodiscard]] LRESULT _OnNcCalcSize(const WPARAM wParam, const LPARAM lParam) noexcept; + [[nodiscard]] LRESULT _OnFocusChanged(const WPARAM wParam, const LPARAM lParam) noexcept; [[nodiscard]] LRESULT _OnNcHitTest(POINT ptMouse) const noexcept; [[nodiscard]] LRESULT _OnPaint() noexcept; [[nodiscard]] LRESULT _OnSetCursor(WPARAM wParam, LPARAM lParam) const noexcept; From ab4ff28d1385b1cc1c887f3069537465382ebc05 Mon Sep 17 00:00:00 2001 From: AnuthaDev Date: Wed, 24 Jun 2020 22:14:40 +0530 Subject: [PATCH 002/266] shouldwork --- src/cascadia/TerminalApp/MinMaxCloseControl.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/cascadia/TerminalApp/MinMaxCloseControl.cpp b/src/cascadia/TerminalApp/MinMaxCloseControl.cpp index 9eda3f8f143..1bc8b58d35b 100644 --- a/src/cascadia/TerminalApp/MinMaxCloseControl.cpp +++ b/src/cascadia/TerminalApp/MinMaxCloseControl.cpp @@ -85,13 +85,15 @@ namespace winrt::TerminalApp::implementation break; case WindowVisualState::WindowVisualStateFocused: + VisualStateManager::GoToState(MaximizeButton(), L"WindowStateFocused", false); + VisualStateManager::GoToState(MinimizeButton(), L"WindowStateFocused", false); + VisualStateManager::GoToState(CloseButton(), L"WindowStateFocused", false); + break; + case WindowVisualState::WindowVisualStateNormal: case WindowVisualState::WindowVisualStateIconified: default: VisualStateManager::GoToState(MaximizeButton(), L"WindowStateNormal", false); - VisualStateManager::GoToState(MaximizeButton(), L"WindowStateFocused", false); - VisualStateManager::GoToState(MinimizeButton(), L"WindowStateFocused", false); - VisualStateManager::GoToState(CloseButton(), L"WindowStateFocused", false); MinimizeButton().Height(windowedHeight); MaximizeButton().Height(windowedHeight); From 91e9da25c913e15cf4f7d37db1c824982868fb5f Mon Sep 17 00:00:00 2001 From: AnuthaDev Date: Thu, 23 Jul 2020 00:16:20 +0530 Subject: [PATCH 003/266] added fixes --- src/cascadia/TerminalApp/MinMaxCloseControl.cpp | 1 + src/cascadia/TerminalApp/MinMaxCloseControl.xaml | 5 +++-- src/cascadia/TerminalApp/TitlebarControl.cpp | 7 +++++++ src/cascadia/TerminalApp/TitlebarControl.h | 3 +++ src/cascadia/TerminalApp/TitlebarControl.idl | 6 +++--- src/cascadia/WindowsTerminal/NonClientIslandWindow.cpp | 4 +--- 6 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/cascadia/TerminalApp/MinMaxCloseControl.cpp b/src/cascadia/TerminalApp/MinMaxCloseControl.cpp index 1bc8b58d35b..cf145bbe917 100644 --- a/src/cascadia/TerminalApp/MinMaxCloseControl.cpp +++ b/src/cascadia/TerminalApp/MinMaxCloseControl.cpp @@ -78,6 +78,7 @@ namespace winrt::TerminalApp::implementation MaximizeButton().Height(maximizedHeight); CloseButton().Height(maximizedHeight); break; + case WindowVisualState::WindowVisualStateUnfocused: VisualStateManager::GoToState(MaximizeButton(), L"WindowStateUnfocused", false); VisualStateManager::GoToState(MinimizeButton(), L"WindowStateUnfocused", false); diff --git a/src/cascadia/TerminalApp/MinMaxCloseControl.xaml b/src/cascadia/TerminalApp/MinMaxCloseControl.xaml index a9ce3e321ad..edd21725ceb 100644 --- a/src/cascadia/TerminalApp/MinMaxCloseControl.xaml +++ b/src/cascadia/TerminalApp/MinMaxCloseControl.xaml @@ -22,10 +22,10 @@ the MIT License. See LICENSE in the project root for license information. --> + - @@ -36,10 +36,10 @@ the MIT License. See LICENSE in the project root for license information. --> + - @@ -51,6 +51,7 @@ the MIT License. See LICENSE in the project root for license information. --> + diff --git a/src/cascadia/TerminalApp/TitlebarControl.cpp b/src/cascadia/TerminalApp/TitlebarControl.cpp index 05806726cfe..4c31950669a 100644 --- a/src/cascadia/TerminalApp/TitlebarControl.cpp +++ b/src/cascadia/TerminalApp/TitlebarControl.cpp @@ -66,6 +66,13 @@ namespace winrt::TerminalApp::implementation } } + void TitlebarControl::Focused(bool focused) + { + const auto state = focused ? winrt::TerminalApp::WindowVisualState::WindowVisualStateFocused : + winrt::TerminalApp::WindowVisualState::WindowVisualStateUnfocused; + MinMaxCloseControl().SetWindowVisualState(state); + } + void TitlebarControl::Maximize_Click(winrt::Windows::Foundation::IInspectable const& /*sender*/, winrt::Windows::UI::Xaml::RoutedEventArgs const& /*e*/) { _OnMaximizeOrRestore(HTMAXBUTTON); diff --git a/src/cascadia/TerminalApp/TitlebarControl.h b/src/cascadia/TerminalApp/TitlebarControl.h index a30f347d868..0790c823617 100644 --- a/src/cascadia/TerminalApp/TitlebarControl.h +++ b/src/cascadia/TerminalApp/TitlebarControl.h @@ -17,6 +17,9 @@ namespace winrt::TerminalApp::implementation { TitlebarControl(uint64_t handle); + bool Focused() const; + void Focused(bool focused); + IInspectable Content(); void Content(IInspectable content); diff --git a/src/cascadia/TerminalApp/TitlebarControl.idl b/src/cascadia/TerminalApp/TitlebarControl.idl index e0c522e3427..5f1612cb153 100644 --- a/src/cascadia/TerminalApp/TitlebarControl.idl +++ b/src/cascadia/TerminalApp/TitlebarControl.idl @@ -7,9 +7,7 @@ namespace TerminalApp { WindowVisualStateNormal = 0, WindowVisualStateMaximized, - WindowVisualStateIconified, - WindowVisualStateFocused, - WindowVisualStateUnfocused + WindowVisualStateIconified }; [default_interface] runtimeclass TitlebarControl : Windows.UI.Xaml.Controls.Grid @@ -17,6 +15,8 @@ namespace TerminalApp TitlebarControl(UInt64 parentWindowHandle); void SetWindowVisualState(WindowVisualState visualState); + Boolean Focused { get; set; }; + IInspectable Content; Windows.UI.Xaml.Controls.Border DragBar { get; }; } diff --git a/src/cascadia/WindowsTerminal/NonClientIslandWindow.cpp b/src/cascadia/WindowsTerminal/NonClientIslandWindow.cpp index 03531d29971..595a16ae28c 100644 --- a/src/cascadia/WindowsTerminal/NonClientIslandWindow.cpp +++ b/src/cascadia/WindowsTerminal/NonClientIslandWindow.cpp @@ -532,11 +532,9 @@ int NonClientIslandWindow::_GetResizeHandleHeight() const noexcept if (_titlebar) { _isFocused = wParam; - const auto state = _isFocused ? winrt::TerminalApp::WindowVisualState::WindowVisualStateFocused : - winrt::TerminalApp::WindowVisualState::WindowVisualStateUnfocused; try { - _titlebar.SetWindowVisualState(state); + _titlebar.Focused(_isFocused); } CATCH_LOG(); } From 8ceae9aaf77655bd0a52573d5323008c5ec27271 Mon Sep 17 00:00:00 2001 From: AnuthaDev Date: Thu, 23 Jul 2020 00:46:46 +0530 Subject: [PATCH 004/266] final fix --- src/cascadia/TerminalApp/TitlebarControl.h | 4 ++-- src/cascadia/TerminalApp/TitlebarControl.idl | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/cascadia/TerminalApp/TitlebarControl.h b/src/cascadia/TerminalApp/TitlebarControl.h index 0790c823617..65778d70910 100644 --- a/src/cascadia/TerminalApp/TitlebarControl.h +++ b/src/cascadia/TerminalApp/TitlebarControl.h @@ -17,8 +17,8 @@ namespace winrt::TerminalApp::implementation { TitlebarControl(uint64_t handle); - bool Focused() const; - void Focused(bool focused); + bool Focused() const; + void Focused(bool focused); IInspectable Content(); void Content(IInspectable content); diff --git a/src/cascadia/TerminalApp/TitlebarControl.idl b/src/cascadia/TerminalApp/TitlebarControl.idl index 5f1612cb153..0b2d43dcf98 100644 --- a/src/cascadia/TerminalApp/TitlebarControl.idl +++ b/src/cascadia/TerminalApp/TitlebarControl.idl @@ -7,7 +7,9 @@ namespace TerminalApp { WindowVisualStateNormal = 0, WindowVisualStateMaximized, - WindowVisualStateIconified + WindowVisualStateIconified, + WindowVisualStateFocused, + WindowVisualStateUnfocused }; [default_interface] runtimeclass TitlebarControl : Windows.UI.Xaml.Controls.Grid From 878ed57db63f973b4229bd5a5d478d298a3459d6 Mon Sep 17 00:00:00 2001 From: Dustin Howett Date: Wed, 22 Jul 2020 23:29:15 +0000 Subject: [PATCH 005/266] Merged PR 4947060: Migrate OS delayload changes [Git2Git] Git Train: Merge of building/rs_onecore_dep_uxp/200720-1445 into official/rs_onecore_dep_uxp Retrieved from https://microsoft.visualstudio.com os.2020 OS official/rs_onecore_dep_uxp 5e1509a00f1acdefe1e6392468ffc9ae44dc89cb Related work items: MSFT:25731998 --- src/host/sources.inc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/host/sources.inc b/src/host/sources.inc index fae931ef24f..e8aa074e88e 100644 --- a/src/host/sources.inc +++ b/src/host/sources.inc @@ -200,13 +200,16 @@ TARGETLIBS = \ $(WINCORE_OBJ_PATH)\console\open\src\types\lib\$(O)\ConTypes.lib \ DELAYLOAD = \ - PROPSYS.dll; \ D2D1.dll; \ + D3D11.dll; \ DWrite.dll; \ DXGI.dll; \ - D3D11.dll; \ OLEAUT32.dll; \ + PROPSYS.dll; \ + api-ms-win-core-com-l1.dll; \ + api-ms-win-core-registry-l2.dll; \ api-ms-win-mm-playsound-l1.dll; \ + api-ms-win-shcore-obsolete-l1.dll; \ api-ms-win-shcore-scaling-l1.dll; \ api-ms-win-shell-namespace-l1.dll; \ ext-ms-win-dwmapi-ext-l1.dll; \ From f486a6504c060af3f505a79259dec41a4e17b78c Mon Sep 17 00:00:00 2001 From: Javier Date: Thu, 30 Jul 2020 11:55:07 -0500 Subject: [PATCH 006/266] Expose text selection through terminal WPF control API (#7121) We've been trying to improve the copy/paste experience with the terminal in Visual Studio. Once of our problematic scenarios is when the terminal is connected to a remote environment and the user attempts to copy/paste. This gets forwarded to the remote shell that copy/paste into the remote clipboard instead of the local one. So we opted to add ctrl+shift+c/v to the terminal and need access to the selected text via the terminal control VALIDATION Tested with Visual Studio integrated terminal --- .../WpfTerminalControl/TerminalContainer.cs | 14 ++++++++++++++ .../WpfTerminalControl/TerminalControl.xaml.cs | 9 +++++++++ 2 files changed, 23 insertions(+) diff --git a/src/cascadia/WpfTerminalControl/TerminalContainer.cs b/src/cascadia/WpfTerminalControl/TerminalContainer.cs index cf1db1d4019..86549a9e05c 100644 --- a/src/cascadia/WpfTerminalControl/TerminalContainer.cs +++ b/src/cascadia/WpfTerminalControl/TerminalContainer.cs @@ -124,6 +124,20 @@ internal void SetTheme(TerminalTheme theme, string fontFamily, short fontSize) this.TriggerResize(this.RenderSize); } + /// + /// Gets the selected text from the terminal renderer and clears the selection. + /// + /// The selected text, empty if no text is selected. + internal string GetSelectedText() + { + if (NativeMethods.TerminalIsSelectionActive(this.terminal)) + { + return NativeMethods.TerminalGetSelection(this.terminal); + } + + return string.Empty; + } + /// /// Triggers a refresh of the terminal with the given size. /// diff --git a/src/cascadia/WpfTerminalControl/TerminalControl.xaml.cs b/src/cascadia/WpfTerminalControl/TerminalControl.xaml.cs index f068d0edfd3..ef8f6b30ae0 100644 --- a/src/cascadia/WpfTerminalControl/TerminalControl.xaml.cs +++ b/src/cascadia/WpfTerminalControl/TerminalControl.xaml.cs @@ -70,6 +70,15 @@ public void SetTheme(TerminalTheme theme, string fontFamily, short fontSize) this.termContainer.SetTheme(theme, fontFamily, fontSize); } + /// + /// Gets the selected text in the terminal, clearing the selection. Otherwise returns an empty string. + /// + /// Selected text, empty string if no content is selected. + public string GetSelectedText() + { + return this.termContainer.GetSelectedText(); + } + /// /// Resizes the terminal to the specified rows and columns. /// From bf90869f300791fce98f39287bedecbfbec8a3ab Mon Sep 17 00:00:00 2001 From: PankajBhojwani Date: Thu, 30 Jul 2020 14:58:28 -0400 Subject: [PATCH 007/266] Fixed window title not updating with tab rename (#7119) * Fixed window title not updating with tab rename * pass the correct title to event handler instead --- src/cascadia/TerminalApp/TerminalPage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index 81cfaf1735c..8fc907ca89f 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -1795,7 +1795,7 @@ namespace winrt::TerminalApp::implementation tab->SetFocused(true); // Raise an event that our title changed - _titleChangeHandlers(*this, Title()); + _titleChangeHandlers(*this, tab->GetActiveTitle()); // Raise an event that our titlebar color changed std::optional color = tab->GetTabColor(); From 2f5ba9471da3580db86c41555bd5f63bdeedaabf Mon Sep 17 00:00:00 2001 From: PankajBhojwani Date: Thu, 30 Jul 2020 18:24:59 -0400 Subject: [PATCH 008/266] Implement SetCursorColor in Terminal (#7123) This was never hooked up to the TerminalCore implementation. Closes #7102 --- src/cascadia/TerminalCore/ITerminalApi.hpp | 1 + src/cascadia/TerminalCore/Terminal.hpp | 1 + src/cascadia/TerminalCore/TerminalApi.cpp | 8 ++++++++ src/cascadia/TerminalCore/TerminalDispatch.cpp | 7 +++++++ src/cascadia/TerminalCore/TerminalDispatch.hpp | 1 + 5 files changed, 18 insertions(+) diff --git a/src/cascadia/TerminalCore/ITerminalApi.hpp b/src/cascadia/TerminalCore/ITerminalApi.hpp index d92a536c9d6..98945de1cfe 100644 --- a/src/cascadia/TerminalCore/ITerminalApi.hpp +++ b/src/cascadia/TerminalCore/ITerminalApi.hpp @@ -39,6 +39,7 @@ namespace Microsoft::Terminal::Core virtual bool SetColorTableEntry(const size_t tableIndex, const DWORD color) noexcept = 0; virtual bool SetCursorStyle(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::CursorStyle cursorStyle) noexcept = 0; + virtual bool SetCursorColor(const DWORD color) noexcept = 0; virtual bool SetDefaultForeground(const DWORD color) noexcept = 0; virtual bool SetDefaultBackground(const DWORD color) noexcept = 0; diff --git a/src/cascadia/TerminalCore/Terminal.hpp b/src/cascadia/TerminalCore/Terminal.hpp index 64232ef963d..ac8d59d3e02 100644 --- a/src/cascadia/TerminalCore/Terminal.hpp +++ b/src/cascadia/TerminalCore/Terminal.hpp @@ -93,6 +93,7 @@ class Microsoft::Terminal::Core::Terminal final : bool SetWindowTitle(std::wstring_view title) noexcept override; bool SetColorTableEntry(const size_t tableIndex, const COLORREF color) noexcept override; bool SetCursorStyle(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::CursorStyle cursorStyle) noexcept override; + bool SetCursorColor(const COLORREF color) noexcept override; bool SetDefaultForeground(const COLORREF color) noexcept override; bool SetDefaultBackground(const COLORREF color) noexcept override; diff --git a/src/cascadia/TerminalCore/TerminalApi.cpp b/src/cascadia/TerminalCore/TerminalApi.cpp index 4c7f27a88ea..1e27a59702c 100644 --- a/src/cascadia/TerminalCore/TerminalApi.cpp +++ b/src/cascadia/TerminalCore/TerminalApi.cpp @@ -64,6 +64,14 @@ COORD Terminal::GetCursorPosition() noexcept return newPos; } +bool Terminal::SetCursorColor(const COLORREF color) noexcept +try +{ + _buffer->GetCursor().SetColor(color); + return true; +} +CATCH_LOG_RETURN_FALSE() + // Method Description: // - Moves the cursor down one line, and possibly also to the leftmost column. // Arguments: diff --git a/src/cascadia/TerminalCore/TerminalDispatch.cpp b/src/cascadia/TerminalCore/TerminalDispatch.cpp index cf79384f70c..f119cc266c7 100644 --- a/src/cascadia/TerminalCore/TerminalDispatch.cpp +++ b/src/cascadia/TerminalCore/TerminalDispatch.cpp @@ -146,6 +146,13 @@ try } CATCH_LOG_RETURN_FALSE() +bool TerminalDispatch::SetCursorColor(const DWORD color) noexcept +try +{ + return _terminalApi.SetCursorColor(color); +} +CATCH_LOG_RETURN_FALSE() + bool TerminalDispatch::SetClipboard(std::wstring_view content) noexcept try { diff --git a/src/cascadia/TerminalCore/TerminalDispatch.hpp b/src/cascadia/TerminalCore/TerminalDispatch.hpp index 640f8eb242f..4f3dc8e7371 100644 --- a/src/cascadia/TerminalCore/TerminalDispatch.hpp +++ b/src/cascadia/TerminalCore/TerminalDispatch.hpp @@ -35,6 +35,7 @@ class TerminalDispatch : public Microsoft::Console::VirtualTerminal::TermDispatc bool SetColorTableEntry(const size_t tableIndex, const DWORD color) noexcept override; bool SetCursorStyle(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::CursorStyle cursorStyle) noexcept override; + bool SetCursorColor(const DWORD color) noexcept override; bool SetClipboard(std::wstring_view content) noexcept override; From 6ee8099a2c92b99b87d5062e06835a9b3d75f183 Mon Sep 17 00:00:00 2001 From: James Holderness Date: Thu, 30 Jul 2020 23:43:37 +0100 Subject: [PATCH 009/266] Refactor grid line renderers with support for more line types (#7107) This is a refactoring of the grid line renderers, adjusting the line widths to scale with the font size, and optimising the implementation to cut down on the number of draw calls. It also extends the supported grid line types to include true underlines and strike-through lines in the style of the active font. The main gist of the optimisation was to render the horizontal lines with a single draw call, instead of a loop with lots of little strokes joined together. In the case of the vertical lines, which still needed to be handled in a loop, I've tried to move the majority of static calculations outside the loop, so there is bit of optimisation there too. At the same time this code was updated to support a variable stroke width for the lines, instead of having them hardcoded to 1 pixel. The width is now calculated as a fraction of the font size (0.025 "em"), which is still going to be 1 pixel wide in most typical usage, but will scale up appropriately if you zoom in far enough. And in preparation for supporting the SGR strike-through attribute, and true underlines, I've extended the grid line renders with options for handling those line types as well. The offset and thickness of the lines is obtained from the font metrics (rounded to a pixel width, with a minimum of one pixel), so they match the style of the font. VALIDATION For now we're still only rendering grid lines, and only the top and bottom lines in the case of the DirectX renderer in Windows Terminal. So to test, I hacked in some code to force the renderer to use all the different options, confirming that they were working in both the GDI and DirectX renderers. I've tested the output with a number of different fonts, comparing it with the same text rendered in WordPad. For the most part they match exactly, but there can be slight differences when we adjust the font size for grid alignment. And in the case of the GDI renderer, where we're working with pixel heights rather than points, it's difficult to match the sizes exactly. This is a first step towards supporting the strike-through attribute (#6205) and true underlines (#2915). Closes #6911 --- .../actions/spell-check/dictionary/apis.txt | 3 + src/renderer/dx/DxRenderer.cpp | 135 ++++++++++++------ src/renderer/dx/DxRenderer.hpp | 13 +- src/renderer/gdi/gdirenderer.hpp | 10 ++ src/renderer/gdi/paint.cpp | 64 ++++++--- src/renderer/gdi/state.cpp | 37 +++++ src/renderer/inc/IRenderEngine.hpp | 4 +- 7 files changed, 200 insertions(+), 66 deletions(-) diff --git a/.github/actions/spell-check/dictionary/apis.txt b/.github/actions/spell-check/dictionary/apis.txt index 298b869c186..1e33da10d7e 100644 --- a/.github/actions/spell-check/dictionary/apis.txt +++ b/.github/actions/spell-check/dictionary/apis.txt @@ -23,6 +23,7 @@ IObject IStorage llabs LCID +lround LSHIFT NCHITTEST NCLBUTTONDBLCLK @@ -31,6 +32,8 @@ NOAGGREGATION NOREDIRECTIONBITMAP oaidl ocidl +otms +OUTLINETEXTMETRICW PAGESCROLL RETURNCMD rfind diff --git a/src/renderer/dx/DxRenderer.cpp b/src/renderer/dx/DxRenderer.cpp index e5d3d848e18..cdd1bc72e58 100644 --- a/src/renderer/dx/DxRenderer.cpp +++ b/src/renderer/dx/DxRenderer.cpp @@ -1484,63 +1484,84 @@ try _d2dBrushForeground->SetColor(_ColorFFromColorRef(color)); - const auto font = _glyphCell; - D2D_POINT_2F target = til::point{ coordTarget } * font; + const D2D1_SIZE_F font = _glyphCell; + const D2D_POINT_2F target = { coordTarget.X * font.width, coordTarget.Y * font.height }; + const auto fullRunWidth = font.width * gsl::narrow_cast(cchLine); - D2D_POINT_2F start = { 0 }; - D2D_POINT_2F end = { 0 }; - - for (size_t i = 0; i < cchLine; i++) + const auto DrawLine = [=](const auto x0, const auto y0, const auto x1, const auto y1, const auto strokeWidth) noexcept { - // 0.5 pixel offset for crisp lines - start = { target.x + 0.5f, target.y + 0.5f }; + _d2dDeviceContext->DrawLine({ x0, y0 }, { x1, y1 }, _d2dBrushForeground.Get(), strokeWidth, _strokeStyle.Get()); + }; - if (lines & GridLines::Top) - { - end = start; - end.x += font.width(); + // NOTE: Line coordinates are centered within the line, so they need to be + // offset by half the stroke width. For the start coordinate we add half + // the stroke width, and for the end coordinate we subtract half the width. - _d2dDeviceContext->DrawLine(start, end, _d2dBrushForeground.Get(), 1.0f, _strokeStyle.Get()); - } + if (lines & (GridLines::Left | GridLines::Right)) + { + const auto halfGridlineWidth = _lineMetrics.gridlineWidth / 2.0f; + const auto startY = target.y + halfGridlineWidth; + const auto endY = target.y + font.height - halfGridlineWidth; if (lines & GridLines::Left) { - end = start; - end.y += font.height(); + auto x = target.x + halfGridlineWidth; + for (size_t i = 0; i < cchLine; i++, x += font.width) + { + DrawLine(x, startY, x, endY, _lineMetrics.gridlineWidth); + } + } - _d2dDeviceContext->DrawLine(start, end, _d2dBrushForeground.Get(), 1.0f, _strokeStyle.Get()); + if (lines & GridLines::Right) + { + auto x = target.x + font.width - halfGridlineWidth; + for (size_t i = 0; i < cchLine; i++, x += font.width) + { + DrawLine(x, startY, x, endY, _lineMetrics.gridlineWidth); + } } + } - // NOTE: Watch out for inclusive/exclusive rectangles here. - // We have to remove 1 from the font size for the bottom and right lines to ensure that the - // starting point remains within the clipping rectangle. - // For example, if we're drawing a letter at 0,0 and the font size is 8x16.... - // The bottom left corner inclusive is at 0,15 which is Y (0) + Font Height (16) - 1 = 15. - // The top right corner inclusive is at 7,0 which is X (0) + Font Height (8) - 1 = 7. + if (lines & (GridLines::Top | GridLines::Bottom)) + { + const auto halfGridlineWidth = _lineMetrics.gridlineWidth / 2.0f; + const auto startX = target.x + halfGridlineWidth; + const auto endX = target.x + fullRunWidth - halfGridlineWidth; - // 0.5 pixel offset for crisp lines; -0.5 on the Y to fit _in_ the cell, not outside it. - start = { target.x + 0.5f, target.y + font.height() - 0.5f }; + if (lines & GridLines::Top) + { + const auto y = target.y + halfGridlineWidth; + DrawLine(startX, y, endX, y, _lineMetrics.gridlineWidth); + } if (lines & GridLines::Bottom) { - end = start; - end.x += font.width() - 1.f; - - _d2dDeviceContext->DrawLine(start, end, _d2dBrushForeground.Get(), 1.0f, _strokeStyle.Get()); + const auto y = target.y + font.height - halfGridlineWidth; + DrawLine(startX, y, endX, y, _lineMetrics.gridlineWidth); } + } - start = { target.x + font.width() - 0.5f, target.y + 0.5f }; + // In the case of the underline and strikethrough offsets, the stroke width + // is already accounted for, so they don't require further adjustments. - if (lines & GridLines::Right) - { - end = start; - end.y += font.height() - 1.f; + if (lines & GridLines::Underline) + { + const auto halfUnderlineWidth = _lineMetrics.underlineWidth / 2.0f; + const auto startX = target.x + halfUnderlineWidth; + const auto endX = target.x + fullRunWidth - halfUnderlineWidth; + const auto y = target.y + _lineMetrics.underlineOffset; - _d2dDeviceContext->DrawLine(start, end, _d2dBrushForeground.Get(), 1.0f, _strokeStyle.Get()); - } + DrawLine(startX, y, endX, y, _lineMetrics.underlineWidth); + } - // Move to the next character in this run. - target.x += font.width(); + if (lines & GridLines::Strikethrough) + { + const auto halfStrikethroughWidth = _lineMetrics.strikethroughWidth / 2.0f; + const auto startX = target.x + halfStrikethroughWidth; + const auto endX = target.x + fullRunWidth - halfStrikethroughWidth; + const auto y = target.y + _lineMetrics.strikethroughOffset; + + DrawLine(startX, y, endX, y, _lineMetrics.strikethroughWidth); } return S_OK; @@ -1707,7 +1728,8 @@ try _dpi, _dwriteTextFormat, _dwriteTextAnalyzer, - _dwriteFontFace)); + _dwriteFontFace, + _lineMetrics)); _glyphCell = fiFontInfo.GetSize(); @@ -1796,13 +1818,15 @@ float DxEngine::GetScaling() const noexcept Microsoft::WRL::ComPtr format; Microsoft::WRL::ComPtr analyzer; Microsoft::WRL::ComPtr face; + LineMetrics lineMetrics; return _GetProposedFont(pfiFontInfoDesired, pfiFontInfo, iDpi, format, analyzer, - face); + face, + lineMetrics); } // Routine Description: @@ -2071,7 +2095,8 @@ CATCH_RETURN(); const int dpi, Microsoft::WRL::ComPtr& textFormat, Microsoft::WRL::ComPtr& textAnalyzer, - Microsoft::WRL::ComPtr& fontFace) const noexcept + Microsoft::WRL::ComPtr& fontFace, + LineMetrics& lineMetrics) const noexcept { try { @@ -2234,6 +2259,34 @@ CATCH_RETURN(); false, scaled, unscaled); + + // There is no font metric for the grid line width, so we use a small + // multiple of the font size, which typically rounds to a pixel. + lineMetrics.gridlineWidth = std::round(fontSize * 0.025f); + + // All other line metrics are in design units, so to get a pixel value, + // we scale by the font size divided by the design-units-per-em. + const auto scale = fontSize / fontMetrics.designUnitsPerEm; + lineMetrics.underlineOffset = std::round(fontMetrics.underlinePosition * scale); + lineMetrics.underlineWidth = std::round(fontMetrics.underlineThickness * scale); + lineMetrics.strikethroughOffset = std::round(fontMetrics.strikethroughPosition * scale); + lineMetrics.strikethroughWidth = std::round(fontMetrics.strikethroughThickness * scale); + + // We always want the lines to be visible, so if a stroke width ends up + // at zero after rounding, we need to make it at least 1 pixel. + lineMetrics.gridlineWidth = std::max(lineMetrics.gridlineWidth, 1.0f); + lineMetrics.underlineWidth = std::max(lineMetrics.underlineWidth, 1.0f); + lineMetrics.strikethroughWidth = std::max(lineMetrics.strikethroughWidth, 1.0f); + + // Offsets are relative to the base line of the font, so we subtract + // from the ascent to get an offset relative to the top of the cell. + lineMetrics.underlineOffset = fullPixelAscent - lineMetrics.underlineOffset; + lineMetrics.strikethroughOffset = fullPixelAscent - lineMetrics.strikethroughOffset; + + // We also add half the stroke width to the offset, since the line + // coordinates designate the center of the line. + lineMetrics.underlineOffset += lineMetrics.underlineWidth / 2.0f; + lineMetrics.strikethroughOffset += lineMetrics.strikethroughWidth / 2.0f; } CATCH_RETURN(); diff --git a/src/renderer/dx/DxRenderer.hpp b/src/renderer/dx/DxRenderer.hpp index c56262d7d28..5eeb781a57f 100644 --- a/src/renderer/dx/DxRenderer.hpp +++ b/src/renderer/dx/DxRenderer.hpp @@ -142,6 +142,16 @@ namespace Microsoft::Console::Render bool _isEnabled; bool _isPainting; + struct LineMetrics + { + float gridlineWidth; + float underlineOffset; + float underlineWidth; + float strikethroughOffset; + float strikethroughWidth; + }; + + LineMetrics _lineMetrics; til::size _displaySizePixels; til::size _glyphCell; ::Microsoft::WRL::ComPtr _boxDrawingEffect; @@ -267,7 +277,8 @@ namespace Microsoft::Console::Render const int dpi, ::Microsoft::WRL::ComPtr& textFormat, ::Microsoft::WRL::ComPtr& textAnalyzer, - ::Microsoft::WRL::ComPtr& fontFace) const noexcept; + ::Microsoft::WRL::ComPtr& fontFace, + LineMetrics& lineMetrics) const noexcept; [[nodiscard]] til::size _GetClientSize() const; diff --git a/src/renderer/gdi/gdirenderer.hpp b/src/renderer/gdi/gdirenderer.hpp index c375f8b764a..ad3b7089f09 100644 --- a/src/renderer/gdi/gdirenderer.hpp +++ b/src/renderer/gdi/gdirenderer.hpp @@ -96,6 +96,16 @@ namespace Microsoft::Console::Render std::vector cursorInvertRects; + struct LineMetrics + { + int gridlineWidth; + int underlineOffset; + int underlineWidth; + int strikethroughOffset; + int strikethroughWidth; + }; + + LineMetrics _lineMetrics; COORD _coordFontLast; int _iCurrentDpi; diff --git a/src/renderer/gdi/paint.cpp b/src/renderer/gdi/paint.cpp index b416510f99e..2008b220399 100644 --- a/src/renderer/gdi/paint.cpp +++ b/src/renderer/gdi/paint.cpp @@ -459,40 +459,58 @@ using namespace Microsoft::Console::Render; auto restoreBrushOnExit = wil::scope_exit([&] { hbr.reset(SelectBrush(_hdcMemoryContext, hbrPrev.get())); }); // Get the font size so we know the size of the rectangle lines we'll be inscribing. - COORD const coordFontSize = _GetFontSize(); + const auto fontWidth = _GetFontSize().X; + const auto fontHeight = _GetFontSize().Y; + const auto widthOfAllCells = fontWidth * gsl::narrow_cast(cchLine); + + const auto DrawLine = [=](const auto x, const auto y, const auto w, const auto h) { + return PatBlt(_hdcMemoryContext, x, y, w, h, PATCOPY); + }; - // For each length of the line, inscribe the various lines as specified by the enum - for (size_t i = 0; i < cchLine; i++) + if (lines & GridLines::Left) { - if (lines & GridLines::Top) + auto x = ptTarget.x; + for (size_t i = 0; i < cchLine; i++, x += fontWidth) { - RETURN_HR_IF(E_FAIL, !(PatBlt(_hdcMemoryContext, ptTarget.x, ptTarget.y, coordFontSize.X, 1, PATCOPY))); + RETURN_HR_IF(E_FAIL, !DrawLine(x, ptTarget.y, _lineMetrics.gridlineWidth, fontHeight)); } + } - if (lines & GridLines::Left) + if (lines & GridLines::Right) + { + // NOTE: We have to subtract the stroke width from the cell width + // to ensure the x coordinate remains inside the clipping rectangle. + auto x = ptTarget.x + fontWidth - _lineMetrics.gridlineWidth; + for (size_t i = 0; i < cchLine; i++, x += fontWidth) { - RETURN_HR_IF(E_FAIL, !(PatBlt(_hdcMemoryContext, ptTarget.x, ptTarget.y, 1, coordFontSize.Y, PATCOPY))); + RETURN_HR_IF(E_FAIL, !DrawLine(x, ptTarget.y, _lineMetrics.gridlineWidth, fontHeight)); } + } - // NOTE: Watch out for inclusive/exclusive rectangles here. - // We have to remove 1 from the font size for the bottom and right lines to ensure that the - // starting point remains within the clipping rectangle. - // For example, if we're drawing a letter at 0,0 and the font size is 8x16.... - // The bottom left corner inclusive is at 0,15 which is Y (0) + Font Height (16) - 1 = 15. - // The top right corner inclusive is at 7,0 which is X (0) + Font Height (8) - 1 = 7. + if (lines & GridLines::Top) + { + const auto y = ptTarget.y; + RETURN_HR_IF(E_FAIL, !DrawLine(ptTarget.x, y, widthOfAllCells, _lineMetrics.gridlineWidth)); + } - if (lines & GridLines::Bottom) - { - RETURN_HR_IF(E_FAIL, !(PatBlt(_hdcMemoryContext, ptTarget.x, ptTarget.y + coordFontSize.Y - 1, coordFontSize.X, 1, PATCOPY))); - } + if (lines & GridLines::Bottom) + { + // NOTE: We have to subtract the stroke width from the cell height + // to ensure the y coordinate remains inside the clipping rectangle. + const auto y = ptTarget.y + fontHeight - _lineMetrics.gridlineWidth; + RETURN_HR_IF(E_FAIL, !DrawLine(ptTarget.x, y, widthOfAllCells, _lineMetrics.gridlineWidth)); + } - if (lines & GridLines::Right) - { - RETURN_HR_IF(E_FAIL, !(PatBlt(_hdcMemoryContext, ptTarget.x + coordFontSize.X - 1, ptTarget.y, 1, coordFontSize.Y, PATCOPY))); - } + if (lines & GridLines::Underline) + { + const auto y = ptTarget.y + _lineMetrics.underlineOffset; + RETURN_HR_IF(E_FAIL, !DrawLine(ptTarget.x, y, widthOfAllCells, _lineMetrics.underlineWidth)); + } - // Move to the next character in this run. - ptTarget.x += coordFontSize.X; + if (lines & GridLines::Strikethrough) + { + const auto y = ptTarget.y + _lineMetrics.strikethroughOffset; + RETURN_HR_IF(E_FAIL, !DrawLine(ptTarget.x, y, widthOfAllCells, _lineMetrics.strikethroughWidth)); } return S_OK; diff --git a/src/renderer/gdi/state.cpp b/src/renderer/gdi/state.cpp index 65eec1aaa4e..e7ad9e2f6ef 100644 --- a/src/renderer/gdi/state.cpp +++ b/src/renderer/gdi/state.cpp @@ -232,6 +232,43 @@ GdiEngine::~GdiEngine() // Save off the font metrics for various other calculations RETURN_HR_IF(E_FAIL, !(GetTextMetricsW(_hdcMemoryContext, &_tmFontMetrics))); + // There is no font metric for the grid line width, so we use a small + // multiple of the font size, which typically rounds to a pixel. + const auto fontSize = _tmFontMetrics.tmHeight - _tmFontMetrics.tmInternalLeading; + _lineMetrics.gridlineWidth = std::lround(fontSize * 0.025); + + OUTLINETEXTMETRICW outlineMetrics; + if (GetOutlineTextMetricsW(_hdcMemoryContext, sizeof(outlineMetrics), &outlineMetrics)) + { + // For TrueType fonts, the other line metrics can be obtained from + // the font's outline text metric structure. + _lineMetrics.underlineOffset = outlineMetrics.otmsUnderscorePosition; + _lineMetrics.underlineWidth = outlineMetrics.otmsUnderscoreSize; + _lineMetrics.strikethroughOffset = outlineMetrics.otmsStrikeoutPosition; + _lineMetrics.strikethroughWidth = outlineMetrics.otmsStrikeoutSize; + } + else + { + // If we can't obtain the outline metrics for the font, we just pick + // some reasonable values for the offsets and widths. + _lineMetrics.underlineOffset = -std::lround(fontSize * 0.05); + _lineMetrics.underlineWidth = _lineMetrics.gridlineWidth; + _lineMetrics.strikethroughOffset = std::lround(_tmFontMetrics.tmAscent / 3.0); + _lineMetrics.strikethroughWidth = _lineMetrics.gridlineWidth; + } + + // We always want the lines to be visible, so if a stroke width ends + // up being zero, we need to make it at least 1 pixel. + _lineMetrics.gridlineWidth = std::max(_lineMetrics.gridlineWidth, 1); + _lineMetrics.underlineWidth = std::max(_lineMetrics.underlineWidth, 1); + _lineMetrics.strikethroughWidth = std::max(_lineMetrics.strikethroughWidth, 1); + + // Offsets are relative to the base line of the font, so we subtract + // from the ascent to get an offset relative to the top of the cell. + const auto ascent = _tmFontMetrics.tmAscent; + _lineMetrics.underlineOffset = ascent - _lineMetrics.underlineOffset; + _lineMetrics.strikethroughOffset = ascent - _lineMetrics.strikethroughOffset; + // Now find the size of a 0 in this current font and save it for conversions done later. _coordFontLast = Font.GetSize(); diff --git a/src/renderer/inc/IRenderEngine.hpp b/src/renderer/inc/IRenderEngine.hpp index a70960754c0..388ba308960 100644 --- a/src/renderer/inc/IRenderEngine.hpp +++ b/src/renderer/inc/IRenderEngine.hpp @@ -35,7 +35,9 @@ namespace Microsoft::Console::Render Top = 0x1, Bottom = 0x2, Left = 0x4, - Right = 0x8 + Right = 0x8, + Underline = 0x10, + Strikethrough = 0x20 }; virtual ~IRenderEngine() = 0; From 5c5c437ab8946013550e097187c7ed558ee0ea07 Mon Sep 17 00:00:00 2001 From: Dustin Howett Date: Thu, 30 Jul 2020 22:48:48 +0000 Subject: [PATCH 010/266] Merged PR 4963673: OS-side build fixes for 09471c375 (gsl-3.1.0 update) Retrieved from https://microsoft.visualstudio.com os.2020 OS official/rs_onecore_dep_uxp 29b1a1d663d0047dc0d2125dd05f75959bca27ef Related work items: MSFT:27866336 --- src/interactivity/onecore/BgfxEngine.cpp | 2 +- src/project.inc | 2 ++ src/renderer/wddmcon/WddmConRenderer.cpp | 2 +- src/terminal/parser/ft_fuzzer/sources | 2 ++ 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/interactivity/onecore/BgfxEngine.cpp b/src/interactivity/onecore/BgfxEngine.cpp index a800e2c2a0b..fda66e69969 100644 --- a/src/interactivity/onecore/BgfxEngine.cpp +++ b/src/interactivity/onecore/BgfxEngine.cpp @@ -157,7 +157,7 @@ BgfxEngine::BgfxEngine(PVOID SharedViewBase, LONG DisplayHeight, LONG DisplayWid for (size_t i = 0; i < clusters.size() && i < (size_t)_displayWidth; i++) { - NewRun[coord.X + i].Character = clusters.at(i).GetTextAsSingle(); + NewRun[coord.X + i].Character = til::at(clusters, i).GetTextAsSingle(); NewRun[coord.X + i].Attribute = _currentLegacyColorAttribute; } diff --git a/src/project.inc b/src/project.inc index c083d8b82c6..5d28741ed44 100644 --- a/src/project.inc +++ b/src/project.inc @@ -3,6 +3,8 @@ # - Common Project Configuration # ------------------------------------- +!include $(OSDEPENDSROOT)\OSS\gsl\3.1.0\consume.inc + # ------------------------------------- # Preprocessor Settings # ------------------------------------- diff --git a/src/renderer/wddmcon/WddmConRenderer.cpp b/src/renderer/wddmcon/WddmConRenderer.cpp index 277dd2bcf39..d19aa5250b4 100644 --- a/src/renderer/wddmcon/WddmConRenderer.cpp +++ b/src/renderer/wddmcon/WddmConRenderer.cpp @@ -278,7 +278,7 @@ bool WddmConEngine::IsInitialized() OldChar->Character = NewChar->Character; OldChar->Attribute = NewChar->Attribute; - NewChar->Character = clusters.at(i).GetTextAsSingle(); + NewChar->Character = til::at(clusters, i).GetTextAsSingle(); NewChar->Attribute = _currentLegacyColorAttribute; } diff --git a/src/terminal/parser/ft_fuzzer/sources b/src/terminal/parser/ft_fuzzer/sources index cd23c492c70..6a0cbb9fd8e 100644 --- a/src/terminal/parser/ft_fuzzer/sources +++ b/src/terminal/parser/ft_fuzzer/sources @@ -3,6 +3,8 @@ # - Console Virtual Terminal Parser Fuzzer # ------------------------------------- +!include $(OSDEPENDSROOT)\OSS\gsl\3.1.0\consume.inc + # This program will generate fuzz input for the parsing engine # and is to be used in conjunction with the fuzz wrapper tool. From f49ae2451dd8083714582f5b41bd8478fedaffac Mon Sep 17 00:00:00 2001 From: Dustin Howett Date: Thu, 30 Jul 2020 22:55:57 +0000 Subject: [PATCH 011/266] Merged PR 4988918: Reflect OS changes for LKG10 Reverts "Merged PR 4670666: Workaround for LKG10 internal linker error" Related work items: MSFT:25439646, MSFT:26598503 --- src/host/sources.inc | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/host/sources.inc b/src/host/sources.inc index e8aa074e88e..cc7cf682a46 100644 --- a/src/host/sources.inc +++ b/src/host/sources.inc @@ -244,7 +244,3 @@ DELAYLOAD = \ ext-ms-win-uxtheme-themes-l1.dll; \ DLOAD_ERROR_HANDLER = kernelbase - -# Add /d2:-notypeopt to disable optimization bug caused by LKG9. Bug #25439646 -USER_C_FLAGS=/d2notypeopt $(USER_C_FLAGS) -LINKER_FLAGS=/d2:-notypeopt $(LINKER_FLAGS) From 8b669b5484d39cd777e8dcb6312f4308ee2861a8 Mon Sep 17 00:00:00 2001 From: PankajBhojwani Date: Thu, 30 Jul 2020 21:07:47 -0400 Subject: [PATCH 012/266] Implement split pane with new tab button (#7117) Allows splitting pane (with default settings) by holding down ALT and pressing the new tab button ('+') ## PR Checklist * [X] Closes #6757 * [X] Works here. * [X] Manual test (below) * [X] Is core contributor. ## More detailed description Pretty much exactly the code added in #5928 (all credit to @carlos-zamora), but put at the new tab button event binding ## Validation steps Seems to work - holding ALT while pressing '+' opens a pane instead of a tab. Holding ALT while starting up terminal for the first time does not seem to affect the behaviour. --- src/cascadia/TerminalApp/TerminalPage.cpp | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index 8fc907ca89f..fd613d8a82e 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -167,7 +167,28 @@ namespace winrt::TerminalApp::implementation _newTabButton.Click([weakThis{ get_weak() }](auto&&, auto&&) { if (auto page{ weakThis.get() }) { - page->_OpenNewTab(nullptr); + // if alt is pressed, open a pane + const CoreWindow window = CoreWindow::GetForCurrentThread(); + const auto rAltState = window.GetKeyState(VirtualKey::RightMenu); + const auto lAltState = window.GetKeyState(VirtualKey::LeftMenu); + const bool altPressed = WI_IsFlagSet(lAltState, CoreVirtualKeyStates::Down) || + WI_IsFlagSet(rAltState, CoreVirtualKeyStates::Down); + + // Check for DebugTap + bool debugTap = page->_settings->GlobalSettings().DebugFeaturesEnabled() && + WI_IsFlagSet(lAltState, CoreVirtualKeyStates::Down) && + WI_IsFlagSet(rAltState, CoreVirtualKeyStates::Down); + + if (altPressed && !debugTap) + { + page->_SplitPane(TerminalApp::SplitState::Automatic, + TerminalApp::SplitType::Manual, + nullptr); + } + else + { + page->_OpenNewTab(nullptr); + } } }); _tabView.SelectionChanged({ this, &TerminalPage::_OnTabSelectionChanged }); From dd0f7b701a01c93756c26aef001c5b3ee04ac649 Mon Sep 17 00:00:00 2001 From: "Dustin L. Howett" Date: Fri, 31 Jul 2020 10:16:27 -0700 Subject: [PATCH 013/266] Send ENHANCED_KEY in Win32 input mode in the wpf/uwp controls (#7106) When we added support for win32 input mode, we neglected to pass `ENHANCED_KEY` through the two surfaces that would generate events. This broke arrow keys in much the same way was #2397, but in a different layer. While I was working on the WPF control, I took a moment to refactor the message cracking out into a helper. It's a lot easier on the eyes than four lines of bit shifting repeated three times. Fixes #7074 --- .../PublicTerminalCore/HwndTerminal.cpp | 28 ++++++++++++------- .../PublicTerminalCore/HwndTerminal.hpp | 12 ++++---- src/cascadia/TerminalControl/TermControl.cpp | 12 ++++++-- .../WpfTerminalControl/NativeMethods.cs | 4 +-- .../WpfTerminalControl/TerminalContainer.cs | 26 +++++++++++++---- 5 files changed, 56 insertions(+), 26 deletions(-) diff --git a/src/cascadia/PublicTerminalCore/HwndTerminal.cpp b/src/cascadia/PublicTerminalCore/HwndTerminal.cpp index 16e41fef05f..27775bb314d 100644 --- a/src/cascadia/PublicTerminalCore/HwndTerminal.cpp +++ b/src/cascadia/PublicTerminalCore/HwndTerminal.cpp @@ -625,15 +625,19 @@ catch (...) return false; } -void HwndTerminal::_SendKeyEvent(WORD vkey, WORD scanCode, bool keyDown) noexcept +void HwndTerminal::_SendKeyEvent(WORD vkey, WORD scanCode, WORD flags, bool keyDown) noexcept try { - const auto flags = getControlKeyState(); - _terminal->SendKeyEvent(vkey, scanCode, flags, keyDown); + auto modifiers = getControlKeyState(); + if (WI_IsFlagSet(flags, ENHANCED_KEY)) + { + modifiers |= ControlKeyStates::EnhancedKey; + } + _terminal->SendKeyEvent(vkey, scanCode, modifiers, keyDown); } CATCH_LOG(); -void HwndTerminal::_SendCharEvent(wchar_t ch, WORD scanCode) noexcept +void HwndTerminal::_SendCharEvent(wchar_t ch, WORD scanCode, WORD flags) noexcept try { if (_terminal->IsSelectionActive()) @@ -653,21 +657,25 @@ try return; } - const auto flags = getControlKeyState(); - _terminal->SendCharEvent(ch, scanCode, flags); + auto modifiers = getControlKeyState(); + if (WI_IsFlagSet(flags, ENHANCED_KEY)) + { + modifiers |= ControlKeyStates::EnhancedKey; + } + _terminal->SendCharEvent(ch, scanCode, modifiers); } CATCH_LOG(); -void _stdcall TerminalSendKeyEvent(void* terminal, WORD vkey, WORD scanCode, bool keyDown) +void _stdcall TerminalSendKeyEvent(void* terminal, WORD vkey, WORD scanCode, WORD flags, bool keyDown) { const auto publicTerminal = static_cast(terminal); - publicTerminal->_SendKeyEvent(vkey, scanCode, keyDown); + publicTerminal->_SendKeyEvent(vkey, scanCode, flags, keyDown); } -void _stdcall TerminalSendCharEvent(void* terminal, wchar_t ch, WORD scanCode) +void _stdcall TerminalSendCharEvent(void* terminal, wchar_t ch, WORD scanCode, WORD flags) { const auto publicTerminal = static_cast(terminal); - publicTerminal->_SendCharEvent(ch, scanCode); + publicTerminal->_SendCharEvent(ch, scanCode, flags); } void _stdcall DestroyTerminal(void* terminal) diff --git a/src/cascadia/PublicTerminalCore/HwndTerminal.hpp b/src/cascadia/PublicTerminalCore/HwndTerminal.hpp index f904f526cad..47ee1f88dc7 100644 --- a/src/cascadia/PublicTerminalCore/HwndTerminal.hpp +++ b/src/cascadia/PublicTerminalCore/HwndTerminal.hpp @@ -34,8 +34,8 @@ __declspec(dllexport) bool _stdcall TerminalIsSelectionActive(void* terminal); __declspec(dllexport) void _stdcall DestroyTerminal(void* terminal); __declspec(dllexport) void _stdcall TerminalSetTheme(void* terminal, TerminalTheme theme, LPCWSTR fontFamily, short fontSize, int newDpi); __declspec(dllexport) void _stdcall TerminalRegisterWriteCallback(void* terminal, const void __stdcall callback(wchar_t*)); -__declspec(dllexport) void _stdcall TerminalSendKeyEvent(void* terminal, WORD vkey, WORD scanCode, bool keyDown); -__declspec(dllexport) void _stdcall TerminalSendCharEvent(void* terminal, wchar_t ch, WORD scanCode); +__declspec(dllexport) void _stdcall TerminalSendKeyEvent(void* terminal, WORD vkey, WORD scanCode, WORD flags, bool keyDown); +__declspec(dllexport) void _stdcall TerminalSendCharEvent(void* terminal, wchar_t ch, WORD flags, WORD scanCode); __declspec(dllexport) void _stdcall TerminalBlinkCursor(void* terminal); __declspec(dllexport) void _stdcall TerminalSetCursorVisible(void* terminal, const bool visible); __declspec(dllexport) void _stdcall TerminalSetFocus(void* terminal); @@ -93,8 +93,8 @@ struct HwndTerminal : ::Microsoft::Console::Types::IControlAccessibilityInfo friend void _stdcall TerminalClearSelection(void* terminal); friend const wchar_t* _stdcall TerminalGetSelection(void* terminal); friend bool _stdcall TerminalIsSelectionActive(void* terminal); - friend void _stdcall TerminalSendKeyEvent(void* terminal, WORD vkey, WORD scanCode, bool keyDown); - friend void _stdcall TerminalSendCharEvent(void* terminal, wchar_t ch, WORD scanCode); + friend void _stdcall TerminalSendKeyEvent(void* terminal, WORD vkey, WORD scanCode, WORD flags, bool keyDown); + friend void _stdcall TerminalSendCharEvent(void* terminal, wchar_t ch, WORD scanCode, WORD flags); friend void _stdcall TerminalSetTheme(void* terminal, TerminalTheme theme, LPCWSTR fontFamily, short fontSize, int newDpi); friend void _stdcall TerminalBlinkCursor(void* terminal); friend void _stdcall TerminalSetCursorVisible(void* terminal, const bool visible); @@ -118,8 +118,8 @@ struct HwndTerminal : ::Microsoft::Console::Types::IControlAccessibilityInfo bool _CanSendVTMouseInput() const noexcept; bool _SendMouseEvent(UINT uMsg, WPARAM wParam, LPARAM lParam) noexcept; - void _SendKeyEvent(WORD vkey, WORD scanCode, bool keyDown) noexcept; - void _SendCharEvent(wchar_t ch, WORD scanCode) noexcept; + void _SendKeyEvent(WORD vkey, WORD scanCode, WORD flags, bool keyDown) noexcept; + void _SendCharEvent(wchar_t ch, WORD scanCode, WORD flags) noexcept; // Inherited via IControlAccessibilityInfo COORD GetFontSize() const override; diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index 8838eb5df11..784275fa324 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -738,7 +738,11 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation const auto ch = e.Character(); const auto scanCode = gsl::narrow_cast(e.KeyStatus().ScanCode); - const auto modifiers = _GetPressedModifierKeys(); + auto modifiers = _GetPressedModifierKeys(); + if (e.KeyStatus().IsExtendedKey) + { + modifiers |= ControlKeyStates::EnhancedKey; + } const bool handled = _terminal->SendCharEvent(ch, scanCode, modifiers); e.Handled(handled); } @@ -827,9 +831,13 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation return; } - const auto modifiers = _GetPressedModifierKeys(); + auto modifiers = _GetPressedModifierKeys(); const auto vkey = gsl::narrow_cast(e.OriginalKey()); const auto scanCode = gsl::narrow_cast(e.KeyStatus().ScanCode); + if (e.KeyStatus().IsExtendedKey) + { + modifiers |= ControlKeyStates::EnhancedKey; + } // Alt-Numpad# input will send us a character once the user releases // Alt, so we should be ignoring the individual keydowns. The character diff --git a/src/cascadia/WpfTerminalControl/NativeMethods.cs b/src/cascadia/WpfTerminalControl/NativeMethods.cs index 3ba2a78f094..0e40d646652 100644 --- a/src/cascadia/WpfTerminalControl/NativeMethods.cs +++ b/src/cascadia/WpfTerminalControl/NativeMethods.cs @@ -225,10 +225,10 @@ public enum SetWindowPosFlags : uint public static extern void DestroyTerminal(IntPtr terminal); [DllImport("PublicTerminalCore.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)] - public static extern void TerminalSendKeyEvent(IntPtr terminal, ushort vkey, ushort scanCode, bool keyDown); + public static extern void TerminalSendKeyEvent(IntPtr terminal, ushort vkey, ushort scanCode, ushort flags, bool keyDown); [DllImport("PublicTerminalCore.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)] - public static extern void TerminalSendCharEvent(IntPtr terminal, char ch, ushort scanCode); + public static extern void TerminalSendCharEvent(IntPtr terminal, char ch, ushort scanCode, ushort flags); [DllImport("PublicTerminalCore.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)] public static extern void TerminalSetTheme(IntPtr terminal, [MarshalAs(UnmanagedType.Struct)] TerminalTheme theme, string fontFamily, short fontSize, int newDpi); diff --git a/src/cascadia/WpfTerminalControl/TerminalContainer.cs b/src/cascadia/WpfTerminalControl/TerminalContainer.cs index 86549a9e05c..2f5c6839455 100644 --- a/src/cascadia/WpfTerminalControl/TerminalContainer.cs +++ b/src/cascadia/WpfTerminalControl/TerminalContainer.cs @@ -20,6 +20,20 @@ namespace Microsoft.Terminal.Wpf /// public class TerminalContainer : HwndHost { + private static void UnpackKeyMessage(IntPtr wParam, IntPtr lParam, out ushort vkey, out ushort scanCode, out ushort flags) + { + ulong scanCodeAndFlags = (((ulong)lParam) & 0xFFFF0000) >> 16; + scanCode = (ushort)(scanCodeAndFlags & 0x00FFu); + flags = (ushort)(scanCodeAndFlags & 0xFF00u); + vkey = (ushort)wParam; + } + + private static void UnpackCharMessage(IntPtr wParam, IntPtr lParam, out char character, out ushort scanCode, out ushort flags) + { + UnpackKeyMessage(wParam, lParam, out ushort vKey, out scanCode, out flags); + character = (char)vKey; + } + private ITerminalConnection connection; private IntPtr hwnd; private IntPtr terminal; @@ -254,9 +268,9 @@ private IntPtr TerminalContainer_MessageHook(IntPtr hwnd, int msg, IntPtr wParam { // WM_KEYDOWN lParam layout documentation: https://docs.microsoft.com/en-us/windows/win32/inputdev/wm-keydown NativeMethods.TerminalSetCursorVisible(this.terminal, true); - ulong scanCode = (((ulong)lParam) & 0x00FF0000) >> 16; - NativeMethods.TerminalSendKeyEvent(this.terminal, (ushort)wParam, (ushort)scanCode, true); + UnpackKeyMessage(wParam, lParam, out ushort vkey, out ushort scanCode, out ushort flags); + NativeMethods.TerminalSendKeyEvent(this.terminal, vkey, scanCode, flags, true); this.blinkTimer?.Start(); break; } @@ -265,16 +279,16 @@ private IntPtr TerminalContainer_MessageHook(IntPtr hwnd, int msg, IntPtr wParam case NativeMethods.WindowMessage.WM_KEYUP: { // WM_KEYUP lParam layout documentation: https://docs.microsoft.com/en-us/windows/win32/inputdev/wm-keyup - ulong scanCode = (((ulong)lParam) & 0x00FF0000) >> 16; - NativeMethods.TerminalSendKeyEvent(this.terminal, (ushort)wParam, (ushort)scanCode, false); + UnpackKeyMessage(wParam, lParam, out ushort vkey, out ushort scanCode, out ushort flags); + NativeMethods.TerminalSendKeyEvent(this.terminal, (ushort)wParam, scanCode, flags, false); break; } case NativeMethods.WindowMessage.WM_CHAR: { // WM_CHAR lParam layout documentation: https://docs.microsoft.com/en-us/windows/win32/inputdev/wm-char - ulong scanCode = (((ulong)lParam) & 0x00FF0000) >> 16; - NativeMethods.TerminalSendCharEvent(this.terminal, (char)wParam, (ushort)scanCode); + UnpackCharMessage(wParam, lParam, out char character, out ushort scanCode, out ushort flags); + NativeMethods.TerminalSendCharEvent(this.terminal, character, scanCode, flags); break; } From ef4aed944a45c82355a7245b1d575a97968ef219 Mon Sep 17 00:00:00 2001 From: James Holderness Date: Sat, 1 Aug 2020 09:09:37 +0100 Subject: [PATCH 014/266] Add support for the "crossed-out" graphic rendition attribute (#7143) This PR adds support for the ANSI _crossed-out_ graphic rendition attribute, which is enabled by the `SGR 9` escape sequence. * Support for the escape sequences and storage of the attribute was originally added in #2917. * Support for drawing the strikethrough effect in the grid line renderer was added in #7107. Since the majority of the code required for this attribute had already been implemented, it was just a matter of activating the `GridLines::Strikethrough` style in the `Renderer::s_GetGridlines` method when the `CrossedOut` attribute was set. VALIDATION There were already some unit tests in place in `VtRendererTest` and the `ScreenBufferTests`, but I've also now extended the SGR tests in `AdapterTest` to cover this attribute. I've manually confirmed the first test case from #6205 now works as expected in both conhost and Terminal. Closes #6205 --- src/renderer/base/renderer.cpp | 5 +++++ src/terminal/adapter/ut_adapter/adapterTest.cpp | 14 +++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/renderer/base/renderer.cpp b/src/renderer/base/renderer.cpp index bdda98bc3cf..c4e9d71d9c5 100644 --- a/src/renderer/base/renderer.cpp +++ b/src/renderer/base/renderer.cpp @@ -860,6 +860,11 @@ IRenderEngine::GridLines Renderer::s_GetGridlines(const TextAttribute& textAttri { lines |= IRenderEngine::GridLines::Right; } + + if (textAttribute.IsCrossedOut()) + { + lines |= IRenderEngine::GridLines::Strikethrough; + } return lines; } diff --git a/src/terminal/adapter/ut_adapter/adapterTest.cpp b/src/terminal/adapter/ut_adapter/adapterTest.cpp index 3823a6179c5..6ecdfb7f0a4 100644 --- a/src/terminal/adapter/ut_adapter/adapterTest.cpp +++ b/src/terminal/adapter/ut_adapter/adapterTest.cpp @@ -1260,7 +1260,7 @@ class AdapterTest TEST_METHOD(GraphicsSingleTests) { BEGIN_TEST_METHOD_PROPERTIES() - TEST_METHOD_PROPERTY(L"Data:uiGraphicsOptions", L"{0, 1, 2, 4, 7, 8, 22, 24, 27, 28, 30, 31, 32, 33, 34, 35, 36, 37, 39, 40, 41, 42, 43, 44, 45, 46, 47, 49, 53, 55, 90, 91, 92, 93, 94, 95, 96, 97, 100, 101, 102, 103, 104, 105, 106, 107}") // corresponds to options in DispatchTypes::GraphicsOptions + TEST_METHOD_PROPERTY(L"Data:uiGraphicsOptions", L"{0, 1, 2, 4, 7, 8, 9, 22, 24, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 39, 40, 41, 42, 43, 44, 45, 46, 47, 49, 53, 55, 90, 91, 92, 93, 94, 95, 96, 97, 100, 101, 102, 103, 104, 105, 106, 107}") // corresponds to options in DispatchTypes::GraphicsOptions END_TEST_METHOD_PROPERTIES() Log::Comment(L"Starting test..."); @@ -1316,6 +1316,12 @@ class AdapterTest _testGetSet->_expectedAttribute = TextAttribute{ 0 }; _testGetSet->_expectedAttribute.SetInvisible(true); break; + case DispatchTypes::GraphicsOptions::CrossedOut: + Log::Comment(L"Testing graphics 'Crossed Out'"); + _testGetSet->_attribute = TextAttribute{ 0 }; + _testGetSet->_expectedAttribute = TextAttribute{ 0 }; + _testGetSet->_expectedAttribute.SetCrossedOut(true); + break; case DispatchTypes::GraphicsOptions::NotBoldOrFaint: Log::Comment(L"Testing graphics 'No Bold or Faint'"); _testGetSet->_attribute = TextAttribute{ 0 }; @@ -1344,6 +1350,12 @@ class AdapterTest _testGetSet->_attribute.SetInvisible(true); _testGetSet->_expectedAttribute = TextAttribute{ 0 }; break; + case DispatchTypes::GraphicsOptions::NotCrossedOut: + Log::Comment(L"Testing graphics 'Not Crossed Out'"); + _testGetSet->_attribute = TextAttribute{ 0 }; + _testGetSet->_attribute.SetCrossedOut(true); + _testGetSet->_expectedAttribute = TextAttribute{ 0 }; + break; case DispatchTypes::GraphicsOptions::ForegroundBlack: Log::Comment(L"Testing graphics 'Foreground Color Black'"); _testGetSet->_attribute = TextAttribute{ FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY }; From 158a1708a62504d59d2f5000489f7ceddb90b8f2 Mon Sep 17 00:00:00 2001 From: James Holderness Date: Mon, 3 Aug 2020 13:49:25 +0100 Subject: [PATCH 015/266] Render the SGR "underlined" attribute in the style of the font (#7148) This PR updates the rendering of the _underlined_ graphic rendition attribute, using the style specified in the active font, instead of just reusing the grid line at the bottom of the character cell. * Support for drawing the correct underline effect in the grid line renderer was added in #7107. There was already an `ExtendedAttributes` flag defined for the underlined state, but I needed to update the `SetUnderlined` and `IsUnderlined` methods in the `TextAttribute` class to use that flag now in place of the legacy `LVB_UNDERSCORE` attribute. This enables underlines set via a VT sequence to be tracked separately from `LVB_UNDERSCORE` grid lines set via the console API. I then needed to update the `Renderer::s_GetGridlines` method to activate the `GridLines::Underline` style when the `Underlined` attribute was set. The `GridLines::Bottom` style is still triggered by the `LVB_UNDERSCORE` attribute to produce the bottom grid line effect. Validation ---------- Because this is a change from the existing behaviour, certain unit tests that were expecting the `LVB_UNDERSCORE` to be toggled by `SGR 4` and `SGR 24` have now had to be updated to check the `Underlined` flag instead. There were also some UI Automation tests that were checking for `SGR 4` mapping to `LVB_UNDERSCORE` attribute, which I've now substituted with a test of the `SGR 53` overline attribute mapping to `LVB_GRID_HORIZONTAL`. These tests only work with legacy attributes, so they can't access the extended underline state, and I thought a replacement test that covered similar ground would be better than dropping the tests altogether. As far as the visual rendering is concerned, I've manually confirmed that the VT underline sequences now draw the underline in the correct position and style, while grid lines output via the console API are still displayed in their original form. Closes #2915 --- src/buffer/out/TextAttribute.cpp | 6 ++---- src/host/ft_uia/VirtualTerminalTests.cs | 16 ++++++++-------- src/host/ut_host/TextBufferTests.cpp | 4 ++-- src/inc/conattrs.hpp | 2 +- src/renderer/base/renderer.cpp | 5 +++++ src/terminal/adapter/ut_adapter/adapterTest.cpp | 6 ++++-- src/tools/vtapp/Program.cs | 6 +++--- 7 files changed, 25 insertions(+), 20 deletions(-) diff --git a/src/buffer/out/TextAttribute.cpp b/src/buffer/out/TextAttribute.cpp index 371fedb2b64..ad7ee0546e7 100644 --- a/src/buffer/out/TextAttribute.cpp +++ b/src/buffer/out/TextAttribute.cpp @@ -246,8 +246,7 @@ bool TextAttribute::IsCrossedOut() const noexcept bool TextAttribute::IsUnderlined() const noexcept { - // TODO:GH#2915 Treat underline separately from LVB_UNDERSCORE - return WI_IsFlagSet(_wAttrLegacy, COMMON_LVB_UNDERSCORE); + return WI_IsFlagSet(_extendedAttrs, ExtendedAttributes::Underlined); } bool TextAttribute::IsOverlined() const noexcept @@ -292,8 +291,7 @@ void TextAttribute::SetCrossedOut(bool isCrossedOut) noexcept void TextAttribute::SetUnderlined(bool isUnderlined) noexcept { - // TODO:GH#2915 Treat underline separately from LVB_UNDERSCORE - WI_UpdateFlag(_wAttrLegacy, COMMON_LVB_UNDERSCORE, isUnderlined); + WI_UpdateFlag(_extendedAttrs, ExtendedAttributes::Underlined, isUnderlined); } void TextAttribute::SetOverlined(bool isOverlined) noexcept diff --git a/src/host/ft_uia/VirtualTerminalTests.cs b/src/host/ft_uia/VirtualTerminalTests.cs index 65fdf71b401..6210e297363 100644 --- a/src/host/ft_uia/VirtualTerminalTests.cs +++ b/src/host/ft_uia/VirtualTerminalTests.cs @@ -381,23 +381,23 @@ private static void TestGraphicsCommands(CmdApp app, ViewportArea area, IntPtr h ciActual = area.GetCharInfoAt(hConsole, pt); Verify.AreEqual(ciExpected, ciActual, "Verify that background bright cyan got set."); - Log.Comment("Set underline (SGR.4)"); + Log.Comment("Set overline (SGR.53)"); app.FillCursorPosition(hConsole, ref pt); app.UIRoot.SendKeys("e`"); - ciExpected.Attributes |= WinCon.CONSOLE_ATTRIBUTES.COMMON_LVB_UNDERSCORE; + ciExpected.Attributes |= WinCon.CONSOLE_ATTRIBUTES.COMMON_LVB_GRID_HORIZONTAL; ciActual = area.GetCharInfoAt(hConsole, pt); - Verify.AreEqual(ciExpected, ciActual, "Verify that underline got set."); + Verify.AreEqual(ciExpected, ciActual, "Verify that overline got set."); - Log.Comment("Clear underline (SGR.24)"); + Log.Comment("Clear overline (SGR.55)"); app.FillCursorPosition(hConsole, ref pt); app.UIRoot.SendKeys("d`"); - ciExpected.Attributes &= ~WinCon.CONSOLE_ATTRIBUTES.COMMON_LVB_UNDERSCORE; + ciExpected.Attributes &= ~WinCon.CONSOLE_ATTRIBUTES.COMMON_LVB_GRID_HORIZONTAL; ciActual = area.GetCharInfoAt(hConsole, pt); - Verify.AreEqual(ciExpected, ciActual, "Verify that underline got cleared."); + Verify.AreEqual(ciExpected, ciActual, "Verify that overline got cleared."); Log.Comment("Set negative image video (SGR.7)"); app.FillCursorPosition(hConsole, ref pt); @@ -426,14 +426,14 @@ private static void TestGraphicsCommands(CmdApp app, ViewportArea area, IntPtr h ciActual = area.GetCharInfoAt(hConsole, pt); Verify.AreEqual(ciExpected, ciActual, "Verify that we got set back to the original state."); - Log.Comment("Set multiple properties in the same message (SGR.1,37,43,4)"); + Log.Comment("Set multiple properties in the same message (SGR.1,37,43,53)"); app.FillCursorPosition(hConsole, ref pt); app.UIRoot.SendKeys("9`"); ciExpected.Attributes |= WinCon.CONSOLE_ATTRIBUTES.FOREGROUND_COLORS; ciExpected.Attributes |= WinCon.CONSOLE_ATTRIBUTES.FOREGROUND_INTENSITY; ciExpected.Attributes |= WinCon.CONSOLE_ATTRIBUTES.BACKGROUND_YELLOW; - ciExpected.Attributes |= WinCon.CONSOLE_ATTRIBUTES.COMMON_LVB_UNDERSCORE; + ciExpected.Attributes |= WinCon.CONSOLE_ATTRIBUTES.COMMON_LVB_GRID_HORIZONTAL; ciActual = area.GetCharInfoAt(hConsole, pt); Verify.AreEqual(ciExpected, ciActual, "Verify that we set foreground bright white, background yellow, and underscore in the same SGR command."); diff --git a/src/host/ut_host/TextBufferTests.cpp b/src/host/ut_host/TextBufferTests.cpp index 6755cc7b76e..6f4351b6c26 100644 --- a/src/host/ut_host/TextBufferTests.cpp +++ b/src/host/ut_host/TextBufferTests.cpp @@ -757,8 +757,8 @@ void TextBufferTests::TestMixedRgbAndLegacyUnderline() VERIFY_ARE_EQUAL(gci.LookupAttributeColors(attrA), std::make_pair(fgColor, bgColor)); VERIFY_ARE_EQUAL(gci.LookupAttributeColors(attrB), std::make_pair(fgColor, bgColor)); - VERIFY_ARE_EQUAL(attrA.GetLegacyAttributes() & COMMON_LVB_UNDERSCORE, 0); - VERIFY_ARE_EQUAL(attrB.GetLegacyAttributes() & COMMON_LVB_UNDERSCORE, COMMON_LVB_UNDERSCORE); + VERIFY_ARE_EQUAL(attrA.IsUnderlined(), false); + VERIFY_ARE_EQUAL(attrB.IsUnderlined(), true); wchar_t* reset = L"\x1b[0m"; stateMachine.ProcessString(reset); diff --git a/src/inc/conattrs.hpp b/src/inc/conattrs.hpp index 1ad1fa90302..06d2d9d3ebe 100644 --- a/src/inc/conattrs.hpp +++ b/src/inc/conattrs.hpp @@ -17,7 +17,7 @@ enum class ExtendedAttributes : BYTE Invisible = 0x08, CrossedOut = 0x10, // TODO:GH#2916 add support for these to the parser as well. - Underlined = 0x20, // _technically_ different from LVB_UNDERSCORE, see TODO:GH#2915 + Underlined = 0x20, DoublyUnderlined = 0x40, // Included for completeness, but not currently supported. Faint = 0x80, }; diff --git a/src/renderer/base/renderer.cpp b/src/renderer/base/renderer.cpp index c4e9d71d9c5..2bbbf220b47 100644 --- a/src/renderer/base/renderer.cpp +++ b/src/renderer/base/renderer.cpp @@ -865,6 +865,11 @@ IRenderEngine::GridLines Renderer::s_GetGridlines(const TextAttribute& textAttri { lines |= IRenderEngine::GridLines::Strikethrough; } + + if (textAttribute.IsUnderlined()) + { + lines |= IRenderEngine::GridLines::Underline; + } return lines; } diff --git a/src/terminal/adapter/ut_adapter/adapterTest.cpp b/src/terminal/adapter/ut_adapter/adapterTest.cpp index 6ecdfb7f0a4..e3c8746f650 100644 --- a/src/terminal/adapter/ut_adapter/adapterTest.cpp +++ b/src/terminal/adapter/ut_adapter/adapterTest.cpp @@ -1298,7 +1298,8 @@ class AdapterTest case DispatchTypes::GraphicsOptions::Underline: Log::Comment(L"Testing graphics 'Underline'"); _testGetSet->_attribute = TextAttribute{ 0 }; - _testGetSet->_expectedAttribute = TextAttribute{ COMMON_LVB_UNDERSCORE }; + _testGetSet->_expectedAttribute = TextAttribute{ 0 }; + _testGetSet->_expectedAttribute.SetUnderlined(true); break; case DispatchTypes::GraphicsOptions::Overline: Log::Comment(L"Testing graphics 'Overline'"); @@ -1331,7 +1332,8 @@ class AdapterTest break; case DispatchTypes::GraphicsOptions::NoUnderline: Log::Comment(L"Testing graphics 'No Underline'"); - _testGetSet->_attribute = TextAttribute{ COMMON_LVB_UNDERSCORE }; + _testGetSet->_attribute = TextAttribute{ 0 }; + _testGetSet->_attribute.SetUnderlined(true); _testGetSet->_expectedAttribute = TextAttribute{ 0 }; break; case DispatchTypes::GraphicsOptions::NoOverline: diff --git a/src/tools/vtapp/Program.cs b/src/tools/vtapp/Program.cs index 20cff98abb7..6b2017c004b 100644 --- a/src/tools/vtapp/Program.cs +++ b/src/tools/vtapp/Program.cs @@ -236,11 +236,11 @@ static void Main(string[] args) break; case 'e': Console.Write(CSI); - Console.Write("4m"); + Console.Write("53m"); break; case 'd': Console.Write(CSI); - Console.Write("24m"); + Console.Write("55m"); break; case 'r': Console.Write(CSI); @@ -260,7 +260,7 @@ static void Main(string[] args) break; case '9': Console.Write(CSI); - Console.Write("1;37;43;4m"); + Console.Write("1;37;43;53m"); break; case '(': Console.Write(CSI); From 14c94f5963b07962ab7f0573e6618f388f48820d Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Mon, 3 Aug 2020 15:01:36 -0500 Subject: [PATCH 016/266] Add a spec for per-profile tab colors (#7134) Co-authored-by: Mike Griese ## Summary of the Pull Request This spec is a subset of #5772, but specific to per-profile tab colors. We've had enough requests for that in the last few days that I want to pull that feature out into it's own spec, so we can get that approved and implemented in a future-proof way. > This spec describes a way to specify tab colors in a profile in a way that will > be forward compatible with theming the Terminal. This spec will be largely > dedicated to the design of a single setting, but within the context of theming. > ## PR Checklist * [x] Specs: #1337 * [x] References: #5772 * [x] I work here ## Detailed Description of the Pull Request / Additional comments _\*\*\* read the spec \*\*\*_ --- .../#1337 - Per-Profile Tab Colors.md | 146 ++++++++++++++++++ .../profile-tabColor-000.gif | Bin 0 -> 835167 bytes 2 files changed, 146 insertions(+) create mode 100644 doc/specs/#1337 - Per-Profile Tab Colors/#1337 - Per-Profile Tab Colors.md create mode 100644 doc/specs/#1337 - Per-Profile Tab Colors/profile-tabColor-000.gif diff --git a/doc/specs/#1337 - Per-Profile Tab Colors/#1337 - Per-Profile Tab Colors.md b/doc/specs/#1337 - Per-Profile Tab Colors/#1337 - Per-Profile Tab Colors.md new file mode 100644 index 00000000000..e2830babbe7 --- /dev/null +++ b/doc/specs/#1337 - Per-Profile Tab Colors/#1337 - Per-Profile Tab Colors.md @@ -0,0 +1,146 @@ +--- +author: Mike Griese @zadjii-msft +created on: 2020-07-31 +last updated: 2020-08-03 +issue id: #1337 +--- +# Per-Profile Tab Colors + +## Abstract + +This spec describes a way to specify tab colors in a profile in a way that will +be forward compatible with theming the Terminal. This spec will be largely +dedicated to the design of a single setting, but within the context of theming. + +## Inspiration + +Following the addition of the Tab Color Picker in [#3789], we've had numerous +requests for the ability to set the color of a tab directly within a profile. +While largely we're tracking theming in [#3327], including the specification of +a tab color, the theming spec ([#5772] )is very large and will take a while to +revise and approve. This spec is intended to pull a single point out from that +spec to make it more easily reviewable, and implement it in a way that will +continue working when we add support for themes in the future. + +## Solution Design + +To enable per-profile tab colors, we'll add a single setting: `tabColor`. For +now[[1](#user-content-footnote-1)], this setting will accept any +`#rrggbb` color string. + +Since each profile creates a `Pane` with a `TermControl`, we'll need to store +this color not in the `Tab`, but somewhere below `Pane`, so that when you switch +between Panes in a tab with different `tabColor`s, the color will update +automatically. When a new `TermControl` is created, we'll store this color in the +`TermControl`'s `Terminal` core. This is to support the future possibility of +setting the tab color via VT sequences. + +A Tab's color will be the result of layering a variety of sources, from the bottom up: + +Color | | Set by +-- | -- | -- +Runtime Color | _optional_ |Color Picker / `setTabColor` action +Control Tab Color | _optional_ | Profile's `tabColor`, or a color set by VT +Theme Tab Background | _optional_ | `tab.backgroundColor` in the theme +Tab Default Color | **default** | TabView in XAML + +Some examples: +* **Scenario 1**: The user has set `"tabColor": "#ff0000"` in their profile. + When they create tabs with that profile, instead of appearing in the default + color for the TabView, they'll be `#ff0000`. +* **Scenario 2**: The user has set `"tabColor": "#ff0000"` in their profile. + When they try to set the color for that tab (with the color picker) to + `#0000ff`, the tab's color is updated to reflect this new blue color. When + they clear the runtime color (with the color picker), the tab will return to + `#ff0000`. +* **Scenario 3**: The user has two profiles with colors set, one to `"tabColor": + "#ff0000"`, and the other with `"tabColor": "#00ff00"`. If they open these + profiles in two panes side-by side, the tab's color will update to reflect the + color from the currently-focused control. +* **Scenario 4**: The user has two profiles with colors set, one to `"tabColor": + "#ff0000"`, and the other with `"tabColor": "#00ff00"`. If they open these + profiles in two panes side-by side, and try to set the color for that tab + (with the color picker) to `#0000ff`, the tab's color is updated to reflect + this new blue color. Regardless of which pane is focused, the tab will be + blue. +* **Scenario 5**: The user has set `"tabColor": "#ff0000"` in their profile + ("Profile A"), and `"tab.backgroundColor": "#00ff00"`in their theme. When they + create tabs with "Profile A", the tabs will appear red. Other tabs (for + profiles without `tabColor` set) will appear green, using the color from the + theme. + + +## UI/UX Design + +In general, this is going to look exactly like the colored tabs look now. + +![preview](profile-tabColor-000.gif) + +## Capabilities + + + + + + + + + + + + + + + + + + + + + + +
Accessibility +N/A +
Security +N/A +
Reliability +No expected change +
Compatibility +This entire spec outlines how this feature is designed with a emphasis on future +compatibility. As such, there are no expected regressions in the future when we +do add support for themes. +
Performance, Power, and Efficiency +No expected change +
+ +## Potential Issues + +None expected. + +## Footnotes + +[1]: When full theming support is added, themes will +provide support for setting colors as one of a variety of values: + + * An `#rrggbb` string + * The system accent color + * The current background color of the Terminal + * A value from a given resource key from XAML + +When support for these other types of "smart" colors is added, then the profile +`tabColor` setting will also gracefully accept these values. + +## Future considerations + +* It's not out of the realm of possibility that someone might want to color each + _pane_'s color at runtime. In that case, the runtime color would be stored in + the `Pane`, not the `Tab`. + + + + + +[#1337]: https://github.com/microsoft/terminal/issues/1337 +[#3789]: https://github.com/microsoft/terminal/issues/3789 +[#3327]: https://github.com/microsoft/terminal/issues/3327 +[#5772]: https://github.com/microsoft/terminal/pull/5772 diff --git a/doc/specs/#1337 - Per-Profile Tab Colors/profile-tabColor-000.gif b/doc/specs/#1337 - Per-Profile Tab Colors/profile-tabColor-000.gif new file mode 100644 index 0000000000000000000000000000000000000000..2b3e04a65131d6729ae886aa2f4622105be2992f GIT binary patch literal 835167 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%0A*SZ{2<(k@hxlg{vbprt$#u=C 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 z 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 z zbbc?He=?)~*8MV#5E69gv!9c&It6zp{;Di3QY|ZX&7a`+7mRhvLj9L2gAy!C!UGyZUJ(-dm~jB4$jK=7rM(=%E&$TbZQiZ zEww`g6J3ebg|NxB7-NfsUYUwa>L(6AF(}s5Rh(=4nYtVkd|&~Q0Y#C7758o*OV3}&38@oz8~Lb zd)NBb`Ug7ZV2o>==YH&m%K#VvIE>YL041HLlzk|;E2eqkz?_~ivuM*Meao{LGNO_Y zDv<=uO*mKzohiLw_4K=kjW6UbqMIN-VvCD}e5?Ptuj87u=Q~mp;#|9Di$ylacd-J? z*QT|`^tha(0-yyHUQV;Ql8oR3Kqobv_@&Bz05k;p0V{4$V=P$%#XFPx2_flKBh_Xu zF#|p9kL#Z>6XE!zo=+Tfrs+_e;#|Xs#J=6~D*Ao@!)#gWD682I$)4+IbRHA4JSI)b zA&a=Au2Z2^8$wLTjjEYxMTg`s$X@xAp}%0|j=>6J9}Fl&!l`PlrdK?f1oN81hqGb+ ziz1*heDZNl1}B?R^OWrQ)#EK_75;t}S&g6SK~vay*ar zo>)Y4GFUzZR-B2P`qVIL(JXQ@k8CbeOp8{7WJZ1nx91bp?#02^;08}QdiB&2n@8S7Pt=g8Fhh<|bDe{|IwPf` zRyo-}+{Ip0{LUs$7*Jw%WxuM;@YORkBz%jVIW-7~83gIp(U%5Nm2i`Hc6*l+AWLH-0 z!rch3=6Zq!ba{S>g5J7oApyGVC0(p{AuWEk6EDlLn*s;#pC{<|w~qtl(Whr-oe4D} z5tAD*P%KH46|Ha*4M@U$&t?z2Ss$Jd@hL;OfS z!TOu3&>VDhBqwh~Nd%6v3k7Na(i_!vwgYK#zUTufrlr5_p$T@|4iQv`FtpCFYf2;< zL5Yy&c`Lrw$CbXXU;4Fm*b3SSW@SBfP6c0QeYoaBwPgOHSkH z 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 E2T5tfAOHXW literal 0 HcmV?d00001 diff --git a/doc/specs/#6899 - Action IDs/data-mockup-actions-and-ids-and-keys.png b/doc/specs/#6899 - Action IDs/data-mockup-actions-and-ids-and-keys.png new file mode 100644 index 0000000000000000000000000000000000000000..f1148daaf3ce440d7e71fa64f944fedae35f8f25 GIT binary patch literal 133455 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%0Dx3Jy=SSKPKp>P^( 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 literal 0 HcmV?d00001 From a34cfa4e78c46e1a964ede019c97448b44068928 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Wed, 12 Aug 2020 08:40:38 -0500 Subject: [PATCH 043/266] Mini-spec for New Tab Menu Customization (#5888) * This is a mini-spec for how I see this working * good bot * These were some typos * Addd a future consideration about the command palette and commands * Update spec to reflect discussion with Carlos * update spec to reflect investigations in Command Palette Addenda 1 * add references to #6899, and minor bits of review feedback * add `remainingProfiles` as a way of adding all the user's other profiles quickly to the menu as well * clarify why we're not doing it in the profiles list * no two commits do not contain a misspelling of separate --- .../#1571 - New Tab Menu Customization.md | 300 ++++++++++++++++++ .../Menu-Customization-000.png | Bin 0 -> 46941 bytes 2 files changed, 300 insertions(+) create mode 100644 doc/specs/#1571 - New Tab Menu Customization/#1571 - New Tab Menu Customization.md create mode 100644 doc/specs/#1571 - New Tab Menu Customization/Menu-Customization-000.png diff --git a/doc/specs/#1571 - New Tab Menu Customization/#1571 - New Tab Menu Customization.md b/doc/specs/#1571 - New Tab Menu Customization/#1571 - New Tab Menu Customization.md new file mode 100644 index 00000000000..210db5499c0 --- /dev/null +++ b/doc/specs/#1571 - New Tab Menu Customization/#1571 - New Tab Menu Customization.md @@ -0,0 +1,300 @@ +--- +author: Mike Griese @zadjii-msft +created on: 2020-5-13 +last updated: 2020-08-04 +issue id: 1571 +--- + +# New Tab Menu Customization + +## Abstract + +Many users have lots and _lots_ of profiles that they use. Some of these +profiles the user might not use that frequently. When that happens, the new tab +dropdown can become quite cluttered. + +A common ask is for the ability to reorder and reorganize this dropdown. This +spec provides a design for how the user might be able to specify the +customization in their settings. + +## Inspiration + +Largely, this spec was inspired by discussion in +[#1571](https://github.com/microsoft/terminal/issues/1571#issuecomment-519504048) +and the _many_ linked threads. + +## Solution Design + +This design proposes adding a new setting `"newTabMenu"`. When unset, (the +default), the new tab menu is populated with all the profiles, in the order they +appear in the users settings file. When set, this enables the user to control +the appearance of the new tab dropdown. Let's take a look at an example: + +```json +{ + "profiles":{ ... }, + "newTabMenu": [ + { "type":"profile", "profile": "cmd" }, + { "type":"profile", "profile": "Windows PowerShell" }, + { "type":"separator" }, + { + "type":"folder", + "name": "ssh", + "icon": "C:\\path\\to\\icon.png", + "entries":[ + { "type":"profile", "profile": "Host 1" }, + { "type":"profile", "profile": "8.8.8.8" }, + { "type":"profile", "profile": "Host 2" } + ] + }, + { "type":"separator" }, + { "type":"profile", "profile": "Ubuntu-18.04" }, + { "type":"profile", "profile": "Fedora" } + ] +} +``` + +If a user were to use this as their new tab menu, that they would get is a menu +that looks like this: + +![fig 1](Menu-Customization-000.png) + +_fig 1_: A _very rough_ mockup of what this feature might look like + +There are five `type`s of objects in this menu: +* `"type":"profile"`: This is a profile. Clicking on this entry will open a new + tab, with that profile. The profile is identified with the `"profile"` + parameter, which accepts either a profile `name` or GUID. The icon for this + entry will be the profile's icon, and the text on the entry will be the + profile's name. +* `"type":"separator"`: This represents a XAML `MenuFlyoutSeparator`, enabling + the user to visually space out entries. +* `"type":"folder"`: This represents a nested menu of entries. + - The `"name"` property provides a string of text to display for the group. + - The `"icon"` property provides a path to a image to use as the icon. This + property is optional. + - The `"entries"` property specifies a list of menu entries that will appear + nested under this entry. This can contain other `"type":"folder"` groups as + well! +* `"type":"action"`: This represents a menu entry that should execute a specific + `ShortcutAction`. + - the `id` property will specify the global action ID (see [#6899], [#7175]) + to identify the action to perform when the user selects the entry. Actions + with invalid IDs will be ignored and omitted from the list. + - The text for this entry will be the action's label (which is + either provided as the `"name"` in the global list of actions, or the + generated name if no `name` was provided) + - The icon for this entry will similarly re-use the action's `icon`. +* `"type":"remainingProfiles"`: This is a special type of entry that will be + expanded to contain one `"type":"profile"` entry for every profile that was + not already listed in the menu. This will allow users to add one entry for + just "all the profiles they haven't manually added to the menu". + - This type of entry can only be specified once - trying to add it to the menu + twice will raise a warning, and ignore all but the first `remainingProfiles` + entry. + - This type of entry can also be set inside a `folder` entry, allowing users + to highlight only a couple profiles in the top-level of the menu, but + enabling all other profiles to also be accessible. + - The "name" of these entries will simply be the name of the profile + - The "icon" of these entries will simply be the profile's icon + +The "default" new tab menu could be imagined as the following blob of json: + +```json +{ + "newTabMenu": [ + { "type":"remainingProfiles" } + ] +} +``` + +### Other considerations + +Also considered during the investigation for this feature was re-using the list +of profiles to expose the structure of the new tab menu. For example, doing +something like: + +```json +"profiles": { + "defaults": {}, + "list": + [ + { "name": "cmd" }, + { "name": "powershell" }, + { "type": "separator" }, + { + "type": "folder" , + "profiles": [ + { "name": "ubuntu" } + ] + } + ] +} +``` + +This option was not pursued because we felt that it needlessly complicated the +contents of the list of profiles objects. We'd rather have the `profiles` list +exclusively contain `Profile` objects, and have other elements of the json +_refer_ to those profiles. What if someone would like to have an action that +opened a new tab with profile index 4, and then they set that action as entry 4 +in the profile's list? That would certainly be some sort of unexpected behavior. + +Additionally, what if someone wants to have an entry that opens a tab with one +pane with one profile in it, and another pane with different profile in it? Or +what if they want the same profile to appear twice in the menu? + +By overloading the structure of the `profiles` list, we're forcing all other +consumers of the list of profiles to care about the structure of the elements of +the list. These other consumers should only really care about the list of +profiles, and not necessarily how they're structured in the new tab dropdown. +Furthermore, it complicates the list of profiles, by adding actions intermixed +with the profiles. + +The design chosen in this spec more cleanly separates the responsibilities of +the list of profiles and the contents of the new tab menu. This way, each object +can be defined independent of the structure of the other. + +## UI/UX Design + +See the above _figure 1_. + +The profile's `icon` will also appear as the icon on `profile` entries. If +there's a keybinding bound to open a new tab with that profile, then that will +also be added to the `MenuFlyoutItem` as the accelerator text, similar to the +text we have nowadays. + +Beneath the list of profiles will _always_ be the same "Settings", "Feedback" +and "About" entries, separated by a `MenuFlyoutSeparator`. This is consistent +with the UI as it exists with no customization. These entries cannot be removed +with this feature, only the list of profiles customized. + +## Capabilities + +### Accessibility + +This menu will be added to the XAML tree in the same fashion as the current new +tab flyout, so there should be no dramatic change here. + +### Security + +_(no change expected)_ + +### Reliability + +_(no change expected)_ + +### Compatibility + +_(no change expected)_ + +### Performance, Power, and Efficiency + +_(no change expected)_ + +## Potential Issues + +Currently, the `openTab` and `splitPane` keybindings will accept a `index` +parameter to say either: +* "Create a new tab/pane with the N'th profile" +* "Create a new tab/pane with the profile at index N in the new +tab dropdown". + +These two were previously synonymous, as the N'th profile was always the N'th in +the dropdown. However, with this change, we'll be changing the meaning of that +argument to mean explicitly the first option - "Open a tab/pane with the N'th +profile". + +A previous version of this spec considered changing the meaning of that +parameter to mean "open the entry at index N", the second option. However, in +[Command Palette, Addendum 1], we found that naming that command would become +unnecessarily complex. + +To cover that above scenario, we could consider adding an `index` parameter to +the `openNewTabDropdown` action. If specified, that would open either the N'th +action in the dropdown (ignoring separators), or open the dropdown with the n'th +item selected. + +The N'th entry in the menu won't always be a profile: it might be a folder with +more options, or it might be an action (that might not be opening a new tab/pane +at all). + +Given all the above scenarios, `openNewTabDropdown` with an `"index":N` +parameter will behave in the following ways. If the Nth top-level entry in the +new tab menu is a: +* `"type":"profile"`: perform the `newTab` or `splitPane` action with that profile. +* `"type":"folder"`: Focus the first element in the sub menu, so the user could + navigate it with the keyboard. +* `"type":"separator"`: Ignore these when counting top-level entries. +* `"type":"action"`: Perform the action. + +So for example: + +``` +New Tab Button ▽ +├─ Folder 1 +│ └─ Profile A +│ └─ Action B +├─ Separator +├─ Folder 2 +│ └─ Profile C +│ └─ Profile D +├─ Action E +└─ Profile F +``` + +And assuming the user has bound: +```json +{ + "bindings": + [ + { "command": { "action": "openNewTabDropdown", "index": 0 }, "keys": "ctrl+shift+1" }, + { "command": { "action": "openNewTabDropdown", "index": 1 }, "keys": "ctrl+shift+2" }, + { "command": { "action": "openNewTabDropdown", "index": 2 }, "keys": "ctrl+shift+3" }, + { "command": { "action": "openNewTabDropdown", "index": 3 }, "keys": "ctrl+shift+4" }, + ] +} +``` + +* ctrl+shift+1 focuses "Profile A", but the user needs to press + enter/space to creates a new tab/split +* ctrl+shift+2 focuses "Profile C", but the user needs to press + enter/space to creates a new tab/split +* ctrl+shift+3 performs Action E +* ctrl+shift+4 Creates a new tab/split with Profile F + +## Future considerations + +* The user could set a `"name"`/`"text"`, or `"icon"` property to these menu + items manually, to override the value from the profile or action. These + settings would be totally optional, but it's not unreasonable that someone + might want this. +* We may want to consider adding a default icon for all folders or actions in + the menu. For example, a folder (like 📁) for `folder` entries, or something + like ⚡ for actions. We'll leave these unset by default, and evaluate setting + these icons by default in the future. +* Something considered during review was a way to specify "All my WSL profiles". + Maybe the user wants to have all their profiles generated by the WSL Distro + Generator appear in a "WSL" folder. This would likely require a more elaborate + filtering syntax, to be able to select only profiles where a certain property + has a specific value. Consider the user who has multiple "SSH + me@\.com" profiles, and they want all their "SSH\*" profiles to + appear in an "SSH" folder. This feels out-of-scope for this spec. +* A similar structure could potentially also be used for customizing the context + menu within a control, or the context menu for the tab. (see [#3337]) + - In both of those cases, it might be important to somehow refer to the + context of the current tab or control in the json. Think for example about + "Close tab" or "Close other tabs" - currently, those work by _knowing_ which + tab the "action" is specified for, not by actually using a `closeTab` action. + In the future, they might need to be implemented as something like + - Close Tab: `{ "action": "closeTab", "index": "${selectedTab.index}" }` + - Close Other Tabs: `{ "action": "closeTabs", "otherThan": "${selectedTab.index}" }` + - Close Tabs to the Right: `{ "action": "closeTabs", "after": "${selectedTab.index}" }` + + + +[#2046]: https://github.com/microsoft/terminal/issues/2046 +[Command Palette, Addendum 1]: https://github.com/microsoft/terminal/blob/master/doc/specs/%232046%20-%20Unified%20keybindings%20and%20commands%2C%20and%20synthesized%20action%20names.md + +[#3337]: https://github.com/microsoft/terminal/issues/3337 +[#6899]: https://github.com/microsoft/terminal/issues/6899 +[#7175]: https://github.com/microsoft/terminal/issues/7175 diff --git a/doc/specs/#1571 - New Tab Menu Customization/Menu-Customization-000.png b/doc/specs/#1571 - New Tab Menu Customization/Menu-Customization-000.png new file mode 100644 index 0000000000000000000000000000000000000000..54ade166f34e15377326e2c0f18feeb7bb0ea8fb GIT binary patch literal 46941 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�%D&*n=DESo9x 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
j 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 literal 0 HcmV?d00001 From a2721c104343575945320b0df0d4809fc4f0cdce Mon Sep 17 00:00:00 2001 From: Leonard Hecker Date: Wed, 12 Aug 2020 15:46:53 +0200 Subject: [PATCH 044/266] Fixed #3799: Introduce sendInput command (#7249) ## Summary of the Pull Request This PR enables users to send arbitrary text input to the shell via a keybinding. ## PR Checklist * [x] Closes #3799 * [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. * [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: #3799 ## Detailed Description of the Pull Request / Additional comments ## Validation Steps Performed Added the following keybindings: ```json { "keys": "p", "command": { "action": "sendInput", "input": "foobar" } }, { "keys": "q", "command": { "action": "sendInput", "input": "\u001b[A" } }, ``` Ensured that when pressing P "foobar" is echoed to the shell and when pressing Q the shell history is being navigated backwards. --- doc/cascadia/SettingsSchema.md | 1 + doc/cascadia/profiles.schema.json | 24 ++++++++++++++ src/cascadia/TerminalApp/ActionAndArgs.cpp | 5 +++ src/cascadia/TerminalApp/ActionArgs.cpp | 13 ++++++++ src/cascadia/TerminalApp/ActionArgs.h | 32 +++++++++++++++++++ src/cascadia/TerminalApp/ActionArgs.idl | 5 +++ .../TerminalApp/AppActionHandlers.cpp | 15 +++++++++ .../TerminalApp/DebugTapConnection.cpp | 26 ++------------- .../Resources/en-US/Resources.resw | 4 +++ .../TerminalApp/ShortcutActionDispatch.cpp | 6 ++++ .../TerminalApp/ShortcutActionDispatch.h | 1 + .../TerminalApp/ShortcutActionDispatch.idl | 2 ++ src/cascadia/TerminalApp/TerminalPage.cpp | 1 + src/cascadia/TerminalApp/TerminalPage.h | 1 + src/cascadia/TerminalApp/Utils.cpp | 25 +++++++++++++++ src/cascadia/TerminalApp/Utils.h | 7 ++++ .../TerminalApp/lib/TerminalAppLib.vcxproj | 1 + .../lib/TerminalAppLib.vcxproj.filters | 3 +- src/cascadia/TerminalControl/TermControl.cpp | 27 +++++++++++++--- src/cascadia/TerminalControl/TermControl.h | 4 ++- src/cascadia/TerminalControl/TermControl.idl | 1 + 21 files changed, 175 insertions(+), 29 deletions(-) create mode 100644 src/cascadia/TerminalApp/Utils.cpp diff --git a/doc/cascadia/SettingsSchema.md b/doc/cascadia/SettingsSchema.md index 9c58edc89f4..66e5cb67113 100644 --- a/doc/cascadia/SettingsSchema.md +++ b/doc/cascadia/SettingsSchema.md @@ -142,6 +142,7 @@ For commands with arguments: | `scrollUp` | Move the screen up. | | | | | `scrollUpPage` | Move the screen up a whole page. | | | | | `scrollDownPage` | Move the screen down a whole page. | | | | +| `sendInput` | Sends some text input to the shell. | `input` | string | The text input to feed into the shell.
ANSI escape sequences may be used. Escape codes like `\x1b` must be written as `\u001b`.
For instance the input `"text\n"` will write "text" followed by a newline. `"\u001b[D"` will behave as if the left arrow button had been pressed. | | `splitPane` | Halve the size of the active pane and open another. Without any arguments, this will open the default profile in the new pane. | 1. `split`*
2. `commandLine`
3. `startingDirectory`
4. `tabTitle`
5. `index`
6. `profile`
7. `splitMode` | 1. `vertical`, `horizontal`, `auto`
2. string
3. string
4. string
5. integer
6. string
7. string | 1. How the pane will split. `auto` will split in the direction that provides the most surface area.
2. Executable run within the pane.
3. Directory in which the pane will open.
4. Title of the tab when the new pane is focused.
5. Profile that will open based on its position in the dropdown (starting at 0).
6. Profile that will open based on its GUID or name.
7. Controls how the pane splits. Only accepts `duplicate` which will duplicate the focused pane's profile into a new pane. | | `switchToTab` | Open a specific tab depending on index. | `index`* | integer | Tab that will open based on its position in the tab bar (starting at 0). | | `toggleFullscreen` | Switch between fullscreen and default window sizes. | | | | diff --git a/doc/cascadia/profiles.schema.json b/doc/cascadia/profiles.schema.json index f1e1843bf96..e2253724a54 100644 --- a/doc/cascadia/profiles.schema.json +++ b/doc/cascadia/profiles.schema.json @@ -52,6 +52,7 @@ "scrollDownPage", "scrollUp", "scrollUpPage", + "sendInput", "splitPane", "switchToTab", "toggleFocusMode", @@ -230,6 +231,28 @@ ], "required": [ "direction" ] }, + "SendInputAction": { + "description": "Arguments corresponding to a Send Input Action", + "allOf": [ + { + "$ref": "#/definitions/ShortcutAction" + }, + { + "properties": { + "action": { + "type": "string", + "pattern": "sendInput" + }, + "input": { + "type": "string", + "default": "", + "description": "The text input to feed into the shell. ANSI escape sequences may be used. Escape codes like \\x1b must be written as \\u001b." + } + } + } + ], + "required": [ "input" ] + }, "SplitPaneAction": { "description": "Arguments corresponding to a Split Pane Action", "allOf": [ @@ -390,6 +413,7 @@ { "$ref": "#/definitions/SwitchToTabAction" }, { "$ref": "#/definitions/MoveFocusAction" }, { "$ref": "#/definitions/ResizePaneAction" }, + { "$ref": "#/definitions/SendInputAction" }, { "$ref": "#/definitions/SplitPaneAction" }, { "$ref": "#/definitions/OpenSettingsAction" }, { "$ref": "#/definitions/SetTabColorAction" }, diff --git a/src/cascadia/TerminalApp/ActionAndArgs.cpp b/src/cascadia/TerminalApp/ActionAndArgs.cpp index fadadac3b24..150a31c92ea 100644 --- a/src/cascadia/TerminalApp/ActionAndArgs.cpp +++ b/src/cascadia/TerminalApp/ActionAndArgs.cpp @@ -27,6 +27,7 @@ static constexpr std::string_view ScrolluppageKey{ "scrollUpPage" }; static constexpr std::string_view ScrolldownpageKey{ "scrollDownPage" }; static constexpr std::string_view SwitchToTabKey{ "switchToTab" }; static constexpr std::string_view OpenSettingsKey{ "openSettings" }; // TODO GH#2557: Add args for OpenSettings +static constexpr std::string_view SendInputKey{ "sendInput" }; static constexpr std::string_view SplitPaneKey{ "splitPane" }; static constexpr std::string_view TogglePaneZoomKey{ "togglePaneZoom" }; static constexpr std::string_view ResizePaneKey{ "resizePane" }; @@ -90,6 +91,7 @@ namespace winrt::TerminalApp::implementation { ToggleFocusModeKey, ShortcutAction::ToggleFocusMode }, { ToggleFullscreenKey, ShortcutAction::ToggleFullscreen }, { ToggleAlwaysOnTopKey, ShortcutAction::ToggleAlwaysOnTop }, + { SendInputKey, ShortcutAction::SendInput }, { SplitPaneKey, ShortcutAction::SplitPane }, { TogglePaneZoomKey, ShortcutAction::TogglePaneZoom }, { SetTabColorKey, ShortcutAction::SetTabColor }, @@ -125,6 +127,8 @@ namespace winrt::TerminalApp::implementation { ShortcutAction::AdjustFontSize, winrt::TerminalApp::implementation::AdjustFontSizeArgs::FromJson }, + { ShortcutAction::SendInput, winrt::TerminalApp::implementation::SendInputArgs::FromJson }, + { ShortcutAction::SplitPane, winrt::TerminalApp::implementation::SplitPaneArgs::FromJson }, { ShortcutAction::OpenSettings, winrt::TerminalApp::implementation::OpenSettingsArgs::FromJson }, @@ -284,6 +288,7 @@ namespace winrt::TerminalApp::implementation { ShortcutAction::ToggleFocusMode, RS_(L"ToggleFocusModeCommandKey") }, { ShortcutAction::ToggleFullscreen, RS_(L"ToggleFullscreenCommandKey") }, { ShortcutAction::ToggleAlwaysOnTop, RS_(L"ToggleAlwaysOnTopCommandKey") }, + { ShortcutAction::SendInput, L"" }, { ShortcutAction::SplitPane, RS_(L"SplitPaneCommandKey") }, { ShortcutAction::TogglePaneZoom, RS_(L"TogglePaneZoomCommandKey") }, { ShortcutAction::Invalid, L"" }, diff --git a/src/cascadia/TerminalApp/ActionArgs.cpp b/src/cascadia/TerminalApp/ActionArgs.cpp index d6e7219fd13..1bc3983481d 100644 --- a/src/cascadia/TerminalApp/ActionArgs.cpp +++ b/src/cascadia/TerminalApp/ActionArgs.cpp @@ -13,6 +13,7 @@ #include "ResizePaneArgs.g.cpp" #include "MoveFocusArgs.g.cpp" #include "AdjustFontSizeArgs.g.cpp" +#include "SendInputArgs.g.cpp" #include "SplitPaneArgs.g.cpp" #include "OpenSettingsArgs.g.cpp" #include "SetColorSchemeArgs.g.cpp" @@ -21,6 +22,8 @@ #include "ExecuteCommandlineArgs.g.cpp" #include "ToggleTabSwitcherArgs.g.h" +#include "Utils.h" + #include namespace winrt::TerminalApp::implementation @@ -167,6 +170,16 @@ namespace winrt::TerminalApp::implementation } } + winrt::hstring SendInputArgs::GenerateName() const + { + // The string will be similar to the following: + // * "Send Input: ...input..." + + auto escapedInput = VisualizeControlCodes(_Input); + auto name = fmt::format(std::wstring_view(RS_(L"SendInputCommandKey")), escapedInput); + return winrt::hstring{ name }; + } + winrt::hstring SplitPaneArgs::GenerateName() const { // The string will be similar to the following: diff --git a/src/cascadia/TerminalApp/ActionArgs.h b/src/cascadia/TerminalApp/ActionArgs.h index 7c768d58054..d52cc3f4494 100644 --- a/src/cascadia/TerminalApp/ActionArgs.h +++ b/src/cascadia/TerminalApp/ActionArgs.h @@ -13,6 +13,7 @@ #include "ResizePaneArgs.g.h" #include "MoveFocusArgs.g.h" #include "AdjustFontSizeArgs.g.h" +#include "SendInputArgs.g.h" #include "SplitPaneArgs.g.h" #include "OpenSettingsArgs.g.h" #include "SetColorSchemeArgs.g.h" @@ -270,6 +271,37 @@ namespace winrt::TerminalApp::implementation } }; + struct SendInputArgs : public SendInputArgsT + { + SendInputArgs() = default; + GETSET_PROPERTY(winrt::hstring, Input, L""); + + static constexpr std::string_view InputKey{ "input" }; + + public: + hstring GenerateName() const; + + bool Equals(const IActionArgs& other) + { + if (auto otherAsUs = other.try_as(); otherAsUs) + { + return otherAsUs->_Input == _Input; + } + return false; + }; + static FromJsonResult FromJson(const Json::Value& json) + { + // LOAD BEARING: Not using make_self here _will_ break you in the future! + auto args = winrt::make_self(); + JsonUtils::GetValueForKey(json, InputKey, args->_Input); + if (args->_Input.empty()) + { + return { nullptr, { ::TerminalApp::SettingsLoadWarnings::MissingRequiredParameter } }; + } + return { *args, {} }; + } + }; + struct SplitPaneArgs : public SplitPaneArgsT { SplitPaneArgs() = default; diff --git a/src/cascadia/TerminalApp/ActionArgs.idl b/src/cascadia/TerminalApp/ActionArgs.idl index a460d712a92..ee50771eb94 100644 --- a/src/cascadia/TerminalApp/ActionArgs.idl +++ b/src/cascadia/TerminalApp/ActionArgs.idl @@ -94,6 +94,11 @@ namespace TerminalApp Int32 Delta { get; }; }; + [default_interface] runtimeclass SendInputArgs : IActionArgs + { + String Input { get; }; + }; + [default_interface] runtimeclass SplitPaneArgs : IActionArgs { SplitState SplitStyle { get; }; diff --git a/src/cascadia/TerminalApp/AppActionHandlers.cpp b/src/cascadia/TerminalApp/AppActionHandlers.cpp index 19a8c44f2ad..80a06e733de 100644 --- a/src/cascadia/TerminalApp/AppActionHandlers.cpp +++ b/src/cascadia/TerminalApp/AppActionHandlers.cpp @@ -89,6 +89,21 @@ namespace winrt::TerminalApp::implementation args.Handled(true); } + void TerminalPage::_HandleSendInput(const IInspectable& /*sender*/, + const TerminalApp::ActionEventArgs& args) + { + if (args == nullptr) + { + args.Handled(false); + } + else if (const auto& realArgs = args.ActionArgs().try_as()) + { + const auto termControl = _GetActiveControl(); + termControl.SendInput(realArgs.Input()); + args.Handled(true); + } + } + void TerminalPage::_HandleSplitPane(const IInspectable& /*sender*/, const TerminalApp::ActionEventArgs& args) { diff --git a/src/cascadia/TerminalApp/DebugTapConnection.cpp b/src/cascadia/TerminalApp/DebugTapConnection.cpp index 21994920ecd..d149ad46213 100644 --- a/src/cascadia/TerminalApp/DebugTapConnection.cpp +++ b/src/cascadia/TerminalApp/DebugTapConnection.cpp @@ -3,6 +3,7 @@ #include "pch.h" #include "DebugTapConnection.h" +#include "Utils.h" using namespace ::winrt::Microsoft::Terminal::TerminalConnection; using namespace ::winrt::Windows::Foundation; @@ -91,36 +92,15 @@ namespace winrt::Microsoft::TerminalApp::implementation return ConnectionState::Failed; } - static std::wstring _sanitizeString(const std::wstring_view str) - { - std::wstring newString{ str.begin(), str.end() }; - for (auto& ch : newString) - { - if (ch < 0x20) - { - ch += 0x2400; - } - else if (ch == 0x20) - { - ch = 0x2423; // replace space with ␣ - } - else if (ch == 0x7f) - { - ch = 0x2421; // replace del with ␡ - } - } - return newString; - } - void DebugTapConnection::_OutputHandler(const hstring str) { - _TerminalOutputHandlers(_sanitizeString(str)); + _TerminalOutputHandlers(VisualizeControlCodes(str)); } // Called by the DebugInputTapConnection to print user input void DebugTapConnection::_PrintInput(const hstring& str) { - auto clean{ _sanitizeString(str) }; + auto clean{ VisualizeControlCodes(str) }; auto formatted{ wil::str_printf(L"\x1b[91m%ls\x1b[m", clean.data()) }; _TerminalOutputHandlers(formatted); } diff --git a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw index c891d53df6a..c8951fac9f2 100644 --- a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw +++ b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw @@ -449,6 +449,10 @@ New tab + + Send Input: "{0}" + {0} will be replaced with a string of input as defined by the user + Split pane diff --git a/src/cascadia/TerminalApp/ShortcutActionDispatch.cpp b/src/cascadia/TerminalApp/ShortcutActionDispatch.cpp index e8b9eb778c4..20a43791c2d 100644 --- a/src/cascadia/TerminalApp/ShortcutActionDispatch.cpp +++ b/src/cascadia/TerminalApp/ShortcutActionDispatch.cpp @@ -113,6 +113,12 @@ namespace winrt::TerminalApp::implementation break; } + case ShortcutAction::SendInput: + { + _SendInputHandlers(*this, *eventArgs); + break; + } + case ShortcutAction::SplitVertical: case ShortcutAction::SplitHorizontal: case ShortcutAction::SplitPane: diff --git a/src/cascadia/TerminalApp/ShortcutActionDispatch.h b/src/cascadia/TerminalApp/ShortcutActionDispatch.h index fa139848e63..9da3aadcdf2 100644 --- a/src/cascadia/TerminalApp/ShortcutActionDispatch.h +++ b/src/cascadia/TerminalApp/ShortcutActionDispatch.h @@ -35,6 +35,7 @@ namespace winrt::TerminalApp::implementation TYPED_EVENT(SwitchToTab, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs); TYPED_EVENT(NextTab, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs); TYPED_EVENT(PrevTab, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs); + TYPED_EVENT(SendInput, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs); TYPED_EVENT(SplitPane, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs); TYPED_EVENT(TogglePaneZoom, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs); TYPED_EVENT(AdjustFontSize, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs); diff --git a/src/cascadia/TerminalApp/ShortcutActionDispatch.idl b/src/cascadia/TerminalApp/ShortcutActionDispatch.idl index b0341d4bf81..e13c0433565 100644 --- a/src/cascadia/TerminalApp/ShortcutActionDispatch.idl +++ b/src/cascadia/TerminalApp/ShortcutActionDispatch.idl @@ -20,6 +20,7 @@ namespace TerminalApp PrevTab, SplitVertical, SplitHorizontal, + SendInput, SplitPane, TogglePaneZoom, SwitchToTab, @@ -71,6 +72,7 @@ namespace TerminalApp event Windows.Foundation.TypedEventHandler SwitchToTab; event Windows.Foundation.TypedEventHandler NextTab; event Windows.Foundation.TypedEventHandler PrevTab; + event Windows.Foundation.TypedEventHandler SendInput; event Windows.Foundation.TypedEventHandler SplitPane; event Windows.Foundation.TypedEventHandler TogglePaneZoom; event Windows.Foundation.TypedEventHandler AdjustFontSize; diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index 3838e4ccf50..22547b2e005 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -889,6 +889,7 @@ namespace winrt::TerminalApp::implementation _actionDispatch->ScrollDown({ this, &TerminalPage::_HandleScrollDown }); _actionDispatch->NextTab({ this, &TerminalPage::_HandleNextTab }); _actionDispatch->PrevTab({ this, &TerminalPage::_HandlePrevTab }); + _actionDispatch->SendInput({ this, &TerminalPage::_HandleSendInput }); _actionDispatch->SplitPane({ this, &TerminalPage::_HandleSplitPane }); _actionDispatch->TogglePaneZoom({ this, &TerminalPage::_HandleTogglePaneZoom }); _actionDispatch->ScrollUpPage({ this, &TerminalPage::_HandleScrollUpPage }); diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h index 984f1064245..d89f96ca931 100644 --- a/src/cascadia/TerminalApp/TerminalPage.h +++ b/src/cascadia/TerminalApp/TerminalPage.h @@ -203,6 +203,7 @@ namespace winrt::TerminalApp::implementation void _HandleScrollDown(const IInspectable& sender, const TerminalApp::ActionEventArgs& args); void _HandleNextTab(const IInspectable& sender, const TerminalApp::ActionEventArgs& args); void _HandlePrevTab(const IInspectable& sender, const TerminalApp::ActionEventArgs& args); + void _HandleSendInput(const IInspectable& sender, const TerminalApp::ActionEventArgs& args); void _HandleSplitPane(const IInspectable& sender, const TerminalApp::ActionEventArgs& args); void _HandleTogglePaneZoom(const IInspectable& sender, const TerminalApp::ActionEventArgs& args); void _HandleScrollUpPage(const IInspectable& sender, const TerminalApp::ActionEventArgs& args); diff --git a/src/cascadia/TerminalApp/Utils.cpp b/src/cascadia/TerminalApp/Utils.cpp new file mode 100644 index 00000000000..46f07b9bd93 --- /dev/null +++ b/src/cascadia/TerminalApp/Utils.cpp @@ -0,0 +1,25 @@ +// Copyright (c) Microsoft Corporation +// Licensed under the MIT license. + +#include "pch.h" +#include "Utils.h" + +std::wstring VisualizeControlCodes(std::wstring str) noexcept +{ + for (auto& ch : str) + { + if (ch < 0x20) + { + ch += 0x2400; + } + else if (ch == 0x20) + { + ch = 0x2423; // replace space with ␣ + } + else if (ch == 0x7f) + { + ch = 0x2421; // replace del with ␡ + } + } + return str; +} diff --git a/src/cascadia/TerminalApp/Utils.h b/src/cascadia/TerminalApp/Utils.h index cb23bac450d..91915804139 100644 --- a/src/cascadia/TerminalApp/Utils.h +++ b/src/cascadia/TerminalApp/Utils.h @@ -115,3 +115,10 @@ TIconSource GetColoredIcon(const winrt::hstring& path) return nullptr; } + +std::wstring VisualizeControlCodes(std::wstring str) noexcept; + +inline std::wstring VisualizeControlCodes(std::wstring_view str) noexcept +{ + return VisualizeControlCodes(std::wstring{ str }); +} diff --git a/src/cascadia/TerminalApp/lib/TerminalAppLib.vcxproj b/src/cascadia/TerminalApp/lib/TerminalAppLib.vcxproj index f3c98e58e4e..aecf0ef0847 100644 --- a/src/cascadia/TerminalApp/lib/TerminalAppLib.vcxproj +++ b/src/cascadia/TerminalApp/lib/TerminalAppLib.vcxproj @@ -189,6 +189,7 @@ + ../TerminalSettings.idl diff --git a/src/cascadia/TerminalApp/lib/TerminalAppLib.vcxproj.filters b/src/cascadia/TerminalApp/lib/TerminalAppLib.vcxproj.filters index fea379bc66c..9a80a146c43 100644 --- a/src/cascadia/TerminalApp/lib/TerminalAppLib.vcxproj.filters +++ b/src/cascadia/TerminalApp/lib/TerminalAppLib.vcxproj.filters @@ -59,6 +59,7 @@ + settings @@ -202,4 +203,4 @@ app - \ No newline at end of file + diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index 245413fe75c..058e478bc72 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -104,8 +104,9 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation }; _connectionOutputEventToken = _connection.TerminalOutput(onReceiveOutputFn); - auto inputFn = std::bind(&TermControl::_SendInputToConnection, this, std::placeholders::_1); - _terminal->SetWriteInputCallback(inputFn); + _terminal->SetWriteInputCallback([this](std::wstring& wstr) { + _SendInputToConnection(wstr); + }); _terminal->UpdateSettings(settings); @@ -296,6 +297,18 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation } } } + + // Method Description: + // - Writes the given sequence as input to the active terminal connection, + // Arguments: + // - wstr: the string of characters to write to the terminal connection. + // Return Value: + // - + void TermControl::SendInput(const winrt::hstring& wstr) + { + _SendInputToConnection(wstr); + } + void TermControl::ToggleRetroEffect() { auto lock = _terminal->LockForWriting(); @@ -1764,12 +1777,18 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation } // Method Description: - // - Writes the given sequence as input to the active terminal connection, + // - Writes the given sequence as input to the active terminal connection. + // - This method has been overloaded to allow zero-copy winrt::param::hstring optimizations. // Arguments: // - wstr: the string of characters to write to the terminal connection. // Return Value: // - - void TermControl::_SendInputToConnection(const std::wstring& wstr) + void TermControl::_SendInputToConnection(const winrt::hstring& wstr) + { + _connection.WriteInput(wstr); + } + + void TermControl::_SendInputToConnection(std::wstring_view wstr) { _connection.WriteInput(wstr); } diff --git a/src/cascadia/TerminalControl/TermControl.h b/src/cascadia/TerminalControl/TermControl.h index a3f26712962..b34ea7b813c 100644 --- a/src/cascadia/TerminalControl/TermControl.h +++ b/src/cascadia/TerminalControl/TermControl.h @@ -81,6 +81,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation void AdjustFontSize(int fontSizeDelta); void ResetFontSize(); + void SendInput(const winrt::hstring& input); void ToggleRetroEffect(); winrt::fire_and_forget RenderEngineSwapChainChanged(); @@ -221,7 +222,8 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation void _CursorTimerTick(Windows::Foundation::IInspectable const& sender, Windows::Foundation::IInspectable const& e); void _SetEndSelectionPointAtCursor(Windows::Foundation::Point const& cursorPosition); - void _SendInputToConnection(const std::wstring& wstr); + void _SendInputToConnection(const winrt::hstring& wstr); + void _SendInputToConnection(std::wstring_view wstr); void _SendPastedTextToConnection(const std::wstring& wstr); void _SwapChainSizeChanged(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::SizeChangedEventArgs const& e); void _SwapChainScaleChanged(Windows::UI::Xaml::Controls::SwapChainPanel const& sender, Windows::Foundation::IInspectable const& args); diff --git a/src/cascadia/TerminalControl/TermControl.idl b/src/cascadia/TerminalControl/TermControl.idl index 85b6e602cfd..4e3eefa0c44 100644 --- a/src/cascadia/TerminalControl/TermControl.idl +++ b/src/cascadia/TerminalControl/TermControl.idl @@ -71,6 +71,7 @@ namespace Microsoft.Terminal.TerminalControl void AdjustFontSize(Int32 fontSizeDelta); void ResetFontSize(); + void SendInput(String input); void ToggleRetroEffect(); Windows.Foundation.IReference TabColor { get; }; From a02a29783ea6475dc09f2fb3e838e2a84280ec08 Mon Sep 17 00:00:00 2001 From: Kayla Cinnamon Date: Wed, 12 Aug 2020 15:05:04 -0700 Subject: [PATCH 045/266] doc: Add Pankaj to our README (#7266) We have a new team member! --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 1d1bd786174..a418e7a9bd7 100644 --- a/README.md +++ b/README.md @@ -163,6 +163,7 @@ If you would like to ask a question that you feel doesn't warrant an issue (yet) * Mike Griese, Developer: [@zadjii](https://twitter.com/zadjii) * Carlos Zamora, Developer: [@cazamor_msft](https://twitter.com/cazamor_msft) * Leon Liang, Developer: [@leonmsft](https://twitter.com/leonmsft) +* Pankaj Bhojwani, Developer ## Developer Guidance From 93ae6b6dba703860c68eaf5798b34717f59f5d23 Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Wed, 12 Aug 2020 16:25:50 -0700 Subject: [PATCH 046/266] Default initialize a CmdPal mode (#7263) Whoops, members are zero initialized in Debug builds but most likely not in Release builds So, this PR adds a couple of default values to `_currentMode` and its associated XAML strings to make cmdpal/ats work deterministically on first use. I also added a default value to `_anchorKey` just to be safe. Closes #7254 --- src/cascadia/TerminalApp/CommandPalette.cpp | 38 ++++++++++++--------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/src/cascadia/TerminalApp/CommandPalette.cpp b/src/cascadia/TerminalApp/CommandPalette.cpp index b743d8c1e29..962478d0677 100644 --- a/src/cascadia/TerminalApp/CommandPalette.cpp +++ b/src/cascadia/TerminalApp/CommandPalette.cpp @@ -22,6 +22,7 @@ using namespace winrt::Windows::Foundation::Collections; namespace winrt::TerminalApp::implementation { CommandPalette::CommandPalette() : + _anchorKey{ VirtualKey::None }, _switcherStartIdx{ 0 } { InitializeComponent(); @@ -30,6 +31,8 @@ namespace winrt::TerminalApp::implementation _allCommands = winrt::single_threaded_vector(); _allTabActions = winrt::single_threaded_vector(); + _switchToMode(CommandPaletteMode::ActionMode); + if (CommandPaletteShadow()) { // Hook up the shadow on the command palette to the backdrop that @@ -389,23 +392,26 @@ namespace winrt::TerminalApp::implementation { _filteredActions.Append(action); } + } - switch (_currentMode) - { - case CommandPaletteMode::TabSwitcherMode: - { - SearchBoxText(RS_(L"TabSwitcher_SearchBoxText")); - NoMatchesText(RS_(L"TabSwitcher_NoMatchesText")); - ControlName(RS_(L"TabSwitcherControlName")); - break; - } - case CommandPaletteMode::ActionMode: - default: - SearchBoxText(RS_(L"CommandPalette_SearchBox/PlaceholderText")); - NoMatchesText(RS_(L"CommandPalette_NoMatchesText/Text")); - ControlName(RS_(L"CommandPaletteControlName")); - break; - } + // Leaving this block of code outside the above if-statement + // guarantees that the correct text is shown for the mode + // whenever _switchToMode is called. + switch (_currentMode) + { + case CommandPaletteMode::TabSwitcherMode: + { + SearchBoxText(RS_(L"TabSwitcher_SearchBoxText")); + NoMatchesText(RS_(L"TabSwitcher_NoMatchesText")); + ControlName(RS_(L"TabSwitcherControlName")); + break; + } + case CommandPaletteMode::ActionMode: + default: + SearchBoxText(RS_(L"CommandPalette_SearchBox/PlaceholderText")); + NoMatchesText(RS_(L"CommandPalette_NoMatchesText/Text")); + ControlName(RS_(L"CommandPaletteControlName")); + break; } } From 01e3fda91b893fb7b465d9c74a874aa877eec61b Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Thu, 13 Aug 2020 14:17:58 -0500 Subject: [PATCH 047/266] Don't zoom when there's only one pane (#7273) This is a minor fix from #6989. If there's only one pane in the Terminal, then we'd still "zoom" it and give it a border, but all the borders would be black. A single pane is already "zoomed", so it doesn't really make sense to try and zoom if there's only one. --- src/cascadia/TerminalApp/AppActionHandlers.cpp | 4 +++- src/cascadia/TerminalApp/Tab.cpp | 2 +- src/cascadia/TerminalApp/Tab.h | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/cascadia/TerminalApp/AppActionHandlers.cpp b/src/cascadia/TerminalApp/AppActionHandlers.cpp index 80a06e733de..ad06916cd4e 100644 --- a/src/cascadia/TerminalApp/AppActionHandlers.cpp +++ b/src/cascadia/TerminalApp/AppActionHandlers.cpp @@ -122,7 +122,9 @@ namespace winrt::TerminalApp::implementation const TerminalApp::ActionEventArgs& args) { auto activeTab = _GetFocusedTab(); - if (activeTab) + + // Don't do anything if there's only one pane. It's already zoomed. + if (activeTab && activeTab->GetLeafPaneCount() > 1) { // First thing's first, remove the current content from the UI // tree. This is important, because we might be leaving zoom, and if diff --git a/src/cascadia/TerminalApp/Tab.cpp b/src/cascadia/TerminalApp/Tab.cpp index ead28ce1f02..43f29440745 100644 --- a/src/cascadia/TerminalApp/Tab.cpp +++ b/src/cascadia/TerminalApp/Tab.cpp @@ -960,7 +960,7 @@ namespace winrt::TerminalApp::implementation // - // Return Value: // - The total number of leaf panes hosted by this tab. - int Tab::_GetLeafPaneCount() const noexcept + int Tab::GetLeafPaneCount() const noexcept { return _rootPane->GetLeafPaneCount(); } diff --git a/src/cascadia/TerminalApp/Tab.h b/src/cascadia/TerminalApp/Tab.h index 02055b05767..2cc39b23375 100644 --- a/src/cascadia/TerminalApp/Tab.h +++ b/src/cascadia/TerminalApp/Tab.h @@ -66,6 +66,8 @@ namespace winrt::TerminalApp::implementation void EnterZoom(); void ExitZoom(); + int GetLeafPaneCount() const noexcept; + WINRT_CALLBACK(Closed, winrt::Windows::Foundation::EventHandler); WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler); DECLARE_EVENT(ActivePaneChanged, _ActivePaneChangedHandlers, winrt::delegate<>); @@ -102,7 +104,6 @@ namespace winrt::TerminalApp::implementation void _AttachEventHandlersToControl(const winrt::Microsoft::Terminal::TerminalControl::TermControl& control); void _AttachEventHandlersToPane(std::shared_ptr pane); - int _GetLeafPaneCount() const noexcept; void _UpdateActivePane(std::shared_ptr pane); void _UpdateTabHeader(); From d9ffca6614ad8d2ab52d93cd75f5238e8ee2337f Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Thu, 13 Aug 2020 13:35:29 -0700 Subject: [PATCH 048/266] Remove unnecessary check when updating ATS indices (#7280) Removes the if-statement in `UpdateTabIndices` that blocks all scenarios where you delete the second to last tab. This fixes the issue where the ATS gets confused about which item in the ListView is associated with which tab. Closes #7278 --- src/cascadia/TerminalApp/CommandPalette.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/cascadia/TerminalApp/CommandPalette.cpp b/src/cascadia/TerminalApp/CommandPalette.cpp index 962478d0677..8325500b398 100644 --- a/src/cascadia/TerminalApp/CommandPalette.cpp +++ b/src/cascadia/TerminalApp/CommandPalette.cpp @@ -772,14 +772,11 @@ namespace winrt::TerminalApp::implementation // - void CommandPalette::UpdateTabIndices(const uint32_t startIdx) { - if (startIdx != _allTabActions.Size() - 1) + for (auto i = startIdx; i < _allTabActions.Size(); ++i) { - for (auto i = startIdx; i < _allTabActions.Size(); ++i) - { - auto command = _allTabActions.GetAt(i); + auto command = _allTabActions.GetAt(i); - command.Action().Args().as()->TabIndex(i); - } + command.Action().Args().as()->TabIndex(i); } } From dcc2799457c569ce6a7666113ce043db61c6cbac Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Thu, 13 Aug 2020 16:22:46 -0500 Subject: [PATCH 049/266] Add support for iterable, nested commands (#6856) ## Summary of the Pull Request This PR adds support for both _nested_ and _iterable_ commands in the Command palette. ![nested-commands-000](https://user-images.githubusercontent.com/18356694/87072916-2d991c00-c1e2-11ea-8917-a70e8b8b9803.gif) * **Nested commands**: These are commands that include additional sub-commands. When the user selects on of these, the palette will update to only show the nested commands. * **Iterable commands**: These are commands what allow the user to define only a single command, which is repeated once for every profile. (in the future, also repeated for color schemes, themes, etc.) The above gif uses the following json: ```json { "name": "Split Pane...", "commands": [ { "iterateOn": "profiles", "name": "Split with ${profile.name}...", "commands": [ { "command": { "action": "splitPane", "profile": "${profile.name}", "split": "automatic" } }, { "command": { "action": "splitPane", "profile": "${profile.name}", "split": "vertical" } }, { "command": { "action": "splitPane", "profile": "${profile.name}", "split": "horizontal" } } ] } ] }, ``` ## References ## PR Checklist * [x] Closes #3994 * [x] I work here * [x] Tests added/passed * [ ] Requires documentation to be updated - Sure does, but we'll finish polishing this first. ## Detailed Description of the Pull Request / Additional comments We've now gotta keep the original json for a command around, so that once we know what all the profiles will be, we can expand the commands that need it. We've also got to parse commands recursively, because they might have any number of child commands. These together made the command parsing a _lot_ more complicated, but it feels good so far. ## Validation Steps Performed * wrote a bunch of tests * Played with it a bunch --- .../LocalTests_TerminalApp/CommandTests.cpp | 73 +- .../LocalTests_TerminalApp/SettingsTests.cpp | 1381 ++++++++++++++++- src/cascadia/TerminalApp/AppKeyBindings.cpp | 5 + src/cascadia/TerminalApp/AppLogic.cpp | 3 +- src/cascadia/TerminalApp/CascadiaSettings.cpp | 27 +- .../CascadiaSettingsSerialization.cpp | 1 - src/cascadia/TerminalApp/Command.cpp | 257 ++- src/cascadia/TerminalApp/Command.h | 42 +- src/cascadia/TerminalApp/Command.idl | 3 + src/cascadia/TerminalApp/CommandPalette.cpp | 86 +- src/cascadia/TerminalApp/CommandPalette.h | 8 +- .../TerminalApp/GlobalAppSettings.cpp | 8 +- src/cascadia/TerminalApp/GlobalAppSettings.h | 5 +- .../Resources/en-US/Resources.resw | 4 + src/cascadia/TerminalApp/TerminalPage.cpp | 147 +- src/cascadia/TerminalApp/TerminalPage.h | 6 + src/cascadia/TerminalApp/TerminalWarnings.h | 1 + src/cascadia/TerminalApp/lib/pch.h | 1 + src/cascadia/WindowsTerminal/AppHost.cpp | 3 +- src/cascadia/WindowsTerminal/AppHost.h | 1 - src/cascadia/WindowsTerminal/IslandWindow.h | 1 - src/inc/til.h | 1 + src/inc/til/replace.h | 73 + src/til/ut_til/ReplaceTests.cpp | 132 ++ src/til/ut_til/til.unit.tests.vcxproj | 1 + 25 files changed, 2140 insertions(+), 130 deletions(-) create mode 100644 src/inc/til/replace.h create mode 100644 src/til/ut_til/ReplaceTests.cpp diff --git a/src/cascadia/LocalTests_TerminalApp/CommandTests.cpp b/src/cascadia/LocalTests_TerminalApp/CommandTests.cpp index 28e53cdf5a0..d8028a88545 100644 --- a/src/cascadia/LocalTests_TerminalApp/CommandTests.cpp +++ b/src/cascadia/LocalTests_TerminalApp/CommandTests.cpp @@ -11,6 +11,7 @@ using namespace Microsoft::Console; using namespace TerminalApp; using namespace winrt::TerminalApp; using namespace winrt::Microsoft::Terminal::TerminalControl; +using namespace winrt::Windows::Foundation::Collections; using namespace WEX::Logging; using namespace WEX::TestExecution; using namespace WEX::Common; @@ -61,25 +62,25 @@ namespace TerminalAppLocalTests const auto commands1Json = VerifyParseSucceeded(commands1String); const auto commands2Json = VerifyParseSucceeded(commands2String); - std::unordered_map commands; - VERIFY_ARE_EQUAL(0u, commands.size()); + IMap commands = winrt::single_threaded_map(); + VERIFY_ARE_EQUAL(0u, commands.Size()); { auto warnings = implementation::Command::LayerJson(commands, commands0Json); VERIFY_ARE_EQUAL(0u, warnings.size()); } - VERIFY_ARE_EQUAL(1u, commands.size()); + VERIFY_ARE_EQUAL(1u, commands.Size()); { auto warnings = implementation::Command::LayerJson(commands, commands1Json); VERIFY_ARE_EQUAL(0u, warnings.size()); } - VERIFY_ARE_EQUAL(2u, commands.size()); + VERIFY_ARE_EQUAL(2u, commands.Size()); { auto warnings = implementation::Command::LayerJson(commands, commands2Json); VERIFY_ARE_EQUAL(0u, warnings.size()); } - VERIFY_ARE_EQUAL(4u, commands.size()); + VERIFY_ARE_EQUAL(4u, commands.Size()); } void CommandTests::LayerCommand() @@ -95,13 +96,13 @@ namespace TerminalAppLocalTests const auto commands2Json = VerifyParseSucceeded(commands2String); const auto commands3Json = VerifyParseSucceeded(commands3String); - std::unordered_map commands; - VERIFY_ARE_EQUAL(0u, commands.size()); + IMap commands = winrt::single_threaded_map(); + VERIFY_ARE_EQUAL(0u, commands.Size()); { auto warnings = implementation::Command::LayerJson(commands, commands0Json); VERIFY_ARE_EQUAL(0u, warnings.size()); - VERIFY_ARE_EQUAL(1u, commands.size()); - auto command = commands.at(L"action0"); + VERIFY_ARE_EQUAL(1u, commands.Size()); + auto command = commands.Lookup(L"action0"); VERIFY_IS_NOT_NULL(command); VERIFY_IS_NOT_NULL(command.Action()); VERIFY_ARE_EQUAL(ShortcutAction::CopyText, command.Action().Action()); @@ -111,8 +112,8 @@ namespace TerminalAppLocalTests { auto warnings = implementation::Command::LayerJson(commands, commands1Json); VERIFY_ARE_EQUAL(0u, warnings.size()); - VERIFY_ARE_EQUAL(1u, commands.size()); - auto command = commands.at(L"action0"); + VERIFY_ARE_EQUAL(1u, commands.Size()); + auto command = commands.Lookup(L"action0"); VERIFY_IS_NOT_NULL(command); VERIFY_IS_NOT_NULL(command.Action()); VERIFY_ARE_EQUAL(ShortcutAction::PasteText, command.Action().Action()); @@ -121,8 +122,8 @@ namespace TerminalAppLocalTests { auto warnings = implementation::Command::LayerJson(commands, commands2Json); VERIFY_ARE_EQUAL(0u, warnings.size()); - VERIFY_ARE_EQUAL(1u, commands.size()); - auto command = commands.at(L"action0"); + VERIFY_ARE_EQUAL(1u, commands.Size()); + auto command = commands.Lookup(L"action0"); VERIFY_IS_NOT_NULL(command); VERIFY_IS_NOT_NULL(command.Action()); VERIFY_ARE_EQUAL(ShortcutAction::NewTab, command.Action().Action()); @@ -133,7 +134,7 @@ namespace TerminalAppLocalTests // This last command should "unbind" the action. auto warnings = implementation::Command::LayerJson(commands, commands3Json); VERIFY_ARE_EQUAL(0u, warnings.size()); - VERIFY_ARE_EQUAL(0u, commands.size()); + VERIFY_ARE_EQUAL(0u, commands.Size()); } } @@ -153,14 +154,14 @@ namespace TerminalAppLocalTests const auto commands0Json = VerifyParseSucceeded(commands0String); - std::unordered_map commands; - VERIFY_ARE_EQUAL(0u, commands.size()); + IMap commands = winrt::single_threaded_map(); + VERIFY_ARE_EQUAL(0u, commands.Size()); auto warnings = implementation::Command::LayerJson(commands, commands0Json); VERIFY_ARE_EQUAL(0u, warnings.size()); - VERIFY_ARE_EQUAL(5u, commands.size()); + VERIFY_ARE_EQUAL(5u, commands.Size()); { - auto command = commands.at(L"command0"); + auto command = commands.Lookup(L"command0"); VERIFY_IS_NOT_NULL(command); VERIFY_IS_NOT_NULL(command.Action()); VERIFY_ARE_EQUAL(ShortcutAction::SplitPane, command.Action().Action()); @@ -170,7 +171,7 @@ namespace TerminalAppLocalTests VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::Automatic, realArgs.SplitStyle()); } { - auto command = commands.at(L"command1"); + auto command = commands.Lookup(L"command1"); VERIFY_IS_NOT_NULL(command); VERIFY_IS_NOT_NULL(command.Action()); VERIFY_ARE_EQUAL(ShortcutAction::SplitPane, command.Action().Action()); @@ -180,7 +181,7 @@ namespace TerminalAppLocalTests VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::Vertical, realArgs.SplitStyle()); } { - auto command = commands.at(L"command2"); + auto command = commands.Lookup(L"command2"); VERIFY_IS_NOT_NULL(command); VERIFY_IS_NOT_NULL(command.Action()); VERIFY_ARE_EQUAL(ShortcutAction::SplitPane, command.Action().Action()); @@ -190,7 +191,7 @@ namespace TerminalAppLocalTests VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::Horizontal, realArgs.SplitStyle()); } { - auto command = commands.at(L"command4"); + auto command = commands.Lookup(L"command4"); VERIFY_IS_NOT_NULL(command); VERIFY_IS_NOT_NULL(command.Action()); VERIFY_ARE_EQUAL(ShortcutAction::SplitPane, command.Action().Action()); @@ -200,7 +201,7 @@ namespace TerminalAppLocalTests VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::Automatic, realArgs.SplitStyle()); } { - auto command = commands.at(L"command5"); + auto command = commands.Lookup(L"command5"); VERIFY_IS_NOT_NULL(command); VERIFY_IS_NOT_NULL(command.Action()); VERIFY_ARE_EQUAL(ShortcutAction::SplitPane, command.Action().Action()); @@ -217,17 +218,17 @@ namespace TerminalAppLocalTests const std::string commands0String{ R"([ { "name": { "key": "DuplicateTabCommandKey"}, "command": "copy" } ])" }; const auto commands0Json = VerifyParseSucceeded(commands0String); - std::unordered_map commands; - VERIFY_ARE_EQUAL(0u, commands.size()); + IMap commands = winrt::single_threaded_map(); + VERIFY_ARE_EQUAL(0u, commands.Size()); { auto warnings = implementation::Command::LayerJson(commands, commands0Json); VERIFY_ARE_EQUAL(0u, warnings.size()); - VERIFY_ARE_EQUAL(1u, commands.size()); + VERIFY_ARE_EQUAL(1u, commands.Size()); // NOTE: We're relying on DuplicateTabCommandKey being defined as // "Duplicate Tab" here. If that string changes in our resources, // this test will break. - auto command = commands.at(L"Duplicate tab"); + auto command = commands.Lookup(L"Duplicate tab"); VERIFY_IS_NOT_NULL(command); VERIFY_IS_NOT_NULL(command.Action()); VERIFY_ARE_EQUAL(ShortcutAction::CopyText, command.Action().Action()); @@ -257,18 +258,18 @@ namespace TerminalAppLocalTests const auto commands0Json = VerifyParseSucceeded(commands0String); - std::unordered_map commands; - VERIFY_ARE_EQUAL(0u, commands.size()); + IMap commands = winrt::single_threaded_map(); + VERIFY_ARE_EQUAL(0u, commands.Size()); auto warnings = implementation::Command::LayerJson(commands, commands0Json); VERIFY_ARE_EQUAL(0u, warnings.size()); // There are only 3 commands here: all of the `"none"`, `"auto"`, // `"foo"`, `null`, and bindings all generate the same action, // which will generate just a single name for all of them. - VERIFY_ARE_EQUAL(3u, commands.size()); + VERIFY_ARE_EQUAL(3u, commands.Size()); { - auto command = commands.at(L"Split pane"); + auto command = commands.Lookup(L"Split pane"); VERIFY_IS_NOT_NULL(command); VERIFY_IS_NOT_NULL(command.Action()); VERIFY_ARE_EQUAL(ShortcutAction::SplitPane, command.Action().Action()); @@ -278,7 +279,7 @@ namespace TerminalAppLocalTests VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::Automatic, realArgs.SplitStyle()); } { - auto command = commands.at(L"Split pane, direction: vertical"); + auto command = commands.Lookup(L"Split pane, split: vertical"); VERIFY_IS_NOT_NULL(command); VERIFY_IS_NOT_NULL(command.Action()); VERIFY_ARE_EQUAL(ShortcutAction::SplitPane, command.Action().Action()); @@ -288,7 +289,7 @@ namespace TerminalAppLocalTests VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::Vertical, realArgs.SplitStyle()); } { - auto command = commands.at(L"Split pane, direction: horizontal"); + auto command = commands.Lookup(L"Split pane, split: horizontal"); VERIFY_IS_NOT_NULL(command); VERIFY_IS_NOT_NULL(command.Action()); VERIFY_ARE_EQUAL(ShortcutAction::SplitPane, command.Action().Action()); @@ -307,14 +308,14 @@ namespace TerminalAppLocalTests const auto commands0Json = VerifyParseSucceeded(commands0String); - std::unordered_map commands; - VERIFY_ARE_EQUAL(0u, commands.size()); + IMap commands = winrt::single_threaded_map(); + VERIFY_ARE_EQUAL(0u, commands.Size()); auto warnings = implementation::Command::LayerJson(commands, commands0Json); VERIFY_ARE_EQUAL(0u, warnings.size()); - VERIFY_ARE_EQUAL(1u, commands.size()); + VERIFY_ARE_EQUAL(1u, commands.Size()); { - auto command = commands.at(L"Split pane"); + auto command = commands.Lookup(L"Split pane"); VERIFY_IS_NOT_NULL(command); VERIFY_IS_NOT_NULL(command.Action()); VERIFY_ARE_EQUAL(ShortcutAction::SplitPane, command.Action().Action()); diff --git a/src/cascadia/LocalTests_TerminalApp/SettingsTests.cpp b/src/cascadia/LocalTests_TerminalApp/SettingsTests.cpp index abd710a6833..4c430688d24 100644 --- a/src/cascadia/LocalTests_TerminalApp/SettingsTests.cpp +++ b/src/cascadia/LocalTests_TerminalApp/SettingsTests.cpp @@ -5,6 +5,7 @@ #include "../TerminalApp/ColorScheme.h" #include "../TerminalApp/CascadiaSettings.h" +#include "../TerminalApp/TerminalPage.h" #include "JsonTestClass.h" #include "TestUtils.h" #include @@ -84,11 +85,48 @@ namespace TerminalAppLocalTests TEST_METHOD(TestCommandsAndKeybindings); + TEST_METHOD(TestIterateCommands); + TEST_METHOD(TestIterateOnGeneratedNamedCommands); + TEST_METHOD(TestIterateOnBadJson); + TEST_METHOD(TestNestedCommands); + TEST_METHOD(TestNestedInNestedCommand); + TEST_METHOD(TestNestedInIterableCommand); + TEST_METHOD(TestIterableInNestedCommand); + TEST_METHOD(TestMixedNestedAndIterableCommand); + TEST_METHOD(TestNestedCommandWithoutName); + TEST_METHOD(TestUnbindNestedCommand); + TEST_METHOD(TestRebindNestedCommand); + TEST_CLASS_SETUP(ClassSetup) { InitializeJsonReader(); return true; } + + private: + void _logCommandNames(winrt::Windows::Foundation::Collections::IMap& commands, const int indentation = 1) + { + if (indentation == 1) + { + Log::Comment((commands.Size() == 0) ? L"Commands:\n " : L"Commands:"); + } + for (const auto& nameAndCommand : commands) + { + Log::Comment(fmt::format(L"{0:>{1}}* {2}->{3}", + L"", + indentation, + nameAndCommand.Key(), + nameAndCommand.Value().Name()) + .c_str()); + + winrt::com_ptr cmdImpl; + cmdImpl.copy_from(winrt::get_self(nameAndCommand.Value())); + if (cmdImpl->HasNestedCommands()) + { + _logCommandNames(cmdImpl->_subcommands, indentation + 2); + } + } + } }; void SettingsTests::TryCreateWinRTType() @@ -2433,7 +2471,7 @@ namespace TerminalAppLocalTests // * A and D share the same name, so they'll only generate a single action. // * F's name is set manually to `null` auto commands = settings._globals.GetCommands(); - VERIFY_ARE_EQUAL(4u, commands.size()); + VERIFY_ARE_EQUAL(4u, commands.Size()); { KeyChord kc{ true, false, false, static_cast('A') }; @@ -2510,9 +2548,9 @@ namespace TerminalAppLocalTests } Log::Comment(L"Now verify the commands"); - + _logCommandNames(commands); { - auto command = commands.at(L"Split pane, direction: Vertical"); + auto command = commands.Lookup(L"Split pane, split: vertical"); VERIFY_IS_NOT_NULL(command); auto actionAndArgs = command.Action(); VERIFY_IS_NOT_NULL(actionAndArgs); @@ -2528,7 +2566,7 @@ namespace TerminalAppLocalTests VERIFY_IS_TRUE(realArgs.TerminalArgs().Profile().empty()); } { - auto command = commands.at(L"ctrl+b"); + auto command = commands.Lookup(L"ctrl+b"); VERIFY_IS_NOT_NULL(command); auto actionAndArgs = command.Action(); VERIFY_IS_NOT_NULL(actionAndArgs); @@ -2544,7 +2582,7 @@ namespace TerminalAppLocalTests VERIFY_IS_TRUE(realArgs.TerminalArgs().Profile().empty()); } { - auto command = commands.at(L"ctrl+c"); + auto command = commands.Lookup(L"ctrl+c"); VERIFY_IS_NOT_NULL(command); auto actionAndArgs = command.Action(); VERIFY_IS_NOT_NULL(actionAndArgs); @@ -2560,7 +2598,7 @@ namespace TerminalAppLocalTests VERIFY_IS_TRUE(realArgs.TerminalArgs().Profile().empty()); } { - auto command = commands.at(L"Split pane, direction: Horizontal"); + auto command = commands.Lookup(L"Split pane, split: horizontal"); VERIFY_IS_NOT_NULL(command); auto actionAndArgs = command.Action(); VERIFY_IS_NOT_NULL(actionAndArgs); @@ -2576,5 +2614,1336 @@ namespace TerminalAppLocalTests VERIFY_IS_TRUE(realArgs.TerminalArgs().Profile().empty()); } } + void SettingsTests::TestIterateCommands() + { + // For this test, put an iterable command with a given `name`, + // containing a ${profile.name} to replace. When we expand it, it should + // have created one command for each profile. + + const std::string settingsJson{ R"( + { + "defaultProfile": "{6239a42c-0000-49a3-80bd-e8fdd045185c}", + "profiles": [ + { + "name": "profile0", + "guid": "{6239a42c-0000-49a3-80bd-e8fdd045185c}", + "historySize": 1, + "commandline": "cmd.exe" + }, + { + "name": "profile1", + "guid": "{6239a42c-1111-49a3-80bd-e8fdd045185c}", + "historySize": 2, + "commandline": "pwsh.exe" + }, + { + "name": "profile2", + "historySize": 3, + "commandline": "wsl.exe" + } + ], + "bindings": [ + { + "name": "iterable command ${profile.name}", + "iterateOn": "profiles", + "command": { "action": "splitPane", "profile": "${profile.name}" } + }, + ], + "schemes": [ { "name": "Campbell" } ] // This is included here to prevent settings validation errors. + })" }; + + const auto guid0 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-0000-49a3-80bd-e8fdd045185c}"); + const auto guid1 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-1111-49a3-80bd-e8fdd045185c}"); + + VerifyParseSucceeded(settingsJson); + CascadiaSettings settings{}; + settings._ParseJsonString(settingsJson, false); + settings.LayerJson(settings._userSettings); + + VERIFY_ARE_EQUAL(0u, settings._warnings.size()); + + VERIFY_ARE_EQUAL(3u, settings.GetProfiles().size()); + + auto& commands = settings._globals.GetCommands(); + VERIFY_ARE_EQUAL(1u, commands.Size()); + + { + auto command = commands.Lookup(L"iterable command ${profile.name}"); + VERIFY_IS_NOT_NULL(command); + auto actionAndArgs = command.Action(); + VERIFY_IS_NOT_NULL(actionAndArgs); + VERIFY_ARE_EQUAL(ShortcutAction::SplitPane, actionAndArgs.Action()); + const auto& realArgs = actionAndArgs.Args().try_as(); + VERIFY_IS_NOT_NULL(realArgs); + // Verify the args have the expected value + VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::Automatic, realArgs.SplitStyle()); + VERIFY_IS_NOT_NULL(realArgs.TerminalArgs()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().Commandline().empty()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().StartingDirectory().empty()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().TabTitle().empty()); + VERIFY_IS_FALSE(realArgs.TerminalArgs().Profile().empty()); + VERIFY_ARE_EQUAL(L"${profile.name}", realArgs.TerminalArgs().Profile()); + } + + auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands.GetView(), settings.GetProfiles()); + _logCommandNames(expandedCommands); + + VERIFY_ARE_EQUAL(0u, settings._warnings.size()); + VERIFY_ARE_EQUAL(3u, expandedCommands.Size()); + + { + auto command = expandedCommands.Lookup(L"iterable command profile0"); + VERIFY_IS_NOT_NULL(command); + auto actionAndArgs = command.Action(); + VERIFY_IS_NOT_NULL(actionAndArgs); + VERIFY_ARE_EQUAL(ShortcutAction::SplitPane, actionAndArgs.Action()); + const auto& realArgs = actionAndArgs.Args().try_as(); + VERIFY_IS_NOT_NULL(realArgs); + // Verify the args have the expected value + VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::Automatic, realArgs.SplitStyle()); + VERIFY_IS_NOT_NULL(realArgs.TerminalArgs()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().Commandline().empty()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().StartingDirectory().empty()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().TabTitle().empty()); + VERIFY_IS_FALSE(realArgs.TerminalArgs().Profile().empty()); + VERIFY_ARE_EQUAL(L"profile0", realArgs.TerminalArgs().Profile()); + } + + { + auto command = expandedCommands.Lookup(L"iterable command profile1"); + VERIFY_IS_NOT_NULL(command); + auto actionAndArgs = command.Action(); + VERIFY_IS_NOT_NULL(actionAndArgs); + VERIFY_ARE_EQUAL(ShortcutAction::SplitPane, actionAndArgs.Action()); + const auto& realArgs = actionAndArgs.Args().try_as(); + VERIFY_IS_NOT_NULL(realArgs); + // Verify the args have the expected value + VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::Automatic, realArgs.SplitStyle()); + VERIFY_IS_NOT_NULL(realArgs.TerminalArgs()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().Commandline().empty()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().StartingDirectory().empty()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().TabTitle().empty()); + VERIFY_IS_FALSE(realArgs.TerminalArgs().Profile().empty()); + VERIFY_ARE_EQUAL(L"profile1", realArgs.TerminalArgs().Profile()); + } + + { + auto command = expandedCommands.Lookup(L"iterable command profile2"); + VERIFY_IS_NOT_NULL(command); + auto actionAndArgs = command.Action(); + VERIFY_IS_NOT_NULL(actionAndArgs); + VERIFY_ARE_EQUAL(ShortcutAction::SplitPane, actionAndArgs.Action()); + const auto& realArgs = actionAndArgs.Args().try_as(); + VERIFY_IS_NOT_NULL(realArgs); + // Verify the args have the expected value + VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::Automatic, realArgs.SplitStyle()); + VERIFY_IS_NOT_NULL(realArgs.TerminalArgs()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().Commandline().empty()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().StartingDirectory().empty()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().TabTitle().empty()); + VERIFY_IS_FALSE(realArgs.TerminalArgs().Profile().empty()); + VERIFY_ARE_EQUAL(L"profile2", realArgs.TerminalArgs().Profile()); + } + } + + void SettingsTests::TestIterateOnGeneratedNamedCommands() + { + // For this test, put an iterable command without a given `name` to + // replace. When we expand it, it should still work. + + const std::string settingsJson{ R"( + { + "defaultProfile": "{6239a42c-0000-49a3-80bd-e8fdd045185c}", + "profiles": [ + { + "name": "profile0", + "guid": "{6239a42c-0000-49a3-80bd-e8fdd045185c}", + "historySize": 1, + "commandline": "cmd.exe" + }, + { + "name": "profile1", + "guid": "{6239a42c-1111-49a3-80bd-e8fdd045185c}", + "historySize": 2, + "commandline": "pwsh.exe" + }, + { + "name": "profile2", + "historySize": 3, + "commandline": "wsl.exe" + } + ], + "bindings": [ + { + "iterateOn": "profiles", + "command": { "action": "splitPane", "profile": "${profile.name}" } + }, + ], + "schemes": [ { "name": "Campbell" } ] // This is included here to prevent settings validation errors. + })" }; + + const auto guid0 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-0000-49a3-80bd-e8fdd045185c}"); + const auto guid1 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-1111-49a3-80bd-e8fdd045185c}"); + + VerifyParseSucceeded(settingsJson); + CascadiaSettings settings{}; + settings._ParseJsonString(settingsJson, false); + settings.LayerJson(settings._userSettings); + + VERIFY_ARE_EQUAL(0u, settings._warnings.size()); + + VERIFY_ARE_EQUAL(3u, settings.GetProfiles().size()); + + auto& commands = settings._globals.GetCommands(); + VERIFY_ARE_EQUAL(1u, commands.Size()); + + { + auto command = commands.Lookup(L"Split pane, profile: ${profile.name}"); + VERIFY_IS_NOT_NULL(command); + auto actionAndArgs = command.Action(); + VERIFY_IS_NOT_NULL(actionAndArgs); + VERIFY_ARE_EQUAL(ShortcutAction::SplitPane, actionAndArgs.Action()); + const auto& realArgs = actionAndArgs.Args().try_as(); + VERIFY_IS_NOT_NULL(realArgs); + // Verify the args have the expected value + VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::Automatic, realArgs.SplitStyle()); + VERIFY_IS_NOT_NULL(realArgs.TerminalArgs()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().Commandline().empty()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().StartingDirectory().empty()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().TabTitle().empty()); + VERIFY_IS_FALSE(realArgs.TerminalArgs().Profile().empty()); + VERIFY_ARE_EQUAL(L"${profile.name}", realArgs.TerminalArgs().Profile()); + } + + auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands.GetView(), settings.GetProfiles()); + _logCommandNames(expandedCommands); + + VERIFY_ARE_EQUAL(0u, settings._warnings.size()); + VERIFY_ARE_EQUAL(3u, expandedCommands.Size()); + + { + auto command = expandedCommands.Lookup(L"Split pane, profile: profile0"); + VERIFY_IS_NOT_NULL(command); + auto actionAndArgs = command.Action(); + VERIFY_IS_NOT_NULL(actionAndArgs); + VERIFY_ARE_EQUAL(ShortcutAction::SplitPane, actionAndArgs.Action()); + const auto& realArgs = actionAndArgs.Args().try_as(); + VERIFY_IS_NOT_NULL(realArgs); + // Verify the args have the expected value + VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::Automatic, realArgs.SplitStyle()); + VERIFY_IS_NOT_NULL(realArgs.TerminalArgs()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().Commandline().empty()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().StartingDirectory().empty()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().TabTitle().empty()); + VERIFY_IS_FALSE(realArgs.TerminalArgs().Profile().empty()); + VERIFY_ARE_EQUAL(L"profile0", realArgs.TerminalArgs().Profile()); + } + + { + auto command = expandedCommands.Lookup(L"Split pane, profile: profile1"); + VERIFY_IS_NOT_NULL(command); + auto actionAndArgs = command.Action(); + VERIFY_IS_NOT_NULL(actionAndArgs); + VERIFY_ARE_EQUAL(ShortcutAction::SplitPane, actionAndArgs.Action()); + const auto& realArgs = actionAndArgs.Args().try_as(); + VERIFY_IS_NOT_NULL(realArgs); + // Verify the args have the expected value + VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::Automatic, realArgs.SplitStyle()); + VERIFY_IS_NOT_NULL(realArgs.TerminalArgs()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().Commandline().empty()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().StartingDirectory().empty()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().TabTitle().empty()); + VERIFY_IS_FALSE(realArgs.TerminalArgs().Profile().empty()); + VERIFY_ARE_EQUAL(L"profile1", realArgs.TerminalArgs().Profile()); + } + + { + auto command = expandedCommands.Lookup(L"Split pane, profile: profile2"); + VERIFY_IS_NOT_NULL(command); + auto actionAndArgs = command.Action(); + VERIFY_IS_NOT_NULL(actionAndArgs); + VERIFY_ARE_EQUAL(ShortcutAction::SplitPane, actionAndArgs.Action()); + const auto& realArgs = actionAndArgs.Args().try_as(); + VERIFY_IS_NOT_NULL(realArgs); + // Verify the args have the expected value + VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::Automatic, realArgs.SplitStyle()); + VERIFY_IS_NOT_NULL(realArgs.TerminalArgs()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().Commandline().empty()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().StartingDirectory().empty()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().TabTitle().empty()); + VERIFY_IS_FALSE(realArgs.TerminalArgs().Profile().empty()); + VERIFY_ARE_EQUAL(L"profile2", realArgs.TerminalArgs().Profile()); + } + } + + void SettingsTests::TestIterateOnBadJson() + { + // For this test, put an iterable command with a profile name that would + // cause bad json to be filled in. Something like a profile with a name + // of "Foo\"", so the trailing '"' might break the json parsing. + + const std::string settingsJson{ R"( + { + "defaultProfile": "{6239a42c-0000-49a3-80bd-e8fdd045185c}", + "profiles": [ + { + "name": "profile0", + "guid": "{6239a42c-0000-49a3-80bd-e8fdd045185c}", + "historySize": 1, + "commandline": "cmd.exe" + }, + { + "name": "profile1\"", + "guid": "{6239a42c-1111-49a3-80bd-e8fdd045185c}", + "historySize": 2, + "commandline": "pwsh.exe" + }, + { + "name": "profile2", + "historySize": 3, + "commandline": "wsl.exe" + } + ], + "bindings": [ + { + "name": "iterable command ${profile.name}", + "iterateOn": "profiles", + "command": { "action": "splitPane", "profile": "${profile.name}" } + }, + ], + "schemes": [ { "name": "Campbell" } ] // This is included here to prevent settings validation errors. + })" }; + + const auto guid0 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-0000-49a3-80bd-e8fdd045185c}"); + const auto guid1 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-1111-49a3-80bd-e8fdd045185c}"); + + VerifyParseSucceeded(settingsJson); + CascadiaSettings settings{}; + settings._ParseJsonString(settingsJson, false); + settings.LayerJson(settings._userSettings); + + VERIFY_ARE_EQUAL(0u, settings._warnings.size()); + + VERIFY_ARE_EQUAL(3u, settings.GetProfiles().size()); + + auto& commands = settings._globals.GetCommands(); + VERIFY_ARE_EQUAL(1u, commands.Size()); + + { + auto command = commands.Lookup(L"iterable command ${profile.name}"); + VERIFY_IS_NOT_NULL(command); + auto actionAndArgs = command.Action(); + VERIFY_IS_NOT_NULL(actionAndArgs); + VERIFY_ARE_EQUAL(ShortcutAction::SplitPane, actionAndArgs.Action()); + const auto& realArgs = actionAndArgs.Args().try_as(); + VERIFY_IS_NOT_NULL(realArgs); + // Verify the args have the expected value + VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::Automatic, realArgs.SplitStyle()); + VERIFY_IS_NOT_NULL(realArgs.TerminalArgs()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().Commandline().empty()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().StartingDirectory().empty()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().TabTitle().empty()); + VERIFY_IS_FALSE(realArgs.TerminalArgs().Profile().empty()); + VERIFY_ARE_EQUAL(L"${profile.name}", realArgs.TerminalArgs().Profile()); + } + + settings._ValidateSettings(); + auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands.GetView(), settings.GetProfiles()); + _logCommandNames(expandedCommands); + + VERIFY_ARE_EQUAL(0u, settings._warnings.size()); + VERIFY_ARE_EQUAL(3u, expandedCommands.Size()); + + { + auto command = expandedCommands.Lookup(L"iterable command profile0"); + VERIFY_IS_NOT_NULL(command); + auto actionAndArgs = command.Action(); + VERIFY_IS_NOT_NULL(actionAndArgs); + VERIFY_ARE_EQUAL(ShortcutAction::SplitPane, actionAndArgs.Action()); + const auto& realArgs = actionAndArgs.Args().try_as(); + VERIFY_IS_NOT_NULL(realArgs); + // Verify the args have the expected value + VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::Automatic, realArgs.SplitStyle()); + VERIFY_IS_NOT_NULL(realArgs.TerminalArgs()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().Commandline().empty()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().StartingDirectory().empty()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().TabTitle().empty()); + VERIFY_IS_FALSE(realArgs.TerminalArgs().Profile().empty()); + VERIFY_ARE_EQUAL(L"profile0", realArgs.TerminalArgs().Profile()); + } + + { + auto command = expandedCommands.Lookup(L"iterable command profile1\""); + VERIFY_IS_NOT_NULL(command); + auto actionAndArgs = command.Action(); + VERIFY_IS_NOT_NULL(actionAndArgs); + VERIFY_ARE_EQUAL(ShortcutAction::SplitPane, actionAndArgs.Action()); + const auto& realArgs = actionAndArgs.Args().try_as(); + VERIFY_IS_NOT_NULL(realArgs); + // Verify the args have the expected value + VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::Automatic, realArgs.SplitStyle()); + VERIFY_IS_NOT_NULL(realArgs.TerminalArgs()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().Commandline().empty()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().StartingDirectory().empty()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().TabTitle().empty()); + VERIFY_IS_FALSE(realArgs.TerminalArgs().Profile().empty()); + VERIFY_ARE_EQUAL(L"profile1\"", realArgs.TerminalArgs().Profile()); + } + + { + auto command = expandedCommands.Lookup(L"iterable command profile2"); + VERIFY_IS_NOT_NULL(command); + auto actionAndArgs = command.Action(); + VERIFY_IS_NOT_NULL(actionAndArgs); + VERIFY_ARE_EQUAL(ShortcutAction::SplitPane, actionAndArgs.Action()); + const auto& realArgs = actionAndArgs.Args().try_as(); + VERIFY_IS_NOT_NULL(realArgs); + // Verify the args have the expected value + VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::Automatic, realArgs.SplitStyle()); + VERIFY_IS_NOT_NULL(realArgs.TerminalArgs()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().Commandline().empty()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().StartingDirectory().empty()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().TabTitle().empty()); + VERIFY_IS_FALSE(realArgs.TerminalArgs().Profile().empty()); + VERIFY_ARE_EQUAL(L"profile2", realArgs.TerminalArgs().Profile()); + } + } + + void SettingsTests::TestNestedCommands() + { + // This test checks a nested command. + // The commands should look like: + // + // + // └─ Connect to ssh... + // ├─ first.com + // └─ second.com + + const std::string settingsJson{ R"( + { + "defaultProfile": "{6239a42c-0000-49a3-80bd-e8fdd045185c}", + "profiles": [ + { + "name": "profile0", + "guid": "{6239a42c-0000-49a3-80bd-e8fdd045185c}", + "historySize": 1, + "commandline": "cmd.exe" + }, + { + "name": "profile1", + "guid": "{6239a42c-1111-49a3-80bd-e8fdd045185c}", + "historySize": 2, + "commandline": "pwsh.exe" + }, + { + "name": "profile2", + "historySize": 3, + "commandline": "wsl.exe" + } + ], + "bindings": [ + { + "name": "Connect to ssh...", + "commands": [ + { + "name": "first.com", + "command": { "action": "newTab", "commandline": "ssh me@first.com" } + }, + { + "name": "second.com", + "command": { "action": "newTab", "commandline": "ssh me@second.com" } + } + ] + }, + ], + "schemes": [ { "name": "Campbell" } ] // This is included here to prevent settings validation errors. + })" }; + + VerifyParseSucceeded(settingsJson); + CascadiaSettings settings{}; + settings._ParseJsonString(settingsJson, false); + settings.LayerJson(settings._userSettings); + + VERIFY_ARE_EQUAL(0u, settings._warnings.size()); + VERIFY_ARE_EQUAL(3u, settings.GetProfiles().size()); + + auto& commands = settings._globals.GetCommands(); + settings._ValidateSettings(); + auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands.GetView(), settings.GetProfiles()); + _logCommandNames(expandedCommands); + + VERIFY_ARE_EQUAL(0u, settings._warnings.size()); + VERIFY_ARE_EQUAL(1u, expandedCommands.Size()); + + auto rootCommandProj = expandedCommands.Lookup(L"Connect to ssh..."); + VERIFY_IS_NOT_NULL(rootCommandProj); + auto rootActionAndArgs = rootCommandProj.Action(); + VERIFY_IS_NULL(rootActionAndArgs); + + winrt::com_ptr rootCommandImpl; + rootCommandImpl.copy_from(winrt::get_self(rootCommandProj)); + + VERIFY_ARE_EQUAL(2u, rootCommandImpl->_subcommands.Size()); + + { + winrt::hstring commandName{ L"first.com" }; + auto commandProj = rootCommandImpl->_subcommands.Lookup(commandName); + VERIFY_IS_NOT_NULL(commandProj); + auto actionAndArgs = commandProj.Action(); + VERIFY_IS_NOT_NULL(actionAndArgs); + + winrt::com_ptr commandImpl; + commandImpl.copy_from(winrt::get_self(commandProj)); + + VERIFY_IS_FALSE(commandImpl->HasNestedCommands()); + } + { + winrt::hstring commandName{ L"second.com" }; + auto commandProj = rootCommandImpl->_subcommands.Lookup(commandName); + VERIFY_IS_NOT_NULL(commandProj); + auto actionAndArgs = commandProj.Action(); + VERIFY_IS_NOT_NULL(actionAndArgs); + + winrt::com_ptr commandImpl; + commandImpl.copy_from(winrt::get_self(commandProj)); + + VERIFY_IS_FALSE(commandImpl->HasNestedCommands()); + } + } + + void SettingsTests::TestNestedInNestedCommand() + { + // This test checks a nested command that includes nested commands. + // The commands should look like: + // + // + // └─ grandparent + // └─ parent + // ├─ child1 + // └─ child2 + + const std::string settingsJson{ R"( + { + "defaultProfile": "{6239a42c-0000-49a3-80bd-e8fdd045185c}", + "profiles": [ + { + "name": "profile0", + "guid": "{6239a42c-0000-49a3-80bd-e8fdd045185c}", + "historySize": 1, + "commandline": "cmd.exe" + }, + { + "name": "profile1", + "guid": "{6239a42c-1111-49a3-80bd-e8fdd045185c}", + "historySize": 2, + "commandline": "pwsh.exe" + }, + { + "name": "profile2", + "historySize": 3, + "commandline": "wsl.exe" + } + ], + "bindings": [ + { + "name": "grandparent", + "commands": [ + { + "name": "parent", + "commands": [ + { + "name": "child1", + "command": { "action": "newTab", "commandline": "ssh me@first.com" } + }, + { + "name": "child2", + "command": { "action": "newTab", "commandline": "ssh me@second.com" } + } + ] + }, + ] + }, + ], + "schemes": [ { "name": "Campbell" } ] // This is included here to prevent settings validation errors. + })" }; + + VerifyParseSucceeded(settingsJson); + CascadiaSettings settings{}; + settings._ParseJsonString(settingsJson, false); + settings.LayerJson(settings._userSettings); + + VERIFY_ARE_EQUAL(0u, settings._warnings.size()); + VERIFY_ARE_EQUAL(3u, settings.GetProfiles().size()); + + auto& commands = settings._globals.GetCommands(); + settings._ValidateSettings(); + auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands.GetView(), settings.GetProfiles()); + _logCommandNames(expandedCommands); + + VERIFY_ARE_EQUAL(0u, settings._warnings.size()); + VERIFY_ARE_EQUAL(1u, expandedCommands.Size()); + + auto grandparentCommandProj = expandedCommands.Lookup(L"grandparent"); + VERIFY_IS_NOT_NULL(grandparentCommandProj); + auto grandparentActionAndArgs = grandparentCommandProj.Action(); + VERIFY_IS_NULL(grandparentActionAndArgs); + + winrt::com_ptr grandparentCommandImpl; + grandparentCommandImpl.copy_from(winrt::get_self(grandparentCommandProj)); + + VERIFY_ARE_EQUAL(1u, grandparentCommandImpl->_subcommands.Size()); + + winrt::hstring parentName{ L"parent" }; + auto parentProj = grandparentCommandImpl->_subcommands.Lookup(parentName); + VERIFY_IS_NOT_NULL(parentProj); + auto parentActionAndArgs = parentProj.Action(); + VERIFY_IS_NULL(parentActionAndArgs); + + winrt::com_ptr parentImpl; + parentImpl.copy_from(winrt::get_self(parentProj)); + + VERIFY_ARE_EQUAL(2u, parentImpl->_subcommands.Size()); + { + winrt::hstring childName{ L"child1" }; + auto childProj = parentImpl->_subcommands.Lookup(childName); + VERIFY_IS_NOT_NULL(childProj); + auto childActionAndArgs = childProj.Action(); + VERIFY_IS_NOT_NULL(childActionAndArgs); + + VERIFY_ARE_EQUAL(ShortcutAction::NewTab, childActionAndArgs.Action()); + const auto& realArgs = childActionAndArgs.Args().try_as(); + VERIFY_IS_NOT_NULL(realArgs); + // Verify the args have the expected value + VERIFY_IS_NOT_NULL(realArgs.TerminalArgs()); + VERIFY_IS_FALSE(realArgs.TerminalArgs().Commandline().empty()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().StartingDirectory().empty()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().TabTitle().empty()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().Profile().empty()); + VERIFY_ARE_EQUAL(L"ssh me@first.com", realArgs.TerminalArgs().Commandline()); + + winrt::com_ptr childImpl; + childImpl.copy_from(winrt::get_self(childProj)); + + VERIFY_IS_FALSE(childImpl->HasNestedCommands()); + } + { + winrt::hstring childName{ L"child2" }; + auto childProj = parentImpl->_subcommands.Lookup(childName); + VERIFY_IS_NOT_NULL(childProj); + auto childActionAndArgs = childProj.Action(); + VERIFY_IS_NOT_NULL(childActionAndArgs); + + VERIFY_ARE_EQUAL(ShortcutAction::NewTab, childActionAndArgs.Action()); + const auto& realArgs = childActionAndArgs.Args().try_as(); + VERIFY_IS_NOT_NULL(realArgs); + // Verify the args have the expected value + VERIFY_IS_NOT_NULL(realArgs.TerminalArgs()); + VERIFY_IS_FALSE(realArgs.TerminalArgs().Commandline().empty()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().StartingDirectory().empty()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().TabTitle().empty()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().Profile().empty()); + VERIFY_ARE_EQUAL(L"ssh me@second.com", realArgs.TerminalArgs().Commandline()); + + winrt::com_ptr childImpl; + childImpl.copy_from(winrt::get_self(childProj)); + + VERIFY_IS_FALSE(childImpl->HasNestedCommands()); + } + } + + void SettingsTests::TestNestedInIterableCommand() + { + // This test checks a iterable command that includes a nested command. + // The commands should look like: + // + // + // ├─ profile0... + // | ├─ Split pane, profile: profile0 + // | ├─ Split pane, direction: vertical, profile: profile0 + // | └─ Split pane, direction: horizontal, profile: profile0 + // ├─ profile1... + // | ├─Split pane, profile: profile1 + // | ├─Split pane, direction: vertical, profile: profile1 + // | └─Split pane, direction: horizontal, profile: profile1 + // └─ profile2... + // ├─ Split pane, profile: profile2 + // ├─ Split pane, direction: vertical, profile: profile2 + // └─ Split pane, direction: horizontal, profile: profile2 + + const std::string settingsJson{ R"( + { + "defaultProfile": "{6239a42c-0000-49a3-80bd-e8fdd045185c}", + "profiles": [ + { + "name": "profile0", + "guid": "{6239a42c-0000-49a3-80bd-e8fdd045185c}", + "historySize": 1, + "commandline": "cmd.exe" + }, + { + "name": "profile1", + "guid": "{6239a42c-1111-49a3-80bd-e8fdd045185c}", + "historySize": 2, + "commandline": "pwsh.exe" + }, + { + "name": "profile2", + "historySize": 3, + "commandline": "wsl.exe" + } + ], + "bindings": [ + { + "iterateOn": "profiles", + "name": "${profile.name}...", + "commands": [ + { "command": { "action": "splitPane", "profile": "${profile.name}", "split": "auto" } }, + { "command": { "action": "splitPane", "profile": "${profile.name}", "split": "vertical" } }, + { "command": { "action": "splitPane", "profile": "${profile.name}", "split": "horizontal" } } + ] + } + ], + "schemes": [ { "name": "Campbell" } ] // This is included here to prevent settings validation errors. + })" }; + + VerifyParseSucceeded(settingsJson); + CascadiaSettings settings{}; + settings._ParseJsonString(settingsJson, false); + settings.LayerJson(settings._userSettings); + + VERIFY_ARE_EQUAL(0u, settings._warnings.size()); + VERIFY_ARE_EQUAL(3u, settings.GetProfiles().size()); + + auto& commands = settings._globals.GetCommands(); + settings._ValidateSettings(); + auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands.GetView(), settings.GetProfiles()); + _logCommandNames(expandedCommands); + + VERIFY_ARE_EQUAL(0u, settings._warnings.size()); + + VERIFY_ARE_EQUAL(3u, expandedCommands.Size()); + + for (auto name : std::vector({ L"profile0", L"profile1", L"profile2" })) + { + winrt::hstring commandName{ name + L"..." }; + auto commandProj = expandedCommands.Lookup(commandName); + VERIFY_IS_NOT_NULL(commandProj); + auto actionAndArgs = commandProj.Action(); + VERIFY_IS_NULL(actionAndArgs); + + winrt::com_ptr commandImpl; + commandImpl.copy_from(winrt::get_self(commandProj)); + + VERIFY_IS_TRUE(commandImpl->HasNestedCommands()); + VERIFY_ARE_EQUAL(3u, commandImpl->_subcommands.Size()); + _logCommandNames(commandImpl->_subcommands); + { + winrt::hstring childCommandName{ fmt::format(L"Split pane, profile: {}", name) }; + auto childCommandProj = commandImpl->_subcommands.Lookup(childCommandName); + VERIFY_IS_NOT_NULL(childCommandProj); + auto childActionAndArgs = childCommandProj.Action(); + VERIFY_IS_NOT_NULL(childActionAndArgs); + + VERIFY_ARE_EQUAL(ShortcutAction::SplitPane, childActionAndArgs.Action()); + const auto& realArgs = childActionAndArgs.Args().try_as(); + VERIFY_IS_NOT_NULL(realArgs); + // Verify the args have the expected value + VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::Automatic, realArgs.SplitStyle()); + VERIFY_IS_NOT_NULL(realArgs.TerminalArgs()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().Commandline().empty()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().StartingDirectory().empty()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().TabTitle().empty()); + VERIFY_IS_FALSE(realArgs.TerminalArgs().Profile().empty()); + VERIFY_ARE_EQUAL(name, realArgs.TerminalArgs().Profile()); + + winrt::com_ptr childCommandImpl; + childCommandImpl.copy_from(winrt::get_self(childCommandProj)); + + VERIFY_IS_FALSE(childCommandImpl->HasNestedCommands()); + } + { + winrt::hstring childCommandName{ fmt::format(L"Split pane, split: horizontal, profile: {}", name) }; + auto childCommandProj = commandImpl->_subcommands.Lookup(childCommandName); + VERIFY_IS_NOT_NULL(childCommandProj); + auto childActionAndArgs = childCommandProj.Action(); + VERIFY_IS_NOT_NULL(childActionAndArgs); + + VERIFY_ARE_EQUAL(ShortcutAction::SplitPane, childActionAndArgs.Action()); + const auto& realArgs = childActionAndArgs.Args().try_as(); + VERIFY_IS_NOT_NULL(realArgs); + // Verify the args have the expected value + VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::Horizontal, realArgs.SplitStyle()); + VERIFY_IS_NOT_NULL(realArgs.TerminalArgs()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().Commandline().empty()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().StartingDirectory().empty()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().TabTitle().empty()); + VERIFY_IS_FALSE(realArgs.TerminalArgs().Profile().empty()); + VERIFY_ARE_EQUAL(name, realArgs.TerminalArgs().Profile()); + + winrt::com_ptr childCommandImpl; + childCommandImpl.copy_from(winrt::get_self(childCommandProj)); + + VERIFY_IS_FALSE(childCommandImpl->HasNestedCommands()); + } + { + winrt::hstring childCommandName{ fmt::format(L"Split pane, split: vertical, profile: {}", name) }; + auto childCommandProj = commandImpl->_subcommands.Lookup(childCommandName); + VERIFY_IS_NOT_NULL(childCommandProj); + auto childActionAndArgs = childCommandProj.Action(); + VERIFY_IS_NOT_NULL(childActionAndArgs); + + VERIFY_ARE_EQUAL(ShortcutAction::SplitPane, childActionAndArgs.Action()); + const auto& realArgs = childActionAndArgs.Args().try_as(); + VERIFY_IS_NOT_NULL(realArgs); + // Verify the args have the expected value + VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::Vertical, realArgs.SplitStyle()); + VERIFY_IS_NOT_NULL(realArgs.TerminalArgs()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().Commandline().empty()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().StartingDirectory().empty()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().TabTitle().empty()); + VERIFY_IS_FALSE(realArgs.TerminalArgs().Profile().empty()); + VERIFY_ARE_EQUAL(name, realArgs.TerminalArgs().Profile()); + + winrt::com_ptr childCommandImpl; + childCommandImpl.copy_from(winrt::get_self(childCommandProj)); + + VERIFY_IS_FALSE(childCommandImpl->HasNestedCommands()); + } + } + } + + void SettingsTests::TestIterableInNestedCommand() + { + // This test checks a nested command that includes an iterable command. + // The commands should look like: + // + // + // └─ New Tab With Profile... + // ├─ Profile 1 + // ├─ Profile 2 + // └─ Profile 3 + + const std::string settingsJson{ R"( + { + "defaultProfile": "{6239a42c-0000-49a3-80bd-e8fdd045185c}", + "profiles": [ + { + "name": "profile0", + "guid": "{6239a42c-0000-49a3-80bd-e8fdd045185c}", + "historySize": 1, + "commandline": "cmd.exe" + }, + { + "name": "profile1", + "guid": "{6239a42c-1111-49a3-80bd-e8fdd045185c}", + "historySize": 2, + "commandline": "pwsh.exe" + }, + { + "name": "profile2", + "historySize": 3, + "commandline": "wsl.exe" + } + ], + "bindings": [ + { + "name": "New Tab With Profile...", + "commands": [ + { + "iterateOn": "profiles", + "command": { "action": "newTab", "profile": "${profile.name}" } + } + ] + } + ], + "schemes": [ { "name": "Campbell" } ] // This is included here to prevent settings validation errors. + })" }; + + VerifyParseSucceeded(settingsJson); + CascadiaSettings settings{}; + settings._ParseJsonString(settingsJson, false); + settings.LayerJson(settings._userSettings); + + VERIFY_ARE_EQUAL(0u, settings._warnings.size()); + VERIFY_ARE_EQUAL(3u, settings.GetProfiles().size()); + + auto& commands = settings._globals.GetCommands(); + settings._ValidateSettings(); + auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands.GetView(), settings.GetProfiles()); + _logCommandNames(expandedCommands); + + VERIFY_ARE_EQUAL(0u, settings._warnings.size()); + VERIFY_ARE_EQUAL(1u, expandedCommands.Size()); + + auto rootCommandProj = expandedCommands.Lookup(L"New Tab With Profile..."); + VERIFY_IS_NOT_NULL(rootCommandProj); + auto rootActionAndArgs = rootCommandProj.Action(); + VERIFY_IS_NULL(rootActionAndArgs); + + winrt::com_ptr rootCommandImpl; + rootCommandImpl.copy_from(winrt::get_self(rootCommandProj)); + + VERIFY_ARE_EQUAL(3u, rootCommandImpl->_subcommands.Size()); + + for (auto name : std::vector({ L"profile0", L"profile1", L"profile2" })) + { + winrt::hstring commandName{ fmt::format(L"New tab, profile: {}", name) }; + auto commandProj = rootCommandImpl->_subcommands.Lookup(commandName); + VERIFY_IS_NOT_NULL(commandProj); + auto actionAndArgs = commandProj.Action(); + VERIFY_IS_NOT_NULL(actionAndArgs); + + VERIFY_ARE_EQUAL(ShortcutAction::NewTab, actionAndArgs.Action()); + const auto& realArgs = actionAndArgs.Args().try_as(); + VERIFY_IS_NOT_NULL(realArgs); + // Verify the args have the expected value + VERIFY_IS_NOT_NULL(realArgs.TerminalArgs()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().Commandline().empty()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().StartingDirectory().empty()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().TabTitle().empty()); + VERIFY_IS_FALSE(realArgs.TerminalArgs().Profile().empty()); + VERIFY_ARE_EQUAL(name, realArgs.TerminalArgs().Profile()); + + winrt::com_ptr commandImpl; + commandImpl.copy_from(winrt::get_self(commandProj)); + + VERIFY_IS_FALSE(commandImpl->HasNestedCommands()); + } + } + void SettingsTests::TestMixedNestedAndIterableCommand() + { + // This test checks a nested commands that includes an iterable command + // that includes a nested command. + // The commands should look like: + // + // + // └─ New Pane... + // ├─ profile0... + // | ├─ Split automatically + // | ├─ Split vertically + // | └─ Split horizontally + // ├─ profile1... + // | ├─ Split automatically + // | ├─ Split vertically + // | └─ Split horizontally + // └─ profile2... + // ├─ Split automatically + // ├─ Split vertically + // └─ Split horizontally + + const std::string settingsJson{ R"( + { + "defaultProfile": "{6239a42c-0000-49a3-80bd-e8fdd045185c}", + "profiles": [ + { + "name": "profile0", + "guid": "{6239a42c-0000-49a3-80bd-e8fdd045185c}", + "historySize": 1, + "commandline": "cmd.exe" + }, + { + "name": "profile1", + "guid": "{6239a42c-1111-49a3-80bd-e8fdd045185c}", + "historySize": 2, + "commandline": "pwsh.exe" + }, + { + "name": "profile2", + "historySize": 3, + "commandline": "wsl.exe" + } + ], + "bindings": [ + { + "name": "New Pane...", + "commands": [ + { + "iterateOn": "profiles", + "name": "${profile.name}...", + "commands": [ + { "command": { "action": "splitPane", "profile": "${profile.name}", "split": "auto" } }, + { "command": { "action": "splitPane", "profile": "${profile.name}", "split": "vertical" } }, + { "command": { "action": "splitPane", "profile": "${profile.name}", "split": "horizontal" } } + ] + } + ] + } + ], + "schemes": [ { "name": "Campbell" } ] // This is included here to prevent settings validation errors. + })" }; + + VerifyParseSucceeded(settingsJson); + CascadiaSettings settings{}; + settings._ParseJsonString(settingsJson, false); + settings.LayerJson(settings._userSettings); + + VERIFY_ARE_EQUAL(0u, settings._warnings.size()); + VERIFY_ARE_EQUAL(3u, settings.GetProfiles().size()); + + auto& commands = settings._globals.GetCommands(); + settings._ValidateSettings(); + auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands.GetView(), settings.GetProfiles()); + _logCommandNames(expandedCommands); + + VERIFY_ARE_EQUAL(0u, settings._warnings.size()); + VERIFY_ARE_EQUAL(1u, expandedCommands.Size()); + + auto rootCommandProj = expandedCommands.Lookup(L"New Pane..."); + VERIFY_IS_NOT_NULL(rootCommandProj); + auto rootActionAndArgs = rootCommandProj.Action(); + VERIFY_IS_NULL(rootActionAndArgs); + + winrt::com_ptr rootCommandImpl; + rootCommandImpl.copy_from(winrt::get_self(rootCommandProj)); + + VERIFY_ARE_EQUAL(3u, rootCommandImpl->_subcommands.Size()); + + for (auto name : std::vector({ L"profile0", L"profile1", L"profile2" })) + { + winrt::hstring commandName{ name + L"..." }; + auto commandProj = rootCommandImpl->_subcommands.Lookup(commandName); + VERIFY_IS_NOT_NULL(commandProj); + auto actionAndArgs = commandProj.Action(); + VERIFY_IS_NULL(actionAndArgs); + + winrt::com_ptr commandImpl; + commandImpl.copy_from(winrt::get_self(commandProj)); + + VERIFY_IS_TRUE(commandImpl->HasNestedCommands()); + VERIFY_ARE_EQUAL(3u, commandImpl->_subcommands.Size()); + + _logCommandNames(commandImpl->_subcommands); + { + winrt::hstring childCommandName{ fmt::format(L"Split pane, profile: {}", name) }; + auto childCommandProj = commandImpl->_subcommands.Lookup(childCommandName); + VERIFY_IS_NOT_NULL(childCommandProj); + auto childActionAndArgs = childCommandProj.Action(); + VERIFY_IS_NOT_NULL(childActionAndArgs); + + VERIFY_ARE_EQUAL(ShortcutAction::SplitPane, childActionAndArgs.Action()); + const auto& realArgs = childActionAndArgs.Args().try_as(); + VERIFY_IS_NOT_NULL(realArgs); + // Verify the args have the expected value + VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::Automatic, realArgs.SplitStyle()); + VERIFY_IS_NOT_NULL(realArgs.TerminalArgs()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().Commandline().empty()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().StartingDirectory().empty()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().TabTitle().empty()); + VERIFY_IS_FALSE(realArgs.TerminalArgs().Profile().empty()); + VERIFY_ARE_EQUAL(name, realArgs.TerminalArgs().Profile()); + + winrt::com_ptr childCommandImpl; + childCommandImpl.copy_from(winrt::get_self(childCommandProj)); + + VERIFY_IS_FALSE(childCommandImpl->HasNestedCommands()); + } + { + winrt::hstring childCommandName{ fmt::format(L"Split pane, split: horizontal, profile: {}", name) }; + auto childCommandProj = commandImpl->_subcommands.Lookup(childCommandName); + VERIFY_IS_NOT_NULL(childCommandProj); + auto childActionAndArgs = childCommandProj.Action(); + VERIFY_IS_NOT_NULL(childActionAndArgs); + + VERIFY_ARE_EQUAL(ShortcutAction::SplitPane, childActionAndArgs.Action()); + const auto& realArgs = childActionAndArgs.Args().try_as(); + VERIFY_IS_NOT_NULL(realArgs); + // Verify the args have the expected value + VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::Horizontal, realArgs.SplitStyle()); + VERIFY_IS_NOT_NULL(realArgs.TerminalArgs()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().Commandline().empty()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().StartingDirectory().empty()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().TabTitle().empty()); + VERIFY_IS_FALSE(realArgs.TerminalArgs().Profile().empty()); + VERIFY_ARE_EQUAL(name, realArgs.TerminalArgs().Profile()); + + winrt::com_ptr childCommandImpl; + childCommandImpl.copy_from(winrt::get_self(childCommandProj)); + + VERIFY_IS_FALSE(childCommandImpl->HasNestedCommands()); + } + { + winrt::hstring childCommandName{ fmt::format(L"Split pane, split: vertical, profile: {}", name) }; + auto childCommandProj = commandImpl->_subcommands.Lookup(childCommandName); + VERIFY_IS_NOT_NULL(childCommandProj); + auto childActionAndArgs = childCommandProj.Action(); + VERIFY_IS_NOT_NULL(childActionAndArgs); + + VERIFY_ARE_EQUAL(ShortcutAction::SplitPane, childActionAndArgs.Action()); + const auto& realArgs = childActionAndArgs.Args().try_as(); + VERIFY_IS_NOT_NULL(realArgs); + // Verify the args have the expected value + VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::Vertical, realArgs.SplitStyle()); + VERIFY_IS_NOT_NULL(realArgs.TerminalArgs()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().Commandline().empty()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().StartingDirectory().empty()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().TabTitle().empty()); + VERIFY_IS_FALSE(realArgs.TerminalArgs().Profile().empty()); + VERIFY_ARE_EQUAL(name, realArgs.TerminalArgs().Profile()); + + winrt::com_ptr childCommandImpl; + childCommandImpl.copy_from(winrt::get_self(childCommandProj)); + + VERIFY_IS_FALSE(childCommandImpl->HasNestedCommands()); + } + } + } + + void SettingsTests::TestNestedCommandWithoutName() + { + // This test tests a nested command without a name specified. This type + // of command should just be ignored, since we can't auto-generate names + // for nested commands, they _must_ have names specified. + + const std::string settingsJson{ R"( + { + "defaultProfile": "{6239a42c-0000-49a3-80bd-e8fdd045185c}", + "profiles": [ + { + "name": "profile0", + "guid": "{6239a42c-0000-49a3-80bd-e8fdd045185c}", + "historySize": 1, + "commandline": "cmd.exe" + }, + { + "name": "profile1", + "guid": "{6239a42c-1111-49a3-80bd-e8fdd045185c}", + "historySize": 2, + "commandline": "pwsh.exe" + }, + { + "name": "profile2", + "historySize": 3, + "commandline": "wsl.exe" + } + ], + "bindings": [ + { + "commands": [ + { + "name": "child1", + "command": { "action": "newTab", "commandline": "ssh me@first.com" } + }, + { + "name": "child2", + "command": { "action": "newTab", "commandline": "ssh me@second.com" } + } + ] + }, + ], + "schemes": [ { "name": "Campbell" } ] // This is included here to prevent settings validation errors. + })" }; + + VerifyParseSucceeded(settingsJson); + CascadiaSettings settings{}; + settings._ParseJsonString(settingsJson, false); + settings.LayerJson(settings._userSettings); + + VERIFY_ARE_EQUAL(0u, settings._warnings.size()); + VERIFY_ARE_EQUAL(3u, settings.GetProfiles().size()); + + auto& commands = settings._globals.GetCommands(); + settings._ValidateSettings(); + _logCommandNames(commands); + + VERIFY_ARE_EQUAL(0u, settings._warnings.size()); + + // Because the "parent" command didn't have a name, it couldn't be + // placed into the list of commands. It and it's children are just + // ignored. + VERIFY_ARE_EQUAL(0u, commands.Size()); + } + + void SettingsTests::TestUnbindNestedCommand() + { + // Test that layering a command with `"commands": null` set will unbind a command that already exists. + + const std::string settingsJson{ R"( + { + "defaultProfile": "{6239a42c-0000-49a3-80bd-e8fdd045185c}", + "profiles": [ + { + "name": "profile0", + "guid": "{6239a42c-0000-49a3-80bd-e8fdd045185c}", + "historySize": 1, + "commandline": "cmd.exe" + }, + { + "name": "profile1", + "guid": "{6239a42c-1111-49a3-80bd-e8fdd045185c}", + "historySize": 2, + "commandline": "pwsh.exe" + }, + { + "name": "profile2", + "historySize": 3, + "commandline": "wsl.exe" + } + ], + "bindings": [ + { + "name": "parent", + "commands": [ + { + "name": "child1", + "command": { "action": "newTab", "commandline": "ssh me@first.com" } + }, + { + "name": "child2", + "command": { "action": "newTab", "commandline": "ssh me@second.com" } + } + ] + }, + ], + "schemes": [ { "name": "Campbell" } ] // This is included here to prevent settings validation errors. + })" }; + + const std::string settings1Json{ R"( + { + "defaultProfile": "{6239a42c-0000-49a3-80bd-e8fdd045185c}", + "bindings": [ + { + "name": "parent", + "commands": null + }, + ], + })" }; + + VerifyParseSucceeded(settingsJson); + VerifyParseSucceeded(settings1Json); + + CascadiaSettings settings{}; + settings._ParseJsonString(settingsJson, false); + settings.LayerJson(settings._userSettings); + + VERIFY_ARE_EQUAL(0u, settings._warnings.size()); + VERIFY_ARE_EQUAL(3u, settings.GetProfiles().size()); + + auto& commands = settings._globals.GetCommands(); + settings._ValidateSettings(); + _logCommandNames(commands); + + VERIFY_ARE_EQUAL(0u, settings._warnings.size()); + VERIFY_ARE_EQUAL(1u, commands.Size()); + + Log::Comment(L"Layer second bit of json, to unbind the original command."); + + settings._ParseJsonString(settings1Json, false); + settings.LayerJson(settings._userSettings); + settings._ValidateSettings(); + _logCommandNames(commands); + VERIFY_ARE_EQUAL(0u, settings._warnings.size()); + VERIFY_ARE_EQUAL(0u, commands.Size()); + } + + void SettingsTests::TestRebindNestedCommand() + { + // Test that layering a command with an action set on top of a command + // with nested commands replaces the nested commands with an action. + + const std::string settingsJson{ R"( + { + "defaultProfile": "{6239a42c-0000-49a3-80bd-e8fdd045185c}", + "profiles": [ + { + "name": "profile0", + "guid": "{6239a42c-0000-49a3-80bd-e8fdd045185c}", + "historySize": 1, + "commandline": "cmd.exe" + }, + { + "name": "profile1", + "guid": "{6239a42c-1111-49a3-80bd-e8fdd045185c}", + "historySize": 2, + "commandline": "pwsh.exe" + }, + { + "name": "profile2", + "historySize": 3, + "commandline": "wsl.exe" + } + ], + "bindings": [ + { + "name": "parent", + "commands": [ + { + "name": "child1", + "command": { "action": "newTab", "commandline": "ssh me@first.com" } + }, + { + "name": "child2", + "command": { "action": "newTab", "commandline": "ssh me@second.com" } + } + ] + }, + ], + "schemes": [ { "name": "Campbell" } ] // This is included here to prevent settings validation errors. + })" }; + + const std::string settings1Json{ R"( + { + "defaultProfile": "{6239a42c-0000-49a3-80bd-e8fdd045185c}", + "bindings": [ + { + "name": "parent", + "command": "newTab" + }, + ], + })" }; + + VerifyParseSucceeded(settingsJson); + VerifyParseSucceeded(settings1Json); + + CascadiaSettings settings{}; + settings._ParseJsonString(settingsJson, false); + settings.LayerJson(settings._userSettings); + + VERIFY_ARE_EQUAL(0u, settings._warnings.size()); + VERIFY_ARE_EQUAL(3u, settings.GetProfiles().size()); + + auto& commands = settings._globals.GetCommands(); + settings._ValidateSettings(); + _logCommandNames(commands); + + VERIFY_ARE_EQUAL(0u, settings._warnings.size()); + VERIFY_ARE_EQUAL(1u, commands.Size()); + + { + winrt::hstring commandName{ L"parent" }; + auto commandProj = commands.Lookup(commandName); + VERIFY_IS_NOT_NULL(commandProj); + + winrt::com_ptr commandImpl; + commandImpl.copy_from(winrt::get_self(commandProj)); + + VERIFY_IS_TRUE(commandImpl->HasNestedCommands()); + VERIFY_ARE_EQUAL(2u, commandImpl->_subcommands.Size()); + } + + Log::Comment(L"Layer second bit of json, to unbind the original command."); + settings._ParseJsonString(settings1Json, false); + settings.LayerJson(settings._userSettings); + settings._ValidateSettings(); + _logCommandNames(commands); + VERIFY_ARE_EQUAL(0u, settings._warnings.size()); + VERIFY_ARE_EQUAL(1u, commands.Size()); + + { + winrt::hstring commandName{ L"parent" }; + auto commandProj = commands.Lookup(commandName); + + VERIFY_IS_NOT_NULL(commandProj); + auto actionAndArgs = commandProj.Action(); + VERIFY_IS_NOT_NULL(actionAndArgs); + VERIFY_ARE_EQUAL(ShortcutAction::NewTab, actionAndArgs.Action()); + const auto& realArgs = actionAndArgs.Args().try_as(); + VERIFY_IS_NOT_NULL(realArgs); + + winrt::com_ptr commandImpl; + commandImpl.copy_from(winrt::get_self(commandProj)); + + VERIFY_IS_FALSE(commandImpl->HasNestedCommands()); + } + } } diff --git a/src/cascadia/TerminalApp/AppKeyBindings.cpp b/src/cascadia/TerminalApp/AppKeyBindings.cpp index 4ac3f012c2c..166200cf132 100644 --- a/src/cascadia/TerminalApp/AppKeyBindings.cpp +++ b/src/cascadia/TerminalApp/AppKeyBindings.cpp @@ -53,6 +53,11 @@ namespace winrt::TerminalApp::implementation // - The bound keychord, if this ActionAndArgs is bound to a key, otherwise nullptr. KeyChord AppKeyBindings::GetKeyBindingForActionWithArgs(TerminalApp::ActionAndArgs const& actionAndArgs) { + if (actionAndArgs == nullptr) + { + return { nullptr }; + } + for (auto& kv : _keyShortcuts) { const auto action = kv.second.Action(); diff --git a/src/cascadia/TerminalApp/AppLogic.cpp b/src/cascadia/TerminalApp/AppLogic.cpp index 9b6c3eddc77..b11c1e2a1fd 100644 --- a/src/cascadia/TerminalApp/AppLogic.cpp +++ b/src/cascadia/TerminalApp/AppLogic.cpp @@ -38,7 +38,8 @@ static const std::array(SettingsLoadWar USES_RESOURCE(L"AtLeastOneKeybindingWarning"), USES_RESOURCE(L"TooManyKeysForChord"), USES_RESOURCE(L"MissingRequiredParameter"), - USES_RESOURCE(L"LegacyGlobalsProperty") + USES_RESOURCE(L"LegacyGlobalsProperty"), + USES_RESOURCE(L"FailedToParseCommandJson") }; static const std::array(SettingsLoadErrors::ERRORS_SIZE)> settingsLoadErrorsLabels { USES_RESOURCE(L"NoProfilesText"), diff --git a/src/cascadia/TerminalApp/CascadiaSettings.cpp b/src/cascadia/TerminalApp/CascadiaSettings.cpp index 182ae429b2d..e8b8a06e428 100644 --- a/src/cascadia/TerminalApp/CascadiaSettings.cpp +++ b/src/cascadia/TerminalApp/CascadiaSettings.cpp @@ -694,14 +694,11 @@ void CascadiaSettings::_ValidateNoGlobalsKey() // - The new settings string. std::string CascadiaSettings::_ApplyFirstRunChangesToSettingsTemplate(std::string_view settingsTemplate) const { + // We're using replace_needle_in_haystack_inplace here, because it's more + // efficient to iteratively modify a single string in-place than it is to + // keep copying over the contents and modifying a copy (which + // replace_needle_in_haystack would do). std::string finalSettings{ settingsTemplate }; - auto replace{ [](std::string& haystack, std::string_view needle, std::string_view replacement) { - auto pos{ std::string::npos }; - while ((pos = haystack.rfind(needle, pos)) != std::string::npos) - { - haystack.replace(pos, needle.size(), replacement); - } - } }; std::wstring defaultProfileGuid{ DEFAULT_WINDOWS_POWERSHELL_GUID }; if (const auto psCoreProfileGuid{ _GetProfileGuidByName(PowershellCoreProfileGenerator::GetPreferredPowershellProfileName()) }) @@ -709,14 +706,22 @@ std::string CascadiaSettings::_ApplyFirstRunChangesToSettingsTemplate(std::strin defaultProfileGuid = Utils::GuidToString(*psCoreProfileGuid); } - replace(finalSettings, "%DEFAULT_PROFILE%", til::u16u8(defaultProfileGuid)); + til::replace_needle_in_haystack_inplace(finalSettings, + "%DEFAULT_PROFILE%", + til::u16u8(defaultProfileGuid)); if (const auto appLogic{ winrt::TerminalApp::implementation::AppLogic::Current() }) { - replace(finalSettings, "%VERSION%", til::u16u8(appLogic->ApplicationVersion())); - replace(finalSettings, "%PRODUCT%", til::u16u8(appLogic->ApplicationDisplayName())); + til::replace_needle_in_haystack_inplace(finalSettings, + "%VERSION%", + til::u16u8(appLogic->ApplicationVersion())); + til::replace_needle_in_haystack_inplace(finalSettings, + "%PRODUCT%", + til::u16u8(appLogic->ApplicationDisplayName())); } - replace(finalSettings, "%COMMAND_PROMPT_LOCALIZED_NAME%", RS_A(L"CommandPromptDisplayName")); + til::replace_needle_in_haystack_inplace(finalSettings, + "%COMMAND_PROMPT_LOCALIZED_NAME%", + RS_A(L"CommandPromptDisplayName")); return finalSettings; } diff --git a/src/cascadia/TerminalApp/CascadiaSettingsSerialization.cpp b/src/cascadia/TerminalApp/CascadiaSettingsSerialization.cpp index bba84551f4d..8a4c1c50086 100644 --- a/src/cascadia/TerminalApp/CascadiaSettingsSerialization.cpp +++ b/src/cascadia/TerminalApp/CascadiaSettingsSerialization.cpp @@ -19,7 +19,6 @@ // "Generated Files" directory. using namespace ::TerminalApp; -using namespace winrt::Microsoft::Terminal::TerminalControl; using namespace winrt::TerminalApp; using namespace ::Microsoft::Console; diff --git a/src/cascadia/TerminalApp/Command.cpp b/src/cascadia/TerminalApp/Command.cpp index 6d164bc7445..10b7adba0aa 100644 --- a/src/cascadia/TerminalApp/Command.cpp +++ b/src/cascadia/TerminalApp/Command.cpp @@ -11,15 +11,36 @@ #include using namespace winrt::TerminalApp; +using namespace winrt::Windows::Foundation; using namespace ::TerminalApp; static constexpr std::string_view NameKey{ "name" }; static constexpr std::string_view IconPathKey{ "iconPath" }; static constexpr std::string_view ActionKey{ "command" }; static constexpr std::string_view ArgsKey{ "args" }; +static constexpr std::string_view IterateOnKey{ "iterateOn" }; +static constexpr std::string_view CommandsKey{ "commands" }; + +static constexpr std::string_view IterateOnProfilesValue{ "profiles" }; + +static constexpr std::string_view ProfileName{ "${profile.name}" }; namespace winrt::TerminalApp::implementation { + Command::Command() + { + _setAction(nullptr); + } + + Collections::IMapView Command::NestedCommands() + { + return _subcommands ? _subcommands.GetView() : nullptr; + } + + bool Command::HasNestedCommands() + { + return _subcommands ? _subcommands.Size() > 0 : false; + } // Function Description: // - attempt to get the name of this command from the provided json object. // * If the "name" property is a string, return that value. @@ -99,35 +120,83 @@ namespace winrt::TerminalApp::implementation { auto result = winrt::make_self(); + bool nested = false; + if (const auto iterateOnJson{ json[JsonKey(IterateOnKey)] }) + { + auto s = iterateOnJson.asString(); + if (s == IterateOnProfilesValue) + { + result->_IterateOn = ExpandCommandType::Profiles; + } + } + + // For iterable commands, we'll make another pass at parsing them once + // the json is patched. So ignore parsing sub-commands for now. Commands + // will only be marked iterable on the first pass. + if (const auto nestedCommandsJson{ json[JsonKey(CommandsKey)] }) + { + // Initialize our list of subcommands. + result->_subcommands = winrt::single_threaded_map(); + auto nestedWarnings = Command::LayerJson(result->_subcommands, nestedCommandsJson); + // It's possible that the nested commands have some warnings + warnings.insert(warnings.end(), nestedWarnings.begin(), nestedWarnings.end()); + + nested = true; + } + else if (json.isMember(JsonKey(CommandsKey))) + { + // { "name": "foo", "commands": null } will land in this case, which + // should also be used for unbinding. + return nullptr; + } + // TODO GH#6644: iconPath not implemented quite yet. Can't seem to get // the binding quite right. Additionally, do we want it to be an image, // or a FontIcon? I've had difficulty binding either/or. - if (const auto actionJson{ json[JsonKey(ActionKey)] }) + // If we're a nested command, we can ignore the current action. + if (!nested) { - auto actionAndArgs = ActionAndArgs::FromJson(actionJson, warnings); - - if (actionAndArgs) + if (const auto actionJson{ json[JsonKey(ActionKey)] }) { - result->_setAction(*actionAndArgs); + auto actionAndArgs = ActionAndArgs::FromJson(actionJson, warnings); + + if (actionAndArgs) + { + result->_setAction(*actionAndArgs); + } + else + { + // Something like + // { name: "foo", action: "unbound" } + // will _remove_ the "foo" command, by returning null here. + return nullptr; + } + + // If an iterable command doesn't have a name set, we'll still just + // try and generate a fake name for the command give the string we + // currently have. It'll probably generate something like "New tab, + // profile: ${profile.name}". This string will only be temporarily + // used internally, so there's no problem. + result->_setName(_nameFromJsonOrAction(json, actionAndArgs)); } else { - // Something like - // { name: "foo", action: "unbound" } - // will _remove_ the "foo" command, by returning null here. + // { name: "foo", action: null } will land in this case, which + // should also be used for unbinding. return nullptr; } - - result->_setName(_nameFromJsonOrAction(json, actionAndArgs)); } else { - // { name: "foo", action: null } will land in this case, which - // should also be used for unbinding. - return nullptr; + result->_setName(_nameFromJson(json)); } + // Stash the original json value in this object. If the command is + // iterable, we'll need to re-parse it later, once we know what all the + // values we can iterate on are. + result->_originalJson = json; + if (result->_Name.empty()) { return nullptr; @@ -147,7 +216,7 @@ namespace winrt::TerminalApp::implementation // - json: A Json::Value containing an array of serialized commands // Return Value: // - A vector containing any warnings detected while parsing - std::vector<::TerminalApp::SettingsLoadWarnings> Command::LayerJson(std::unordered_map& commands, + std::vector<::TerminalApp::SettingsLoadWarnings> Command::LayerJson(Windows::Foundation::Collections::IMap& commands, const Json::Value& json) { std::vector<::TerminalApp::SettingsLoadWarnings> warnings; @@ -162,7 +231,7 @@ namespace winrt::TerminalApp::implementation if (result) { // Override commands with the same name - commands.insert_or_assign(result->Name(), *result); + commands.Insert(result->Name(), *result); } else { @@ -172,7 +241,7 @@ namespace winrt::TerminalApp::implementation const auto name = _nameFromJson(value); if (!name.empty()) { - commands.erase(name); + commands.Remove(name); } } } @@ -181,4 +250,160 @@ namespace winrt::TerminalApp::implementation } return warnings; } + + // Function Description: + // - Helper to escape a string as a json string. This function will also + // trim off the leading and trailing double-quotes, so the output string + // can be inserted directly into another json blob. + // Arguments: + // - input: the string to JSON escape. + // Return Value: + // - the input string escaped properly to be inserted into another json blob. + std::string _escapeForJson(const std::string& input) + { + Json::Value inJson{ input }; + Json::StreamWriterBuilder builder; + builder.settings_["indentation"] = ""; + std::string out{ Json::writeString(builder, inJson) }; + if (out.size() >= 2) + { + // trim off the leading/trailing '"'s + auto ss{ out.substr(1, out.size() - 2) }; + return ss; + } + return out; + } + + // Method Description: + // - Iterate over all the provided commands, and recursively expand any + // commands with `iterateOn` set. If we successfully generated expanded + // commands for them, then we'll remove the original command, and add all + // the newly generated commands. + // - For more specific implementation details, see _expandCommand. + // Arguments: + // - commands: a map of commands to expand. Newly created commands will be + // inserted into the map to replace the expandable commands. + // - profiles: A list of all the profiles that this command should be expanded on. + // - warnings: If there were any warnings during parsing, they'll be + // appended to this vector. + // Return Value: + // - + void Command::ExpandCommands(Windows::Foundation::Collections::IMap& commands, + gsl::span profiles, + std::vector<::TerminalApp::SettingsLoadWarnings>& warnings) + { + std::vector commandsToRemove; + std::vector commandsToAdd; + + // First, collect up all the commands that need replacing. + for (const auto& nameAndCmd : commands) + { + auto cmd{ get_self(nameAndCmd.Value()) }; + + auto newCommands = _expandCommand(cmd, profiles, warnings); + if (newCommands.size() > 0) + { + commandsToRemove.push_back(nameAndCmd.Key()); + commandsToAdd.insert(commandsToAdd.end(), newCommands.begin(), newCommands.end()); + } + } + + // Second, remove all the commands that need to be removed. + for (auto& name : commandsToRemove) + { + commands.Remove(name); + } + + // Finally, add all the new commands. + for (auto& cmd : commandsToAdd) + { + commands.Insert(cmd.Name(), cmd); + } + } + + // Function Description: + // - Attempts to expand the given command into many commands, if the command + // has `"iterateOn": "profiles"` set. + // - If it doesn't, this function will do + // nothing and return an empty vector. + // - If it does, we're going to attempt to build a new set of commands using + // the given command as a prototype. We'll attempt to create a new command + // for each and every profile, to replace the original command. + // * For the new commands, we'll replace any instance of "${profile.name}" + // in the original json used to create this action with the name of the + // given profile. + // - If we encounter any errors while re-parsing the json with the replaced + // name, we'll just return immediately. + // - At the end, we'll return all the new commands we've build for the given command. + // Arguments: + // - expandable: the Command to potentially turn into more commands + // - profiles: A list of all the profiles that this command should be expanded on. + // - warnings: If there were any warnings during parsing, they'll be + // appended to this vector. + // Return Value: + // - and empty vector if the command wasn't expandable, otherwise a list of + // the newly-created commands. + std::vector Command::_expandCommand(Command* const expandable, + gsl::span profiles, + std::vector<::TerminalApp::SettingsLoadWarnings>& warnings) + { + std::vector newCommands; + + if (expandable->HasNestedCommands()) + { + ExpandCommands(expandable->_subcommands, profiles, warnings); + } + + if (expandable->_IterateOn == ExpandCommandType::None) + { + return newCommands; + } + + std::string errs; // This string will receive any error text from failing to parse. + std::unique_ptr reader{ Json::CharReaderBuilder::CharReaderBuilder().newCharReader() }; + + // First, get a string for the original Json::Value + auto oldJsonString = expandable->_originalJson.toStyledString(); + + if (expandable->_IterateOn == ExpandCommandType::Profiles) + { + for (const auto& p : profiles) + { + // For each profile, create a new command. This command will have: + // * the icon path and keychord text of the original command + // * the Name will have any instances of "${profile.name}" + // replaced with the profile's name + // * for the action, we'll take the original json, replace any + // instances of "${profile.name}" with the profile's name, + // then re-attempt to parse the action and args. + + // Replace all the keywords in the original json, and try and parse that + + // - Escape the profile name for JSON appropriately + auto escapedProfileName = _escapeForJson(til::u16u8(p.GetName())); + auto newJsonString = til::replace_needle_in_haystack(oldJsonString, + ProfileName, + escapedProfileName); + + // - Now, re-parse the modified value. + Json::Value newJsonValue; + const auto actualDataStart = newJsonString.data(); + const auto actualDataEnd = newJsonString.data() + newJsonString.size(); + if (!reader->parse(actualDataStart, actualDataEnd, &newJsonValue, &errs)) + { + warnings.push_back(::TerminalApp::SettingsLoadWarnings::FailedToParseCommandJson); + // If we encounter a re-parsing error, just stop processing the rest of the commands. + break; + } + + // Pass the new json back though FromJson, to get the new expanded value. + if (auto newCmd{ Command::FromJson(newJsonValue, warnings) }) + { + newCommands.push_back(*newCmd); + } + } + } + + return newCommands; + } } diff --git a/src/cascadia/TerminalApp/Command.h b/src/cascadia/TerminalApp/Command.h index b037df3beb7..700dd87e2d7 100644 --- a/src/cascadia/TerminalApp/Command.h +++ b/src/cascadia/TerminalApp/Command.h @@ -1,4 +1,4 @@ -/*++ +/*++ Copyright (c) Microsoft Corporation Licensed under the MIT license. @@ -20,17 +20,39 @@ Author(s): #include "Command.g.h" #include "TerminalWarnings.h" +#include "Profile.h" #include "..\inc\cppwinrt_utils.h" +// fwdecl unittest classes +namespace TerminalAppLocalTests +{ + class SettingsTests; + class CommandTests; +}; + namespace winrt::TerminalApp::implementation { + enum class ExpandCommandType : uint32_t + { + None = 0, + Profiles + }; + struct Command : CommandT { - Command() = default; + Command(); - static winrt::com_ptr FromJson(const Json::Value& json, std::vector<::TerminalApp::SettingsLoadWarnings>& warnings); - static std::vector<::TerminalApp::SettingsLoadWarnings> LayerJson(std::unordered_map& commands, + static winrt::com_ptr FromJson(const Json::Value& json, + std::vector<::TerminalApp::SettingsLoadWarnings>& warnings); + + static void ExpandCommands(Windows::Foundation::Collections::IMap& commands, + gsl::span profiles, + std::vector<::TerminalApp::SettingsLoadWarnings>& warnings); + + static std::vector<::TerminalApp::SettingsLoadWarnings> LayerJson(Windows::Foundation::Collections::IMap& commands, const Json::Value& json); + bool HasNestedCommands(); + Windows::Foundation::Collections::IMapView NestedCommands(); winrt::Windows::UI::Xaml::Data::INotifyPropertyChanged::PropertyChanged_revoker propertyChangedRevoker; @@ -39,6 +61,18 @@ namespace winrt::TerminalApp::implementation OBSERVABLE_GETSET_PROPERTY(winrt::TerminalApp::ActionAndArgs, Action, _PropertyChangedHandlers); OBSERVABLE_GETSET_PROPERTY(winrt::hstring, KeyChordText, _PropertyChangedHandlers); OBSERVABLE_GETSET_PROPERTY(winrt::Windows::UI::Xaml::Controls::IconSource, IconSource, _PropertyChangedHandlers, nullptr); + + GETSET_PROPERTY(ExpandCommandType, IterateOn, ExpandCommandType::None); + + private: + Json::Value _originalJson; + Windows::Foundation::Collections::IMap _subcommands{ nullptr }; + + static std::vector _expandCommand(Command* const expandable, + gsl::span profiles, + std::vector<::TerminalApp::SettingsLoadWarnings>& warnings); + friend class TerminalAppLocalTests::SettingsTests; + friend class TerminalAppLocalTests::CommandTests; }; } diff --git a/src/cascadia/TerminalApp/Command.idl b/src/cascadia/TerminalApp/Command.idl index f54de393f9e..3aa55c64420 100644 --- a/src/cascadia/TerminalApp/Command.idl +++ b/src/cascadia/TerminalApp/Command.idl @@ -14,5 +14,8 @@ namespace TerminalApp String KeyChordText; Windows.UI.Xaml.Controls.IconSource IconSource; + + Boolean HasNestedCommands(); + Windows.Foundation.Collections.IMapView NestedCommands { get; }; } } diff --git a/src/cascadia/TerminalApp/CommandPalette.cpp b/src/cascadia/TerminalApp/CommandPalette.cpp index 8325500b398..c6c2061b004 100644 --- a/src/cascadia/TerminalApp/CommandPalette.cpp +++ b/src/cascadia/TerminalApp/CommandPalette.cpp @@ -28,6 +28,8 @@ namespace winrt::TerminalApp::implementation InitializeComponent(); _filteredActions = winrt::single_threaded_observable_vector(); + _nestedActionStack = winrt::single_threaded_vector(); + _currentNestedCommands = winrt::single_threaded_vector(); _allCommands = winrt::single_threaded_vector(); _allTabActions = winrt::single_threaded_vector(); @@ -67,6 +69,7 @@ namespace winrt::TerminalApp::implementation else { _searchBox().Focus(FocusState::Programmatic); + _updateFilteredActions(); _filteredActionsView().SelectedIndex(0); } @@ -271,6 +274,29 @@ namespace winrt::TerminalApp::implementation _dispatchCommand(e.ClickedItem().try_as()); } + // Method Description: + // - This is called when the user selects a command with subcommands. It + // will update our UI to now display the list of subcommands instead, and + // clear the search text so the user can search from the new list of + // commands. + // Arguments: + // - + // Return Value: + // - + void CommandPalette::_updateUIForStackChange() + { + if (_searchBox().Text().empty()) + { + // Manually call _filterTextChanged, because setting the text to the + // empty string won't update it for us (as it won't actually change value.) + _filterTextChanged(nullptr, nullptr); + } + + // Changing the value of the search box will trigger _filterTextChanged, + // which will cause us to refresh the list of filterable commands. + _searchBox().Text(L""); + } + // Method Description: // - Retrieve the list of commands that we should currently be filtering. // * If the user has command with subcommands, this will return that command's subcommands. @@ -285,6 +311,11 @@ namespace winrt::TerminalApp::implementation switch (_currentMode) { case CommandPaletteMode::ActionMode: + if (_nestedActionStack.Size() > 0) + { + return _currentNestedCommands; + } + return _allCommands; case CommandPaletteMode::TabSwitcherMode: return _allTabActions; @@ -306,20 +337,44 @@ namespace winrt::TerminalApp::implementation { if (command) { - // Close before we dispatch so that actions that open the command - // palette like the Tab Switcher will be able to have the last laugh. - _close(); - - const auto actionAndArgs = command.Action(); - _dispatch.DoAction(actionAndArgs); - - TraceLoggingWrite( - g_hTerminalAppProvider, // handle to TerminalApp tracelogging provider - "CommandPaletteDispatchedAction", - TraceLoggingDescription("Event emitted when the user selects an action in the Command Palette"), - TraceLoggingUInt32(_searchBox().Text().size(), "SearchTextLength", "Number of characters in the search string"), - TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), - TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance)); + if (command.HasNestedCommands()) + { + // If this Command had subcommands, then don't dispatch the + // action. Instead, display a new list of commands for the user + // to pick from. + _nestedActionStack.Append(command); + _currentNestedCommands.Clear(); + for (const auto& nameAndCommand : command.NestedCommands()) + { + _currentNestedCommands.Append(nameAndCommand.Value()); + } + + _updateUIForStackChange(); + } + else + { + // First stash the search text length, because _close will clear this. + const auto searchTextLength = _searchBox().Text().size(); + + // An action from the root command list has depth=0 + const auto nestedCommandDepth = _nestedActionStack.Size(); + + // Close before we dispatch so that actions that open the command + // palette like the Tab Switcher will be able to have the last laugh. + _close(); + + const auto actionAndArgs = command.Action(); + _dispatch.DoAction(actionAndArgs); + + TraceLoggingWrite( + g_hTerminalAppProvider, // handle to TerminalApp tracelogging provider + "CommandPaletteDispatchedAction", + TraceLoggingDescription("Event emitted when the user selects an action in the Command Palette"), + TraceLoggingUInt32(searchTextLength, "SearchTextLength", "Number of characters in the search string"), + TraceLoggingUInt32(nestedCommandDepth, "NestedCommandDepth", "the depth in the tree of commands for the dispatched action"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), + TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance)); + } } } @@ -707,6 +762,9 @@ namespace winrt::TerminalApp::implementation // Clear the text box each time we close the dialog. This is consistent with VsCode. _searchBox().Text(L""); + + _nestedActionStack.Clear(); + _currentNestedCommands.Clear(); } // Method Description: diff --git a/src/cascadia/TerminalApp/CommandPalette.h b/src/cascadia/TerminalApp/CommandPalette.h index b062b42003c..641f0606f19 100644 --- a/src/cascadia/TerminalApp/CommandPalette.h +++ b/src/cascadia/TerminalApp/CommandPalette.h @@ -37,9 +37,11 @@ namespace winrt::TerminalApp::implementation private: friend struct CommandPaletteT; // for Xaml to bind events + Windows::Foundation::Collections::IVector _allCommands{ nullptr }; + Windows::Foundation::Collections::IVector _currentNestedCommands{ nullptr }; Windows::Foundation::Collections::IObservableVector _filteredActions{ nullptr }; + Windows::Foundation::Collections::IVector _nestedActionStack{ nullptr }; - Windows::Foundation::Collections::IVector _allCommands{ nullptr }; winrt::TerminalApp::ShortcutActionDispatch _dispatch; Windows::Foundation::Collections::IVector _commandsToFilter(); @@ -53,6 +55,8 @@ namespace winrt::TerminalApp::implementation void _keyUpHandler(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::Input::KeyRoutedEventArgs const& e); + void _updateUIForStackChange(); + void _rootPointerPressed(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs const& e); void _backdropPointerPressed(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs const& e); @@ -61,7 +65,9 @@ namespace winrt::TerminalApp::implementation void _selectNextItem(const bool moveDown); void _updateFilteredActions(); + std::vector _collectFilteredActions(); + static int _getWeight(const winrt::hstring& searchText, const winrt::hstring& name); void _close(); diff --git a/src/cascadia/TerminalApp/GlobalAppSettings.cpp b/src/cascadia/TerminalApp/GlobalAppSettings.cpp index afeca688c6d..b9d6175df01 100644 --- a/src/cascadia/TerminalApp/GlobalAppSettings.cpp +++ b/src/cascadia/TerminalApp/GlobalAppSettings.cpp @@ -60,6 +60,7 @@ GlobalAppSettings::GlobalAppSettings() : _WordDelimiters{ DEFAULT_WORD_DELIMITERS }, _DebugFeaturesEnabled{ debugFeaturesDefault } { + _commands = winrt::single_threaded_map(); } GlobalAppSettings::~GlobalAppSettings() @@ -230,7 +231,12 @@ std::vector GlobalAppSettings::GetKeybindings return _keybindingsWarnings; } -const std::unordered_map& GlobalAppSettings::GetCommands() const noexcept +const winrt::Windows::Foundation::Collections::IMap& GlobalAppSettings::GetCommands() const noexcept +{ + return _commands; +} + +winrt::Windows::Foundation::Collections::IMap& GlobalAppSettings::GetCommands() noexcept { return _commands; } diff --git a/src/cascadia/TerminalApp/GlobalAppSettings.h b/src/cascadia/TerminalApp/GlobalAppSettings.h index ba51109fa0b..6a72d0ad857 100644 --- a/src/cascadia/TerminalApp/GlobalAppSettings.h +++ b/src/cascadia/TerminalApp/GlobalAppSettings.h @@ -50,7 +50,8 @@ class TerminalApp::GlobalAppSettings final std::vector GetKeybindingsWarnings() const; - const std::unordered_map& GetCommands() const noexcept; + const winrt::Windows::Foundation::Collections::IMap& GetCommands() const noexcept; + winrt::Windows::Foundation::Collections::IMap& GetCommands() noexcept; // These are implemented manually to handle the string/GUID exchange // by higher layers in the app. @@ -89,7 +90,7 @@ class TerminalApp::GlobalAppSettings final std::vector<::TerminalApp::SettingsLoadWarnings> _keybindingsWarnings; std::unordered_map _colorSchemes; - std::unordered_map _commands; + winrt::Windows::Foundation::Collections::IMap _commands; friend class TerminalAppLocalTests::SettingsTests; friend class TerminalAppLocalTests::ColorSchemeTests; diff --git a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw index c8951fac9f2..9d9cd244648 100644 --- a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw +++ b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw @@ -222,6 +222,10 @@ For more info, see this web page. + + Failed to expand a command with "iterateOn" set. This command will be ignored. + {Locked="\"iterateOn\""} + An optional command, with arguments, to be spawned in the new tab or pane diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index 22547b2e005..abd7768afc9 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -51,6 +51,60 @@ namespace winrt::TerminalApp::implementation InitializeComponent(); } + // Function Description: + // - Recursively check our commands to see if there's a keybinding for + // exactly their action. If there is, label that command with the text + // corresponding to that key chord. + // - Will recurse into nested commands as well. + // Arguments: + // - settings: The settings who's keybindings we should use to look up the key chords from + // - commands: The list of commands to label. + static void _recursiveUpdateCommandKeybindingLabels(std::shared_ptr<::TerminalApp::CascadiaSettings> settings, + Windows::Foundation::Collections::IMapView commands) + { + for (const auto& nameAndCmd : commands) + { + const auto& command = nameAndCmd.Value(); + // If there's a keybinding that's bound to exactly this command, + // then get the string for that keychord and display it as a + // part of the command in the UI. Each Command's KeyChordText is + // unset by default, so we don't need to worry about clearing it + // if there isn't a key associated with it. + auto keyChord{ settings->GetKeybindings().GetKeyBindingForActionWithArgs(command.Action()) }; + + if (keyChord) + { + command.KeyChordText(KeyChordSerialization::ToString(keyChord)); + } + if (command.HasNestedCommands()) + { + _recursiveUpdateCommandKeybindingLabels(settings, command.NestedCommands()); + } + } + } + + static void _recursiveUpdateCommandIcons(Windows::Foundation::Collections::IMapView commands) + { + for (const auto& nameAndCmd : commands) + { + const auto& command = nameAndCmd.Value(); + // Set the default IconSource to a BitmapIconSource with a null source + // (instead of just nullptr) because there's a really weird crash when swapping + // data bound IconSourceElements in a ListViewTemplate (i.e. CommandPalette). + // Swapping between nullptr IconSources and non-null IconSources causes a crash + // to occur, but swapping between IconSources with a null source and non-null IconSources + // work perfectly fine :shrug:. + winrt::Windows::UI::Xaml::Controls::BitmapIconSource icon; + icon.UriSource(nullptr); + command.IconSource(icon); + + if (command.HasNestedCommands()) + { + _recursiveUpdateCommandIcons(command.NestedCommands()); + } + } + } + winrt::fire_and_forget TerminalPage::SetSettings(std::shared_ptr<::TerminalApp::CascadiaSettings> settings, bool needRefreshUI) { @@ -64,36 +118,7 @@ namespace winrt::TerminalApp::implementation co_await winrt::resume_foreground(Dispatcher()); if (auto page{ weakThis.get() }) { - // Update the command palette when settings reload - auto commandsCollection = winrt::single_threaded_vector(); - for (auto& nameAndCommand : _settings->GlobalSettings().GetCommands()) - { - auto command = nameAndCommand.second; - - // If there's a keybinding that's bound to exactly this command, - // then get the string for that keychord and display it as a - // part of the command in the UI. Each Command's KeyChordText is - // unset by default, so we don't need to worry about clearing it - // if there isn't a key associated with it. - auto keyChord{ _settings->GetKeybindings().GetKeyBindingForActionWithArgs(command.Action()) }; - if (keyChord) - { - command.KeyChordText(KeyChordSerialization::ToString(keyChord)); - } - - // Set the default IconSource to a BitmapIconSource with a null source - // (instead of just nullptr) because there's a really weird crash when swapping - // data bound IconSourceElements in a ListViewTemplate (i.e. CommandPalette). - // Swapping between nullptr IconSources and non-null IconSources causes a crash - // to occur, but swapping between IconSources with a null source and non-null IconSources - // work perfectly fine :shrug:. - winrt::Windows::UI::Xaml::Controls::BitmapIconSource icon; - icon.UriSource(nullptr); - command.IconSource(icon); - - commandsCollection.Append(command); - } - CommandPalette().SetCommands(commandsCollection); + _UpdateCommandsForPalette(); } } @@ -1807,10 +1832,12 @@ namespace winrt::TerminalApp::implementation } // Method Description: - // - Responds to changes in the TabView's item list by changing the tabview's - // visibility. This method is also invoked when tabs are dragged / dropped as part of tab reordering - // and this method hands that case as well in concert with TabDragStarting and TabDragCompleted handlers - // that are set up in TerminalPage::Create() + // - Responds to changes in the TabView's item list by changing the + // tabview's visibility. + // - This method is also invoked when tabs are dragged / dropped as part of + // tab reordering and this method hands that case as well in concert with + // TabDragStarting and TabDragCompleted handlers that are set up in + // TerminalPage::Create() // Arguments: // - sender: the control that originated this event // - eventArgs: the event's constituent arguments @@ -1828,6 +1855,10 @@ namespace winrt::TerminalApp::implementation _rearrangeTo = eventArgs.Index(); } } + else + { + _UpdateCommandsForPalette(); + } _UpdateTabView(); } @@ -2004,6 +2035,54 @@ namespace winrt::TerminalApp::implementation _alwaysOnTopChangedHandlers(*this, nullptr); } + // Method Description: + // - Takes a mapping of names->commands and expands them + // Arguments: + // - + // Return Value: + // - + IMap TerminalPage::_ExpandCommands(IMapView commandsToExpand, + gsl::span profiles) + { + std::vector<::TerminalApp::SettingsLoadWarnings> warnings; + IMap copyOfCommands = winrt::single_threaded_map(); + for (const auto& nameAndCommand : commandsToExpand) + { + copyOfCommands.Insert(nameAndCommand.Key(), nameAndCommand.Value()); + } + + Command::ExpandCommands(copyOfCommands, + profiles, + warnings); + + return copyOfCommands; + } + // Method Description: + // - Repopulates the list of commands in the command palette with the + // current commands in the settings. Also updates the keybinding labels to + // reflect any matching keybindings. + // Arguments: + // - + // Return Value: + // - + void TerminalPage::_UpdateCommandsForPalette() + { + IMap copyOfCommands = _ExpandCommands(_settings->GlobalSettings().GetCommands().GetView(), + _settings->GetProfiles()); + + _recursiveUpdateCommandKeybindingLabels(_settings, copyOfCommands.GetView()); + _recursiveUpdateCommandIcons(copyOfCommands.GetView()); + + // Update the command palette when settings reload + auto commandsCollection = winrt::single_threaded_vector(); + for (const auto& nameAndCommand : copyOfCommands) + { + commandsCollection.Append(nameAndCommand.Value()); + } + + CommandPalette().SetCommands(commandsCollection); + } + // Method Description: // - Sets the initial actions to process on startup. We'll make a copy of // this list, and process these actions when we're loaded. diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h index d89f96ca931..36c8d1328c6 100644 --- a/src/cascadia/TerminalApp/TerminalPage.h +++ b/src/cascadia/TerminalApp/TerminalPage.h @@ -16,6 +16,7 @@ namespace TerminalAppLocalTests { class TabTests; + class SettingsTests; }; namespace winrt::TerminalApp::implementation @@ -134,6 +135,10 @@ namespace winrt::TerminalApp::implementation void _UpdateTabIcon(Tab& tab); void _UpdateTabView(); void _UpdateTabWidthMode(); + void _UpdateCommandsForPalette(); + static winrt::Windows::Foundation::Collections::IMap _ExpandCommands(Windows::Foundation::Collections::IMapView commandsToExpand, + gsl::span profiles); + void _DuplicateTabViewItem(); void _RemoveTabViewItem(const Microsoft::UI::Xaml::Controls::TabViewItem& tabViewItem); void _RemoveTabViewItemByIndex(uint32_t tabIndex); @@ -236,6 +241,7 @@ namespace winrt::TerminalApp::implementation #pragma endregion friend class TerminalAppLocalTests::TabTests; + friend class TerminalAppLocalTests::SettingsTests; }; } diff --git a/src/cascadia/TerminalApp/TerminalWarnings.h b/src/cascadia/TerminalApp/TerminalWarnings.h index aa0bb1b869d..3b0be2b4022 100644 --- a/src/cascadia/TerminalApp/TerminalWarnings.h +++ b/src/cascadia/TerminalApp/TerminalWarnings.h @@ -30,6 +30,7 @@ namespace TerminalApp TooManyKeysForChord = 6, MissingRequiredParameter = 7, LegacyGlobalsProperty = 8, + FailedToParseCommandJson = 9, WARNINGS_SIZE // IMPORTANT: This MUST be the last value in this enum. It's an unused placeholder. }; diff --git a/src/cascadia/TerminalApp/lib/pch.h b/src/cascadia/TerminalApp/lib/pch.h index 4cb7a49f1e3..dcac6c4e1ab 100644 --- a/src/cascadia/TerminalApp/lib/pch.h +++ b/src/cascadia/TerminalApp/lib/pch.h @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index 1f0fb413e26..0590243e6eb 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -6,9 +6,10 @@ #include "../types/inc/Viewport.hpp" #include "../types/inc/utils.hpp" #include "../types/inc/User32Utils.hpp" - #include "resource.h" +#include + using namespace winrt::Windows::UI; using namespace winrt::Windows::UI::Composition; using namespace winrt::Windows::UI::Xaml; diff --git a/src/cascadia/WindowsTerminal/AppHost.h b/src/cascadia/WindowsTerminal/AppHost.h index 4e072411de8..d2b6dd77c69 100644 --- a/src/cascadia/WindowsTerminal/AppHost.h +++ b/src/cascadia/WindowsTerminal/AppHost.h @@ -3,7 +3,6 @@ #include "pch.h" -#include #include #include "NonClientIslandWindow.h" diff --git a/src/cascadia/WindowsTerminal/IslandWindow.h b/src/cascadia/WindowsTerminal/IslandWindow.h index cd593e6663f..29d24156f55 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.h +++ b/src/cascadia/WindowsTerminal/IslandWindow.h @@ -3,7 +3,6 @@ #include "pch.h" #include "BaseWindow.h" -#include #include #include "../../cascadia/inc/cppwinrt_utils.h" diff --git a/src/inc/til.h b/src/inc/til.h index 36e10ad0e6f..1816d2e0736 100644 --- a/src/inc/til.h +++ b/src/inc/til.h @@ -17,6 +17,7 @@ #include "til/u8u16convert.h" #include "til/spsc.h" #include "til/coalesce.h" +#include "til/replace.h" namespace til // Terminal Implementation Library. Also: "Today I Learned" { diff --git a/src/inc/til/replace.h b/src/inc/til/replace.h new file mode 100644 index 00000000000..466eb035e21 --- /dev/null +++ b/src/inc/til/replace.h @@ -0,0 +1,73 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +#pragma once + +namespace til +{ + namespace details + { + template + struct view_type_oracle + { + }; + + template<> + struct view_type_oracle + { + using type = std::string_view; + }; + + template<> + struct view_type_oracle + { + using type = std::wstring_view; + }; + + } + + // Method Description: + // - This is a function for finding all occurences of a given string + // `needle` in a larger string `haystack`, and replacing them with the + // string `replacement`. + // - This find/replace is done in-place, leaving `haystack` modified as a result. + // Arguments: + // - haystack: The string to find and replace in + // - needle: The string to search for + // - replacement: The string to replace `needle` with + // Return Value: + // - + template + void replace_needle_in_haystack_inplace(T& haystack, + const typename details::view_type_oracle::type& needle, + const typename details::view_type_oracle::type& replacement) + { + auto pos{ T::npos }; + while ((pos = haystack.rfind(needle, pos)) != T::npos) + { + haystack.replace(pos, needle.size(), replacement); + } + } + + // Method Description: + // - This is a function for finding all occurences of a given string + // `needle` in a larger string `haystack`, and replacing them with the + // string `replacement`. + // - This find/replace is done on a copy of `haystack`, leaving `haystack` + // unmodified, and returning a new string. + // Arguments: + // - haystack: The string to search for `needle` in. + // - needle: The string to search for + // - replacement: The string to replace `needle` with + // Return Value: + // - a copy of `haystack` with all instances of `needle` replaced with `replacement`.` + template + T replace_needle_in_haystack(const T& haystack, + const typename details::view_type_oracle::type& needle, + const typename details::view_type_oracle::type& replacement) + { + std::basic_string result{ haystack }; + replace_needle_in_haystack_inplace(result, needle, replacement); + return result; + } +} diff --git a/src/til/ut_til/ReplaceTests.cpp b/src/til/ut_til/ReplaceTests.cpp new file mode 100644 index 00000000000..827c6872cdd --- /dev/null +++ b/src/til/ut_til/ReplaceTests.cpp @@ -0,0 +1,132 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +#include "precomp.h" +#include "WexTestClass.h" + +using namespace WEX::Common; +using namespace WEX::Logging; +using namespace WEX::TestExecution; + +class ReplaceTests +{ + TEST_CLASS(ReplaceTests); + + TEST_METHOD(ReplaceStrings); + TEST_METHOD(ReplaceStringAndViews); + TEST_METHOD(ReplaceStringsInplace); + TEST_METHOD(ReplaceStringAndViewsInplace); + + TEST_METHOD(ReplaceWstrings); + TEST_METHOD(ReplaceWstringAndViews); + TEST_METHOD(ReplaceWstringsInplace); + TEST_METHOD(ReplaceWstringAndViewsInplace); + + // There are explicitly no winrt::hstring tests here, because it's capital-H + // hard to get the winrt hstring header included in this project without + // pulling in all of the winrt machinery. +}; + +void ReplaceTests::ReplaceStrings() +{ + std::string foo{ "foo" }; + + auto temp1 = til::replace_needle_in_haystack(foo, "f", "b"); + VERIFY_ARE_EQUAL("boo", temp1); + + auto temp2 = til::replace_needle_in_haystack(temp1, "o", "00"); + VERIFY_ARE_EQUAL("b0000", temp2); +} + +void ReplaceTests::ReplaceStringAndViews() +{ + std::string foo{ "foo" }; + std::string_view f{ "f" }; + std::string_view b{ "b" }; + std::string_view o{ "o" }; + std::string_view zeroZero{ "00" }; + + auto temp1 = til::replace_needle_in_haystack(foo, f, b); + VERIFY_ARE_EQUAL("boo", temp1); + + auto temp2 = til::replace_needle_in_haystack(temp1, o, zeroZero); + VERIFY_ARE_EQUAL("b0000", temp2); +} + +void ReplaceTests::ReplaceStringsInplace() +{ + std::string foo{ "foo" }; + + til::replace_needle_in_haystack_inplace(foo, "f", "b"); + VERIFY_ARE_EQUAL("boo", foo); + + til::replace_needle_in_haystack_inplace(foo, "o", "00"); + VERIFY_ARE_EQUAL("b0000", foo); +} + +void ReplaceTests::ReplaceStringAndViewsInplace() +{ + std::string foo{ "foo" }; + std::string_view f{ "f" }; + std::string_view b{ "b" }; + std::string_view o{ "o" }; + std::string_view zeroZero{ "00" }; + + til::replace_needle_in_haystack_inplace(foo, f, b); + VERIFY_ARE_EQUAL("boo", foo); + + til::replace_needle_in_haystack_inplace(foo, o, zeroZero); + VERIFY_ARE_EQUAL("b0000", foo); +} + +void ReplaceTests::ReplaceWstrings() +{ + std::wstring foo{ L"foo" }; + + auto temp1 = til::replace_needle_in_haystack(foo, L"f", L"b"); + VERIFY_ARE_EQUAL(L"boo", temp1); + + auto temp2 = til::replace_needle_in_haystack(temp1, L"o", L"00"); + VERIFY_ARE_EQUAL(L"b0000", temp2); +} + +void ReplaceTests::ReplaceWstringAndViews() +{ + std::wstring foo{ L"foo" }; + std::wstring_view f{ L"f" }; + std::wstring_view b{ L"b" }; + std::wstring_view o{ L"o" }; + std::wstring_view zeroZero{ L"00" }; + + auto temp1 = til::replace_needle_in_haystack(foo, f, b); + VERIFY_ARE_EQUAL(L"boo", temp1); + + auto temp2 = til::replace_needle_in_haystack(temp1, o, zeroZero); + VERIFY_ARE_EQUAL(L"b0000", temp2); +} + +void ReplaceTests::ReplaceWstringsInplace() +{ + std::wstring foo{ L"foo" }; + + til::replace_needle_in_haystack_inplace(foo, L"f", L"b"); + VERIFY_ARE_EQUAL(L"boo", foo); + + til::replace_needle_in_haystack_inplace(foo, L"o", L"00"); + VERIFY_ARE_EQUAL(L"b0000", foo); +} + +void ReplaceTests::ReplaceWstringAndViewsInplace() +{ + std::wstring foo{ L"foo" }; + std::wstring_view f{ L"f" }; + std::wstring_view b{ L"b" }; + std::wstring_view o{ L"o" }; + std::wstring_view zeroZero{ L"00" }; + + til::replace_needle_in_haystack_inplace(foo, f, b); + VERIFY_ARE_EQUAL(L"boo", foo); + + til::replace_needle_in_haystack_inplace(foo, o, zeroZero); + VERIFY_ARE_EQUAL(L"b0000", foo); +} diff --git a/src/til/ut_til/til.unit.tests.vcxproj b/src/til/ut_til/til.unit.tests.vcxproj index 52a07246b81..d25d9147f02 100644 --- a/src/til/ut_til/til.unit.tests.vcxproj +++ b/src/til/ut_til/til.unit.tests.vcxproj @@ -19,6 +19,7 @@ + Create From aecd99e0ca3275e1a02e782ee2ff815a93248c6c Mon Sep 17 00:00:00 2001 From: "Dustin L. Howett" Date: Fri, 14 Aug 2020 16:44:39 -0700 Subject: [PATCH 050/266] Pass the scancode in our tunneled DirectKey event (#7298) #7145 introduced a check so that we wouldn't dispatch keys unless they actually had a scancode. Our synthetic events actually _didn't_ have scancodes. Not because they couldn't--just because they didn't. Fixes #7297 --- src/cascadia/TerminalApp/AppLogic.cpp | 4 ++-- src/cascadia/TerminalApp/AppLogic.h | 2 +- src/cascadia/TerminalApp/IDirectKeyListener.idl | 4 ++-- src/cascadia/TerminalControl/TermControl.cpp | 8 +++----- src/cascadia/TerminalControl/TermControl.h | 2 +- src/cascadia/TerminalControl/TermControl.idl | 4 ++-- src/cascadia/WindowsTerminal/AppHost.cpp | 4 ++-- src/cascadia/WindowsTerminal/AppHost.h | 2 +- src/cascadia/WindowsTerminal/main.cpp | 4 ++-- 9 files changed, 16 insertions(+), 18 deletions(-) diff --git a/src/cascadia/TerminalApp/AppLogic.cpp b/src/cascadia/TerminalApp/AppLogic.cpp index b11c1e2a1fd..148898cd94f 100644 --- a/src/cascadia/TerminalApp/AppLogic.cpp +++ b/src/cascadia/TerminalApp/AppLogic.cpp @@ -917,7 +917,7 @@ namespace winrt::TerminalApp::implementation // - Implements the Alt handler (per GH#6421) // Return value: // - whether the key was handled - bool AppLogic::OnDirectKeyEvent(const uint32_t vkey, const bool down) + bool AppLogic::OnDirectKeyEvent(const uint32_t vkey, const uint8_t scanCode, const bool down) { if (_root) { @@ -928,7 +928,7 @@ namespace winrt::TerminalApp::implementation { if (auto keyListener{ focusedObject.try_as() }) { - if (keyListener.OnDirectKeyEvent(vkey, down)) + if (keyListener.OnDirectKeyEvent(vkey, scanCode, down)) { return true; } diff --git a/src/cascadia/TerminalApp/AppLogic.h b/src/cascadia/TerminalApp/AppLogic.h index de2b225f81f..c0c75952b1a 100644 --- a/src/cascadia/TerminalApp/AppLogic.h +++ b/src/cascadia/TerminalApp/AppLogic.h @@ -48,7 +48,7 @@ namespace winrt::TerminalApp::implementation hstring Title(); void TitlebarClicked(); - bool OnDirectKeyEvent(const uint32_t vkey, const bool down); + bool OnDirectKeyEvent(const uint32_t vkey, const uint8_t scanCode, const bool down); void WindowCloseButtonClicked(); diff --git a/src/cascadia/TerminalApp/IDirectKeyListener.idl b/src/cascadia/TerminalApp/IDirectKeyListener.idl index 4fb5dea1bc0..06df1a5d3bd 100644 --- a/src/cascadia/TerminalApp/IDirectKeyListener.idl +++ b/src/cascadia/TerminalApp/IDirectKeyListener.idl @@ -8,7 +8,7 @@ namespace TerminalApp // If you update this one, please update the one in TerminalControl\TermControl.idl // If you change this interface, please update the guid. // If you press F7 or Alt and get a runtime error, go make sure both copies are the same. - [uuid("339e1a87-5315-4da6-96f0-565549b6472b")] interface IDirectKeyListener { - Boolean OnDirectKeyEvent(UInt32 vkey, Boolean down); + [uuid("0ddf4edc-3fda-4dee-97ca-a417ee3dd510")] interface IDirectKeyListener { + Boolean OnDirectKeyEvent(UInt32 vkey, UInt8 scanCode, Boolean down); } } diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index 058e478bc72..b493054c6a1 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -763,7 +763,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation // normally. Namely, the keys we're concerned with are F7 down and Alt up. // Return value: // - Whether the key was handled. - bool TermControl::OnDirectKeyEvent(const uint32_t vkey, const bool down) + bool TermControl::OnDirectKeyEvent(const uint32_t vkey, const uint8_t scanCode, const bool down) { const auto modifiers{ _GetPressedModifierKeys() }; auto handled = false; @@ -771,9 +771,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation { // Manually generate an Alt KeyUp event into the key bindings or terminal. // This is required as part of GH#6421. - // GH#6513 - make sure to set the scancode too, otherwise conpty - // will think this is a NUL - (void)_TrySendKeyEvent(VK_MENU, LOWORD(MapVirtualKeyW(VK_MENU, MAPVK_VK_TO_VSC)), modifiers, false); + (void)_TrySendKeyEvent(VK_MENU, scanCode, modifiers, false); handled = true; } else if (vkey == VK_F7 && down) @@ -795,7 +793,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation if (!handled) { // _TrySendKeyEvent pretends it didn't handle F7 for some unknown reason. - (void)_TrySendKeyEvent(VK_F7, 0, modifiers, true); + (void)_TrySendKeyEvent(VK_F7, scanCode, modifiers, true); // GH#6438: Note that we're _not_ sending the key up here - that'll // get passed through XAML to our KeyUp handler normally. handled = true; diff --git a/src/cascadia/TerminalControl/TermControl.h b/src/cascadia/TerminalControl/TermControl.h index b34ea7b813c..e62f7fe25e5 100644 --- a/src/cascadia/TerminalControl/TermControl.h +++ b/src/cascadia/TerminalControl/TermControl.h @@ -91,7 +91,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation void CreateSearchBoxControl(); - bool OnDirectKeyEvent(const uint32_t vkey, const bool down); + bool OnDirectKeyEvent(const uint32_t vkey, const uint8_t scanCode, const bool down); bool OnMouseWheel(const Windows::Foundation::Point location, const int32_t delta, const bool leftButtonDown, const bool midButtonDown, const bool rightButtonDown); diff --git a/src/cascadia/TerminalControl/TermControl.idl b/src/cascadia/TerminalControl/TermControl.idl index 4e3eefa0c44..66d64d74265 100644 --- a/src/cascadia/TerminalControl/TermControl.idl +++ b/src/cascadia/TerminalControl/TermControl.idl @@ -15,8 +15,8 @@ namespace Microsoft.Terminal.TerminalControl // If you update this one, please update TerminalApp\IDirectKeyListener.idl. // If you change this interface, please update the guid. // If you press F7 or Alt and get a runtime error, go make sure both copies are the same. - [uuid("339e1a87-5315-4da6-96f0-565549b6472b")] interface IDirectKeyListener { - Boolean OnDirectKeyEvent(UInt32 vkey, Boolean down); + [uuid("0ddf4edc-3fda-4dee-97ca-a417ee3dd510")] interface IDirectKeyListener { + Boolean OnDirectKeyEvent(UInt32 vkey, UInt8 scanCode, Boolean down); } runtimeclass CopyToClipboardEventArgs diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index 0590243e6eb..0ae788956a5 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -69,11 +69,11 @@ AppHost::~AppHost() _app = nullptr; } -bool AppHost::OnDirectKeyEvent(const uint32_t vkey, const bool down) +bool AppHost::OnDirectKeyEvent(const uint32_t vkey, const uint8_t scanCode, const bool down) { if (_logic) { - return _logic.OnDirectKeyEvent(vkey, down); + return _logic.OnDirectKeyEvent(vkey, scanCode, down); } return false; } diff --git a/src/cascadia/WindowsTerminal/AppHost.h b/src/cascadia/WindowsTerminal/AppHost.h index d2b6dd77c69..d99fddadb92 100644 --- a/src/cascadia/WindowsTerminal/AppHost.h +++ b/src/cascadia/WindowsTerminal/AppHost.h @@ -16,7 +16,7 @@ class AppHost void AppTitleChanged(const winrt::Windows::Foundation::IInspectable& sender, winrt::hstring newTitle); void LastTabClosed(const winrt::Windows::Foundation::IInspectable& sender, const winrt::TerminalApp::LastTabClosedEventArgs& args); void Initialize(); - bool OnDirectKeyEvent(const uint32_t vkey, const bool down); + bool OnDirectKeyEvent(const uint32_t vkey, const uint8_t scanCode, const bool down); private: bool _useNonClientArea; diff --git a/src/cascadia/WindowsTerminal/main.cpp b/src/cascadia/WindowsTerminal/main.cpp index 69663349b8c..63d007a9800 100644 --- a/src/cascadia/WindowsTerminal/main.cpp +++ b/src/cascadia/WindowsTerminal/main.cpp @@ -141,7 +141,7 @@ int __stdcall wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int) // been handled we can discard the message before we even translate it. if (_messageIsF7Keypress(message)) { - if (host.OnDirectKeyEvent(VK_F7, true)) + if (host.OnDirectKeyEvent(VK_F7, LOBYTE(HIWORD(message.lParam)), true)) { // The application consumed the F7. Don't let Xaml get it. continue; @@ -154,7 +154,7 @@ int __stdcall wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int) if (_messageIsAltKeyup(message)) { // Let's pass to the application - if (host.OnDirectKeyEvent(VK_MENU, false)) + if (host.OnDirectKeyEvent(VK_MENU, LOBYTE(HIWORD(message.lParam)), false)) { // The application consumed the Alt. Don't let Xaml get it. continue; From e9a7053629bbfeb285fc49e7072d271e18b539c5 Mon Sep 17 00:00:00 2001 From: Carlos Zamora Date: Fri, 14 Aug 2020 17:54:35 -0700 Subject: [PATCH 051/266] Make ColorScheme a WinRT object (#7238) ColorScheme is now a WinRT object. All of the JSON stuff can't be exposed via the idl. So the plan here is that we'll have the TerminalSettingsModel project handle all of the serialization when it's moved over. These functions will be exposed off of the `implementation` namespace, not projected namespace. References #7141 - ColorScheme is a settings object References #885 - this new settings object will be moved to a new TerminalSettingsModel project ## Validation Steps Performed - [x] Tests passed - [x] Deployment succeeded --- .../ColorSchemeTests.cpp | 133 ++++++++++-------- src/cascadia/TerminalApp/CascadiaSettings.cpp | 4 +- src/cascadia/TerminalApp/CascadiaSettings.h | 6 +- .../CascadiaSettingsSerialization.cpp | 13 +- src/cascadia/TerminalApp/ColorScheme.cpp | 31 ++-- src/cascadia/TerminalApp/ColorScheme.h | 65 +++++---- src/cascadia/TerminalApp/ColorScheme.idl | 21 +++ .../TerminalApp/GlobalAppSettings.cpp | 2 +- src/cascadia/TerminalApp/GlobalAppSettings.h | 11 +- src/cascadia/TerminalApp/Profile.h | 4 +- src/cascadia/TerminalApp/TerminalPage.cpp | 4 +- .../TerminalApp/lib/TerminalAppLib.vcxproj | 9 +- .../lib/TerminalAppLib.vcxproj.filters | 3 + src/cascadia/ut_app/JsonTests.cpp | 14 +- src/cascadia/ut_app/precomp.h | 3 +- 15 files changed, 186 insertions(+), 137 deletions(-) create mode 100644 src/cascadia/TerminalApp/ColorScheme.idl diff --git a/src/cascadia/LocalTests_TerminalApp/ColorSchemeTests.cpp b/src/cascadia/LocalTests_TerminalApp/ColorSchemeTests.cpp index 55c2026bada..ab56263cad0 100644 --- a/src/cascadia/LocalTests_TerminalApp/ColorSchemeTests.cpp +++ b/src/cascadia/LocalTests_TerminalApp/ColorSchemeTests.cpp @@ -9,6 +9,7 @@ using namespace Microsoft::Console; using namespace TerminalApp; +using namespace winrt::TerminalApp::implementation; using namespace WEX::Logging; using namespace WEX::TestExecution; using namespace WEX::Common; @@ -73,24 +74,24 @@ namespace TerminalAppLocalTests const auto scheme0 = ColorScheme::FromJson(scheme0Json); - VERIFY_IS_TRUE(scheme0.ShouldBeLayered(scheme0Json)); - VERIFY_IS_FALSE(scheme0.ShouldBeLayered(scheme1Json)); - VERIFY_IS_TRUE(scheme0.ShouldBeLayered(scheme2Json)); - VERIFY_IS_FALSE(scheme0.ShouldBeLayered(scheme3Json)); + VERIFY_IS_TRUE(scheme0->ShouldBeLayered(scheme0Json)); + VERIFY_IS_FALSE(scheme0->ShouldBeLayered(scheme1Json)); + VERIFY_IS_TRUE(scheme0->ShouldBeLayered(scheme2Json)); + VERIFY_IS_FALSE(scheme0->ShouldBeLayered(scheme3Json)); const auto scheme1 = ColorScheme::FromJson(scheme1Json); - VERIFY_IS_FALSE(scheme1.ShouldBeLayered(scheme0Json)); - VERIFY_IS_TRUE(scheme1.ShouldBeLayered(scheme1Json)); - VERIFY_IS_FALSE(scheme1.ShouldBeLayered(scheme2Json)); - VERIFY_IS_FALSE(scheme1.ShouldBeLayered(scheme3Json)); + VERIFY_IS_FALSE(scheme1->ShouldBeLayered(scheme0Json)); + VERIFY_IS_TRUE(scheme1->ShouldBeLayered(scheme1Json)); + VERIFY_IS_FALSE(scheme1->ShouldBeLayered(scheme2Json)); + VERIFY_IS_FALSE(scheme1->ShouldBeLayered(scheme3Json)); const auto scheme3 = ColorScheme::FromJson(scheme3Json); - VERIFY_IS_FALSE(scheme3.ShouldBeLayered(scheme0Json)); - VERIFY_IS_FALSE(scheme3.ShouldBeLayered(scheme1Json)); - VERIFY_IS_FALSE(scheme3.ShouldBeLayered(scheme2Json)); - VERIFY_IS_FALSE(scheme3.ShouldBeLayered(scheme3Json)); + VERIFY_IS_FALSE(scheme3->ShouldBeLayered(scheme0Json)); + VERIFY_IS_FALSE(scheme3->ShouldBeLayered(scheme1Json)); + VERIFY_IS_FALSE(scheme3->ShouldBeLayered(scheme2Json)); + VERIFY_IS_FALSE(scheme3->ShouldBeLayered(scheme3Json)); } void ColorSchemeTests::LayerColorSchemeProperties() @@ -130,38 +131,38 @@ namespace TerminalAppLocalTests const auto scheme2Json = VerifyParseSucceeded(scheme2String); auto scheme0 = ColorScheme::FromJson(scheme0Json); - VERIFY_ARE_EQUAL(L"scheme0", scheme0._schemeName); - VERIFY_ARE_EQUAL(ARGB(0, 0, 0, 0), scheme0._defaultForeground); - VERIFY_ARE_EQUAL(ARGB(0, 1, 1, 1), scheme0._defaultBackground); - VERIFY_ARE_EQUAL(ARGB(0, 1, 1, 0), scheme0._selectionBackground); - VERIFY_ARE_EQUAL(ARGB(0, 1, 0, 1), scheme0._cursorColor); - VERIFY_ARE_EQUAL(ARGB(0, 1, 0, 0), scheme0._table[XTERM_RED_ATTR]); - VERIFY_ARE_EQUAL(ARGB(0, 0, 1, 0), scheme0._table[XTERM_GREEN_ATTR]); - VERIFY_ARE_EQUAL(ARGB(0, 0, 0, 1), scheme0._table[XTERM_BLUE_ATTR]); + VERIFY_ARE_EQUAL(L"scheme0", scheme0->_schemeName); + VERIFY_ARE_EQUAL(ARGB(0, 0, 0, 0), scheme0->_defaultForeground); + VERIFY_ARE_EQUAL(ARGB(0, 1, 1, 1), scheme0->_defaultBackground); + VERIFY_ARE_EQUAL(ARGB(0, 1, 1, 0), scheme0->_selectionBackground); + VERIFY_ARE_EQUAL(ARGB(0, 1, 0, 1), scheme0->_cursorColor); + VERIFY_ARE_EQUAL(ARGB(0, 1, 0, 0), scheme0->_table[XTERM_RED_ATTR]); + VERIFY_ARE_EQUAL(ARGB(0, 0, 1, 0), scheme0->_table[XTERM_GREEN_ATTR]); + VERIFY_ARE_EQUAL(ARGB(0, 0, 0, 1), scheme0->_table[XTERM_BLUE_ATTR]); Log::Comment(NoThrowString().Format( L"Layering scheme1 on top of scheme0")); - scheme0.LayerJson(scheme1Json); + scheme0->LayerJson(scheme1Json); - VERIFY_ARE_EQUAL(ARGB(0, 2, 2, 2), scheme0._defaultForeground); - VERIFY_ARE_EQUAL(ARGB(0, 3, 3, 3), scheme0._defaultBackground); - VERIFY_ARE_EQUAL(ARGB(0, 2, 2, 0), scheme0._selectionBackground); - VERIFY_ARE_EQUAL(ARGB(0, 4, 0, 4), scheme0._cursorColor); - VERIFY_ARE_EQUAL(ARGB(0, 2, 0, 0), scheme0._table[XTERM_RED_ATTR]); - VERIFY_ARE_EQUAL(ARGB(0, 0, 1, 0), scheme0._table[XTERM_GREEN_ATTR]); - VERIFY_ARE_EQUAL(ARGB(0, 0, 0, 2), scheme0._table[XTERM_BLUE_ATTR]); + VERIFY_ARE_EQUAL(ARGB(0, 2, 2, 2), scheme0->_defaultForeground); + VERIFY_ARE_EQUAL(ARGB(0, 3, 3, 3), scheme0->_defaultBackground); + VERIFY_ARE_EQUAL(ARGB(0, 2, 2, 0), scheme0->_selectionBackground); + VERIFY_ARE_EQUAL(ARGB(0, 4, 0, 4), scheme0->_cursorColor); + VERIFY_ARE_EQUAL(ARGB(0, 2, 0, 0), scheme0->_table[XTERM_RED_ATTR]); + VERIFY_ARE_EQUAL(ARGB(0, 0, 1, 0), scheme0->_table[XTERM_GREEN_ATTR]); + VERIFY_ARE_EQUAL(ARGB(0, 0, 0, 2), scheme0->_table[XTERM_BLUE_ATTR]); Log::Comment(NoThrowString().Format( L"Layering scheme2Json on top of (scheme0+scheme1)")); - scheme0.LayerJson(scheme2Json); - - VERIFY_ARE_EQUAL(ARGB(0, 4, 4, 4), scheme0._defaultForeground); - VERIFY_ARE_EQUAL(ARGB(0, 5, 5, 5), scheme0._defaultBackground); - VERIFY_ARE_EQUAL(ARGB(0, 3, 3, 0), scheme0._selectionBackground); - VERIFY_ARE_EQUAL(ARGB(0, 6, 0, 6), scheme0._cursorColor); - VERIFY_ARE_EQUAL(ARGB(0, 3, 0, 0), scheme0._table[XTERM_RED_ATTR]); - VERIFY_ARE_EQUAL(ARGB(0, 0, 3, 0), scheme0._table[XTERM_GREEN_ATTR]); - VERIFY_ARE_EQUAL(ARGB(0, 0, 0, 2), scheme0._table[XTERM_BLUE_ATTR]); + scheme0->LayerJson(scheme2Json); + + VERIFY_ARE_EQUAL(ARGB(0, 4, 4, 4), scheme0->_defaultForeground); + VERIFY_ARE_EQUAL(ARGB(0, 5, 5, 5), scheme0->_defaultBackground); + VERIFY_ARE_EQUAL(ARGB(0, 3, 3, 0), scheme0->_selectionBackground); + VERIFY_ARE_EQUAL(ARGB(0, 6, 0, 6), scheme0->_cursorColor); + VERIFY_ARE_EQUAL(ARGB(0, 3, 0, 0), scheme0->_table[XTERM_RED_ATTR]); + VERIFY_ARE_EQUAL(ARGB(0, 0, 3, 0), scheme0->_table[XTERM_GREEN_ATTR]); + VERIFY_ARE_EQUAL(ARGB(0, 0, 0, 2), scheme0->_table[XTERM_BLUE_ATTR]); } void ColorSchemeTests::LayerColorSchemesOnArray() @@ -205,19 +206,20 @@ namespace TerminalAppLocalTests for (auto& kv : settings._globals._colorSchemes) { Log::Comment(NoThrowString().Format( - L"kv:%s->%s", kv.first.data(), kv.second.GetName().data())); + L"kv:%s->%s", kv.first.data(), kv.second.Name().data())); } VERIFY_ARE_EQUAL(1u, settings._globals.GetColorSchemes().size()); VERIFY_IS_TRUE(settings._globals._colorSchemes.find(L"scheme0") != settings._globals._colorSchemes.end()); - auto scheme0 = settings._globals._colorSchemes.find(L"scheme0")->second; + auto scheme0Proj = settings._globals._colorSchemes.find(L"scheme0")->second; + auto scheme0 = winrt::get_self(scheme0Proj); VERIFY_IS_NOT_NULL(settings._FindMatchingColorScheme(scheme0Json)); VERIFY_IS_NULL(settings._FindMatchingColorScheme(scheme1Json)); VERIFY_IS_NOT_NULL(settings._FindMatchingColorScheme(scheme2Json)); VERIFY_IS_NULL(settings._FindMatchingColorScheme(scheme3Json)); - VERIFY_ARE_EQUAL(ARGB(0, 0, 0, 0), scheme0._defaultForeground); - VERIFY_ARE_EQUAL(ARGB(0, 1, 1, 1), scheme0._defaultBackground); + VERIFY_ARE_EQUAL(ARGB(0, 0, 0, 0), scheme0->_defaultForeground); + VERIFY_ARE_EQUAL(ARGB(0, 1, 1, 1), scheme0->_defaultBackground); } settings._LayerOrCreateColorScheme(scheme1Json); @@ -226,18 +228,20 @@ namespace TerminalAppLocalTests VERIFY_ARE_EQUAL(2u, settings._globals.GetColorSchemes().size()); VERIFY_IS_TRUE(settings._globals._colorSchemes.find(L"scheme0") != settings._globals._colorSchemes.end()); - auto scheme0 = settings._globals._colorSchemes.find(L"scheme0")->second; + auto scheme0Proj = settings._globals._colorSchemes.find(L"scheme0")->second; + auto scheme0 = winrt::get_self(scheme0Proj); VERIFY_IS_TRUE(settings._globals._colorSchemes.find(L"scheme1") != settings._globals._colorSchemes.end()); - auto scheme1 = settings._globals._colorSchemes.find(L"scheme1")->second; + auto scheme1Proj = settings._globals._colorSchemes.find(L"scheme1")->second; + auto scheme1 = winrt::get_self(scheme1Proj); VERIFY_IS_NOT_NULL(settings._FindMatchingColorScheme(scheme0Json)); VERIFY_IS_NOT_NULL(settings._FindMatchingColorScheme(scheme1Json)); VERIFY_IS_NOT_NULL(settings._FindMatchingColorScheme(scheme2Json)); VERIFY_IS_NULL(settings._FindMatchingColorScheme(scheme3Json)); - VERIFY_ARE_EQUAL(ARGB(0, 0, 0, 0), scheme0._defaultForeground); - VERIFY_ARE_EQUAL(ARGB(0, 1, 1, 1), scheme0._defaultBackground); - VERIFY_ARE_EQUAL(ARGB(0, 2, 2, 2), scheme1._defaultForeground); - VERIFY_ARE_EQUAL(ARGB(0, 3, 3, 3), scheme1._defaultBackground); + VERIFY_ARE_EQUAL(ARGB(0, 0, 0, 0), scheme0->_defaultForeground); + VERIFY_ARE_EQUAL(ARGB(0, 1, 1, 1), scheme0->_defaultBackground); + VERIFY_ARE_EQUAL(ARGB(0, 2, 2, 2), scheme1->_defaultForeground); + VERIFY_ARE_EQUAL(ARGB(0, 3, 3, 3), scheme1->_defaultBackground); } settings._LayerOrCreateColorScheme(scheme2Json); @@ -245,18 +249,20 @@ namespace TerminalAppLocalTests VERIFY_ARE_EQUAL(2u, settings._globals.GetColorSchemes().size()); VERIFY_IS_TRUE(settings._globals._colorSchemes.find(L"scheme0") != settings._globals._colorSchemes.end()); - auto scheme0 = settings._globals._colorSchemes.find(L"scheme0")->second; + auto scheme0Proj = settings._globals._colorSchemes.find(L"scheme0")->second; + auto scheme0 = winrt::get_self(scheme0Proj); VERIFY_IS_TRUE(settings._globals._colorSchemes.find(L"scheme1") != settings._globals._colorSchemes.end()); - auto scheme1 = settings._globals._colorSchemes.find(L"scheme1")->second; + auto scheme1Proj = settings._globals._colorSchemes.find(L"scheme1")->second; + auto scheme1 = winrt::get_self(scheme1Proj); VERIFY_IS_NOT_NULL(settings._FindMatchingColorScheme(scheme0Json)); VERIFY_IS_NOT_NULL(settings._FindMatchingColorScheme(scheme1Json)); VERIFY_IS_NOT_NULL(settings._FindMatchingColorScheme(scheme2Json)); VERIFY_IS_NULL(settings._FindMatchingColorScheme(scheme3Json)); - VERIFY_ARE_EQUAL(ARGB(0, 4, 4, 4), scheme0._defaultForeground); - VERIFY_ARE_EQUAL(ARGB(0, 5, 5, 5), scheme0._defaultBackground); - VERIFY_ARE_EQUAL(ARGB(0, 2, 2, 2), scheme1._defaultForeground); - VERIFY_ARE_EQUAL(ARGB(0, 3, 3, 3), scheme1._defaultBackground); + VERIFY_ARE_EQUAL(ARGB(0, 4, 4, 4), scheme0->_defaultForeground); + VERIFY_ARE_EQUAL(ARGB(0, 5, 5, 5), scheme0->_defaultBackground); + VERIFY_ARE_EQUAL(ARGB(0, 2, 2, 2), scheme1->_defaultForeground); + VERIFY_ARE_EQUAL(ARGB(0, 3, 3, 3), scheme1->_defaultBackground); } settings._LayerOrCreateColorScheme(scheme3Json); @@ -264,22 +270,25 @@ namespace TerminalAppLocalTests VERIFY_ARE_EQUAL(3u, settings._globals.GetColorSchemes().size()); VERIFY_IS_TRUE(settings._globals._colorSchemes.find(L"scheme0") != settings._globals._colorSchemes.end()); - auto scheme0 = settings._globals._colorSchemes.find(L"scheme0")->second; + auto scheme0Proj = settings._globals._colorSchemes.find(L"scheme0")->second; + auto scheme0 = winrt::get_self(scheme0Proj); VERIFY_IS_TRUE(settings._globals._colorSchemes.find(L"scheme1") != settings._globals._colorSchemes.end()); - auto scheme1 = settings._globals._colorSchemes.find(L"scheme1")->second; + auto scheme1Proj = settings._globals._colorSchemes.find(L"scheme1")->second; + auto scheme1 = winrt::get_self(scheme1Proj); VERIFY_IS_TRUE(settings._globals._colorSchemes.find(L"") != settings._globals._colorSchemes.end()); - auto scheme2 = settings._globals._colorSchemes.find(L"")->second; + auto scheme2Proj = settings._globals._colorSchemes.find(L"")->second; + auto scheme2 = winrt::get_self(scheme2Proj); VERIFY_IS_NOT_NULL(settings._FindMatchingColorScheme(scheme0Json)); VERIFY_IS_NOT_NULL(settings._FindMatchingColorScheme(scheme1Json)); VERIFY_IS_NOT_NULL(settings._FindMatchingColorScheme(scheme2Json)); VERIFY_IS_NULL(settings._FindMatchingColorScheme(scheme3Json)); - VERIFY_ARE_EQUAL(ARGB(0, 4, 4, 4), scheme0._defaultForeground); - VERIFY_ARE_EQUAL(ARGB(0, 5, 5, 5), scheme0._defaultBackground); - VERIFY_ARE_EQUAL(ARGB(0, 2, 2, 2), scheme1._defaultForeground); - VERIFY_ARE_EQUAL(ARGB(0, 3, 3, 3), scheme1._defaultBackground); - VERIFY_ARE_EQUAL(ARGB(0, 6, 6, 6), scheme2._defaultForeground); - VERIFY_ARE_EQUAL(ARGB(0, 7, 7, 7), scheme2._defaultBackground); + VERIFY_ARE_EQUAL(ARGB(0, 4, 4, 4), scheme0->_defaultForeground); + VERIFY_ARE_EQUAL(ARGB(0, 5, 5, 5), scheme0->_defaultBackground); + VERIFY_ARE_EQUAL(ARGB(0, 2, 2, 2), scheme1->_defaultForeground); + VERIFY_ARE_EQUAL(ARGB(0, 3, 3, 3), scheme1->_defaultBackground); + VERIFY_ARE_EQUAL(ARGB(0, 6, 6, 6), scheme2->_defaultForeground); + VERIFY_ARE_EQUAL(ARGB(0, 7, 7, 7), scheme2->_defaultBackground); } } } diff --git a/src/cascadia/TerminalApp/CascadiaSettings.cpp b/src/cascadia/TerminalApp/CascadiaSettings.cpp index e8b8a06e428..2ecfa174543 100644 --- a/src/cascadia/TerminalApp/CascadiaSettings.cpp +++ b/src/cascadia/TerminalApp/CascadiaSettings.cpp @@ -734,7 +734,7 @@ std::string CascadiaSettings::_ApplyFirstRunChangesToSettingsTemplate(std::strin // - profileGuid: the GUID of the profile to find the scheme for. // Return Value: // - a non-owning pointer to the scheme. -const ColorScheme* CascadiaSettings::GetColorSchemeForProfile(const GUID profileGuid) const +const ColorScheme CascadiaSettings::GetColorSchemeForProfile(const GUID profileGuid) const { auto* profile = FindProfile(profileGuid); if (!profile) @@ -745,7 +745,7 @@ const ColorScheme* CascadiaSettings::GetColorSchemeForProfile(const GUID profile auto scheme = _globals.GetColorSchemes().find(schemeName); if (scheme != _globals.GetColorSchemes().end()) { - return &scheme->second; + return scheme->second; } else { diff --git a/src/cascadia/TerminalApp/CascadiaSettings.h b/src/cascadia/TerminalApp/CascadiaSettings.h index a4b61893112..def568424f5 100644 --- a/src/cascadia/TerminalApp/CascadiaSettings.h +++ b/src/cascadia/TerminalApp/CascadiaSettings.h @@ -22,6 +22,8 @@ Author(s): #include "Profile.h" #include "IDynamicProfileGenerator.h" +#include "ColorScheme.h" + // fwdecl unittest classes namespace TerminalAppLocalTests { @@ -78,7 +80,7 @@ class TerminalApp::CascadiaSettings final static std::filesystem::path GetDefaultSettingsPath(); const Profile* FindProfile(GUID profileGuid) const noexcept; - const ColorScheme* GetColorSchemeForProfile(const GUID profileGuid) const; + const winrt::TerminalApp::ColorScheme GetColorSchemeForProfile(const GUID profileGuid) const; std::vector& GetWarnings(); @@ -99,7 +101,7 @@ class TerminalApp::CascadiaSettings final void _LayerOrCreateProfile(const Json::Value& profileJson); Profile* _FindMatchingProfile(const Json::Value& profileJson); void _LayerOrCreateColorScheme(const Json::Value& schemeJson); - ColorScheme* _FindMatchingColorScheme(const Json::Value& schemeJson); + winrt::com_ptr _FindMatchingColorScheme(const Json::Value& schemeJson); void _ParseJsonString(std::string_view fileData, const bool isDefaultSettings); static const Json::Value& _GetProfilesJsonObject(const Json::Value& json); static const Json::Value& _GetDisabledProfileSourcesJsonObject(const Json::Value& json); diff --git a/src/cascadia/TerminalApp/CascadiaSettingsSerialization.cpp b/src/cascadia/TerminalApp/CascadiaSettingsSerialization.cpp index 8a4c1c50086..33433a3b9eb 100644 --- a/src/cascadia/TerminalApp/CascadiaSettingsSerialization.cpp +++ b/src/cascadia/TerminalApp/CascadiaSettingsSerialization.cpp @@ -708,7 +708,8 @@ void CascadiaSettings::_LayerOrCreateColorScheme(const Json::Value& schemeJson) } else { - _globals.AddColorScheme(ColorScheme::FromJson(schemeJson)); + const auto scheme = implementation::ColorScheme::FromJson(schemeJson); + _globals.AddColorScheme(*scheme); } } @@ -723,19 +724,15 @@ void CascadiaSettings::_LayerOrCreateColorScheme(const Json::Value& schemeJson) // Return Value: // - a ColorScheme that can be layered with the given json object, iff such a // color scheme exists. -ColorScheme* CascadiaSettings::_FindMatchingColorScheme(const Json::Value& schemeJson) +winrt::com_ptr CascadiaSettings::_FindMatchingColorScheme(const Json::Value& schemeJson) { - if (auto schemeName = ColorScheme::GetNameFromJson(schemeJson)) + if (auto schemeName = implementation::ColorScheme::GetNameFromJson(schemeJson)) { auto& schemes = _globals.GetColorSchemes(); auto iterator = schemes.find(*schemeName); if (iterator != schemes.end()) { - // HERE BE DRAGONS: Returning a pointer to a type in the vector is - // maybe not the _safest_ thing, but we have a mind to make Profile - // and ColorScheme winrt types in the future, so this will be safer - // then. - return &iterator->second; + return winrt::get_self(iterator->second)->get_strong(); } } return nullptr; diff --git a/src/cascadia/TerminalApp/ColorScheme.cpp b/src/cascadia/TerminalApp/ColorScheme.cpp index af70c3595e4..206b7baad67 100644 --- a/src/cascadia/TerminalApp/ColorScheme.cpp +++ b/src/cascadia/TerminalApp/ColorScheme.cpp @@ -8,9 +8,12 @@ #include "Utils.h" #include "JsonUtils.h" +#include "ColorScheme.g.cpp" + using namespace ::Microsoft::Console; using namespace TerminalApp; -using namespace winrt::TerminalApp; +using namespace winrt::TerminalApp::implementation; +using namespace winrt::Windows::UI; static constexpr std::string_view NameKey{ "name" }; static constexpr std::string_view ForegroundKey{ "foreground" }; @@ -46,7 +49,7 @@ ColorScheme::ColorScheme() : { } -ColorScheme::ColorScheme(std::wstring name, til::color defaultFg, til::color defaultBg, til::color cursorColor) : +ColorScheme::ColorScheme(winrt::hstring name, Color defaultFg, Color defaultBg, Color cursorColor) : _schemeName{ name }, _table{}, _defaultForeground{ defaultFg }, @@ -87,10 +90,10 @@ void ColorScheme::ApplyScheme(const winrt::Microsoft::Terminal::TerminalControl: // - json: an object which should be a serialization of a ColorScheme object. // Return Value: // - a new ColorScheme instance created from the values in `json` -ColorScheme ColorScheme::FromJson(const Json::Value& json) +winrt::com_ptr ColorScheme::FromJson(const Json::Value& json) { - ColorScheme result; - result.LayerJson(json); + auto result = winrt::make_self(); + result->LayerJson(json); return result; } @@ -138,32 +141,34 @@ void ColorScheme::LayerJson(const Json::Value& json) } } -std::wstring_view ColorScheme::GetName() const noexcept +winrt::hstring ColorScheme::Name() const noexcept { - return { _schemeName }; + return _schemeName; } -std::array& ColorScheme::GetTable() noexcept +winrt::com_array ColorScheme::Table() const noexcept { - return _table; + winrt::com_array result{ COLOR_TABLE_SIZE }; + std::transform(_table.begin(), _table.end(), result.begin(), [](til::color c) -> Color { return c; }); + return result; } -til::color ColorScheme::GetForeground() const noexcept +Color ColorScheme::Foreground() const noexcept { return _defaultForeground; } -til::color ColorScheme::GetBackground() const noexcept +Color ColorScheme::Background() const noexcept { return _defaultBackground; } -til::color ColorScheme::GetSelectionBackground() const noexcept +Color ColorScheme::SelectionBackground() const noexcept { return _selectionBackground; } -til::color ColorScheme::GetCursorColor() const noexcept +Color ColorScheme::CursorColor() const noexcept { return _cursorColor; } diff --git a/src/cascadia/TerminalApp/ColorScheme.h b/src/cascadia/TerminalApp/ColorScheme.h index 2267eb8f006..fe7c8186a69 100644 --- a/src/cascadia/TerminalApp/ColorScheme.h +++ b/src/cascadia/TerminalApp/ColorScheme.h @@ -18,6 +18,8 @@ Author(s): #include "TerminalSettings.h" #include "../../inc/conattrs.hpp" +#include "ColorScheme.g.h" + // fwdecl unittest classes namespace TerminalAppLocalTests { @@ -25,41 +27,44 @@ namespace TerminalAppLocalTests class ColorSchemeTests; }; -namespace TerminalApp +namespace winrt::TerminalApp::implementation { - class ColorScheme; -}; + struct ColorScheme : ColorSchemeT + { + public: + ColorScheme(); + ColorScheme(hstring name, Windows::UI::Color defaultFg, Windows::UI::Color defaultBg, Windows::UI::Color cursorColor); + ~ColorScheme(); -class TerminalApp::ColorScheme -{ -public: - ColorScheme(); - ColorScheme(std::wstring name, til::color defaultFg, til::color defaultBg, til::color cursorColor); - ~ColorScheme(); + void ApplyScheme(const winrt::Microsoft::Terminal::TerminalControl::IControlSettings& terminalSettings) const; - void ApplyScheme(const winrt::Microsoft::Terminal::TerminalControl::IControlSettings& terminalSettings) const; + static com_ptr FromJson(const Json::Value& json); + bool ShouldBeLayered(const Json::Value& json) const; + void LayerJson(const Json::Value& json); - static ColorScheme FromJson(const Json::Value& json); - bool ShouldBeLayered(const Json::Value& json) const; - void LayerJson(const Json::Value& json); + hstring Name() const noexcept; + com_array Table() const noexcept; + Windows::UI::Color Foreground() const noexcept; + Windows::UI::Color Background() const noexcept; + Windows::UI::Color SelectionBackground() const noexcept; + Windows::UI::Color CursorColor() const noexcept; - std::wstring_view GetName() const noexcept; - std::array& GetTable() noexcept; - til::color GetForeground() const noexcept; - til::color GetBackground() const noexcept; - til::color GetSelectionBackground() const noexcept; - til::color GetCursorColor() const noexcept; + static std::optional GetNameFromJson(const Json::Value& json); - static std::optional GetNameFromJson(const Json::Value& json); + private: + hstring _schemeName; + std::array _table; + til::color _defaultForeground; + til::color _defaultBackground; + til::color _selectionBackground; + til::color _cursorColor; -private: - std::wstring _schemeName; - std::array _table; - til::color _defaultForeground; - til::color _defaultBackground; - til::color _selectionBackground; - til::color _cursorColor; + friend class TerminalAppLocalTests::SettingsTests; + friend class TerminalAppLocalTests::ColorSchemeTests; + }; +} - friend class TerminalAppLocalTests::SettingsTests; - friend class TerminalAppLocalTests::ColorSchemeTests; -}; +namespace winrt::TerminalApp::factory_implementation +{ + BASIC_FACTORY(ColorScheme); +} diff --git a/src/cascadia/TerminalApp/ColorScheme.idl b/src/cascadia/TerminalApp/ColorScheme.idl new file mode 100644 index 00000000000..ea0d2979aad --- /dev/null +++ b/src/cascadia/TerminalApp/ColorScheme.idl @@ -0,0 +1,21 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +namespace TerminalApp +{ + [default_interface] runtimeclass ColorScheme { + ColorScheme(); + ColorScheme(String name, Windows.UI.Color defaultFg, Windows.UI.Color defaultBg, Windows.UI.Color cursorColor); + + void ApplyScheme(Microsoft.Terminal.TerminalControl.IControlSettings terminalSettings); + + String Name { get; }; + + Windows.UI.Color Foreground { get; }; + Windows.UI.Color Background { get; }; + Windows.UI.Color SelectionBackground { get; }; + Windows.UI.Color CursorColor { get; }; + + Windows.UI.Color[] Table { get; }; + } +} diff --git a/src/cascadia/TerminalApp/GlobalAppSettings.cpp b/src/cascadia/TerminalApp/GlobalAppSettings.cpp index b9d6175df01..834038bfad8 100644 --- a/src/cascadia/TerminalApp/GlobalAppSettings.cpp +++ b/src/cascadia/TerminalApp/GlobalAppSettings.cpp @@ -213,7 +213,7 @@ void GlobalAppSettings::LayerJson(const Json::Value& json) // - void GlobalAppSettings::AddColorScheme(ColorScheme scheme) { - std::wstring name{ scheme.GetName() }; + std::wstring name{ scheme.Name() }; _colorSchemes[name] = std::move(scheme); } diff --git a/src/cascadia/TerminalApp/GlobalAppSettings.h b/src/cascadia/TerminalApp/GlobalAppSettings.h index 6a72d0ad857..b7386429046 100644 --- a/src/cascadia/TerminalApp/GlobalAppSettings.h +++ b/src/cascadia/TerminalApp/GlobalAppSettings.h @@ -15,10 +15,11 @@ Author(s): --*/ #pragma once #include "AppKeyBindings.h" -#include "ColorScheme.h" #include "Command.h" #include "SettingsTypes.h" +#include "ColorScheme.g.h" + // fwdecl unittest classes namespace TerminalAppLocalTests { @@ -37,9 +38,9 @@ class TerminalApp::GlobalAppSettings final GlobalAppSettings(); ~GlobalAppSettings(); - std::unordered_map& GetColorSchemes() noexcept; - const std::unordered_map& GetColorSchemes() const noexcept; - void AddColorScheme(ColorScheme scheme); + std::unordered_map& GetColorSchemes() noexcept; + const std::unordered_map& GetColorSchemes() const noexcept; + void AddColorScheme(winrt::TerminalApp::ColorScheme scheme); winrt::TerminalApp::AppKeyBindings GetKeybindings() const noexcept; @@ -89,7 +90,7 @@ class TerminalApp::GlobalAppSettings final winrt::com_ptr _keybindings; std::vector<::TerminalApp::SettingsLoadWarnings> _keybindingsWarnings; - std::unordered_map _colorSchemes; + std::unordered_map _colorSchemes; winrt::Windows::Foundation::Collections::IMap _commands; friend class TerminalAppLocalTests::SettingsTests; diff --git a/src/cascadia/TerminalApp/Profile.h b/src/cascadia/TerminalApp/Profile.h index a6794bbcc07..2ab88f0c884 100644 --- a/src/cascadia/TerminalApp/Profile.h +++ b/src/cascadia/TerminalApp/Profile.h @@ -14,7 +14,7 @@ Author(s): --*/ #pragma once -#include "ColorScheme.h" +#include "ColorScheme.g.h" #include "SettingsTypes.h" // fwdecl unittest classes @@ -46,7 +46,7 @@ class TerminalApp::Profile final ~Profile(); - winrt::TerminalApp::TerminalSettings CreateTerminalSettings(const std::unordered_map& schemes) const; + winrt::TerminalApp::TerminalSettings CreateTerminalSettings(const std::unordered_map& schemes) const; Json::Value GenerateStub() const; static Profile FromJson(const Json::Value& json); diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index abd7768afc9..1c9bc9fd212 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -634,10 +634,10 @@ namespace winrt::TerminalApp::implementation newTerminalArgs.Profile().empty()); // Lookup the name of the color scheme used by this profile. - const auto* scheme = _settings->GetColorSchemeForProfile(profileGuid); + const auto scheme = _settings->GetColorSchemeForProfile(profileGuid); // If they explicitly specified `null` as the scheme (indicating _no_ scheme), log // that as the empty string. - const auto schemeName = scheme ? scheme->GetName() : L"\0"; + const auto schemeName = scheme ? scheme.Name() : L"\0"; TraceLoggingWrite( g_hTerminalAppProvider, // handle to TerminalApp tracelogging provider diff --git a/src/cascadia/TerminalApp/lib/TerminalAppLib.vcxproj b/src/cascadia/TerminalApp/lib/TerminalAppLib.vcxproj index aecf0ef0847..95f01337336 100644 --- a/src/cascadia/TerminalApp/lib/TerminalAppLib.vcxproj +++ b/src/cascadia/TerminalApp/lib/TerminalAppLib.vcxproj @@ -101,7 +101,9 @@ ../Tab.idl - + + ../ColorScheme.idl + @@ -175,7 +177,9 @@ ../Tab.idl - + + ../ColorScheme.idl + @@ -264,6 +268,7 @@ + diff --git a/src/cascadia/TerminalApp/lib/TerminalAppLib.vcxproj.filters b/src/cascadia/TerminalApp/lib/TerminalAppLib.vcxproj.filters index 9a80a146c43..3056b71130d 100644 --- a/src/cascadia/TerminalApp/lib/TerminalAppLib.vcxproj.filters +++ b/src/cascadia/TerminalApp/lib/TerminalAppLib.vcxproj.filters @@ -148,6 +148,9 @@ settings + + settings + diff --git a/src/cascadia/ut_app/JsonTests.cpp b/src/cascadia/ut_app/JsonTests.cpp index f18579b1d0d..c145c48c1dc 100644 --- a/src/cascadia/ut_app/JsonTests.cpp +++ b/src/cascadia/ut_app/JsonTests.cpp @@ -92,12 +92,12 @@ namespace TerminalAppUnitTests "}" }; const auto schemeObject = VerifyParseSucceeded(campbellScheme); - auto scheme = ColorScheme::FromJson(schemeObject); - VERIFY_ARE_EQUAL(L"Campbell", scheme.GetName()); - VERIFY_ARE_EQUAL(ARGB(0, 0xf2, 0xf2, 0xf2), scheme.GetForeground()); - VERIFY_ARE_EQUAL(ARGB(0, 0x0c, 0x0c, 0x0c), scheme.GetBackground()); - VERIFY_ARE_EQUAL(ARGB(0, 0x13, 0x13, 0x13), scheme.GetSelectionBackground()); - VERIFY_ARE_EQUAL(ARGB(0, 0xFF, 0xFF, 0xFF), scheme.GetCursorColor()); + auto scheme = implementation::ColorScheme::FromJson(schemeObject); + VERIFY_ARE_EQUAL(L"Campbell", scheme->Name()); + VERIFY_ARE_EQUAL(til::color(0xf2, 0xf2, 0xf2, 255), scheme->Foreground()); + VERIFY_ARE_EQUAL(til::color(0x0c, 0x0c, 0x0c, 255), scheme->Background()); + VERIFY_ARE_EQUAL(til::color(0x13, 0x13, 0x13, 255), scheme->SelectionBackground()); + VERIFY_ARE_EQUAL(til::color(0xFF, 0xFF, 0xFF, 255), scheme->CursorColor()); std::array expectedCampbellTable; auto campbellSpan = gsl::span(&expectedCampbellTable[0], COLOR_TABLE_SIZE); @@ -107,7 +107,7 @@ namespace TerminalAppUnitTests for (size_t i = 0; i < expectedCampbellTable.size(); i++) { const auto& expected = expectedCampbellTable.at(i); - const auto& actual = scheme.GetTable().at(i); + const til::color actual{ scheme->Table().at(static_cast(i)) }; VERIFY_ARE_EQUAL(expected, actual); } } diff --git a/src/cascadia/ut_app/precomp.h b/src/cascadia/ut_app/precomp.h index 9097a630411..3ab75f96a8b 100644 --- a/src/cascadia/ut_app/precomp.h +++ b/src/cascadia/ut_app/precomp.h @@ -46,4 +46,5 @@ Author(s): #include #include #include -#include +#include +#include From 24b8c13bd05092517322cac1f03a2c6f61b6e398 Mon Sep 17 00:00:00 2001 From: Carlos Zamora Date: Fri, 14 Aug 2020 18:02:24 -0700 Subject: [PATCH 052/266] Add copyFormatting keybinding arg and array support (#6004) Adds array support for the existing `copyFormatting` global setting. This allows users to define which formats they would specifically like to be copied. A boolean value is still accepted and is translated to the following: - `false` --> `"none"` or `[]` - `true` --> `"all"` or `["html", "rtf"]` This also adds `copyFormatting` as a keybinding arg for `copy`. As with the global setting, a boolean value and array value is accepted. CopyFormat is a WinRT enum where each accepted format is a flag. Currently accepted formats include `html`, and `rtf`. A boolean value is accepted and converted. `true` is a conjunction of all the formats. `false` only includes plain text. For the global setting, `null` is not accepted. We already have a default value from before so no worries there. For the keybinding arg, `null` (the default value) means that we just do what the global arg says to do. Overall, the `copyFormatting` keybinding arg is an override of the global setting **when using that keybinding**. References #5212 - Spec for formatted copying References #2690 - disable html copy Validated behavior with every combination of values below: - `copyFormatting` global: { `true`, `false`, `[]`, `["html"]` } - `copyFormatting` copy arg: { `null`, `true`, `false`, `[]`, `[, "html"]`} Closes #4191 Closes #5262 --- doc/cascadia/SettingsSchema.md | 4 +- doc/cascadia/profiles.schema.json | 42 ++++++++++++++++++- src/cascadia/TerminalApp/ActionArgs.cpp | 42 ++++++++++++++++++- src/cascadia/TerminalApp/ActionArgs.h | 6 ++- src/cascadia/TerminalApp/ActionArgs.idl | 1 + .../TerminalApp/AppActionHandlers.cpp | 2 +- src/cascadia/TerminalApp/GlobalAppSettings.h | 2 +- src/cascadia/TerminalApp/JsonUtils.h | 2 +- src/cascadia/TerminalApp/TerminalPage.cpp | 17 ++++++-- src/cascadia/TerminalApp/TerminalPage.h | 2 +- .../TerminalSettingsSerializationHelpers.h | 24 +++++++++++ src/cascadia/TerminalControl/TermControl.cpp | 37 +++++++++------- src/cascadia/TerminalControl/TermControl.h | 15 +++++-- src/cascadia/TerminalControl/TermControl.idl | 11 ++++- 14 files changed, 174 insertions(+), 33 deletions(-) diff --git a/doc/cascadia/SettingsSchema.md b/doc/cascadia/SettingsSchema.md index 66e5cb67113..6b281c23aea 100644 --- a/doc/cascadia/SettingsSchema.md +++ b/doc/cascadia/SettingsSchema.md @@ -8,7 +8,7 @@ Properties listed below affect the entire window, regardless of the profile sett | -------- | --------- | ---- | ------- | ----------- | | `alwaysShowTabs` | _Required_ | Boolean | `true` | When set to `true`, tabs are always displayed. When set to `false` and `showTabsInTitlebar` is set to `false`, tabs only appear after typing Ctrl + T. | | `copyOnSelect` | Optional | Boolean | `false` | When set to `true`, a selection is immediately copied to your clipboard upon creation. When set to `false`, the selection persists and awaits further action. | -| `copyFormatting` | Optional | Boolean | `false` | When set to `true`, the color and font formatting of selected text is also copied to your clipboard. When set to `false`, only plain text is copied to your clipboard. | +| `copyFormatting` | Optional | Boolean, Array | `true` | When set to `true`, the color and font formatting of selected text is also copied to your clipboard. When set to `false`, only plain text is copied to your clipboard. An array of specific formats can also be used. Supported array values include `html` and `rtf`. Plain text is always copied. | | `largePasteWarning` | Optional | Boolean | `true` | When set to `true`, trying to paste text with more than 5 KiB of characters will display a warning asking you whether to continue or not with the paste. | | `multiLinePasteWarning` | Optional | Boolean | `true` | When set to `true`, trying to paste text with a _new line_ character will display a warning asking you whether to continue or not with the paste. | | `defaultProfile` | _Required_ | String | PowerShell guid | Sets the default profile. Opens by typing Ctrl + T or by clicking the '+' icon. The guid of the desired default profile is used as the value. | @@ -126,7 +126,7 @@ For commands with arguments: | `closePane` | Close the active pane. | | | | | `closeTab` | Close the current tab. | | | | | `closeWindow` | Close the current window and all tabs within it. | | | | -| `copy` | Copy the selected terminal content to your Windows Clipboard. | `singleLine` | boolean | When `true`, the copied content will be copied as a single line. When `false`, newlines persist from the selected text. | +| `copy` | Copy the selected terminal content to your Windows Clipboard. | 1. `singleLine`
2. `copyFormatting` | 1. boolean
2. boolean, array | 1. When `true`, the copied content will be copied as a single line. When `false`, newlines persist from the selected text.
2. When set to `true`, the color and font formatting of selected text is also copied to your clipboard. When set to `false`, only plain text is copied to your clipboard. An array of specific formats can also be used. Supported array values include `html` and `rtf`. Plain text is always copied. Not setting this value inherits the behavior of the `copyFormatting` global setting. | | `duplicateTab` | Make a copy and open the current tab. | | | | | `find` | Open the search dialog box. | | | | | `moveFocus` | Focus on a different pane depending on direction. | `direction`* | `left`, `right`, `up`, `down` | Direction in which the focus will move. | diff --git a/doc/cascadia/profiles.schema.json b/doc/cascadia/profiles.schema.json index e2253724a54..6456d452c13 100644 --- a/doc/cascadia/profiles.schema.json +++ b/doc/cascadia/profiles.schema.json @@ -90,6 +90,32 @@ ], "type": "string" }, + "CopyFormat": { + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "array", + "items": { + "type": "string", + "enum": [ + "html", + "rtf" + ] + } + }, + { + "type": "string", + "enum": [ + "html", + "rtf", + "all", + "none" + ] + } + ] + }, "AnchorKey": { "enum": [ "ctrl", @@ -163,6 +189,18 @@ "type": "boolean", "default": false, "description": "If true, the copied content will be copied as a single line (even if there are hard line breaks present in the text). If false, newlines persist from the selected text." + }, + "copyFormatting": { + "default": null, + "description": "When set to `true`, the color and font formatting of selected text is also copied to your clipboard. When set to `false`, only plain text is copied to your clipboard. An array of specific formats can also be used. Supported array values include `html` and `rtf`. Plain text is always copied. Not setting this value inherits the behavior of the `copyFormatting` global setting.", + "oneOf": [ + { + "$ref": "#/definitions/CopyFormat" + }, + { + "type": "null" + } + ] } } } @@ -468,8 +506,8 @@ }, "copyFormatting": { "default": true, - "description": "When set to `true`, the color and font formatting of selected text is also copied to your clipboard. When set to `false`, only plain text is copied to your clipboard.", - "type": "boolean" + "description": "When set to `true`, the color and font formatting of selected text is also copied to your clipboard. When set to `false`, only plain text is copied to your clipboard. An array of specific formats can also be used. Supported array values include `html` and `rtf`. Plain text is always copied.", + "$ref": "#/definitions/CopyFormat" }, "largePasteWarning": { "default": true, diff --git a/src/cascadia/TerminalApp/ActionArgs.cpp b/src/cascadia/TerminalApp/ActionArgs.cpp index 1bc3983481d..d1af86df394 100644 --- a/src/cascadia/TerminalApp/ActionArgs.cpp +++ b/src/cascadia/TerminalApp/ActionArgs.cpp @@ -26,6 +26,8 @@ #include +using namespace winrt::Microsoft::Terminal::TerminalControl; + namespace winrt::TerminalApp::implementation { winrt::hstring NewTerminalArgs::GenerateName() const @@ -67,11 +69,47 @@ namespace winrt::TerminalApp::implementation winrt::hstring CopyTextArgs::GenerateName() const { + std::wstringstream ss; + if (_SingleLine) { - return RS_(L"CopyTextAsSingleLineCommandKey"); + ss << RS_(L"CopyTextAsSingleLineCommandKey").c_str(); + } + else + { + ss << RS_(L"CopyTextCommandKey").c_str(); } - return RS_(L"CopyTextCommandKey"); + + if (_CopyFormatting != nullptr) + { + ss << L", copyFormatting: "; + if (_CopyFormatting.Value() == CopyFormat::All) + { + ss << L"all, "; + } + else if (_CopyFormatting.Value() == static_cast(0)) + { + ss << L"none, "; + } + else + { + if (WI_IsFlagSet(_CopyFormatting.Value(), CopyFormat::HTML)) + { + ss << L"html, "; + } + + if (WI_IsFlagSet(_CopyFormatting.Value(), CopyFormat::RTF)) + { + ss << L"rtf, "; + } + } + + // Chop off the last "," + auto result = ss.str(); + return winrt::hstring{ result.substr(0, result.size() - 2) }; + } + + return winrt::hstring{ ss.str() }; } winrt::hstring NewTabArgs::GenerateName() const diff --git a/src/cascadia/TerminalApp/ActionArgs.h b/src/cascadia/TerminalApp/ActionArgs.h index d52cc3f4494..7e140b17d18 100644 --- a/src/cascadia/TerminalApp/ActionArgs.h +++ b/src/cascadia/TerminalApp/ActionArgs.h @@ -95,8 +95,10 @@ namespace winrt::TerminalApp::implementation { CopyTextArgs() = default; GETSET_PROPERTY(bool, SingleLine, false); + GETSET_PROPERTY(Windows::Foundation::IReference, CopyFormatting, nullptr); static constexpr std::string_view SingleLineKey{ "singleLine" }; + static constexpr std::string_view CopyFormattingKey{ "copyFormatting" }; public: hstring GenerateName() const; @@ -106,7 +108,8 @@ namespace winrt::TerminalApp::implementation auto otherAsUs = other.try_as(); if (otherAsUs) { - return otherAsUs->_SingleLine == _SingleLine; + return otherAsUs->_SingleLine == _SingleLine && + otherAsUs->_CopyFormatting == _CopyFormatting; } return false; }; @@ -115,6 +118,7 @@ namespace winrt::TerminalApp::implementation // LOAD BEARING: Not using make_self here _will_ break you in the future! auto args = winrt::make_self(); JsonUtils::GetValueForKey(json, SingleLineKey, args->_SingleLine); + JsonUtils::GetValueForKey(json, CopyFormattingKey, args->_CopyFormatting); return { *args, {} }; } }; diff --git a/src/cascadia/TerminalApp/ActionArgs.idl b/src/cascadia/TerminalApp/ActionArgs.idl index ee50771eb94..15d211e6f63 100644 --- a/src/cascadia/TerminalApp/ActionArgs.idl +++ b/src/cascadia/TerminalApp/ActionArgs.idl @@ -67,6 +67,7 @@ namespace TerminalApp [default_interface] runtimeclass CopyTextArgs : IActionArgs { Boolean SingleLine { get; }; + Windows.Foundation.IReference CopyFormatting { get; }; }; [default_interface] runtimeclass NewTabArgs : IActionArgs diff --git a/src/cascadia/TerminalApp/AppActionHandlers.cpp b/src/cascadia/TerminalApp/AppActionHandlers.cpp index ad06916cd4e..9e9378bb411 100644 --- a/src/cascadia/TerminalApp/AppActionHandlers.cpp +++ b/src/cascadia/TerminalApp/AppActionHandlers.cpp @@ -237,7 +237,7 @@ namespace winrt::TerminalApp::implementation { if (const auto& realArgs = args.ActionArgs().try_as()) { - const auto handled = _CopyText(realArgs.SingleLine()); + const auto handled = _CopyText(realArgs.SingleLine(), realArgs.CopyFormatting()); args.Handled(handled); } } diff --git a/src/cascadia/TerminalApp/GlobalAppSettings.h b/src/cascadia/TerminalApp/GlobalAppSettings.h index b7386429046..bc00276f8d4 100644 --- a/src/cascadia/TerminalApp/GlobalAppSettings.h +++ b/src/cascadia/TerminalApp/GlobalAppSettings.h @@ -70,7 +70,7 @@ class TerminalApp::GlobalAppSettings final GETSET_PROPERTY(bool, ShowTabsInTitlebar, true); GETSET_PROPERTY(std::wstring, WordDelimiters); // default value set in constructor GETSET_PROPERTY(bool, CopyOnSelect, false); - GETSET_PROPERTY(bool, CopyFormatting, false); + GETSET_PROPERTY(winrt::Microsoft::Terminal::TerminalControl::CopyFormat, CopyFormatting, 0); GETSET_PROPERTY(bool, WarnAboutLargePaste, true); GETSET_PROPERTY(bool, WarnAboutMultiLinePaste, true); GETSET_PROPERTY(LaunchPosition, InitialPosition); diff --git a/src/cascadia/TerminalApp/JsonUtils.h b/src/cascadia/TerminalApp/JsonUtils.h index b15eb1478a2..b75c58200e1 100644 --- a/src/cascadia/TerminalApp/JsonUtils.h +++ b/src/cascadia/TerminalApp/JsonUtils.h @@ -372,7 +372,7 @@ namespace TerminalApp::JsonUtils { // attempt to combine AllClear (explicitly) with anything else DeserializationError e{ element }; - e.expectedType = TypeDescription(); + e.expectedType = BaseEnumMapper::TypeDescription(); throw e; } value |= newFlag; diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index 1c9bc9fd212..307ba9edfea 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -1676,10 +1676,17 @@ namespace winrt::TerminalApp::implementation DataPackage dataPack = DataPackage(); dataPack.RequestedOperation(DataPackageOperation::Copy); + // The EventArgs.Formats() is an override for the global setting "copyFormatting" + // iff it is set + bool useGlobal = copiedData.Formats() == nullptr; + auto copyFormats = useGlobal ? + _settings->GlobalSettings().CopyFormatting() : + copiedData.Formats().Value(); + // copy text to dataPack dataPack.SetText(copiedData.Text()); - if (_settings->GlobalSettings().CopyFormatting()) + if (WI_IsFlagSet(copyFormats, CopyFormat::HTML)) { // copy html to dataPack const auto htmlData = copiedData.Html(); @@ -1687,7 +1694,10 @@ namespace winrt::TerminalApp::implementation { dataPack.SetHtmlFormat(htmlData); } + } + if (WI_IsFlagSet(copyFormats, CopyFormat::RTF)) + { // copy rtf data to dataPack const auto rtfData = copiedData.Rtf(); if (!rtfData.empty()) @@ -1780,12 +1790,13 @@ namespace winrt::TerminalApp::implementation // - Copy text from the focused terminal to the Windows Clipboard // Arguments: // - singleLine: if enabled, copy contents as a single line of text + // - formats: dictate which formats need to be copied // Return Value: // - true iff we we able to copy text (if a selection was active) - bool TerminalPage::_CopyText(const bool singleLine) + bool TerminalPage::_CopyText(const bool singleLine, const Windows::Foundation::IReference& formats) { const auto control = _GetActiveControl(); - return control.CopySelectionToClipboard(singleLine); + return control.CopySelectionToClipboard(singleLine, formats); } // Method Description: diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h index 36c8d1328c6..c19c404bc13 100644 --- a/src/cascadia/TerminalApp/TerminalPage.h +++ b/src/cascadia/TerminalApp/TerminalPage.h @@ -170,7 +170,7 @@ namespace winrt::TerminalApp::implementation winrt::fire_and_forget _CopyToClipboardHandler(const IInspectable sender, const winrt::Microsoft::Terminal::TerminalControl::CopyToClipboardEventArgs copiedData); winrt::fire_and_forget _PasteFromClipboardHandler(const IInspectable sender, const Microsoft::Terminal::TerminalControl::PasteFromClipboardEventArgs eventArgs); - bool _CopyText(const bool trimTrailingWhitespace); + bool _CopyText(const bool singleLine, const Windows::Foundation::IReference& formats); void _PasteText(); fire_and_forget _LaunchSettings(const winrt::TerminalApp::SettingsTarget target); diff --git a/src/cascadia/TerminalApp/TerminalSettingsSerializationHelpers.h b/src/cascadia/TerminalApp/TerminalSettingsSerializationHelpers.h index c1e60b6a705..c83d0ae1298 100644 --- a/src/cascadia/TerminalApp/TerminalSettingsSerializationHelpers.h +++ b/src/cascadia/TerminalApp/TerminalSettingsSerializationHelpers.h @@ -184,6 +184,30 @@ JSON_ENUM_MAPPER(::winrt::Microsoft::UI::Xaml::Controls::TabViewWidthMode) }; }; +JSON_FLAG_MAPPER(::winrt::Microsoft::Terminal::TerminalControl::CopyFormat) +{ + JSON_MAPPINGS(5) = { + pair_type{ "none", AllClear }, + pair_type{ "html", ValueType::HTML }, + pair_type{ "rtf", ValueType::RTF }, + pair_type{ "all", AllSet }, + }; + + auto FromJson(const Json::Value& json) + { + if (json.isBool()) + { + return json.asBool() ? AllSet : AllClear; + } + return BaseFlagMapper::FromJson(json); + } + + bool CanConvert(const Json::Value& json) + { + return BaseFlagMapper::CanConvert(json) || json.isBool(); + } +}; + // Type Description: // - Helper for converting the initial position string into // 2 coordinate values. We allow users to only provide one coordinate, diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index b493054c6a1..dd033691e5d 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -35,6 +35,8 @@ constexpr const auto ScrollBarUpdateInterval = std::chrono::milliseconds(8); // The minimum delay between updating the TSF input control. constexpr const auto TsfRedrawInterval = std::chrono::milliseconds(100); +DEFINE_ENUM_FLAG_OPERATORS(winrt::Microsoft::Terminal::TerminalControl::CopyFormat); + namespace winrt::Microsoft::Terminal::TerminalControl::implementation { // Helper static function to ensure that all ambiguous-width glyphs are reported as narrow. @@ -1152,7 +1154,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation } else { - CopySelectionToClipboard(shiftEnabled); + CopySelectionToClipboard(shiftEnabled, nullptr); } } } @@ -1312,7 +1314,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation // Right clicks and middle clicks should not need to do anything when released. if (_settings.CopyOnSelect() && point.Properties().PointerUpdateKind() == Windows::UI::Input::PointerUpdateKind::LeftButtonReleased && _selectionNeedsToBeCopied) { - CopySelectionToClipboard(); + CopySelectionToClipboard(false, nullptr); } } else if (ptr.PointerDeviceType() == Windows::Devices::Input::PointerDeviceType::Touch) @@ -2088,9 +2090,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation void TermControl::_CopyToClipboard(const std::wstring_view& wstr) { - auto copyArgs = winrt::make_self(winrt::hstring(wstr), - winrt::hstring(L""), - winrt::hstring(L"")); + auto copyArgs = winrt::make_self(winrt::hstring(wstr)); _clipboardCopyHandlers(*this, *copyArgs); } @@ -2154,7 +2154,9 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation // - CopyOnSelect does NOT clear the selection // Arguments: // - singleLine: collapse all of the text to one line - bool TermControl::CopySelectionToClipboard(bool singleLine) + // - formats: which formats to copy (defined by action's CopyFormatting arg). nullptr + // if we should defer which formats are copied to the global setting + bool TermControl::CopySelectionToClipboard(bool singleLine, const Windows::Foundation::IReference& formats) { if (_closing) { @@ -2184,16 +2186,20 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation // GH#5347 - Don't provide a title for the generated HTML, as many // web applications will paste the title first, followed by the HTML // content, which is unexpected. - const auto htmlData = TextBuffer::GenHTML(bufferData, - _actualFont.GetUnscaledSize().Y, - _actualFont.GetFaceName(), - _settings.DefaultBackground()); + const auto htmlData = formats == nullptr || WI_IsFlagSet(formats.Value(), CopyFormat::HTML) ? + TextBuffer::GenHTML(bufferData, + _actualFont.GetUnscaledSize().Y, + _actualFont.GetFaceName(), + _settings.DefaultBackground()) : + ""; // convert to RTF format - const auto rtfData = TextBuffer::GenRTF(bufferData, - _actualFont.GetUnscaledSize().Y, - _actualFont.GetFaceName(), - _settings.DefaultBackground()); + const auto rtfData = formats == nullptr || WI_IsFlagSet(formats.Value(), CopyFormat::RTF) ? + TextBuffer::GenRTF(bufferData, + _actualFont.GetUnscaledSize().Y, + _actualFont.GetFaceName(), + _settings.DefaultBackground()) : + ""; if (!_settings.CopyOnSelect()) { @@ -2204,7 +2210,8 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation // send data up for clipboard auto copyArgs = winrt::make_self(winrt::hstring(textData), winrt::to_hstring(htmlData), - winrt::to_hstring(rtfData)); + winrt::to_hstring(rtfData), + formats); _clipboardCopyHandlers(*this, *copyArgs); return true; } diff --git a/src/cascadia/TerminalControl/TermControl.h b/src/cascadia/TerminalControl/TermControl.h index e62f7fe25e5..2f9de1d7f07 100644 --- a/src/cascadia/TerminalControl/TermControl.h +++ b/src/cascadia/TerminalControl/TermControl.h @@ -27,19 +27,28 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation public CopyToClipboardEventArgsT { public: - CopyToClipboardEventArgs(hstring text, hstring html, hstring rtf) : + CopyToClipboardEventArgs(hstring text) : + _text(text), + _html(), + _rtf(), + _formats(static_cast(0)) {} + + CopyToClipboardEventArgs(hstring text, hstring html, hstring rtf, Windows::Foundation::IReference formats) : _text(text), _html(html), - _rtf(rtf) {} + _rtf(rtf), + _formats(formats) {} hstring Text() { return _text; }; hstring Html() { return _html; }; hstring Rtf() { return _rtf; }; + Windows::Foundation::IReference Formats() { return _formats; }; private: hstring _text; hstring _html; hstring _rtf; + Windows::Foundation::IReference _formats; }; struct PasteFromClipboardEventArgs : @@ -67,7 +76,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation hstring Title(); hstring GetProfileName() const; - bool CopySelectionToClipboard(bool collapseText = false); + bool CopySelectionToClipboard(bool singleLine, const Windows::Foundation::IReference& formats); void PasteTextFromClipboard(); void Close(); Windows::Foundation::Size CharacterDimensions() const; diff --git a/src/cascadia/TerminalControl/TermControl.idl b/src/cascadia/TerminalControl/TermControl.idl index 66d64d74265..e7f9c958802 100644 --- a/src/cascadia/TerminalControl/TermControl.idl +++ b/src/cascadia/TerminalControl/TermControl.idl @@ -19,11 +19,20 @@ namespace Microsoft.Terminal.TerminalControl Boolean OnDirectKeyEvent(UInt32 vkey, UInt8 scanCode, Boolean down); } + [flags] + enum CopyFormat + { + HTML = 0x1, + RTF = 0x2, + All = 0xffffffff + }; + runtimeclass CopyToClipboardEventArgs { String Text { get; }; String Html { get; }; String Rtf { get; }; + Windows.Foundation.IReference Formats { get; }; } runtimeclass PasteFromClipboardEventArgs @@ -54,7 +63,7 @@ namespace Microsoft.Terminal.TerminalControl String Title { get; }; - Boolean CopySelectionToClipboard(Boolean collapseText); + Boolean CopySelectionToClipboard(Boolean singleLine, Windows.Foundation.IReference formats); void PasteTextFromClipboard(); void Close(); Windows.Foundation.Size CharacterDimensions { get; }; From acac35023d12f194918a1af388c57b7ea6f0c388 Mon Sep 17 00:00:00 2001 From: Chester Liu Date: Tue, 18 Aug 2020 01:30:07 +0800 Subject: [PATCH 053/266] Add initial support for VT DCS sequences (#6328) As the title suggests, this commit adds initial support for the VT DCS sequences. The parameters are parsed but not yet used. The pass through data is yet to be handled. This effectively fixes #120 by making Sixel graphics sequences *ignored* instead of printed. * https://vt100.net/docs/vt510-rm/chapter4.html * https://vt100.net/emu/dec_ansi_parser Tests added. References #448 Closes #120 --- .../spell-check/dictionary/dictionary.txt | 2 + .../parser/OutputStateMachineEngine.cpp | 6 + src/terminal/parser/stateMachine.cpp | 489 ++++++++++++++++-- src/terminal/parser/stateMachine.hpp | 21 +- .../parser/ut_parser/OutputEngineTest.cpp | 204 +++++++- 5 files changed, 678 insertions(+), 44 deletions(-) diff --git a/.github/actions/spell-check/dictionary/dictionary.txt b/.github/actions/spell-check/dictionary/dictionary.txt index c01a75b1927..e1b7da0f86a 100644 --- a/.github/actions/spell-check/dictionary/dictionary.txt +++ b/.github/actions/spell-check/dictionary/dictionary.txt @@ -99401,6 +99401,8 @@ DCP DCPR DCPSK DCS +Dcs +dcs DCT DCTN DCTS diff --git a/src/terminal/parser/OutputStateMachineEngine.cpp b/src/terminal/parser/OutputStateMachineEngine.cpp index 4d5b4d0c8ac..85a219db8f3 100644 --- a/src/terminal/parser/OutputStateMachineEngine.cpp +++ b/src/terminal/parser/OutputStateMachineEngine.cpp @@ -186,6 +186,12 @@ bool OutputStateMachineEngine::ActionPassThroughString(const std::wstring_view s bool OutputStateMachineEngine::ActionEscDispatch(const wchar_t wch, const gsl::span intermediates) { + if (wch == L'\\' && intermediates.empty()) + { + // This is presumably the 7-bit string terminator, which is essentially a no-op. + return true; + } + bool success = false; // no intermediates. diff --git a/src/terminal/parser/stateMachine.cpp b/src/terminal/parser/stateMachine.cpp index c49e52e3c78..7e60032c5e0 100644 --- a/src/terminal/parser/stateMachine.cpp +++ b/src/terminal/parser/stateMachine.cpp @@ -45,7 +45,7 @@ IStateMachineEngine& StateMachine::Engine() noexcept // - wch - Character to check. // Return Value: // - True if it is. False if it isn't. -static constexpr bool _isNumber(const wchar_t wch) noexcept +static constexpr bool _isNumericParamValue(const wchar_t wch) noexcept { return wch >= L'0' && wch <= L'9'; // 0x30 - 0x39 } @@ -92,6 +92,21 @@ static constexpr bool _isC1Csi(const wchar_t wch) noexcept return wch == L'\x9b'; } +// Routine Description: +// - Determines if a character is a C1 DCS (Device Control Strings) +// This is a single-character way to start a control sequence, as opposed to "ESC P". +// +// See the comment above _isC1Csi for more information on how this is impacted by codepages. +// +// Arguments: +// - wch - Character to check. +// Return Value: +// - True if it is. False if it isn't. +static constexpr bool _isC1Dcs(const wchar_t wch) noexcept +{ + return wch == L'\x90'; +} + // Routine Description: // - Determines if a character is a valid intermediate in an VT escape sequence. // Intermediates are punctuation type characters that are generally vendor specific and @@ -129,6 +144,17 @@ static constexpr bool _isEscape(const wchar_t wch) noexcept return wch == AsciiChars::ESC; } +// Routine Description: +// - Determines if a character is a delimiter between two parameters in a "control sequence". +// Arguments: +// - wch - Character to check. +// Return Value: +// - True if it is. False if it isn't. +static constexpr bool _isParameterDelimiter(const wchar_t wch) noexcept +{ + return wch == L';'; // 0x3B +} + // Routine Description: // - Determines if a character is "control sequence" beginning indicator. // This immediately follows an escape and signifies a varying length control sequence. @@ -142,51 +168,72 @@ static constexpr bool _isCsiIndicator(const wchar_t wch) noexcept } // Routine Description: -// - Determines if a character is a delimiter between two parameters in a "control sequence" -// This occurs in the middle of a control sequence after escape and CsiIndicator have been recognized -// between a series of parameters. +// - Determines if a character is a private range marker for a control sequence. +// Private range markers indicate vendor-specific behavior. // Arguments: // - wch - Character to check. // Return Value: // - True if it is. False if it isn't. -static constexpr bool _isCsiDelimiter(const wchar_t wch) noexcept +static constexpr bool _isCsiPrivateMarker(const wchar_t wch) noexcept { - return wch == L';'; // 0x3B + return wch == L'<' || wch == L'=' || wch == L'>' || wch == L'?'; // 0x3C - 0x3F } // Routine Description: -// - Determines if a character is a valid parameter value -// Parameters must be numerical digits. +// - Determines if a character is invalid in a control sequence // Arguments: // - wch - Character to check. // Return Value: // - True if it is. False if it isn't. -static constexpr bool _isCsiParamValue(const wchar_t wch) noexcept +static constexpr bool _isCsiInvalid(const wchar_t wch) noexcept { - return wch >= L'0' && wch <= L'9'; // 0x30 - 0x39 + return wch == L':'; // 0x3A } // Routine Description: -// - Determines if a character is a private range marker for a control sequence. -// Private range markers indicate vendor-specific behavior. +// - Determines if a character is an invalid intermediate. // Arguments: // - wch - Character to check. // Return Value: // - True if it is. False if it isn't. -static constexpr bool _isCsiPrivateMarker(const wchar_t wch) noexcept +static constexpr bool _isIntermediateInvalid(const wchar_t wch) noexcept { - return wch == L'<' || wch == L'=' || wch == L'>' || wch == L'?'; // 0x3C - 0x3F + // 0x30 - 0x3F + return _isNumericParamValue(wch) || _isCsiInvalid(wch) || _isParameterDelimiter(wch) || _isCsiPrivateMarker(wch); } // Routine Description: -// - Determines if a character is invalid in a control sequence +// - Determines if a character is an invalid parameter. // Arguments: // - wch - Character to check. // Return Value: // - True if it is. False if it isn't. -static constexpr bool _isCsiInvalid(const wchar_t wch) noexcept +static constexpr bool _isParameterInvalid(const wchar_t wch) noexcept { - return wch == L':'; // 0x3A + // 0x3A, 0x3C - 0x3F + return _isCsiInvalid(wch) || _isCsiPrivateMarker(wch); +} + +// Routine Description: +// - Determines if a character is a string terminator. +// Arguments: +// - wch - Character to check. +// Return Value: +// - True if it is. False if it isn't. +static constexpr bool _isStringTerminator(const wchar_t wch) noexcept +{ + return wch == L'\x9C'; +} + +// Routine Description: +// - Determines if a character is a string terminator indicator. +// Arguments: +// - wch - Character to check. +// Return Value: +// - True if it is. False if it isn't. +static constexpr bool _isStringTerminatorIndicator(const wchar_t wch) noexcept +{ + return wch == L'\\'; // 0x5c } // Routine Description: @@ -241,19 +288,6 @@ static constexpr bool _isOscDelimiter(const wchar_t wch) noexcept return wch == L';'; // 0x3B } -// Routine Description: -// - Determines if a character is a valid parameter value for an OSC String, -// that is, the indicator of which OSC action to take. -// Parameters must be numerical digits. -// Arguments: -// - wch - Character to check. -// Return Value: -// - True if it is. False if it isn't. -static constexpr bool _isOscParamValue(const wchar_t wch) noexcept -{ - return _isNumber(wch); // 0x30 - 0x39 -} - // Routine Description: // - Determines if a character should be initiate the end of an OSC sequence. // Arguments: @@ -287,7 +321,42 @@ static constexpr bool _isOscInvalid(const wchar_t wch) noexcept // - True if it is. False if it isn't. static constexpr bool _isOscTerminator(const wchar_t wch) noexcept { - return wch == L'\x7' || wch == L'\x9C'; // Bell character or C1 terminator + return wch == AsciiChars::BEL || _isStringTerminator(wch); // Bell character or C1 terminator +} + +// Routine Description: +// - Determines if a character is "device control string" beginning +// indicator. +// Arguments: +// - wch - Character to check. +// Return Value: +// - True if it is. False if it isn't. +static constexpr bool _isDcsIndicator(const wchar_t wch) noexcept +{ + return wch == L'P'; // 0x50 +} + +// Routine Description: +// - Determines if a character should initiate the end of a DCS sequence. +// Arguments: +// - wch - Character to check. +// Return Value: +// - True if it is. False if it isn't. +static constexpr bool _isDcsTerminationInitiator(const wchar_t wch) noexcept +{ + return wch == AsciiChars::ESC; +} + +// Routine Description: +// - Determines if a character is valid for a DCS pass through sequence. +// Arguments: +// - wch - Character to check. +// Return Value: +// - True if it is. False if it isn't. +static constexpr bool _isDcsPassThroughValid(const wchar_t wch) noexcept +{ + // 0x20 - 0x7E + return wch >= AsciiChars::SPC && wch < AsciiChars::DEL; } // Routine Description: @@ -299,7 +368,7 @@ static constexpr bool _isOscTerminator(const wchar_t wch) noexcept // - True if it is. False if it isn't. static constexpr bool _isActionableFromGround(const wchar_t wch) noexcept { - return (wch <= AsciiChars::US) || _isC1Csi(wch) || _isDelete(wch); + return (wch <= AsciiChars::US) || _isC1Csi(wch) || _isC1Dcs(wch) || _isDelete(wch); } #pragma warning(pop) @@ -566,6 +635,19 @@ void StateMachine::_ActionSs3Dispatch(const wchar_t wch) } } +// Routine Description: +// - Triggers the DcsPassThrough action to indicate that the listener should handle a DCS data string character. +// Arguments: +// - wch - Character to dispatch. +// Return Value: +// - +void StateMachine::_ActionDcsPassThrough(const wchar_t wch) +{ + _trace.TraceOnAction(L"DcsPassThrough"); + _trace.TraceOnExecute(wch); + // TODO:GH#7316: Send the DCS passthrough sequence to the engine +} + // Routine Description: // - Moves the state machine into the Ground state. // This state is entered: @@ -757,6 +839,96 @@ void StateMachine::_EnterVt52Param() noexcept _trace.TraceStateChange(L"Vt52Param"); } +// Routine Description: +// - Moves the state machine into the DcsEntry state. +// This state is entered: +// 1. When the DcsEntry character is seen after an Escape entry (only from the Escape state) +// Arguments: +// - +// Return Value: +// - +void StateMachine::_EnterDcsEntry() +{ + _state = VTStates::DcsEntry; + _trace.TraceStateChange(L"DcsEntry"); + _ActionClear(); +} + +// Routine Description: +// - Moves the state machine into the DcsParam state. +// This state is entered: +// 1. When valid parameter characters are detected on entering a DCS (from DcsEntry state) +// Arguments: +// - +// Return Value: +// - +void StateMachine::_EnterDcsParam() noexcept +{ + _state = VTStates::DcsParam; + _trace.TraceStateChange(L"DcsParam"); +} + +// Routine Description: +// - Moves the state machine into the DcsIgnore state. +// This state is entered: +// 1. When an invalid character is detected during a DCS sequence indicating we should ignore the whole sequence. +// (From DcsEntry, DcsParam, DcsPassThrough, or DcsIntermediate states.) +// Arguments: +// - +// Return Value: +// - +void StateMachine::_EnterDcsIgnore() noexcept +{ + _state = VTStates::DcsIgnore; + _trace.TraceStateChange(L"DcsIgnore"); +} + +// Routine Description: +// - Moves the state machine into the DcsIntermediate state. +// This state is entered: +// 1. When an intermediate character is seen immediately after entering a control sequence (from DcsEntry) +// 2. When an intermediate character is seen while collecting parameter data (from DcsParam) +// Arguments: +// - +// Return Value: +// - +void StateMachine::_EnterDcsIntermediate() noexcept +{ + _state = VTStates::DcsIntermediate; + _trace.TraceStateChange(L"DcsIntermediate"); +} + +// Routine Description: +// - Moves the state machine into the DcsPassThrough state. +// This state is entered: +// 1. When a data string character is seen immediately after entering a control sequence (from DcsEntry) +// 2. When a data string character is seen while collecting parameter data (from DcsParam) +// 3. When a data string character is seen while collecting intermediate data (from DcsIntermediate) +// Arguments: +// - +// Return Value: +// - +void StateMachine::_EnterDcsPassThrough() noexcept +{ + _state = VTStates::DcsPassThrough; + _trace.TraceStateChange(L"DcsPassThrough"); +} + +// Routine Description: +// - Moves the state machine into the DcsTermination state. +// This state is entered: +// 1. When an ESC is seen in a DCS string. This escape will be followed by a +// '\', as to encode a 0x9C as a 7-bit ASCII char stream. +// Arguments: +// - +// Return Value: +// - +void StateMachine::_EnterDcsTermination() noexcept +{ + _state = VTStates::DcsTermination; + _trace.TraceStateChange(L"DcsTermination"); +} + // Routine Description: // - Processes a character event into an Action that occurs while in the Ground state. // Events in this state will: @@ -778,6 +950,10 @@ void StateMachine::_EventGround(const wchar_t wch) { _EnterCsiEntry(); } + else if (_isC1Dcs(wch) && _isInAnsiMode) + { + _EnterDcsEntry(); + } else { _ActionPrint(wch); @@ -842,6 +1018,10 @@ void StateMachine::_EventEscape(const wchar_t wch) { _EnterSs3Entry(); } + else if (_isDcsIndicator(wch)) + { + _EnterDcsEntry(); + } else { _ActionEscDispatch(wch); @@ -935,7 +1115,7 @@ void StateMachine::_EventCsiEntry(const wchar_t wch) { _EnterCsiIgnore(); } - else if (_isCsiParamValue(wch) || _isCsiDelimiter(wch)) + else if (_isNumericParamValue(wch) || _isParameterDelimiter(wch)) { _ActionParam(wch); _EnterCsiParam(); @@ -979,7 +1159,7 @@ void StateMachine::_EventCsiIntermediate(const wchar_t wch) { _ActionIgnore(); } - else if (_isCsiParamValue(wch) || _isCsiInvalid(wch) || _isCsiDelimiter(wch) || _isCsiPrivateMarker(wch)) + else if (_isIntermediateInvalid(wch)) { _EnterCsiIgnore(); } @@ -1017,7 +1197,7 @@ void StateMachine::_EventCsiIgnore(const wchar_t wch) { _ActionIgnore(); } - else if (_isCsiParamValue(wch) || _isCsiInvalid(wch) || _isCsiDelimiter(wch) || _isCsiPrivateMarker(wch)) + else if (_isIntermediateInvalid(wch)) { _ActionIgnore(); } @@ -1051,7 +1231,7 @@ void StateMachine::_EventCsiParam(const wchar_t wch) { _ActionIgnore(); } - else if (_isCsiParamValue(wch) || _isCsiDelimiter(wch)) + else if (_isNumericParamValue(wch) || _isParameterDelimiter(wch)) { _ActionParam(wch); } @@ -1060,7 +1240,7 @@ void StateMachine::_EventCsiParam(const wchar_t wch) _ActionCollect(wch); _EnterCsiIntermediate(); } - else if (_isCsiInvalid(wch) || _isCsiPrivateMarker(wch)) + else if (_isParameterInvalid(wch)) { _EnterCsiIgnore(); } @@ -1088,7 +1268,7 @@ void StateMachine::_EventOscParam(const wchar_t wch) noexcept { _EnterGround(); } - else if (_isOscParamValue(wch)) + else if (_isNumericParamValue(wch)) { _ActionOscParam(wch); } @@ -1185,7 +1365,7 @@ void StateMachine::_EventSs3Entry(const wchar_t wch) // CSI sequences ignore characters the same way. _EnterCsiIgnore(); } - else if (_isCsiParamValue(wch) || _isCsiDelimiter(wch)) + else if (_isNumericParamValue(wch) || _isParameterDelimiter(wch)) { _ActionParam(wch); _EnterSs3Param(); @@ -1220,11 +1400,11 @@ void StateMachine::_EventSs3Param(const wchar_t wch) { _ActionIgnore(); } - else if (_isCsiParamValue(wch) || _isCsiDelimiter(wch)) + else if (_isNumericParamValue(wch) || _isParameterDelimiter(wch)) { _ActionParam(wch); } - else if (_isCsiInvalid(wch) || _isCsiPrivateMarker(wch)) + else if (_isParameterInvalid(wch)) { _EnterCsiIgnore(); } @@ -1270,6 +1450,217 @@ void StateMachine::_EventVt52Param(const wchar_t wch) } } +// Routine Description: +// - Processes a character event into an Action that occurs while in the DcsEntry state. +// Events in this state will: +// 1. Ignore C0 control characters +// 2. Ignore Delete characters +// 3. Begin to ignore all remaining characters when an invalid character is detected (DcsIgnore) +// 4. Store parameter data +// 5. Collect Intermediate characters +// 6. Pass through everything else +// DCS sequences are structurally almost the same as CSI sequences, just with an +// extra data string. It's safe to reuse CSI functions for +// determining if a character is a parameter, delimiter, or invalid. +// Arguments: +// - wch - Character that triggered the event +// Return Value: +// - +void StateMachine::_EventDcsEntry(const wchar_t wch) +{ + _trace.TraceOnEvent(L"DcsEntry"); + if (_isC0Code(wch)) + { + _ActionIgnore(); + } + else if (_isDelete(wch)) + { + _ActionIgnore(); + } + else if (_isCsiInvalid(wch)) + { + _EnterDcsIgnore(); + } + else if (_isNumericParamValue(wch) || _isParameterDelimiter(wch)) + { + _ActionParam(wch); + _EnterDcsParam(); + } + else if (_isIntermediate(wch)) + { + _ActionCollect(wch); + _EnterDcsIntermediate(); + } + else + { + _ActionDcsPassThrough(wch); + _EnterDcsPassThrough(); + } +} + +// Routine Description: +// - Processes a character event into an Action that occurs while in the DcsIgnore state. +// Events in this state will: +// 1. Enter ground on a String terminator +// 2. Ignore everything else. +// Arguments: +// - wch - Character that triggered the event +// Return Value: +// - +void StateMachine::_EventDcsIgnore(const wchar_t wch) noexcept +{ + _trace.TraceOnEvent(L"DcsIgnore"); + if (_isStringTerminator(wch)) + { + _EnterGround(); + } + else + { + _ActionIgnore(); + } +} + +// Routine Description: +// - Processes a character event into an Action that occurs while in the DcsIntermediate state. +// Events in this state will: +// 1. Ignore C0 control characters +// 2. Ignore Delete characters +// 3. Collect intermediate data. +// 4. Begin to ignore all remaining intermediates when an invalid character is detected (DcsIgnore) +// 5. Enter DcsPassThrough if we see DCS pass through indicator +// 6. Pass through everything else. +// Arguments: +// - wch - Character that triggered the event +// Return Value: +// - +void StateMachine::_EventDcsIntermediate(const wchar_t wch) +{ + _trace.TraceOnEvent(L"DcsIntermediate"); + if (_isC0Code(wch)) + { + _ActionIgnore(); + } + else if (_isDelete(wch)) + { + _ActionIgnore(); + } + else if (_isIntermediate(wch)) + { + _ActionCollect(wch); + } + else if (_isIntermediateInvalid(wch)) + { + _EnterDcsIgnore(); + } + else + { + _ActionDcsPassThrough(wch); + _EnterDcsPassThrough(); + } +} + +// Routine Description: +// - Processes a character event into an Action that occurs while in the DcsParam state. +// Events in this state will: +// 1. Ignore C0 control characters +// 2. Ignore Delete characters +// 3. Collect DCS parameter data +// 4. Enter DcsIntermediate if we see an intermediate +// 5. Begin to ignore all remaining parameters when an invalid character is detected (DcsIgnore) +// 6. Pass through everything else. +// Arguments: +// - wch - Character that triggered the event +// Return Value: +// - +void StateMachine::_EventDcsParam(const wchar_t wch) +{ + _trace.TraceOnEvent(L"DcsParam"); + if (_isC0Code(wch)) + { + _ActionIgnore(); + } + else if (_isDelete(wch)) + { + _ActionIgnore(); + } + if (_isNumericParamValue(wch) || _isParameterDelimiter(wch)) + { + _ActionParam(wch); + } + else if (_isIntermediate(wch)) + { + _ActionCollect(wch); + _EnterDcsIntermediate(); + } + else if (_isParameterInvalid(wch)) + { + _EnterDcsIgnore(); + } + else + { + _ActionDcsPassThrough(wch); + _EnterDcsPassThrough(); + } +} + +// Routine Description: +// - Processes a character event into an Action that occurs while in the DcsPassThrough state. +// Events in this state will: +// 1. Enter ground on a String terminator +// 2. Pass through if character is valid. +// 3. If we see a ESC, enter the DcsTermination state. +// 4. Ignore everything else. +// Arguments: +// - wch - Character that triggered the event +// Return Value: +// - +void StateMachine::_EventDcsPassThrough(const wchar_t wch) +{ + _trace.TraceOnEvent(L"DcsPassThrough"); + if (_isStringTerminator(wch)) + { + // TODO:GH#7316: The Dcs sequence has successfully terminated. This is where we'd be dispatching the DCS command. + _EnterGround(); + } + if (_isC0Code(wch) || _isDcsPassThroughValid(wch)) + { + _ActionDcsPassThrough(wch); + } + else if (_isDcsTerminationInitiator(wch)) + { + _EnterDcsTermination(); + } + else + { + _ActionIgnore(); + } +} + +// Routine Description: +// - Handle the two-character termination of a DCS sequence. +// Events in this state will: +// 1. Enter ground on a string terminator +// 2. Pass on everything else as the start of a regular escape sequence +// Arguments: +// - wch - Character that triggered the event +// Return Value: +// - +void StateMachine::_EventDcsTermination(const wchar_t wch) +{ + _trace.TraceOnEvent(L"DcsTermination"); + + if (_isStringTerminatorIndicator(wch)) + { + // TODO: The Dcs sequence has successfully terminated. This is where we'd be dispatching the DCS command. + _EnterGround(); + } + else + { + _EnterEscape(); + _EventEscape(wch); + } +} + // Routine Description: // - Entry to the state machine. Takes characters one by one and processes them according to the state machine rules. // Arguments: @@ -1292,10 +1683,12 @@ void StateMachine::ProcessCharacter(const wchar_t wch) _ActionExecute(wch); _EnterGround(); } - else if (_isEscape(wch) && _state != VTStates::OscString) + else if (_isEscape(wch) && _state != VTStates::OscString && _state != VTStates::DcsPassThrough) { // Don't go to escape from the OSC string state - ESC can be used to // terminate OSC strings. + // + // Same for DCS pass through state. _EnterEscape(); } else @@ -1329,6 +1722,18 @@ void StateMachine::ProcessCharacter(const wchar_t wch) return _EventSs3Param(wch); case VTStates::Vt52Param: return _EventVt52Param(wch); + case VTStates::DcsEntry: + return _EventDcsEntry(wch); + case VTStates::DcsIgnore: + return _EventDcsIgnore(wch); + case VTStates::DcsIntermediate: + return _EventDcsIntermediate(wch); + case VTStates::DcsParam: + return _EventDcsParam(wch); + case VTStates::DcsPassThrough: + return _EventDcsPassThrough(wch); + case VTStates::DcsTermination: + return _EventDcsTermination(wch); default: return; } diff --git a/src/terminal/parser/stateMachine.hpp b/src/terminal/parser/stateMachine.hpp index dfa66e5ec1e..bcbf3f95b90 100644 --- a/src/terminal/parser/stateMachine.hpp +++ b/src/terminal/parser/stateMachine.hpp @@ -62,6 +62,7 @@ namespace Microsoft::Console::VirtualTerminal void _ActionOscPut(const wchar_t wch); void _ActionOscDispatch(const wchar_t wch); void _ActionSs3Dispatch(const wchar_t wch); + void _ActionDcsPassThrough(const wchar_t wch); void _ActionClear(); void _ActionIgnore() noexcept; @@ -79,6 +80,12 @@ namespace Microsoft::Console::VirtualTerminal void _EnterSs3Entry(); void _EnterSs3Param() noexcept; void _EnterVt52Param() noexcept; + void _EnterDcsEntry(); + void _EnterDcsParam() noexcept; + void _EnterDcsIgnore() noexcept; + void _EnterDcsIntermediate() noexcept; + void _EnterDcsPassThrough() noexcept; + void _EnterDcsTermination() noexcept; void _EventGround(const wchar_t wch); void _EventEscape(const wchar_t wch); @@ -93,6 +100,12 @@ namespace Microsoft::Console::VirtualTerminal void _EventSs3Entry(const wchar_t wch); void _EventSs3Param(const wchar_t wch); void _EventVt52Param(const wchar_t wch); + void _EventDcsEntry(const wchar_t wch); + void _EventDcsIgnore(const wchar_t wch) noexcept; + void _EventDcsIntermediate(const wchar_t wch); + void _EventDcsParam(const wchar_t wch); + void _EventDcsPassThrough(const wchar_t wch); + void _EventDcsTermination(const wchar_t wch); void _AccumulateTo(const wchar_t wch, size_t& value) noexcept; @@ -110,7 +123,13 @@ namespace Microsoft::Console::VirtualTerminal OscTermination, Ss3Entry, Ss3Param, - Vt52Param + Vt52Param, + DcsEntry, + DcsIgnore, + DcsIntermediate, + DcsParam, + DcsPassThrough, + DcsTermination }; Microsoft::Console::VirtualTerminal::ParserTracing _trace; diff --git a/src/terminal/parser/ut_parser/OutputEngineTest.cpp b/src/terminal/parser/ut_parser/OutputEngineTest.cpp index 17caebefada..166578b8055 100644 --- a/src/terminal/parser/ut_parser/OutputEngineTest.cpp +++ b/src/terminal/parser/ut_parser/OutputEngineTest.cpp @@ -56,7 +56,7 @@ class Microsoft::Console::VirtualTerminal::OutputEngineTest final TEST_METHOD(TestEscapePath) { BEGIN_TEST_METHOD_PROPERTIES() - TEST_METHOD_PROPERTY(L"Data:uiTest", L"{0,1,2,3,4,5,6,7,8,9,10,11}") // one value for each type of state test below. + TEST_METHOD_PROPERTY(L"Data:uiTest", L"{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17}") // one value for each type of state test below. END_TEST_METHOD_PROPERTIES() size_t uiTest; @@ -66,6 +66,7 @@ class Microsoft::Console::VirtualTerminal::OutputEngineTest final StateMachine mach(std::move(engine)); // The OscString state shouldn't escape out after an ESC. + // Same for DcsPassThrough state. bool shouldEscapeOut = true; switch (uiTest) @@ -143,6 +144,43 @@ class Microsoft::Console::VirtualTerminal::OutputEngineTest final mach._state = StateMachine::VTStates::Ss3Param; break; } + case 12: + { + Log::Comment(L"Escape from DcsEntry"); + mach._state = StateMachine::VTStates::DcsEntry; + break; + } + case 13: + { + Log::Comment(L"Escape from DcsIgnore"); + mach._state = StateMachine::VTStates::DcsIgnore; + break; + } + case 14: + { + Log::Comment(L"Escape from DcsIntermediate"); + mach._state = StateMachine::VTStates::DcsIntermediate; + break; + } + case 15: + { + Log::Comment(L"Escape from DcsParam"); + mach._state = StateMachine::VTStates::DcsParam; + break; + } + case 16: + { + Log::Comment(L"Escape from DcsPassThrough"); + shouldEscapeOut = false; + mach._state = StateMachine::VTStates::DcsPassThrough; + break; + } + case 17: + { + Log::Comment(L"Escape from DcsTermination"); + mach._state = StateMachine::VTStates::DcsTermination; + break; + } } mach.ProcessCharacter(AsciiChars::ESC); @@ -284,6 +322,12 @@ class Microsoft::Console::VirtualTerminal::OutputEngineTest final VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::CsiParam); mach.ProcessCharacter(L'J'); VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::Ground); + + VERIFY_ARE_EQUAL(mach._parameters.size(), 4u); + VERIFY_ARE_EQUAL(mach._parameters.at(0), 0u); + VERIFY_ARE_EQUAL(mach._parameters.at(1), 324u); + VERIFY_ARE_EQUAL(mach._parameters.at(2), 0u); + VERIFY_ARE_EQUAL(mach._parameters.at(3), 8u); } TEST_METHOD(TestLeadingZeroCsiParam) @@ -428,6 +472,7 @@ class Microsoft::Console::VirtualTerminal::OutputEngineTest final mach.ProcessCharacter(L'\\'); VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::Ground); } + TEST_METHOD(TestLongOscString) { auto dispatch = std::make_unique(); @@ -550,6 +595,163 @@ class Microsoft::Console::VirtualTerminal::OutputEngineTest final mach.ProcessCharacter(AsciiChars::BEL); VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::Ground); } + + TEST_METHOD(TestDcsEntry) + { + auto dispatch = std::make_unique(); + auto engine = std::make_unique(std::move(dispatch)); + StateMachine mach(std::move(engine)); + + VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::Ground); + mach.ProcessCharacter(AsciiChars::ESC); + VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::Escape); + mach.ProcessCharacter(L'P'); + VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::DcsEntry); + mach.ProcessCharacter(AsciiChars::ESC); + mach.ProcessCharacter(L'\\'); + VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::Ground); + } + + TEST_METHOD(TestC1DcsEntry) + { + auto dispatch = std::make_unique(); + auto engine = std::make_unique(std::move(dispatch)); + StateMachine mach(std::move(engine)); + + VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::Ground); + mach.ProcessCharacter(L'\x90'); + VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::DcsEntry); + mach.ProcessCharacter(AsciiChars::ESC); + mach.ProcessCharacter(L'\\'); + VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::Ground); + } + + TEST_METHOD(TestDcsImmediate) + { + auto dispatch = std::make_unique(); + auto engine = std::make_unique(std::move(dispatch)); + StateMachine mach(std::move(engine)); + + VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::Ground); + mach.ProcessCharacter(AsciiChars::ESC); + VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::Escape); + mach.ProcessCharacter(L'P'); + VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::DcsEntry); + mach.ProcessCharacter(L' '); + VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::DcsIntermediate); + mach.ProcessCharacter(L'#'); + VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::DcsIntermediate); + mach.ProcessCharacter(L'%'); + VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::DcsIntermediate); + mach.ProcessCharacter(AsciiChars::ESC); + mach.ProcessCharacter(L'\\'); + VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::Ground); + } + + TEST_METHOD(TestDcsIgnore) + { + auto dispatch = std::make_unique(); + auto engine = std::make_unique(std::move(dispatch)); + StateMachine mach(std::move(engine)); + + VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::Ground); + mach.ProcessCharacter(AsciiChars::ESC); + VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::Escape); + mach.ProcessCharacter(L'P'); + VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::DcsEntry); + mach.ProcessCharacter(L':'); + VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::DcsIgnore); + mach.ProcessCharacter(AsciiChars::ESC); + mach.ProcessCharacter(L'\\'); + VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::Ground); + } + + TEST_METHOD(TestDcsParam) + { + auto dispatch = std::make_unique(); + auto engine = std::make_unique(std::move(dispatch)); + StateMachine mach(std::move(engine)); + + VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::Ground); + mach.ProcessCharacter(AsciiChars::ESC); + VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::Escape); + mach.ProcessCharacter(L'P'); + VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::DcsEntry); + mach.ProcessCharacter(L';'); + VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::DcsParam); + mach.ProcessCharacter(L'3'); + VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::DcsParam); + mach.ProcessCharacter(L'2'); + VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::DcsParam); + mach.ProcessCharacter(L'4'); + VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::DcsParam); + mach.ProcessCharacter(L';'); + VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::DcsParam); + mach.ProcessCharacter(L';'); + VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::DcsParam); + mach.ProcessCharacter(L'8'); + VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::DcsParam); + + VERIFY_ARE_EQUAL(mach._parameters.size(), 4u); + VERIFY_ARE_EQUAL(mach._parameters.at(0), 0u); + VERIFY_ARE_EQUAL(mach._parameters.at(1), 324u); + VERIFY_ARE_EQUAL(mach._parameters.at(2), 0u); + VERIFY_ARE_EQUAL(mach._parameters.at(3), 8u); + + mach.ProcessCharacter(AsciiChars::ESC); + mach.ProcessCharacter(L'\\'); + VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::Ground); + } + + TEST_METHOD(TestDcsIntermediateAndPassThrough) + { + auto dispatch = std::make_unique(); + auto engine = std::make_unique(std::move(dispatch)); + StateMachine mach(std::move(engine)); + + VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::Ground); + mach.ProcessCharacter(AsciiChars::ESC); + VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::Escape); + mach.ProcessCharacter(L'P'); + VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::DcsEntry); + mach.ProcessCharacter(L' '); + VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::DcsIntermediate); + mach.ProcessCharacter(L'x'); + VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::DcsPassThrough); + mach.ProcessCharacter(AsciiChars::ESC); + VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::DcsTermination); + mach.ProcessCharacter(L'\\'); + VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::Ground); + } + + TEST_METHOD(TestDcsLongStringPassThrough) + { + auto dispatch = std::make_unique(); + auto engine = std::make_unique(std::move(dispatch)); + StateMachine mach(std::move(engine)); + + VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::Ground); + mach.ProcessCharacter(AsciiChars::ESC); + VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::Escape); + mach.ProcessCharacter(L'P'); + VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::DcsEntry); + mach.ProcessCharacter(L'q'); + VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::DcsPassThrough); + mach.ProcessCharacter(L'#'); + VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::DcsPassThrough); + mach.ProcessCharacter(L'1'); + VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::DcsPassThrough); + mach.ProcessCharacter(L'N'); + VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::DcsPassThrough); + mach.ProcessCharacter(L'N'); + VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::DcsPassThrough); + mach.ProcessCharacter(L'N'); + VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::DcsPassThrough); + mach.ProcessCharacter(AsciiChars::ESC); + VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::DcsTermination); + mach.ProcessCharacter(L'\\'); + VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::Ground); + } }; class StatefulDispatch final : public TermDispatch From c4a9752be1d10f72cbf97660fae8de4d106fdc32 Mon Sep 17 00:00:00 2001 From: "Dustin L. Howett" Date: Mon, 17 Aug 2020 17:01:50 -0700 Subject: [PATCH 054/266] Disable parallel build (again) and keep TerminalApp PCHs (#7322) The build now builds every project multiple times, so I figure, why not try to fix it. --- build/pipelines/templates/build-console-steps.yml | 2 +- src/common.build.post.props | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build/pipelines/templates/build-console-steps.yml b/build/pipelines/templates/build-console-steps.yml index 0fd6c7b6878..a1bb9df128e 100644 --- a/build/pipelines/templates/build-console-steps.yml +++ b/build/pipelines/templates/build-console-steps.yml @@ -34,7 +34,7 @@ steps: configuration: '$(BuildConfiguration)' msbuildArgs: "${{ parameters.additionalBuildArguments }}" clean: true - maximumCpuCount: true + maximumCpuCount: false - task: PowerShell@2 displayName: 'Check MSIX for common regressions' diff --git a/src/common.build.post.props b/src/common.build.post.props index 64ac5f12228..3f271eaf626 100644 --- a/src/common.build.post.props +++ b/src/common.build.post.props @@ -54,7 +54,7 @@ + Condition="'$(AGENT_ID)' != '' and !$(ProjectName.Contains('TerminalApp'))"> From baefa462382d346497cb471c93a37b6827e90ab2 Mon Sep 17 00:00:00 2001 From: Michelle Tan <41475767+MichelleTanPY@users.noreply.github.com> Date: Tue, 18 Aug 2020 01:21:11 +0100 Subject: [PATCH 055/266] Update colour picker buttons with round edges. (#7305) ![RoundedButtons](https://user-images.githubusercontent.com/41475767/90323225-39e96500-df56-11ea-9219-d386f74fc1b4.png) ## Validation Steps Performed Deployed locally and verified that the colour picker's button has round edges. Closes #7142 --- src/cascadia/TerminalApp/ColorPickupFlyout.xaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cascadia/TerminalApp/ColorPickupFlyout.xaml b/src/cascadia/TerminalApp/ColorPickupFlyout.xaml index 48563ac97a9..06f99df0083 100644 --- a/src/cascadia/TerminalApp/ColorPickupFlyout.xaml +++ b/src/cascadia/TerminalApp/ColorPickupFlyout.xaml @@ -114,11 +114,11 @@ From 8943f68d4dd3334f875baafba4ebde1354ac873a Mon Sep 17 00:00:00 2001 From: Jorge Cabot Date: Mon, 17 Aug 2020 20:24:00 -0400 Subject: [PATCH 056/266] Add startOnUserLogin & fullscreen launchMode to schema (#7300) Fixes #7294 Co-authored-by: Mike Griese --- doc/cascadia/profiles.schema.json | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/doc/cascadia/profiles.schema.json b/doc/cascadia/profiles.schema.json index 6456d452c13..b41a6e50678 100644 --- a/doc/cascadia/profiles.schema.json +++ b/doc/cascadia/profiles.schema.json @@ -556,10 +556,16 @@ "minimum": 1, "type": "integer" }, + "startOnUserLogin": { + "default": false, + "description": "When set to true, this enables the launch of Windows Terminal at startup. Setting this to false will disable the startup task entry. If the Windows Terminal startup task entry is disabled either by org policy or by user action this setting will have no effect.", + "type": "boolean" + }, "launchMode": { "default": "default", - "description": "Defines whether the Terminal will launch as maximized or not.", + "description": "Defines whether the terminal will launch as maximized, full screen, or in a window.", "enum": [ + "fullscreen", "maximized", "default" ], From a50c48cd605f7447c450b0664d7007847b19aecc Mon Sep 17 00:00:00 2001 From: Michael Niksa Date: Tue, 18 Aug 2020 09:59:31 -0700 Subject: [PATCH 057/266] Compensate for new warnings and STL changes in VS 16.7 (#7319) New warnings were added in VS 16.7 and `std::map::erase` is now `noexcept`. Update our code to be compatible with the new enforcement. ## PR Checklist * [x] Closes broken audit in main after Agents updated over the weekend. * [x] I work here. * [x] Audit mode passes now * [x] Am core contributor. ## Validation Steps Performed * [x] Ran audit mode locally --- src/buffer/out/UnicodeStorage.cpp | 5 +++++ .../PublicTerminalCore/HwndTerminal.cpp | 4 ++++ src/cascadia/TerminalConnection/init.cpp | 2 ++ src/inc/til/bitmap.h | 2 +- src/renderer/dx/DxRenderer.cpp | 2 +- src/terminal/adapter/adaptDispatch.cpp | 6 +++++ src/terminal/adapter/terminalOutput.cpp | 9 +++++--- src/terminal/input/mouseInput.cpp | 22 ++++++++++++------- src/terminal/input/terminalInput.cpp | 2 +- .../parser/InputStateMachineEngine.cpp | 6 ++++- .../parser/OutputStateMachineEngine.cpp | 12 ++++++++++ src/terminal/parser/base64.cpp | 6 +++++ 12 files changed, 63 insertions(+), 15 deletions(-) diff --git a/src/buffer/out/UnicodeStorage.cpp b/src/buffer/out/UnicodeStorage.cpp index 1f4c1831ae2..bfc236e06bf 100644 --- a/src/buffer/out/UnicodeStorage.cpp +++ b/src/buffer/out/UnicodeStorage.cpp @@ -35,6 +35,11 @@ void UnicodeStorage::StoreGlyph(const key_type key, const mapped_type& glyph) // - erases key and its associated data from the storage // Arguments: // - key - the key to remove +// ~~~~~~~~~~~~~~ +// NOTE: VS 16.7 changes std::map::erase to noexcept, but the build agents are still 16.6.5. +// Ignore this audit warning on your dev box until the build starts failing. Then fix it +// and remove this comment. +// ~~~~~~~~~~~~~ void UnicodeStorage::Erase(const key_type key) { _map.erase(key); diff --git a/src/cascadia/PublicTerminalCore/HwndTerminal.cpp b/src/cascadia/PublicTerminalCore/HwndTerminal.cpp index c194e5d77a8..01d78f77a32 100644 --- a/src/cascadia/PublicTerminalCore/HwndTerminal.cpp +++ b/src/cascadia/PublicTerminalCore/HwndTerminal.cpp @@ -79,6 +79,8 @@ try case WM_RBUTTONUP: ReleaseCapture(); break; + default: + break; } // Suppress all mouse events that made it into the terminal. @@ -132,6 +134,8 @@ try terminal->_hwnd.release(); terminal->Teardown(); return 0; + default: + break; } } return DefWindowProc(hwnd, uMsg, wParam, lParam); diff --git a/src/cascadia/TerminalConnection/init.cpp b/src/cascadia/TerminalConnection/init.cpp index 12ce0ec8770..0d1e411aa17 100644 --- a/src/cascadia/TerminalConnection/init.cpp +++ b/src/cascadia/TerminalConnection/init.cpp @@ -28,6 +28,8 @@ BOOL WINAPI DllMain(HINSTANCE hInstDll, DWORD reason, LPVOID /*reserved*/) TraceLoggingUnregister(g_hTerminalConnectionProvider); } break; + default: + break; } return TRUE; diff --git a/src/inc/til/bitmap.h b/src/inc/til/bitmap.h index 26492815176..028123cc455 100644 --- a/src/inc/til/bitmap.h +++ b/src/inc/til/bitmap.h @@ -315,7 +315,7 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned" // Copy any regions that overlap from this map to the new one. // Just iterate our runs... - for (const auto run : *this) + for (const auto& run : *this) { // intersect them with the new map // so we don't attempt to set bits that fit outside diff --git a/src/renderer/dx/DxRenderer.cpp b/src/renderer/dx/DxRenderer.cpp index 8e851e62cc0..72b1a1e8fc8 100644 --- a/src/renderer/dx/DxRenderer.cpp +++ b/src/renderer/dx/DxRenderer.cpp @@ -1417,7 +1417,7 @@ try // Use a transform by the size of one cell to convert cells-to-pixels // as we clear. _d2dDeviceContext->SetTransform(D2D1::Matrix3x2F::Scale(_glyphCell)); - for (const auto rect : _invalidMap.runs()) + for (const auto& rect : _invalidMap.runs()) { // Use aliased. // For graphics reasons, it'll look better because it will ensure that diff --git a/src/terminal/adapter/adaptDispatch.cpp b/src/terminal/adapter/adaptDispatch.cpp index 7578e4fbc9a..8d656e572dd 100644 --- a/src/terminal/adapter/adaptDispatch.cpp +++ b/src/terminal/adapter/adaptDispatch.cpp @@ -1578,6 +1578,9 @@ bool AdaptDispatch::TabClear(const size_t clearType) case DispatchTypes::TabClearType::ClearAllColumns: success = _ClearAllTabStops(); break; + default: + success = false; + break; } return success; } @@ -1695,6 +1698,9 @@ bool AdaptDispatch::DesignateCodingSystem(const wchar_t codingSystem) _termOutput.EnableGrTranslation(false); } break; + default: + success = false; + break; } return success; } diff --git a/src/terminal/adapter/terminalOutput.cpp b/src/terminal/adapter/terminalOutput.cpp index a7b7c58aee7..f320839ac5f 100644 --- a/src/terminal/adapter/terminalOutput.cpp +++ b/src/terminal/adapter/terminalOutput.cpp @@ -66,8 +66,9 @@ bool TerminalOutput::Designate94Charset(size_t gsetNumber, const std::pair 0 ? 0x40 : 0x41; + break; + default: + xvalue = 0; + break; } if (isHover) { @@ -235,6 +237,10 @@ static constexpr int _windowsButtonToSGREncoding(const unsigned int button, case WM_MOUSEWHEEL: case WM_MOUSEHWHEEL: xvalue = delta > 0 ? 0x40 : 0x41; + break; + default: + xvalue = 0; + break; } if (isHover) { diff --git a/src/terminal/input/terminalInput.cpp b/src/terminal/input/terminalInput.cpp index 54a99a925cd..8f5c5c4f7f3 100644 --- a/src/terminal/input/terminalInput.cpp +++ b/src/terminal/input/terminalInput.cpp @@ -378,7 +378,7 @@ static bool _searchWithModifier(const KeyEvent& keyEvent, InputSender sender) { s_modifierKeyMapping.data(), s_modifierKeyMapping.size() }); if (match) { - const auto v = match.value(); + const auto& v = match.value(); if (!v.sequence.empty()) { std::wstring modified{ v.sequence }; // Make a copy so we can modify it. diff --git a/src/terminal/parser/InputStateMachineEngine.cpp b/src/terminal/parser/InputStateMachineEngine.cpp index 59f34e20ab9..a4d903f5644 100644 --- a/src/terminal/parser/InputStateMachineEngine.cpp +++ b/src/terminal/parser/InputStateMachineEngine.cpp @@ -408,6 +408,7 @@ bool InputStateMachineEngine::ActionCsiDispatch(const wchar_t wch, // even if we failed to parse a portion of this sequence. success = _UpdateSGRMouseButtonState(wch, parameters, buttonState, eventFlags) && success; success = success && _WriteMouseEvent(col, row, buttonState, modifierState, eventFlags); + break; } default: success = false; @@ -432,6 +433,7 @@ bool InputStateMachineEngine::ActionCsiDispatch(const wchar_t wch, success = _GetXYPosition(parameters, row, col); break; } + [[fallthrough]]; case CsiActionCodes::ArrowUp: case CsiActionCodes::ArrowDown: case CsiActionCodes::ArrowRight: @@ -477,7 +479,7 @@ bool InputStateMachineEngine::ActionCsiDispatch(const wchar_t wch, _lookingForDSR = false; break; } - __fallthrough; + [[fallthrough]]; case CsiActionCodes::Generic: case CsiActionCodes::ArrowUp: case CsiActionCodes::ArrowDown: @@ -1364,6 +1366,8 @@ bool InputStateMachineEngine::_GenerateWin32Key(const gsl::span pa case 1: key.SetVirtualKeyCode(::base::saturated_cast(til::at(parameters, 0))); break; + default: + break; } return true; diff --git a/src/terminal/parser/OutputStateMachineEngine.cpp b/src/terminal/parser/OutputStateMachineEngine.cpp index 85a219db8f3..86a2023af93 100644 --- a/src/terminal/parser/OutputStateMachineEngine.cpp +++ b/src/terminal/parser/OutputStateMachineEngine.cpp @@ -441,6 +441,9 @@ bool OutputStateMachineEngine::_IntermediateScsDispatch(const wchar_t wch, success = _dispatch->Designate96Charset(3, charset); TermTelemetry::Instance().Log(TermTelemetry::Codes::DesignateG3); break; + default: + success = false; + break; } return success; @@ -812,9 +815,15 @@ bool OutputStateMachineEngine::_IntermediateGreaterThanOrEqualDispatch(const wch success = _dispatch->TertiaryDeviceAttributes(); TermTelemetry::Instance().Log(TermTelemetry::Codes::DA3); break; + default: + success = false; + break; } } break; + default: + success = false; + break; } return success; @@ -1336,6 +1345,9 @@ bool OutputStateMachineEngine::_GetDeviceStatusOperation(const gsl::span Date: Tue, 18 Aug 2020 18:21:50 +0100 Subject: [PATCH 058/266] Add menu (also known as "app") as a bindable key (#7328) - Add MENU key with "menu" "app" as key bindings. - Updated profiles.schema.json and documentation. ## Validation Steps Performed Ran tests locally. Tested out the new key binding. ```{ "command": "openNewTabDropdown", "keys": "app" }``` Closes #7144 --- doc/cascadia/SettingsSchema.md | 2 +- doc/cascadia/profiles.schema.json | 4 ++-- src/cascadia/TerminalApp/KeyChordSerialization.cpp | 2 ++ 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/doc/cascadia/SettingsSchema.md b/doc/cascadia/SettingsSchema.md index 6b281c23aea..6f5288910f0 100644 --- a/doc/cascadia/SettingsSchema.md +++ b/doc/cascadia/SettingsSchema.md @@ -159,7 +159,7 @@ For commands with arguments: | ---- | ---- | | Function and Alphanumeric Keys | `f1-f24`, `a-z`, `0-9` | | Symbols | ``` ` ```, `-`, `=`, `[`, `]`, `\`, `;`, `'`, `,`, `.`, `/` | -| Arrow Keys | `down`, `left`, `right`, `up`, `pagedown`, `pageup`, `pgdn`, `pgup`, `end`, `home`, `plus` | +| Arrow Keys | `down`, `left`, `right`, `up`, `pagedown`, `pageup`, `pgdn`, `pgup`, `end`, `home`, `plus`, `app`, `menu` | | Action Keys | `tab`, `enter`, `esc`, `escape`, `space`, `backspace`, `delete`, `insert` | | Numpad Keys | `numpad_0-numpad_9`, `numpad0-numpad9`, `numpad_add`, `numpad_plus`, `numpad_decimal`, `numpad_period`, `numpad_divide`, `numpad_minus`, `numpad_subtract`, `numpad_multiply` | diff --git a/doc/cascadia/profiles.schema.json b/doc/cascadia/profiles.schema.json index b41a6e50678..d26500bd857 100644 --- a/doc/cascadia/profiles.schema.json +++ b/doc/cascadia/profiles.schema.json @@ -4,9 +4,9 @@ "title": "Microsoft's Windows Terminal Settings Profile Schema", "definitions": { "KeyChordSegment": { - "pattern": "^(?(ctrl|alt|shift)(?:\\+(ctrl|alt|shift)(?[^\\s+]|backspace|tab|enter|esc|escape|space|pgup|pageup|pgdn|pagedown|end|home|left|up|right|down|insert|delete|(?(ctrl|alt|shift)(?:\\+(ctrl|alt|shift)(?[^\\s+]|app|menu|backspace|tab|enter|esc|escape|space|pgup|pageup|pgdn|pagedown|end|home|left|up|right|down|insert|delete|(?\", where each modifier is optional, separated by + symbols, and keyName is either one of the names listed in the table below, or any single key character. The string should be written in full lowercase.\nbackspace\tBACKSPACE key\ntab\tTAB key\nenter\tENTER key\nesc, escape\tESC key\nspace\tSPACEBAR\npgup, pageup\tPAGE UP key\npgdn, pagedown\tPAGE DOWN key\nend\tEND key\nhome\tHOME key\nleft\tLEFT ARROW key\nup\tUP ARROW key\nright\tRIGHT ARROW key\ndown\tDOWN ARROW key\ninsert\tINS key\ndelete\tDEL key\nnumpad_0-numpad_9, numpad0-numpad9\tNumeric keypad keys 0 to 9. Can't be combined with the shift modifier.\nnumpad_multiply\tNumeric keypad MULTIPLY key (*)\nnumpad_plus, numpad_add\tNumeric keypad ADD key (+)\nnumpad_minus, numpad_subtract\tNumeric keypad SUBTRACT key (-)\nnumpad_period, numpad_decimal\tNumeric keypad DECIMAL key (.). Can't be combined with the shift modifier.\nnumpad_divide\tNumeric keypad DIVIDE key (/)\nf1-f24\tF1 to F24 function keys\nplus\tADD key (+)" + "description": "The string should fit the format \"[ctrl+][alt+][shift+]\", where each modifier is optional, separated by + symbols, and keyName is either one of the names listed in the table below, or any single key character. The string should be written in full lowercase.\napp, menu\tMENU key\nbackspace\tBACKSPACE key\ntab\tTAB key\nenter\tENTER key\nesc, escape\tESC key\nspace\tSPACEBAR\npgup, pageup\tPAGE UP key\npgdn, pagedown\tPAGE DOWN key\nend\tEND key\nhome\tHOME key\nleft\tLEFT ARROW key\nup\tUP ARROW key\nright\tRIGHT ARROW key\ndown\tDOWN ARROW key\ninsert\tINS key\ndelete\tDEL key\nnumpad_0-numpad_9, numpad0-numpad9\tNumeric keypad keys 0 to 9. Can't be combined with the shift modifier.\nnumpad_multiply\tNumeric keypad MULTIPLY key (*)\nnumpad_plus, numpad_add\tNumeric keypad ADD key (+)\nnumpad_minus, numpad_subtract\tNumeric keypad SUBTRACT key (-)\nnumpad_period, numpad_decimal\tNumeric keypad DECIMAL key (.). Can't be combined with the shift modifier.\nnumpad_divide\tNumeric keypad DIVIDE key (/)\nf1-f24\tF1 to F24 function keys\nplus\tADD key (+)" }, "Color": { "default": "#", diff --git a/src/cascadia/TerminalApp/KeyChordSerialization.cpp b/src/cascadia/TerminalApp/KeyChordSerialization.cpp index 69625004d14..16e9732a57f 100644 --- a/src/cascadia/TerminalApp/KeyChordSerialization.cpp +++ b/src/cascadia/TerminalApp/KeyChordSerialization.cpp @@ -14,11 +14,13 @@ static constexpr int MAX_CHORD_PARTS = 4; // clang-format off static const std::unordered_map vkeyNamePairs { + { L"app" , VK_APPS }, { L"backspace" , VK_BACK }, { L"tab" , VK_TAB }, { L"enter" , VK_RETURN }, { L"esc" , VK_ESCAPE }, { L"escape" , VK_ESCAPE }, + { L"menu" , VK_APPS }, { L"space" , VK_SPACE }, { L"pgup" , VK_PRIOR }, { L"pageup" , VK_PRIOR }, From 66fd9c367d618deccd77b9d0edcd921b415e743e Mon Sep 17 00:00:00 2001 From: "Dustin L. Howett" Date: Tue, 18 Aug 2020 11:05:14 -0700 Subject: [PATCH 059/266] Add til::static_map, a constexpr key-value store (#7323) This is based on (cribbed almost directly from) code written by the inimitable @StephanTLavavej on one of our mailing lists. This is a nice generic version of the approach used in JsonUtils::EnumMapper and CodepointWidthDetector: a static array of key-value pairs that we binary-search at runtime (or at compile time, as the case may be.) Keys are not required to be sorted, as we're taking advantage of constexpr std::sort (VS 16.6+) to get the compiler to do it for us. How cool is that? static_map presents an operator[] or at much like std::map/std::unordered_map does. I've added some tests, but they're practically fully-solveable at compile time so they pretty much act like `VERIFY_IS_TRUE(true)`. --- src/inc/til/static_map.h | 74 ++++++++++++++ src/til/ut_til/StaticMapTests.cpp | 98 +++++++++++++++++++ src/til/ut_til/til.unit.tests.vcxproj | 1 + src/til/ut_til/til.unit.tests.vcxproj.filters | 1 + 4 files changed, 174 insertions(+) create mode 100644 src/inc/til/static_map.h create mode 100644 src/til/ut_til/StaticMapTests.cpp diff --git a/src/inc/til/static_map.h b/src/inc/til/static_map.h new file mode 100644 index 00000000000..452e2dab36b --- /dev/null +++ b/src/inc/til/static_map.h @@ -0,0 +1,74 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +#pragma once + +// static_map implements a very simple std::map-like type +// that is entirely (compile-time-)constant. +// There is no requirement that keys be sorted, as it will +// use constexpr std::sort during construction. + +namespace til // Terminal Implementation Library. Also: "Today I Learned" +{ + template, size_t N = 0> + class static_map + { + public: + using const_iterator = typename std::array, N>::const_iterator; + + template + constexpr explicit static_map(const Args&... args) : + _predicate{}, + _array{ { args... } } + { + static_assert(sizeof...(Args) == N); + const auto compareKeys = [&](const auto& p1, const auto& p2) { return _predicate(p1.first, p2.first); }; + std::sort(_array.begin(), _array.end(), compareKeys); // compile-time sorting! + } + + [[nodiscard]] constexpr const_iterator find(const K& key) const noexcept + { + const auto compareKey = [&](const auto& p) { return _predicate(p.first, key); }; + const auto iter{ std::partition_point(_array.begin(), _array.end(), compareKey) }; + + if (iter == _array.end() || _predicate(key, iter->first)) + { + return _array.end(); + } + + return iter; + } + + [[nodiscard]] constexpr const_iterator end() const noexcept + { + return _array.end(); + } + + [[nodiscard]] constexpr const V& at(const K& key) const + { + const auto iter{ find(key) }; + + if (iter == end()) + { + throw std::runtime_error("key not found"); + } + + return iter->second; + } + + [[nodiscard]] constexpr const V& operator[](const K& key) const + { + return at(key); + } + + private: + Compare _predicate; + std::array, N> _array; + }; + + // this is a deduction guide that ensures two things: + // 1. static_map's member types are all the same + // 2. static_map's fourth template argument (otherwise undeduced) is how many pairs it contains + template + static_map(First, Rest...)->static_map...>, typename First::first_type, void>, typename First::second_type, std::less, 1 + sizeof...(Rest)>; +} diff --git a/src/til/ut_til/StaticMapTests.cpp b/src/til/ut_til/StaticMapTests.cpp new file mode 100644 index 00000000000..3dade824a32 --- /dev/null +++ b/src/til/ut_til/StaticMapTests.cpp @@ -0,0 +1,98 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +#include "precomp.h" + +#include + +using namespace WEX::Common; +using namespace WEX::Logging; +using namespace WEX::TestExecution; + +using namespace std::string_view_literals; + +class StaticMapTests +{ + TEST_CLASS(StaticMapTests); + + TEST_METHOD(Basic) + { + til::static_map intIntMap{ + std::pair{ 1, 100 }, + std::pair{ 3, 300 }, + std::pair{ 5, 500 }, + }; + + VERIFY_ARE_EQUAL(100, intIntMap.at(1)); + VERIFY_ARE_EQUAL(300, intIntMap.at(3)); + VERIFY_ARE_EQUAL(500, intIntMap.at(5)); + + int unused{}; + VERIFY_THROWS(unused = intIntMap.at(0), std::runtime_error); + VERIFY_THROWS(unused = intIntMap.at(7), std::runtime_error); + } + + TEST_METHOD(Unsorted) + { + til::static_map intIntMap{ + std::pair{ 5, 500 }, + std::pair{ 3, 300 }, + std::pair{ 1, 100 }, + }; + + VERIFY_ARE_EQUAL(100, intIntMap.at(1)); + VERIFY_ARE_EQUAL(300, intIntMap.at(3)); + VERIFY_ARE_EQUAL(500, intIntMap.at(5)); + + int unused{}; + VERIFY_THROWS(unused = intIntMap.at(0), std::runtime_error); + VERIFY_THROWS(unused = intIntMap.at(7), std::runtime_error); + } + + TEST_METHOD(StringViewKeys) + { + // We have to use the string view literal type here, as leaving the strings unviewed + // will result in a static_map + // Deduction guides are only applied when *no* template arguments are specified, + // which means we would need to specify them all, including the comparator and number of entries. + til::static_map stringIntMap{ + std::pair{ "xylophones"sv, 100 }, + std::pair{ "apples"sv, 200 }, + std::pair{ "grapes"sv, 300 }, + std::pair{ "pears"sv, 400 }, + }; + + VERIFY_ARE_EQUAL(100, stringIntMap.at("xylophones")); + VERIFY_ARE_EQUAL(300, stringIntMap.at("grapes")); + VERIFY_ARE_EQUAL(400, stringIntMap.at("pears")); + VERIFY_ARE_EQUAL(200, stringIntMap.at("apples")); + + int unused{}; + VERIFY_THROWS(unused = stringIntMap.at("0_hello"), std::runtime_error); + VERIFY_THROWS(unused = stringIntMap.at("z_world"), std::runtime_error); + } + + TEST_METHOD(Find) + { + til::static_map intIntMap{ + std::pair{ 5, 500 }, + }; + + VERIFY_ARE_NOT_EQUAL(intIntMap.end(), intIntMap.find(5)); + VERIFY_ARE_EQUAL(intIntMap.end(), intIntMap.find(7)); + } + +#pragma warning(push) +#pragma warning(disable : 26446) // Suppress bounds.4 check for subscript operator. + TEST_METHOD(Subscript) + { + til::static_map intIntMap{ + std::pair{ 5, 500 }, + }; + + VERIFY_ARE_EQUAL(500, intIntMap[5]); + int unused{}; + VERIFY_THROWS(unused = intIntMap[7], std::runtime_error); + } +#pragma warning(pop) +}; diff --git a/src/til/ut_til/til.unit.tests.vcxproj b/src/til/ut_til/til.unit.tests.vcxproj index d25d9147f02..1b9975ec83b 100644 --- a/src/til/ut_til/til.unit.tests.vcxproj +++ b/src/til/ut_til/til.unit.tests.vcxproj @@ -14,6 +14,7 @@ + diff --git a/src/til/ut_til/til.unit.tests.vcxproj.filters b/src/til/ut_til/til.unit.tests.vcxproj.filters index 5633f453b7d..924ee638336 100644 --- a/src/til/ut_til/til.unit.tests.vcxproj.filters +++ b/src/til/ut_til/til.unit.tests.vcxproj.filters @@ -10,6 +10,7 @@ + From 6eea6a3cedc6ad58815bb51489b4ab1a4cc9ff70 Mon Sep 17 00:00:00 2001 From: Rashil Gandhi <46838874+rashil2000@users.noreply.github.com> Date: Tue, 18 Aug 2020 23:38:22 +0530 Subject: [PATCH 060/266] Add Scoop (unofficial) installation method (#7303) --- README.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/README.md b/README.md index a418e7a9bd7..115eb0ab362 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,22 @@ choco upgrade microsoft-windows-terminal If you have any issues when installing/upgrading the package please go to the [Windows Terminal package page](https://chocolatey.org/packages/microsoft-windows-terminal) and follow the [Chocolatey triage process](https://chocolatey.org/docs/package-triage-process) +#### Via Scoop (unofficial) + +[Scoop](https://scoop.sh) users can download and install the latest Terminal release by installing the `windows-terminal` package: + +```powershell +scoop install windows-terminal +``` + +To update Windows Terminal using Scoop, run the following: + +```powershell +scoop update windows-terminal +``` + +If you have any issues when installing/updating the package, please search for or report the same on the [issues page](https://github.com/lukesampson/scoop-extras/issues) of Scoop Extras bucket repository. + --- ## Windows Terminal 2.0 Roadmap From 97c52c6503038a28364317f981193ad7355aace4 Mon Sep 17 00:00:00 2001 From: Michael Niksa Date: Tue, 18 Aug 2020 11:14:38 -0700 Subject: [PATCH 061/266] fix spell check, how did I miss that. --- .github/actions/spell-check/dictionary/names.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/actions/spell-check/dictionary/names.txt b/.github/actions/spell-check/dictionary/names.txt index 6d47c4e98e9..c7f4c1f2b15 100644 --- a/.github/actions/spell-check/dictionary/names.txt +++ b/.github/actions/spell-check/dictionary/names.txt @@ -25,6 +25,7 @@ Kourosh kowalczyk leonmsft Lepilleur +lukesampson Manandhar mbadolato Mehrain From 5d082ffe67c9714472dcc1548c6b5b7b60780d2c Mon Sep 17 00:00:00 2001 From: Michael Niksa Date: Tue, 18 Aug 2020 11:23:24 -0700 Subject: [PATCH 062/266] Helix Testing (#6992) Use the Helix testing orchestration framework to run our Terminal LocalTests and Console Host UIA tests. ## References #### Creates the following new issues: - #7281 - re-enable local tests that were disabled to turn on Helix - #7282 - re-enable UIA tests that were disabled to turn on Helix - #7286 - investigate and implement appropriate compromise solution to how Skipped is handled by MUX Helix scripts #### Consumes from: - #7164 - The update to TAEF includes wttlog.dll. The WTT logs are what MUX's Helix scripts use to track the run state, convert to XUnit format, and notify both Helix and AzDO of what's going on. #### Produces for: - #671 - Making Terminal UIA tests is now possible - #6963 - MUX's Helix scripts are already ready to capture PGO data on the Helix machines as certain tests run. Presuming we can author some reasonable scenarios, turning on the Helix environment gets us a good way toward automated PGO. #### Related: - #4490 - We lost the AzDO integration of our test data when I moved from the TAEF/VSTest adapter directly back to TE. Thanks to the WTTLog + Helix conversion scripts to XUnit + new upload phase, we have it back! ## PR Checklist * [x] Closes #3838 * [x] I work here. * [x] Literally adds tests. * [ ] Should I update a testing doc in this repo? * [x] Am core contributor. Hear me roar. * [ ] Correct spell-checking the right way before merge. ## Detailed Description of the Pull Request / Additional comments We have had two classes of tests that don't work in our usual build-machine testing environment: 1. Tests that require interactive UI automation or input injection (a.k.a. require a logged in user) 2. Tests that require the entire Windows Terminal to stand up (because our Xaml Islands dependency requires 1903 or later and the Windows Server instance for the build is based on 1809.) The Helix testing environment solves both of these and is brought to us by our friends over in https://github.com/microsoft/microsoft-ui-xaml. This PR takes a large portion of scripts and pipeline configuration steps from the Microsoft-UI-XAML repository and adjusts them for Terminal needs. You can see the source of most of the files in either https://github.com/microsoft/microsoft-ui-xaml/tree/master/build/Helix or https://github.com/microsoft/microsoft-ui-xaml/tree/master/build/AzurePipelinesTemplates Some of the modifications in the files include (but are not limited to) reasons like: - Our test binaries are named differently than MUX's test binaries - We don't need certain types of testing that MUX does. - We use C++ and C# tests while MUX was using only C# tests (so the naming pattern and some of the parsing of those names is different e.g. :: separators in C++ and . separators in C#) - Our pipeline phases work a bit differently than MUX and/or we need significantly fewer pieces to the testing matrix (like we don't test a wide variety of OS versions). The build now runs in a few stages: 1. The usual build and run of unit tests/feature tests, packaging verification, and whatnot. This phase now also picks up and packs anything required for running tests in Helix into an artifact. (It also unifies the artifact name between the things Helix needs and the existing build outputs into the single `drop` artifact to make life a little easier.) 2. The Helix preparation build runs that picks up those artifacts, generates all the scripts required for Helix to understand the test modules/functions from our existing TAEF tests, packs it all up, and queues it on the Helix pool. 3. Helix generates a VM for our testing environment and runs all the TAEF tests that require it. The orchestrator at helix.dot.net watches over this and tracks the success/fail and progress of each module and function. The scripts from our MUX friends handle installing dependencies, making the system quiet for better reliability, detecting flaky tests and rerunning them, and coordinating all the log uploads (including for the subruns of tests that are re-run.) 4. A final build phase is run to look through the results with the Helix API and clean up the marking of tests that are flaky, link all the screenshots and console output logs into the AzDO tests panel, and other such niceities. We are set to run Helix tests on the Feature test policy of only x64 for now. Additionally, because the set up of the Helix VMs takes so long, we are *NOT* running these in PR trigger right now as I believe we all very much value our 15ish minute PR turnaround (and the VM takes another 15 minutes to just get going for whatever reason.) For now, they will only run as a rolling build on master after PRs are merged. We should still know when there's an issue within about an hour of something merging and multiple PRs merging fast will be done on the rolling build as a batch run (not one per). In addition to setting up the entire Helix testing pipeline for the tests that require it, I've preserved our classic way of running unit and feature tests (that don't require an elaborate environment) directly on the build machines. But with one bonus feature... They now use some of the scripts from MUX to transform their log data and report it to AzDO so it shows up beautifully in the build report. (We used to have this before I removed the MStest/VStest wrapper for performance reasons, but now we can have reporting AND performance!) See https://dev.azure.com/ms/terminal/_build/results?buildId=101654&view=ms.vss-test-web.build-test-results-tab for an example. I explored running all of the tests on Helix but.... the Helix setup time is long and the resources are more expensive. I felt it was better to preserve the "quick signal" by continuing to run these directly on the build machine (and skipping the more expensive/slow Helix setup if they fail.) It also works well with the split between PR builds not running Helix and the rolling build running Helix. PR builds will get a good chunk of tests for a quick turn around and the rolling build will finish the more thorough job a bit more slowly. ## Validation Steps Performed - [x] Ran the updated pipelines with Pull Request configuration ensuring that Helix tests don't run in the usual CI - [x] Ran with simulation of the rolling build to ensure that the tests now running in Helix will pass. All failures marked for follow on in reference issues. --- .../actions/spell-check/dictionary/apis.txt | 4 + .../spell-check/dictionary/microsoft.txt | 19 + ...1ff90dc512c83c902762b02f284c1c61603b4a.txt | 10 - .../actions/spell-check/expect/alphabet.txt | 3 + .github/actions/spell-check/expect/expect.txt | 35 + NuGet.Config | 5 + build/Helix/AzurePipelinesHelperScripts.ps1 | 32 + build/Helix/ConvertWttLogToXUnit.ps1 | 28 + build/Helix/EnsureMachineState.ps1 | 112 +++ build/Helix/GenerateTestProjFile.ps1 | 336 +++++++++ build/Helix/HelixTestHelpers.cs | 669 ++++++++++++++++++ build/Helix/InstallTestAppDependencies.ps1 | 12 + build/Helix/OutputFailedTestQuery.ps1 | 8 + build/Helix/OutputSubResultsJsonFiles.ps1 | 32 + build/Helix/OutputTestResults.ps1 | 131 ++++ build/Helix/PrepareHelixPayload.ps1 | 54 ++ build/Helix/ProcessHelixFiles.ps1 | 112 +++ build/Helix/RunTestsInHelix.proj | 18 + build/Helix/UpdateUnreliableTests.ps1 | 135 ++++ build/Helix/global.json | 5 + build/Helix/packages.config | 8 + build/Helix/readme.md | 32 + build/Helix/runtests.cmd | 106 +++ build/packages.config | 5 + .../pipelines/templates/build-console-ci.yml | 18 + .../templates/build-console-steps.yml | 76 +- .../templates/helix-createprojfile-steps.yml | 15 + .../helix-processtestresults-job.yml | 67 ++ .../templates/helix-runtests-job.yml | 131 ++++ build/scripts/Get-WttLog.ps1 | 15 + build/scripts/Run-Tests.ps1 | 16 +- .../LocalTests_TerminalApp/CommandTests.cpp | 8 + .../LocalTests_TerminalApp/SettingsTests.cpp | 15 + .../LocalTests_TerminalApp/TabTests.cpp | 14 + src/host/ft_uia/AccessibilityTests.cs | 26 + src/host/ft_uia/CloseTests.cs | 1 + src/host/ft_uia/Common/Globals.cs | 2 +- src/host/ft_uia/ExperimentalTabTests.cs | 3 + src/host/ft_uia/KeyPressTests.cs | 2 + src/host/ft_uia/WinEventTests.cs | 4 + 40 files changed, 2299 insertions(+), 25 deletions(-) delete mode 100644 .github/actions/spell-check/expect/af1ff90dc512c83c902762b02f284c1c61603b4a.txt create mode 100644 build/Helix/AzurePipelinesHelperScripts.ps1 create mode 100644 build/Helix/ConvertWttLogToXUnit.ps1 create mode 100644 build/Helix/EnsureMachineState.ps1 create mode 100644 build/Helix/GenerateTestProjFile.ps1 create mode 100644 build/Helix/HelixTestHelpers.cs create mode 100644 build/Helix/InstallTestAppDependencies.ps1 create mode 100644 build/Helix/OutputFailedTestQuery.ps1 create mode 100644 build/Helix/OutputSubResultsJsonFiles.ps1 create mode 100644 build/Helix/OutputTestResults.ps1 create mode 100644 build/Helix/PrepareHelixPayload.ps1 create mode 100644 build/Helix/ProcessHelixFiles.ps1 create mode 100644 build/Helix/RunTestsInHelix.proj create mode 100644 build/Helix/UpdateUnreliableTests.ps1 create mode 100644 build/Helix/global.json create mode 100644 build/Helix/packages.config create mode 100644 build/Helix/readme.md create mode 100644 build/Helix/runtests.cmd create mode 100644 build/packages.config create mode 100644 build/pipelines/templates/helix-createprojfile-steps.yml create mode 100644 build/pipelines/templates/helix-processtestresults-job.yml create mode 100644 build/pipelines/templates/helix-runtests-job.yml create mode 100644 build/scripts/Get-WttLog.ps1 diff --git a/.github/actions/spell-check/dictionary/apis.txt b/.github/actions/spell-check/dictionary/apis.txt index 9dc4909592f..96d302a13c3 100644 --- a/.github/actions/spell-check/dictionary/apis.txt +++ b/.github/actions/spell-check/dictionary/apis.txt @@ -9,6 +9,7 @@ EXPCMDFLAGS EXPCMDSTATE fullkbd futex +Hashtable href IAsync IBind @@ -41,6 +42,7 @@ rfind roundf RSHIFT rx +serializer SIZENS spsc STDCPP @@ -48,3 +50,5 @@ syscall tmp tx userenv +XDocument +XElement diff --git a/.github/actions/spell-check/dictionary/microsoft.txt b/.github/actions/spell-check/dictionary/microsoft.txt index ef2c23c5ab6..0e94847f887 100644 --- a/.github/actions/spell-check/dictionary/microsoft.txt +++ b/.github/actions/spell-check/dictionary/microsoft.txt @@ -1,18 +1,37 @@ ACLs altform +appendwttlogging backplating DACL DACLs +dotnetfeed +DWINRT +enablewttlogging LKG mfcribbon microsoft microsoftonline +netcore osgvsowi +pgc +pgo +pgosweep powerrename powershell pscustomobject +robocopy SACLs +Shobjidl +Skype +sysnative +systemroot +taskkill +tasklist tdbuildteamid vcruntime visualstudio +wlk wslpath +wtl +wtt +wttlog diff --git a/.github/actions/spell-check/expect/af1ff90dc512c83c902762b02f284c1c61603b4a.txt b/.github/actions/spell-check/expect/af1ff90dc512c83c902762b02f284c1c61603b4a.txt deleted file mode 100644 index 66fb99de72d..00000000000 --- a/.github/actions/spell-check/expect/af1ff90dc512c83c902762b02f284c1c61603b4a.txt +++ /dev/null @@ -1,10 +0,0 @@ -abcd -dst -EFG -EFGh -EMPTYBOX -GFEh -nrcs -Remoting -Scs -Shobjidl diff --git a/.github/actions/spell-check/expect/alphabet.txt b/.github/actions/spell-check/expect/alphabet.txt index 6d395ae7a5d..2f3072f0177 100644 --- a/.github/actions/spell-check/expect/alphabet.txt +++ b/.github/actions/spell-check/expect/alphabet.txt @@ -1,3 +1,4 @@ +abcd abcde abcdef ABCDEFG @@ -10,6 +11,8 @@ abcdefghijklmnopqrstuvwxyz ABE BBGGRR BBBBBBBBBBBBBBDDDD +EFG +EFGh QQQQQQQQQQABCDEFGHIJ QQQQQQQQQQABCDEFGHIJKLMNOPQRSTQQQQQQQQQ QQQQQQQQQQABCDEFGHIJKLMNOPQRSTQQQQQQQQQQ diff --git a/.github/actions/spell-check/expect/expect.txt b/.github/actions/spell-check/expect/expect.txt index 9379acedf80..ba5e05b86ba 100644 --- a/.github/actions/spell-check/expect/expect.txt +++ b/.github/actions/spell-check/expect/expect.txt @@ -7,6 +7,7 @@ ABCDEFGHIJKLMNO ABCG abf abi +ACCESSTOKEN acec acf acidev @@ -23,6 +24,7 @@ addressof ADDSTRING ADDTOOL AEnd +aef AFew AFill AFX @@ -71,6 +73,7 @@ apps APPWINDOW appx appxbundle +appxerror appxmanifest APrep apsect @@ -188,6 +191,7 @@ buffersize buflen bugfix buildtransitive +BUILDURI burriter BValue byref @@ -293,6 +297,7 @@ codepage codepoint codeproject COINIT +COLLECTIONURI colorizing colororacle colorref @@ -507,6 +512,7 @@ dealloc debian debolden debounce +debugbreak DECALN DECANM DECAUPSS @@ -594,6 +600,7 @@ df DFactory DFMT dh +dhandler dialogbox diffing DINLINE @@ -616,6 +623,8 @@ dllmain DLLVERSIONINFO DLOAD DLOOK +dmp +dnceng DOCTYPE docx DONTCARE @@ -638,6 +647,7 @@ DROPDOWNLIST DROPFILES drv dsm +dst DSwap DTest dtor @@ -680,6 +690,7 @@ Elems elif elseif emacs +EMPTYBOX enabledelayedexpansion endian endif @@ -703,6 +714,7 @@ errno errorlevel esa ETB +etcoreapp ETW ETX EUDC @@ -885,6 +897,7 @@ GETWHEELSCROLLCHARACTERS GETWHEELSCROLLCHARS GETWHEELSCROLLLINES getwriter +GFEh Gfun gfx gh @@ -1150,6 +1163,7 @@ iwch IWin IWindow IXaml +IXMP jconcpp JOBOBJECT JOBOBJECTINFOCLASS @@ -1232,6 +1246,7 @@ linputfile Linq linux listbox +listproperties listptr listptrsize lk @@ -1252,6 +1267,7 @@ locstudio Loewen LOGFONT LOGFONTW +logissue Loremipsumdolorsitamet lowercased loword @@ -1376,6 +1392,7 @@ mimetype mincore mindbogglingly mingw +minimizeall minkernel minwin minwindef @@ -1537,6 +1554,7 @@ NOYIELD NOZORDER NPM npos +nrcs NSTATUS ntapi ntcon @@ -1779,6 +1797,7 @@ prect prefast prefilled prefs +preinstalled PRELOAD PREMULTIPLIED prepopulated @@ -1924,6 +1943,7 @@ REGSTR reingest Relayout RELBINPATH +Remoting renderengine rendersize reparent @@ -1939,6 +1959,7 @@ resheader resizable resmimetype restrictedcapabilities +restrictederrorinfo resw resx retval @@ -1979,6 +2000,7 @@ roundtrip rparen RRF RRRGGGBB +rsas rtcore RTEXT rtf @@ -1995,6 +2017,7 @@ runformat runft RUNFULLSCREEN runsettings +runtests runtimeclass runuia runut @@ -2037,6 +2060,7 @@ SCROLLSCALE SCROLLSCREENBUFFER Scrollup Scrolluppage +Scs scursor sddl sdeleted @@ -2142,6 +2166,7 @@ SND SOLIDBOX Solutiondir somefile +SOURCEBRANCH sourced SOURCESDIRECTORY SPACEBAR @@ -2215,6 +2240,7 @@ subspan substr subsystemconsole subsystemwindows +suiteless svg swapchain swapchainpanel @@ -2266,6 +2292,7 @@ tcommandline tcommands tcon TDP +TEAMPROJECT tearoff Teb techcommunity @@ -2280,6 +2307,7 @@ TERMINALSCROLLING terminfo TEs testapp +testbuildplatform testcon testd testdlls @@ -2288,11 +2316,15 @@ testlab testlist testmd testmddefinition +testmode +testname +testnameprefix TESTNULL testpass testpasses testtestabc testtesttesttesttest +testtimeout TEXCOORD texel TExpected @@ -2449,6 +2481,7 @@ unpause Unregister Unregistering unte +untests untextured untimes UPDATEDISPLAY @@ -2682,6 +2715,7 @@ WNull workarea workaround workflow +workitem wostream WOutside WOWARM @@ -2770,6 +2804,7 @@ XSubstantial xtended xterm XTest +xunit xutr xvalue XVIRTUALSCREEN diff --git a/NuGet.Config b/NuGet.Config index 00b1de60c4f..e5cb393dc59 100644 --- a/NuGet.Config +++ b/NuGet.Config @@ -9,6 +9,11 @@ + + + + + + + + \ No newline at end of file diff --git a/build/Helix/UpdateUnreliableTests.ps1 b/build/Helix/UpdateUnreliableTests.ps1 new file mode 100644 index 00000000000..06af44f6950 --- /dev/null +++ b/build/Helix/UpdateUnreliableTests.ps1 @@ -0,0 +1,135 @@ +[CmdLetBinding()] +Param( + [Parameter(Mandatory = $true)] + [int]$RerunPassesRequiredToAvoidFailure, + + [string]$AccessToken = $env:SYSTEM_ACCESSTOKEN, + [string]$CollectionUri = $env:SYSTEM_COLLECTIONURI, + [string]$TeamProject = $env:SYSTEM_TEAMPROJECT, + [string]$BuildUri = $env:BUILD_BUILDURI +) + +. "$PSScriptRoot/AzurePipelinesHelperScripts.ps1" + + +$azureDevOpsRestApiHeaders = @{ + "Accept"="application/json" + "Authorization"="Basic $([System.Convert]::ToBase64String([System.Text.ASCIIEncoding]::ASCII.GetBytes(":$AccessToken")))" +} + +$queryUri = GetQueryTestRunsUri -CollectionUri $CollectionUri -TeamProject $TeamProject -BuildUri $BuildUri +Write-Host "queryUri = $queryUri" + +# To account for unreliable tests, we'll iterate through all of the tests associated with this build, check to see any tests that were unreliable +# (denoted by being marked as "skipped"), and if so, we'll instead mark those tests with a warning and enumerate all of the attempted runs +# with their pass/fail states as well as any relevant error messages for failed attempts. +$testRuns = Invoke-RestMethod -Uri $queryUri -Method Get -Headers $azureDevOpsRestApiHeaders + +$timesSeenByRunName = @{} + +foreach ($testRun in $testRuns.value) +{ + $testRunResultsUri = "$($testRun.url)/results?api-version=5.0" + + Write-Host "Marking test run `"$($testRun.name)`" as in progress so we can change its results to account for unreliable tests." + Invoke-RestMethod -Uri "$($testRun.url)?api-version=5.0" -Method Patch -Body (ConvertTo-Json @{ "state" = "InProgress" }) -Headers $azureDevOpsRestApiHeaders -ContentType "application/json" | Out-Null + + Write-Host "Retrieving test results..." + $testResults = Invoke-RestMethod -Uri $testRunResultsUri -Method Get -Headers $azureDevOpsRestApiHeaders + + foreach ($testResult in $testResults.value) + { + $testNeedsSubResultProcessing = $false + if ($testResult.outcome -eq "NotExecuted") + { + $testNeedsSubResultProcessing = $true + } + elseif($testResult.outcome -eq "Failed") + { + $testNeedsSubResultProcessing = $testResult.errorMessage -like "*_subresults.json*" + } + + if ($testNeedsSubResultProcessing) + { + Write-Host " Test $($testResult.testCaseTitle) was detected as unreliable. Updating..." + + # The errorMessage field contains a link to the JSON-encoded rerun result data. + $rerunResults = ConvertFrom-Json (New-Object System.Net.WebClient).DownloadString($testResult.errorMessage) + [System.Collections.Generic.List[System.Collections.Hashtable]]$rerunDataList = @() + $attemptCount = 0 + $passCount = 0 + $totalDuration = 0 + + foreach ($rerun in $rerunResults.results) + { + $rerunData = @{ + "displayName" = "Attempt #$($attemptCount + 1) - $($testResult.testCaseTitle)"; + "durationInMs" = $rerun.duration; + "outcome" = $rerun.outcome; + } + + if ($rerun.outcome -eq "Passed") + { + $passCount++ + } + + if ($attemptCount -gt 0) + { + $rerunData["sequenceId"] = $attemptCount + } + + Write-Host " Attempt #$($attemptCount + 1): $($rerun.outcome)" + + if ($rerun.outcome -ne "Passed") + { + $screenshots = "$($rerunResults.blobPrefix)/$($rerun.screenshots -join @" +$($rerunResults.blobSuffix) +$($rerunResults.blobPrefix) +"@)$($rerunResults.blobSuffix)" + + # We subtract 1 from the error index because we added 1 so we could use 0 + # as a default value not injected into the JSON in order to keep its size down. + # We did this because there's a maximum size enforced for the errorMessage parameter + # in the Azure DevOps REST API. + $fullErrorMessage = @" +Log: $($rerunResults.blobPrefix)/$($rerun.log)$($rerunResults.blobSuffix) + +Screenshots: +$screenshots + +Error log: +$($rerunResults.errors[$rerun.errorIndex - 1]) +"@ + + $rerunData["errorMessage"] = $fullErrorMessage + } + + $attemptCount++ + $totalDuration += $rerun.duration + $rerunDataList.Add($rerunData) + } + + $overallOutcome = "Warning" + + if ($attemptCount -eq 2) + { + Write-Host " Test $($testResult.testCaseTitle) passed on the immediate rerun, so we'll mark it as unreliable." + } + elseif ($passCount -gt $RerunPassesRequiredToAvoidFailure) + { + Write-Host " Test $($testResult.testCaseTitle) passed on $passCount of $attemptCount attempts, which is greater than or equal to the $RerunPassesRequiredToAvoidFailure passes required to avoid being marked as failed. Marking as unreliable." + } + else + { + Write-Host " Test $($testResult.testCaseTitle) passed on only $passCount of $attemptCount attempts, which is less than the $RerunPassesRequiredToAvoidFailure passes required to avoid being marked as failed. Marking as failed." + $overallOutcome = "Failed" + } + + $updateBody = ConvertTo-Json @(@{ "id" = $testResult.id; "outcome" = $overallOutcome; "errorMessage" = " "; "durationInMs" = $totalDuration; "subResults" = $rerunDataList; "resultGroupType" = "rerun" }) -Depth 5 + Invoke-RestMethod -Uri $testRunResultsUri -Method Patch -Headers $azureDevOpsRestApiHeaders -Body $updateBody -ContentType "application/json" | Out-Null + } + } + + Write-Host "Finished updates. Re-marking test run `"$($testRun.name)`" as completed." + Invoke-RestMethod -Uri "$($testRun.url)?api-version=5.0" -Method Patch -Body (ConvertTo-Json @{ "state" = "Completed" }) -Headers $azureDevOpsRestApiHeaders -ContentType "application/json" | Out-Null +} diff --git a/build/Helix/global.json b/build/Helix/global.json new file mode 100644 index 00000000000..cec97c1d235 --- /dev/null +++ b/build/Helix/global.json @@ -0,0 +1,5 @@ +{ + "msbuild-sdks": { + "Microsoft.DotNet.Helix.Sdk": "5.0.0-beta.20277.5" + } +} diff --git a/build/Helix/packages.config b/build/Helix/packages.config new file mode 100644 index 00000000000..9d5e0fdc3a9 --- /dev/null +++ b/build/Helix/packages.config @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/build/Helix/readme.md b/build/Helix/readme.md new file mode 100644 index 00000000000..d51fc973c1e --- /dev/null +++ b/build/Helix/readme.md @@ -0,0 +1,32 @@ +This directory contains code and configuration files to run WinUI tests in Helix. + +Helix is a cloud hosted test execution environment which is accessed via the Arcade SDK. +More details: +* [Arcade](https://github.com/dotnet/arcade) +* [Helix](https://github.com/dotnet/arcade/tree/master/src/Microsoft.DotNet.Helix/Sdk) + +WinUI tests are scheduled in Helix by the Azure DevOps Pipeline: [RunHelixTests.yml](../RunHelixTests.yml). + +The workflow is as follows: +1. NuGet Restore is called on the packages.config in this directory. This downloads any runtime dependencies +that are needed to run tests. +2. PrepareHelixPayload.ps1 is called. This copies the necessary files from various locations into a Helix +payload directory. This directory is what will get sent to the Helix machines. +3. RunTestsInHelix.proj is executed. This proj has a dependency on +[Microsoft.DotNet.Helix.Sdk](https://github.com/dotnet/arcade/tree/master/src/Microsoft.DotNet.Helix/Sdk) +which it uses to publish the Helix payload directory and to schedule the Helix Work Items. The WinUI tests +are parallelized into multiple Helix Work Items. +4. Each Helix Work Item calls [runtests.cmd](runtests.cmd) with a specific query to pass to +[TAEF](https://docs.microsoft.com/en-us/windows-hardware/drivers/taef/) which runs the tests. +5. If a test is detected to have failed, we run it again, first once, then eight more times if it fails again. +If it fails all ten times, we report the test as failed; otherwise, we report it as unreliable, +which will show up as a warning, but which will not fail the build. When a test is reported as unreliable, +we include the results for each individual run via a JSON string in the original test's errorMessage field. +6. TAEF produces logs in WTT format. Helix is able to process logs in XUnit format. We run +[ConvertWttLogToXUnit.ps1](ConvertWttLogToXUnit.ps1) to convert the logs into the necessary format. +7. RunTestsInHelix.proj has EnableAzurePipelinesReporter set to true. This allows the XUnit formatted test +results to be reported back to the Azure DevOps Pipeline. +8. We process unreliable tests once all tests have been reported by reading the JSON string from the +errorMessage field and calling the Azure DevOps REST API to modify the unreliable tests to have sub-results +added to the test and to mark the test as "warning", which will enable people to see exactly how the test +failed in runs where it did. \ No newline at end of file diff --git a/build/Helix/runtests.cmd b/build/Helix/runtests.cmd new file mode 100644 index 00000000000..ddf8c2d3d11 --- /dev/null +++ b/build/Helix/runtests.cmd @@ -0,0 +1,106 @@ +setlocal ENABLEDELAYEDEXPANSION + +echo %TIME% + +robocopy %HELIX_CORRELATION_PAYLOAD% . /s /NP > NUL + +echo %TIME% + +reg add HKLM\Software\Policies\Microsoft\Windows\Appx /v AllowAllTrustedApps /t REG_DWORD /d 1 /f + +rem enable dump collection for our test apps: +rem note, this script is run from a 32-bit cmd, but we need to set the native reg-key +FOR %%A IN (TestHostApp.exe,te.exe,te.processhost.exe,conhost.exe,OpenConsole.exe,WindowsTerminal.exe) DO ( + %systemroot%\sysnative\cmd.exe /c reg add "HKLM\Software\Microsoft\Windows\Windows Error Reporting\LocalDumps\%%A" /v DumpFolder /t REG_EXPAND_SZ /d %HELIX_DUMP_FOLDER% /f + %systemroot%\sysnative\cmd.exe /c reg add "HKLM\Software\Microsoft\Windows\Windows Error Reporting\LocalDumps\%%A" /v DumpType /t REG_DWORD /d 2 /f + %systemroot%\sysnative\cmd.exe /c reg add "HKLM\Software\Microsoft\Windows\Windows Error Reporting\LocalDumps\%%A" /v DumpCount /t REG_DWORD /d 10 /f +) + +echo %TIME% + +:: kill dhandler, which is a tool designed to handle unexpected windows appearing. But since our tests are +:: expected to show UI we don't want it running. +taskkill -f -im dhandler.exe + +echo %TIME% +powershell -ExecutionPolicy Bypass .\EnsureMachineState.ps1 +echo %TIME% +powershell -ExecutionPolicy Bypass .\InstallTestAppDependencies.ps1 +echo %TIME% + +set testBinaryCandidates=TerminalApp.LocalTests.dll Conhost.UIA.Tests.dll +set testBinaries= +for %%B in (%testBinaryCandidates%) do ( + if exist %%B ( + set "testBinaries=!testBinaries! %%B" + ) +) + +echo %TIME% +te.exe %testBinaries% /enablewttlogging /unicodeOutput:false /sessionTimeout:0:15 /testtimeout:0:10 /screenCaptureOnError %* +echo %TIME% + +powershell -ExecutionPolicy Bypass Get-Process + +move te.wtl te_original.wtl + +copy /y te_original.wtl %HELIX_WORKITEM_UPLOAD_ROOT% +copy /y WexLogFileOutput\*.jpg %HELIX_WORKITEM_UPLOAD_ROOT% +for /f "tokens=* delims=" %%a in ('dir /b *.pgc') do ren "%%a" "%testnameprefix%.%%~na.pgc" +copy /y *.pgc %HELIX_WORKITEM_UPLOAD_ROOT% + +set FailedTestQuery= +for /F "tokens=* usebackq" %%I IN (`powershell -ExecutionPolicy Bypass .\OutputFailedTestQuery.ps1 te_original.wtl`) DO ( + set FailedTestQuery=%%I +) + +rem The first time, we'll just re-run failed tests once. In many cases, tests fail very rarely, such that +rem a single re-run will be sufficient to detect many unreliable tests. +if "%FailedTestQuery%" == "" goto :SkipReruns + +echo %TIME% +te.exe %testBinaries% /enablewttlogging /unicodeOutput:false /sessionTimeout:0:15 /testtimeout:0:10 /screenCaptureOnError /select:"%FailedTestQuery%" +echo %TIME% + +move te.wtl te_rerun.wtl + +copy /y te_rerun.wtl %HELIX_WORKITEM_UPLOAD_ROOT% +copy /y WexLogFileOutput\*.jpg %HELIX_WORKITEM_UPLOAD_ROOT% + +rem If there are still failing tests remaining, we'll run them eight more times, so they'll have been run a total of ten times. +rem If any tests fail all ten times, we can be pretty confident that these are actual test failures rather than unreliable tests. +if not exist te_rerun.wtl goto :SkipReruns + +set FailedTestQuery= +for /F "tokens=* usebackq" %%I IN (`powershell -ExecutionPolicy Bypass .\OutputFailedTestQuery.ps1 te_rerun.wtl`) DO ( + set FailedTestQuery=%%I +) + +if "%FailedTestQuery%" == "" goto :SkipReruns + +echo %TIME% +te.exe %testBinaries% /enablewttlogging /unicodeOutput:false /sessionTimeout:0:15 /testtimeout:0:10 /screenCaptureOnError /testmode:Loop /LoopTest:8 /select:"%FailedTestQuery%" +echo %TIME% + +powershell -ExecutionPolicy Bypass Get-Process + +move te.wtl te_rerun_multiple.wtl + +copy /y te_rerun_multiple.wtl %HELIX_WORKITEM_UPLOAD_ROOT% +copy /y WexLogFileOutput\*.jpg %HELIX_WORKITEM_UPLOAD_ROOT% +powershell -ExecutionPolicy Bypass .\CopyVisualTreeVerificationFiles.ps1 + +:SkipReruns + +powershell -ExecutionPolicy Bypass Get-Process + +echo %TIME% +powershell -ExecutionPolicy Bypass .\OutputSubResultsJsonFiles.ps1 te_original.wtl te_rerun.wtl te_rerun_multiple.wtl %testnameprefix% +powershell -ExecutionPolicy Bypass .\ConvertWttLogToXUnit.ps1 te_original.wtl te_rerun.wtl te_rerun_multiple.wtl testResults.xml %testnameprefix% +echo %TIME% + +copy /y *_subresults.json %HELIX_WORKITEM_UPLOAD_ROOT% + +type testResults.xml + +echo %TIME% \ No newline at end of file diff --git a/build/packages.config b/build/packages.config new file mode 100644 index 00000000000..11c8417e608 --- /dev/null +++ b/build/packages.config @@ -0,0 +1,5 @@ + + + + + diff --git a/build/pipelines/templates/build-console-ci.yml b/build/pipelines/templates/build-console-ci.yml index 34c8d09add7..b60c8237489 100644 --- a/build/pipelines/templates/build-console-ci.yml +++ b/build/pipelines/templates/build-console-ci.yml @@ -2,6 +2,8 @@ parameters: configuration: 'Release' platform: '' additionalBuildArguments: '' + minimumExpectedTestsExecutedCount: 10 # Sanity check for minimum expected tests to be reported + rerunPassesRequiredToAvoidFailure: 5 jobs: - job: Build${{ parameters.platform }}${{ parameters.configuration }} @@ -15,3 +17,19 @@ jobs: - template: build-console-steps.yml parameters: additionalBuildArguments: ${{ parameters.additionalBuildArguments }} + +- template: helix-runtests-job.yml + parameters: + name: 'RunTestsInHelix' + dependsOn: Build${{ parameters.platform }}${{ parameters.configuration }} + condition: and(succeeded(), and(eq('${{ parameters.platform }}', 'x64'), not(eq(variables['Build.Reason'], 'PullRequest')))) + testSuite: 'DevTestSuite' + rerunPassesRequiredToAvoidFailure: ${{ parameters.rerunPassesRequiredToAvoidFailure }} + +- template: helix-processtestresults-job.yml + parameters: + dependsOn: + - RunTestsInHelix + condition: and(succeeded(), and(eq('${{ parameters.platform }}', 'x64'), not(eq(variables['Build.Reason'], 'PullRequest')))) + rerunPassesRequiredToAvoidFailure: ${{ parameters.rerunPassesRequiredToAvoidFailure }} + minimumExpectedTestsExecutedCount: ${{ parameters.minimumExpectedTestsExecutedCount }} \ No newline at end of file diff --git a/build/pipelines/templates/build-console-steps.yml b/build/pipelines/templates/build-console-steps.yml index a1bb9df128e..8342d1314ce 100644 --- a/build/pipelines/templates/build-console-steps.yml +++ b/build/pipelines/templates/build-console-steps.yml @@ -1,5 +1,6 @@ parameters: additionalBuildArguments: '' + testLogPath: '$(Build.BinariesDirectory)\$(BuildPlatform)\$(BuildConfiguration)\testsOnBuildMachine.wtl' steps: - checkout: self @@ -7,23 +8,29 @@ steps: clean: true - task: NuGetToolInstaller@0 - displayName: Ensure NuGet 4.8.1 + displayName: 'Use NuGet 5.2.0' inputs: - versionSpec: 4.8.1 - -- task: VisualStudioTestPlatformInstaller@1 - displayName: Ensure VSTest Platform + versionSpec: 5.2.0 # In the Microsoft Azure DevOps tenant, NuGetCommand is ambiguous. # This should be `task: NuGetCommand@2` - task: 333b11bd-d341-40d9-afcf-b32d5ce6f23b@2 - displayName: Restore NuGet packages + displayName: Restore NuGet packages for solution inputs: command: restore feedsToUse: config configPath: NuGet.config restoreSolution: OpenConsole.sln restoreDirectory: '$(Build.SourcesDirectory)\packages' + +- task: 333b11bd-d341-40d9-afcf-b32d5ce6f23b@2 + displayName: Restore NuGet packages for extraneous build actions + inputs: + command: restore + feedsToUse: config + configPath: NuGet.config + restoreSolution: build/packages.config + restoreDirectory: '$(Build.SourcesDirectory)\packages' - task: VSBuild@1 displayName: 'Build solution **\OpenConsole.sln' @@ -66,7 +73,7 @@ steps: inputs: targetType: filePath filePath: build\scripts\Run-Tests.ps1 - arguments: -MatchPattern '*unit.test*.dll' -Platform '$(RationalizedBuildPlatform)' -Configuration '$(BuildConfiguration)' + arguments: -MatchPattern '*unit.test*.dll' -Platform '$(RationalizedBuildPlatform)' -Configuration '$(BuildConfiguration)' -LogPath '${{ parameters.testLogPath }}' condition: and(succeeded(), or(eq(variables['BuildPlatform'], 'x64'), eq(variables['BuildPlatform'], 'x86'))) - task: PowerShell@2 @@ -74,9 +81,41 @@ steps: inputs: targetType: filePath filePath: build\scripts\Run-Tests.ps1 - arguments: -MatchPattern '*feature.test*.dll' -Platform '$(RationalizedBuildPlatform)' -Configuration '$(BuildConfiguration)' + arguments: -MatchPattern '*feature.test*.dll' -Platform '$(RationalizedBuildPlatform)' -Configuration '$(BuildConfiguration)' -LogPath '${{ parameters.testLogPath }}' condition: and(succeeded(), eq(variables['BuildPlatform'], 'x64')) +- task: PowerShell@2 + displayName: 'Convert Test Logs from WTL to xUnit format' + inputs: + targetType: filePath + filePath: build\Helix\ConvertWttLogToXUnit.ps1 + arguments: -WttInputPath '${{ parameters.testLogPath }}' -WttSingleRerunInputPath 'unused.wtl' -WttMultipleRerunInputPath 'unused2.wtl' -XUnitOutputPath 'onBuildMachineResults.xml' -TestNamePrefix '$(BuildConfiguration).$(BuildPlatform)' + condition: or(eq(variables['BuildPlatform'], 'x64'), eq(variables['BuildPlatform'], 'x86')) + +- task: PublishTestResults@2 + displayName: 'Upload converted test logs' + inputs: + testResultsFormat: 'xUnit' # Options: JUnit, NUnit, VSTest, xUnit, cTest + testResultsFiles: '**/onBuildMachineResults.xml' + #searchFolder: '$(System.DefaultWorkingDirectory)' # Optional + #mergeTestResults: false # Optional + #failTaskOnFailedTests: false # Optional + testRunTitle: 'On Build Machine Tests' # Optional + buildPlatform: $(BuildPlatform) # Optional + buildConfiguration: $(BuildConfiguration) # Optional + #publishRunAttachments: true # Optional + +- task: CopyFiles@2 + displayName: 'Copy result logs to Artifacts' + inputs: + Contents: | + **/*.wtl + **/*onBuildMachineResults.xml + ${{ parameters.testLogPath }} + TargetFolder: '$(Build.ArtifactStagingDirectory)/$(BuildConfiguration)/$(BuildPlatform)/test' + OverWrite: true + flattenFolders: true + - task: CopyFiles@2 displayName: 'Copy *.appx/*.msix to Artifacts (Non-PR builds only)' inputs: @@ -90,9 +129,22 @@ steps: flattenFolders: true condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest')) +- task: CopyFiles@2 + displayName: 'Copy outputs needed for test runs to Artifacts' + inputs: + Contents: | + $(Build.SourcesDirectory)/bin/$(BuildPlatform)/$(BuildConfiguration)/*.exe + $(Build.SourcesDirectory)/bin/$(BuildPlatform)/$(BuildConfiguration)/*.dll + $(Build.SourcesDirectory)/bin/$(BuildPlatform)/$(BuildConfiguration)/*.xml + **/Microsoft.VCLibs.*.appx + **/TestHostApp/* + TargetFolder: '$(Build.ArtifactStagingDirectory)/$(BuildConfiguration)/$(BuildPlatform)/test' + OverWrite: true + flattenFolders: true + condition: and(and(succeeded(), eq(variables['BuildPlatform'], 'x64')), ne(variables['Build.Reason'], 'PullRequest')) + - task: PublishBuildArtifacts@1 - displayName: 'Publish Artifact (appx) (Non-PR builds only)' + displayName: 'Publish All Build Artifacts' inputs: - PathtoPublish: '$(Build.ArtifactStagingDirectory)/appx' - ArtifactName: 'appx-$(BuildConfiguration)' - condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest')) + PathtoPublish: '$(Build.ArtifactStagingDirectory)' + ArtifactName: 'drop' \ No newline at end of file diff --git a/build/pipelines/templates/helix-createprojfile-steps.yml b/build/pipelines/templates/helix-createprojfile-steps.yml new file mode 100644 index 00000000000..89818ae8e95 --- /dev/null +++ b/build/pipelines/templates/helix-createprojfile-steps.yml @@ -0,0 +1,15 @@ +parameters: + condition: '' + testFilePath: '' + outputProjFileName: '' + testSuite: '' + taefQuery: '' + +steps: + - task: powershell@2 + displayName: 'Create ${{ parameters.outputProjFileName }}' + condition: ${{ parameters.condition }} + inputs: + targetType: filePath + filePath: build\Helix\GenerateTestProjFile.ps1 + arguments: -TestFile '${{ parameters.testFilePath }}' -OutputProjFile '$(Build.ArtifactStagingDirectory)\${{ parameters.outputProjFileName }}' -JobTestSuiteName '${{ parameters.testSuite }}' -TaefPath '$(Build.SourcesDirectory)\build\Helix\packages\taef.redist.wlk.10.57.200731005-develop\build\Binaries\x86' -TaefQuery '${{ parameters.taefQuery }}' \ No newline at end of file diff --git a/build/pipelines/templates/helix-processtestresults-job.yml b/build/pipelines/templates/helix-processtestresults-job.yml new file mode 100644 index 00000000000..f1c18db4fde --- /dev/null +++ b/build/pipelines/templates/helix-processtestresults-job.yml @@ -0,0 +1,67 @@ +parameters: + dependsOn: '' + rerunPassesRequiredToAvoidFailure: 5 + minimumExpectedTestsExecutedCount: 10 + checkJobAttempt: false + pgoArtifact: '' + +jobs: +- job: ProcessTestResults + condition: succeededOrFailed() + dependsOn: ${{ parameters.dependsOn }} + pool: + vmImage: 'windows-2019' + timeoutInMinutes: 120 + variables: + helixOutputFolder: $(Build.SourcesDirectory)\HelixOutput + + steps: + - task: powershell@2 + displayName: 'UpdateUnreliableTests.ps1' + condition: succeededOrFailed() + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + inputs: + targetType: filePath + filePath: build\Helix\UpdateUnreliableTests.ps1 + arguments: -RerunPassesRequiredToAvoidFailure '${{ parameters.rerunPassesRequiredToAvoidFailure }}' + + - task: powershell@2 + displayName: 'OutputTestResults.ps1' + condition: succeededOrFailed() + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + inputs: + targetType: filePath + filePath: build\Helix\OutputTestResults.ps1 + arguments: -MinimumExpectedTestsExecutedCount '${{ parameters.minimumExpectedTestsExecutedCount }}' -CheckJobAttempt $${{ parameters.checkJobAttempt }} + + - task: powershell@2 + displayName: 'ProcessHelixFiles.ps1' + condition: succeededOrFailed() + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + HelixAccessToken: $(HelixApiAccessToken) + inputs: + targetType: filePath + filePath: build\Helix\ProcessHelixFiles.ps1 + arguments: -OutputFolder '$(helixOutputFolder)' + + - ${{if ne(parameters.pgoArtifact, '') }}: + - script: move /y $(helixOutputFolder)\PGO $(Build.ArtifactStagingDirectory) + displayName: 'Move pgc files to PGO artifact' + + - task: PublishBuildArtifacts@1 + displayName: 'Publish Helix files' + condition: succeededOrFailed() + inputs: + PathtoPublish: $(helixOutputFolder) + artifactName: drop + + - ${{if ne(parameters.pgoArtifact, '') }}: + - task: PublishBuildArtifacts@1 + displayName: 'Publish pgc files' + condition: succeededOrFailed() + inputs: + PathtoPublish: $(Build.ArtifactStagingDirectory)\PGO\Release + artifactName: ${{ parameters.pgoArtifact }} diff --git a/build/pipelines/templates/helix-runtests-job.yml b/build/pipelines/templates/helix-runtests-job.yml new file mode 100644 index 00000000000..81125f3d988 --- /dev/null +++ b/build/pipelines/templates/helix-runtests-job.yml @@ -0,0 +1,131 @@ +parameters: + name: 'RunTestsInHelix' + dependsOn: '' + condition: '' + testSuite: '' + # If a Pipeline runs this template more than once, this parameter should be unique per build flavor to differentiate the + # the different test runs: + helixType: 'test/devtest' + artifactName: 'drop' + maxParallel: 4 + rerunPassesRequiredToAvoidFailure: 5 + taefQuery: '' + # if 'useBuildOutputFromBuildId' is set, we will default to using a build from this pipeline: + useBuildOutputFromPipeline: $(System.DefinitionId) + matrix: + # Release_x86: + # buildPlatform: 'x86' + # buildConfiguration: 'release' + # openHelixTargetQueues: 'windows.10.amd64.client19h1.open.xaml' + # closedHelixTargetQueues: 'windows.10.amd64.client19h1.xaml' + Release_x64: + buildPlatform: 'x64' + buildConfiguration: 'release' + openHelixTargetQueues: 'windows.10.amd64.client19h1.open.xaml' + closedHelixTargetQueues: 'windows.10.amd64.client19h1.xaml' + +jobs: +- job: ${{ parameters.name }} + dependsOn: ${{ parameters.dependsOn }} + condition: ${{ parameters.condition }} + pool: + vmImage: 'windows-2019' + timeoutInMinutes: 120 + strategy: + maxParallel: ${{ parameters.maxParallel }} + matrix: ${{ parameters.matrix }} + variables: + artifactsDir: $(Build.SourcesDirectory)\Artifacts + taefPath: $(Build.SourcesDirectory)\build\Helix\packages\taef.redist.wlk.10.57.200731005-develop\build\Binaries\$(buildPlatform) + helixCommonArgs: '/binaryLogger:$(Build.SourcesDirectory)/${{parameters.name}}.$(buildPlatform).$(buildConfiguration).binlog /p:HelixBuild=$(Build.BuildId).$(buildPlatform).$(buildConfiguration) /p:Platform=$(buildPlatform) /p:Configuration=$(buildConfiguration) /p:HelixType=${{parameters.helixType}} /p:TestSuite=${{parameters.testSuite}} /p:ProjFilesPath=$(Build.ArtifactStagingDirectory) /p:rerunPassesRequiredToAvoidFailure=${{parameters.rerunPassesRequiredToAvoidFailure}}' + + + steps: + - task: CmdLine@1 + displayName: 'Display build machine environment variables' + inputs: + filename: 'set' + + - task: NuGetToolInstaller@0 + displayName: 'Use NuGet 5.2.0' + inputs: + versionSpec: 5.2.0 + + - task: 333b11bd-d341-40d9-afcf-b32d5ce6f23b@2 + displayName: 'NuGet restore build/Helix/packages.config' + inputs: + restoreSolution: build/Helix/packages.config + feedsToUse: config + nugetConfigPath: nuget.config + restoreDirectory: packages + + - task: DownloadBuildArtifacts@0 + condition: + and(succeeded(),eq(variables['useBuildOutputFromBuildId'],'')) + inputs: + artifactName: ${{ parameters.artifactName }} + downloadPath: '$(artifactsDir)' + + - task: DownloadBuildArtifacts@0 + condition: + and(succeeded(),ne(variables['useBuildOutputFromBuildId'],'')) + inputs: + buildType: specific + buildVersionToDownload: specific + project: $(System.TeamProjectId) + pipeline: ${{ parameters.useBuildOutputFromPipeline }} + buildId: $(useBuildOutputFromBuildId) + artifactName: ${{ parameters.artifactName }} + downloadPath: '$(artifactsDir)' + + - task: CmdLine@1 + displayName: 'Display Artifact Directory payload contents' + inputs: + filename: 'dir' + arguments: '/s $(artifactsDir)' + + - task: powershell@2 + displayName: 'PrepareHelixPayload.ps1' + inputs: + targetType: filePath + filePath: build\Helix\PrepareHelixPayload.ps1 + arguments: -Platform '$(buildPlatform)' -Configuration '$(buildConfiguration)' -ArtifactName '${{ parameters.artifactName }}' + + - task: CmdLine@1 + displayName: 'Display Helix payload contents' + inputs: + filename: 'dir' + arguments: '/s $(Build.SourcesDirectory)\HelixPayload' + + - template: helix-createprojfile-steps.yml + parameters: + condition: and(succeeded(),ne('${{ parameters.testSuite }}','NugetTestSuite')) + testFilePath: '$(artifactsDir)\${{ parameters.artifactName }}\$(buildConfiguration)\$(buildPlatform)\Test\TerminalApp.LocalTests.dll' + outputProjFileName: 'RunTestsInHelix-TerminalAppLocalTests.proj' + testSuite: '${{ parameters.testSuite }}' + taefQuery: ${{ parameters.taefQuery }} + + - template: helix-createprojfile-steps.yml + parameters: + condition: and(succeeded(),ne('${{ parameters.testSuite }}','NugetTestSuite')) + testFilePath: '$(artifactsDir)\${{ parameters.artifactName }}\$(buildConfiguration)\$(buildPlatform)\Test\Conhost.UIA.Tests.dll' + outputProjFileName: 'RunTestsInHelix-HostTestsUIA.proj' + testSuite: '${{ parameters.testSuite }}' + taefQuery: ${{ parameters.taefQuery }} + + - task: PublishBuildArtifacts@1 + displayName: 'Publish generated .proj files' + inputs: + PathtoPublish: $(Build.ArtifactStagingDirectory) + artifactName: ${{ parameters.artifactName }} + + - task: DotNetCoreCLI@2 + displayName: 'Run tests in Helix (open queues)' + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + inputs: + command: custom + projects: build\Helix\RunTestsInHelix.proj + custom: msbuild + arguments: '$(helixCommonArgs) /p:IsExternal=true /p:Creator=Terminal /p:HelixTargetQueues=$(openHelixTargetQueues)' + diff --git a/build/scripts/Get-WttLog.ps1 b/build/scripts/Get-WttLog.ps1 new file mode 100644 index 00000000000..46aab2f12aa --- /dev/null +++ b/build/scripts/Get-WttLog.ps1 @@ -0,0 +1,15 @@ +[CmdLetBinding()] +Param( + [Parameter(Mandatory=$true, Position=0)][string]$BuildPlatform, + [Parameter(Mandatory=$true, Position=1)][string]$RationalizedPlatform, + [Parameter(Mandatory=$true, Position=2)][string]$Configuration +) + + +$i = Get-Item .\packages\MuxCustomBuild* +$wtt = Join-Path -Path $i[0].FullName -ChildPath (Join-Path -Path 'tools' -ChildPath (Join-Path -Path $BuildPlatform -ChildPath 'wttlog.dll')) +$dest = Join-Path -Path .\bin -ChildPath (Join-Path -Path $RationalizedPlatform -ChildPath ($Configuration)) +copy $wtt $dest + + +Exit 0 diff --git a/build/scripts/Run-Tests.ps1 b/build/scripts/Run-Tests.ps1 index 28c9b5bd95f..377577a36c1 100644 --- a/build/scripts/Run-Tests.ps1 +++ b/build/scripts/Run-Tests.ps1 @@ -2,12 +2,24 @@ Param( [Parameter(Mandatory=$true, Position=0)][string]$MatchPattern, [Parameter(Mandatory=$true, Position=1)][string]$Platform, - [Parameter(Mandatory=$true, Position=2)][string]$Configuration + [Parameter(Mandatory=$true, Position=2)][string]$Configuration, + [Parameter(Mandatory=$false, Position=3)][string]$LogPath ) $testdlls = Get-ChildItem -Path ".\bin\$Platform\$Configuration" -Recurse -Filter $MatchPattern -&".\bin\$Platform\$Configuration\te.exe" $testdlls.FullName + +$args = @(); + +if ($LogPath) +{ + $args += '/enablewttlogging'; + $args += '/appendwttlogging'; + $args += "/logFile:$LogPath"; + Write-Host "Wtt Logging Enabled"; +} + +&".\bin\$Platform\$Configuration\te.exe" $args $testdlls.FullName if ($lastexitcode -Ne 0) { Exit $lastexitcode } diff --git a/src/cascadia/LocalTests_TerminalApp/CommandTests.cpp b/src/cascadia/LocalTests_TerminalApp/CommandTests.cpp index d8028a88545..c2fcc95af9c 100644 --- a/src/cascadia/LocalTests_TerminalApp/CommandTests.cpp +++ b/src/cascadia/LocalTests_TerminalApp/CommandTests.cpp @@ -239,6 +239,14 @@ namespace TerminalAppLocalTests void CommandTests::TestAutogeneratedName() { + // Tests run in Helix can't report Skipped until GH#7286 is resolved. + // Set ignore flag to make Helix run completely overlook it. + BEGIN_TEST_METHOD_PROPERTIES() + TEST_METHOD_PROPERTY(L"Ignore", L"True") + END_TEST_METHOD_PROPERTIES() + + // This test to be corrected as a part of GH#7281 + // This test ensures that we'll correctly create commands for actions // that don't have given names, pursuant to the spec in GH#6532. diff --git a/src/cascadia/LocalTests_TerminalApp/SettingsTests.cpp b/src/cascadia/LocalTests_TerminalApp/SettingsTests.cpp index 4c430688d24..f158525548d 100644 --- a/src/cascadia/LocalTests_TerminalApp/SettingsTests.cpp +++ b/src/cascadia/LocalTests_TerminalApp/SettingsTests.cpp @@ -2296,6 +2296,13 @@ namespace TerminalAppLocalTests void SettingsTests::ValidateExecuteCommandlineWarning() { + // Tests run in Helix can't report Skipped until GH#7286 is resolved. + // Set ignore flag to make Helix run completely overlook it. + BEGIN_TEST_METHOD_PROPERTIES() + TEST_METHOD_PROPERTY(L"Ignore", L"True") + END_TEST_METHOD_PROPERTIES() + + // This test to be corrected as a part of GH#7281 Log::Comment(L"This test is affected by GH#6949, so we're just skipping it for now."); Log::Result(WEX::Logging::TestResults::Skipped); return; @@ -2418,6 +2425,14 @@ namespace TerminalAppLocalTests void SettingsTests::TestCommandsAndKeybindings() { + // Tests run in Helix can't report Skipped until GH#7286 is resolved. + // Set ignore flag to make Helix run completely overlook it. + BEGIN_TEST_METHOD_PROPERTIES() + TEST_METHOD_PROPERTY(L"Ignore", L"True") + END_TEST_METHOD_PROPERTIES() + + // This test to be corrected as a part of GH#7281 + const std::string settingsJson{ R"( { "defaultProfile": "{6239a42c-0000-49a3-80bd-e8fdd045185c}", diff --git a/src/cascadia/LocalTests_TerminalApp/TabTests.cpp b/src/cascadia/LocalTests_TerminalApp/TabTests.cpp index 3c417174c59..9b0b4df8b18 100644 --- a/src/cascadia/LocalTests_TerminalApp/TabTests.cpp +++ b/src/cascadia/LocalTests_TerminalApp/TabTests.cpp @@ -278,6 +278,13 @@ namespace TerminalAppLocalTests void TabTests::TryDuplicateBadTab() { + // Tests run in Helix can't report Skipped until GH#7286 is resolved. + // Set ignore flag to make Helix run completely overlook it. + BEGIN_TEST_METHOD_PROPERTIES() + TEST_METHOD_PROPERTY(L"Ignore", L"True") + END_TEST_METHOD_PROPERTIES() + + // This test to be corrected as a part of GH#7281 Log::Comment(L"This test regressed recently - it is temporarily disabled while GH#5169 is investigated"); Log::Result(WEX::Logging::TestResults::Skipped); return; @@ -377,6 +384,13 @@ namespace TerminalAppLocalTests void TabTests::TryDuplicateBadPane() { + // Tests run in Helix can't report Skipped until GH#7286 is resolved. + // Set ignore flag to make Helix run completely overlook it. + BEGIN_TEST_METHOD_PROPERTIES() + TEST_METHOD_PROPERTY(L"Ignore", L"True") + END_TEST_METHOD_PROPERTIES() + + // This test to be corrected as a part of GH#7281 Log::Comment(L"This test regressed recently - it is temporarily disabled while GH#5169 is investigated"); Log::Result(WEX::Logging::TestResults::Skipped); return; diff --git a/src/host/ft_uia/AccessibilityTests.cs b/src/host/ft_uia/AccessibilityTests.cs index db636f8d1e2..0cd51bf0a70 100644 --- a/src/host/ft_uia/AccessibilityTests.cs +++ b/src/host/ft_uia/AccessibilityTests.cs @@ -136,6 +136,7 @@ public void CanAccessAccessibilityTree() } [TestMethod] + [TestProperty("Ignore", "True")] // GH#7282 - investigate and reenable public void CanAccessTextAreaUiaElement() { using (CmdApp app = new CmdApp(CreateType.ProcessOnly, TestContext)) @@ -146,6 +147,7 @@ public void CanAccessTextAreaUiaElement() } [TestMethod] + [TestProperty("Ignore", "True")] // GH#7282 - investigate and reenable public void CanGetDocumentRangeText() { using (CmdApp app = new CmdApp(CreateType.ProcessOnly, TestContext)) @@ -181,6 +183,7 @@ public void CanGetDocumentRangeText() } [TestMethod] + [TestProperty("Ignore", "True")] // GH#7282 - investigate and reenable public void CanGetTextAtCharacterLevel() { using (CmdApp app = new CmdApp(CreateType.ProcessOnly, TestContext)) @@ -224,6 +227,7 @@ public void CanGetTextAtCharacterLevel() } [TestMethod] + [TestProperty("Ignore", "True")] // GH#7282 - investigate and reenable public void CanGetVisibleRange() { using (CmdApp app = new CmdApp(CreateType.ProcessOnly, TestContext)) @@ -333,6 +337,7 @@ public void CanCloneTextRangeProvider() } [TestMethod] + [TestProperty("Ignore", "True")] // GH#7282 - investigate and reenable public void CanCompareTextRangeProviderEndpoints() { using (CmdApp app = new CmdApp(CreateType.ProcessOnly, TestContext)) @@ -356,10 +361,15 @@ public void CanCompareTextRangeProviderEndpoints() } [TestMethod] + [TestProperty("Ignore", "True")] // GH#7282 - investigate and reenable public void CanExpandToEnclosingUnitTextRangeProvider() { using (CmdApp app = new CmdApp(CreateType.ProcessOnly, TestContext)) { + var sbiex = app.GetScreenBufferInfo(); + sbiex.dwSize.Y = (short)(2 * sbiex.srWindow.Height); + app.SetScreenBufferInfo(sbiex); + AutomationElement textAreaUiaElement = GetTextAreaUiaElement(app); TextPattern textPattern = textAreaUiaElement.GetCurrentPattern(TextPattern.Pattern) as TextPattern; TextPatternRange[] visibleRanges = textPattern.GetVisibleRanges(); @@ -391,10 +401,15 @@ public void CanExpandToEnclosingUnitTextRangeProvider() } [TestMethod] + [TestProperty("Ignore", "True")] // GH#7282 - investigate and reenable public void CanMoveRange() { using (CmdApp app = new CmdApp(CreateType.ProcessOnly, TestContext)) { + var sbiex = app.GetScreenBufferInfo(); + sbiex.dwSize.Y = (short)(2 * sbiex.srWindow.Height); + app.SetScreenBufferInfo(sbiex); + AutomationElement textAreaUiaElement = GetTextAreaUiaElement(app); TextPattern textPattern = textAreaUiaElement.GetCurrentPattern(TextPattern.Pattern) as TextPattern; TextPatternRange[] visibleRanges = textPattern.GetVisibleRanges(); @@ -471,10 +486,15 @@ public void CanMoveRange() } [TestMethod] + [TestProperty("Ignore", "True")] // GH#7282 - investigate and reenable public void CanMoveEndpointByUnitNearTopBoundary() { using (CmdApp app = new CmdApp(CreateType.ProcessOnly, TestContext)) { + var sbiex = app.GetScreenBufferInfo(); + sbiex.dwSize.Y = (short)(2 * sbiex.srWindow.Height); + app.SetScreenBufferInfo(sbiex); + AutomationElement textAreaUiaElement = GetTextAreaUiaElement(app); TextPattern textPattern = textAreaUiaElement.GetCurrentPattern(TextPattern.Pattern) as TextPattern; TextPatternRange[] visibleRanges = textPattern.GetVisibleRanges(); @@ -532,10 +552,15 @@ public void CanMoveEndpointByUnitNearTopBoundary() } [TestMethod] + [TestProperty("Ignore", "True")] // GH#7282 - investigate and reenable public void CanMoveEndpointByUnitNearBottomBoundary() { using (CmdApp app = new CmdApp(CreateType.ProcessOnly, TestContext)) { + var sbiex = app.GetScreenBufferInfo(); + sbiex.dwSize.Y = (short)(2 * sbiex.srWindow.Height); + app.SetScreenBufferInfo(sbiex); + AutomationElement textAreaUiaElement = GetTextAreaUiaElement(app); TextPattern textPattern = textAreaUiaElement.GetCurrentPattern(TextPattern.Pattern) as TextPattern; TextPatternRange[] visibleRanges = textPattern.GetVisibleRanges(); @@ -592,6 +617,7 @@ public void CanMoveEndpointByUnitNearBottomBoundary() } [TestMethod] + [TestProperty("Ignore", "True")] // GH#7282 - investigate and reenable public void CanGetBoundingRectangles() { using (CmdApp app = new CmdApp(CreateType.ProcessOnly, TestContext)) diff --git a/src/host/ft_uia/CloseTests.cs b/src/host/ft_uia/CloseTests.cs index fffd239181b..50da1f13682 100644 --- a/src/host/ft_uia/CloseTests.cs +++ b/src/host/ft_uia/CloseTests.cs @@ -74,6 +74,7 @@ public void MakePipeServer(CancellationToken token) [TestMethod] [TestProperty("IsolationLevel", "Method")] + [TestProperty("Ignore", "True")] // GH#7282 - investigate and reenable public void CheckClose() { string closeTestCmdLine = $"{closeTestBinaryLocation} -n {processCount} --log {testPipeName} --delay 1000 --no-realloc"; diff --git a/src/host/ft_uia/Common/Globals.cs b/src/host/ft_uia/Common/Globals.cs index b957c5264f7..cdd8d9559a7 100644 --- a/src/host/ft_uia/Common/Globals.cs +++ b/src/host/ft_uia/Common/Globals.cs @@ -10,7 +10,7 @@ namespace Conhost.UIA.Tests.Common public static class Globals { - public const int Timeout = 500; // in milliseconds + public const int Timeout = 50; // in milliseconds public const int AppCreateTimeout = 3000; // in milliseconds // These were pulled via UISpy from system defined window classes. diff --git a/src/host/ft_uia/ExperimentalTabTests.cs b/src/host/ft_uia/ExperimentalTabTests.cs index f0f9c9c39fe..5261b66cf7e 100644 --- a/src/host/ft_uia/ExperimentalTabTests.cs +++ b/src/host/ft_uia/ExperimentalTabTests.cs @@ -35,6 +35,7 @@ public class ExperimentalTabTests public const int timeout = Globals.Timeout; [TestMethod] + [TestProperty("Ignore", "True")] // GH#7282 - investigate and reenable public void CheckExperimentalDisableState() { using (RegistryHelper reg = new RegistryHelper()) @@ -95,6 +96,7 @@ public void CheckExperimentalDisableState() } [TestMethod] + [TestProperty("Ignore", "True")] // GH#7282 - investigate and reenable public void CheckRegistryWritebacks() { using (RegistryHelper reg = new RegistryHelper()) @@ -110,6 +112,7 @@ public void CheckRegistryWritebacks() } [TestMethod] + [TestProperty("Ignore", "True")] // GH#7282 - investigate and reenable public void CheckShortcutWritebacks() { using (RegistryHelper reg = new RegistryHelper()) diff --git a/src/host/ft_uia/KeyPressTests.cs b/src/host/ft_uia/KeyPressTests.cs index 5a667ff3184..89147c20e27 100644 --- a/src/host/ft_uia/KeyPressTests.cs +++ b/src/host/ft_uia/KeyPressTests.cs @@ -30,6 +30,7 @@ class KeyPressTests public TestContext TestContext { get; set; } [TestMethod] + [TestProperty("Ignore", "True")] // GH#7282 - investigate and reenable public void VerifyCtrlKeysBash() { using (RegistryHelper reg = new RegistryHelper()) @@ -69,6 +70,7 @@ public void VerifyCtrlKeysBash() } [TestMethod] + [TestProperty("Ignore", "True")] // GH#7282 - investigate and reenable public void VerifyCtrlCBash() { using (RegistryHelper reg = new RegistryHelper()) diff --git a/src/host/ft_uia/WinEventTests.cs b/src/host/ft_uia/WinEventTests.cs index 9ebfa664b91..aad372e1292 100644 --- a/src/host/ft_uia/WinEventTests.cs +++ b/src/host/ft_uia/WinEventTests.cs @@ -210,6 +210,7 @@ void RunTest(AccessibilityTest test) } [TestMethod] + [TestProperty("Ignore", "True")] // GH#7282 - investigate and reenable public void TestSelection() { RunTest(TestSelectionImpl); @@ -293,6 +294,7 @@ private void TestSelectionImpl(CmdApp app, ViewportArea area, IntPtr hConsole, W } [TestMethod] + [TestProperty("Ignore", "True")] // GH#7282 - investigate and reenable public void TestLaunchAndExitChild() { RunTest(TestLaunchAndExitChildImpl); @@ -353,6 +355,7 @@ private void TestLaunchAndExitChildImpl(CmdApp app, ViewportArea area, IntPtr hC } [TestMethod] + [TestProperty("Ignore", "True")] // GH#7282 - investigate and reenable public void TestScrollByWheel() { RunTest(TestScrollByWheelImpl); @@ -389,6 +392,7 @@ private void TestScrollByWheelImpl(CmdApp app, ViewportArea area, IntPtr hConsol } [TestMethod] + [TestProperty("Ignore", "True")] // GH#7282 - investigate and reenable public void TestScrollByOverflow() { RunTest(TestScrollByOverflowImpl); From 7fcff4d33ad5595192a57b92c5506e6b745071b7 Mon Sep 17 00:00:00 2001 From: James Holderness Date: Tue, 18 Aug 2020 19:57:52 +0100 Subject: [PATCH 063/266] Refactor VT control sequence identification (#7304) This PR changes the way VT control sequences are identified and dispatched, to be more efficient and easier to extend. Instead of parsing the intermediate characters into a vector, and then having to identify a sequence using both that vector and the final char, we now use just a single `uint64_t` value as the identifier. The way the identifier is constructed is by taking the private parameter prefix, each of the intermediate characters, and then the final character, and shifting them into a 64-bit integer one byte at a time, in reverse order. For example, the `DECTLTC` control has a private parameter prefix of `?`, one intermediate of `'`, and a final character of `s`. The ASCII values of those characters are `0x3F`, `0x27`, and `0x73` respectively, and reversing them gets you 0x73273F, so that would then be the identifier for the control. The reason for storing them in reverse order, is because sometimes we need to look at the first intermediate to determine the operation, and treat the rest of the sequence as a kind of sub-identifier (the character set designation sequences are one example of this). When in reverse order, this can easily be achieved by masking off the low byte to get the first intermediate, and then shifting the value right by 8 bits to get a new identifier with the rest of the sequence. With 64 bits we have enough space for a private prefix, six intermediates, and the final char, which is way more than we should ever need (the _DEC STD 070_ specification recommends supporting at least three intermediates, but in practice we're unlikely to see more than two). With this new way of identifying controls, it should now be possible for every action code to be unique (for the most part). So I've also used this PR to clean up the action codes a bit, splitting the codes for the escape sequences from the control sequences, and sorting them into alphabetical order (which also does a reasonable job of clustering associated controls). ## Validation Steps Performed I think the existing unit tests should be good enough to confirm that all sequences are still being dispatched correctly. However, I've also manually tested a number of sequences to make sure they were still working as expected, in particular those that used intermediates, since they were the most affected by the dispatch code refactoring. Since these changes also affected the input state machine, I've done some manual testing of the conpty keyboard handling (both with and without the new Win32 input mode enabled) to make sure the keyboard VT sequences were processed correctly. I've also manually tested the various VT mouse modes in Vttest to confirm that they were still working correctly too. Closes #7276 --- .github/actions/spell-check/expect/expect.txt | 2 + src/terminal/adapter/DispatchTypes.hpp | 102 +- src/terminal/adapter/ITermDispatch.hpp | 6 +- src/terminal/adapter/adaptDispatch.cpp | 10 +- src/terminal/adapter/adaptDispatch.hpp | 6 +- src/terminal/adapter/termDispatch.hpp | 6 +- src/terminal/adapter/terminalOutput.cpp | 124 +-- src/terminal/adapter/terminalOutput.hpp | 4 +- src/terminal/parser/IStateMachineEngine.hpp | 14 +- .../parser/InputStateMachineEngine.cpp | 91 +- .../parser/InputStateMachineEngine.hpp | 58 +- .../parser/OutputStateMachineEngine.cpp | 985 +++++++----------- .../parser/OutputStateMachineEngine.hpp | 174 ++-- src/terminal/parser/stateMachine.cpp | 15 +- src/terminal/parser/stateMachine.hpp | 4 +- .../parser/ut_parser/InputEngineTest.cpp | 10 +- .../parser/ut_parser/StateMachineTest.cpp | 11 +- 17 files changed, 721 insertions(+), 901 deletions(-) diff --git a/.github/actions/spell-check/expect/expect.txt b/.github/actions/spell-check/expect/expect.txt index ba5e05b86ba..ddb33c771f3 100644 --- a/.github/actions/spell-check/expect/expect.txt +++ b/.github/actions/spell-check/expect/expect.txt @@ -548,6 +548,7 @@ DECSCUSR DECSED DECSEL DECSET +DECSLPP DECSLRM DECSMBV DECSMKR @@ -2579,6 +2580,7 @@ vstudio vswhere vtapp VTE +VTID vtio vtmode vtpipeterm diff --git a/src/terminal/adapter/DispatchTypes.hpp b/src/terminal/adapter/DispatchTypes.hpp index 9de95ca1527..1454ed279e4 100644 --- a/src/terminal/adapter/DispatchTypes.hpp +++ b/src/terminal/adapter/DispatchTypes.hpp @@ -3,6 +3,94 @@ #pragma once +namespace Microsoft::Console::VirtualTerminal +{ + class VTID + { + public: + template + constexpr VTID(const char (&s)[Length]) : + _value{ _FromString(s) } + { + } + + constexpr VTID(const uint64_t value) : + _value{ value } + { + } + + constexpr operator uint64_t() const + { + return _value; + } + + constexpr char operator[](const size_t offset) const + { + return SubSequence(offset)._value & 0xFF; + } + + constexpr VTID SubSequence(const size_t offset) const + { + return _value >> (CHAR_BIT * offset); + } + + private: + template + static constexpr uint64_t _FromString(const char (&s)[Length]) + { + static_assert(Length - 1 <= sizeof(_value)); + uint64_t value = 0; + for (auto i = Length - 1; i-- > 0;) + { + value = (value << CHAR_BIT) + gsl::at(s, i); + } + return value; + } + + uint64_t _value; + }; + + class VTIDBuilder + { + public: + void Clear() noexcept + { + _idAccumulator = 0; + _idShift = 0; + } + + void AddIntermediate(const wchar_t intermediateChar) noexcept + { + if (_idShift + CHAR_BIT >= sizeof(_idAccumulator) * CHAR_BIT) + { + // If there is not enough space in the accumulator to add + // the intermediate and still have room left for the final, + // then we reset the accumulator to zero. This will result + // in an id with all zero intermediates, which shouldn't + // match anything. + _idAccumulator = 0; + } + else + { + // Otherwise we shift the intermediate so as to add it to the + // accumulator in the next available space, and then increment + // the shift by 8 bits in preparation for the next character. + _idAccumulator += (static_cast(intermediateChar) << _idShift); + _idShift += CHAR_BIT; + } + } + + VTID Finalize(const wchar_t finalChar) noexcept + { + return _idAccumulator + (static_cast(finalChar) << _idShift); + } + + private: + uint64_t _idAccumulator = 0; + size_t _idShift = 0; + }; +} + namespace Microsoft::Console::VirtualTerminal::DispatchTypes { enum class EraseType : unsigned int @@ -101,16 +189,16 @@ namespace Microsoft::Console::VirtualTerminal::DispatchTypes W32IM_Win32InputMode = 9001 }; - namespace CharacterSets + enum CharacterSets : uint64_t { - constexpr auto DecSpecialGraphics = std::make_pair(L'0', L'\0'); - constexpr auto ASCII = std::make_pair(L'B', L'\0'); - } + DecSpecialGraphics = VTID("0"), + ASCII = VTID("B") + }; - enum CodingSystem : wchar_t + enum CodingSystem : uint64_t { - ISO2022 = L'@', - UTF8 = L'G' + ISO2022 = VTID("@"), + UTF8 = VTID("G") }; enum TabClearType : unsigned short diff --git a/src/terminal/adapter/ITermDispatch.hpp b/src/terminal/adapter/ITermDispatch.hpp index 93f1dffeccd..b90705ac4a9 100644 --- a/src/terminal/adapter/ITermDispatch.hpp +++ b/src/terminal/adapter/ITermDispatch.hpp @@ -98,9 +98,9 @@ class Microsoft::Console::VirtualTerminal::ITermDispatch virtual bool TertiaryDeviceAttributes() = 0; // DA3 virtual bool Vt52DeviceAttributes() = 0; // VT52 Identify - virtual bool DesignateCodingSystem(const wchar_t codingSystem) = 0; // DOCS - virtual bool Designate94Charset(const size_t gsetNumber, const std::pair charset) = 0; // SCS - virtual bool Designate96Charset(const size_t gsetNumber, const std::pair charset) = 0; // SCS + virtual bool DesignateCodingSystem(const VTID codingSystem) = 0; // DOCS + virtual bool Designate94Charset(const size_t gsetNumber, const VTID charset) = 0; // SCS + virtual bool Designate96Charset(const size_t gsetNumber, const VTID charset) = 0; // SCS virtual bool LockingShift(const size_t gsetNumber) = 0; // LS0, LS1, LS2, LS3 virtual bool LockingShiftRight(const size_t gsetNumber) = 0; // LS1R, LS2R, LS3R virtual bool SingleShift(const size_t gsetNumber) = 0; // SS2, SS3 diff --git a/src/terminal/adapter/adaptDispatch.cpp b/src/terminal/adapter/adaptDispatch.cpp index 8d656e572dd..d435498c322 100644 --- a/src/terminal/adapter/adaptDispatch.cpp +++ b/src/terminal/adapter/adaptDispatch.cpp @@ -1670,7 +1670,7 @@ void AdaptDispatch::_InitTabStopsForWidth(const size_t width) // - codingSystem - The coding system that will be selected. // Return value: // True if handled successfully. False otherwise. -bool AdaptDispatch::DesignateCodingSystem(const wchar_t codingSystem) +bool AdaptDispatch::DesignateCodingSystem(const VTID codingSystem) { // If we haven't previously saved the initial code page, do so now. // This will be used to restore the code page in response to a reset. @@ -1712,10 +1712,10 @@ bool AdaptDispatch::DesignateCodingSystem(const wchar_t codingSystem) // If the specified charset is unsupported, we do nothing (remain on the current one) //Arguments: // - gsetNumber - The G-set into which the charset will be selected. -// - charset - The characters indicating the charset that will be used. +// - charset - The identifier indicating the charset that will be used. // Return value: // True if handled successfully. False otherwise. -bool AdaptDispatch::Designate94Charset(const size_t gsetNumber, const std::pair charset) +bool AdaptDispatch::Designate94Charset(const size_t gsetNumber, const VTID charset) { return _termOutput.Designate94Charset(gsetNumber, charset); } @@ -1727,10 +1727,10 @@ bool AdaptDispatch::Designate94Charset(const size_t gsetNumber, const std::pair< // If the specified charset is unsupported, we do nothing (remain on the current one) //Arguments: // - gsetNumber - The G-set into which the charset will be selected. -// - charset - The characters indicating the charset that will be used. +// - charset - The identifier indicating the charset that will be used. // Return value: // True if handled successfully. False otherwise. -bool AdaptDispatch::Designate96Charset(const size_t gsetNumber, const std::pair charset) +bool AdaptDispatch::Designate96Charset(const size_t gsetNumber, const VTID charset) { return _termOutput.Designate96Charset(gsetNumber, charset); } diff --git a/src/terminal/adapter/adaptDispatch.hpp b/src/terminal/adapter/adaptDispatch.hpp index 12a0c902104..2e5f27a7823 100644 --- a/src/terminal/adapter/adaptDispatch.hpp +++ b/src/terminal/adapter/adaptDispatch.hpp @@ -89,9 +89,9 @@ namespace Microsoft::Console::VirtualTerminal bool ForwardTab(const size_t numTabs) override; // CHT, HT bool BackwardsTab(const size_t numTabs) override; // CBT bool TabClear(const size_t clearType) override; // TBC - bool DesignateCodingSystem(const wchar_t codingSystem) override; // DOCS - bool Designate94Charset(const size_t gsetNumber, const std::pair charset) override; // SCS - bool Designate96Charset(const size_t gsetNumber, const std::pair charset) override; // SCS + bool DesignateCodingSystem(const VTID codingSystem) override; // DOCS + bool Designate94Charset(const size_t gsetNumber, const VTID charset) override; // SCS + bool Designate96Charset(const size_t gsetNumber, const VTID charset) override; // SCS bool LockingShift(const size_t gsetNumber) override; // LS0, LS1, LS2, LS3 bool LockingShiftRight(const size_t gsetNumber) override; // LS1R, LS2R, LS3R bool SingleShift(const size_t gsetNumber) override; // SS2, SS3 diff --git a/src/terminal/adapter/termDispatch.hpp b/src/terminal/adapter/termDispatch.hpp index e13579c688e..47ecd990784 100644 --- a/src/terminal/adapter/termDispatch.hpp +++ b/src/terminal/adapter/termDispatch.hpp @@ -92,9 +92,9 @@ class Microsoft::Console::VirtualTerminal::TermDispatch : public Microsoft::Cons bool TertiaryDeviceAttributes() noexcept override { return false; } // DA3 bool Vt52DeviceAttributes() noexcept override { return false; } // VT52 Identify - bool DesignateCodingSystem(const wchar_t /*codingSystem*/) noexcept override { return false; } // DOCS - bool Designate94Charset(const size_t /*gsetNumber*/, const std::pair /*charset*/) noexcept override { return false; } // SCS - bool Designate96Charset(const size_t /*gsetNumber*/, const std::pair /*charset*/) noexcept override { return false; } // SCS + bool DesignateCodingSystem(const VTID /*codingSystem*/) noexcept override { return false; } // DOCS + bool Designate94Charset(const size_t /*gsetNumber*/, const VTID /*charset*/) noexcept override { return false; } // SCS + bool Designate96Charset(const size_t /*gsetNumber*/, const VTID /*charset*/) noexcept override { return false; } // SCS bool LockingShift(const size_t /*gsetNumber*/) noexcept override { return false; } // LS0, LS1, LS2, LS3 bool LockingShiftRight(const size_t /*gsetNumber*/) noexcept override { return false; } // LS1R, LS2R, LS3R bool SingleShift(const size_t /*gsetNumber*/) noexcept override { return false; } // SS2, SS3 diff --git a/src/terminal/adapter/terminalOutput.cpp b/src/terminal/adapter/terminalOutput.cpp index f320839ac5f..14de84e1393 100644 --- a/src/terminal/adapter/terminalOutput.cpp +++ b/src/terminal/adapter/terminalOutput.cpp @@ -17,107 +17,89 @@ TerminalOutput::TerminalOutput() noexcept _gsetTranslationTables.at(3) = Latin1; } -bool TerminalOutput::Designate94Charset(size_t gsetNumber, const std::pair charset) +bool TerminalOutput::Designate94Charset(size_t gsetNumber, const VTID charset) { - switch (charset.first) + switch (charset) { - case L'B': // US ASCII - case L'1': // Alternate Character ROM + case VTID("B"): // US ASCII + case VTID("1"): // Alternate Character ROM return _SetTranslationTable(gsetNumber, Ascii); - case L'0': // DEC Special Graphics - case L'2': // Alternate Character ROM Special Graphics + case VTID("0"): // DEC Special Graphics + case VTID("2"): // Alternate Character ROM Special Graphics return _SetTranslationTable(gsetNumber, DecSpecialGraphics); - case L'<': // DEC Supplemental + case VTID("<"): // DEC Supplemental return _SetTranslationTable(gsetNumber, DecSupplemental); - case L'A': // British NRCS + case VTID("A"): // British NRCS return _SetTranslationTable(gsetNumber, BritishNrcs); - case L'4': // Dutch NRCS + case VTID("4"): // Dutch NRCS return _SetTranslationTable(gsetNumber, DutchNrcs); - case L'5': // Finnish NRCS - case L'C': // (fallback) + case VTID("5"): // Finnish NRCS + case VTID("C"): // (fallback) return _SetTranslationTable(gsetNumber, FinnishNrcs); - case L'R': // French NRCS + case VTID("R"): // French NRCS return _SetTranslationTable(gsetNumber, FrenchNrcs); - case L'f': // French NRCS (ISO update) + case VTID("f"): // French NRCS (ISO update) return _SetTranslationTable(gsetNumber, FrenchNrcsIso); - case L'9': // French Canadian NRCS - case L'Q': // (fallback) + case VTID("9"): // French Canadian NRCS + case VTID("Q"): // (fallback) return _SetTranslationTable(gsetNumber, FrenchCanadianNrcs); - case L'K': // German NRCS + case VTID("K"): // German NRCS return _SetTranslationTable(gsetNumber, GermanNrcs); - case L'Y': // Italian NRCS + case VTID("Y"): // Italian NRCS return _SetTranslationTable(gsetNumber, ItalianNrcs); - case L'6': // Norwegian/Danish NRCS - case L'E': // (fallback) + case VTID("6"): // Norwegian/Danish NRCS + case VTID("E"): // (fallback) return _SetTranslationTable(gsetNumber, NorwegianDanishNrcs); - case L'`': // Norwegian/Danish NRCS (ISO standard) + case VTID("`"): // Norwegian/Danish NRCS (ISO standard) return _SetTranslationTable(gsetNumber, NorwegianDanishNrcsIso); - case L'Z': // Spanish NRCS + case VTID("Z"): // Spanish NRCS return _SetTranslationTable(gsetNumber, SpanishNrcs); - case L'7': // Swedish NRCS - case L'H': // (fallback) + case VTID("7"): // Swedish NRCS + case VTID("H"): // (fallback) return _SetTranslationTable(gsetNumber, SwedishNrcs); - case L'=': // Swiss NRCS + case VTID("="): // Swiss NRCS return _SetTranslationTable(gsetNumber, SwissNrcs); - case L'&': - switch (charset.second) - { - case L'4': // DEC Cyrillic - return _SetTranslationTable(gsetNumber, DecCyrillic); - case L'5': // Russian NRCS - return _SetTranslationTable(gsetNumber, RussianNrcs); - default: - return false; - } - case L'"': - switch (charset.second) - { - case L'?': // DEC Greek - return _SetTranslationTable(gsetNumber, DecGreek); - case L'>': // Greek NRCS - return _SetTranslationTable(gsetNumber, GreekNrcs); - case L'4': // DEC Hebrew - return _SetTranslationTable(gsetNumber, DecHebrew); - default: - return false; - } - case L'%': - switch (charset.second) - { - case L'=': // Hebrew NRCS - return _SetTranslationTable(gsetNumber, HebrewNrcs); - case L'0': // DEC Turkish - return _SetTranslationTable(gsetNumber, DecTurkish); - case L'2': // Turkish NRCS - return _SetTranslationTable(gsetNumber, TurkishNrcs); - case L'5': // DEC Supplemental - return _SetTranslationTable(gsetNumber, DecSupplemental); - case L'6': // Portuguese NRCS - return _SetTranslationTable(gsetNumber, PortugueseNrcs); - default: - return false; - } + case VTID("&4"): // DEC Cyrillic + return _SetTranslationTable(gsetNumber, DecCyrillic); + case VTID("&5"): // Russian NRCS + return _SetTranslationTable(gsetNumber, RussianNrcs); + case VTID("\"?"): // DEC Greek + return _SetTranslationTable(gsetNumber, DecGreek); + case VTID("\">"): // Greek NRCS + return _SetTranslationTable(gsetNumber, GreekNrcs); + case VTID("\"4"): // DEC Hebrew + return _SetTranslationTable(gsetNumber, DecHebrew); + case VTID("%="): // Hebrew NRCS + return _SetTranslationTable(gsetNumber, HebrewNrcs); + case VTID("%0"): // DEC Turkish + return _SetTranslationTable(gsetNumber, DecTurkish); + case VTID("%2"): // Turkish NRCS + return _SetTranslationTable(gsetNumber, TurkishNrcs); + case VTID("%5"): // DEC Supplemental + return _SetTranslationTable(gsetNumber, DecSupplemental); + case VTID("%6"): // Portuguese NRCS + return _SetTranslationTable(gsetNumber, PortugueseNrcs); default: return false; } } -bool TerminalOutput::Designate96Charset(size_t gsetNumber, const std::pair charset) +bool TerminalOutput::Designate96Charset(size_t gsetNumber, const VTID charset) { - switch (charset.first) + switch (charset) { - case L'A': // ISO Latin-1 Supplemental - case L'<': // (UPSS when assigned to Latin-1) + case VTID("A"): // ISO Latin-1 Supplemental + case VTID("<"): // (UPSS when assigned to Latin-1) return _SetTranslationTable(gsetNumber, Latin1); - case L'B': // ISO Latin-2 Supplemental + case VTID("B"): // ISO Latin-2 Supplemental return _SetTranslationTable(gsetNumber, Latin2); - case L'L': // ISO Latin-Cyrillic Supplemental + case VTID("L"): // ISO Latin-Cyrillic Supplemental return _SetTranslationTable(gsetNumber, LatinCyrillic); - case L'F': // ISO Latin-Greek Supplemental + case VTID("F"): // ISO Latin-Greek Supplemental return _SetTranslationTable(gsetNumber, LatinGreek); - case L'H': // ISO Latin-Hebrew Supplemental + case VTID("H"): // ISO Latin-Hebrew Supplemental return _SetTranslationTable(gsetNumber, LatinHebrew); - case L'M': // ISO Latin-5 Supplemental + case VTID("M"): // ISO Latin-5 Supplemental return _SetTranslationTable(gsetNumber, Latin5); default: return false; diff --git a/src/terminal/adapter/terminalOutput.hpp b/src/terminal/adapter/terminalOutput.hpp index a26f6d85a61..e82e067a7c2 100644 --- a/src/terminal/adapter/terminalOutput.hpp +++ b/src/terminal/adapter/terminalOutput.hpp @@ -26,8 +26,8 @@ namespace Microsoft::Console::VirtualTerminal TerminalOutput() noexcept; wchar_t TranslateKey(const wchar_t wch) const noexcept; - bool Designate94Charset(const size_t gsetNumber, const std::pair charset); - bool Designate96Charset(const size_t gsetNumber, const std::pair charset); + bool Designate94Charset(const size_t gsetNumber, const VTID charset); + bool Designate96Charset(const size_t gsetNumber, const VTID charset); bool LockingShift(const size_t gsetNumber); bool LockingShiftRight(const size_t gsetNumber); bool SingleShift(const size_t gsetNumber); diff --git a/src/terminal/parser/IStateMachineEngine.hpp b/src/terminal/parser/IStateMachineEngine.hpp index c1a668fb72c..169cf8ac021 100644 --- a/src/terminal/parser/IStateMachineEngine.hpp +++ b/src/terminal/parser/IStateMachineEngine.hpp @@ -12,6 +12,9 @@ Module Name: the existing VT parsing. */ #pragma once + +#include "../adapter/DispatchTypes.hpp" + namespace Microsoft::Console::VirtualTerminal { class IStateMachineEngine @@ -30,14 +33,9 @@ namespace Microsoft::Console::VirtualTerminal virtual bool ActionPassThroughString(const std::wstring_view string) = 0; - virtual bool ActionEscDispatch(const wchar_t wch, - const gsl::span intermediates) = 0; - virtual bool ActionVt52EscDispatch(const wchar_t wch, - const gsl::span intermediates, - const gsl::span parameters) = 0; - virtual bool ActionCsiDispatch(const wchar_t wch, - const gsl::span intermediates, - const gsl::span parameters) = 0; + virtual bool ActionEscDispatch(const VTID id) = 0; + virtual bool ActionVt52EscDispatch(const VTID id, const gsl::span parameters) = 0; + virtual bool ActionCsiDispatch(const VTID id, const gsl::span parameters) = 0; virtual bool ActionClear() = 0; diff --git a/src/terminal/parser/InputStateMachineEngine.cpp b/src/terminal/parser/InputStateMachineEngine.cpp index a4d903f5644..c795243bf0c 100644 --- a/src/terminal/parser/InputStateMachineEngine.cpp +++ b/src/terminal/parser/InputStateMachineEngine.cpp @@ -34,9 +34,9 @@ static constexpr std::array s_csiMap = { CsiToVkey{ CsiActionCodes::CSI_F4, VK_F4 } }; -static bool operator==(const CsiToVkey& pair, const CsiActionCodes code) noexcept +static bool operator==(const CsiToVkey& pair, const VTID id) noexcept { - return pair.action == code; + return pair.action == id; } struct GenericToVkey @@ -298,12 +298,10 @@ bool InputStateMachineEngine::ActionPassThroughString(const std::wstring_view st // a simple escape sequence. These sequences traditionally start with ESC // and a simple letter. No complicated parameters. // Arguments: -// - wch - Character to dispatch. -// - intermediates - Intermediate characters in the sequence +// - id - Identifier of the escape sequence to dispatch. // Return Value: // - true iff we successfully dispatched the sequence. -bool InputStateMachineEngine::ActionEscDispatch(const wchar_t wch, - const gsl::span /*intermediates*/) +bool InputStateMachineEngine::ActionEscDispatch(const VTID id) { if (_pDispatch->IsVtInputEnabled() && _pfnFlushToInputQueue) { @@ -312,6 +310,9 @@ bool InputStateMachineEngine::ActionEscDispatch(const wchar_t wch, bool success = false; + // There are no intermediates, so the id is effectively the final char. + const wchar_t wch = gsl::narrow_cast(id); + // 0x7f is DEL, which we treat effectively the same as a ctrl character. if (wch == 0x7f) { @@ -339,14 +340,11 @@ bool InputStateMachineEngine::ActionEscDispatch(const wchar_t wch, // a VT52 escape sequence. These sequences start with ESC and a single letter, // sometimes followed by parameters. // Arguments: -// - wch - Character to dispatch. -// - intermediates - Intermediate characters in the sequence. +// - id - Identifier of the VT52 sequence to dispatch. // - parameters - Set of parameters collected while parsing the sequence. // Return Value: // - true iff we successfully dispatched the sequence. -bool InputStateMachineEngine::ActionVt52EscDispatch(const wchar_t /*wch*/, - const gsl::span /*intermediates*/, - const gsl::span /*parameters*/) noexcept +bool InputStateMachineEngine::ActionVt52EscDispatch(const VTID /*id*/, const gsl::span /*parameters*/) noexcept { // VT52 escape sequences are not used in the input state machine. return false; @@ -357,17 +355,12 @@ bool InputStateMachineEngine::ActionVt52EscDispatch(const wchar_t /*wch*/, // a control sequence. These sequences perform various API-type commands // that can include many parameters. // Arguments: -// - wch - Character to dispatch. -// - intermediates - Intermediate characters in the sequence +// - id - Identifier of the control sequence to dispatch. // - parameters - set of numeric parameters collected while parsing the sequence. // Return Value: // - true iff we successfully dispatched the sequence. -bool InputStateMachineEngine::ActionCsiDispatch(const wchar_t wch, - const gsl::span intermediates, - const gsl::span parameters) +bool InputStateMachineEngine::ActionCsiDispatch(const VTID id, const gsl::span parameters) { - const auto actionCode = static_cast(wch); - // GH#4999 - If the client was in VT input mode, but we received a // win32-input-mode sequence, then _don't_ passthrough the sequence to the // client. It's impossibly unlikely that the client actually wanted @@ -376,7 +369,7 @@ bool InputStateMachineEngine::ActionCsiDispatch(const wchar_t wch, // client reads it. if (_pDispatch->IsVtInputEnabled() && _pfnFlushToInputQueue && - actionCode != CsiActionCodes::Win32KeyboardInput) + id != CsiActionCodes::Win32KeyboardInput) { return _pfnFlushToInputQueue(); } @@ -392,32 +385,22 @@ bool InputStateMachineEngine::ActionCsiDispatch(const wchar_t wch, const auto remainingArgs = parameters.size() > 1 ? parameters.subspan(1) : gsl::span{}; bool success = false; - // Handle intermediate characters, if any - if (!intermediates.empty()) + switch (id) { - switch (static_cast(til::at(intermediates, 0))) - { - case CsiIntermediateCodes::MOUSE_SGR: - { - DWORD buttonState = 0; - DWORD eventFlags = 0; - modifierState = _GetSGRMouseModifierState(parameters); - success = _GetSGRXYPosition(parameters, row, col); - - // we need _UpdateSGRMouseButtonState() on the left side here because we _always_ should be updating our state - // even if we failed to parse a portion of this sequence. - success = _UpdateSGRMouseButtonState(wch, parameters, buttonState, eventFlags) && success; - success = success && _WriteMouseEvent(col, row, buttonState, modifierState, eventFlags); - break; - } - default: - success = false; - break; - } + case CsiActionCodes::MouseDown: + case CsiActionCodes::MouseUp: + { + DWORD buttonState = 0; + DWORD eventFlags = 0; + modifierState = _GetSGRMouseModifierState(parameters); + success = _GetSGRXYPosition(parameters, row, col); + + // we need _UpdateSGRMouseButtonState() on the left side here because we _always_ should be updating our state + // even if we failed to parse a portion of this sequence. + success = _UpdateSGRMouseButtonState(id, parameters, buttonState, eventFlags) && success; + success = success && _WriteMouseEvent(col, row, buttonState, modifierState, eventFlags); return success; } - switch (actionCode) - { case CsiActionCodes::Generic: modifierState = _GetGenericKeysModifierState(parameters); success = _GetGenericVkey(parameters, vkey); @@ -443,8 +426,8 @@ bool InputStateMachineEngine::ActionCsiDispatch(const wchar_t wch, case CsiActionCodes::CSI_F1: case CsiActionCodes::CSI_F2: case CsiActionCodes::CSI_F4: - success = _GetCursorKeysVkey(wch, vkey); - modifierState = _GetCursorKeysModifierState(parameters, static_cast(wch)); + success = _GetCursorKeysVkey(id, vkey); + modifierState = _GetCursorKeysModifierState(parameters, id); break; case CsiActionCodes::CursorBackTab: modifierState = SHIFT_PRESSED; @@ -464,7 +447,7 @@ bool InputStateMachineEngine::ActionCsiDispatch(const wchar_t wch, if (success) { - switch (static_cast(wch)) + switch (id) { // case CsiActionCodes::DSR_DeviceStatusReportResponse: case CsiActionCodes::CSI_F3: @@ -799,10 +782,10 @@ bool InputStateMachineEngine::_WriteMouseEvent(const size_t column, const size_t // sequence. This is for Arrow keys, Home, End, etc. // Arguments: // - parameters - the set of parameters to get the modifier state from. -// - actionCode - the actionCode for the sequence we're operating on. +// - id - the identifier for the sequence we're operating on. // Return Value: // - the INPUT_RECORD compatible modifier state. -DWORD InputStateMachineEngine::_GetCursorKeysModifierState(const gsl::span parameters, const CsiActionCodes actionCode) noexcept +DWORD InputStateMachineEngine::_GetCursorKeysModifierState(const gsl::span parameters, const VTID id) noexcept { DWORD modifiers = 0; if (_IsModified(parameters.size()) && parameters.size() >= 2) @@ -816,7 +799,7 @@ DWORD InputStateMachineEngine::_GetCursorKeysModifierState(const gsl::span CsiActionCodes::CSI_F4) + if (id < CsiActionCodes::CSI_F1 || id > CsiActionCodes::CSI_F4) { WI_SetFlag(modifiers, ENHANCED_KEY); } @@ -917,13 +900,13 @@ DWORD InputStateMachineEngine::_GetModifier(const size_t modifierParam) noexcept // - Here, we refer to and maintain the global state of our mouse. // - Mouse wheel events are added at the end to keep them out of the global state // Arguments: -// - wch: the wchar_t representing whether the button was pressed or released +// - id: the sequence identifier representing whether the button was pressed or released // - parameters: the wchar_t to get the mapped vkey of. Represents the direction of the button (down vs up) // - buttonState: Receives the button state for the record // - eventFlags: Receives the special mouse events for the record // Return Value: // true iff we were able to synthesize buttonState -bool InputStateMachineEngine::_UpdateSGRMouseButtonState(const wchar_t wch, +bool InputStateMachineEngine::_UpdateSGRMouseButtonState(const VTID id, const gsl::span parameters, DWORD& buttonState, DWORD& eventFlags) noexcept @@ -987,7 +970,7 @@ bool InputStateMachineEngine::_UpdateSGRMouseButtonState(const wchar_t wch, // Step 2: Decide whether to set or clear that button's bit // NOTE: WI_SetFlag/WI_ClearFlag can't be used here because buttonFlag would have to be a compile-time constant - switch (static_cast(wch)) + switch (id) { case CsiActionCodes::MouseDown: // set flag @@ -1049,15 +1032,15 @@ bool InputStateMachineEngine::_GetGenericVkey(const gsl::span para // Method Description: // - Gets the Vkey from the CSI codes table associated with a particular character. // Arguments: -// - wch: the wchar_t to get the mapped vkey of. +// - id: the sequence identifier to get the mapped vkey of. // - vkey: Receives the vkey // Return Value: // true iff we found the key -bool InputStateMachineEngine::_GetCursorKeysVkey(const wchar_t wch, short& vkey) const +bool InputStateMachineEngine::_GetCursorKeysVkey(const VTID id, short& vkey) const { vkey = 0; - const auto mapping = std::find(s_csiMap.cbegin(), s_csiMap.cend(), (CsiActionCodes)wch); + const auto mapping = std::find(s_csiMap.cbegin(), s_csiMap.cend(), id); if (mapping != s_csiMap.end()) { vkey = mapping->vkey; diff --git a/src/terminal/parser/InputStateMachineEngine.hpp b/src/terminal/parser/InputStateMachineEngine.hpp index 14f6cedc188..a14aa87f633 100644 --- a/src/terminal/parser/InputStateMachineEngine.hpp +++ b/src/terminal/parser/InputStateMachineEngine.hpp @@ -50,30 +50,25 @@ namespace Microsoft::Console::VirtualTerminal // CAPSLOCK_ON 0x0080 // ENHANCED_KEY 0x0100 - enum CsiIntermediateCodes : wchar_t + enum CsiActionCodes : uint64_t { - MOUSE_SGR = L'<', - }; - - enum class CsiActionCodes : wchar_t - { - ArrowUp = L'A', - ArrowDown = L'B', - ArrowRight = L'C', - ArrowLeft = L'D', - Home = L'H', - End = L'F', - MouseDown = L'M', - MouseUp = L'm', - Generic = L'~', // Used for a whole bunch of possible keys - CSI_F1 = L'P', - CSI_F2 = L'Q', - CSI_F3 = L'R', // Both F3 and DSR are on R. - // DSR_DeviceStatusReportResponse = L'R', - CSI_F4 = L'S', - DTTERM_WindowManipulation = L't', - CursorBackTab = L'Z', - Win32KeyboardInput = L'_' + ArrowUp = VTID("A"), + ArrowDown = VTID("B"), + ArrowRight = VTID("C"), + ArrowLeft = VTID("D"), + Home = VTID("H"), + End = VTID("F"), + MouseDown = VTID(" intermediates) override; + bool ActionEscDispatch(const VTID id) override; - bool ActionVt52EscDispatch(const wchar_t wch, - const gsl::span intermediates, - const gsl::span parameters) noexcept override; + bool ActionVt52EscDispatch(const VTID id, const gsl::span parameters) noexcept override; - bool ActionCsiDispatch(const wchar_t wch, - const gsl::span intermediates, - const gsl::span parameters) override; + bool ActionCsiDispatch(const VTID id, const gsl::span parameters) override; bool ActionClear() noexcept override; @@ -180,7 +170,7 @@ namespace Microsoft::Console::VirtualTerminal bool _lookingForDSR; DWORD _mouseButtonState = 0; - DWORD _GetCursorKeysModifierState(const gsl::span parameters, const CsiActionCodes actionCode) noexcept; + DWORD _GetCursorKeysModifierState(const gsl::span parameters, const VTID id) noexcept; DWORD _GetGenericKeysModifierState(const gsl::span parameters) noexcept; DWORD _GetSGRMouseModifierState(const gsl::span parameters) noexcept; bool _GenerateKeyFromChar(const wchar_t wch, short& vkey, DWORD& modifierState) noexcept; @@ -188,13 +178,13 @@ namespace Microsoft::Console::VirtualTerminal bool _IsModified(const size_t paramCount) noexcept; DWORD _GetModifier(const size_t parameter) noexcept; - bool _UpdateSGRMouseButtonState(const wchar_t wch, + bool _UpdateSGRMouseButtonState(const VTID id, const gsl::span parameters, DWORD& buttonState, DWORD& eventFlags) noexcept; bool _GetGenericVkey(const gsl::span parameters, short& vkey) const; - bool _GetCursorKeysVkey(const wchar_t wch, short& vkey) const; + bool _GetCursorKeysVkey(const VTID id, short& vkey) const; bool _GetSs3KeysVkey(const wchar_t wch, short& vkey) const; bool _WriteSingleKey(const short vkey, const DWORD modifierState); diff --git a/src/terminal/parser/OutputStateMachineEngine.cpp b/src/terminal/parser/OutputStateMachineEngine.cpp index 86a2023af93..cdecc28bbd8 100644 --- a/src/terminal/parser/OutputStateMachineEngine.cpp +++ b/src/terminal/parser/OutputStateMachineEngine.cpp @@ -179,89 +179,123 @@ bool OutputStateMachineEngine::ActionPassThroughString(const std::wstring_view s // a simple escape sequence. These sequences traditionally start with ESC // and a simple letter. No complicated parameters. // Arguments: -// - wch - Character to dispatch. -// - intermediates - Intermediate characters in the sequence +// - id - Identifier of the escape sequence to dispatch. // Return Value: // - true iff we successfully dispatched the sequence. -bool OutputStateMachineEngine::ActionEscDispatch(const wchar_t wch, - const gsl::span intermediates) +bool OutputStateMachineEngine::ActionEscDispatch(const VTID id) { - if (wch == L'\\' && intermediates.empty()) - { - // This is presumably the 7-bit string terminator, which is essentially a no-op. - return true; - } - bool success = false; - // no intermediates. - if (intermediates.empty()) + switch (id) { - switch (wch) + case EscActionCodes::ST_StringTerminator: + // This is the 7-bit string terminator, which is essentially a no-op. + success = true; + break; + case EscActionCodes::DECSC_CursorSave: + success = _dispatch->CursorSaveState(); + TermTelemetry::Instance().Log(TermTelemetry::Codes::DECSC); + break; + case EscActionCodes::DECRC_CursorRestore: + success = _dispatch->CursorRestoreState(); + TermTelemetry::Instance().Log(TermTelemetry::Codes::DECRC); + break; + case EscActionCodes::DECKPAM_KeypadApplicationMode: + success = _dispatch->SetKeypadMode(true); + TermTelemetry::Instance().Log(TermTelemetry::Codes::DECKPAM); + break; + case EscActionCodes::DECKPNM_KeypadNumericMode: + success = _dispatch->SetKeypadMode(false); + TermTelemetry::Instance().Log(TermTelemetry::Codes::DECKPNM); + break; + case EscActionCodes::NEL_NextLine: + success = _dispatch->LineFeed(DispatchTypes::LineFeedType::WithReturn); + TermTelemetry::Instance().Log(TermTelemetry::Codes::NEL); + break; + case EscActionCodes::IND_Index: + success = _dispatch->LineFeed(DispatchTypes::LineFeedType::WithoutReturn); + TermTelemetry::Instance().Log(TermTelemetry::Codes::IND); + break; + case EscActionCodes::RI_ReverseLineFeed: + success = _dispatch->ReverseLineFeed(); + TermTelemetry::Instance().Log(TermTelemetry::Codes::RI); + break; + case EscActionCodes::HTS_HorizontalTabSet: + success = _dispatch->HorizontalTabSet(); + TermTelemetry::Instance().Log(TermTelemetry::Codes::HTS); + break; + case EscActionCodes::RIS_ResetToInitialState: + success = _dispatch->HardReset(); + TermTelemetry::Instance().Log(TermTelemetry::Codes::RIS); + break; + case EscActionCodes::SS2_SingleShift: + success = _dispatch->SingleShift(2); + TermTelemetry::Instance().Log(TermTelemetry::Codes::SS2); + break; + case EscActionCodes::SS3_SingleShift: + success = _dispatch->SingleShift(3); + TermTelemetry::Instance().Log(TermTelemetry::Codes::SS3); + break; + case EscActionCodes::LS2_LockingShift: + success = _dispatch->LockingShift(2); + TermTelemetry::Instance().Log(TermTelemetry::Codes::LS2); + break; + case EscActionCodes::LS3_LockingShift: + success = _dispatch->LockingShift(3); + TermTelemetry::Instance().Log(TermTelemetry::Codes::LS3); + break; + case EscActionCodes::LS1R_LockingShift: + success = _dispatch->LockingShiftRight(1); + TermTelemetry::Instance().Log(TermTelemetry::Codes::LS1R); + break; + case EscActionCodes::LS2R_LockingShift: + success = _dispatch->LockingShiftRight(2); + TermTelemetry::Instance().Log(TermTelemetry::Codes::LS2R); + break; + case EscActionCodes::LS3R_LockingShift: + success = _dispatch->LockingShiftRight(3); + TermTelemetry::Instance().Log(TermTelemetry::Codes::LS3R); + break; + case EscActionCodes::DECALN_ScreenAlignmentPattern: + success = _dispatch->ScreenAlignmentPattern(); + TermTelemetry::Instance().Log(TermTelemetry::Codes::DECALN); + break; + default: + const auto commandChar = id[0]; + const auto commandParameter = id.SubSequence(1); + switch (commandChar) { - case VTActionCodes::DECSC_CursorSave: - success = _dispatch->CursorSaveState(); - TermTelemetry::Instance().Log(TermTelemetry::Codes::DECSC); - break; - case VTActionCodes::DECRC_CursorRestore: - success = _dispatch->CursorRestoreState(); - TermTelemetry::Instance().Log(TermTelemetry::Codes::DECRC); - break; - case VTActionCodes::DECKPAM_KeypadApplicationMode: - success = _dispatch->SetKeypadMode(true); - TermTelemetry::Instance().Log(TermTelemetry::Codes::DECKPAM); - break; - case VTActionCodes::DECKPNM_KeypadNumericMode: - success = _dispatch->SetKeypadMode(false); - TermTelemetry::Instance().Log(TermTelemetry::Codes::DECKPNM); - break; - case VTActionCodes::NEL_NextLine: - success = _dispatch->LineFeed(DispatchTypes::LineFeedType::WithReturn); - TermTelemetry::Instance().Log(TermTelemetry::Codes::NEL); - break; - case VTActionCodes::IND_Index: - success = _dispatch->LineFeed(DispatchTypes::LineFeedType::WithoutReturn); - TermTelemetry::Instance().Log(TermTelemetry::Codes::IND); - break; - case VTActionCodes::RI_ReverseLineFeed: - success = _dispatch->ReverseLineFeed(); - TermTelemetry::Instance().Log(TermTelemetry::Codes::RI); - break; - case VTActionCodes::HTS_HorizontalTabSet: - success = _dispatch->HorizontalTabSet(); - TermTelemetry::Instance().Log(TermTelemetry::Codes::HTS); - break; - case VTActionCodes::RIS_ResetToInitialState: - success = _dispatch->HardReset(); - TermTelemetry::Instance().Log(TermTelemetry::Codes::RIS); + case '%': + success = _dispatch->DesignateCodingSystem(commandParameter); + TermTelemetry::Instance().Log(TermTelemetry::Codes::DOCS); break; - case VTActionCodes::SS2_SingleShift: - success = _dispatch->SingleShift(2); - TermTelemetry::Instance().Log(TermTelemetry::Codes::SS2); + case '(': + success = _dispatch->Designate94Charset(0, commandParameter); + TermTelemetry::Instance().Log(TermTelemetry::Codes::DesignateG0); break; - case VTActionCodes::SS3_SingleShift: - success = _dispatch->SingleShift(3); - TermTelemetry::Instance().Log(TermTelemetry::Codes::SS3); + case ')': + success = _dispatch->Designate94Charset(1, commandParameter); + TermTelemetry::Instance().Log(TermTelemetry::Codes::DesignateG1); break; - case VTActionCodes::LS2_LockingShift: - success = _dispatch->LockingShift(2); - TermTelemetry::Instance().Log(TermTelemetry::Codes::LS2); + case '*': + success = _dispatch->Designate94Charset(2, commandParameter); + TermTelemetry::Instance().Log(TermTelemetry::Codes::DesignateG2); break; - case VTActionCodes::LS3_LockingShift: - success = _dispatch->LockingShift(3); - TermTelemetry::Instance().Log(TermTelemetry::Codes::LS3); + case '+': + success = _dispatch->Designate94Charset(3, commandParameter); + TermTelemetry::Instance().Log(TermTelemetry::Codes::DesignateG3); break; - case VTActionCodes::LS1R_LockingShift: - success = _dispatch->LockingShiftRight(1); - TermTelemetry::Instance().Log(TermTelemetry::Codes::LS1R); + case '-': + success = _dispatch->Designate96Charset(1, commandParameter); + TermTelemetry::Instance().Log(TermTelemetry::Codes::DesignateG1); break; - case VTActionCodes::LS2R_LockingShift: - success = _dispatch->LockingShiftRight(2); - TermTelemetry::Instance().Log(TermTelemetry::Codes::LS2R); + case '.': + success = _dispatch->Designate96Charset(2, commandParameter); + TermTelemetry::Instance().Log(TermTelemetry::Codes::DesignateG2); break; - case VTActionCodes::LS3R_LockingShift: - success = _dispatch->LockingShiftRight(3); - TermTelemetry::Instance().Log(TermTelemetry::Codes::LS3R); + case '/': + success = _dispatch->Designate96Charset(3, commandParameter); + TermTelemetry::Instance().Log(TermTelemetry::Codes::DesignateG3); break; default: // If no functions to call, overall dispatch was a failure. @@ -269,36 +303,6 @@ bool OutputStateMachineEngine::ActionEscDispatch(const wchar_t wch, break; } } - else if (intermediates.size() == 1) - { - switch (til::at(intermediates, 0)) - { - case L'%': - success = _dispatch->DesignateCodingSystem(wch); - TermTelemetry::Instance().Log(TermTelemetry::Codes::DOCS); - break; - case L'#': - switch (wch) - { - case VTActionCodes::DECALN_ScreenAlignmentPattern: - success = _dispatch->ScreenAlignmentPattern(); - TermTelemetry::Instance().Log(TermTelemetry::Codes::DECALN); - break; - default: - // If no functions to call, overall dispatch was a failure. - success = false; - break; - } - break; - default: - success = _IntermediateScsDispatch(wch, intermediates); - break; - } - } - else if (intermediates.size() == 2) - { - success = _IntermediateScsDispatch(wch, intermediates); - } // If we were unable to process the string, and there's a TTY attached to us, // trigger the state machine to flush the string to the terminal. @@ -317,135 +321,74 @@ bool OutputStateMachineEngine::ActionEscDispatch(const wchar_t wch, // a VT52 escape sequence. These sequences start with ESC and a single letter, // sometimes followed by parameters. // Arguments: -// - wch - Character to dispatch. -// - intermediates - Intermediate characters in the sequence. +// - id - Identifier of the VT52 sequence to dispatch. // - parameters - Set of parameters collected while parsing the sequence. // Return Value: // - true iff we successfully dispatched the sequence. -bool OutputStateMachineEngine::ActionVt52EscDispatch(const wchar_t wch, - const gsl::span intermediates, - const gsl::span parameters) -{ - bool success = false; - - // no intermediates. - if (intermediates.empty()) - { - switch (wch) - { - case Vt52ActionCodes::CursorUp: - success = _dispatch->CursorUp(1); - break; - case Vt52ActionCodes::CursorDown: - success = _dispatch->CursorDown(1); - break; - case Vt52ActionCodes::CursorRight: - success = _dispatch->CursorForward(1); - break; - case Vt52ActionCodes::CursorLeft: - success = _dispatch->CursorBackward(1); - break; - case Vt52ActionCodes::EnterGraphicsMode: - success = _dispatch->Designate94Charset(0, DispatchTypes::CharacterSets::DecSpecialGraphics); - break; - case Vt52ActionCodes::ExitGraphicsMode: - success = _dispatch->Designate94Charset(0, DispatchTypes::CharacterSets::ASCII); - break; - case Vt52ActionCodes::CursorToHome: - success = _dispatch->CursorPosition(1, 1); - break; - case Vt52ActionCodes::ReverseLineFeed: - success = _dispatch->ReverseLineFeed(); - break; - case Vt52ActionCodes::EraseToEndOfScreen: - success = _dispatch->EraseInDisplay(DispatchTypes::EraseType::ToEnd); - break; - case Vt52ActionCodes::EraseToEndOfLine: - success = _dispatch->EraseInLine(DispatchTypes::EraseType::ToEnd); - break; - case Vt52ActionCodes::DirectCursorAddress: - // VT52 cursor addresses are provided as ASCII characters, with - // the lowest value being a space, representing an address of 1. - success = _dispatch->CursorPosition(gsl::at(parameters, 0) - ' ' + 1, gsl::at(parameters, 1) - ' ' + 1); - break; - case Vt52ActionCodes::Identify: - success = _dispatch->Vt52DeviceAttributes(); - break; - case Vt52ActionCodes::EnterAlternateKeypadMode: - success = _dispatch->SetKeypadMode(true); - break; - case Vt52ActionCodes::ExitAlternateKeypadMode: - success = _dispatch->SetKeypadMode(false); - break; - case Vt52ActionCodes::ExitVt52Mode: - { - const DispatchTypes::PrivateModeParams mode[] = { DispatchTypes::PrivateModeParams::DECANM_AnsiMode }; - success = _dispatch->SetPrivateModes(mode); - break; - } - default: - // If no functions to call, overall dispatch was a failure. - success = false; - break; - } - } - - _ClearLastChar(); - - return success; -} - -// Routine Description: -// - Handles SCS charset designation actions that can have one or two possible intermediates. -// Arguments: -// - wch - Character to dispatch. -// - intermediates - Intermediate characters in the sequence -// Return Value: -// - True if handled successfully. False otherwise. -bool OutputStateMachineEngine::_IntermediateScsDispatch(const wchar_t wch, - const gsl::span intermediates) +bool OutputStateMachineEngine::ActionVt52EscDispatch(const VTID id, const gsl::span parameters) { bool success = false; - // If we have more than one intermediate, the second intermediate forms part of - // the charset identifier. Otherwise it's identified by just the final character. - const auto charset = intermediates.size() > 1 ? std::make_pair(til::at(intermediates, 1), wch) : std::make_pair(wch, L'\0'); - - switch (til::at(intermediates, 0)) + switch (id) { - case L'(': - success = _dispatch->Designate94Charset(0, charset); - TermTelemetry::Instance().Log(TermTelemetry::Codes::DesignateG0); + case Vt52ActionCodes::CursorUp: + success = _dispatch->CursorUp(1); + break; + case Vt52ActionCodes::CursorDown: + success = _dispatch->CursorDown(1); + break; + case Vt52ActionCodes::CursorRight: + success = _dispatch->CursorForward(1); + break; + case Vt52ActionCodes::CursorLeft: + success = _dispatch->CursorBackward(1); + break; + case Vt52ActionCodes::EnterGraphicsMode: + success = _dispatch->Designate94Charset(0, DispatchTypes::CharacterSets::DecSpecialGraphics); + break; + case Vt52ActionCodes::ExitGraphicsMode: + success = _dispatch->Designate94Charset(0, DispatchTypes::CharacterSets::ASCII); + break; + case Vt52ActionCodes::CursorToHome: + success = _dispatch->CursorPosition(1, 1); + break; + case Vt52ActionCodes::ReverseLineFeed: + success = _dispatch->ReverseLineFeed(); + break; + case Vt52ActionCodes::EraseToEndOfScreen: + success = _dispatch->EraseInDisplay(DispatchTypes::EraseType::ToEnd); break; - case L')': - success = _dispatch->Designate94Charset(1, charset); - TermTelemetry::Instance().Log(TermTelemetry::Codes::DesignateG1); + case Vt52ActionCodes::EraseToEndOfLine: + success = _dispatch->EraseInLine(DispatchTypes::EraseType::ToEnd); break; - case L'*': - success = _dispatch->Designate94Charset(2, charset); - TermTelemetry::Instance().Log(TermTelemetry::Codes::DesignateG2); + case Vt52ActionCodes::DirectCursorAddress: + // VT52 cursor addresses are provided as ASCII characters, with + // the lowest value being a space, representing an address of 1. + success = _dispatch->CursorPosition(gsl::at(parameters, 0) - ' ' + 1, gsl::at(parameters, 1) - ' ' + 1); break; - case L'+': - success = _dispatch->Designate94Charset(3, charset); - TermTelemetry::Instance().Log(TermTelemetry::Codes::DesignateG3); + case Vt52ActionCodes::Identify: + success = _dispatch->Vt52DeviceAttributes(); break; - case L'-': - success = _dispatch->Designate96Charset(1, charset); - TermTelemetry::Instance().Log(TermTelemetry::Codes::DesignateG1); + case Vt52ActionCodes::EnterAlternateKeypadMode: + success = _dispatch->SetKeypadMode(true); break; - case L'.': - success = _dispatch->Designate96Charset(2, charset); - TermTelemetry::Instance().Log(TermTelemetry::Codes::DesignateG2); + case Vt52ActionCodes::ExitAlternateKeypadMode: + success = _dispatch->SetKeypadMode(false); break; - case L'/': - success = _dispatch->Designate96Charset(3, charset); - TermTelemetry::Instance().Log(TermTelemetry::Codes::DesignateG3); + case Vt52ActionCodes::ExitVt52Mode: + { + const DispatchTypes::PrivateModeParams mode[] = { DispatchTypes::PrivateModeParams::DECANM_AnsiMode }; + success = _dispatch->SetPrivateModes(mode); break; + } default: + // If no functions to call, overall dispatch was a failure. success = false; break; } + _ClearLastChar(); + return success; } @@ -454,14 +397,11 @@ bool OutputStateMachineEngine::_IntermediateScsDispatch(const wchar_t wch, // a control sequence. These sequences perform various API-type commands // that can include many parameters. // Arguments: -// - wch - Character to dispatch. -// - intermediates - Intermediate characters in the sequence +// - id - Identifier of the control sequence to dispatch. // - parameters - set of numeric parameters collected while parsing the sequence. // Return Value: // - true iff we successfully dispatched the sequence. -bool OutputStateMachineEngine::ActionCsiDispatch(const wchar_t wch, - const gsl::span intermediates, - gsl::span parameters) +bool OutputStateMachineEngine::ActionCsiDispatch(const VTID id, gsl::span parameters) { bool success = false; size_t distance = 0; @@ -473,420 +413,262 @@ bool OutputStateMachineEngine::ActionCsiDispatch(const wchar_t wch, size_t clearType = 0; unsigned int function = 0; DispatchTypes::EraseType eraseType = DispatchTypes::EraseType::ToEnd; + std::vector privateModeParams; // We hold the vector in the class because client applications that do a lot of color work // would spend a lot of time reallocating/resizing the vector. _graphicsOptions.clear(); DispatchTypes::AnsiStatusType deviceStatusType = static_cast(0); // there is no default status type. size_t repeatCount = 0; + DispatchTypes::CursorStyle cursorStyle = DefaultCursorStyle; // This is all the args after the first arg, and the count of args not including the first one. const auto remainingParams = parameters.size() > 1 ? parameters.subspan(1) : gsl::span{}; - if (intermediates.empty()) - { - // fill params - switch (wch) - { - case VTActionCodes::CUU_CursorUp: - case VTActionCodes::CUD_CursorDown: - case VTActionCodes::CUF_CursorForward: - case VTActionCodes::CUB_CursorBackward: - case VTActionCodes::CNL_CursorNextLine: - case VTActionCodes::CPL_CursorPrevLine: - case VTActionCodes::CHA_CursorHorizontalAbsolute: - case VTActionCodes::HPA_HorizontalPositionAbsolute: - case VTActionCodes::VPA_VerticalLinePositionAbsolute: - case VTActionCodes::HPR_HorizontalPositionRelative: - case VTActionCodes::VPR_VerticalPositionRelative: - case VTActionCodes::ICH_InsertCharacter: - case VTActionCodes::DCH_DeleteCharacter: - case VTActionCodes::ECH_EraseCharacters: - success = _GetCursorDistance(parameters, distance); - break; - case VTActionCodes::HVP_HorizontalVerticalPosition: - case VTActionCodes::CUP_CursorPosition: - success = _GetXYPosition(parameters, line, column); - break; - case VTActionCodes::DECSTBM_SetScrollingRegion: - success = _GetTopBottomMargins(parameters, topMargin, bottomMargin); - break; - case VTActionCodes::ED_EraseDisplay: - case VTActionCodes::EL_EraseLine: - success = _GetEraseOperation(parameters, eraseType); - break; - case VTActionCodes::SGR_SetGraphicsRendition: - success = _GetGraphicsOptions(parameters, _graphicsOptions); - break; - case VTActionCodes::DSR_DeviceStatusReport: - success = _GetDeviceStatusOperation(parameters, deviceStatusType); - break; - case VTActionCodes::DA_DeviceAttributes: - success = _VerifyDeviceAttributesParams(parameters); - break; - case VTActionCodes::SU_ScrollUp: - case VTActionCodes::SD_ScrollDown: - success = _GetScrollDistance(parameters, distance); - break; - case VTActionCodes::ANSISYSSC_CursorSave: - case VTActionCodes::ANSISYSRC_CursorRestore: - success = _VerifyHasNoParameters(parameters); - break; - case VTActionCodes::IL_InsertLine: - case VTActionCodes::DL_DeleteLine: - success = _GetScrollDistance(parameters, distance); - break; - case VTActionCodes::CHT_CursorForwardTab: - case VTActionCodes::CBT_CursorBackTab: - success = _GetTabDistance(parameters, numTabs); - break; - case VTActionCodes::TBC_TabClear: - success = _GetTabClearType(parameters, clearType); - break; - case VTActionCodes::DTTERM_WindowManipulation: - success = _GetWindowManipulationType(parameters, function); - break; - case VTActionCodes::REP_RepeatCharacter: - success = _GetRepeatCount(parameters, repeatCount); - break; - default: - // If no params to fill, param filling was successful. - success = true; - break; - } - - // if param filling successful, try to dispatch - if (success) - { - switch (wch) - { - case VTActionCodes::CUU_CursorUp: - success = _dispatch->CursorUp(distance); - TermTelemetry::Instance().Log(TermTelemetry::Codes::CUU); - break; - case VTActionCodes::CUD_CursorDown: - success = _dispatch->CursorDown(distance); - TermTelemetry::Instance().Log(TermTelemetry::Codes::CUD); - break; - case VTActionCodes::CUF_CursorForward: - success = _dispatch->CursorForward(distance); - TermTelemetry::Instance().Log(TermTelemetry::Codes::CUF); - break; - case VTActionCodes::CUB_CursorBackward: - success = _dispatch->CursorBackward(distance); - TermTelemetry::Instance().Log(TermTelemetry::Codes::CUB); - break; - case VTActionCodes::CNL_CursorNextLine: - success = _dispatch->CursorNextLine(distance); - TermTelemetry::Instance().Log(TermTelemetry::Codes::CNL); - break; - case VTActionCodes::CPL_CursorPrevLine: - success = _dispatch->CursorPrevLine(distance); - TermTelemetry::Instance().Log(TermTelemetry::Codes::CPL); - break; - case VTActionCodes::CHA_CursorHorizontalAbsolute: - case VTActionCodes::HPA_HorizontalPositionAbsolute: - success = _dispatch->CursorHorizontalPositionAbsolute(distance); - TermTelemetry::Instance().Log(TermTelemetry::Codes::CHA); - break; - case VTActionCodes::VPA_VerticalLinePositionAbsolute: - success = _dispatch->VerticalLinePositionAbsolute(distance); - TermTelemetry::Instance().Log(TermTelemetry::Codes::VPA); - break; - case VTActionCodes::HPR_HorizontalPositionRelative: - success = _dispatch->HorizontalPositionRelative(distance); - TermTelemetry::Instance().Log(TermTelemetry::Codes::HPR); - break; - case VTActionCodes::VPR_VerticalPositionRelative: - success = _dispatch->VerticalPositionRelative(distance); - TermTelemetry::Instance().Log(TermTelemetry::Codes::VPR); - break; - case VTActionCodes::CUP_CursorPosition: - case VTActionCodes::HVP_HorizontalVerticalPosition: - success = _dispatch->CursorPosition(line, column); - TermTelemetry::Instance().Log(TermTelemetry::Codes::CUP); - break; - case VTActionCodes::DECSTBM_SetScrollingRegion: - success = _dispatch->SetTopBottomScrollingMargins(topMargin, bottomMargin); - TermTelemetry::Instance().Log(TermTelemetry::Codes::DECSTBM); - break; - case VTActionCodes::ICH_InsertCharacter: - success = _dispatch->InsertCharacter(distance); - TermTelemetry::Instance().Log(TermTelemetry::Codes::ICH); - break; - case VTActionCodes::DCH_DeleteCharacter: - success = _dispatch->DeleteCharacter(distance); - TermTelemetry::Instance().Log(TermTelemetry::Codes::DCH); - break; - case VTActionCodes::ED_EraseDisplay: - success = _dispatch->EraseInDisplay(eraseType); - TermTelemetry::Instance().Log(TermTelemetry::Codes::ED); - break; - case VTActionCodes::EL_EraseLine: - success = _dispatch->EraseInLine(eraseType); - TermTelemetry::Instance().Log(TermTelemetry::Codes::EL); - break; - case VTActionCodes::SGR_SetGraphicsRendition: - success = _dispatch->SetGraphicsRendition({ _graphicsOptions.data(), _graphicsOptions.size() }); - TermTelemetry::Instance().Log(TermTelemetry::Codes::SGR); - break; - case VTActionCodes::DSR_DeviceStatusReport: - success = _dispatch->DeviceStatusReport(deviceStatusType); - TermTelemetry::Instance().Log(TermTelemetry::Codes::DSR); - break; - case VTActionCodes::DA_DeviceAttributes: - success = _dispatch->DeviceAttributes(); - TermTelemetry::Instance().Log(TermTelemetry::Codes::DA); - break; - case VTActionCodes::SU_ScrollUp: - success = _dispatch->ScrollUp(distance); - TermTelemetry::Instance().Log(TermTelemetry::Codes::SU); - break; - case VTActionCodes::SD_ScrollDown: - success = _dispatch->ScrollDown(distance); - TermTelemetry::Instance().Log(TermTelemetry::Codes::SD); - break; - case VTActionCodes::ANSISYSSC_CursorSave: - success = _dispatch->CursorSaveState(); - TermTelemetry::Instance().Log(TermTelemetry::Codes::ANSISYSSC); - break; - case VTActionCodes::ANSISYSRC_CursorRestore: - success = _dispatch->CursorRestoreState(); - TermTelemetry::Instance().Log(TermTelemetry::Codes::ANSISYSRC); - break; - case VTActionCodes::IL_InsertLine: - success = _dispatch->InsertLine(distance); - TermTelemetry::Instance().Log(TermTelemetry::Codes::IL); - break; - case VTActionCodes::DL_DeleteLine: - success = _dispatch->DeleteLine(distance); - TermTelemetry::Instance().Log(TermTelemetry::Codes::DL); - break; - case VTActionCodes::CHT_CursorForwardTab: - success = _dispatch->ForwardTab(numTabs); - TermTelemetry::Instance().Log(TermTelemetry::Codes::CHT); - break; - case VTActionCodes::CBT_CursorBackTab: - success = _dispatch->BackwardsTab(numTabs); - TermTelemetry::Instance().Log(TermTelemetry::Codes::CBT); - break; - case VTActionCodes::TBC_TabClear: - success = _dispatch->TabClear(clearType); - TermTelemetry::Instance().Log(TermTelemetry::Codes::TBC); - break; - case VTActionCodes::ECH_EraseCharacters: - success = _dispatch->EraseCharacters(distance); - TermTelemetry::Instance().Log(TermTelemetry::Codes::ECH); - break; - case VTActionCodes::DTTERM_WindowManipulation: - success = _dispatch->WindowManipulation(static_cast(function), - remainingParams); - TermTelemetry::Instance().Log(TermTelemetry::Codes::DTTERM_WM); - break; - case VTActionCodes::REP_RepeatCharacter: - // Handled w/o the dispatch. This function is unique in that way - // If this were in the ITerminalDispatch, then each - // implementation would effectively be the same, calling only - // functions that are already part of the interface. - // Print the last graphical character a number of times. - if (_lastPrintedChar != AsciiChars::NUL) - { - std::wstring wstr(repeatCount, _lastPrintedChar); - _dispatch->PrintString(wstr); - } - success = true; - TermTelemetry::Instance().Log(TermTelemetry::Codes::REP); - break; - default: - // If no functions to call, overall dispatch was a failure. - success = false; - break; - } - } - } - else if (intermediates.size() == 1) - { - const auto value = til::at(intermediates, 0); - switch (value) - { - case L'?': - success = _IntermediateQuestionMarkDispatch(wch, parameters); - break; - case L'>': - case L'=': - success = _IntermediateGreaterThanOrEqualDispatch(wch, value, parameters); - break; - case L'!': - success = _IntermediateExclamationDispatch(wch); - break; - case L' ': - success = _IntermediateSpaceDispatch(wch, parameters); - break; - default: - // If no functions to call, overall dispatch was a failure. - success = false; - break; - } - } - // If we were unable to process the string, and there's a TTY attached to us, - // trigger the state machine to flush the string to the terminal. - if (_pfnFlushToTerminal != nullptr && !success) - { - success = _pfnFlushToTerminal(); - } - - _ClearLastChar(); - - return success; -} - -// Routine Description: -// - Handles actions that have postfix params on an intermediate '?', such as DECTCEM, DECCOLM, ATT610 -// Arguments: -// - wch - Character to dispatch. -// - parameters - set of numeric parameters collected while parsing the sequence. -// Return Value: -// - True if handled successfully. False otherwise. -bool OutputStateMachineEngine::_IntermediateQuestionMarkDispatch(const wchar_t wchAction, - const gsl::span parameters) -{ - bool success = false; - - std::vector privateModeParams; - // Ensure that there was the right number of params - switch (wchAction) - { - case VTActionCodes::DECSET_PrivateModeSet: - case VTActionCodes::DECRST_PrivateModeReset: + // fill params + switch (id) + { + case CsiActionCodes::CUU_CursorUp: + case CsiActionCodes::CUD_CursorDown: + case CsiActionCodes::CUF_CursorForward: + case CsiActionCodes::CUB_CursorBackward: + case CsiActionCodes::CNL_CursorNextLine: + case CsiActionCodes::CPL_CursorPrevLine: + case CsiActionCodes::CHA_CursorHorizontalAbsolute: + case CsiActionCodes::HPA_HorizontalPositionAbsolute: + case CsiActionCodes::VPA_VerticalLinePositionAbsolute: + case CsiActionCodes::HPR_HorizontalPositionRelative: + case CsiActionCodes::VPR_VerticalPositionRelative: + case CsiActionCodes::ICH_InsertCharacter: + case CsiActionCodes::DCH_DeleteCharacter: + case CsiActionCodes::ECH_EraseCharacters: + success = _GetCursorDistance(parameters, distance); + break; + case CsiActionCodes::HVP_HorizontalVerticalPosition: + case CsiActionCodes::CUP_CursorPosition: + success = _GetXYPosition(parameters, line, column); + break; + case CsiActionCodes::DECSTBM_SetScrollingRegion: + success = _GetTopBottomMargins(parameters, topMargin, bottomMargin); + break; + case CsiActionCodes::ED_EraseDisplay: + case CsiActionCodes::EL_EraseLine: + success = _GetEraseOperation(parameters, eraseType); + break; + case CsiActionCodes::DECSET_PrivateModeSet: + case CsiActionCodes::DECRST_PrivateModeReset: success = _GetPrivateModeParams(parameters, privateModeParams); break; - + case CsiActionCodes::SGR_SetGraphicsRendition: + success = _GetGraphicsOptions(parameters, _graphicsOptions); + break; + case CsiActionCodes::DSR_DeviceStatusReport: + success = _GetDeviceStatusOperation(parameters, deviceStatusType); + break; + case CsiActionCodes::DA_DeviceAttributes: + case CsiActionCodes::DA2_SecondaryDeviceAttributes: + case CsiActionCodes::DA3_TertiaryDeviceAttributes: + success = _VerifyDeviceAttributesParams(parameters); + break; + case CsiActionCodes::SU_ScrollUp: + case CsiActionCodes::SD_ScrollDown: + success = _GetScrollDistance(parameters, distance); + break; + case CsiActionCodes::ANSISYSSC_CursorSave: + case CsiActionCodes::ANSISYSRC_CursorRestore: + success = _VerifyHasNoParameters(parameters); + break; + case CsiActionCodes::IL_InsertLine: + case CsiActionCodes::DL_DeleteLine: + success = _GetScrollDistance(parameters, distance); + break; + case CsiActionCodes::CHT_CursorForwardTab: + case CsiActionCodes::CBT_CursorBackTab: + success = _GetTabDistance(parameters, numTabs); + break; + case CsiActionCodes::TBC_TabClear: + success = _GetTabClearType(parameters, clearType); + break; + case CsiActionCodes::DTTERM_WindowManipulation: + success = _GetWindowManipulationType(parameters, function); + break; + case CsiActionCodes::REP_RepeatCharacter: + success = _GetRepeatCount(parameters, repeatCount); + break; + case CsiActionCodes::DECSCUSR_SetCursorStyle: + success = _GetCursorStyle(parameters, cursorStyle); + break; default: // If no params to fill, param filling was successful. success = true; break; } + + // if param filling successful, try to dispatch if (success) { - switch (wchAction) + switch (id) { - case VTActionCodes::DECSET_PrivateModeSet: + case CsiActionCodes::CUU_CursorUp: + success = _dispatch->CursorUp(distance); + TermTelemetry::Instance().Log(TermTelemetry::Codes::CUU); + break; + case CsiActionCodes::CUD_CursorDown: + success = _dispatch->CursorDown(distance); + TermTelemetry::Instance().Log(TermTelemetry::Codes::CUD); + break; + case CsiActionCodes::CUF_CursorForward: + success = _dispatch->CursorForward(distance); + TermTelemetry::Instance().Log(TermTelemetry::Codes::CUF); + break; + case CsiActionCodes::CUB_CursorBackward: + success = _dispatch->CursorBackward(distance); + TermTelemetry::Instance().Log(TermTelemetry::Codes::CUB); + break; + case CsiActionCodes::CNL_CursorNextLine: + success = _dispatch->CursorNextLine(distance); + TermTelemetry::Instance().Log(TermTelemetry::Codes::CNL); + break; + case CsiActionCodes::CPL_CursorPrevLine: + success = _dispatch->CursorPrevLine(distance); + TermTelemetry::Instance().Log(TermTelemetry::Codes::CPL); + break; + case CsiActionCodes::CHA_CursorHorizontalAbsolute: + case CsiActionCodes::HPA_HorizontalPositionAbsolute: + success = _dispatch->CursorHorizontalPositionAbsolute(distance); + TermTelemetry::Instance().Log(TermTelemetry::Codes::CHA); + break; + case CsiActionCodes::VPA_VerticalLinePositionAbsolute: + success = _dispatch->VerticalLinePositionAbsolute(distance); + TermTelemetry::Instance().Log(TermTelemetry::Codes::VPA); + break; + case CsiActionCodes::HPR_HorizontalPositionRelative: + success = _dispatch->HorizontalPositionRelative(distance); + TermTelemetry::Instance().Log(TermTelemetry::Codes::HPR); + break; + case CsiActionCodes::VPR_VerticalPositionRelative: + success = _dispatch->VerticalPositionRelative(distance); + TermTelemetry::Instance().Log(TermTelemetry::Codes::VPR); + break; + case CsiActionCodes::CUP_CursorPosition: + case CsiActionCodes::HVP_HorizontalVerticalPosition: + success = _dispatch->CursorPosition(line, column); + TermTelemetry::Instance().Log(TermTelemetry::Codes::CUP); + break; + case CsiActionCodes::DECSTBM_SetScrollingRegion: + success = _dispatch->SetTopBottomScrollingMargins(topMargin, bottomMargin); + TermTelemetry::Instance().Log(TermTelemetry::Codes::DECSTBM); + break; + case CsiActionCodes::ICH_InsertCharacter: + success = _dispatch->InsertCharacter(distance); + TermTelemetry::Instance().Log(TermTelemetry::Codes::ICH); + break; + case CsiActionCodes::DCH_DeleteCharacter: + success = _dispatch->DeleteCharacter(distance); + TermTelemetry::Instance().Log(TermTelemetry::Codes::DCH); + break; + case CsiActionCodes::ED_EraseDisplay: + success = _dispatch->EraseInDisplay(eraseType); + TermTelemetry::Instance().Log(TermTelemetry::Codes::ED); + break; + case CsiActionCodes::EL_EraseLine: + success = _dispatch->EraseInLine(eraseType); + TermTelemetry::Instance().Log(TermTelemetry::Codes::EL); + break; + case CsiActionCodes::DECSET_PrivateModeSet: success = _dispatch->SetPrivateModes({ privateModeParams.data(), privateModeParams.size() }); //TODO: MSFT:6367459 Add specific logging for each of the DECSET/DECRST codes TermTelemetry::Instance().Log(TermTelemetry::Codes::DECSET); break; - case VTActionCodes::DECRST_PrivateModeReset: + case CsiActionCodes::DECRST_PrivateModeReset: success = _dispatch->ResetPrivateModes({ privateModeParams.data(), privateModeParams.size() }); TermTelemetry::Instance().Log(TermTelemetry::Codes::DECRST); break; - default: - // If no functions to call, overall dispatch was a failure. - success = false; + case CsiActionCodes::SGR_SetGraphicsRendition: + success = _dispatch->SetGraphicsRendition({ _graphicsOptions.data(), _graphicsOptions.size() }); + TermTelemetry::Instance().Log(TermTelemetry::Codes::SGR); break; - } - } - return success; -} - -// Routine Description: -// - Handles actions that have postfix params on an intermediate '>' or '='. -// Arguments: -// - wch - Character to dispatch. -// - intermediate - The intermediate character. -// - parameters - Set of numeric parameters collected while parsing the sequence. -// Return Value: -// - True if handled successfully. False otherwise. -bool OutputStateMachineEngine::_IntermediateGreaterThanOrEqualDispatch(const wchar_t wch, - const wchar_t intermediate, - const gsl::span parameters) -{ - bool success = false; - - switch (wch) - { - case VTActionCodes::DA_DeviceAttributes: - if (_VerifyDeviceAttributesParams(parameters)) - { - switch (intermediate) + case CsiActionCodes::DSR_DeviceStatusReport: + success = _dispatch->DeviceStatusReport(deviceStatusType); + TermTelemetry::Instance().Log(TermTelemetry::Codes::DSR); + break; + case CsiActionCodes::DA_DeviceAttributes: + success = _dispatch->DeviceAttributes(); + TermTelemetry::Instance().Log(TermTelemetry::Codes::DA); + break; + case CsiActionCodes::DA2_SecondaryDeviceAttributes: + success = _dispatch->SecondaryDeviceAttributes(); + TermTelemetry::Instance().Log(TermTelemetry::Codes::DA2); + break; + case CsiActionCodes::DA3_TertiaryDeviceAttributes: + success = _dispatch->TertiaryDeviceAttributes(); + TermTelemetry::Instance().Log(TermTelemetry::Codes::DA3); + break; + case CsiActionCodes::SU_ScrollUp: + success = _dispatch->ScrollUp(distance); + TermTelemetry::Instance().Log(TermTelemetry::Codes::SU); + break; + case CsiActionCodes::SD_ScrollDown: + success = _dispatch->ScrollDown(distance); + TermTelemetry::Instance().Log(TermTelemetry::Codes::SD); + break; + case CsiActionCodes::ANSISYSSC_CursorSave: + success = _dispatch->CursorSaveState(); + TermTelemetry::Instance().Log(TermTelemetry::Codes::ANSISYSSC); + break; + case CsiActionCodes::ANSISYSRC_CursorRestore: + success = _dispatch->CursorRestoreState(); + TermTelemetry::Instance().Log(TermTelemetry::Codes::ANSISYSRC); + break; + case CsiActionCodes::IL_InsertLine: + success = _dispatch->InsertLine(distance); + TermTelemetry::Instance().Log(TermTelemetry::Codes::IL); + break; + case CsiActionCodes::DL_DeleteLine: + success = _dispatch->DeleteLine(distance); + TermTelemetry::Instance().Log(TermTelemetry::Codes::DL); + break; + case CsiActionCodes::CHT_CursorForwardTab: + success = _dispatch->ForwardTab(numTabs); + TermTelemetry::Instance().Log(TermTelemetry::Codes::CHT); + break; + case CsiActionCodes::CBT_CursorBackTab: + success = _dispatch->BackwardsTab(numTabs); + TermTelemetry::Instance().Log(TermTelemetry::Codes::CBT); + break; + case CsiActionCodes::TBC_TabClear: + success = _dispatch->TabClear(clearType); + TermTelemetry::Instance().Log(TermTelemetry::Codes::TBC); + break; + case CsiActionCodes::ECH_EraseCharacters: + success = _dispatch->EraseCharacters(distance); + TermTelemetry::Instance().Log(TermTelemetry::Codes::ECH); + break; + case CsiActionCodes::DTTERM_WindowManipulation: + success = _dispatch->WindowManipulation(static_cast(function), + remainingParams); + TermTelemetry::Instance().Log(TermTelemetry::Codes::DTTERM_WM); + break; + case CsiActionCodes::REP_RepeatCharacter: + // Handled w/o the dispatch. This function is unique in that way + // If this were in the ITerminalDispatch, then each + // implementation would effectively be the same, calling only + // functions that are already part of the interface. + // Print the last graphical character a number of times. + if (_lastPrintedChar != AsciiChars::NUL) { - case L'>': - success = _dispatch->SecondaryDeviceAttributes(); - TermTelemetry::Instance().Log(TermTelemetry::Codes::DA2); - break; - case L'=': - success = _dispatch->TertiaryDeviceAttributes(); - TermTelemetry::Instance().Log(TermTelemetry::Codes::DA3); - break; - default: - success = false; - break; + std::wstring wstr(repeatCount, _lastPrintedChar); + _dispatch->PrintString(wstr); } - } - break; - default: - success = false; - break; - } - - return success; -} - -// Routine Description: -// - Handles actions that have an intermediate '!', such as DECSTR -// Arguments: -// - wch - Character to dispatch. -// Return Value: -// - True if handled successfully. False otherwise. -bool OutputStateMachineEngine::_IntermediateExclamationDispatch(const wchar_t wchAction) -{ - bool success = false; - - switch (wchAction) - { - case VTActionCodes::DECSTR_SoftReset: - success = _dispatch->SoftReset(); - TermTelemetry::Instance().Log(TermTelemetry::Codes::DECSTR); - break; - default: - // If no functions to call, overall dispatch was a failure. - success = false; - break; - } - return success; -} - -// Routine Description: -// - Handles actions that have an intermediate ' ' (0x20), such as DECSCUSR -// Arguments: -// - wch - Character to dispatch. -// - parameters - set of numeric parameters collected while parsing the sequence. -// Return Value: -// - True if handled successfully. False otherwise. -bool OutputStateMachineEngine::_IntermediateSpaceDispatch(const wchar_t wchAction, - const gsl::span parameters) -{ - bool success = false; - DispatchTypes::CursorStyle cursorStyle = DefaultCursorStyle; - - // Parse params - switch (wchAction) - { - case VTActionCodes::DECSCUSR_SetCursorStyle: - success = _GetCursorStyle(parameters, cursorStyle); - break; - default: - // If no functions to call, overall dispatch was a failure. - success = false; - break; - } - - // if param filling successful, try to dispatch - if (success) - { - switch (wchAction) - { - case VTActionCodes::DECSCUSR_SetCursorStyle: + success = true; + TermTelemetry::Instance().Log(TermTelemetry::Codes::REP); + break; + case CsiActionCodes::DECSCUSR_SetCursorStyle: success = _dispatch->SetCursorStyle(cursorStyle); TermTelemetry::Instance().Log(TermTelemetry::Codes::DECSCUSR); break; + case CsiActionCodes::DECSTR_SoftReset: + success = _dispatch->SoftReset(); + TermTelemetry::Instance().Log(TermTelemetry::Codes::DECSTR); + break; default: // If no functions to call, overall dispatch was a failure. success = false; @@ -894,6 +676,15 @@ bool OutputStateMachineEngine::_IntermediateSpaceDispatch(const wchar_t wchActio } } + // If we were unable to process the string, and there's a TTY attached to us, + // trigger the state machine to flush the string to the terminal. + if (_pfnFlushToTerminal != nullptr && !success) + { + success = _pfnFlushToTerminal(); + } + + _ClearLastChar(); + return success; } diff --git a/src/terminal/parser/OutputStateMachineEngine.hpp b/src/terminal/parser/OutputStateMachineEngine.hpp index bce98255e0e..e6332a076e1 100644 --- a/src/terminal/parser/OutputStateMachineEngine.hpp +++ b/src/terminal/parser/OutputStateMachineEngine.hpp @@ -33,16 +33,11 @@ namespace Microsoft::Console::VirtualTerminal bool ActionPassThroughString(const std::wstring_view string) override; - bool ActionEscDispatch(const wchar_t wch, - const gsl::span intermediates) override; + bool ActionEscDispatch(const VTID id) override; - bool ActionVt52EscDispatch(const wchar_t wch, - const gsl::span intermediates, - const gsl::span parameters) override; + bool ActionVt52EscDispatch(const VTID id, const gsl::span parameters) override; - bool ActionCsiDispatch(const wchar_t wch, - const gsl::span intermediates, - const gsl::span parameters) override; + bool ActionCsiDispatch(const VTID id, const gsl::span parameters) override; bool ActionClear() noexcept override; @@ -73,94 +68,89 @@ namespace Microsoft::Console::VirtualTerminal wchar_t _lastPrintedChar; std::vector _graphicsOptions; - bool _IntermediateScsDispatch(const wchar_t wch, - const gsl::span intermediates); - bool _IntermediateQuestionMarkDispatch(const wchar_t wchAction, - const gsl::span parameters); - bool _IntermediateGreaterThanOrEqualDispatch(const wchar_t wch, - const wchar_t intermediate, - const gsl::span parameters); - bool _IntermediateExclamationDispatch(const wchar_t wch); - bool _IntermediateSpaceDispatch(const wchar_t wchAction, - const gsl::span parameters); - - enum VTActionCodes : wchar_t + enum EscActionCodes : uint64_t { - CUU_CursorUp = L'A', - CUD_CursorDown = L'B', - CUF_CursorForward = L'C', - CUB_CursorBackward = L'D', - CNL_CursorNextLine = L'E', - CPL_CursorPrevLine = L'F', - CHA_CursorHorizontalAbsolute = L'G', - CUP_CursorPosition = L'H', - ED_EraseDisplay = L'J', - EL_EraseLine = L'K', - SU_ScrollUp = L'S', - SD_ScrollDown = L'T', - ICH_InsertCharacter = L'@', - DCH_DeleteCharacter = L'P', - SGR_SetGraphicsRendition = L'm', - DECSC_CursorSave = L'7', - DECRC_CursorRestore = L'8', - DECSET_PrivateModeSet = L'h', - DECRST_PrivateModeReset = L'l', - ANSISYSSC_CursorSave = L's', // NOTE: Overlaps with DECLRMM/DECSLRM. Fix when/if implemented. - ANSISYSRC_CursorRestore = L'u', // NOTE: Overlaps with DECSMBV. Fix when/if implemented. - DECKPAM_KeypadApplicationMode = L'=', - DECKPNM_KeypadNumericMode = L'>', - DSR_DeviceStatusReport = L'n', - DA_DeviceAttributes = L'c', - DECSCPP_SetColumnsPerPage = L'|', - IL_InsertLine = L'L', - DL_DeleteLine = L'M', // Yes, this is the same as RI, however, RI is not preceded by a CSI, and DL is. - HPA_HorizontalPositionAbsolute = L'`', - VPA_VerticalLinePositionAbsolute = L'd', - HPR_HorizontalPositionRelative = L'a', - VPR_VerticalPositionRelative = L'e', - DECSTBM_SetScrollingRegion = L'r', - NEL_NextLine = L'E', // Not a CSI, so doesn't overlap with CNL - IND_Index = L'D', // Not a CSI, so doesn't overlap with CUB - RI_ReverseLineFeed = L'M', - HTS_HorizontalTabSet = L'H', // Not a CSI, so doesn't overlap with CUP - CHT_CursorForwardTab = L'I', - CBT_CursorBackTab = L'Z', - TBC_TabClear = L'g', - ECH_EraseCharacters = L'X', - HVP_HorizontalVerticalPosition = L'f', - DECSTR_SoftReset = L'p', - RIS_ResetToInitialState = L'c', // DA is prefaced by CSI, RIS by ESC - // 'q' is overloaded - no postfix is DECLL, ' ' postfix is DECSCUSR, and '"' is DECSCA - DECSCUSR_SetCursorStyle = L'q', // I believe we'll only ever implement DECSCUSR - DTTERM_WindowManipulation = L't', - REP_RepeatCharacter = L'b', - SS2_SingleShift = L'N', - SS3_SingleShift = L'O', - LS2_LockingShift = L'n', - LS3_LockingShift = L'o', - LS1R_LockingShift = L'~', - LS2R_LockingShift = L'}', - LS3R_LockingShift = L'|', - DECALN_ScreenAlignmentPattern = L'8' + DECSC_CursorSave = VTID("7"), + DECRC_CursorRestore = VTID("8"), + DECKPAM_KeypadApplicationMode = VTID("="), + DECKPNM_KeypadNumericMode = VTID(">"), + IND_Index = VTID("D"), + NEL_NextLine = VTID("E"), + HTS_HorizontalTabSet = VTID("H"), + RI_ReverseLineFeed = VTID("M"), + SS2_SingleShift = VTID("N"), + SS3_SingleShift = VTID("O"), + ST_StringTerminator = VTID("\\"), + RIS_ResetToInitialState = VTID("c"), + LS2_LockingShift = VTID("n"), + LS3_LockingShift = VTID("o"), + LS1R_LockingShift = VTID("~"), + LS2R_LockingShift = VTID("}"), + LS3R_LockingShift = VTID("|"), + DECALN_ScreenAlignmentPattern = VTID("#8") }; - enum Vt52ActionCodes : wchar_t + enum CsiActionCodes : uint64_t { - CursorUp = L'A', - CursorDown = L'B', - CursorRight = L'C', - CursorLeft = L'D', - EnterGraphicsMode = L'F', - ExitGraphicsMode = L'G', - CursorToHome = L'H', - ReverseLineFeed = L'I', - EraseToEndOfScreen = L'J', - EraseToEndOfLine = L'K', - DirectCursorAddress = L'Y', - Identify = L'Z', - EnterAlternateKeypadMode = L'=', - ExitAlternateKeypadMode = L'>', - ExitVt52Mode = L'<' + ICH_InsertCharacter = VTID("@"), + CUU_CursorUp = VTID("A"), + CUD_CursorDown = VTID("B"), + CUF_CursorForward = VTID("C"), + CUB_CursorBackward = VTID("D"), + CNL_CursorNextLine = VTID("E"), + CPL_CursorPrevLine = VTID("F"), + CHA_CursorHorizontalAbsolute = VTID("G"), + CUP_CursorPosition = VTID("H"), + CHT_CursorForwardTab = VTID("I"), + ED_EraseDisplay = VTID("J"), + EL_EraseLine = VTID("K"), + IL_InsertLine = VTID("L"), + DL_DeleteLine = VTID("M"), + DCH_DeleteCharacter = VTID("P"), + SU_ScrollUp = VTID("S"), + SD_ScrollDown = VTID("T"), + ECH_EraseCharacters = VTID("X"), + CBT_CursorBackTab = VTID("Z"), + HPA_HorizontalPositionAbsolute = VTID("`"), + HPR_HorizontalPositionRelative = VTID("a"), + REP_RepeatCharacter = VTID("b"), + DA_DeviceAttributes = VTID("c"), + DA2_SecondaryDeviceAttributes = VTID(">c"), + DA3_TertiaryDeviceAttributes = VTID("=c"), + VPA_VerticalLinePositionAbsolute = VTID("d"), + VPR_VerticalPositionRelative = VTID("e"), + HVP_HorizontalVerticalPosition = VTID("f"), + TBC_TabClear = VTID("g"), + DECSET_PrivateModeSet = VTID("?h"), + DECRST_PrivateModeReset = VTID("?l"), + SGR_SetGraphicsRendition = VTID("m"), + DSR_DeviceStatusReport = VTID("n"), + DECSTBM_SetScrollingRegion = VTID("r"), + ANSISYSSC_CursorSave = VTID("s"), // NOTE: Overlaps with DECLRMM/DECSLRM. Fix when/if implemented. + DTTERM_WindowManipulation = VTID("t"), // NOTE: Overlaps with DECSLPP. Fix when/if implemented. + ANSISYSRC_CursorRestore = VTID("u"), + DECSCUSR_SetCursorStyle = VTID(" q"), + DECSTR_SoftReset = VTID("!p"), + DECSCPP_SetColumnsPerPage = VTID("$|") + }; + + enum Vt52ActionCodes : uint64_t + { + CursorUp = VTID("A"), + CursorDown = VTID("B"), + CursorRight = VTID("C"), + CursorLeft = VTID("D"), + EnterGraphicsMode = VTID("F"), + ExitGraphicsMode = VTID("G"), + CursorToHome = VTID("H"), + ReverseLineFeed = VTID("I"), + EraseToEndOfScreen = VTID("J"), + EraseToEndOfLine = VTID("K"), + DirectCursorAddress = VTID("Y"), + Identify = VTID("Z"), + EnterAlternateKeypadMode = VTID("="), + ExitAlternateKeypadMode = VTID(">"), + ExitVt52Mode = VTID("<") }; enum OscActionCodes : unsigned int diff --git a/src/terminal/parser/stateMachine.cpp b/src/terminal/parser/stateMachine.cpp index 7e60032c5e0..536bc591c0b 100644 --- a/src/terminal/parser/stateMachine.cpp +++ b/src/terminal/parser/stateMachine.cpp @@ -15,7 +15,6 @@ StateMachine::StateMachine(std::unique_ptr engine) : _state(VTStates::Ground), _trace(Microsoft::Console::VirtualTerminal::ParserTracing()), _isInAnsiMode(true), - _intermediates{}, _parameters{}, _oscString{}, _cachedSequence{ std::nullopt }, @@ -422,7 +421,7 @@ void StateMachine::_ActionEscDispatch(const wchar_t wch) { _trace.TraceOnAction(L"EscDispatch"); - const bool success = _engine->ActionEscDispatch(wch, { _intermediates.data(), _intermediates.size() }); + const bool success = _engine->ActionEscDispatch(_identifier.Finalize(wch)); // Trace the result. _trace.DispatchSequenceTrace(success); @@ -445,8 +444,7 @@ void StateMachine::_ActionVt52EscDispatch(const wchar_t wch) { _trace.TraceOnAction(L"Vt52EscDispatch"); - const bool success = _engine->ActionVt52EscDispatch(wch, - { _intermediates.data(), _intermediates.size() }, + const bool success = _engine->ActionVt52EscDispatch(_identifier.Finalize(wch), { _parameters.data(), _parameters.size() }); // Trace the result. @@ -470,8 +468,7 @@ void StateMachine::_ActionCsiDispatch(const wchar_t wch) { _trace.TraceOnAction(L"CsiDispatch"); - const bool success = _engine->ActionCsiDispatch(wch, - { _intermediates.data(), _intermediates.size() }, + const bool success = _engine->ActionCsiDispatch(_identifier.Finalize(wch), { _parameters.data(), _parameters.size() }); // Trace the result. @@ -490,12 +487,12 @@ void StateMachine::_ActionCsiDispatch(const wchar_t wch) // - wch - Character to dispatch. // Return Value: // - -void StateMachine::_ActionCollect(const wchar_t wch) +void StateMachine::_ActionCollect(const wchar_t wch) noexcept { _trace.TraceOnAction(L"Collect"); // store collect data - _intermediates.push_back(wch); + _identifier.AddIntermediate(wch); } // Routine Description: @@ -541,7 +538,7 @@ void StateMachine::_ActionClear() _trace.TraceOnAction(L"Clear"); // clear all internal stored state. - _intermediates.clear(); + _identifier.Clear(); _parameters.clear(); diff --git a/src/terminal/parser/stateMachine.hpp b/src/terminal/parser/stateMachine.hpp index bcbf3f95b90..03d134dfc86 100644 --- a/src/terminal/parser/stateMachine.hpp +++ b/src/terminal/parser/stateMachine.hpp @@ -55,7 +55,7 @@ namespace Microsoft::Console::VirtualTerminal void _ActionPrint(const wchar_t wch); void _ActionEscDispatch(const wchar_t wch); void _ActionVt52EscDispatch(const wchar_t wch); - void _ActionCollect(const wchar_t wch); + void _ActionCollect(const wchar_t wch) noexcept; void _ActionParam(const wchar_t wch); void _ActionCsiDispatch(const wchar_t wch); void _ActionOscParam(const wchar_t wch) noexcept; @@ -142,7 +142,7 @@ namespace Microsoft::Console::VirtualTerminal std::wstring_view _run; - std::vector _intermediates; + VTIDBuilder _identifier; std::vector _parameters; std::wstring _oscString; diff --git a/src/terminal/parser/ut_parser/InputEngineTest.cpp b/src/terminal/parser/ut_parser/InputEngineTest.cpp index b97fa263c1c..c9d97b86801 100644 --- a/src/terminal/parser/ut_parser/InputEngineTest.cpp +++ b/src/terminal/parser/ut_parser/InputEngineTest.cpp @@ -222,7 +222,7 @@ class Microsoft::Console::VirtualTerminal::InputEngineTest std::wstring GenerateSgrMouseSequence(const CsiMouseButtonCodes button, const unsigned short modifiers, const COORD position, - const CsiActionCodes direction); + const VTID direction); // SGR_PARAMS serves as test input // - the state of the buttons (constructed via InputStateMachineEngine::CsiActionMouseCodes) @@ -1089,7 +1089,7 @@ void InputEngineTest::AltBackspaceEnterTest() std::wstring InputEngineTest::GenerateSgrMouseSequence(const CsiMouseButtonCodes button, const unsigned short modifiers, const COORD position, - const CsiActionCodes direction) + const VTID direction) { // we first need to convert "button" and "modifiers" into an 8 bit sequence unsigned int actionCode = 0; @@ -1102,7 +1102,11 @@ std::wstring InputEngineTest::GenerateSgrMouseSequence(const CsiMouseButtonCodes // modifiers represents the middle 4 bits actionCode |= modifiers; - return wil::str_printf_failfast(L"\x1b[<%d;%d;%d%c", static_cast(actionCode), position.X, position.Y, direction); + // mouse sequence identifiers consist of a private parameter prefix and a final character + const wchar_t prefixChar = direction[0]; + const wchar_t finalChar = direction[1]; + + return wil::str_printf_failfast(L"\x1b[%c%d;%d;%d%c", prefixChar, static_cast(actionCode), position.X, position.Y, finalChar); } void InputEngineTest::VerifySGRMouseData(const std::vector> testData) diff --git a/src/terminal/parser/ut_parser/StateMachineTest.cpp b/src/terminal/parser/ut_parser/StateMachineTest.cpp index 74e29ea72af..1b4e2f057dd 100644 --- a/src/terminal/parser/ut_parser/StateMachineTest.cpp +++ b/src/terminal/parser/ut_parser/StateMachineTest.cpp @@ -50,12 +50,9 @@ class Microsoft::Console::VirtualTerminal::TestStateMachineEngine : public IStat return true; }; - bool ActionEscDispatch(const wchar_t /* wch */, - const gsl::span /* intermediates */) override { return true; }; + bool ActionEscDispatch(const VTID /* id */) override { return true; }; - bool ActionVt52EscDispatch(const wchar_t /*wch*/, - const gsl::span /*intermediates*/, - const gsl::span /*parameters*/) override { return true; }; + bool ActionVt52EscDispatch(const VTID /*id*/, const gsl::span /*parameters*/) override { return true; }; bool ActionClear() override { return true; }; @@ -82,9 +79,7 @@ class Microsoft::Console::VirtualTerminal::TestStateMachineEngine : public IStat bool DispatchIntermediatesFromEscape() const override { return false; }; // ActionCsiDispatch is the only method that's actually implemented. - bool ActionCsiDispatch(const wchar_t /*wch*/, - const gsl::span /*intermediates*/, - const gsl::span parameters) override + bool ActionCsiDispatch(const VTID /*id*/, const gsl::span parameters) override { // If flush to terminal is registered for a test, then use it. if (pfnFlushToTerminal) From 3d64921120cfb145963babb5978299dca6c8cb35 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Tue, 18 Aug 2020 14:32:17 -0500 Subject: [PATCH 064/266] Add some polish to nested commands in the command palette (#7299) ## Summary of the Pull Request ![cmdpal-nested-command-polish](https://user-images.githubusercontent.com/18356694/90293616-1f29ca00-de4a-11ea-8942-00d255de929a.gif) * Add a chevron for nested commands * Add the text of the parent command when entering a child command ## References ## PR Checklist * [x] Closes #7265 * [x] I work here * [n/a] Tests added/passed * [n/a] Requires documentation to be updated ## Validation Steps Performed _look at that gif_ --- src/cascadia/TerminalApp/Command.idl | 2 +- src/cascadia/TerminalApp/CommandPalette.cpp | 3 ++ src/cascadia/TerminalApp/CommandPalette.h | 1 + src/cascadia/TerminalApp/CommandPalette.idl | 1 + src/cascadia/TerminalApp/CommandPalette.xaml | 46 +++++++++++++++---- ...cpp => EmptyStringVisibilityConverter.cpp} | 22 ++++----- ...ter.h => EmptyStringVisibilityConverter.h} | 8 ++-- ...idl => EmptyStringVisibilityConverter.idl} | 8 ++-- .../HasNestedCommandsVisibilityConverter.cpp | 38 +++++++++++++++ .../HasNestedCommandsVisibilityConverter.h | 27 +++++++++++ .../HasNestedCommandsVisibilityConverter.idl | 19 ++++++++ .../TerminalApp/lib/TerminalAppLib.vcxproj | 17 +++++-- 12 files changed, 158 insertions(+), 34 deletions(-) rename src/cascadia/TerminalApp/{CommandKeyChordVisibilityConverter.cpp => EmptyStringVisibilityConverter.cpp} (69%) rename src/cascadia/TerminalApp/{CommandKeyChordVisibilityConverter.h => EmptyStringVisibilityConverter.h} (75%) rename src/cascadia/TerminalApp/{CommandKeyChordVisibilityConverter.idl => EmptyStringVisibilityConverter.idl} (60%) create mode 100644 src/cascadia/TerminalApp/HasNestedCommandsVisibilityConverter.cpp create mode 100644 src/cascadia/TerminalApp/HasNestedCommandsVisibilityConverter.h create mode 100644 src/cascadia/TerminalApp/HasNestedCommandsVisibilityConverter.idl diff --git a/src/cascadia/TerminalApp/Command.idl b/src/cascadia/TerminalApp/Command.idl index 3aa55c64420..beb0a43f10c 100644 --- a/src/cascadia/TerminalApp/Command.idl +++ b/src/cascadia/TerminalApp/Command.idl @@ -15,7 +15,7 @@ namespace TerminalApp Windows.UI.Xaml.Controls.IconSource IconSource; - Boolean HasNestedCommands(); + Boolean HasNestedCommands { get; }; Windows.Foundation.Collections.IMapView NestedCommands { get; }; } } diff --git a/src/cascadia/TerminalApp/CommandPalette.cpp b/src/cascadia/TerminalApp/CommandPalette.cpp index c6c2061b004..e1c96bc00d0 100644 --- a/src/cascadia/TerminalApp/CommandPalette.cpp +++ b/src/cascadia/TerminalApp/CommandPalette.cpp @@ -343,6 +343,7 @@ namespace winrt::TerminalApp::implementation // action. Instead, display a new list of commands for the user // to pick from. _nestedActionStack.Append(command); + ParentCommandName(command.Name()); _currentNestedCommands.Clear(); for (const auto& nameAndCommand : command.NestedCommands()) { @@ -764,6 +765,8 @@ namespace winrt::TerminalApp::implementation _searchBox().Text(L""); _nestedActionStack.Clear(); + + ParentCommandName(L""); _currentNestedCommands.Clear(); } diff --git a/src/cascadia/TerminalApp/CommandPalette.h b/src/cascadia/TerminalApp/CommandPalette.h index 641f0606f19..97a18ac28cb 100644 --- a/src/cascadia/TerminalApp/CommandPalette.h +++ b/src/cascadia/TerminalApp/CommandPalette.h @@ -33,6 +33,7 @@ namespace winrt::TerminalApp::implementation OBSERVABLE_GETSET_PROPERTY(winrt::hstring, NoMatchesText, _PropertyChangedHandlers); OBSERVABLE_GETSET_PROPERTY(winrt::hstring, SearchBoxText, _PropertyChangedHandlers); OBSERVABLE_GETSET_PROPERTY(winrt::hstring, ControlName, _PropertyChangedHandlers); + OBSERVABLE_GETSET_PROPERTY(winrt::hstring, ParentCommandName, _PropertyChangedHandlers); private: friend struct CommandPaletteT; // for Xaml to bind events diff --git a/src/cascadia/TerminalApp/CommandPalette.idl b/src/cascadia/TerminalApp/CommandPalette.idl index 8286077a4e4..93d5851f60d 100644 --- a/src/cascadia/TerminalApp/CommandPalette.idl +++ b/src/cascadia/TerminalApp/CommandPalette.idl @@ -12,6 +12,7 @@ namespace TerminalApp String NoMatchesText { get; }; String SearchBoxText { get; }; String ControlName { get; }; + String ParentCommandName { get; }; Windows.Foundation.Collections.IObservableVector FilteredActions { get; }; diff --git a/src/cascadia/TerminalApp/CommandPalette.xaml b/src/cascadia/TerminalApp/CommandPalette.xaml index 50b35e8bbb6..015ce7677d6 100644 --- a/src/cascadia/TerminalApp/CommandPalette.xaml +++ b/src/cascadia/TerminalApp/CommandPalette.xaml @@ -9,8 +9,8 @@ the MIT License. See LICENSE in the project root for license information. --> xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:Windows10version1903="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractPresent(Windows.Foundation.UniversalApiContract, 8)" - TabNavigation="Cycle" - IsTabStop="True" + TabNavigation="Cycle" + IsTabStop="True" AllowFocusOnInteraction="True" PointerPressed="_rootPointerPressed" PreviewKeyDown="_previewKeyDownHandler" @@ -27,7 +27,9 @@ the MIT License. See LICENSE in the project root for license information. --> - + + + @@ -170,12 +172,23 @@ the MIT License. See LICENSE in the project root for license information. --> + Padding="16, 0, 16, 4" + x:Name="_parentCommandText" + FontStyle="Italic" + Visibility="{x:Bind ParentCommandName, + Mode=OneWay, + Converter={StaticResource ParentCommandVisibilityConverter}}" + Grid.Row="1" + Text="{x:Bind ParentCommandName, Mode=OneWay}"> + + + Text="{x:Bind KeyChordText, Mode=OneWay}" /> + + + + + + + + diff --git a/src/cascadia/TerminalApp/CommandKeyChordVisibilityConverter.cpp b/src/cascadia/TerminalApp/EmptyStringVisibilityConverter.cpp similarity index 69% rename from src/cascadia/TerminalApp/CommandKeyChordVisibilityConverter.cpp rename to src/cascadia/TerminalApp/EmptyStringVisibilityConverter.cpp index 24af0da0029..ed4bec4f7ae 100644 --- a/src/cascadia/TerminalApp/CommandKeyChordVisibilityConverter.cpp +++ b/src/cascadia/TerminalApp/EmptyStringVisibilityConverter.cpp @@ -1,6 +1,6 @@ #include "pch.h" -#include "CommandKeyChordVisibilityConverter.h" -#include "CommandKeyChordVisibilityConverter.g.cpp" +#include "EmptyStringVisibilityConverter.h" +#include "EmptyStringVisibilityConverter.g.cpp" using namespace winrt::Windows; using namespace winrt::Windows::UI::Xaml; @@ -9,7 +9,7 @@ namespace winrt::TerminalApp::implementation { // Method Description: // - Attempt to convert something into another type. For the - // CommandKeyChordVisibilityConverter, we're gonna check if `value` is a + // EmptyStringVisibilityConverter, we're gonna check if `value` is a // string, and try and convert it into a Visibility value. If the input // param wasn't a string, or was the empty string, we'll return // Visibility::Collapsed. Otherwise, we'll return Visible. @@ -18,20 +18,20 @@ namespace winrt::TerminalApp::implementation // - value: the input object to attempt to convert into a Visibility. // Return Value: // - Visible if the object was a string and wasn't the empty string. - Foundation::IInspectable CommandKeyChordVisibilityConverter::Convert(Foundation::IInspectable const& value, - Windows::UI::Xaml::Interop::TypeName const& /* targetType */, - Foundation::IInspectable const& /* parameter */, - hstring const& /* language */) + Foundation::IInspectable EmptyStringVisibilityConverter::Convert(Foundation::IInspectable const& value, + Windows::UI::Xaml::Interop::TypeName const& /* targetType */, + Foundation::IInspectable const& /* parameter */, + hstring const& /* language */) { const auto& name = winrt::unbox_value_or(value, L""); return winrt::box_value(name.empty() ? Visibility::Collapsed : Visibility::Visible); } // unused for one-way bindings - Foundation::IInspectable CommandKeyChordVisibilityConverter::ConvertBack(Foundation::IInspectable const& /* value */, - Windows::UI::Xaml::Interop::TypeName const& /* targetType */, - Foundation::IInspectable const& /* parameter */, - hstring const& /* language */) + Foundation::IInspectable EmptyStringVisibilityConverter::ConvertBack(Foundation::IInspectable const& /* value */, + Windows::UI::Xaml::Interop::TypeName const& /* targetType */, + Foundation::IInspectable const& /* parameter */, + hstring const& /* language */) { throw hresult_not_implemented(); } diff --git a/src/cascadia/TerminalApp/CommandKeyChordVisibilityConverter.h b/src/cascadia/TerminalApp/EmptyStringVisibilityConverter.h similarity index 75% rename from src/cascadia/TerminalApp/CommandKeyChordVisibilityConverter.h rename to src/cascadia/TerminalApp/EmptyStringVisibilityConverter.h index 298f6ac0a0f..bf6b9bbe9a2 100644 --- a/src/cascadia/TerminalApp/CommandKeyChordVisibilityConverter.h +++ b/src/cascadia/TerminalApp/EmptyStringVisibilityConverter.h @@ -1,13 +1,13 @@ #pragma once -#include "CommandKeyChordVisibilityConverter.g.h" +#include "EmptyStringVisibilityConverter.g.h" #include "..\inc\cppwinrt_utils.h" namespace winrt::TerminalApp::implementation { - struct CommandKeyChordVisibilityConverter : CommandKeyChordVisibilityConverterT + struct EmptyStringVisibilityConverter : EmptyStringVisibilityConverterT { - CommandKeyChordVisibilityConverter() = default; + EmptyStringVisibilityConverter() = default; Windows::Foundation::IInspectable Convert(Windows::Foundation::IInspectable const& value, Windows::UI::Xaml::Interop::TypeName const& targetType, @@ -23,5 +23,5 @@ namespace winrt::TerminalApp::implementation namespace winrt::TerminalApp::factory_implementation { - BASIC_FACTORY(CommandKeyChordVisibilityConverter); + BASIC_FACTORY(EmptyStringVisibilityConverter); } diff --git a/src/cascadia/TerminalApp/CommandKeyChordVisibilityConverter.idl b/src/cascadia/TerminalApp/EmptyStringVisibilityConverter.idl similarity index 60% rename from src/cascadia/TerminalApp/CommandKeyChordVisibilityConverter.idl rename to src/cascadia/TerminalApp/EmptyStringVisibilityConverter.idl index b293224e64d..fd03a0021bb 100644 --- a/src/cascadia/TerminalApp/CommandKeyChordVisibilityConverter.idl +++ b/src/cascadia/TerminalApp/EmptyStringVisibilityConverter.idl @@ -6,14 +6,14 @@ namespace TerminalApp // See https://docs.microsoft.com/en-us/windows/uwp/data-binding/data-binding-quickstart // We use the default attribute to declare IValueConverter as the default - // interface. In the listing, CommandKeyChordVisibilityConverter has only a + // interface. In the listing, EmptyStringVisibilityConverter has only a // constructor, and no methods, so no default interface is generated for it. // The default attribute is optimal if you won't be adding instance members - // to CommandKeyChordVisibilityConverter, because no QueryInterface will be + // to EmptyStringVisibilityConverter, because no QueryInterface will be // required to call the IValueConverter methods - runtimeclass CommandKeyChordVisibilityConverter : [default] Windows.UI.Xaml.Data.IValueConverter + runtimeclass EmptyStringVisibilityConverter : [default] Windows.UI.Xaml.Data.IValueConverter { - CommandKeyChordVisibilityConverter(); + EmptyStringVisibilityConverter(); }; } diff --git a/src/cascadia/TerminalApp/HasNestedCommandsVisibilityConverter.cpp b/src/cascadia/TerminalApp/HasNestedCommandsVisibilityConverter.cpp new file mode 100644 index 00000000000..d398dbc40bd --- /dev/null +++ b/src/cascadia/TerminalApp/HasNestedCommandsVisibilityConverter.cpp @@ -0,0 +1,38 @@ +#include "pch.h" +#include "HasNestedCommandsVisibilityConverter.h" +#include "HasNestedCommandsVisibilityConverter.g.cpp" + +using namespace winrt::Windows; +using namespace winrt::Windows::UI::Xaml; + +namespace winrt::TerminalApp::implementation +{ + // Method Description: + // - Attempt to convert something into another type. For the + // HasNestedCommandsVisibilityConverter, we're gonna check if `value` is a + // string, and try and convert it into a Visibility value. If the input + // param wasn't a string, or was the empty string, we'll return + // Visibility::Collapsed. Otherwise, we'll return Visible. + + // Arguments: + // - value: the input object to attempt to convert into a Visibility. + // Return Value: + // - Visible if the object was a string and wasn't the empty string. + Foundation::IInspectable HasNestedCommandsVisibilityConverter::Convert(Foundation::IInspectable const& value, + Windows::UI::Xaml::Interop::TypeName const& /* targetType */, + Foundation::IInspectable const& /* parameter */, + hstring const& /* language */) + { + const auto& hasNestedCommands = winrt::unbox_value_or(value, false); + return winrt::box_value(hasNestedCommands ? Visibility::Visible : Visibility::Collapsed); + } + + // unused for one-way bindings + Foundation::IInspectable HasNestedCommandsVisibilityConverter::ConvertBack(Foundation::IInspectable const& /* value */, + Windows::UI::Xaml::Interop::TypeName const& /* targetType */, + Foundation::IInspectable const& /* parameter */, + hstring const& /* language */) + { + throw hresult_not_implemented(); + } +} diff --git a/src/cascadia/TerminalApp/HasNestedCommandsVisibilityConverter.h b/src/cascadia/TerminalApp/HasNestedCommandsVisibilityConverter.h new file mode 100644 index 00000000000..e8526b8b48f --- /dev/null +++ b/src/cascadia/TerminalApp/HasNestedCommandsVisibilityConverter.h @@ -0,0 +1,27 @@ +#pragma once + +#include "HasNestedCommandsVisibilityConverter.g.h" +#include "..\inc\cppwinrt_utils.h" + +namespace winrt::TerminalApp::implementation +{ + struct HasNestedCommandsVisibilityConverter : HasNestedCommandsVisibilityConverterT + { + HasNestedCommandsVisibilityConverter() = default; + + Windows::Foundation::IInspectable Convert(Windows::Foundation::IInspectable const& value, + Windows::UI::Xaml::Interop::TypeName const& targetType, + Windows::Foundation::IInspectable const& parameter, + hstring const& language); + + Windows::Foundation::IInspectable ConvertBack(Windows::Foundation::IInspectable const& value, + Windows::UI::Xaml::Interop::TypeName const& targetType, + Windows::Foundation::IInspectable const& parameter, + hstring const& language); + }; +} + +namespace winrt::TerminalApp::factory_implementation +{ + BASIC_FACTORY(HasNestedCommandsVisibilityConverter); +} diff --git a/src/cascadia/TerminalApp/HasNestedCommandsVisibilityConverter.idl b/src/cascadia/TerminalApp/HasNestedCommandsVisibilityConverter.idl new file mode 100644 index 00000000000..6d28f5dea67 --- /dev/null +++ b/src/cascadia/TerminalApp/HasNestedCommandsVisibilityConverter.idl @@ -0,0 +1,19 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +namespace TerminalApp +{ + // See https://docs.microsoft.com/en-us/windows/uwp/data-binding/data-binding-quickstart + + // We use the default attribute to declare IValueConverter as the default + // interface. In the listing, HasNestedCommandsVisibilityConverter has only a + // constructor, and no methods, so no default interface is generated for it. + // The default attribute is optimal if you won't be adding instance members + // to HasNestedCommandsVisibilityConverter, because no QueryInterface will be + // required to call the IValueConverter methods + runtimeclass HasNestedCommandsVisibilityConverter : [default] Windows.UI.Xaml.Data.IValueConverter + { + HasNestedCommandsVisibilityConverter(); + }; + +} diff --git a/src/cascadia/TerminalApp/lib/TerminalAppLib.vcxproj b/src/cascadia/TerminalApp/lib/TerminalAppLib.vcxproj index 95f01337336..abb49e21e58 100644 --- a/src/cascadia/TerminalApp/lib/TerminalAppLib.vcxproj +++ b/src/cascadia/TerminalApp/lib/TerminalAppLib.vcxproj @@ -94,8 +94,11 @@ ../Command.idl - - ../CommandKeyChordVisibilityConverter.idl + + ../EmptyStringVisibilityConverter.idl + + + ../HasNestedCommandsVisibilityConverter.idl ../Tab.idl @@ -170,8 +173,11 @@ ../Command.idl - - ../CommandKeyChordVisibilityConverter.idl + + ../EmptyStringVisibilityConverter.idl + + + ../HasNestedCommandsVisibilityConverter.idl ../Tab.idl @@ -265,7 +271,8 @@ Code
- + + From b8b0dd75cfdc361122cdad1e330e4ff19e0dc922 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Tue, 18 Aug 2020 16:50:02 -0500 Subject: [PATCH 065/266] Fix broken localtests (#7333) --- .../LocalTests_TerminalApp/SettingsTests.cpp | 105 ++-- .../LocalTests_TerminalApp/TabTests.cpp | 524 +++++++++--------- 2 files changed, 306 insertions(+), 323 deletions(-) diff --git a/src/cascadia/LocalTests_TerminalApp/SettingsTests.cpp b/src/cascadia/LocalTests_TerminalApp/SettingsTests.cpp index f158525548d..b99d86e35db 100644 --- a/src/cascadia/LocalTests_TerminalApp/SettingsTests.cpp +++ b/src/cascadia/LocalTests_TerminalApp/SettingsTests.cpp @@ -2296,60 +2296,49 @@ namespace TerminalAppLocalTests void SettingsTests::ValidateExecuteCommandlineWarning() { - // Tests run in Helix can't report Skipped until GH#7286 is resolved. - // Set ignore flag to make Helix run completely overlook it. - BEGIN_TEST_METHOD_PROPERTIES() - TEST_METHOD_PROPERTY(L"Ignore", L"True") - END_TEST_METHOD_PROPERTIES() - - // This test to be corrected as a part of GH#7281 - Log::Comment(L"This test is affected by GH#6949, so we're just skipping it for now."); - Log::Result(WEX::Logging::TestResults::Skipped); - return; - - // const std::string badSettings{ R"( - // { - // "defaultProfile": "{6239a42c-2222-49a3-80bd-e8fdd045185c}", - // "profiles": [ - // { - // "name" : "profile0", - // "guid": "{6239a42c-2222-49a3-80bd-e8fdd045185c}" - // }, - // { - // "name" : "profile1", - // "guid": "{6239a42c-3333-49a3-80bd-e8fdd045185c}" - // } - // ], - // "keybindings": [ - // { "name":null, "command": { "action": "wt" }, "keys": [ "ctrl+a" ] }, - // { "name":null, "command": { "action": "wt", "commandline":"" }, "keys": [ "ctrl+b" ] }, - // { "name":null, "command": { "action": "wt", "commandline":null }, "keys": [ "ctrl+c" ] } - // ] - // })" }; - - // const auto settingsObject = VerifyParseSucceeded(badSettings); - - // auto settings = CascadiaSettings::FromJson(settingsObject); - - // VERIFY_ARE_EQUAL(0u, settings->_globals._keybindings->_keyShortcuts.size()); - - // for (const auto& warning : settings->_globals._keybindingsWarnings) - // { - // Log::Comment(NoThrowString().Format( - // L"warning:%d", warning)); - // } - // VERIFY_ARE_EQUAL(3u, settings->_globals._keybindingsWarnings.size()); - // VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::MissingRequiredParameter, settings->_globals._keybindingsWarnings.at(0)); - // VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::MissingRequiredParameter, settings->_globals._keybindingsWarnings.at(1)); - // VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::MissingRequiredParameter, settings->_globals._keybindingsWarnings.at(2)); - - // settings->_ValidateKeybindings(); - - // VERIFY_ARE_EQUAL(4u, settings->_warnings.size()); - // VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::AtLeastOneKeybindingWarning, settings->_warnings.at(0)); - // VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::MissingRequiredParameter, settings->_warnings.at(1)); - // VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::MissingRequiredParameter, settings->_warnings.at(2)); - // VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::MissingRequiredParameter, settings->_warnings.at(3)); + const std::string badSettings{ R"( + { + "defaultProfile": "{6239a42c-2222-49a3-80bd-e8fdd045185c}", + "profiles": [ + { + "name" : "profile0", + "guid": "{6239a42c-2222-49a3-80bd-e8fdd045185c}" + }, + { + "name" : "profile1", + "guid": "{6239a42c-3333-49a3-80bd-e8fdd045185c}" + } + ], + "keybindings": [ + { "name":null, "command": { "action": "wt" }, "keys": [ "ctrl+a" ] }, + { "name":null, "command": { "action": "wt", "commandline":"" }, "keys": [ "ctrl+b" ] }, + { "name":null, "command": { "action": "wt", "commandline":null }, "keys": [ "ctrl+c" ] } + ] + })" }; + + const auto settingsObject = VerifyParseSucceeded(badSettings); + + auto settings = CascadiaSettings::FromJson(settingsObject); + + VERIFY_ARE_EQUAL(0u, settings->_globals._keybindings->_keyShortcuts.size()); + + for (const auto& warning : settings->_globals._keybindingsWarnings) + { + Log::Comment(NoThrowString().Format( + L"warning:%d", warning)); + } + VERIFY_ARE_EQUAL(3u, settings->_globals._keybindingsWarnings.size()); + VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::MissingRequiredParameter, settings->_globals._keybindingsWarnings.at(0)); + VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::MissingRequiredParameter, settings->_globals._keybindingsWarnings.at(1)); + VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::MissingRequiredParameter, settings->_globals._keybindingsWarnings.at(2)); + + settings->_ValidateKeybindings(); + + VERIFY_ARE_EQUAL(4u, settings->_warnings.size()); + VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::AtLeastOneKeybindingWarning, settings->_warnings.at(0)); + VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::MissingRequiredParameter, settings->_warnings.at(1)); + VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::MissingRequiredParameter, settings->_warnings.at(2)); + VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::MissingRequiredParameter, settings->_warnings.at(3)); } void SettingsTests::ValidateLegacyGlobalsWarning() @@ -2425,14 +2414,6 @@ namespace TerminalAppLocalTests void SettingsTests::TestCommandsAndKeybindings() { - // Tests run in Helix can't report Skipped until GH#7286 is resolved. - // Set ignore flag to make Helix run completely overlook it. - BEGIN_TEST_METHOD_PROPERTIES() - TEST_METHOD_PROPERTY(L"Ignore", L"True") - END_TEST_METHOD_PROPERTIES() - - // This test to be corrected as a part of GH#7281 - const std::string settingsJson{ R"( { "defaultProfile": "{6239a42c-0000-49a3-80bd-e8fdd045185c}", diff --git a/src/cascadia/LocalTests_TerminalApp/TabTests.cpp b/src/cascadia/LocalTests_TerminalApp/TabTests.cpp index 9b0b4df8b18..e9042847628 100644 --- a/src/cascadia/LocalTests_TerminalApp/TabTests.cpp +++ b/src/cascadia/LocalTests_TerminalApp/TabTests.cpp @@ -51,7 +51,8 @@ namespace TerminalAppLocalTests TEST_METHOD(TryCreateSettingsType); TEST_METHOD(TryCreateConnectionType); TEST_METHOD(TryCreateXamlObjects); - TEST_METHOD(TryCreateTab); + + TEST_METHOD(TryInitializePage); TEST_METHOD(CreateSimpleTerminalXamlType); TEST_METHOD(CreateTerminalMuxXamlType); @@ -67,6 +68,11 @@ namespace TerminalAppLocalTests return true; } + TEST_METHOD_CLEANUP(MethodCleanup) + { + return true; + } + private: void _initializeTerminalPage(winrt::com_ptr& page, std::shared_ptr initialSettings); @@ -125,35 +131,6 @@ namespace TerminalAppLocalTests VERIFY_SUCCEEDED(result); } - void TabTests::TryCreateTab() - { - // If you leave the Tab ptr owned by the RunOnUIThread lambda, it - // will crash when the test tears down. Not totally clear why, but make - // sure it's owned outside the lambda - winrt::com_ptr newTab{ nullptr }; - - auto result = RunOnUIThread([&newTab]() { - // Try creating all of: - // 1. one of our pure c++ types (Profile) - // 2. one of our c++winrt types (TerminalSettings, EchoConnection) - // 3. one of our types that uses MUX/Xaml (TermControl). - // 4. one of our types that uses MUX/Xaml in this dll (Tab). - // Just creating all of them is enough to know that everything is working. - const auto profileGuid{ Utils::CreateGuid() }; - TerminalSettings settings{}; - VERIFY_IS_NOT_NULL(settings); - winrt::Microsoft::Terminal::TerminalConnection::EchoConnection conn{}; - VERIFY_IS_NOT_NULL(conn); - winrt::Microsoft::Terminal::TerminalControl::TermControl term{ settings, conn }; - VERIFY_IS_NOT_NULL(term); - - newTab = winrt::make_self(profileGuid, term); - VERIFY_IS_NOT_NULL(newTab); - }); - - VERIFY_SUCCEEDED(result); - } - void TabTests::CreateSimpleTerminalXamlType() { winrt::com_ptr mmcc{ nullptr }; @@ -276,243 +253,268 @@ namespace TerminalAppLocalTests VERIFY_SUCCEEDED(result); } + void TabTests::TryInitializePage() + { + // This is a very simple test to prove we can create settings and a + // TerminalPage and not only create them successfully, but also create a + // tab using those settings successfully. + + const std::string settingsJson0{ R"( + { + "defaultProfile": "{6239a42c-1111-49a3-80bd-e8fdd045185c}", + "profiles": [ + { + "name" : "profile0", + "guid": "{6239a42c-1111-49a3-80bd-e8fdd045185c}", + "historySize": 1 + }, + { + "name" : "profile1", + "guid": "{6239a42c-2222-49a3-80bd-e8fdd045185c}", + "historySize": 2 + } + ] + })" }; + + VerifyParseSucceeded(settingsJson0); + auto settings0 = std::make_shared(false); + VERIFY_IS_NOT_NULL(settings0); + settings0->_ParseJsonString(settingsJson0, false); + settings0->LayerJson(settings0->_userSettings); + settings0->_ValidateSettings(); + + // This is super wacky, but we can't just initialize the + // com_ptr in the lambda and assign it back out of + // the lambda. We'll crash trying to get a weak_ref to the TerminalPage + // during TerminalPage::Create() below. + // + // Instead, create the winrt object, then get a com_ptr to the + // implementation _from_ the winrt object. This seems to work, even if + // it's weird. + winrt::com_ptr page{ nullptr }; + _initializeTerminalPage(page, settings0); + + auto result = RunOnUIThread([&page]() { + VERIFY_ARE_EQUAL(1u, page->_tabs.Size()); + }); + VERIFY_SUCCEEDED(result); + } + void TabTests::TryDuplicateBadTab() { - // Tests run in Helix can't report Skipped until GH#7286 is resolved. - // Set ignore flag to make Helix run completely overlook it. - BEGIN_TEST_METHOD_PROPERTIES() - TEST_METHOD_PROPERTY(L"Ignore", L"True") - END_TEST_METHOD_PROPERTIES() - - // This test to be corrected as a part of GH#7281 - Log::Comment(L"This test regressed recently - it is temporarily disabled while GH#5169 is investigated"); - Log::Result(WEX::Logging::TestResults::Skipped); - return; - - // // * Create a tab with a profile with GUID 1 - // // * Reload the settings so that GUID 1 is no longer in the list of profiles - // // * Try calling _DuplicateTabViewItem on tab 1 - // // * No new tab should be created (and more importantly, the app should not crash) - // // - // // Created to test GH#2455 - - // const std::string settingsJson0{ R"( - // { - // "defaultProfile": "{6239a42c-1111-49a3-80bd-e8fdd045185c}", - // "profiles": [ - // { - // "name" : "profile0", - // "guid": "{6239a42c-1111-49a3-80bd-e8fdd045185c}", - // "historySize": 1 - // }, - // { - // "name" : "profile1", - // "guid": "{6239a42c-2222-49a3-80bd-e8fdd045185c}", - // "historySize": 2 - // } - // ] - // })" }; - - // const std::string settingsJson1{ R"( - // { - // "defaultProfile": "{6239a42c-1111-49a3-80bd-e8fdd045185c}", - // "profiles": [ - // { - // "name" : "profile1", - // "guid": "{6239a42c-2222-49a3-80bd-e8fdd045185c}", - // "historySize": 2 - // } - // ] - // })" }; - - // VerifyParseSucceeded(settingsJson0); - // auto settings0 = std::make_shared(false); - // VERIFY_IS_NOT_NULL(settings0); - // settings0->_ParseJsonString(settingsJson0, false); - // settings0->LayerJson(settings0->_userSettings); - // settings0->_ValidateSettings(); - - // VerifyParseSucceeded(settingsJson1); - // auto settings1 = std::make_shared(false); - // VERIFY_IS_NOT_NULL(settings1); - // settings1->_ParseJsonString(settingsJson1, false); - // settings1->LayerJson(settings1->_userSettings); - // settings1->_ValidateSettings(); - - // const auto guid1 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-1111-49a3-80bd-e8fdd045185c}"); - // const auto guid2 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-2222-49a3-80bd-e8fdd045185c}"); - // const auto guid3 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-3333-49a3-80bd-e8fdd045185c}"); - - // // This is super wacky, but we can't just initialize the - // // com_ptr in the lambda and assign it back out of - // // the lambda. We'll crash trying to get a weak_ref to the TerminalPage - // // during TerminalPage::Create() below. - // // - // // Instead, create the winrt object, then get a com_ptr to the - // // implementation _from_ the winrt object. This seems to work, even if - // // it's weird. - // winrt::com_ptr page{ nullptr }; - // _initializeTerminalPage(page, settings0); - - // auto result = RunOnUIThread([&page]() { - // VERIFY_ARE_EQUAL(1u, page->_tabs.Size()); - // }); - // VERIFY_SUCCEEDED(result); - - // Log::Comment(L"Duplicate the first tab"); - // result = RunOnUIThread([&page]() { - // page->_DuplicateTabViewItem(); - // VERIFY_ARE_EQUAL(2u, page->_tabs.Size()); - // }); - // VERIFY_SUCCEEDED(result); - - // Log::Comment(NoThrowString().Format( - // L"Change the settings of the TerminalPage so the first profile is " - // L"no longer in the list of profiles")); - // result = RunOnUIThread([&page, settings1]() { - // page->_settings = settings1; - // }); - // VERIFY_SUCCEEDED(result); - - // Log::Comment(L"Duplicate the tab, and don't crash"); - // result = RunOnUIThread([&page]() { - // page->_DuplicateTabViewItem(); - // VERIFY_ARE_EQUAL(2u, page->_tabs.Size(), L"We should gracefully do nothing here - the profile no longer exists."); - // }); - // VERIFY_SUCCEEDED(result); + // * Create a tab with a profile with GUID 1 + // * Reload the settings so that GUID 1 is no longer in the list of profiles + // * Try calling _DuplicateTabViewItem on tab 1 + // * No new tab should be created (and more importantly, the app should not crash) + // + // Created to test GH#2455 + + const std::string settingsJson0{ R"( + { + "defaultProfile": "{6239a42c-1111-49a3-80bd-e8fdd045185c}", + "profiles": [ + { + "name" : "profile0", + "guid": "{6239a42c-1111-49a3-80bd-e8fdd045185c}", + "historySize": 1 + }, + { + "name" : "profile1", + "guid": "{6239a42c-2222-49a3-80bd-e8fdd045185c}", + "historySize": 2 + } + ] + })" }; + + const std::string settingsJson1{ R"( + { + "defaultProfile": "{6239a42c-1111-49a3-80bd-e8fdd045185c}", + "profiles": [ + { + "name" : "profile1", + "guid": "{6239a42c-2222-49a3-80bd-e8fdd045185c}", + "historySize": 2 + } + ] + })" }; + + VerifyParseSucceeded(settingsJson0); + auto settings0 = std::make_shared(false); + VERIFY_IS_NOT_NULL(settings0); + settings0->_ParseJsonString(settingsJson0, false); + settings0->LayerJson(settings0->_userSettings); + settings0->_ValidateSettings(); + + VerifyParseSucceeded(settingsJson1); + auto settings1 = std::make_shared(false); + VERIFY_IS_NOT_NULL(settings1); + settings1->_ParseJsonString(settingsJson1, false); + settings1->LayerJson(settings1->_userSettings); + settings1->_ValidateSettings(); + + const auto guid1 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-1111-49a3-80bd-e8fdd045185c}"); + const auto guid2 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-2222-49a3-80bd-e8fdd045185c}"); + const auto guid3 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-3333-49a3-80bd-e8fdd045185c}"); + + // This is super wacky, but we can't just initialize the + // com_ptr in the lambda and assign it back out of + // the lambda. We'll crash trying to get a weak_ref to the TerminalPage + // during TerminalPage::Create() below. + // + // Instead, create the winrt object, then get a com_ptr to the + // implementation _from_ the winrt object. This seems to work, even if + // it's weird. + winrt::com_ptr page{ nullptr }; + _initializeTerminalPage(page, settings0); + + auto result = RunOnUIThread([&page]() { + VERIFY_ARE_EQUAL(1u, page->_tabs.Size()); + }); + VERIFY_SUCCEEDED(result); + + Log::Comment(L"Duplicate the first tab"); + result = RunOnUIThread([&page]() { + page->_DuplicateTabViewItem(); + VERIFY_ARE_EQUAL(2u, page->_tabs.Size()); + }); + VERIFY_SUCCEEDED(result); + + Log::Comment(NoThrowString().Format( + L"Change the settings of the TerminalPage so the first profile is " + L"no longer in the list of profiles")); + result = RunOnUIThread([&page, settings1]() { + page->_settings = settings1; + }); + VERIFY_SUCCEEDED(result); + + Log::Comment(L"Duplicate the tab, and don't crash"); + result = RunOnUIThread([&page]() { + page->_DuplicateTabViewItem(); + VERIFY_ARE_EQUAL(2u, page->_tabs.Size(), L"We should gracefully do nothing here - the profile no longer exists."); + }); + VERIFY_SUCCEEDED(result); } void TabTests::TryDuplicateBadPane() { - // Tests run in Helix can't report Skipped until GH#7286 is resolved. - // Set ignore flag to make Helix run completely overlook it. - BEGIN_TEST_METHOD_PROPERTIES() - TEST_METHOD_PROPERTY(L"Ignore", L"True") - END_TEST_METHOD_PROPERTIES() - - // This test to be corrected as a part of GH#7281 - Log::Comment(L"This test regressed recently - it is temporarily disabled while GH#5169 is investigated"); - Log::Result(WEX::Logging::TestResults::Skipped); - return; - - // // * Create a tab with a profile with GUID 1 - // // * Reload the settings so that GUID 1 is no longer in the list of profiles - // // * Try calling _SplitPane(Duplicate) on tab 1 - // // * No new pane should be created (and more importantly, the app should not crash) - // // - // // Created to test GH#2455 - - // const std::string settingsJson0{ R"( - // { - // "defaultProfile": "{6239a42c-1111-49a3-80bd-e8fdd045185c}", - // "profiles": [ - // { - // "name" : "profile0", - // "guid": "{6239a42c-1111-49a3-80bd-e8fdd045185c}", - // "historySize": 1 - // }, - // { - // "name" : "profile1", - // "guid": "{6239a42c-2222-49a3-80bd-e8fdd045185c}", - // "historySize": 2 - // } - // ] - // })" }; - - // const std::string settingsJson1{ R"( - // { - // "defaultProfile": "{6239a42c-1111-49a3-80bd-e8fdd045185c}", - // "profiles": [ - // { - // "name" : "profile1", - // "guid": "{6239a42c-2222-49a3-80bd-e8fdd045185c}", - // "historySize": 2 - // } - // ] - // })" }; - - // VerifyParseSucceeded(settingsJson0); - // auto settings0 = std::make_shared(false); - // VERIFY_IS_NOT_NULL(settings0); - // settings0->_ParseJsonString(settingsJson0, false); - // settings0->LayerJson(settings0->_userSettings); - // settings0->_ValidateSettings(); - - // VerifyParseSucceeded(settingsJson1); - // auto settings1 = std::make_shared(false); - // VERIFY_IS_NOT_NULL(settings1); - // settings1->_ParseJsonString(settingsJson1, false); - // settings1->LayerJson(settings1->_userSettings); - // settings1->_ValidateSettings(); - - // const auto guid1 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-1111-49a3-80bd-e8fdd045185c}"); - // const auto guid2 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-2222-49a3-80bd-e8fdd045185c}"); - // const auto guid3 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-3333-49a3-80bd-e8fdd045185c}"); - - // // This is super wacky, but we can't just initialize the - // // com_ptr in the lambda and assign it back out of - // // the lambda. We'll crash trying to get a weak_ref to the TerminalPage - // // during TerminalPage::Create() below. - // // - // // Instead, create the winrt object, then get a com_ptr to the - // // implementation _from_ the winrt object. This seems to work, even if - // // it's weird. - // winrt::com_ptr page{ nullptr }; - // _initializeTerminalPage(page, settings0); - - // auto result = RunOnUIThread([&page]() { - // VERIFY_ARE_EQUAL(1u, page->_tabs.Size()); - // }); - // VERIFY_SUCCEEDED(result); - - // result = RunOnUIThread([&page]() { - // VERIFY_ARE_EQUAL(1u, page->_tabs.Size()); - // auto tab = page->_GetStrongTabImpl(0); - // VERIFY_ARE_EQUAL(1, tab->_GetLeafPaneCount()); - // }); - // VERIFY_SUCCEEDED(result); - - // Log::Comment(NoThrowString().Format(L"Duplicate the first pane")); - // result = RunOnUIThread([&page]() { - // page->_SplitPane(SplitState::Automatic, SplitType::Duplicate, nullptr); - - // VERIFY_ARE_EQUAL(1u, page->_tabs.Size()); - // auto tab = page->_GetStrongTabImpl(0); - // VERIFY_ARE_EQUAL(2, tab->_GetLeafPaneCount()); - // }); - // VERIFY_SUCCEEDED(result); - - // Log::Comment(NoThrowString().Format( - // L"Change the settings of the TerminalPage so the first profile is " - // L"no longer in the list of profiles")); - // result = RunOnUIThread([&page, settings1]() { - // page->_settings = settings1; - // }); - // VERIFY_SUCCEEDED(result); - - // Log::Comment(NoThrowString().Format(L"Duplicate the pane, and don't crash")); - // result = RunOnUIThread([&page]() { - // page->_SplitPane(SplitState::Automatic, SplitType::Duplicate, nullptr); - - // VERIFY_ARE_EQUAL(1u, page->_tabs.Size()); - // auto tab = page->_GetStrongTabImpl(0); - // VERIFY_ARE_EQUAL(2, - // tab->_GetLeafPaneCount(), - // L"We should gracefully do nothing here - the profile no longer exists."); - // }); - // VERIFY_SUCCEEDED(result); - - // auto cleanup = wil::scope_exit([] { - // auto result = RunOnUIThread([]() { - // // There's something causing us to crash north of - // // TSFInputControl::NotifyEnter, or LayoutRequested. It's very - // // unclear what that issue is. Since these tests don't run in - // // CI, simply log a message so that the dev running these tests - // // knows it's expected. - // Log::Comment(L"This test often crashes on cleanup, even when it succeeds. If it succeeded, then crashes, that's okay."); - // }); - // VERIFY_SUCCEEDED(result); - // }); + // * Create a tab with a profile with GUID 1 + // * Reload the settings so that GUID 1 is no longer in the list of profiles + // * Try calling _SplitPane(Duplicate) on tab 1 + // * No new pane should be created (and more importantly, the app should not crash) + // + // Created to test GH#2455 + + const std::string settingsJson0{ R"( + { + "defaultProfile": "{6239a42c-1111-49a3-80bd-e8fdd045185c}", + "profiles": [ + { + "name" : "profile0", + "guid": "{6239a42c-1111-49a3-80bd-e8fdd045185c}", + "historySize": 1 + }, + { + "name" : "profile1", + "guid": "{6239a42c-2222-49a3-80bd-e8fdd045185c}", + "historySize": 2 + } + ] + })" }; + + const std::string settingsJson1{ R"( + { + "defaultProfile": "{6239a42c-1111-49a3-80bd-e8fdd045185c}", + "profiles": [ + { + "name" : "profile1", + "guid": "{6239a42c-2222-49a3-80bd-e8fdd045185c}", + "historySize": 2 + } + ] + })" }; + + VerifyParseSucceeded(settingsJson0); + auto settings0 = std::make_shared(false); + VERIFY_IS_NOT_NULL(settings0); + settings0->_ParseJsonString(settingsJson0, false); + settings0->LayerJson(settings0->_userSettings); + settings0->_ValidateSettings(); + + VerifyParseSucceeded(settingsJson1); + auto settings1 = std::make_shared(false); + VERIFY_IS_NOT_NULL(settings1); + settings1->_ParseJsonString(settingsJson1, false); + settings1->LayerJson(settings1->_userSettings); + settings1->_ValidateSettings(); + + const auto guid1 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-1111-49a3-80bd-e8fdd045185c}"); + const auto guid2 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-2222-49a3-80bd-e8fdd045185c}"); + const auto guid3 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-3333-49a3-80bd-e8fdd045185c}"); + + // This is super wacky, but we can't just initialize the + // com_ptr in the lambda and assign it back out of + // the lambda. We'll crash trying to get a weak_ref to the TerminalPage + // during TerminalPage::Create() below. + // + // Instead, create the winrt object, then get a com_ptr to the + // implementation _from_ the winrt object. This seems to work, even if + // it's weird. + winrt::com_ptr page{ nullptr }; + _initializeTerminalPage(page, settings0); + + auto result = RunOnUIThread([&page]() { + VERIFY_ARE_EQUAL(1u, page->_tabs.Size()); + }); + VERIFY_SUCCEEDED(result); + + result = RunOnUIThread([&page]() { + VERIFY_ARE_EQUAL(1u, page->_tabs.Size()); + auto tab = page->_GetStrongTabImpl(0); + VERIFY_ARE_EQUAL(1, tab->GetLeafPaneCount()); + }); + VERIFY_SUCCEEDED(result); + + Log::Comment(NoThrowString().Format(L"Duplicate the first pane")); + result = RunOnUIThread([&page]() { + page->_SplitPane(SplitState::Automatic, SplitType::Duplicate, nullptr); + + VERIFY_ARE_EQUAL(1u, page->_tabs.Size()); + auto tab = page->_GetStrongTabImpl(0); + VERIFY_ARE_EQUAL(2, tab->GetLeafPaneCount()); + }); + VERIFY_SUCCEEDED(result); + + Log::Comment(NoThrowString().Format( + L"Change the settings of the TerminalPage so the first profile is " + L"no longer in the list of profiles")); + result = RunOnUIThread([&page, settings1]() { + page->_settings = settings1; + }); + VERIFY_SUCCEEDED(result); + + Log::Comment(NoThrowString().Format(L"Duplicate the pane, and don't crash")); + result = RunOnUIThread([&page]() { + page->_SplitPane(SplitState::Automatic, SplitType::Duplicate, nullptr); + + VERIFY_ARE_EQUAL(1u, page->_tabs.Size()); + auto tab = page->_GetStrongTabImpl(0); + VERIFY_ARE_EQUAL(2, + tab->GetLeafPaneCount(), + L"We should gracefully do nothing here - the profile no longer exists."); + }); + VERIFY_SUCCEEDED(result); + + auto cleanup = wil::scope_exit([] { + auto result = RunOnUIThread([]() { + // There's something causing us to crash north of + // TSFInputControl::NotifyEnter, or LayoutRequested. It's very + // unclear what that issue is. Since these tests don't run in + // CI, simply log a message so that the dev running these tests + // knows it's expected. + Log::Comment(L"This test often crashes on cleanup, even when it succeeds. If it succeeded, then crashes, that's okay."); + }); + VERIFY_SUCCEEDED(result); + }); } } From 20b7fe4ef4818ac2ee77af6d7a4f8d9ac366298d Mon Sep 17 00:00:00 2001 From: Javier Date: Tue, 18 Aug 2020 18:11:41 -0500 Subject: [PATCH 066/266] Expose selection background and alpha through the WPF control (#7339) Adds the ability to set the selection background opacity when setting the selection background. This also exposes the selection background and alpha through the terminal WPF container. --- src/cascadia/PublicTerminalCore/HwndTerminal.cpp | 1 + src/cascadia/PublicTerminalCore/HwndTerminal.hpp | 3 +++ src/cascadia/WpfTerminalControl/TerminalTheme.cs | 12 +++++++++++- src/renderer/dx/DxRenderer.cpp | 4 ++-- src/renderer/dx/DxRenderer.hpp | 2 +- 5 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/cascadia/PublicTerminalCore/HwndTerminal.cpp b/src/cascadia/PublicTerminalCore/HwndTerminal.cpp index 01d78f77a32..0a0090338ff 100644 --- a/src/cascadia/PublicTerminalCore/HwndTerminal.cpp +++ b/src/cascadia/PublicTerminalCore/HwndTerminal.cpp @@ -735,6 +735,7 @@ void _stdcall TerminalSetTheme(void* terminal, TerminalTheme theme, LPCWSTR font publicTerminal->_terminal->SetDefaultForeground(theme.DefaultForeground); publicTerminal->_terminal->SetDefaultBackground(theme.DefaultBackground); + publicTerminal->_renderEngine->SetSelectionBackground(theme.DefaultSelectionBackground, theme.SelectionBackgroundAlpha); // Set the font colors for (size_t tableIndex = 0; tableIndex < 16; tableIndex++) diff --git a/src/cascadia/PublicTerminalCore/HwndTerminal.hpp b/src/cascadia/PublicTerminalCore/HwndTerminal.hpp index 47ee1f88dc7..09f7819f312 100644 --- a/src/cascadia/PublicTerminalCore/HwndTerminal.hpp +++ b/src/cascadia/PublicTerminalCore/HwndTerminal.hpp @@ -12,10 +12,13 @@ using namespace Microsoft::Console::VirtualTerminal; +// Keep in sync with TerminalTheme.cs typedef struct _TerminalTheme { COLORREF DefaultBackground; COLORREF DefaultForeground; + COLORREF DefaultSelectionBackground; + float SelectionBackgroundAlpha; DispatchTypes::CursorStyle CursorStyle; COLORREF ColorTable[16]; } TerminalTheme, *LPTerminalTheme; diff --git a/src/cascadia/WpfTerminalControl/TerminalTheme.cs b/src/cascadia/WpfTerminalControl/TerminalTheme.cs index a24c8d3ba55..f0d739e9fcb 100644 --- a/src/cascadia/WpfTerminalControl/TerminalTheme.cs +++ b/src/cascadia/WpfTerminalControl/TerminalTheme.cs @@ -52,7 +52,7 @@ public enum CursorStyle : uint /// /// Structure for color handling in the terminal. /// - /// Pack = 1 removes the padding added by some compilers/processors for optimization purposes. + /// Keep in sync with HwndTerminal.hpp. [StructLayout(LayoutKind.Sequential)] public struct TerminalTheme { @@ -66,6 +66,16 @@ public struct TerminalTheme /// public uint DefaultForeground; + /// + /// The default selection background color of the terminal, represented in Win32 COLORREF format. + /// + public uint DefaultSelectionBackground; + + /// + /// The opacity alpha for the selection color of the terminal, must be between 1.0 and 0.0. + /// + public float SelectionBackgroundAlpha; + /// /// The style of cursor to use in the terminal. /// diff --git a/src/renderer/dx/DxRenderer.cpp b/src/renderer/dx/DxRenderer.cpp index 72b1a1e8fc8..e77d5660f0a 100644 --- a/src/renderer/dx/DxRenderer.cpp +++ b/src/renderer/dx/DxRenderer.cpp @@ -2354,12 +2354,12 @@ CATCH_RETURN(); // - color - GDI Color // Return Value: // - N/A -void DxEngine::SetSelectionBackground(const COLORREF color) noexcept +void DxEngine::SetSelectionBackground(const COLORREF color, const float alpha) noexcept { _selectionBackground = D2D1::ColorF(GetRValue(color) / 255.0f, GetGValue(color) / 255.0f, GetBValue(color) / 255.0f, - 0.5f); + alpha); } // Routine Description: diff --git a/src/renderer/dx/DxRenderer.hpp b/src/renderer/dx/DxRenderer.hpp index fbff81b1834..cf961ace9c1 100644 --- a/src/renderer/dx/DxRenderer.hpp +++ b/src/renderer/dx/DxRenderer.hpp @@ -114,7 +114,7 @@ namespace Microsoft::Console::Render float GetScaling() const noexcept; - void SetSelectionBackground(const COLORREF color) noexcept; + void SetSelectionBackground(const COLORREF color, const float alpha = 0.5f) noexcept; void SetAntialiasingMode(const D2D1_TEXT_ANTIALIAS_MODE antialiasingMode) noexcept; void SetDefaultTextBackgroundOpacity(const float opacity) noexcept; From eecdd53eb89f8d30f0fa3568e69214c8f9241d22 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Wed, 19 Aug 2020 12:33:19 -0500 Subject: [PATCH 067/266] Add support for commands iterable on color schemes (#7329) ## Summary of the Pull Request ![cmdpal-set-color-scheme](https://user-images.githubusercontent.com/18356694/90517094-8eddd480-e12a-11ea-8be4-8b6782d8d88c.gif) Allows for creating commands that iterate over the user's color schemes. Also adds a top-level nested command to `defaults.json` that allows the user to select a color scheme (pictured above). I'm not sure there are really any other use cases that make sense, but it _really_ makes sense for this one. ## References * #5400 - cmdpal megathread * made possible by #6856, _and support from viewers like you._ * All this is being done in pursuit of #6689 ## PR Checklist * [x] Closes wait what? I could have swore there was an issue for this one... * [x] I work here * [x] Tests added/passed * [ ] Requires documentation to be updated - okay maybe now I'll write some docs ## Detailed Description of the Pull Request / Additional comments Most of the hard work for this was already done in #6856. This is just another thing to iterate over. ## Validation Steps Performed * Played with this default command. It works great. * Added tests. --- .../LocalTests_TerminalApp/SettingsTests.cpp | 155 +++++++++++++++++- src/cascadia/TerminalApp/Command.cpp | 74 ++++++--- src/cascadia/TerminalApp/Command.h | 11 +- .../Resources/en-US/Resources.resw | 3 + src/cascadia/TerminalApp/SettingsTypes.h | 7 + src/cascadia/TerminalApp/TerminalPage.cpp | 27 ++- src/cascadia/TerminalApp/TerminalPage.h | 3 +- .../TerminalSettingsSerializationHelpers.h | 8 + src/cascadia/TerminalApp/defaults.json | 13 +- 9 files changed, 258 insertions(+), 43 deletions(-) diff --git a/src/cascadia/LocalTests_TerminalApp/SettingsTests.cpp b/src/cascadia/LocalTests_TerminalApp/SettingsTests.cpp index b99d86e35db..26c764bc8c4 100644 --- a/src/cascadia/LocalTests_TerminalApp/SettingsTests.cpp +++ b/src/cascadia/LocalTests_TerminalApp/SettingsTests.cpp @@ -97,6 +97,8 @@ namespace TerminalAppLocalTests TEST_METHOD(TestUnbindNestedCommand); TEST_METHOD(TestRebindNestedCommand); + TEST_METHOD(TestIterableColorSchemeCommands); + TEST_CLASS_SETUP(ClassSetup) { InitializeJsonReader(); @@ -2681,7 +2683,7 @@ namespace TerminalAppLocalTests VERIFY_ARE_EQUAL(L"${profile.name}", realArgs.TerminalArgs().Profile()); } - auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands.GetView(), settings.GetProfiles()); + auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands.GetView(), settings.GetProfiles(), settings._globals.GetColorSchemes()); _logCommandNames(expandedCommands); VERIFY_ARE_EQUAL(0u, settings._warnings.size()); @@ -2811,7 +2813,7 @@ namespace TerminalAppLocalTests VERIFY_ARE_EQUAL(L"${profile.name}", realArgs.TerminalArgs().Profile()); } - auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands.GetView(), settings.GetProfiles()); + auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands.GetView(), settings.GetProfiles(), settings._globals.GetColorSchemes()); _logCommandNames(expandedCommands); VERIFY_ARE_EQUAL(0u, settings._warnings.size()); @@ -2944,7 +2946,7 @@ namespace TerminalAppLocalTests } settings._ValidateSettings(); - auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands.GetView(), settings.GetProfiles()); + auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands.GetView(), settings.GetProfiles(), settings._globals.GetColorSchemes()); _logCommandNames(expandedCommands); VERIFY_ARE_EQUAL(0u, settings._warnings.size()); @@ -3065,7 +3067,7 @@ namespace TerminalAppLocalTests auto& commands = settings._globals.GetCommands(); settings._ValidateSettings(); - auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands.GetView(), settings.GetProfiles()); + auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands.GetView(), settings.GetProfiles(), settings._globals.GetColorSchemes()); _logCommandNames(expandedCommands); VERIFY_ARE_EQUAL(0u, settings._warnings.size()); @@ -3173,7 +3175,7 @@ namespace TerminalAppLocalTests auto& commands = settings._globals.GetCommands(); settings._ValidateSettings(); - auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands.GetView(), settings.GetProfiles()); + auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands.GetView(), settings.GetProfiles(), settings._globals.GetColorSchemes()); _logCommandNames(expandedCommands); VERIFY_ARE_EQUAL(0u, settings._warnings.size()); @@ -3312,7 +3314,7 @@ namespace TerminalAppLocalTests auto& commands = settings._globals.GetCommands(); settings._ValidateSettings(); - auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands.GetView(), settings.GetProfiles()); + auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands.GetView(), settings.GetProfiles(), settings._globals.GetColorSchemes()); _logCommandNames(expandedCommands); VERIFY_ARE_EQUAL(0u, settings._warnings.size()); @@ -3465,7 +3467,7 @@ namespace TerminalAppLocalTests auto& commands = settings._globals.GetCommands(); settings._ValidateSettings(); - auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands.GetView(), settings.GetProfiles()); + auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands.GetView(), settings.GetProfiles(), settings._globals.GetColorSchemes()); _logCommandNames(expandedCommands); VERIFY_ARE_EQUAL(0u, settings._warnings.size()); @@ -3578,7 +3580,7 @@ namespace TerminalAppLocalTests auto& commands = settings._globals.GetCommands(); settings._ValidateSettings(); - auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands.GetView(), settings.GetProfiles()); + auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands.GetView(), settings.GetProfiles(), settings._globals.GetColorSchemes()); _logCommandNames(expandedCommands); VERIFY_ARE_EQUAL(0u, settings._warnings.size()); @@ -3942,4 +3944,141 @@ namespace TerminalAppLocalTests } } + void SettingsTests::TestIterableColorSchemeCommands() + { + // For this test, put an iterable command with a given `name`, + // containing a ${profile.name} to replace. When we expand it, it should + // have created one command for each profile. + + const std::string settingsJson{ R"( + { + "defaultProfile": "{6239a42c-0000-49a3-80bd-e8fdd045185c}", + "profiles": [ + { + "name": "profile0", + "guid": "{6239a42c-0000-49a3-80bd-e8fdd045185c}", + "historySize": 1, + "commandline": "cmd.exe" + }, + { + "name": "profile1", + "guid": "{6239a42c-1111-49a3-80bd-e8fdd045185c}", + "historySize": 2, + "commandline": "pwsh.exe" + }, + { + "name": "profile2", + "historySize": 3, + "commandline": "wsl.exe" + } + ], + "schemes": [ + { "name": "scheme_0" }, + { "name": "scheme_1" }, + { "name": "scheme_2" }, + ], + "bindings": [ + { + "name": "iterable command ${scheme.name}", + "iterateOn": "schemes", + "command": { "action": "splitPane", "profile": "${scheme.name}" } + }, + ] + })" }; + + VerifyParseSucceeded(settingsJson); + CascadiaSettings settings{}; + settings._ParseJsonString(settingsJson, false); + settings.LayerJson(settings._userSettings); + + VERIFY_ARE_EQUAL(0u, settings._warnings.size()); + + VERIFY_ARE_EQUAL(3u, settings.GetProfiles().size()); + + auto& commands = settings._globals.GetCommands(); + VERIFY_ARE_EQUAL(1u, commands.Size()); + + { + auto command = commands.Lookup(L"iterable command ${scheme.name}"); + VERIFY_IS_NOT_NULL(command); + auto actionAndArgs = command.Action(); + VERIFY_IS_NOT_NULL(actionAndArgs); + VERIFY_ARE_EQUAL(ShortcutAction::SplitPane, actionAndArgs.Action()); + const auto& realArgs = actionAndArgs.Args().try_as(); + VERIFY_IS_NOT_NULL(realArgs); + // Verify the args have the expected value + VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::Automatic, realArgs.SplitStyle()); + VERIFY_IS_NOT_NULL(realArgs.TerminalArgs()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().Commandline().empty()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().StartingDirectory().empty()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().TabTitle().empty()); + VERIFY_IS_FALSE(realArgs.TerminalArgs().Profile().empty()); + VERIFY_ARE_EQUAL(L"${scheme.name}", realArgs.TerminalArgs().Profile()); + } + + auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands.GetView(), settings.GetProfiles(), settings._globals.GetColorSchemes()); + _logCommandNames(expandedCommands); + + VERIFY_ARE_EQUAL(0u, settings._warnings.size()); + VERIFY_ARE_EQUAL(3u, expandedCommands.Size()); + + // Yes, this test is testing splitPane with profiles named after each + // color scheme. These would obviously not work in real life, they're + // just easy tests to write. + + { + auto command = expandedCommands.Lookup(L"iterable command scheme_0"); + VERIFY_IS_NOT_NULL(command); + auto actionAndArgs = command.Action(); + VERIFY_IS_NOT_NULL(actionAndArgs); + VERIFY_ARE_EQUAL(ShortcutAction::SplitPane, actionAndArgs.Action()); + const auto& realArgs = actionAndArgs.Args().try_as(); + VERIFY_IS_NOT_NULL(realArgs); + // Verify the args have the expected value + VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::Automatic, realArgs.SplitStyle()); + VERIFY_IS_NOT_NULL(realArgs.TerminalArgs()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().Commandline().empty()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().StartingDirectory().empty()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().TabTitle().empty()); + VERIFY_IS_FALSE(realArgs.TerminalArgs().Profile().empty()); + VERIFY_ARE_EQUAL(L"scheme_0", realArgs.TerminalArgs().Profile()); + } + + { + auto command = expandedCommands.Lookup(L"iterable command scheme_1"); + VERIFY_IS_NOT_NULL(command); + auto actionAndArgs = command.Action(); + VERIFY_IS_NOT_NULL(actionAndArgs); + VERIFY_ARE_EQUAL(ShortcutAction::SplitPane, actionAndArgs.Action()); + const auto& realArgs = actionAndArgs.Args().try_as(); + VERIFY_IS_NOT_NULL(realArgs); + // Verify the args have the expected value + VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::Automatic, realArgs.SplitStyle()); + VERIFY_IS_NOT_NULL(realArgs.TerminalArgs()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().Commandline().empty()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().StartingDirectory().empty()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().TabTitle().empty()); + VERIFY_IS_FALSE(realArgs.TerminalArgs().Profile().empty()); + VERIFY_ARE_EQUAL(L"scheme_1", realArgs.TerminalArgs().Profile()); + } + + { + auto command = expandedCommands.Lookup(L"iterable command scheme_2"); + VERIFY_IS_NOT_NULL(command); + auto actionAndArgs = command.Action(); + VERIFY_IS_NOT_NULL(actionAndArgs); + VERIFY_ARE_EQUAL(ShortcutAction::SplitPane, actionAndArgs.Action()); + const auto& realArgs = actionAndArgs.Args().try_as(); + VERIFY_IS_NOT_NULL(realArgs); + // Verify the args have the expected value + VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::Automatic, realArgs.SplitStyle()); + VERIFY_IS_NOT_NULL(realArgs.TerminalArgs()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().Commandline().empty()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().StartingDirectory().empty()); + VERIFY_IS_TRUE(realArgs.TerminalArgs().TabTitle().empty()); + VERIFY_IS_FALSE(realArgs.TerminalArgs().Profile().empty()); + VERIFY_ARE_EQUAL(L"scheme_2", realArgs.TerminalArgs().Profile()); + } + } + } diff --git a/src/cascadia/TerminalApp/Command.cpp b/src/cascadia/TerminalApp/Command.cpp index 10b7adba0aa..b8b8540ef33 100644 --- a/src/cascadia/TerminalApp/Command.cpp +++ b/src/cascadia/TerminalApp/Command.cpp @@ -9,6 +9,7 @@ #include "ActionAndArgs.h" #include "JsonUtils.h" #include +#include "TerminalSettingsSerializationHelpers.h" using namespace winrt::TerminalApp; using namespace winrt::Windows::Foundation; @@ -21,9 +22,8 @@ static constexpr std::string_view ArgsKey{ "args" }; static constexpr std::string_view IterateOnKey{ "iterateOn" }; static constexpr std::string_view CommandsKey{ "commands" }; -static constexpr std::string_view IterateOnProfilesValue{ "profiles" }; - -static constexpr std::string_view ProfileName{ "${profile.name}" }; +static constexpr std::string_view ProfileNameToken{ "${profile.name}" }; +static constexpr std::string_view SchemeNameToken{ "${scheme.name}" }; namespace winrt::TerminalApp::implementation { @@ -121,14 +121,7 @@ namespace winrt::TerminalApp::implementation auto result = winrt::make_self(); bool nested = false; - if (const auto iterateOnJson{ json[JsonKey(IterateOnKey)] }) - { - auto s = iterateOnJson.asString(); - if (s == IterateOnProfilesValue) - { - result->_IterateOn = ExpandCommandType::Profiles; - } - } + JsonUtils::GetValueForKey(json, IterateOnKey, result->_IterateOn); // For iterable commands, we'll make another pass at parsing them once // the json is patched. So ignore parsing sub-commands for now. Commands @@ -290,6 +283,7 @@ namespace winrt::TerminalApp::implementation // - void Command::ExpandCommands(Windows::Foundation::Collections::IMap& commands, gsl::span profiles, + gsl::span schemes, std::vector<::TerminalApp::SettingsLoadWarnings>& warnings) { std::vector commandsToRemove; @@ -300,7 +294,7 @@ namespace winrt::TerminalApp::implementation { auto cmd{ get_self(nameAndCmd.Value()) }; - auto newCommands = _expandCommand(cmd, profiles, warnings); + auto newCommands = _expandCommand(cmd, profiles, schemes, warnings); if (newCommands.size() > 0) { commandsToRemove.push_back(nameAndCmd.Key()); @@ -345,13 +339,14 @@ namespace winrt::TerminalApp::implementation // the newly-created commands. std::vector Command::_expandCommand(Command* const expandable, gsl::span profiles, + gsl::span schemes, std::vector<::TerminalApp::SettingsLoadWarnings>& warnings) { std::vector newCommands; if (expandable->HasNestedCommands()) { - ExpandCommands(expandable->_subcommands, profiles, warnings); + ExpandCommands(expandable->_subcommands, profiles, schemes, warnings); } if (expandable->_IterateOn == ExpandCommandType::None) @@ -365,6 +360,26 @@ namespace winrt::TerminalApp::implementation // First, get a string for the original Json::Value auto oldJsonString = expandable->_originalJson.toStyledString(); + auto reParseJson = [&](const auto& newJsonString) -> bool { + // - Now, re-parse the modified value. + Json::Value newJsonValue; + const auto actualDataStart = newJsonString.data(); + const auto actualDataEnd = newJsonString.data() + newJsonString.size(); + if (!reader->parse(actualDataStart, actualDataEnd, &newJsonValue, &errs)) + { + warnings.push_back(::TerminalApp::SettingsLoadWarnings::FailedToParseCommandJson); + // If we encounter a re-parsing error, just stop processing the rest of the commands. + return false; + } + + // Pass the new json back though FromJson, to get the new expanded value. + if (auto newCmd{ Command::FromJson(newJsonValue, warnings) }) + { + newCommands.push_back(*newCmd); + } + return true; + }; + if (expandable->_IterateOn == ExpandCommandType::Profiles) { for (const auto& p : profiles) @@ -382,24 +397,35 @@ namespace winrt::TerminalApp::implementation // - Escape the profile name for JSON appropriately auto escapedProfileName = _escapeForJson(til::u16u8(p.GetName())); auto newJsonString = til::replace_needle_in_haystack(oldJsonString, - ProfileName, + ProfileNameToken, escapedProfileName); - // - Now, re-parse the modified value. - Json::Value newJsonValue; - const auto actualDataStart = newJsonString.data(); - const auto actualDataEnd = newJsonString.data() + newJsonString.size(); - if (!reader->parse(actualDataStart, actualDataEnd, &newJsonValue, &errs)) + // If we encounter a re-parsing error, just stop processing the rest of the commands. + if (!reParseJson(newJsonString)) { - warnings.push_back(::TerminalApp::SettingsLoadWarnings::FailedToParseCommandJson); - // If we encounter a re-parsing error, just stop processing the rest of the commands. break; } + } + } + else if (expandable->_IterateOn == ExpandCommandType::ColorSchemes) + { + for (const auto& s : schemes) + { + // For each scheme, create a new command. We'll take the + // original json, replace any instances of "${scheme.name}" with + // the scheme's name, then re-attempt to parse the action and + // args. - // Pass the new json back though FromJson, to get the new expanded value. - if (auto newCmd{ Command::FromJson(newJsonValue, warnings) }) + // - Escape the profile name for JSON appropriately + auto escapedSchemeName = _escapeForJson(til::u16u8(s.Name())); + auto newJsonString = til::replace_needle_in_haystack(oldJsonString, + SchemeNameToken, + escapedSchemeName); + + // If we encounter a re-parsing error, just stop processing the rest of the commands. + if (!reParseJson(newJsonString)) { - newCommands.push_back(*newCmd); + break; } } } diff --git a/src/cascadia/TerminalApp/Command.h b/src/cascadia/TerminalApp/Command.h index 700dd87e2d7..1b14ba8031d 100644 --- a/src/cascadia/TerminalApp/Command.h +++ b/src/cascadia/TerminalApp/Command.h @@ -22,6 +22,7 @@ Author(s): #include "TerminalWarnings.h" #include "Profile.h" #include "..\inc\cppwinrt_utils.h" +#include "SettingsTypes.h" // fwdecl unittest classes namespace TerminalAppLocalTests @@ -32,12 +33,6 @@ namespace TerminalAppLocalTests namespace winrt::TerminalApp::implementation { - enum class ExpandCommandType : uint32_t - { - None = 0, - Profiles - }; - struct Command : CommandT { Command(); @@ -47,6 +42,7 @@ namespace winrt::TerminalApp::implementation static void ExpandCommands(Windows::Foundation::Collections::IMap& commands, gsl::span profiles, + gsl::span schemes, std::vector<::TerminalApp::SettingsLoadWarnings>& warnings); static std::vector<::TerminalApp::SettingsLoadWarnings> LayerJson(Windows::Foundation::Collections::IMap& commands, @@ -62,7 +58,7 @@ namespace winrt::TerminalApp::implementation OBSERVABLE_GETSET_PROPERTY(winrt::hstring, KeyChordText, _PropertyChangedHandlers); OBSERVABLE_GETSET_PROPERTY(winrt::Windows::UI::Xaml::Controls::IconSource, IconSource, _PropertyChangedHandlers, nullptr); - GETSET_PROPERTY(ExpandCommandType, IterateOn, ExpandCommandType::None); + GETSET_PROPERTY(::TerminalApp::ExpandCommandType, IterateOn, ::TerminalApp::ExpandCommandType::None); private: Json::Value _originalJson; @@ -70,6 +66,7 @@ namespace winrt::TerminalApp::implementation static std::vector _expandCommand(Command* const expandable, gsl::span profiles, + gsl::span schemes, std::vector<::TerminalApp::SettingsLoadWarnings>& warnings); friend class TerminalAppLocalTests::SettingsTests; friend class TerminalAppLocalTests::CommandTests; diff --git a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw index 9d9cd244648..a7384c7ac4a 100644 --- a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw +++ b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw @@ -573,6 +573,9 @@ Close tabs after index {0} {0} will be replaced with a number + + Select color scheme... + Tab Switcher diff --git a/src/cascadia/TerminalApp/SettingsTypes.h b/src/cascadia/TerminalApp/SettingsTypes.h index 66903ab41a4..5a3cc3da00c 100644 --- a/src/cascadia/TerminalApp/SettingsTypes.h +++ b/src/cascadia/TerminalApp/SettingsTypes.h @@ -25,4 +25,11 @@ namespace TerminalApp std::optional x; std::optional y; }; + + enum class ExpandCommandType : uint32_t + { + None = 0, + Profiles, + ColorSchemes + }; }; diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index 307ba9edfea..7049dcf2841 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -2046,6 +2046,14 @@ namespace winrt::TerminalApp::implementation _alwaysOnTopChangedHandlers(*this, nullptr); } + // This is a helper to aid in sorting commands by their `Name`s, alphabetically. + static bool _compareSchemeNames(const winrt::TerminalApp::ColorScheme& lhs, const winrt::TerminalApp::ColorScheme& rhs) + { + std::wstring leftName{ lhs.Name() }; + std::wstring rightName{ rhs.Name() }; + return leftName.compare(rightName) < 0; + } + // Method Description: // - Takes a mapping of names->commands and expands them // Arguments: @@ -2053,9 +2061,22 @@ namespace winrt::TerminalApp::implementation // Return Value: // - IMap TerminalPage::_ExpandCommands(IMapView commandsToExpand, - gsl::span profiles) + gsl::span profiles, + const std::unordered_map& schemes) { std::vector<::TerminalApp::SettingsLoadWarnings> warnings; + + std::vector sortedSchemes; + sortedSchemes.reserve(schemes.size()); + + for (const auto& nameAndScheme : schemes) + { + sortedSchemes.push_back(nameAndScheme.second); + } + std::sort(sortedSchemes.begin(), + sortedSchemes.end(), + _compareSchemeNames); + IMap copyOfCommands = winrt::single_threaded_map(); for (const auto& nameAndCommand : commandsToExpand) { @@ -2064,6 +2085,7 @@ namespace winrt::TerminalApp::implementation Command::ExpandCommands(copyOfCommands, profiles, + sortedSchemes, warnings); return copyOfCommands; @@ -2079,7 +2101,8 @@ namespace winrt::TerminalApp::implementation void TerminalPage::_UpdateCommandsForPalette() { IMap copyOfCommands = _ExpandCommands(_settings->GlobalSettings().GetCommands().GetView(), - _settings->GetProfiles()); + _settings->GetProfiles(), + _settings->GlobalSettings().GetColorSchemes()); _recursiveUpdateCommandKeybindingLabels(_settings, copyOfCommands.GetView()); _recursiveUpdateCommandIcons(copyOfCommands.GetView()); diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h index c19c404bc13..17724e198a0 100644 --- a/src/cascadia/TerminalApp/TerminalPage.h +++ b/src/cascadia/TerminalApp/TerminalPage.h @@ -137,7 +137,8 @@ namespace winrt::TerminalApp::implementation void _UpdateTabWidthMode(); void _UpdateCommandsForPalette(); static winrt::Windows::Foundation::Collections::IMap _ExpandCommands(Windows::Foundation::Collections::IMapView commandsToExpand, - gsl::span profiles); + gsl::span profiles, + const std::unordered_map& schemes); void _DuplicateTabViewItem(); void _RemoveTabViewItem(const Microsoft::UI::Xaml::Controls::TabViewItem& tabViewItem); diff --git a/src/cascadia/TerminalApp/TerminalSettingsSerializationHelpers.h b/src/cascadia/TerminalApp/TerminalSettingsSerializationHelpers.h index c83d0ae1298..06054eab69a 100644 --- a/src/cascadia/TerminalApp/TerminalSettingsSerializationHelpers.h +++ b/src/cascadia/TerminalApp/TerminalSettingsSerializationHelpers.h @@ -184,6 +184,14 @@ JSON_ENUM_MAPPER(::winrt::Microsoft::UI::Xaml::Controls::TabViewWidthMode) }; }; +JSON_ENUM_MAPPER(::TerminalApp::ExpandCommandType) +{ + JSON_MAPPINGS(2) = { + pair_type{ "profiles", ValueType::Profiles }, + pair_type{ "schemes", ValueType::ColorSchemes }, + }; +}; + JSON_FLAG_MAPPER(::winrt::Microsoft::Terminal::TerminalControl::CopyFormat) { JSON_MAPPINGS(5) = { diff --git a/src/cascadia/TerminalApp/defaults.json b/src/cascadia/TerminalApp/defaults.json index a05668723f8..d4f6b40839d 100644 --- a/src/cascadia/TerminalApp/defaults.json +++ b/src/cascadia/TerminalApp/defaults.json @@ -340,6 +340,17 @@ // Visual Adjustments { "command": { "action": "adjustFontSize", "delta": 1 }, "keys": "ctrl+=" }, { "command": { "action": "adjustFontSize", "delta": -1 }, "keys": "ctrl+-" }, - { "command": "resetFontSize", "keys": "ctrl+0" } + { "command": "resetFontSize", "keys": "ctrl+0" }, + + { + "name": { "key": "SetColorSchemeParentCommandName" }, + "commands": [ + { + "iterateOn": "schemes", + "name": "${scheme.name}", + "command": { "action": "setColorScheme", "colorScheme": "${scheme.name}" } + } + ] + }, ] } From 5a0deca3d8dd7acbf473876072b5fa70dfd672bb Mon Sep 17 00:00:00 2001 From: Michael Niksa Date: Wed, 19 Aug 2020 12:31:03 -0700 Subject: [PATCH 068/266] Set ProcessTestResults job to use conditions specified in parent (#7347) Activating a template doesn't actually process conditions. Only jobs, stages, and tasks can process a condition. So specify the full condition in the parent template call as a parameter and ask the child job (who can actually evaluate the condition) to use that parameter to determine if it should run. --- build/pipelines/templates/build-console-ci.yml | 2 +- build/pipelines/templates/helix-processtestresults-job.yml | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/build/pipelines/templates/build-console-ci.yml b/build/pipelines/templates/build-console-ci.yml index b60c8237489..d611a93540c 100644 --- a/build/pipelines/templates/build-console-ci.yml +++ b/build/pipelines/templates/build-console-ci.yml @@ -30,6 +30,6 @@ jobs: parameters: dependsOn: - RunTestsInHelix - condition: and(succeeded(), and(eq('${{ parameters.platform }}', 'x64'), not(eq(variables['Build.Reason'], 'PullRequest')))) + condition: and(succeededOrFailed(), and(eq('${{ parameters.platform }}', 'x64'), not(eq(variables['Build.Reason'], 'PullRequest')))) rerunPassesRequiredToAvoidFailure: ${{ parameters.rerunPassesRequiredToAvoidFailure }} minimumExpectedTestsExecutedCount: ${{ parameters.minimumExpectedTestsExecutedCount }} \ No newline at end of file diff --git a/build/pipelines/templates/helix-processtestresults-job.yml b/build/pipelines/templates/helix-processtestresults-job.yml index f1c18db4fde..9d301e9cb6e 100644 --- a/build/pipelines/templates/helix-processtestresults-job.yml +++ b/build/pipelines/templates/helix-processtestresults-job.yml @@ -1,4 +1,5 @@ parameters: + condition: 'succeededOrFailed()' dependsOn: '' rerunPassesRequiredToAvoidFailure: 5 minimumExpectedTestsExecutedCount: 10 @@ -7,7 +8,7 @@ parameters: jobs: - job: ProcessTestResults - condition: succeededOrFailed() + condition: ${{ parameters.condition }} dependsOn: ${{ parameters.dependsOn }} pool: vmImage: 'windows-2019' From 4814c4f81d686b3da53bcde951f86c6cb8ea176b Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Wed, 19 Aug 2020 20:02:10 -0500 Subject: [PATCH 069/266] Add `togglePaneZoom` to schema, defaults, and sort action names (#7346) #6989 forgot to add `togglePaneZoom` to the schema, so this does that. WHILE I'M HERE: * The action names in the schema and the actual source were both in _random_ order, so I sorted them alphabetically. * I also added an unbound `togglePaneZoom` command to defaults.json, so users can use that command from the cmdpal w/o binding it manually. --- doc/cascadia/profiles.schema.json | 21 +-- src/cascadia/TerminalApp/ActionAndArgs.cpp | 199 ++++++++++----------- src/cascadia/TerminalApp/defaults.json | 1 + 3 files changed, 104 insertions(+), 117 deletions(-) diff --git a/doc/cascadia/profiles.schema.json b/doc/cascadia/profiles.schema.json index d26500bd857..1f28228137a 100644 --- a/doc/cascadia/profiles.schema.json +++ b/doc/cascadia/profiles.schema.json @@ -34,18 +34,24 @@ "ShortcutActionName": { "enum": [ "adjustFontSize", + "closeOtherTabs", "closePane", "closeTab", + "closeTabsAfter", "closeWindow", + "commandPalette", "copy", "duplicateTab", + "find", "moveFocus", "newTab", "nextTab", "openNewTabDropdown", "openSettings", + "openTabColorPicker", "paste", "prevTab", + "renameTab", "resetFontSize", "resizePane", "scrollDown", @@ -53,22 +59,17 @@ "scrollUp", "scrollUpPage", "sendInput", + "setColorScheme", + "setTabColor", "splitPane", "switchToTab", + "tabSwitcher", + "toggleAlwaysOnTop", "toggleFocusMode", "toggleFullscreen", - "toggleAlwaysOnTop", + "togglePaneZoom", "toggleRetroEffect", - "find", - "setColorScheme", - "setTabColor", - "openTabColorPicker", - "renameTab", - "commandPalette", "wt", - "closeOtherTabs", - "closeTabsAfter", - "tabSwitcher", "unbound" ], "type": "string" diff --git a/src/cascadia/TerminalApp/ActionAndArgs.cpp b/src/cascadia/TerminalApp/ActionAndArgs.cpp index 150a31c92ea..cda8332904c 100644 --- a/src/cascadia/TerminalApp/ActionAndArgs.cpp +++ b/src/cascadia/TerminalApp/ActionAndArgs.cpp @@ -7,45 +7,45 @@ #include +static constexpr std::string_view AdjustFontSizeKey{ "adjustFontSize" }; +static constexpr std::string_view CloseOtherTabsKey{ "closeOtherTabs" }; +static constexpr std::string_view ClosePaneKey{ "closePane" }; +static constexpr std::string_view CloseTabKey{ "closeTab" }; +static constexpr std::string_view CloseTabsAfterKey{ "closeTabsAfter" }; +static constexpr std::string_view CloseWindowKey{ "closeWindow" }; static constexpr std::string_view CopyTextKey{ "copy" }; -static constexpr std::string_view PasteTextKey{ "paste" }; -static constexpr std::string_view OpenNewTabDropdownKey{ "openNewTabDropdown" }; static constexpr std::string_view DuplicateTabKey{ "duplicateTab" }; +static constexpr std::string_view ExecuteCommandlineKey{ "wt" }; +static constexpr std::string_view FindKey{ "find" }; +static constexpr std::string_view MoveFocusKey{ "moveFocus" }; static constexpr std::string_view NewTabKey{ "newTab" }; static constexpr std::string_view NewWindowKey{ "newWindow" }; -static constexpr std::string_view CloseWindowKey{ "closeWindow" }; -static constexpr std::string_view CloseTabKey{ "closeTab" }; -static constexpr std::string_view ClosePaneKey{ "closePane" }; -static constexpr std::string_view SwitchtoTabKey{ "switchToTab" }; static constexpr std::string_view NextTabKey{ "nextTab" }; +static constexpr std::string_view OpenNewTabDropdownKey{ "openNewTabDropdown" }; +static constexpr std::string_view OpenSettingsKey{ "openSettings" }; // TODO GH#2557: Add args for OpenSettings +static constexpr std::string_view OpenTabColorPickerKey{ "openTabColorPicker" }; +static constexpr std::string_view PasteTextKey{ "paste" }; static constexpr std::string_view PrevTabKey{ "prevTab" }; -static constexpr std::string_view AdjustFontSizeKey{ "adjustFontSize" }; +static constexpr std::string_view RenameTabKey{ "renameTab" }; static constexpr std::string_view ResetFontSizeKey{ "resetFontSize" }; -static constexpr std::string_view ScrollupKey{ "scrollUp" }; +static constexpr std::string_view ResizePaneKey{ "resizePane" }; static constexpr std::string_view ScrolldownKey{ "scrollDown" }; -static constexpr std::string_view ScrolluppageKey{ "scrollUpPage" }; static constexpr std::string_view ScrolldownpageKey{ "scrollDownPage" }; -static constexpr std::string_view SwitchToTabKey{ "switchToTab" }; -static constexpr std::string_view OpenSettingsKey{ "openSettings" }; // TODO GH#2557: Add args for OpenSettings +static constexpr std::string_view ScrollupKey{ "scrollUp" }; +static constexpr std::string_view ScrolluppageKey{ "scrollUpPage" }; static constexpr std::string_view SendInputKey{ "sendInput" }; -static constexpr std::string_view SplitPaneKey{ "splitPane" }; -static constexpr std::string_view TogglePaneZoomKey{ "togglePaneZoom" }; -static constexpr std::string_view ResizePaneKey{ "resizePane" }; -static constexpr std::string_view MoveFocusKey{ "moveFocus" }; -static constexpr std::string_view FindKey{ "find" }; -static constexpr std::string_view ToggleRetroEffectKey{ "toggleRetroEffect" }; -static constexpr std::string_view ToggleFocusModeKey{ "toggleFocusMode" }; -static constexpr std::string_view ToggleFullscreenKey{ "toggleFullscreen" }; -static constexpr std::string_view ToggleAlwaysOnTopKey{ "toggleAlwaysOnTop" }; static constexpr std::string_view SetColorSchemeKey{ "setColorScheme" }; static constexpr std::string_view SetTabColorKey{ "setTabColor" }; -static constexpr std::string_view OpenTabColorPickerKey{ "openTabColorPicker" }; -static constexpr std::string_view RenameTabKey{ "renameTab" }; -static constexpr std::string_view ExecuteCommandlineKey{ "wt" }; +static constexpr std::string_view SplitPaneKey{ "splitPane" }; +static constexpr std::string_view SwitchtoTabKey{ "switchToTab" }; +static constexpr std::string_view SwitchToTabKey{ "switchToTab" }; +static constexpr std::string_view TabSwitcherKey{ "tabSwitcher" }; +static constexpr std::string_view ToggleAlwaysOnTopKey{ "toggleAlwaysOnTop" }; static constexpr std::string_view ToggleCommandPaletteKey{ "commandPalette" }; -static constexpr std::string_view CloseOtherTabsKey{ "closeOtherTabs" }; -static constexpr std::string_view CloseTabsAfterKey{ "closeTabsAfter" }; -static constexpr std::string_view ToggleTabSwitcherKey{ "tabSwitcher" }; +static constexpr std::string_view ToggleFocusModeKey{ "toggleFocusMode" }; +static constexpr std::string_view ToggleFullscreenKey{ "toggleFullscreen" }; +static constexpr std::string_view TogglePaneZoomKey{ "togglePaneZoom" }; +static constexpr std::string_view ToggleRetroEffectKey{ "toggleRetroEffect" }; static constexpr std::string_view ActionKey{ "action" }; @@ -65,45 +65,45 @@ namespace winrt::TerminalApp::implementation // the map are all const for the lifetime of the app, we have nothing to worry // about here. const std::map> ActionAndArgs::ActionKeyNamesMap{ + { AdjustFontSizeKey, ShortcutAction::AdjustFontSize }, + { CloseOtherTabsKey, ShortcutAction::CloseOtherTabs }, + { ClosePaneKey, ShortcutAction::ClosePane }, + { CloseTabKey, ShortcutAction::CloseTab }, + { CloseTabsAfterKey, ShortcutAction::CloseTabsAfter }, + { CloseWindowKey, ShortcutAction::CloseWindow }, { CopyTextKey, ShortcutAction::CopyText }, - { PasteTextKey, ShortcutAction::PasteText }, - { OpenNewTabDropdownKey, ShortcutAction::OpenNewTabDropdown }, { DuplicateTabKey, ShortcutAction::DuplicateTab }, + { ExecuteCommandlineKey, ShortcutAction::ExecuteCommandline }, + { FindKey, ShortcutAction::Find }, + { MoveFocusKey, ShortcutAction::MoveFocus }, { NewTabKey, ShortcutAction::NewTab }, { NewWindowKey, ShortcutAction::NewWindow }, - { CloseWindowKey, ShortcutAction::CloseWindow }, - { CloseTabKey, ShortcutAction::CloseTab }, - { ClosePaneKey, ShortcutAction::ClosePane }, { NextTabKey, ShortcutAction::NextTab }, + { OpenNewTabDropdownKey, ShortcutAction::OpenNewTabDropdown }, + { OpenSettingsKey, ShortcutAction::OpenSettings }, + { OpenTabColorPickerKey, ShortcutAction::OpenTabColorPicker }, + { PasteTextKey, ShortcutAction::PasteText }, { PrevTabKey, ShortcutAction::PrevTab }, - { AdjustFontSizeKey, ShortcutAction::AdjustFontSize }, + { RenameTabKey, ShortcutAction::RenameTab }, { ResetFontSizeKey, ShortcutAction::ResetFontSize }, - { ScrollupKey, ShortcutAction::ScrollUp }, + { ResizePaneKey, ShortcutAction::ResizePane }, { ScrolldownKey, ShortcutAction::ScrollDown }, - { ScrolluppageKey, ShortcutAction::ScrollUpPage }, { ScrolldownpageKey, ShortcutAction::ScrollDownPage }, - { SwitchToTabKey, ShortcutAction::SwitchToTab }, - { ResizePaneKey, ShortcutAction::ResizePane }, - { MoveFocusKey, ShortcutAction::MoveFocus }, - { OpenSettingsKey, ShortcutAction::OpenSettings }, + { ScrollupKey, ShortcutAction::ScrollUp }, + { ScrolluppageKey, ShortcutAction::ScrollUpPage }, + { SendInputKey, ShortcutAction::SendInput }, { SetColorSchemeKey, ShortcutAction::SetColorScheme }, - { ToggleRetroEffectKey, ShortcutAction::ToggleRetroEffect }, + { SetTabColorKey, ShortcutAction::SetTabColor }, + { SplitPaneKey, ShortcutAction::SplitPane }, + { SwitchToTabKey, ShortcutAction::SwitchToTab }, + { TabSwitcherKey, ShortcutAction::ToggleTabSwitcher }, + { ToggleAlwaysOnTopKey, ShortcutAction::ToggleAlwaysOnTop }, + { ToggleCommandPaletteKey, ShortcutAction::ToggleCommandPalette }, { ToggleFocusModeKey, ShortcutAction::ToggleFocusMode }, { ToggleFullscreenKey, ShortcutAction::ToggleFullscreen }, - { ToggleAlwaysOnTopKey, ShortcutAction::ToggleAlwaysOnTop }, - { SendInputKey, ShortcutAction::SendInput }, - { SplitPaneKey, ShortcutAction::SplitPane }, { TogglePaneZoomKey, ShortcutAction::TogglePaneZoom }, - { SetTabColorKey, ShortcutAction::SetTabColor }, - { OpenTabColorPickerKey, ShortcutAction::OpenTabColorPicker }, + { ToggleRetroEffectKey, ShortcutAction::ToggleRetroEffect }, { UnboundKey, ShortcutAction::Invalid }, - { FindKey, ShortcutAction::Find }, - { RenameTabKey, ShortcutAction::RenameTab }, - { ExecuteCommandlineKey, ShortcutAction::ExecuteCommandline }, - { ToggleCommandPaletteKey, ShortcutAction::ToggleCommandPalette }, - { CloseOtherTabsKey, ShortcutAction::CloseOtherTabs }, - { CloseTabsAfterKey, ShortcutAction::CloseTabsAfter }, - { ToggleTabSwitcherKey, ShortcutAction::ToggleTabSwitcher }, }; using ParseResult = std::tuple>; @@ -115,37 +115,22 @@ namespace winrt::TerminalApp::implementation // placed into this map, with the corresponding deserializer function as the // value. static const std::map> argParsers{ - { ShortcutAction::CopyText, winrt::TerminalApp::implementation::CopyTextArgs::FromJson }, - - { ShortcutAction::NewTab, winrt::TerminalApp::implementation::NewTabArgs::FromJson }, - - { ShortcutAction::SwitchToTab, winrt::TerminalApp::implementation::SwitchToTabArgs::FromJson }, - - { ShortcutAction::ResizePane, winrt::TerminalApp::implementation::ResizePaneArgs::FromJson }, - - { ShortcutAction::MoveFocus, winrt::TerminalApp::implementation::MoveFocusArgs::FromJson }, - - { ShortcutAction::AdjustFontSize, winrt::TerminalApp::implementation::AdjustFontSizeArgs::FromJson }, - - { ShortcutAction::SendInput, winrt::TerminalApp::implementation::SendInputArgs::FromJson }, - - { ShortcutAction::SplitPane, winrt::TerminalApp::implementation::SplitPaneArgs::FromJson }, - - { ShortcutAction::OpenSettings, winrt::TerminalApp::implementation::OpenSettingsArgs::FromJson }, - - { ShortcutAction::SetColorScheme, winrt::TerminalApp::implementation::SetColorSchemeArgs::FromJson }, - - { ShortcutAction::SetTabColor, winrt::TerminalApp::implementation::SetTabColorArgs::FromJson }, - - { ShortcutAction::RenameTab, winrt::TerminalApp::implementation::RenameTabArgs::FromJson }, - - { ShortcutAction::ExecuteCommandline, winrt::TerminalApp::implementation::ExecuteCommandlineArgs::FromJson }, - - { ShortcutAction::CloseOtherTabs, winrt::TerminalApp::implementation::CloseOtherTabsArgs::FromJson }, - - { ShortcutAction::CloseTabsAfter, winrt::TerminalApp::implementation::CloseTabsAfterArgs::FromJson }, - - { ShortcutAction::ToggleTabSwitcher, winrt::TerminalApp::implementation::ToggleTabSwitcherArgs::FromJson }, + { ShortcutAction::AdjustFontSize, AdjustFontSizeArgs::FromJson }, + { ShortcutAction::CloseOtherTabs, CloseOtherTabsArgs::FromJson }, + { ShortcutAction::CloseTabsAfter, CloseTabsAfterArgs::FromJson }, + { ShortcutAction::CopyText, CopyTextArgs::FromJson }, + { ShortcutAction::ExecuteCommandline, ExecuteCommandlineArgs::FromJson }, + { ShortcutAction::MoveFocus, MoveFocusArgs::FromJson }, + { ShortcutAction::NewTab, NewTabArgs::FromJson }, + { ShortcutAction::OpenSettings, OpenSettingsArgs::FromJson }, + { ShortcutAction::RenameTab, RenameTabArgs::FromJson }, + { ShortcutAction::ResizePane, ResizePaneArgs::FromJson }, + { ShortcutAction::SendInput, SendInputArgs::FromJson }, + { ShortcutAction::SetColorScheme, SetColorSchemeArgs::FromJson }, + { ShortcutAction::SetTabColor, SetTabColorArgs::FromJson }, + { ShortcutAction::SplitPane, SplitPaneArgs::FromJson }, + { ShortcutAction::SwitchToTab, SwitchToTabArgs::FromJson }, + { ShortcutAction::ToggleTabSwitcher, ToggleTabSwitcherArgs::FromJson }, { ShortcutAction::Invalid, nullptr }, }; @@ -263,44 +248,44 @@ namespace winrt::TerminalApp::implementation // to load the resources at _init_, only at runtime. static const auto GeneratedActionNames = []() { return std::unordered_map{ + { ShortcutAction::AdjustFontSize, RS_(L"AdjustFontSizeCommandKey") }, + { ShortcutAction::CloseOtherTabs, L"" }, // Intentionally omitted, must be generated by GenerateName + { ShortcutAction::ClosePane, RS_(L"ClosePaneCommandKey") }, + { ShortcutAction::CloseTab, RS_(L"CloseTabCommandKey") }, + { ShortcutAction::CloseTabsAfter, L"" }, // Intentionally omitted, must be generated by GenerateName + { ShortcutAction::CloseWindow, RS_(L"CloseWindowCommandKey") }, { ShortcutAction::CopyText, RS_(L"CopyTextCommandKey") }, - { ShortcutAction::PasteText, RS_(L"PasteTextCommandKey") }, - { ShortcutAction::OpenNewTabDropdown, RS_(L"OpenNewTabDropdownCommandKey") }, { ShortcutAction::DuplicateTab, RS_(L"DuplicateTabCommandKey") }, + { ShortcutAction::ExecuteCommandline, RS_(L"ExecuteCommandlineCommandKey") }, + { ShortcutAction::Find, RS_(L"FindCommandKey") }, + { ShortcutAction::Invalid, L"" }, + { ShortcutAction::MoveFocus, RS_(L"MoveFocusCommandKey") }, { ShortcutAction::NewTab, RS_(L"NewTabCommandKey") }, { ShortcutAction::NewWindow, RS_(L"NewWindowCommandKey") }, - { ShortcutAction::CloseWindow, RS_(L"CloseWindowCommandKey") }, - { ShortcutAction::CloseTab, RS_(L"CloseTabCommandKey") }, - { ShortcutAction::ClosePane, RS_(L"ClosePaneCommandKey") }, { ShortcutAction::NextTab, RS_(L"NextTabCommandKey") }, + { ShortcutAction::OpenNewTabDropdown, RS_(L"OpenNewTabDropdownCommandKey") }, + { ShortcutAction::OpenSettings, RS_(L"OpenSettingsCommandKey") }, + { ShortcutAction::OpenTabColorPicker, RS_(L"OpenTabColorPickerCommandKey") }, + { ShortcutAction::PasteText, RS_(L"PasteTextCommandKey") }, { ShortcutAction::PrevTab, RS_(L"PrevTabCommandKey") }, - { ShortcutAction::AdjustFontSize, RS_(L"AdjustFontSizeCommandKey") }, + { ShortcutAction::RenameTab, RS_(L"ResetTabNameCommandKey") }, { ShortcutAction::ResetFontSize, RS_(L"ResetFontSizeCommandKey") }, - { ShortcutAction::ScrollUp, RS_(L"ScrollUpCommandKey") }, + { ShortcutAction::ResizePane, RS_(L"ResizePaneCommandKey") }, { ShortcutAction::ScrollDown, RS_(L"ScrollDownCommandKey") }, - { ShortcutAction::ScrollUpPage, RS_(L"ScrollUpPageCommandKey") }, { ShortcutAction::ScrollDownPage, RS_(L"ScrollDownPageCommandKey") }, - { ShortcutAction::SwitchToTab, RS_(L"SwitchToTabCommandKey") }, - { ShortcutAction::ResizePane, RS_(L"ResizePaneCommandKey") }, - { ShortcutAction::MoveFocus, RS_(L"MoveFocusCommandKey") }, - { ShortcutAction::OpenSettings, RS_(L"OpenSettingsCommandKey") }, - { ShortcutAction::ToggleRetroEffect, RS_(L"ToggleRetroEffectCommandKey") }, - { ShortcutAction::ToggleFocusMode, RS_(L"ToggleFocusModeCommandKey") }, - { ShortcutAction::ToggleFullscreen, RS_(L"ToggleFullscreenCommandKey") }, - { ShortcutAction::ToggleAlwaysOnTop, RS_(L"ToggleAlwaysOnTopCommandKey") }, + { ShortcutAction::ScrollUp, RS_(L"ScrollUpCommandKey") }, + { ShortcutAction::ScrollUpPage, RS_(L"ScrollUpPageCommandKey") }, { ShortcutAction::SendInput, L"" }, - { ShortcutAction::SplitPane, RS_(L"SplitPaneCommandKey") }, - { ShortcutAction::TogglePaneZoom, RS_(L"TogglePaneZoomCommandKey") }, - { ShortcutAction::Invalid, L"" }, - { ShortcutAction::Find, RS_(L"FindCommandKey") }, { ShortcutAction::SetColorScheme, L"" }, { ShortcutAction::SetTabColor, RS_(L"ResetTabColorCommandKey") }, - { ShortcutAction::OpenTabColorPicker, RS_(L"OpenTabColorPickerCommandKey") }, - { ShortcutAction::RenameTab, RS_(L"ResetTabNameCommandKey") }, - { ShortcutAction::ExecuteCommandline, RS_(L"ExecuteCommandlineCommandKey") }, + { ShortcutAction::SplitPane, RS_(L"SplitPaneCommandKey") }, + { ShortcutAction::SwitchToTab, RS_(L"SwitchToTabCommandKey") }, + { ShortcutAction::ToggleAlwaysOnTop, RS_(L"ToggleAlwaysOnTopCommandKey") }, { ShortcutAction::ToggleCommandPalette, RS_(L"ToggleCommandPaletteCommandKey") }, - { ShortcutAction::CloseOtherTabs, L"" }, // Intentionally omitted, must be generated by GenerateName - { ShortcutAction::CloseTabsAfter, L"" }, // Intentionally omitted, must be generated by GenerateName + { ShortcutAction::ToggleFocusMode, RS_(L"ToggleFocusModeCommandKey") }, + { ShortcutAction::ToggleFullscreen, RS_(L"ToggleFullscreenCommandKey") }, + { ShortcutAction::TogglePaneZoom, RS_(L"TogglePaneZoomCommandKey") }, + { ShortcutAction::ToggleRetroEffect, RS_(L"ToggleRetroEffectCommandKey") }, }; }(); diff --git a/src/cascadia/TerminalApp/defaults.json b/src/cascadia/TerminalApp/defaults.json index d4f6b40839d..4a272e4d0c6 100644 --- a/src/cascadia/TerminalApp/defaults.json +++ b/src/cascadia/TerminalApp/defaults.json @@ -324,6 +324,7 @@ { "command": { "action": "moveFocus", "direction": "left" }, "keys": "alt+left" }, { "command": { "action": "moveFocus", "direction": "right" }, "keys": "alt+right" }, { "command": { "action": "moveFocus", "direction": "up" }, "keys": "alt+up" }, + { "command": "togglePaneZoom" }, // Clipboard Integration { "command": { "action": "copy", "singleLine": false }, "keys": "ctrl+shift+c" }, From 2c4b868b2093367f5f195399c98d870bc61e05fa Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Wed, 19 Aug 2020 20:02:42 -0500 Subject: [PATCH 070/266] Replace "bindings" with "actions" (#7332) In #6532, we thought it would be a good idea to add "bindings" as an overload for "keybindings", as we were no longer going to use the keybindings array for just keybindings. We were going to add commands. So we started secretly treating `"bindings"` the same as `"keybindings"`. Then, in #7175, we discussed using "actions" as the key for the list of commands/keybindings/global actions, instead of using "bindings". We're going to be using this array as the global list of all actions, so it makes sense to just call it `"actions"`. This PR renames "bindings" to "actions". Fortunately, we never documented the "bindings" overload in the first place, so we can get away with this safely, and preferably before we ship "bindings" for too long. References #6899 --- .../LocalTests_TerminalApp/SettingsTests.cpp | 28 +++++++++---------- .../TerminalApp/GlobalAppSettings.cpp | 4 +-- .../TerminalApp/defaults-universal.json | 2 +- src/cascadia/TerminalApp/defaults.json | 2 +- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/cascadia/LocalTests_TerminalApp/SettingsTests.cpp b/src/cascadia/LocalTests_TerminalApp/SettingsTests.cpp index 26c764bc8c4..f72229526c0 100644 --- a/src/cascadia/LocalTests_TerminalApp/SettingsTests.cpp +++ b/src/cascadia/LocalTests_TerminalApp/SettingsTests.cpp @@ -2438,7 +2438,7 @@ namespace TerminalAppLocalTests "commandline": "wsl.exe" } ], - "bindings": [ + "actions": [ { "keys": "ctrl+a", "command": { "action": "splitPane", "split": "vertical" } }, { "name": "ctrl+b", "command": { "action": "splitPane", "split": "vertical" } }, { "keys": "ctrl+c", "name": "ctrl+c", "command": { "action": "splitPane", "split": "vertical" } }, @@ -2640,7 +2640,7 @@ namespace TerminalAppLocalTests "commandline": "wsl.exe" } ], - "bindings": [ + "actions": [ { "name": "iterable command ${profile.name}", "iterateOn": "profiles", @@ -2771,7 +2771,7 @@ namespace TerminalAppLocalTests "commandline": "wsl.exe" } ], - "bindings": [ + "actions": [ { "iterateOn": "profiles", "command": { "action": "splitPane", "profile": "${profile.name}" } @@ -2902,7 +2902,7 @@ namespace TerminalAppLocalTests "commandline": "wsl.exe" } ], - "bindings": [ + "actions": [ { "name": "iterable command ${profile.name}", "iterateOn": "profiles", @@ -3039,7 +3039,7 @@ namespace TerminalAppLocalTests "commandline": "wsl.exe" } ], - "bindings": [ + "actions": [ { "name": "Connect to ssh...", "commands": [ @@ -3142,7 +3142,7 @@ namespace TerminalAppLocalTests "commandline": "wsl.exe" } ], - "bindings": [ + "actions": [ { "name": "grandparent", "commands": [ @@ -3290,7 +3290,7 @@ namespace TerminalAppLocalTests "commandline": "wsl.exe" } ], - "bindings": [ + "actions": [ { "iterateOn": "profiles", "name": "${profile.name}...", @@ -3443,7 +3443,7 @@ namespace TerminalAppLocalTests "commandline": "wsl.exe" } ], - "bindings": [ + "actions": [ { "name": "New Tab With Profile...", "commands": [ @@ -3551,7 +3551,7 @@ namespace TerminalAppLocalTests "commandline": "wsl.exe" } ], - "bindings": [ + "actions": [ { "name": "New Pane...", "commands": [ @@ -3714,7 +3714,7 @@ namespace TerminalAppLocalTests "commandline": "wsl.exe" } ], - "bindings": [ + "actions": [ { "commands": [ { @@ -3777,7 +3777,7 @@ namespace TerminalAppLocalTests "commandline": "wsl.exe" } ], - "bindings": [ + "actions": [ { "name": "parent", "commands": [ @@ -3798,7 +3798,7 @@ namespace TerminalAppLocalTests const std::string settings1Json{ R"( { "defaultProfile": "{6239a42c-0000-49a3-80bd-e8fdd045185c}", - "bindings": [ + "actions": [ { "name": "parent", "commands": null @@ -3860,7 +3860,7 @@ namespace TerminalAppLocalTests "commandline": "wsl.exe" } ], - "bindings": [ + "actions": [ { "name": "parent", "commands": [ @@ -3881,7 +3881,7 @@ namespace TerminalAppLocalTests const std::string settings1Json{ R"( { "defaultProfile": "{6239a42c-0000-49a3-80bd-e8fdd045185c}", - "bindings": [ + "actions": [ { "name": "parent", "command": "newTab" diff --git a/src/cascadia/TerminalApp/GlobalAppSettings.cpp b/src/cascadia/TerminalApp/GlobalAppSettings.cpp index 834038bfad8..449502509cd 100644 --- a/src/cascadia/TerminalApp/GlobalAppSettings.cpp +++ b/src/cascadia/TerminalApp/GlobalAppSettings.cpp @@ -16,7 +16,7 @@ using namespace ::Microsoft::Console; using namespace winrt::Microsoft::UI::Xaml::Controls; static constexpr std::string_view LegacyKeybindingsKey{ "keybindings" }; -static constexpr std::string_view BindingsKey{ "bindings" }; +static constexpr std::string_view ActionsKey{ "actions" }; static constexpr std::string_view DefaultProfileKey{ "defaultProfile" }; static constexpr std::string_view AlwaysShowTabsKey{ "alwaysShowTabs" }; static constexpr std::string_view InitialRowsKey{ "initialRows" }; @@ -202,7 +202,7 @@ void GlobalAppSettings::LayerJson(const Json::Value& json) } }; parseBindings(LegacyKeybindingsKey); - parseBindings(BindingsKey); + parseBindings(ActionsKey); } // Method Description: diff --git a/src/cascadia/TerminalApp/defaults-universal.json b/src/cascadia/TerminalApp/defaults-universal.json index 0ac56908499..993da6d8f47 100644 --- a/src/cascadia/TerminalApp/defaults-universal.json +++ b/src/cascadia/TerminalApp/defaults-universal.json @@ -72,7 +72,7 @@ "brightWhite": "#FFFFFF" } ], - "keybindings": + "actions": [ // Application-level Keys { "command": "closeWindow", "keys": "alt+f4" }, diff --git a/src/cascadia/TerminalApp/defaults.json b/src/cascadia/TerminalApp/defaults.json index 4a272e4d0c6..bab95d13a85 100644 --- a/src/cascadia/TerminalApp/defaults.json +++ b/src/cascadia/TerminalApp/defaults.json @@ -271,7 +271,7 @@ "brightWhite": "#EEEEEC" } ], - "bindings": + "actions": [ // Application-level Keys { "command": "closeWindow", "keys": "alt+f4" }, From 6f991d312e35d294a13fbce0e7a03bdc896e2ec1 Mon Sep 17 00:00:00 2001 From: Michelle Tan <41475767+MichelleTanPY@users.noreply.github.com> Date: Thu, 20 Aug 2020 22:58:13 +0100 Subject: [PATCH 071/266] Make sure we check to profile shortcuts with an index >9 (#7344) Closes #7325 --- src/cascadia/TerminalApp/TerminalPage.cpp | 33 +++++++++++------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index 7049dcf2841..6de63a6be7b 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -462,25 +462,22 @@ namespace winrt::TerminalApp::implementation const auto& profile = _settings->GetProfiles()[profileIndex]; auto profileMenuItem = WUX::Controls::MenuFlyoutItem{}; - // add the keyboard shortcuts for the first 9 profiles - if (profileIndex < 9) + // Add the keyboard shortcuts based on the number of profiles defined + // Look for a keychord that is bound to the equivalent + // NewTab(ProfileIndex=N) action + auto actionAndArgs = winrt::make_self(); + actionAndArgs->Action(ShortcutAction::NewTab); + auto newTabArgs = winrt::make_self(); + auto newTerminalArgs = winrt::make_self(); + newTerminalArgs->ProfileIndex(profileIndex); + newTabArgs->TerminalArgs(*newTerminalArgs); + actionAndArgs->Args(*newTabArgs); + auto profileKeyChord{ keyBindings.GetKeyBindingForActionWithArgs(*actionAndArgs) }; + + // make sure we find one to display + if (profileKeyChord) { - // Look for a keychord that is bound to the equivalent - // NewTab(ProfileIndex=N) action - auto actionAndArgs = winrt::make_self(); - actionAndArgs->Action(ShortcutAction::NewTab); - auto newTabArgs = winrt::make_self(); - auto newTerminalArgs = winrt::make_self(); - newTerminalArgs->ProfileIndex(profileIndex); - newTabArgs->TerminalArgs(*newTerminalArgs); - actionAndArgs->Args(*newTabArgs); - auto profileKeyChord{ keyBindings.GetKeyBindingForActionWithArgs(*actionAndArgs) }; - - // make sure we find one to display - if (profileKeyChord) - { - _SetAcceleratorForMenuItem(profileMenuItem, profileKeyChord); - } + _SetAcceleratorForMenuItem(profileMenuItem, profileKeyChord); } auto profileName = profile.GetName(); From e238dcb84d081c703504498298abe924766f3fbd Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Thu, 20 Aug 2020 17:44:37 -0500 Subject: [PATCH 072/266] Fix intellisense errors by moving TerminalApp projects around (#6897) The easiest fix was actually just moving all the source files from `TerminalApp` to `TerminalApp/lib`, where the appropriate `pch.h` actually resides. Closes #6866 --- OpenConsole.sln | 4 +- .../TerminalApp.LocalTests.vcxproj | 6 +- .../TestHostApp/TestHostApp.vcxproj | 2 +- src/cascadia/TerminalApp/App.idl | 2 +- src/cascadia/TerminalApp/AppKeyBindings.idl | 4 +- src/cascadia/TerminalApp/AppLogic.idl | 6 +- src/cascadia/TerminalApp/Command.idl | 2 +- src/cascadia/TerminalApp/CommandPalette.idl | 2 +- .../TerminalApp/MinMaxCloseControl.idl | 2 +- .../TerminalApp/ShortcutActionDispatch.idl | 2 +- .../{lib => }/TerminalAppLib.vcxproj | 314 +++++++++--------- .../{lib => }/TerminalAppLib.vcxproj.filters | 0 .../{ => dll}/FixVisualStudioBug.targets | 0 .../TerminalApp/{ => dll}/TerminalApp.def | 0 .../TerminalApp/{ => dll}/TerminalApp.vcxproj | 26 +- src/cascadia/TerminalApp/{lib => dll}/pch.cpp | 0 src/cascadia/TerminalApp/dll/pch.h | 12 + src/cascadia/TerminalApp/lib/pch.h | 75 ----- src/cascadia/TerminalApp/pch.h | 69 +++- .../WindowsTerminal/WindowsTerminal.vcxproj | 2 +- .../WindowsTerminalUniversal.vcxproj | 2 +- .../WindowsTerminalUniversal/main.cpp | 2 +- .../ut_app/TerminalApp.UnitTests.vcxproj | 14 +- 23 files changed, 278 insertions(+), 270 deletions(-) rename src/cascadia/TerminalApp/{lib => }/TerminalAppLib.vcxproj (52%) rename src/cascadia/TerminalApp/{lib => }/TerminalAppLib.vcxproj.filters (100%) rename src/cascadia/TerminalApp/{ => dll}/FixVisualStudioBug.targets (100%) rename src/cascadia/TerminalApp/{ => dll}/TerminalApp.def (100%) rename src/cascadia/TerminalApp/{ => dll}/TerminalApp.vcxproj (78%) rename src/cascadia/TerminalApp/{lib => dll}/pch.cpp (100%) create mode 100644 src/cascadia/TerminalApp/dll/pch.h delete mode 100644 src/cascadia/TerminalApp/lib/pch.h diff --git a/OpenConsole.sln b/OpenConsole.sln index 935e252c3f5..82ab30fdc5a 100644 --- a/OpenConsole.sln +++ b/OpenConsole.sln @@ -177,7 +177,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WindowsTerminal", "src\casc {9CBD7DFA-1754-4A9D-93D7-857A9D17CB1B} = {9CBD7DFA-1754-4A9D-93D7-857A9D17CB1B} EndProjectSection EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TerminalApp", "src\cascadia\TerminalApp\TerminalApp.vcxproj", "{CA5CAD1A-44BD-4AC7-AC72-F16E576FDD12}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TerminalApp", "src\cascadia\TerminalApp\dll\TerminalApp.vcxproj", "{CA5CAD1A-44BD-4AC7-AC72-F16E576FDD12}" ProjectSection(ProjectDependencies) = postProject {CA5CAD1A-9A12-429C-B551-8562EC954746} = {CA5CAD1A-9A12-429C-B551-8562EC954746} {CA5CAD1A-C46D-4588-B1C0-40F31AE9100B} = {CA5CAD1A-C46D-4588-B1C0-40F31AE9100B} @@ -227,7 +227,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UnitTests_TerminalApp", "sr {CA5CAD1A-9A12-429C-B551-8562EC954746} = {CA5CAD1A-9A12-429C-B551-8562EC954746} EndProjectSection EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TerminalAppLib", "src\cascadia\TerminalApp\lib\TerminalAppLib.vcxproj", "{CA5CAD1A-9A12-429C-B551-8562EC954746}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TerminalAppLib", "src\cascadia\TerminalApp\TerminalAppLib.vcxproj", "{CA5CAD1A-9A12-429C-B551-8562EC954746}" ProjectSection(ProjectDependencies) = postProject {CA5CAD1A-44BD-4AC7-AC72-6CA5B3AB89ED} = {CA5CAD1A-44BD-4AC7-AC72-6CA5B3AB89ED} EndProjectSection diff --git a/src/cascadia/LocalTests_TerminalApp/TerminalApp.LocalTests.vcxproj b/src/cascadia/LocalTests_TerminalApp/TerminalApp.LocalTests.vcxproj index b99a6146693..67952867d7d 100644 --- a/src/cascadia/LocalTests_TerminalApp/TerminalApp.LocalTests.vcxproj +++ b/src/cascadia/LocalTests_TerminalApp/TerminalApp.LocalTests.vcxproj @@ -74,14 +74,14 @@ - + - + @@ -89,7 +89,7 @@ - ..;$(OpenConsoleDir)\dep;$(OpenConsoleDir)\dep\jsoncpp\json;$(OpenConsoleDir)src\inc;$(OpenConsoleDir)src\inc\test;$(WinRT_IncludePath)\..\cppwinrt\winrt;"$(OpenConsoleDir)\src\cascadia\TerminalApp\lib\Generated Files";%(AdditionalIncludeDirectories) + ..;$(OpenConsoleDir)\dep;$(OpenConsoleDir)\dep\jsoncpp\json;$(OpenConsoleDir)src\inc;$(OpenConsoleDir)src\inc\test;$(WinRT_IncludePath)\..\cppwinrt\winrt;"$(OpenConsoleDir)\src\cascadia\TerminalApp\Generated Files";%(AdditionalIncludeDirectories) pch.h diff --git a/src/cascadia/LocalTests_TerminalApp/TestHostApp/TestHostApp.vcxproj b/src/cascadia/LocalTests_TerminalApp/TestHostApp/TestHostApp.vcxproj index f035d8a74d1..b6d85e9ae04 100644 --- a/src/cascadia/LocalTests_TerminalApp/TestHostApp/TestHostApp.vcxproj +++ b/src/cascadia/LocalTests_TerminalApp/TestHostApp/TestHostApp.vcxproj @@ -96,7 +96,7 @@ - + {ca5cad1a-44bd-4ac7-ac72-f16e576fdd12} diff --git a/src/cascadia/TerminalApp/App.idl b/src/cascadia/TerminalApp/App.idl index 018c495b805..5e000c5a182 100644 --- a/src/cascadia/TerminalApp/App.idl +++ b/src/cascadia/TerminalApp/App.idl @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import "../AppLogic.idl"; +import "AppLogic.idl"; namespace TerminalApp { diff --git a/src/cascadia/TerminalApp/AppKeyBindings.idl b/src/cascadia/TerminalApp/AppKeyBindings.idl index 0dcba935591..ab670a33908 100644 --- a/src/cascadia/TerminalApp/AppKeyBindings.idl +++ b/src/cascadia/TerminalApp/AppKeyBindings.idl @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import "../ActionArgs.idl"; -import "../ShortcutActionDispatch.idl"; +import "ActionArgs.idl"; +import "ShortcutActionDispatch.idl"; namespace TerminalApp { diff --git a/src/cascadia/TerminalApp/AppLogic.idl b/src/cascadia/TerminalApp/AppLogic.idl index 00006608ef1..73b77b54413 100644 --- a/src/cascadia/TerminalApp/AppLogic.idl +++ b/src/cascadia/TerminalApp/AppLogic.idl @@ -1,9 +1,9 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import "../TerminalPage.idl"; -import "../ShortcutActionDispatch.idl"; -import "../IDirectKeyListener.idl"; +import "TerminalPage.idl"; +import "ShortcutActionDispatch.idl"; +import "IDirectKeyListener.idl"; namespace TerminalApp { diff --git a/src/cascadia/TerminalApp/Command.idl b/src/cascadia/TerminalApp/Command.idl index beb0a43f10c..eea4c9bac73 100644 --- a/src/cascadia/TerminalApp/Command.idl +++ b/src/cascadia/TerminalApp/Command.idl @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import "../ShortcutActionDispatch.idl"; +import "ShortcutActionDispatch.idl"; namespace TerminalApp { diff --git a/src/cascadia/TerminalApp/CommandPalette.idl b/src/cascadia/TerminalApp/CommandPalette.idl index 93d5851f60d..793ac8334e4 100644 --- a/src/cascadia/TerminalApp/CommandPalette.idl +++ b/src/cascadia/TerminalApp/CommandPalette.idl @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import "../Command.idl"; +import "Command.idl"; namespace TerminalApp { diff --git a/src/cascadia/TerminalApp/MinMaxCloseControl.idl b/src/cascadia/TerminalApp/MinMaxCloseControl.idl index c0ccb370f21..eb8fbd16e37 100644 --- a/src/cascadia/TerminalApp/MinMaxCloseControl.idl +++ b/src/cascadia/TerminalApp/MinMaxCloseControl.idl @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import "..\TitlebarControl.idl"; +import "TitlebarControl.idl"; namespace TerminalApp { diff --git a/src/cascadia/TerminalApp/ShortcutActionDispatch.idl b/src/cascadia/TerminalApp/ShortcutActionDispatch.idl index e13c0433565..f34256f3a6b 100644 --- a/src/cascadia/TerminalApp/ShortcutActionDispatch.idl +++ b/src/cascadia/TerminalApp/ShortcutActionDispatch.idl @@ -1,6 +1,6 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import "../ActionArgs.idl"; +import "ActionArgs.idl"; namespace TerminalApp { diff --git a/src/cascadia/TerminalApp/lib/TerminalAppLib.vcxproj b/src/cascadia/TerminalApp/TerminalAppLib.vcxproj similarity index 52% rename from src/cascadia/TerminalApp/lib/TerminalAppLib.vcxproj rename to src/cascadia/TerminalApp/TerminalAppLib.vcxproj index abb49e21e58..807f9464445 100644 --- a/src/cascadia/TerminalApp/lib/TerminalAppLib.vcxproj +++ b/src/cascadia/TerminalApp/TerminalAppLib.vcxproj @@ -24,9 +24,9 @@ false nested - + - + @@ -42,190 +42,190 @@ For any types that use XAML information, if their .idl and .h aren't marked DependentUpon the corresponding .xaml file, XamlTypeInfo.g.h won't pick it up correctly. --> - + Designer - + Designer - + Designer - + Designer - + Designer - + Designer - + Designer - - - - - ../MinMaxCloseControl.xaml + + + + + MinMaxCloseControl.xaml - - ../TerminalPage.xaml + + TerminalPage.xaml Code - - ../TitlebarControl.xaml + + TitlebarControl.xaml - - ../TabRowControl.xaml + + TabRowControl.xaml - - ../ColorPickupFlyout.xaml + + ColorPickupFlyout.xaml - - ../CommandPalette.xaml + + CommandPalette.xaml - - ../Command.idl + + Command.idl - - ../EmptyStringVisibilityConverter.idl + + EmptyStringVisibilityConverter.idl - - ../HasNestedCommandsVisibilityConverter.idl + + HasNestedCommandsVisibilityConverter.idl - - ../Tab.idl + + Tab.idl - - - ../ColorScheme.idl + + + ColorScheme.idl - - - - - - - - - - - - - - - - - ../TerminalSettings.idl + + + + + + + + + + + + + + + + + TerminalSettings.idl - - ../ShortcutActionDispatch.idl + + ShortcutActionDispatch.idl - - ../ActionArgs.idl + + ActionArgs.idl - - ../ActionArgs.idl + + ActionArgs.idl - - - ../AppKeyBindings.idl + + + AppKeyBindings.idl - - ../App.xaml + + App.xaml - - ../AppLogic.idl + + AppLogic.idl - - - - - ../MinMaxCloseControl.xaml + + + + + MinMaxCloseControl.xaml - - ../TerminalPage.xaml + + TerminalPage.xaml Code - - ../TitlebarControl.xaml + + TitlebarControl.xaml - - ../TabRowControl.xaml + + TabRowControl.xaml - - ../ColorPickupFlyout.xaml + + ColorPickupFlyout.xaml - - ../CommandPalette.xaml + + CommandPalette.xaml - - ../Command.idl + + Command.idl - - ../EmptyStringVisibilityConverter.idl + + EmptyStringVisibilityConverter.idl - - ../HasNestedCommandsVisibilityConverter.idl + + HasNestedCommandsVisibilityConverter.idl - - ../Tab.idl + + Tab.idl - - - ../ColorScheme.idl + + + ColorScheme.idl - - - - - - - - - - - - - - - - ../TerminalSettings.idl + + + + + + + + + + + + + + + + TerminalSettings.idl Create - - ../AppKeyBindings.idl + + AppKeyBindings.idl - - ../ShortcutActionDispatch.idl + + ShortcutActionDispatch.idl - - ../ActionArgs.idl + + ActionArgs.idl - - ../ActionArgs.idl + + ActionArgs.idl - - ../App.xaml + + App.xaml - - ../App.xaml + + App.xaml - - ../AppLogic.idl + + AppLogic.idl @@ -238,50 +238,50 @@ - - - ../App.xaml + + + App.xaml - - - - - - ../MinMaxCloseControl.xaml + + + + + + MinMaxCloseControl.xaml Code - - ../TerminalPage.xaml + + TerminalPage.xaml Code - - ../TitlebarControl.xaml + + TitlebarControl.xaml Code - - ../TabRowControl.xaml + + TabRowControl.xaml Code - - ../ColorPickupFlyout.xaml + + ColorPickupFlyout.xaml Code - - ../CommandPalette.xaml + + CommandPalette.xaml Code - - - - - - + + + + + + - - - + + + @@ -343,8 +343,8 @@ - - + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. @@ -375,16 +375,16 @@ - - + + - - + + - - + + diff --git a/src/cascadia/TerminalApp/lib/TerminalAppLib.vcxproj.filters b/src/cascadia/TerminalApp/TerminalAppLib.vcxproj.filters similarity index 100% rename from src/cascadia/TerminalApp/lib/TerminalAppLib.vcxproj.filters rename to src/cascadia/TerminalApp/TerminalAppLib.vcxproj.filters diff --git a/src/cascadia/TerminalApp/FixVisualStudioBug.targets b/src/cascadia/TerminalApp/dll/FixVisualStudioBug.targets similarity index 100% rename from src/cascadia/TerminalApp/FixVisualStudioBug.targets rename to src/cascadia/TerminalApp/dll/FixVisualStudioBug.targets diff --git a/src/cascadia/TerminalApp/TerminalApp.def b/src/cascadia/TerminalApp/dll/TerminalApp.def similarity index 100% rename from src/cascadia/TerminalApp/TerminalApp.def rename to src/cascadia/TerminalApp/dll/TerminalApp.def diff --git a/src/cascadia/TerminalApp/TerminalApp.vcxproj b/src/cascadia/TerminalApp/dll/TerminalApp.vcxproj similarity index 78% rename from src/cascadia/TerminalApp/TerminalApp.vcxproj rename to src/cascadia/TerminalApp/dll/TerminalApp.vcxproj index a19fa271c79..8d8962cca79 100644 --- a/src/cascadia/TerminalApp/TerminalApp.vcxproj +++ b/src/cascadia/TerminalApp/dll/TerminalApp.vcxproj @@ -17,9 +17,9 @@ --> true - + - + @@ -28,15 +28,15 @@ - + - - - - - - - + + + + + + + @@ -72,14 +72,14 @@ - + true true - - + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. diff --git a/src/cascadia/TerminalApp/lib/pch.cpp b/src/cascadia/TerminalApp/dll/pch.cpp similarity index 100% rename from src/cascadia/TerminalApp/lib/pch.cpp rename to src/cascadia/TerminalApp/dll/pch.cpp diff --git a/src/cascadia/TerminalApp/dll/pch.h b/src/cascadia/TerminalApp/dll/pch.h new file mode 100644 index 00000000000..465827b00d6 --- /dev/null +++ b/src/cascadia/TerminalApp/dll/pch.h @@ -0,0 +1,12 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. +// +// pch.h +// Header for platform projection include files +// + +#pragma once + +// This file can be empty - the pch.h in TerminalApp/lib does the heavy lifting +// of including all the headers we need. As this project is just a dll wrapper, +// we don't actually need anything in here. diff --git a/src/cascadia/TerminalApp/lib/pch.h b/src/cascadia/TerminalApp/lib/pch.h deleted file mode 100644 index dcac6c4e1ab..00000000000 --- a/src/cascadia/TerminalApp/lib/pch.h +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. -// -// pch.h -// Header for platform projection include files -// - -#pragma once - -#define WIN32_LEAN_AND_MEAN - -// Manually include til after we include Windows.Foundation to give it winrt superpowers -#define BLOCK_TIL -#include -// This is inexplicable, but for whatever reason, cppwinrt conflicts with the -// SDK definition of this function, so the only fix is to undef it. -// from WinBase.h -// Windows::UI::Xaml::Media::Animation::IStoryboard::GetCurrentTime -#ifdef GetCurrentTime -#undef GetCurrentTime -#endif - -#include - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "winrt/Windows.UI.Xaml.Markup.h" -#include "winrt/Windows.UI.Xaml.Documents.h" -#include "winrt/Windows.UI.Xaml.Automation.h" -#include -#include - -#include -#include -#include -#include - -#include - -#include - -// Including TraceLogging essentials for the binary -#include -#include -TRACELOGGING_DECLARE_PROVIDER(g_hTerminalAppProvider); -#include -#include - -// JsonCpp -#include - -#include - -#include -#include - -#include - -// Manually include til after we include Windows.Foundation to give it winrt superpowers -#include "til.h" diff --git a/src/cascadia/TerminalApp/pch.h b/src/cascadia/TerminalApp/pch.h index 465827b00d6..dcac6c4e1ab 100644 --- a/src/cascadia/TerminalApp/pch.h +++ b/src/cascadia/TerminalApp/pch.h @@ -7,6 +7,69 @@ #pragma once -// This file can be empty - the pch.h in TerminalApp/lib does the heavy lifting -// of including all the headers we need. As this project is just a dll wrapper, -// we don't actually need anything in here. +#define WIN32_LEAN_AND_MEAN + +// Manually include til after we include Windows.Foundation to give it winrt superpowers +#define BLOCK_TIL +#include +// This is inexplicable, but for whatever reason, cppwinrt conflicts with the +// SDK definition of this function, so the only fix is to undef it. +// from WinBase.h +// Windows::UI::Xaml::Media::Animation::IStoryboard::GetCurrentTime +#ifdef GetCurrentTime +#undef GetCurrentTime +#endif + +#include + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "winrt/Windows.UI.Xaml.Markup.h" +#include "winrt/Windows.UI.Xaml.Documents.h" +#include "winrt/Windows.UI.Xaml.Automation.h" +#include +#include + +#include +#include +#include +#include + +#include + +#include + +// Including TraceLogging essentials for the binary +#include +#include +TRACELOGGING_DECLARE_PROVIDER(g_hTerminalAppProvider); +#include +#include + +// JsonCpp +#include + +#include + +#include +#include + +#include + +// Manually include til after we include Windows.Foundation to give it winrt superpowers +#include "til.h" diff --git a/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj b/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj index b940f569e23..395c76d9e8e 100644 --- a/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj +++ b/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj @@ -75,7 +75,7 @@ - + diff --git a/src/cascadia/WindowsTerminalUniversal/WindowsTerminalUniversal.vcxproj b/src/cascadia/WindowsTerminalUniversal/WindowsTerminalUniversal.vcxproj index f001359816c..0a749357a56 100644 --- a/src/cascadia/WindowsTerminalUniversal/WindowsTerminalUniversal.vcxproj +++ b/src/cascadia/WindowsTerminalUniversal/WindowsTerminalUniversal.vcxproj @@ -145,7 +145,7 @@ - + {ca5cad1a-44bd-4ac7-ac72-f16e576fdd12} diff --git a/src/cascadia/WindowsTerminalUniversal/main.cpp b/src/cascadia/WindowsTerminalUniversal/main.cpp index 7808afeab24..73e8d87f5aa 100644 --- a/src/cascadia/WindowsTerminalUniversal/main.cpp +++ b/src/cascadia/WindowsTerminalUniversal/main.cpp @@ -1,6 +1,6 @@ #include "pch.h" -#include "Generated Files\winrt\TerminalApp.h" +#include "winrt\TerminalApp.h" int __stdcall wWinMain(HINSTANCE, HINSTANCE, PWSTR, int) { diff --git a/src/cascadia/ut_app/TerminalApp.UnitTests.vcxproj b/src/cascadia/ut_app/TerminalApp.UnitTests.vcxproj index 280cd1c3bed..868002a5fd2 100644 --- a/src/cascadia/ut_app/TerminalApp.UnitTests.vcxproj +++ b/src/cascadia/ut_app/TerminalApp.UnitTests.vcxproj @@ -27,6 +27,14 @@ + + + + true + + + @@ -53,7 +61,7 @@ - + @@ -62,7 +70,7 @@ - ..;$(OpenConsoleDir)\dep\jsoncpp\json;$(OpenConsoleDir)src\inc;$(OpenConsoleDir)src\inc\test;$(WinRT_IncludePath)\..\cppwinrt\winrt;"$(OpenConsoleDir)\src\cascadia\TerminalApp\lib\Generated Files";%(AdditionalIncludeDirectories) + ..;$(OpenConsoleDir)\dep\jsoncpp\json;$(OpenConsoleDir)src\inc;$(OpenConsoleDir)src\inc\test;$(WinRT_IncludePath)\..\cppwinrt\winrt;"$(OpenConsoleDir)\src\cascadia\TerminalApp\Generated Files";%(AdditionalIncludeDirectories) precomp.h @@ -124,6 +132,6 @@ - + From 64e3c848c02ec426de6db86767f30e563d46cbfa Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Fri, 21 Aug 2020 09:54:43 -0500 Subject: [PATCH 073/266] Add a pair of nested, iterable default commands (#7348) ## Summary of the Pull Request ![cmdpal-default-nested-commands](https://user-images.githubusercontent.com/18356694/90684483-e6b13400-e22d-11ea-8ca6-fe90ca8d9e82.gif) Adds a pair of top-level commands that both have nested, iterable sub-commands. The "New Tab..." command has one child for each profile, and will open a new tab for that profile. The "Split Pane..." command similarly has a nested command for each profile, and also has a nested command for split auto/horizontal/vertical. ## References * megathread: #5400 * Would look better with icons from #6644 ## PR Checklist * [x] Closes #7174 * [x] I work here * [ ] Tests added/passed * [n/a] Requires documentation to be updated --- .../Resources/en-US/Resources.resw | 6 ++++ src/cascadia/TerminalApp/defaults.json | 36 +++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw index a7384c7ac4a..36c10376fa6 100644 --- a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw +++ b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw @@ -576,6 +576,12 @@ Select color scheme... + + New Tab... + + + Split Pane... + Tab Switcher diff --git a/src/cascadia/TerminalApp/defaults.json b/src/cascadia/TerminalApp/defaults.json index bab95d13a85..ed96f086d23 100644 --- a/src/cascadia/TerminalApp/defaults.json +++ b/src/cascadia/TerminalApp/defaults.json @@ -343,7 +343,9 @@ { "command": { "action": "adjustFontSize", "delta": -1 }, "keys": "ctrl+-" }, { "command": "resetFontSize", "keys": "ctrl+0" }, + // Other commands { + // Select color scheme... "name": { "key": "SetColorSchemeParentCommandName" }, "commands": [ { @@ -353,5 +355,39 @@ } ] }, + { + // New tab... + "name": { "key": "NewTabParentCommandName" }, + "commands": [ + { + "iterateOn": "profiles", + "icon": "${profile.icon}", + "name": "${profile.name}", + "command": { "action": "newTab", "profile": "${profile.name}" } + } + ] + }, + { + // Split pane... + "name": { "key": "SplitPaneParentCommandName" }, + "commands": [ + { + "iterateOn": "profiles", + "icon": "${profile.icon}", + "name": "${profile.name}...", + "commands": [ + { + "command": { "action": "splitPane", "profile": "${profile.name}", "split": "auto" } + }, + { + "command": { "action": "splitPane", "profile": "${profile.name}", "split": "vertical" } + }, + { + "command": { "action": "splitPane", "profile": "${profile.name}", "split": "horizontal" } + } + ] + } + ] + } ] } From 3d370dc65207acbfad22f7c105d911e9948c953c Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Fri, 21 Aug 2020 08:39:40 -0700 Subject: [PATCH 074/266] Provide global setting to use ATS for nextTab and prevTab (#7321) ## Summary of the Pull Request This PR splits the anchored and unanchored tab switcher into two. The anchored tab switcher is now baked into `nextTab`/`prevTab`, and the unanchored tab switcher command is just named `tabSearch`. `tabSearch` takes no arguments. To reflect this distinction, `CommandPalette.cpp` now refers to one as `TabSwitchMode` and the other as `TabSearchMode`. I've added a global setting named `useTabSwitcher` (name up for debate) that makes the Terminal use the anchored tab switcher experience for `nextTab` and `prevTab`. I've also given the control the ability to detect Alt KeyUp events and to dispatch keybinding events. By listening for keybindings, the ATS can react to `nextTab`/`prevTab` invocations for navigation in addition to listening for tab and the arrow keys. Closes #7178 ## PR Checklist * [x] CLA signed. * [x] Documentation updates: microsoftdocs/terminal#107 * [x] Schema updated. --- doc/cascadia/profiles.schema.json | 24 +-- src/cascadia/TerminalApp/ActionAndArgs.cpp | 7 +- src/cascadia/TerminalApp/ActionArgs.cpp | 19 --- src/cascadia/TerminalApp/ActionArgs.h | 29 ---- src/cascadia/TerminalApp/ActionArgs.idl | 5 - .../TerminalApp/AppActionHandlers.cpp | 24 +-- src/cascadia/TerminalApp/AppLogic.cpp | 7 + src/cascadia/TerminalApp/CommandPalette.cpp | 143 ++++++++++++------ src/cascadia/TerminalApp/CommandPalette.h | 17 ++- src/cascadia/TerminalApp/CommandPalette.idl | 8 +- .../TerminalApp/GlobalAppSettings.cpp | 3 + src/cascadia/TerminalApp/GlobalAppSettings.h | 1 + .../Resources/en-US/Resources.resw | 6 +- .../TerminalApp/ShortcutActionDispatch.cpp | 4 +- .../TerminalApp/ShortcutActionDispatch.h | 2 +- .../TerminalApp/ShortcutActionDispatch.idl | 4 +- src/cascadia/TerminalApp/TerminalPage.cpp | 19 ++- src/cascadia/TerminalApp/TerminalPage.h | 2 +- src/cascadia/TerminalApp/defaults.json | 1 + 19 files changed, 171 insertions(+), 154 deletions(-) diff --git a/doc/cascadia/profiles.schema.json b/doc/cascadia/profiles.schema.json index 1f28228137a..ebd7ec082ed 100644 --- a/doc/cascadia/profiles.schema.json +++ b/doc/cascadia/profiles.schema.json @@ -63,7 +63,7 @@ "setTabColor", "splitPane", "switchToTab", - "tabSwitcher", + "tabSearch", "toggleAlwaysOnTop", "toggleFocusMode", "toggleFullscreen", @@ -423,22 +423,6 @@ ], "required": [ "index" ] }, - "TabSwitcherAction": { - "description": "Arguments corresponding to a Tab Switcher Action", - "allOf": [ - { "$ref": "#/definitions/ShortcutAction" }, - { - "properties": { - "action": { "type": "string", "pattern": "tabSwitcher" }, - "anchorKey": { - "$ref": "#/definitions/AnchorKey", - "default": null, - "description": "If provided, the tab switcher will stay open as long as the anchor key is held down. The anchor key should be part of the keybinding that opens the switcher." - } - } - } - ] - }, "Keybinding": { "additionalProperties": false, "properties": { @@ -460,7 +444,6 @@ { "$ref": "#/definitions/WtAction" }, { "$ref": "#/definitions/CloseOtherTabsAction" }, { "$ref": "#/definitions/CloseTabsAfterAction" }, - { "$ref": "#/definitions/TabSwitcherAction" }, { "type": "null" } ] }, @@ -631,6 +614,11 @@ "default": true, "description": "When set to \"true\" closing a window with multiple tabs open will require confirmation. When set to \"false\", the confirmation dialog will not appear.", "type": "boolean" + }, + "useTabSwitcher": { + "default": true, + "description": "When set to \"true\", the \"nextTab\" and \"prevTab\" commands will use the tab switcher UI.", + "type": "boolean" } }, "required": [ diff --git a/src/cascadia/TerminalApp/ActionAndArgs.cpp b/src/cascadia/TerminalApp/ActionAndArgs.cpp index cda8332904c..76943897177 100644 --- a/src/cascadia/TerminalApp/ActionAndArgs.cpp +++ b/src/cascadia/TerminalApp/ActionAndArgs.cpp @@ -37,9 +37,8 @@ static constexpr std::string_view SendInputKey{ "sendInput" }; static constexpr std::string_view SetColorSchemeKey{ "setColorScheme" }; static constexpr std::string_view SetTabColorKey{ "setTabColor" }; static constexpr std::string_view SplitPaneKey{ "splitPane" }; -static constexpr std::string_view SwitchtoTabKey{ "switchToTab" }; static constexpr std::string_view SwitchToTabKey{ "switchToTab" }; -static constexpr std::string_view TabSwitcherKey{ "tabSwitcher" }; +static constexpr std::string_view TabSearchKey{ "tabSearch" }; static constexpr std::string_view ToggleAlwaysOnTopKey{ "toggleAlwaysOnTop" }; static constexpr std::string_view ToggleCommandPaletteKey{ "commandPalette" }; static constexpr std::string_view ToggleFocusModeKey{ "toggleFocusMode" }; @@ -96,7 +95,7 @@ namespace winrt::TerminalApp::implementation { SetTabColorKey, ShortcutAction::SetTabColor }, { SplitPaneKey, ShortcutAction::SplitPane }, { SwitchToTabKey, ShortcutAction::SwitchToTab }, - { TabSwitcherKey, ShortcutAction::ToggleTabSwitcher }, + { TabSearchKey, ShortcutAction::TabSearch }, { ToggleAlwaysOnTopKey, ShortcutAction::ToggleAlwaysOnTop }, { ToggleCommandPaletteKey, ShortcutAction::ToggleCommandPalette }, { ToggleFocusModeKey, ShortcutAction::ToggleFocusMode }, @@ -130,7 +129,6 @@ namespace winrt::TerminalApp::implementation { ShortcutAction::SetTabColor, SetTabColorArgs::FromJson }, { ShortcutAction::SplitPane, SplitPaneArgs::FromJson }, { ShortcutAction::SwitchToTab, SwitchToTabArgs::FromJson }, - { ShortcutAction::ToggleTabSwitcher, ToggleTabSwitcherArgs::FromJson }, { ShortcutAction::Invalid, nullptr }, }; @@ -280,6 +278,7 @@ namespace winrt::TerminalApp::implementation { ShortcutAction::SetTabColor, RS_(L"ResetTabColorCommandKey") }, { ShortcutAction::SplitPane, RS_(L"SplitPaneCommandKey") }, { ShortcutAction::SwitchToTab, RS_(L"SwitchToTabCommandKey") }, + { ShortcutAction::TabSearch, RS_(L"TabSearchCommandKey") }, { ShortcutAction::ToggleAlwaysOnTop, RS_(L"ToggleAlwaysOnTopCommandKey") }, { ShortcutAction::ToggleCommandPalette, RS_(L"ToggleCommandPaletteCommandKey") }, { ShortcutAction::ToggleFocusMode, RS_(L"ToggleFocusModeCommandKey") }, diff --git a/src/cascadia/TerminalApp/ActionArgs.cpp b/src/cascadia/TerminalApp/ActionArgs.cpp index d1af86df394..046068929b2 100644 --- a/src/cascadia/TerminalApp/ActionArgs.cpp +++ b/src/cascadia/TerminalApp/ActionArgs.cpp @@ -20,7 +20,6 @@ #include "SetTabColorArgs.g.cpp" #include "RenameTabArgs.g.cpp" #include "ExecuteCommandlineArgs.g.cpp" -#include "ToggleTabSwitcherArgs.g.h" #include "Utils.h" @@ -355,22 +354,4 @@ namespace winrt::TerminalApp::implementation _Index) }; } - - winrt::hstring ToggleTabSwitcherArgs::GenerateName() const - { - // If there's an anchor key set, don't generate a name so that - // it won't show up in the command palette. Only an unanchored - // tab switcher should be able to be toggled from the palette. - // TODO: GH#7179 - once this goes in, make sure to hide the - // anchor mode command that was given a name in settings. - if (_AnchorKey != Windows::System::VirtualKey::None) - { - return L""; - } - else - { - return RS_(L"ToggleTabSwitcherCommandKey"); - } - } - } diff --git a/src/cascadia/TerminalApp/ActionArgs.h b/src/cascadia/TerminalApp/ActionArgs.h index 7e140b17d18..c90430a84c6 100644 --- a/src/cascadia/TerminalApp/ActionArgs.h +++ b/src/cascadia/TerminalApp/ActionArgs.h @@ -22,7 +22,6 @@ #include "ExecuteCommandlineArgs.g.h" #include "CloseOtherTabsArgs.g.h" #include "CloseTabsAfterArgs.g.h" -#include "ToggleTabSwitcherArgs.g.h" #include "../../cascadia/inc/cppwinrt_utils.h" #include "Utils.h" @@ -548,34 +547,6 @@ namespace winrt::TerminalApp::implementation return { *args, {} }; } }; - - struct ToggleTabSwitcherArgs : public ToggleTabSwitcherArgsT - { - ToggleTabSwitcherArgs() = default; - GETSET_PROPERTY(Windows::System::VirtualKey, AnchorKey, Windows::System::VirtualKey::None); - - static constexpr std::string_view AnchorJsonKey{ "anchorKey" }; - - public: - hstring GenerateName() const; - - bool Equals(const IActionArgs& other) - { - auto otherAsUs = other.try_as(); - if (otherAsUs) - { - return otherAsUs->_AnchorKey == _AnchorKey; - } - return false; - }; - static FromJsonResult FromJson(const Json::Value& json) - { - // LOAD BEARING: Not using make_self here _will_ break you in the future! - auto args = winrt::make_self(); - JsonUtils::GetValueForKey(json, AnchorJsonKey, args->_AnchorKey); - return { *args, {} }; - } - }; } namespace winrt::TerminalApp::factory_implementation diff --git a/src/cascadia/TerminalApp/ActionArgs.idl b/src/cascadia/TerminalApp/ActionArgs.idl index 15d211e6f63..96b3b04386e 100644 --- a/src/cascadia/TerminalApp/ActionArgs.idl +++ b/src/cascadia/TerminalApp/ActionArgs.idl @@ -141,9 +141,4 @@ namespace TerminalApp { UInt32 Index { get; }; }; - - [default_interface] runtimeclass ToggleTabSwitcherArgs : IActionArgs - { - Windows.System.VirtualKey AnchorKey { get; }; - }; } diff --git a/src/cascadia/TerminalApp/AppActionHandlers.cpp b/src/cascadia/TerminalApp/AppActionHandlers.cpp index 9e9378bb411..8b4f4c6b0e1 100644 --- a/src/cascadia/TerminalApp/AppActionHandlers.cpp +++ b/src/cascadia/TerminalApp/AppActionHandlers.cpp @@ -456,27 +456,15 @@ namespace winrt::TerminalApp::implementation } } - void TerminalPage::_HandleToggleTabSwitcher(const IInspectable& /*sender*/, - const TerminalApp::ActionEventArgs& args) + void TerminalPage::_HandleOpenTabSearch(const IInspectable& /*sender*/, + const TerminalApp::ActionEventArgs& args) { - if (const auto& realArgs = args.ActionArgs().try_as()) - { - auto anchorKey = realArgs.AnchorKey(); + auto opt = _GetFocusedTabIndex(); + uint32_t startIdx = opt.value_or(0); - auto opt = _GetFocusedTabIndex(); - uint32_t startIdx = opt ? *opt : 0; + CommandPalette().EnableTabSwitcherMode(true, startIdx); + CommandPalette().Visibility(Visibility::Visible); - if (anchorKey != VirtualKey::None) - { - // TODO: GH#7178 - delta should also have the option of being -1, in the case when - // a user decides to open the tab switcher going to the prev tab. - int delta = 1; - startIdx = (startIdx + _tabs.Size() + delta) % _tabs.Size(); - } - - CommandPalette().EnableTabSwitcherMode(anchorKey, startIdx); - CommandPalette().Visibility(Visibility::Visible); - } args.Handled(true); } } diff --git a/src/cascadia/TerminalApp/AppLogic.cpp b/src/cascadia/TerminalApp/AppLogic.cpp index 148898cd94f..d7adb4f2456 100644 --- a/src/cascadia/TerminalApp/AppLogic.cpp +++ b/src/cascadia/TerminalApp/AppLogic.cpp @@ -938,6 +938,13 @@ namespace winrt::TerminalApp::implementation if (auto focusedElement{ focusedObject.try_as() }) { focusedObject = focusedElement.Parent(); + + // Parent() seems to return null when the focusedElement is created from an ItemTemplate. + // Use the VisualTreeHelper's GetParent as a fallback. + if (!focusedObject) + { + focusedObject = winrt::Windows::UI::Xaml::Media::VisualTreeHelper::GetParent(focusedElement); + } } else { diff --git a/src/cascadia/TerminalApp/CommandPalette.cpp b/src/cascadia/TerminalApp/CommandPalette.cpp index e1c96bc00d0..a8d0cb12d88 100644 --- a/src/cascadia/TerminalApp/CommandPalette.cpp +++ b/src/cascadia/TerminalApp/CommandPalette.cpp @@ -22,7 +22,6 @@ using namespace winrt::Windows::Foundation::Collections; namespace winrt::TerminalApp::implementation { CommandPalette::CommandPalette() : - _anchorKey{ VirtualKey::None }, _switcherStartIdx{ 0 } { InitializeComponent(); @@ -51,20 +50,16 @@ namespace winrt::TerminalApp::implementation RegisterPropertyChangedCallback(UIElement::VisibilityProperty(), [this](auto&&, auto&&) { if (Visibility() == Visibility::Visible) { - if (_currentMode == CommandPaletteMode::TabSwitcherMode) + if (_currentMode == CommandPaletteMode::TabSwitchMode) { - if (_anchorKey != VirtualKey::None) - { - _searchBox().Visibility(Visibility::Collapsed); - _filteredActionsView().Focus(FocusState::Keyboard); - } - else - { - _searchBox().Focus(FocusState::Programmatic); - } - + _searchBox().Visibility(Visibility::Collapsed); + _filteredActionsView().Focus(FocusState::Keyboard); _filteredActionsView().SelectedIndex(_switcherStartIdx); _filteredActionsView().ScrollIntoView(_filteredActionsView().SelectedItem()); + + // Do this right after becoming visible so we can quickly catch scenarios where + // modifiers aren't held down (e.g. command palette invocation). + _anchorKeyUpHandler(); } else { @@ -94,7 +89,7 @@ namespace winrt::TerminalApp::implementation // when the ListView has been measured out and is ready, and we'll immediately // revoke the handler because we only needed to handle it once on initialization. _sizeChangedRevoker = _filteredActionsView().SizeChanged(winrt::auto_revoke, [this](auto /*s*/, auto /*e*/) { - if (_currentMode == CommandPaletteMode::TabSwitcherMode && _anchorKey != VirtualKey::None) + if (_currentMode == CommandPaletteMode::TabSwitchMode) { _filteredActionsView().Focus(FocusState::Keyboard); } @@ -110,7 +105,7 @@ namespace winrt::TerminalApp::implementation // list. Otherwise, we're attempting to move to the previous. // Return Value: // - - void CommandPalette::_selectNextItem(const bool moveDown) + void CommandPalette::SelectNextItem(const bool moveDown) { const auto selected = _filteredActionsView().SelectedIndex(); const int numItems = ::base::saturated_cast(_filteredActionsView().Items().Size()); @@ -134,19 +129,17 @@ namespace winrt::TerminalApp::implementation // Only give anchored tab switcher the ability to cycle through tabs with the tab button. // For unanchored mode, accessibility becomes an issue when we try to hijack tab since it's // a really widely used keyboard navigation key. - if (_currentMode == CommandPaletteMode::TabSwitcherMode && - key == VirtualKey::Tab && - _anchorKey != VirtualKey::None) + if (_currentMode == CommandPaletteMode::TabSwitchMode && key == VirtualKey::Tab) { auto const state = CoreWindow::GetForCurrentThread().GetKeyState(winrt::Windows::System::VirtualKey::Shift); if (WI_IsFlagSet(state, CoreVirtualKeyStates::Down)) { - _selectNextItem(false); + SelectNextItem(false); e.Handled(true); } else { - _selectNextItem(true); + SelectNextItem(true); e.Handled(true); } } @@ -168,13 +161,13 @@ namespace winrt::TerminalApp::implementation if (key == VirtualKey::Up) { // Action Mode: Move focus to the next item in the list. - _selectNextItem(false); + SelectNextItem(false); e.Handled(true); } else if (key == VirtualKey::Down) { // Action Mode: Move focus to the previous item in the list. - _selectNextItem(true); + SelectNextItem(true); e.Handled(true); } else if (key == VirtualKey::Enter) @@ -202,32 +195,81 @@ namespace winrt::TerminalApp::implementation e.Handled(true); } + else + { + const auto vkey = ::gsl::narrow_cast(e.OriginalKey()); + + // In the interest of not telling all modes to check for keybindings, limit to TabSwitch mode for now. + if (_currentMode == CommandPaletteMode::TabSwitchMode) + { + auto const ctrlDown = WI_IsFlagSet(CoreWindow::GetForCurrentThread().GetKeyState(winrt::Windows::System::VirtualKey::Control), CoreVirtualKeyStates::Down); + auto const altDown = WI_IsFlagSet(CoreWindow::GetForCurrentThread().GetKeyState(winrt::Windows::System::VirtualKey::Menu), CoreVirtualKeyStates::Down); + auto const shiftDown = WI_IsFlagSet(CoreWindow::GetForCurrentThread().GetKeyState(winrt::Windows::System::VirtualKey::Shift), CoreVirtualKeyStates::Down); + + auto success = _bindings.TryKeyChord({ + ctrlDown, + altDown, + shiftDown, + vkey, + }); + + if (success) + { + e.Handled(true); + } + } + } + } + + // Method Description: + // - Implements the Alt handler + // Return value: + // - whether the key was handled + bool CommandPalette::OnDirectKeyEvent(const uint32_t vkey, const uint8_t /*scanCode*/, const bool down) + { + auto handled = false; + if (_currentMode == CommandPaletteMode::TabSwitchMode) + { + if (vkey == VK_MENU && !down) + { + _anchorKeyUpHandler(); + handled = true; + } + } + return handled; } void CommandPalette::_keyUpHandler(IInspectable const& /*sender*/, Windows::UI::Xaml::Input::KeyRoutedEventArgs const& e) { - auto key = e.OriginalKey(); + if (_currentMode == CommandPaletteMode::TabSwitchMode) + { + _anchorKeyUpHandler(); + e.Handled(true); + } + } + + // Method Description: + // - Handles anchor key ups during TabSwitchMode. + // We assume that at least one modifier key should be held down in order to "anchor" + // the ATS UI in place. So this function is called to check if any modifiers are + // still held down, and if not, dispatch the selected tab action and close the ATS. + // Return value: + // - + void CommandPalette::_anchorKeyUpHandler() + { + auto const ctrlDown = WI_IsFlagSet(CoreWindow::GetForCurrentThread().GetKeyState(winrt::Windows::System::VirtualKey::Control), CoreVirtualKeyStates::Down); + auto const altDown = WI_IsFlagSet(CoreWindow::GetForCurrentThread().GetKeyState(winrt::Windows::System::VirtualKey::Menu), CoreVirtualKeyStates::Down); + auto const shiftDown = WI_IsFlagSet(CoreWindow::GetForCurrentThread().GetKeyState(winrt::Windows::System::VirtualKey::Shift), CoreVirtualKeyStates::Down); - if (_currentMode == CommandPaletteMode::TabSwitcherMode) + if (!ctrlDown && !altDown && !shiftDown) { - if (_anchorKey && key == _anchorKey.value()) + if (const auto selectedItem = _filteredActionsView().SelectedItem()) { - // Once the user lifts the anchor key, we'll switch to the currently selected tab - // then close the tab switcher. - - if (const auto selectedItem = _filteredActionsView().SelectedItem()) + if (const auto data = selectedItem.try_as()) { - if (const auto data = selectedItem.try_as()) - { - const auto actionAndArgs = data.Action(); - _dispatch.DoAction(actionAndArgs); - _updateFilteredActions(); - _dismissPalette(); - } + _dispatchCommand(data); } - - e.Handled(true); } } } @@ -317,7 +359,8 @@ namespace winrt::TerminalApp::implementation } return _allCommands; - case CommandPaletteMode::TabSwitcherMode: + case CommandPaletteMode::TabSearchMode: + case CommandPaletteMode::TabSwitchMode: return _allTabActions; default: return _allCommands; @@ -420,6 +463,11 @@ namespace winrt::TerminalApp::implementation return _filteredActions; } + void CommandPalette::SetKeyBindings(Microsoft::Terminal::TerminalControl::IKeyBindings bindings) + { + _bindings = bindings; + } + void CommandPalette::SetCommands(Collections::IVector const& actions) { _allCommands = actions; @@ -455,7 +503,8 @@ namespace winrt::TerminalApp::implementation // whenever _switchToMode is called. switch (_currentMode) { - case CommandPaletteMode::TabSwitcherMode: + case CommandPaletteMode::TabSearchMode: + case CommandPaletteMode::TabSwitchMode: { SearchBoxText(RS_(L"TabSwitcher_SearchBoxText")); NoMatchesText(RS_(L"TabSwitcher_NoMatchesText")); @@ -530,7 +579,7 @@ namespace winrt::TerminalApp::implementation { // If TabSwitcherMode, just add all as is. We don't want // them to be sorted alphabetically. - if (_currentMode == CommandPaletteMode::TabSwitcherMode) + if (_currentMode == CommandPaletteMode::TabSearchMode || _currentMode == CommandPaletteMode::TabSwitchMode) { for (auto action : commandsToFilter) { @@ -899,11 +948,19 @@ namespace winrt::TerminalApp::implementation } } - void CommandPalette::EnableTabSwitcherMode(const VirtualKey& anchorKey, const uint32_t startIdx) + void CommandPalette::EnableTabSwitcherMode(const bool searchMode, const uint32_t startIdx) { _switcherStartIdx = startIdx; - _anchorKey = anchorKey; - _switchToMode(CommandPaletteMode::TabSwitcherMode); + + if (searchMode) + { + _switchToMode(CommandPaletteMode::TabSearchMode); + } + else + { + _switchToMode(CommandPaletteMode::TabSwitchMode); + } + _updateFilteredActions(); } } diff --git a/src/cascadia/TerminalApp/CommandPalette.h b/src/cascadia/TerminalApp/CommandPalette.h index 97a18ac28cb..97b0f0c8d25 100644 --- a/src/cascadia/TerminalApp/CommandPalette.h +++ b/src/cascadia/TerminalApp/CommandPalette.h @@ -11,7 +11,8 @@ namespace winrt::TerminalApp::implementation enum class CommandPaletteMode { ActionMode = 0, - TabSwitcherMode + TabSearchMode, + TabSwitchMode }; struct CommandPalette : CommandPaletteT @@ -21,12 +22,18 @@ namespace winrt::TerminalApp::implementation Windows::Foundation::Collections::IObservableVector FilteredActions(); void SetCommands(Windows::Foundation::Collections::IVector const& actions); + void SetKeyBindings(Microsoft::Terminal::TerminalControl::IKeyBindings bindings); + void EnableCommandPaletteMode(); void SetDispatch(const winrt::TerminalApp::ShortcutActionDispatch& dispatch); + bool OnDirectKeyEvent(const uint32_t vkey, const uint8_t scanCode, const bool down); + + void SelectNextItem(const bool moveDown); + // Tab Switcher - void EnableTabSwitcherMode(const Windows::System::VirtualKey& anchorKey, const uint32_t startIdx); + void EnableTabSwitcherMode(const bool searchMode, const uint32_t startIdx); void OnTabsChanged(const Windows::Foundation::IInspectable& s, const Windows::Foundation::Collections::IVectorChangedEventArgs& e); WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler); @@ -63,8 +70,6 @@ namespace winrt::TerminalApp::implementation void _listItemClicked(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::Controls::ItemClickEventArgs const& e); - void _selectNextItem(const bool moveDown); - void _updateFilteredActions(); std::vector _collectFilteredActions(); @@ -75,12 +80,14 @@ namespace winrt::TerminalApp::implementation CommandPaletteMode _currentMode; void _switchToMode(CommandPaletteMode mode); + Microsoft::Terminal::TerminalControl::IKeyBindings _bindings; + // Tab Switcher - std::optional _anchorKey; void GenerateCommandForTab(const uint32_t idx, bool inserted, winrt::TerminalApp::Tab& tab); void UpdateTabIndices(const uint32_t startIdx); Windows::Foundation::Collections::IVector _allTabActions{ nullptr }; uint32_t _switcherStartIdx; + void _anchorKeyUpHandler(); winrt::Windows::UI::Xaml::Controls::ListView::SizeChanged_revoker _sizeChangedRevoker; diff --git a/src/cascadia/TerminalApp/CommandPalette.idl b/src/cascadia/TerminalApp/CommandPalette.idl index 793ac8334e4..10cfe967fa9 100644 --- a/src/cascadia/TerminalApp/CommandPalette.idl +++ b/src/cascadia/TerminalApp/CommandPalette.idl @@ -2,10 +2,11 @@ // Licensed under the MIT license. import "Command.idl"; +import "IDirectKeyListener.idl"; namespace TerminalApp { - [default_interface] runtimeclass CommandPalette : Windows.UI.Xaml.Controls.UserControl, Windows.UI.Xaml.Data.INotifyPropertyChanged + [default_interface] runtimeclass CommandPalette : Windows.UI.Xaml.Controls.UserControl, Windows.UI.Xaml.Data.INotifyPropertyChanged, IDirectKeyListener { CommandPalette(); @@ -17,11 +18,14 @@ namespace TerminalApp Windows.Foundation.Collections.IObservableVector FilteredActions { get; }; void SetCommands(Windows.Foundation.Collections.IVector actions); + void SetKeyBindings(Microsoft.Terminal.TerminalControl.IKeyBindings bindings); void EnableCommandPaletteMode(); + void SelectNextItem(Boolean moveDown); + void SetDispatch(ShortcutActionDispatch dispatch); - void EnableTabSwitcherMode(Windows.System.VirtualKey anchorKey, UInt32 startIdx); + void EnableTabSwitcherMode(Boolean searchMode, UInt32 startIdx); void OnTabsChanged(IInspectable s, Windows.Foundation.Collections.IVectorChangedEventArgs e); } } diff --git a/src/cascadia/TerminalApp/GlobalAppSettings.cpp b/src/cascadia/TerminalApp/GlobalAppSettings.cpp index 449502509cd..4cbba508b1f 100644 --- a/src/cascadia/TerminalApp/GlobalAppSettings.cpp +++ b/src/cascadia/TerminalApp/GlobalAppSettings.cpp @@ -36,6 +36,7 @@ static constexpr std::string_view ConfirmCloseAllKey{ "confirmCloseAllTabs" }; static constexpr std::string_view SnapToGridOnResizeKey{ "snapToGridOnResize" }; static constexpr std::string_view EnableStartupTaskKey{ "startOnUserLogin" }; static constexpr std::string_view AlwaysOnTopKey{ "alwaysOnTop" }; +static constexpr std::string_view UseTabSwitcherKey{ "useTabSwitcher" }; static constexpr std::string_view DebugFeaturesKey{ "debugFeatures" }; @@ -180,6 +181,8 @@ void GlobalAppSettings::LayerJson(const Json::Value& json) JsonUtils::GetValueForKey(json, AlwaysOnTopKey, _AlwaysOnTop); + JsonUtils::GetValueForKey(json, UseTabSwitcherKey, _UseTabSwitcher); + // This is a helper lambda to get the keybindings and commands out of both // and array of objects. We'll use this twice, once on the legacy // `keybindings` key, and again on the newer `bindings` key. diff --git a/src/cascadia/TerminalApp/GlobalAppSettings.h b/src/cascadia/TerminalApp/GlobalAppSettings.h index bc00276f8d4..d78d15a8e34 100644 --- a/src/cascadia/TerminalApp/GlobalAppSettings.h +++ b/src/cascadia/TerminalApp/GlobalAppSettings.h @@ -82,6 +82,7 @@ class TerminalApp::GlobalAppSettings final GETSET_PROPERTY(bool, DebugFeaturesEnabled); // default value set in constructor GETSET_PROPERTY(bool, StartOnUserLogin, false); GETSET_PROPERTY(bool, AlwaysOnTop, false); + GETSET_PROPERTY(bool, UseTabSwitcher, true); private: std::optional _unparsedDefaultProfile; diff --git a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw index 36c10376fa6..f7d58b6d826 100644 --- a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw +++ b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw @@ -576,6 +576,9 @@ Select color scheme... + + Search for tab... + New Tab... @@ -585,9 +588,6 @@ Tab Switcher - - Toggle tab switcher - Type a tab name... diff --git a/src/cascadia/TerminalApp/ShortcutActionDispatch.cpp b/src/cascadia/TerminalApp/ShortcutActionDispatch.cpp index 20a43791c2d..cce86db1988 100644 --- a/src/cascadia/TerminalApp/ShortcutActionDispatch.cpp +++ b/src/cascadia/TerminalApp/ShortcutActionDispatch.cpp @@ -226,9 +226,9 @@ namespace winrt::TerminalApp::implementation _CloseTabsAfterHandlers(*this, *eventArgs); break; } - case ShortcutAction::ToggleTabSwitcher: + case ShortcutAction::TabSearch: { - _ToggleTabSwitcherHandlers(*this, *eventArgs); + _TabSearchHandlers(*this, *eventArgs); break; } default: diff --git a/src/cascadia/TerminalApp/ShortcutActionDispatch.h b/src/cascadia/TerminalApp/ShortcutActionDispatch.h index 9da3aadcdf2..caecb41ef77 100644 --- a/src/cascadia/TerminalApp/ShortcutActionDispatch.h +++ b/src/cascadia/TerminalApp/ShortcutActionDispatch.h @@ -60,7 +60,7 @@ namespace winrt::TerminalApp::implementation TYPED_EVENT(ExecuteCommandline, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs); TYPED_EVENT(CloseOtherTabs, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs); TYPED_EVENT(CloseTabsAfter, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs); - TYPED_EVENT(ToggleTabSwitcher, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs); + TYPED_EVENT(TabSearch, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs); // clang-format on private: diff --git a/src/cascadia/TerminalApp/ShortcutActionDispatch.idl b/src/cascadia/TerminalApp/ShortcutActionDispatch.idl index f34256f3a6b..48d9eb923ce 100644 --- a/src/cascadia/TerminalApp/ShortcutActionDispatch.idl +++ b/src/cascadia/TerminalApp/ShortcutActionDispatch.idl @@ -46,7 +46,7 @@ namespace TerminalApp ToggleCommandPalette, CloseOtherTabs, CloseTabsAfter, - ToggleTabSwitcher + TabSearch }; [default_interface] runtimeclass ActionAndArgs { @@ -97,6 +97,6 @@ namespace TerminalApp event Windows.Foundation.TypedEventHandler ExecuteCommandline; event Windows.Foundation.TypedEventHandler CloseOtherTabs; event Windows.Foundation.TypedEventHandler CloseTabsAfter; - event Windows.Foundation.TypedEventHandler ToggleTabSwitcher; + event Windows.Foundation.TypedEventHandler TabSearch; } } diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index 6de63a6be7b..02d95dee2b5 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -119,6 +119,7 @@ namespace winrt::TerminalApp::implementation if (auto page{ weakThis.get() }) { _UpdateCommandsForPalette(); + CommandPalette().SetKeyBindings(_settings->GetKeybindings()); } } @@ -938,7 +939,7 @@ namespace winrt::TerminalApp::implementation _actionDispatch->ExecuteCommandline({ this, &TerminalPage::_HandleExecuteCommandline }); _actionDispatch->CloseOtherTabs({ this, &TerminalPage::_HandleCloseOtherTabs }); _actionDispatch->CloseTabsAfter({ this, &TerminalPage::_HandleCloseTabsAfter }); - _actionDispatch->ToggleTabSwitcher({ this, &TerminalPage::_HandleToggleTabSwitcher }); + _actionDispatch->TabSearch({ this, &TerminalPage::_HandleOpenTabSearch }); } // Method Description: @@ -1199,7 +1200,21 @@ namespace winrt::TerminalApp::implementation // we clamp the values to the range [0, tabCount) while still supporting moving // leftward from 0 to tabCount - 1. const auto newTabIndex = ((tabCount + *index + (bMoveRight ? 1 : -1)) % tabCount); - _SelectTab(newTabIndex); + + if (_settings->GlobalSettings().UseTabSwitcher()) + { + if (CommandPalette().Visibility() == Visibility::Visible) + { + CommandPalette().SelectNextItem(bMoveRight); + } + + CommandPalette().EnableTabSwitcherMode(false, newTabIndex); + CommandPalette().Visibility(Visibility::Visible); + } + else + { + _SelectTab(newTabIndex); + } } } diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h index 17724e198a0..02d0af0b53d 100644 --- a/src/cascadia/TerminalApp/TerminalPage.h +++ b/src/cascadia/TerminalApp/TerminalPage.h @@ -237,7 +237,7 @@ namespace winrt::TerminalApp::implementation void _HandleToggleCommandPalette(const IInspectable& sender, const TerminalApp::ActionEventArgs& args); void _HandleCloseOtherTabs(const IInspectable& sender, const TerminalApp::ActionEventArgs& args); void _HandleCloseTabsAfter(const IInspectable& sender, const TerminalApp::ActionEventArgs& args); - void _HandleToggleTabSwitcher(const IInspectable& sender, const TerminalApp::ActionEventArgs& args); + void _HandleOpenTabSearch(const IInspectable& sender, const TerminalApp::ActionEventArgs& args); // Make sure to hook new actions up in _RegisterActionCallbacks! #pragma endregion diff --git a/src/cascadia/TerminalApp/defaults.json b/src/cascadia/TerminalApp/defaults.json index ed96f086d23..818ba8515ca 100644 --- a/src/cascadia/TerminalApp/defaults.json +++ b/src/cascadia/TerminalApp/defaults.json @@ -18,6 +18,7 @@ "showTabsInTitlebar": true, "showTerminalTitleInTitlebar": true, "tabWidthMode": "equal", + "useTabSwitcher": true, // Miscellaneous "confirmCloseAllTabs": true, From 58efe791d1ab025c40d678bf910501368e75555f Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Fri, 21 Aug 2020 13:08:02 -0500 Subject: [PATCH 075/266] Add icons to commands in the Command Palette (#7368) ## Summary of the Pull Request ![cmdpal-icons](https://user-images.githubusercontent.com/18356694/90916410-97dada00-e3a6-11ea-9fb0-755938a68a05.gif) Adds support for setting a command's `icon`. This supports a couple different scenarios: * setting a path to an image * on `"iterateOn": "profiles"` commands, setting the icon to `${profile.icon}` (to use the profile's icon) * setting the icon to a symbol from [Segoe MDL2 Assets](https://docs.microsoft.com/en-us/windows/uwp/design/style/segoe-ui-symbol-font) * setting the icon to an emoji * setting the icon to a character (what is an emoji other than a character, after all?) ## References * Big s/o to @leonMSFT in #6732, who really did all the hard work here. ## PR Checklist * [x] Closes #6644 * [x] I work here * [ ] Tests added/passed * [n/a] Requires documentation to be updated ## Detailed Description of the Pull Request / Additional comments Importantly, the creation of these icons must occur on the UI thread. That's why it's done in a "load the path from json", then "get the actual IconSource" structure. ## Validation Steps Performed see the gif --- src/cascadia/TerminalApp/Command.cpp | 83 +++++++++++++++++++- src/cascadia/TerminalApp/Command.h | 4 + src/cascadia/TerminalApp/Command.idl | 1 + src/cascadia/TerminalApp/CommandPalette.xaml | 34 ++++---- src/cascadia/TerminalApp/TerminalPage.cpp | 18 ++--- 5 files changed, 109 insertions(+), 31 deletions(-) diff --git a/src/cascadia/TerminalApp/Command.cpp b/src/cascadia/TerminalApp/Command.cpp index b8b8540ef33..1eeadc21494 100644 --- a/src/cascadia/TerminalApp/Command.cpp +++ b/src/cascadia/TerminalApp/Command.cpp @@ -15,14 +15,21 @@ using namespace winrt::TerminalApp; using namespace winrt::Windows::Foundation; using namespace ::TerminalApp; +namespace winrt +{ + namespace MUX = Microsoft::UI::Xaml; + namespace WUX = Windows::UI::Xaml; +} + static constexpr std::string_view NameKey{ "name" }; -static constexpr std::string_view IconPathKey{ "iconPath" }; +static constexpr std::string_view IconKey{ "icon" }; static constexpr std::string_view ActionKey{ "command" }; static constexpr std::string_view ArgsKey{ "args" }; static constexpr std::string_view IterateOnKey{ "iterateOn" }; static constexpr std::string_view CommandsKey{ "commands" }; static constexpr std::string_view ProfileNameToken{ "${profile.name}" }; +static constexpr std::string_view ProfileIconToken{ "${profile.icon}" }; static constexpr std::string_view SchemeNameToken{ "${scheme.name}" }; namespace winrt::TerminalApp::implementation @@ -100,6 +107,70 @@ namespace winrt::TerminalApp::implementation return actionAndArgs->GenerateName(); } + // Method Description: + // - Actually initialize our IconSource for our _lastIconPath. Supports a variety of icons: + // * If the icon is a path to an image, we'll use that. + // * If it isn't, then we'll try and use the text as a FontIcon. If the + // character is in the range of symbols reserved for the Segoe MDL2 + // Asserts, well treat it as such. Otherwise, we'll default to a Sego + // UI icon, so things like emoji will work. + // - MUST BE CALLED ON THE UI THREAD. + // Arguments: + // - + // Return Value: + // - + void Command::RefreshIcon() + { + if (!_lastIconPath.empty()) + { + _setIconSource(GetColoredIcon(_lastIconPath)); + + // If we fail to set the icon source using the "icon" as a path, + // let's try it as a symbol/emoji. + // + // Anything longer that 2 wchar_t's _isn't_ an emoji or symbol, so + // don't do this if it's just an invalid path. + if (IconSource() == nullptr && _lastIconPath.size() <= 2) + { + try + { + WUX::Controls::FontIconSource icon; + const wchar_t ch = _lastIconPath[0]; + + // The range of MDL2 Icons isn't explicitly defined, but + // we're using this based off the table on: + // https://docs.microsoft.com/en-us/windows/uwp/design/style/segoe-ui-symbol-font + const bool isMDL2Icon = ch >= L'\uE700' && ch <= L'\uF8FF'; + if (isMDL2Icon) + { + icon.FontFamily(WUX::Media::FontFamily{ L"Segoe MDL2 Assets" }); + } + else + { + // Note: you _do_ need to manually set the font here. + icon.FontFamily(WUX::Media::FontFamily{ L"Segoe UI" }); + } + icon.FontSize(12); + icon.Glyph(_lastIconPath); + _setIconSource(icon); + } + CATCH_LOG(); + } + } + if (IconSource() == nullptr) + { + // Set the default IconSource to a BitmapIconSource with a null source + // (instead of just nullptr) because there's a really weird crash when swapping + // data bound IconSourceElements in a ListViewTemplate (i.e. CommandPalette). + // Swapping between nullptr IconSources and non-null IconSources causes a crash + // to occur, but swapping between IconSources with a null source and non-null IconSources + // work perfectly fine :shrug:. + winrt::Windows::UI::Xaml::Controls::BitmapIconSource icon; + icon.UriSource(nullptr); + _setIconSource(icon); + } + } + // Method Description: // - Deserialize a Command from the `json` object. The json object should // contain a "name" and "action", and optionally an "icon". @@ -143,9 +214,9 @@ namespace winrt::TerminalApp::implementation return nullptr; } - // TODO GH#6644: iconPath not implemented quite yet. Can't seem to get - // the binding quite right. Additionally, do we want it to be an image, - // or a FontIcon? I've had difficulty binding either/or. + // Only get the icon path right now. The icon needs to be resolved into + // an IconSource on the UI thread, which will be done by RefreshIcon. + JsonUtils::GetValueForKey(json, IconKey, result->_lastIconPath); // If we're a nested command, we can ignore the current action. if (!nested) @@ -396,9 +467,13 @@ namespace winrt::TerminalApp::implementation // - Escape the profile name for JSON appropriately auto escapedProfileName = _escapeForJson(til::u16u8(p.GetName())); + auto escapedProfileIcon = _escapeForJson(til::u16u8(p.GetExpandedIconPath())); auto newJsonString = til::replace_needle_in_haystack(oldJsonString, ProfileNameToken, escapedProfileName); + til::replace_needle_in_haystack_inplace(newJsonString, + ProfileIconToken, + escapedProfileIcon); // If we encounter a re-parsing error, just stop processing the rest of the commands. if (!reParseJson(newJsonString)) diff --git a/src/cascadia/TerminalApp/Command.h b/src/cascadia/TerminalApp/Command.h index 1b14ba8031d..e7aa339a41c 100644 --- a/src/cascadia/TerminalApp/Command.h +++ b/src/cascadia/TerminalApp/Command.h @@ -50,6 +50,8 @@ namespace winrt::TerminalApp::implementation bool HasNestedCommands(); Windows::Foundation::Collections::IMapView NestedCommands(); + void RefreshIcon(); + winrt::Windows::UI::Xaml::Data::INotifyPropertyChanged::PropertyChanged_revoker propertyChangedRevoker; WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler); @@ -64,6 +66,8 @@ namespace winrt::TerminalApp::implementation Json::Value _originalJson; Windows::Foundation::Collections::IMap _subcommands{ nullptr }; + winrt::hstring _lastIconPath{}; + static std::vector _expandCommand(Command* const expandable, gsl::span profiles, gsl::span schemes, diff --git a/src/cascadia/TerminalApp/Command.idl b/src/cascadia/TerminalApp/Command.idl index eea4c9bac73..d60287890b5 100644 --- a/src/cascadia/TerminalApp/Command.idl +++ b/src/cascadia/TerminalApp/Command.idl @@ -14,6 +14,7 @@ namespace TerminalApp String KeyChordText; Windows.UI.Xaml.Controls.IconSource IconSource; + void RefreshIcon(); Boolean HasNestedCommands { get; }; Windows.Foundation.Collections.IMapView NestedCommands { get; }; diff --git a/src/cascadia/TerminalApp/CommandPalette.xaml b/src/cascadia/TerminalApp/CommandPalette.xaml index 015ce7677d6..a7ce2822c6f 100644 --- a/src/cascadia/TerminalApp/CommandPalette.xaml +++ b/src/cascadia/TerminalApp/CommandPalette.xaml @@ -208,7 +208,7 @@ the MIT License. See LICENSE in the project root for license information. --> + to make sure it takes the entire width of the line --> @@ -223,30 +223,32 @@ the MIT License. See LICENSE in the project root for license information. --> + Grid.Column="0" + Width="16" + Height="16" + IconSource="{x:Bind IconSource, Mode=OneWay}"/> + when there's actual text set as the label. See + CommandKeyChordVisibilityConverter for details. --> + Grid.Column="2" + Visibility="{x:Bind KeyChordText, + Mode=OneWay, + Converter={StaticResource CommandKeyChordVisibilityConverter}}" + Style="{ThemeResource KeyChordBorderStyle}" + Padding="2,0,2,0" + HorizontalAlignment="Right" + VerticalAlignment="Center"> + Style="{ThemeResource KeyChordTextBlockStyle}" + FontSize="12" + Text="{x:Bind KeyChordText, Mode=OneWay}" /> diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index 02d95dee2b5..24f9504bb66 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -60,7 +60,7 @@ namespace winrt::TerminalApp::implementation // - settings: The settings who's keybindings we should use to look up the key chords from // - commands: The list of commands to label. static void _recursiveUpdateCommandKeybindingLabels(std::shared_ptr<::TerminalApp::CascadiaSettings> settings, - Windows::Foundation::Collections::IMapView commands) + IMapView commands) { for (const auto& nameAndCmd : commands) { @@ -83,20 +83,16 @@ namespace winrt::TerminalApp::implementation } } - static void _recursiveUpdateCommandIcons(Windows::Foundation::Collections::IMapView commands) + static void _recursiveUpdateCommandIcons(IMapView commands) { for (const auto& nameAndCmd : commands) { const auto& command = nameAndCmd.Value(); - // Set the default IconSource to a BitmapIconSource with a null source - // (instead of just nullptr) because there's a really weird crash when swapping - // data bound IconSourceElements in a ListViewTemplate (i.e. CommandPalette). - // Swapping between nullptr IconSources and non-null IconSources causes a crash - // to occur, but swapping between IconSources with a null source and non-null IconSources - // work perfectly fine :shrug:. - winrt::Windows::UI::Xaml::Controls::BitmapIconSource icon; - icon.UriSource(nullptr); - command.IconSource(icon); + + // !!! LOAD-BEARING !!! If this is never called, then Commands will + // have a nullptr icon. If they do, a really weird crash can occur. + // MAKE SURE this is called once after a settings load. + command.RefreshIcon(); if (command.HasNestedCommands()) { From 55b6ace79f197d44c00b5502759dd50528891298 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Mon, 24 Aug 2020 16:21:53 -0500 Subject: [PATCH 076/266] Compensate for VS 16.7, part 2 (#7383) This is just the `noexcept` part of #7319, because the CI apparently got updated overnight. --- src/buffer/out/UnicodeStorage.cpp | 7 +------ src/buffer/out/UnicodeStorage.hpp | 2 +- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/buffer/out/UnicodeStorage.cpp b/src/buffer/out/UnicodeStorage.cpp index bfc236e06bf..7de3c11025a 100644 --- a/src/buffer/out/UnicodeStorage.cpp +++ b/src/buffer/out/UnicodeStorage.cpp @@ -35,12 +35,7 @@ void UnicodeStorage::StoreGlyph(const key_type key, const mapped_type& glyph) // - erases key and its associated data from the storage // Arguments: // - key - the key to remove -// ~~~~~~~~~~~~~~ -// NOTE: VS 16.7 changes std::map::erase to noexcept, but the build agents are still 16.6.5. -// Ignore this audit warning on your dev box until the build starts failing. Then fix it -// and remove this comment. -// ~~~~~~~~~~~~~ -void UnicodeStorage::Erase(const key_type key) +void UnicodeStorage::Erase(const key_type key) noexcept { _map.erase(key); } diff --git a/src/buffer/out/UnicodeStorage.hpp b/src/buffer/out/UnicodeStorage.hpp index d37a01a2aeb..e1bd2ff3659 100644 --- a/src/buffer/out/UnicodeStorage.hpp +++ b/src/buffer/out/UnicodeStorage.hpp @@ -53,7 +53,7 @@ class UnicodeStorage final void StoreGlyph(const key_type key, const mapped_type& glyph); - void Erase(const key_type key); + void Erase(const key_type key) noexcept; void Remap(const std::unordered_map& rowMap, const std::optional width); From f897ce0a9f37b00efc0921fe46fe59628c0a217d Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Mon, 24 Aug 2020 16:39:07 -0500 Subject: [PATCH 077/266] Add support for Commandline Mode to the CmdPal (#7293) ## Summary of the Pull Request Adds support for "commandline mode" to the command palette. ![cmdpal-commandline-mode](https://user-images.githubusercontent.com/18356694/90263053-bbd17500-de14-11ea-8726-fee48fec5888.gif) This allows the user to start typing a `wt.exe` commandline directly in the command palette, to run that commandline directly in the current window. This allows the user input something like `> nt -p Ubuntu ; sp -p ssh` and open up a new tab and split it _in the current window_. ## References * cmdpal megathread: #5400 * Kinda related to #4472 * built with the `wt` action from #6537 ## PR Checklist * [x] Closes #6677 * [x] I work here * [ ] Tests added/passed * [ ] Requires documentation to be updated - sure does, when the cmdpal docs are written in the first place :P ## Validation Steps Performed Tested manually --- src/cascadia/TerminalApp/CommandPalette.cpp | 154 +++++++++++++++++- src/cascadia/TerminalApp/CommandPalette.h | 8 +- .../Resources/en-US/Resources.resw | 4 + 3 files changed, 155 insertions(+), 11 deletions(-) diff --git a/src/cascadia/TerminalApp/CommandPalette.cpp b/src/cascadia/TerminalApp/CommandPalette.cpp index a8d0cb12d88..307ca975ba2 100644 --- a/src/cascadia/TerminalApp/CommandPalette.cpp +++ b/src/cascadia/TerminalApp/CommandPalette.cpp @@ -172,25 +172,59 @@ namespace winrt::TerminalApp::implementation } else if (key == VirtualKey::Enter) { - // Action Mode: Dispatch the action of the selected command. - - if (const auto selectedItem = _filteredActionsView().SelectedItem()) + // Action, TabSwitch or TabSearchMode Mode: Dispatch the action of the selected command. + if (_currentMode != CommandPaletteMode::CommandlineMode) { - _dispatchCommand(selectedItem.try_as()); + if (const auto selectedItem = _filteredActionsView().SelectedItem()) + { + _dispatchCommand(selectedItem.try_as()); + } + } + // Commandline Mode: Use the input to synthesize an ExecuteCommandline action + else if (_currentMode == CommandPaletteMode::CommandlineMode) + { + _dispatchCommandline(); } e.Handled(true); } else if (key == VirtualKey::Escape) { - // Action Mode: Dismiss the palette if the text is empty, otherwise clear the search string. - if (_searchBox().Text().empty()) + // Action, TabSearch, TabSwitch Mode: Dismiss the palette if the + // text is empty, otherwise clear the search string. + if (_currentMode != CommandPaletteMode::CommandlineMode) { - _dismissPalette(); + if (_searchBox().Text().empty()) + { + _dismissPalette(); + } + else + { + _searchBox().Text(L""); + } } - else + else if (_currentMode == CommandPaletteMode::CommandlineMode) { - _searchBox().Text(L""); + const auto currentInput = _getPostPrefixInput(); + if (currentInput.empty()) + { + // The user's only input "> " so far. We should just dismiss + // the palette. This is like dismissing the Action mode with + // empty input. + _dismissPalette(); + } + else + { + // Clear out the current input. We'll leave a ">" in the + // input (to stay in commandline mode), and a leading space + // (if they currently had one). + const bool hasLeadingSpace = (_searchBox().Text().size()) - (currentInput.size()) > 1; + _searchBox().Text(hasLeadingSpace ? L"> " : L">"); + + // This will conveniently move the cursor to the end of the + // text input for us. + _searchBox().Select(_searchBox().Text().size(), 0); + } } e.Handled(true); @@ -362,6 +396,8 @@ namespace winrt::TerminalApp::implementation case CommandPaletteMode::TabSearchMode: case CommandPaletteMode::TabSwitchMode: return _allTabActions; + case CommandPaletteMode::CommandlineMode: + return winrt::single_threaded_vector(); default: return _allCommands; } @@ -422,6 +458,72 @@ namespace winrt::TerminalApp::implementation } } + // Method Description: + // - Get all the input text in _searchBox that follows the prefix character + // and any whitespace following that prefix character. This can be used in + // commandline mode to get all the useful input that the user input after + // the leading ">" prefix. + // - Note that this will behave unexpectedly in Action Mode. + // Arguments: + // - + // Return Value: + // - the string of input following the prefix character. + std::wstring CommandPalette::_getPostPrefixInput() + { + const std::wstring input{ _searchBox().Text() }; + if (input.empty()) + { + return input; + } + + const auto rawCmdline{ input.substr(1) }; + + // Trim leading whitespace + const auto firstNonSpace = rawCmdline.find_first_not_of(L" "); + if (firstNonSpace == std::wstring::npos) + { + // All the following characters are whitespace. + return L""; + } + + return rawCmdline.substr(firstNonSpace); + } + + // Method Description: + // - Dispatch the current search text as a ExecuteCommandline action. + // Arguments: + // - + // Return Value: + // - + void CommandPalette::_dispatchCommandline() + { + const auto input = _getPostPrefixInput(); + if (input.empty()) + { + return; + } + winrt::hstring cmdline{ input }; + + // Build the ExecuteCommandline action from the values we've parsed on the commandline. + auto executeActionAndArgs = winrt::make_self(); + executeActionAndArgs->Action(ShortcutAction::ExecuteCommandline); + auto args = winrt::make_self(); + args->Commandline(cmdline); + executeActionAndArgs->Args(*args); + + TraceLoggingWrite( + g_hTerminalAppProvider, // handle to TerminalApp tracelogging provider + "CommandPaletteDispatchedCommandline", + TraceLoggingDescription("Event emitted when the user runs a commandline in the Command Palette"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), + TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance)); + + if (_dispatch.DoAction(*executeActionAndArgs)) + { + _close(); + } + } + // Method Description: // - Helper method for closing the command palette, when the user has _not_ // selected an action. Also fires a tracelogging event indicating that the @@ -452,12 +554,36 @@ namespace winrt::TerminalApp::implementation void CommandPalette::_filterTextChanged(IInspectable const& /*sender*/, Windows::UI::Xaml::RoutedEventArgs const& /*args*/) { + if (_currentMode == CommandPaletteMode::CommandlineMode || _currentMode == CommandPaletteMode::ActionMode) + { + _evaluatePrefix(); + } + _updateFilteredActions(); _filteredActionsView().SelectedIndex(0); _noMatchesText().Visibility(_filteredActions.Size() > 0 ? Visibility::Collapsed : Visibility::Visible); } + void CommandPalette::_evaluatePrefix() + { + auto newMode = CommandPaletteMode::ActionMode; + + auto inputText = _searchBox().Text(); + if (inputText.size() > 0) + { + if (inputText[0] == L'>') + { + newMode = CommandPaletteMode::CommandlineMode; + } + } + + if (newMode != _currentMode) + { + _switchToMode(newMode); + } + } + Collections::IObservableVector CommandPalette::FilteredActions() { return _filteredActions; @@ -511,6 +637,10 @@ namespace winrt::TerminalApp::implementation ControlName(RS_(L"TabSwitcherControlName")); break; } + case CommandPaletteMode::CommandlineMode: + NoMatchesText(RS_(L"CmdPalCommandlinePrompt")); + ControlName(RS_(L"CommandPaletteControlName")); + break; case CommandPaletteMode::ActionMode: default: SearchBoxText(RS_(L"CommandPalette_SearchBox/PlaceholderText")); @@ -666,6 +796,12 @@ namespace winrt::TerminalApp::implementation // - void CommandPalette::_updateFilteredActions() { + if (_currentMode == CommandPaletteMode::CommandlineMode) + { + _filteredActions.Clear(); + return; + } + auto actions = _collectFilteredActions(); // Make _filteredActions look identical to actions, using only Insert and Remove. diff --git a/src/cascadia/TerminalApp/CommandPalette.h b/src/cascadia/TerminalApp/CommandPalette.h index 97b0f0c8d25..65dd39ab552 100644 --- a/src/cascadia/TerminalApp/CommandPalette.h +++ b/src/cascadia/TerminalApp/CommandPalette.h @@ -12,7 +12,8 @@ namespace winrt::TerminalApp::implementation { ActionMode = 0, TabSearchMode, - TabSwitchMode + TabSwitchMode, + CommandlineMode }; struct CommandPalette : CommandPaletteT @@ -80,6 +81,9 @@ namespace winrt::TerminalApp::implementation CommandPaletteMode _currentMode; void _switchToMode(CommandPaletteMode mode); + void _evaluatePrefix(); + std::wstring _getPostPrefixInput(); + Microsoft::Terminal::TerminalControl::IKeyBindings _bindings; // Tab Switcher @@ -92,7 +96,7 @@ namespace winrt::TerminalApp::implementation winrt::Windows::UI::Xaml::Controls::ListView::SizeChanged_revoker _sizeChangedRevoker; void _dispatchCommand(const TerminalApp::Command& command); - + void _dispatchCommandline(); void _dismissPalette(); }; } diff --git a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw index f7d58b6d826..f36568f8e8e 100644 --- a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw +++ b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw @@ -594,6 +594,10 @@ No matching tab name + + Enter a wt commandline to run + {Locked="wt"} + Crimson From 17e0c1184013b228ff6a962904cbfc93f41c0d84 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Mon, 24 Aug 2020 17:44:36 -0500 Subject: [PATCH 078/266] Bind the command palette by default (#7384) Bind the command palette to Ctrl+Shift+P by default, to enable it for all users in v1.3 --- src/cascadia/TerminalApp/defaults-universal.json | 1 + src/cascadia/TerminalApp/defaults.json | 1 + 2 files changed, 2 insertions(+) diff --git a/src/cascadia/TerminalApp/defaults-universal.json b/src/cascadia/TerminalApp/defaults-universal.json index 993da6d8f47..a580c30ff5d 100644 --- a/src/cascadia/TerminalApp/defaults-universal.json +++ b/src/cascadia/TerminalApp/defaults-universal.json @@ -81,6 +81,7 @@ { "command": "openNewTabDropdown", "keys": "ctrl+shift+space" }, { "command": "openSettings", "keys": "ctrl+," }, { "command": "find", "keys": "ctrl+shift+f" }, + { "command": "commandPalette", "keys":"ctrl+shift+p" }, // Tab Management // "command": "closeTab" is unbound by default. diff --git a/src/cascadia/TerminalApp/defaults.json b/src/cascadia/TerminalApp/defaults.json index 818ba8515ca..ad7584183d6 100644 --- a/src/cascadia/TerminalApp/defaults.json +++ b/src/cascadia/TerminalApp/defaults.json @@ -286,6 +286,7 @@ { "command": "find", "keys": "ctrl+shift+f" }, { "command": "toggleRetroEffect" }, { "command": "openTabColorPicker" }, + { "command": "commandPalette", "keys":"ctrl+shift+p" }, // Tab Management // "command": "closeTab" is unbound by default. From a5bed25417ae17f0eb59a4e5e7e059a72213d0cf Mon Sep 17 00:00:00 2001 From: "Dustin L. Howett" Date: Mon, 24 Aug 2020 15:54:02 -0700 Subject: [PATCH 079/266] TermControl: set the scrollbar jump distance to one screenful (#7385) Most applications with scrollable content seem to define the "large jump" distance as about a screenful of content. You can see this in long pages in Settings and documents in Notepad. We just weren't configuring ScrollBar here. Fixes #7367 --- src/cascadia/TerminalControl/TermControl.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index dd033691e5d..6c86ac93e36 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -156,6 +156,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation scrollBar.Maximum(update.newMaximum); scrollBar.Minimum(update.newMinimum); scrollBar.ViewportSize(update.newViewportSize); + scrollBar.LargeChange(std::max(update.newViewportSize - 1, 0.)); // scroll one "screenful" at a time when the scroll bar is clicked control->_isInternalScrollBarUpdate = false; } @@ -699,6 +700,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation ScrollBar().Minimum(0); ScrollBar().Value(0); ScrollBar().ViewportSize(bufferHeight); + ScrollBar().LargeChange(std::max(bufferHeight - 1, 0)); // scroll one "screenful" at a time when the scroll bar is clicked localPointerToThread->EnablePainting(); From c15b808142a14d0328fa5c7f45f938f413c7adb4 Mon Sep 17 00:00:00 2001 From: Dustin Howett Date: Mon, 24 Aug 2020 16:16:10 -0700 Subject: [PATCH 080/266] version: bump to 1.4 on master Signed-off-by: Dustin Howett --- custom.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom.props b/custom.props index c4bf1eefda0..377aaa3cd33 100644 --- a/custom.props +++ b/custom.props @@ -5,7 +5,7 @@ true 2020 1 - 3 + 4 Windows Terminal From 6acb9f8c90b1e4bc7837fd83fd60afddb46760bf Mon Sep 17 00:00:00 2001 From: Kayla Cinnamon Date: Mon, 24 Aug 2020 16:28:11 -0700 Subject: [PATCH 081/266] schema: swap `closeTabsAfter` and `closeOtherTabs` (#7386) The descriptions were flipped, so I unflipped them. --- doc/cascadia/profiles.schema.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/cascadia/profiles.schema.json b/doc/cascadia/profiles.schema.json index ebd7ec082ed..29dc727df85 100644 --- a/doc/cascadia/profiles.schema.json +++ b/doc/cascadia/profiles.schema.json @@ -399,7 +399,7 @@ "index": { "type": "integer", "default": "", - "description": "close the tabs following the tab at this index" + "description": "Close the tabs other than the one at this index." } } } @@ -416,7 +416,7 @@ "index": { "type": "integer", "default": "", - "description": "close the tabs other than the one at this index" + "description": "Close the tabs following the tab at this index." } } } From dbbe820ae40d208c07c45b700fcc99063e68d1eb Mon Sep 17 00:00:00 2001 From: "Dustin L. Howett" Date: Tue, 25 Aug 2020 10:15:43 -0700 Subject: [PATCH 082/266] Update clang-format to 10.0 (#7389) This commit removes our local copy of clang-format 8 and replaces it with a newly-built nuget package containing clang-format 10. This resolves the inconsistency between our version of clang-format and the one shipped in Visual Studio. A couple minor format changes were either required or erroneously forced upon us--chief among them is a redistribution of `*`s around SAL annotations in inline class members of COM classes. Don't ask why; I couldn't figure it out. We had some aspirational goals for our formatting, which were left in but commented out. Enabling them changes our format a little more than I'm comfortable with, so I uncommented them and locked them to the format style we've been using for the past year. We may not love it, but our aspirations may not matter here any longer. Consistent formatting is better than perfect formatting. --- .clang-format | 14 +++++++++----- dep/llvm/clang-format.exe | Bin 2526208 -> 0 bytes .../PublicTerminalCore/HwndTerminal.cpp | 2 +- src/inc/til/static_map.h | 2 +- src/propsheet/PropSheetHandler.cpp | 12 ++++++------ src/renderer/dx/DxRenderer.cpp | 3 +-- src/terminal/input/terminalInput.cpp | 3 +-- tools/OpenConsole.psm1 | 12 +++++++++--- tools/packages.config | 4 ++++ 9 files changed, 32 insertions(+), 20 deletions(-) delete mode 100644 dep/llvm/clang-format.exe create mode 100644 tools/packages.config diff --git a/.clang-format b/.clang-format index 9e5a7d13157..26a27f32ed1 100644 --- a/.clang-format +++ b/.clang-format @@ -1,17 +1,19 @@ AccessModifierOffset: -4 AlignAfterOpenBracket: Align -#AllowAllArgumentsOnNextLine: false +AllowAllArgumentsOnNextLine: true +AlignConsecutiveMacros: false AlignConsecutiveAssignments: false AlignConsecutiveDeclarations: false -#AllowAllConstructorInitializersOnNextLine: false +AllowAllConstructorInitializersOnNextLine: true AlignEscapedNewlines: Left AlignOperands: true AlignTrailingComments: false AllowAllParametersOfDeclarationOnNextLine: false +AllowShortBlocksOnASingleLine: Never AllowShortFunctionsOnASingleLine: Inline AllowShortCaseLabelsOnASingleLine: false -AllowShortIfStatementsOnASingleLine: false +AllowShortIfStatementsOnASingleLine: Never #AllowShortLambdasOnASingleLine: Inline AllowShortLoopsOnASingleLine: false AlwaysBreakAfterReturnType: None @@ -20,6 +22,7 @@ AlwaysBreakTemplateDeclarations: Yes BinPackArguments: false BinPackParameters: false BraceWrapping: + AfterCaseLabel: true AfterClass: true AfterControlStatement: true AfterEnum: true @@ -47,6 +50,7 @@ ConstructorInitializerAllOnOneLineOrOnePerLine: true ConstructorInitializerIndentWidth: 4 ContinuationIndentWidth: 4 Cpp11BracedListStyle: false +DeriveLineEnding: true DerivePointerAlignment: false FixNamespaceComments: false IncludeBlocks: Regroup @@ -73,7 +77,7 @@ ReflowComments: false SortIncludes: false SortUsingDeclarations: true SpaceAfterCStyleCast: false -#SpaceAfterLogicalNot: false +SpaceAfterLogicalNot: false SpaceAfterTemplateKeyword: false SpaceBeforeAssignmentOperators: true SpaceBeforeCpp11BracedList: false @@ -88,6 +92,6 @@ SpacesInCStyleCastParentheses: false SpacesInContainerLiterals: false SpacesInParentheses: false SpacesInSquareBrackets: false -Standard: Cpp11 +Standard: Latest TabWidth: 4 UseTab: Never diff --git a/dep/llvm/clang-format.exe b/dep/llvm/clang-format.exe deleted file mode 100644 index efed82cc09d1ec79ee4b595518e8cf3b37a8ed51..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2526208 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
LVdH3( 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

uj(7u?TOO=R! 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�Emh3LY6 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 z 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

)L# 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 Hy?_26F?-)b diff --git a/src/cascadia/PublicTerminalCore/HwndTerminal.cpp b/src/cascadia/PublicTerminalCore/HwndTerminal.cpp index 0a0090338ff..6280ae37e72 100644 --- a/src/cascadia/PublicTerminalCore/HwndTerminal.cpp +++ b/src/cascadia/PublicTerminalCore/HwndTerminal.cpp @@ -242,7 +242,7 @@ HRESULT HwndTerminal::Initialize() _terminal->Create(COORD{ 80, 25 }, 1000, *_renderer); _terminal->SetDefaultBackground(RGB(12, 12, 12)); _terminal->SetDefaultForeground(RGB(204, 204, 204)); - _terminal->SetWriteInputCallback([=](std::wstring & input) noexcept { _WriteTextToConnection(input); }); + _terminal->SetWriteInputCallback([=](std::wstring& input) noexcept { _WriteTextToConnection(input); }); localPointerToThread->EnablePainting(); _multiClickTime = std::chrono::milliseconds{ GetDoubleClickTime() }; diff --git a/src/inc/til/static_map.h b/src/inc/til/static_map.h index 452e2dab36b..1a82ac6ff51 100644 --- a/src/inc/til/static_map.h +++ b/src/inc/til/static_map.h @@ -70,5 +70,5 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned" // 1. static_map's member types are all the same // 2. static_map's fourth template argument (otherwise undeduced) is how many pairs it contains template - static_map(First, Rest...)->static_map...>, typename First::first_type, void>, typename First::second_type, std::less, 1 + sizeof...(Rest)>; + static_map(First, Rest...) -> static_map...>, typename First::first_type, void>, typename First::second_type, std::less, 1 + sizeof...(Rest)>; } diff --git a/src/propsheet/PropSheetHandler.cpp b/src/propsheet/PropSheetHandler.cpp index f06d4fc6ebf..f34581d52e7 100644 --- a/src/propsheet/PropSheetHandler.cpp +++ b/src/propsheet/PropSheetHandler.cpp @@ -34,7 +34,7 @@ class ConsolePropertySheetHandler WrlFinal : public RuntimeClass(cchLine); - const auto DrawLine = [=](const auto x0, const auto y0, const auto x1, const auto y1, const auto strokeWidth) noexcept - { + const auto DrawLine = [=](const auto x0, const auto y0, const auto x1, const auto y1, const auto strokeWidth) noexcept { _d2dDeviceContext->DrawLine({ x0, y0 }, { x1, y1 }, _d2dBrushForeground.Get(), strokeWidth, _strokeStyle.Get()); }; diff --git a/src/terminal/input/terminalInput.cpp b/src/terminal/input/terminalInput.cpp index 8f5c5c4f7f3..328ec1c6727 100644 --- a/src/terminal/input/terminalInput.cpp +++ b/src/terminal/input/terminalInput.cpp @@ -588,8 +588,7 @@ bool TerminalInput::HandleKey(const IInputEvent* const pInEvent) } } - const auto senderFunc = [this](const std::wstring_view seq) noexcept - { + const auto senderFunc = [this](const std::wstring_view seq) noexcept { _SendInputSequence(seq); }; diff --git a/tools/OpenConsole.psm1 b/tools/OpenConsole.psm1 index 78c5416eddb..3f628e4235c 100644 --- a/tools/OpenConsole.psm1 +++ b/tools/OpenConsole.psm1 @@ -323,7 +323,10 @@ function Invoke-ClangFormat { [CmdletBinding()] Param ( [Parameter(Mandatory=$true,ValueFromPipeline=$true)] - [string[]]$Path + [string[]]$Path, + + [Parameter(Mandatory=$false)] + [string]$ClangFormatPath = "clang-format" # (whichever one is in $PATH) ) Begin { @@ -340,7 +343,7 @@ function Invoke-ClangFormat { End { For($i = [int]0; $i -Lt $Paths.Length; $i += $BatchSize) { Try { - & "$env:OpenconsoleRoot/dep/llvm/clang-format" -i $Paths[$i .. ($i + $BatchSize - 1)] + & $ClangFormatPath -i $Paths[$i .. ($i + $BatchSize - 1)] } Catch { Write-Error $_ } @@ -351,9 +354,12 @@ function Invoke-ClangFormat { #.SYNOPSIS # runs code formatting on all c++ files function Invoke-CodeFormat() { + & "$env:OpenConsoleRoot\dep\nuget\nuget.exe" restore "$env:OpenConsoleRoot\tools\packages.config" + $clangPackage = ([xml](Get-Content "$env:OpenConsoleRoot\tools\packages.config")).packages.package | Where-Object id -like "clang-format*" + $clangFormatPath = "$env:OpenConsoleRoot\packages\$($clangPackage.id).$($clangPackage.version)\tools\clang-format.exe" Get-ChildItem -Recurse "$env:OpenConsoleRoot/src" -Include *.cpp, *.hpp, *.h | Where FullName -NotLike "*Generated Files*" | - Invoke-ClangFormat + Invoke-ClangFormat -ClangFormatPath $clangFormatPath } Export-ModuleMember -Function Set-MsbuildDevEnvironment,Invoke-OpenConsoleTests,Invoke-OpenConsoleBuild,Start-OpenConsole,Debug-OpenConsole,Invoke-CodeFormat diff --git a/tools/packages.config b/tools/packages.config new file mode 100644 index 00000000000..a552f5bc0ea --- /dev/null +++ b/tools/packages.config @@ -0,0 +1,4 @@ + + + + From 4aecbf383383a952ae8c1802d9defcd94bbfc765 Mon Sep 17 00:00:00 2001 From: "Dustin L. Howett" Date: Tue, 25 Aug 2020 10:17:21 -0700 Subject: [PATCH 083/266] Clear the last error before calling Mb2Wc in ConvertToW (#7391) When the console functional tests are running on OneCoreUAP, the newly-introduced (65bd4e327, #4309) FillOutputCharacterA tests will actually fail because of radio interference on the return value of GLE. Fixes MSFT-28163465 --- src/types/convert.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/types/convert.cpp b/src/types/convert.cpp index f33ab36201d..dc7b7190832 100644 --- a/src/types/convert.cpp +++ b/src/types/convert.cpp @@ -38,6 +38,13 @@ static const WORD leftShiftScanCode = 0x2A; THROW_IF_FAILED(SizeTToInt(source.size(), &iSource)); // Ask how much space we will need. + // In certain codepages, Mb2Wc will "successfully" produce zero characters (like in CP50220, where a SHIFT-IN character + // is consumed but not transformed into anything) without explicitly failing. When it does this, GetLastError will return + // the last error encountered by the last function that actually did have an error. + // This is arguably correct (as the documentation says "The function returns 0 if it does not succeed"). There is a + // difference that we **don't actually care about** between failing and successfully producing zero characters., + // Anyway: we need to clear the last error so that we can fail out and IGNORE_BAD_GLE after it inevitably succeed-fails. + SetLastError(0); int const iTarget = MultiByteToWideChar(codePage, 0, source.data(), iSource, nullptr, 0); THROW_LAST_ERROR_IF_AND_IGNORE_BAD_GLE(0 == iTarget); From ac310d98b7d2d101eac624976721558a221dd4d5 Mon Sep 17 00:00:00 2001 From: Leonard Hecker Date: Tue, 25 Aug 2020 20:04:23 +0200 Subject: [PATCH 084/266] Fixed #7372: Setting "altGrAliasing" to "false" disables AltGr (#7400) ## Summary of the Pull Request Previously, if `altGrAliasing` was disabled, all `Ctrl+Alt` combinations were considered to be aliases of `AltGr` including `AltGr` itself and thus considered as key and not character events. But `AltGr` should not be treated as an alias of itself of course, as that prevents one from entering `AltGr` combinations entirely. ## PR Checklist * [x] Closes #7372 * [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 * [ ] 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 ## Validation Steps Performed * Activate a German keyboard layout * Run `showkey -a` in WSL * **Ensure** that `AltGr+Q` produces `@` * **Ensure** that `Ctrl+Alt+Q` produces `@` * Disable `altGrAliasing` * **Ensure** that `AltGr+Q` produces `@` * **Ensure** that `Ctrl+Alt+Q` produces `^[^Q` --- src/cascadia/TerminalCore/Terminal.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cascadia/TerminalCore/Terminal.cpp b/src/cascadia/TerminalCore/Terminal.cpp index f6b3950a262..55d238d401b 100644 --- a/src/cascadia/TerminalCore/Terminal.cpp +++ b/src/cascadia/TerminalCore/Terminal.cpp @@ -457,7 +457,6 @@ bool Terminal::SendKeyEvent(const WORD vkey, } const auto isAltOnlyPressed = states.IsAltPressed() && !states.IsCtrlPressed(); - const auto isSuppressedAltGrAlias = !_altGrAliasing && states.IsAltPressed() && states.IsCtrlPressed(); // DON'T manually handle Alt+Space - the system will use this to bring up // the system menu for restore, min/maximize, size, move, close. @@ -477,6 +476,7 @@ bool Terminal::SendKeyEvent(const WORD vkey, // as TerminalInput::HandleKey will then fall back to using the vkey which // is the underlying ASCII character (e.g. A-Z) on the keyboard in our case. // See GH#5525/GH#6211 for more details + const auto isSuppressedAltGrAlias = !_altGrAliasing && states.IsAltPressed() && states.IsCtrlPressed() && !states.IsAltGrPressed(); const auto ch = isSuppressedAltGrAlias ? UNICODE_NULL : _CharacterFromKeyEvent(vkey, scanCode, states); // Delegate it to the character event handler if this key event can be From 64f10a0c9d81707500832cc246f9c013069e8902 Mon Sep 17 00:00:00 2001 From: nathpete-msft Date: Tue, 25 Aug 2020 11:16:48 -0700 Subject: [PATCH 085/266] Fix environment block creation (#7401) This fixes a regression in environment variable loading introduced as part of the new environment block creation that prevents some system-defined, volatile environment variables from being defined. ## References https://github.com/microsoft/terminal/pull/7243#discussion_r476603599 ## Validation Steps Performed Manually verified locally. Closes #7399 --- src/types/Environment.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/types/Environment.cpp b/src/types/Environment.cpp index 010f6c8f8f8..962297ace2c 100644 --- a/src/types/Environment.cpp +++ b/src/types/Environment.cpp @@ -3,6 +3,7 @@ #include "precomp.h" #include "inc/Environment.hpp" +#include "wil/token_helpers.h" using namespace ::Microsoft::Console::Utils; @@ -14,7 +15,8 @@ using namespace ::Microsoft::Console::Utils; EnvironmentBlockPtr Microsoft::Console::Utils::CreateEnvironmentBlock() { void* newEnvironmentBlock{ nullptr }; - if (!::CreateEnvironmentBlock(&newEnvironmentBlock, GetCurrentProcessToken(), FALSE)) + auto processToken{ wil::open_current_access_token(TOKEN_QUERY | TOKEN_DUPLICATE) }; + if (!::CreateEnvironmentBlock(&newEnvironmentBlock, processToken.get(), FALSE)) { return nullptr; } From 2fdc88f7ea6a021ec77b27fbf7ad7ea5bb5168a9 Mon Sep 17 00:00:00 2001 From: Carlos Zamora Date: Tue, 25 Aug 2020 12:25:25 -0700 Subject: [PATCH 086/266] Make index in closeOtherTabs and closeTabsAfter optional (#7390) ## Summary of the Pull Request The `index` action argument is now optional for `closeOtherTabs` and `closeTabsAfter`. When `index` is not defined, `index` is set to the focused tab's index. Also, adds the non-index version of these actions to defaults.json. ## PR Checklist * [X] Closes #7181 * [X] CLA signed * [X] Tests 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. ## Validation Steps Performed Opened 4 tabs and ran closeOtherTabs/closeTabsAfter from command palette. --- doc/cascadia/profiles.schema.json | 20 +++++++----- src/cascadia/TerminalApp/ActionArgs.cpp | 28 ++++++++++------ src/cascadia/TerminalApp/ActionArgs.h | 4 +-- src/cascadia/TerminalApp/ActionArgs.idl | 4 +-- .../TerminalApp/AppActionHandlers.cpp | 32 +++++++++++++++++-- .../Resources/en-US/Resources.resw | 8 ++++- src/cascadia/TerminalApp/TerminalPage.cpp | 4 +-- src/cascadia/TerminalApp/defaults.json | 2 ++ 8 files changed, 75 insertions(+), 27 deletions(-) diff --git a/doc/cascadia/profiles.schema.json b/doc/cascadia/profiles.schema.json index 29dc727df85..1f1f6c3864a 100644 --- a/doc/cascadia/profiles.schema.json +++ b/doc/cascadia/profiles.schema.json @@ -397,14 +397,16 @@ "properties": { "action": { "type": "string", "pattern": "closeOtherTabs" }, "index": { - "type": "integer", + "oneOf": [ + { "type": "integer" }, + { "type": null } + ], "default": "", - "description": "Close the tabs other than the one at this index." + "description": "Close the tabs other than the one at this index. If no index is provided, use the focused tab's index." } } } - ], - "required": [ "index" ] + ] }, "CloseTabsAfterAction": { "description": "Arguments for a closeTabsAfter action", @@ -414,14 +416,16 @@ "properties": { "action": { "type": "string", "pattern": "closeTabsAfter" }, "index": { - "type": "integer", + "oneOf": [ + { "type": "integer" }, + { "type": null } + ], "default": "", - "description": "Close the tabs following the tab at this index." + "description": "Close the tabs following the tab at this index. If no index is provided, use the focused tab's index." } } } - ], - "required": [ "index" ] + ] }, "Keybinding": { "additionalProperties": false, diff --git a/src/cascadia/TerminalApp/ActionArgs.cpp b/src/cascadia/TerminalApp/ActionArgs.cpp index 046068929b2..6cc367634c5 100644 --- a/src/cascadia/TerminalApp/ActionArgs.cpp +++ b/src/cascadia/TerminalApp/ActionArgs.cpp @@ -339,19 +339,27 @@ namespace winrt::TerminalApp::implementation winrt::hstring CloseOtherTabsArgs::GenerateName() const { - // "Close tabs other than index {0}" - return winrt::hstring{ - fmt::format(std::wstring_view(RS_(L"CloseOtherTabsCommandKey")), - _Index) - }; + if (_Index) + { + // "Close tabs other than index {0}" + return winrt::hstring{ + fmt::format(std::wstring_view(RS_(L"CloseOtherTabsCommandKey")), + _Index.Value()) + }; + } + return RS_(L"CloseOtherTabsDefaultCommandKey"); } winrt::hstring CloseTabsAfterArgs::GenerateName() const { - // "Close tabs after index {0}" - return winrt::hstring{ - fmt::format(std::wstring_view(RS_(L"CloseTabsAfterCommandKey")), - _Index) - }; + if (_Index) + { + // "Close tabs after index {0}" + return winrt::hstring{ + fmt::format(std::wstring_view(RS_(L"CloseTabsAfterCommandKey")), + _Index.Value()) + }; + } + return RS_(L"CloseTabsAfterDefaultCommandKey"); } } diff --git a/src/cascadia/TerminalApp/ActionArgs.h b/src/cascadia/TerminalApp/ActionArgs.h index c90430a84c6..de3bbd0b3da 100644 --- a/src/cascadia/TerminalApp/ActionArgs.h +++ b/src/cascadia/TerminalApp/ActionArgs.h @@ -495,7 +495,7 @@ namespace winrt::TerminalApp::implementation struct CloseOtherTabsArgs : public CloseOtherTabsArgsT { CloseOtherTabsArgs() = default; - GETSET_PROPERTY(uint32_t, Index, 0); + GETSET_PROPERTY(winrt::Windows::Foundation::IReference, Index, nullptr); static constexpr std::string_view IndexKey{ "index" }; @@ -523,7 +523,7 @@ namespace winrt::TerminalApp::implementation struct CloseTabsAfterArgs : public CloseTabsAfterArgsT { CloseTabsAfterArgs() = default; - GETSET_PROPERTY(uint32_t, Index, 0); + GETSET_PROPERTY(winrt::Windows::Foundation::IReference, Index, nullptr); static constexpr std::string_view IndexKey{ "index" }; diff --git a/src/cascadia/TerminalApp/ActionArgs.idl b/src/cascadia/TerminalApp/ActionArgs.idl index 96b3b04386e..51ecf282941 100644 --- a/src/cascadia/TerminalApp/ActionArgs.idl +++ b/src/cascadia/TerminalApp/ActionArgs.idl @@ -134,11 +134,11 @@ namespace TerminalApp [default_interface] runtimeclass CloseOtherTabsArgs : IActionArgs { - UInt32 Index { get; }; + Windows.Foundation.IReference Index { get; }; }; [default_interface] runtimeclass CloseTabsAfterArgs : IActionArgs { - UInt32 Index { get; }; + Windows.Foundation.IReference Index { get; }; }; } diff --git a/src/cascadia/TerminalApp/AppActionHandlers.cpp b/src/cascadia/TerminalApp/AppActionHandlers.cpp index 8b4f4c6b0e1..8770f6037dc 100644 --- a/src/cascadia/TerminalApp/AppActionHandlers.cpp +++ b/src/cascadia/TerminalApp/AppActionHandlers.cpp @@ -415,7 +415,21 @@ namespace winrt::TerminalApp::implementation { if (const auto& realArgs = actionArgs.ActionArgs().try_as()) { - uint32_t index = realArgs.Index(); + uint32_t index; + if (realArgs.Index()) + { + index = realArgs.Index().Value(); + } + else if (auto focusedTabIndex = _GetFocusedTabIndex()) + { + index = *focusedTabIndex; + } + else + { + // Do nothing + actionArgs.Handled(false); + return; + } // Remove tabs after the current one while (_tabs.Size() > index + 1) @@ -438,7 +452,21 @@ namespace winrt::TerminalApp::implementation { if (const auto& realArgs = actionArgs.ActionArgs().try_as()) { - uint32_t index = realArgs.Index(); + uint32_t index; + if (realArgs.Index()) + { + index = realArgs.Index().Value(); + } + else if (auto focusedTabIndex = _GetFocusedTabIndex()) + { + index = *focusedTabIndex; + } + else + { + // Do nothing + actionArgs.Handled(false); + return; + } // Remove tabs after the current one while (_tabs.Size() > index + 1) diff --git a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw index f36568f8e8e..ce6b1d0e656 100644 --- a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw +++ b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw @@ -646,4 +646,10 @@ Dark Gray - + + Close all other tabs + + + Close all tabs after the current tab + + \ No newline at end of file diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index 24f9504bb66..318fe967f9d 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -1304,9 +1304,9 @@ namespace winrt::TerminalApp::implementation // Method Description: // - Returns the index in our list of tabs of the currently focused tab. If - // no tab is currently selected, returns -1. + // no tab is currently selected, returns nullopt. // Return Value: - // - the index of the currently focused tab if there is one, else -1 + // - the index of the currently focused tab if there is one, else nullopt std::optional TerminalPage::_GetFocusedTabIndex() const noexcept { // GH#1117: This is a workaround because _tabView.SelectedIndex() diff --git a/src/cascadia/TerminalApp/defaults.json b/src/cascadia/TerminalApp/defaults.json index ad7584183d6..4a83ad9b6c2 100644 --- a/src/cascadia/TerminalApp/defaults.json +++ b/src/cascadia/TerminalApp/defaults.json @@ -291,6 +291,8 @@ // Tab Management // "command": "closeTab" is unbound by default. // The closeTab command closes a tab without confirmation, even if it has multiple panes. + { "command": "closeOtherTabs" }, + { "command": "closeTabsAfter" }, { "command": "newTab", "keys": "ctrl+shift+t" }, { "command": { "action": "newTab", "index": 0 }, "keys": "ctrl+shift+1" }, { "command": { "action": "newTab", "index": 1 }, "keys": "ctrl+shift+2" }, From 0488c5322c25824efc8410301a07e9cd8193a8bf Mon Sep 17 00:00:00 2001 From: "Dustin L. Howett" Date: Tue, 25 Aug 2020 14:50:51 -0700 Subject: [PATCH 087/266] Update Cascadia Code to 2008.25 (#7403) --- res/Cascadia.ttf | Bin 341976 -> 342160 bytes res/CascadiaMono.ttf | Bin 323156 -> 323340 bytes res/README.md | 4 ++-- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/res/Cascadia.ttf b/res/Cascadia.ttf index 48acfd4e676af7d52d3532977d3803f03968d7f1..c3963842af07496265414657fcc72e827ab9135b 100644 GIT binary patch delta 24468 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 delta 24178 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 Q#o;LVx^&ro)rn632U~JpmH+?% delta 22491 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 Date: Thu, 27 Aug 2020 10:11:05 -0700 Subject: [PATCH 088/266] Fix schema for `setColorScheme` (#7433) `setColorScheme` should require `colorScheme` rather than `name` --- doc/cascadia/profiles.schema.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/cascadia/profiles.schema.json b/doc/cascadia/profiles.schema.json index 1f1f6c3864a..b41d82c5852 100644 --- a/doc/cascadia/profiles.schema.json +++ b/doc/cascadia/profiles.schema.json @@ -370,7 +370,7 @@ } } ], - "required": [ "name" ] + "required": [ "colorScheme" ] }, "WtAction": { "description": "Arguments corresponding to a wt Action", From 6c0e6d94cda020bf448e74a25875e0937e28b3bf Mon Sep 17 00:00:00 2001 From: Dustin Howett Date: Thu, 27 Aug 2020 17:29:14 -0700 Subject: [PATCH 089/266] ci: run CI and triggered builds on feature/* --- build/pipelines/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build/pipelines/ci.yml b/build/pipelines/ci.yml index 365e0f3abb1..0220419e550 100644 --- a/build/pipelines/ci.yml +++ b/build/pipelines/ci.yml @@ -3,6 +3,7 @@ trigger: branches: include: - master + - feature/* paths: exclude: - doc/* @@ -13,6 +14,7 @@ pr: branches: include: - master + - feature/* paths: exclude: - doc/* From a51091c615fe191c30512d358d6a5ce5241ca80c Mon Sep 17 00:00:00 2001 From: Carlos Zamora Date: Thu, 27 Aug 2020 18:09:22 -0700 Subject: [PATCH 090/266] Make Profile a WinRT object (#7283) Profile is now a WinRT object in the TerminalApp project. As with ColorScheme, all of the serialization logic is not exposed via the idl. TerminalSetingsModel will handle it when it's all moved over. I removed the "Get" and "Set" prefixes from all of the Profile functions. It just makes more sense to use the `GETSET_PROPERTY` macro to do most of the work for us. `CloseOnExitMode` is now an enum off of the Profile.idl. `std::optional` got converted to `hstring` (as opposed to `IReference`). `IReference` is not valid to MIDL. ## References #7141 - Profile is a settings object #885 - this new settings object will be moved to a new TerminalSettingsModel project ## Validation Steps Performed - [x] Tests passed - [x] Deployment succeeded Closes #7435 --- .../LocalTests_TerminalApp/ProfileTests.cpp | 131 ++-- .../LocalTests_TerminalApp/SettingsTests.cpp | 651 +++++++++--------- src/cascadia/LocalTests_TerminalApp/pch.h | 17 +- .../TerminalApp/AzureCloudShellGenerator.cpp | 17 +- .../TerminalApp/AzureCloudShellGenerator.h | 4 +- src/cascadia/TerminalApp/CascadiaSettings.cpp | 87 +-- src/cascadia/TerminalApp/CascadiaSettings.h | 22 +- .../CascadiaSettingsSerialization.cpp | 32 +- src/cascadia/TerminalApp/Command.cpp | 6 +- src/cascadia/TerminalApp/Command.h | 4 +- .../TerminalApp/DefaultProfileUtils.cpp | 13 +- .../TerminalApp/DefaultProfileUtils.h | 2 +- .../TerminalApp/IDynamicProfileGenerator.h | 2 +- src/cascadia/TerminalApp/JsonUtils.h | 47 +- src/cascadia/TerminalApp/Pane.cpp | 6 +- .../PowershellCoreProfileGenerator.cpp | 19 +- .../PowershellCoreProfileGenerator.h | 2 +- src/cascadia/TerminalApp/Profile.cpp | 536 +++++--------- src/cascadia/TerminalApp/Profile.h | 222 +++--- src/cascadia/TerminalApp/Profile.idl | 70 ++ src/cascadia/TerminalApp/SettingsTypes.h | 7 - src/cascadia/TerminalApp/TelnetGenerator.h | 2 +- .../TerminalApp/TerminalAppLib.vcxproj | 9 +- .../TerminalAppLib.vcxproj.filters | 3 + src/cascadia/TerminalApp/TerminalPage.cpp | 42 +- src/cascadia/TerminalApp/TerminalPage.h | 2 +- .../TerminalSettingsSerializationHelpers.h | 4 +- .../TerminalApp/WslDistroGenerator.cpp | 13 +- src/cascadia/TerminalApp/WslDistroGenerator.h | 2 +- src/cascadia/ut_app/DynamicProfileTests.cpp | 344 ++++----- src/cascadia/ut_app/JsonTests.cpp | 40 +- .../ut_app/TestDynamicProfileGenerator.h | 6 +- src/cascadia/ut_app/precomp.h | 17 +- 33 files changed, 1158 insertions(+), 1223 deletions(-) create mode 100644 src/cascadia/TerminalApp/Profile.idl diff --git a/src/cascadia/LocalTests_TerminalApp/ProfileTests.cpp b/src/cascadia/LocalTests_TerminalApp/ProfileTests.cpp index c0064c6a3af..e3cf469f031 100644 --- a/src/cascadia/LocalTests_TerminalApp/ProfileTests.cpp +++ b/src/cascadia/LocalTests_TerminalApp/ProfileTests.cpp @@ -9,6 +9,7 @@ using namespace Microsoft::Console; using namespace TerminalApp; +using namespace winrt::TerminalApp; using namespace WEX::Logging; using namespace WEX::TestExecution; using namespace WEX::Common; @@ -67,27 +68,27 @@ namespace TerminalAppLocalTests const auto profile2Json = VerifyParseSucceeded(profile2String); const auto profile3Json = VerifyParseSucceeded(profile3String); - const auto profile0 = Profile::FromJson(profile0Json); + const auto profile0 = implementation::Profile::FromJson(profile0Json); - VERIFY_IS_FALSE(profile0.ShouldBeLayered(profile1Json)); - VERIFY_IS_TRUE(profile0.ShouldBeLayered(profile2Json)); - VERIFY_IS_FALSE(profile0.ShouldBeLayered(profile3Json)); + VERIFY_IS_FALSE(profile0->ShouldBeLayered(profile1Json)); + VERIFY_IS_TRUE(profile0->ShouldBeLayered(profile2Json)); + VERIFY_IS_FALSE(profile0->ShouldBeLayered(profile3Json)); - const auto profile1 = Profile::FromJson(profile1Json); + const auto profile1 = implementation::Profile::FromJson(profile1Json); - VERIFY_IS_FALSE(profile1.ShouldBeLayered(profile0Json)); + VERIFY_IS_FALSE(profile1->ShouldBeLayered(profile0Json)); // A profile _can_ be layered with itself, though what's the point? - VERIFY_IS_TRUE(profile1.ShouldBeLayered(profile1Json)); - VERIFY_IS_FALSE(profile1.ShouldBeLayered(profile2Json)); - VERIFY_IS_FALSE(profile1.ShouldBeLayered(profile3Json)); + VERIFY_IS_TRUE(profile1->ShouldBeLayered(profile1Json)); + VERIFY_IS_FALSE(profile1->ShouldBeLayered(profile2Json)); + VERIFY_IS_FALSE(profile1->ShouldBeLayered(profile3Json)); - const auto profile3 = Profile::FromJson(profile3Json); + const auto profile3 = implementation::Profile::FromJson(profile3Json); - VERIFY_IS_FALSE(profile3.ShouldBeLayered(profile0Json)); + VERIFY_IS_FALSE(profile3->ShouldBeLayered(profile0Json)); // A profile _can_ be layered with itself, though what's the point? - VERIFY_IS_FALSE(profile3.ShouldBeLayered(profile1Json)); - VERIFY_IS_FALSE(profile3.ShouldBeLayered(profile2Json)); - VERIFY_IS_FALSE(profile3.ShouldBeLayered(profile3Json)); + VERIFY_IS_FALSE(profile3->ShouldBeLayered(profile1Json)); + VERIFY_IS_FALSE(profile3->ShouldBeLayered(profile2Json)); + VERIFY_IS_FALSE(profile3->ShouldBeLayered(profile3Json)); } void ProfileTests::LayerProfileProperties() @@ -116,55 +117,55 @@ namespace TerminalAppLocalTests const auto profile1Json = VerifyParseSucceeded(profile1String); const auto profile2Json = VerifyParseSucceeded(profile2String); - auto profile0 = Profile::FromJson(profile0Json); - VERIFY_IS_TRUE(profile0._defaultForeground.has_value()); - VERIFY_ARE_EQUAL(ARGB(0, 0, 0, 0), profile0._defaultForeground.value()); + auto profile0 = implementation::Profile::FromJson(profile0Json); + VERIFY_IS_NOT_NULL(profile0->Foreground()); + VERIFY_ARE_EQUAL(til::color(0, 0, 0, 0), til::color{ profile0->Foreground().Value() }); - VERIFY_IS_TRUE(profile0._defaultBackground.has_value()); - VERIFY_ARE_EQUAL(ARGB(0, 1, 1, 1), profile0._defaultBackground.value()); + VERIFY_IS_NOT_NULL(profile0->Background()); + VERIFY_ARE_EQUAL(til::color(1, 1, 1, 0), til::color{ profile0->Background().Value() }); - VERIFY_IS_TRUE(profile0._selectionBackground.has_value()); - VERIFY_ARE_EQUAL(ARGB(0, 1, 1, 1), profile0._selectionBackground.value()); + VERIFY_IS_NOT_NULL(profile0->SelectionBackground()); + VERIFY_ARE_EQUAL(til::color(1, 1, 1, 0), til::color{ profile0->SelectionBackground().Value() }); - VERIFY_ARE_EQUAL(L"profile0", profile0._name); + VERIFY_ARE_EQUAL(L"profile0", profile0->Name()); - VERIFY_IS_FALSE(profile0._startingDirectory.has_value()); + VERIFY_IS_TRUE(profile0->StartingDirectory().empty()); Log::Comment(NoThrowString().Format( L"Layering profile1 on top of profile0")); - profile0.LayerJson(profile1Json); + profile0->LayerJson(profile1Json); - VERIFY_IS_TRUE(profile0._defaultForeground.has_value()); - VERIFY_ARE_EQUAL(ARGB(0, 2, 2, 2), profile0._defaultForeground.value()); + VERIFY_IS_NOT_NULL(profile0->Foreground()); + VERIFY_ARE_EQUAL(til::color(2, 2, 2, 0), til::color{ profile0->Foreground().Value() }); - VERIFY_IS_TRUE(profile0._defaultBackground.has_value()); - VERIFY_ARE_EQUAL(ARGB(0, 1, 1, 1), profile0._defaultBackground.value()); + VERIFY_IS_NOT_NULL(profile0->Background()); + VERIFY_ARE_EQUAL(til::color(1, 1, 1, 0), til::color{ profile0->Background().Value() }); - VERIFY_IS_TRUE(profile0._selectionBackground.has_value()); - VERIFY_ARE_EQUAL(ARGB(0, 1, 1, 1), profile0._selectionBackground.value()); + VERIFY_IS_NOT_NULL(profile0->Background()); + VERIFY_ARE_EQUAL(til::color(1, 1, 1, 0), til::color{ profile0->Background().Value() }); - VERIFY_ARE_EQUAL(L"profile1", profile0._name); + VERIFY_ARE_EQUAL(L"profile1", profile0->Name()); - VERIFY_IS_TRUE(profile0._startingDirectory.has_value()); - VERIFY_ARE_EQUAL(L"C:/", profile0._startingDirectory.value()); + VERIFY_IS_FALSE(profile0->StartingDirectory().empty()); + VERIFY_ARE_EQUAL(L"C:/", profile0->StartingDirectory()); Log::Comment(NoThrowString().Format( L"Layering profile2 on top of (profile0+profile1)")); - profile0.LayerJson(profile2Json); + profile0->LayerJson(profile2Json); - VERIFY_IS_TRUE(profile0._defaultForeground.has_value()); - VERIFY_ARE_EQUAL(ARGB(0, 3, 3, 3), profile0._defaultForeground.value()); + VERIFY_IS_NOT_NULL(profile0->Foreground()); + VERIFY_ARE_EQUAL(til::color(3, 3, 3, 0), til::color{ profile0->Foreground().Value() }); - VERIFY_IS_TRUE(profile0._defaultBackground.has_value()); - VERIFY_ARE_EQUAL(ARGB(0, 1, 1, 1), profile0._defaultBackground.value()); + VERIFY_IS_NOT_NULL(profile0->Background()); + VERIFY_ARE_EQUAL(til::color(1, 1, 1, 0), til::color{ profile0->Background().Value() }); - VERIFY_IS_TRUE(profile0._selectionBackground.has_value()); - VERIFY_ARE_EQUAL(ARGB(0, 2, 2, 2), profile0._selectionBackground.value()); + VERIFY_IS_NOT_NULL(profile0->SelectionBackground()); + VERIFY_ARE_EQUAL(til::color(2, 2, 2, 0), til::color{ profile0->SelectionBackground().Value() }); - VERIFY_ARE_EQUAL(L"profile2", profile0._name); + VERIFY_ARE_EQUAL(L"profile2", profile0->Name()); - VERIFY_IS_TRUE(profile0._startingDirectory.has_value()); - VERIFY_ARE_EQUAL(L"C:/", profile0._startingDirectory.value()); + VERIFY_IS_FALSE(profile0->StartingDirectory().empty()); + VERIFY_ARE_EQUAL(L"C:/", profile0->StartingDirectory()); } void ProfileTests::LayerProfileIcon() @@ -194,33 +195,33 @@ namespace TerminalAppLocalTests const auto profile2Json = VerifyParseSucceeded(profile2String); const auto profile3Json = VerifyParseSucceeded(profile3String); - auto profile0 = Profile::FromJson(profile0Json); - VERIFY_IS_TRUE(profile0._icon.has_value()); - VERIFY_ARE_EQUAL(L"not-null.png", profile0._icon.value()); + auto profile0 = implementation::Profile::FromJson(profile0Json); + VERIFY_IS_FALSE(profile0->IconPath().empty()); + VERIFY_ARE_EQUAL(L"not-null.png", profile0->IconPath()); Log::Comment(NoThrowString().Format( L"Verify that layering an object the key set to null will clear the key")); - profile0.LayerJson(profile1Json); - VERIFY_IS_FALSE(profile0._icon.has_value()); + profile0->LayerJson(profile1Json); + VERIFY_IS_TRUE(profile0->IconPath().empty()); - profile0.LayerJson(profile2Json); - VERIFY_IS_FALSE(profile0._icon.has_value()); + profile0->LayerJson(profile2Json); + VERIFY_IS_TRUE(profile0->IconPath().empty()); - profile0.LayerJson(profile3Json); - VERIFY_IS_TRUE(profile0._icon.has_value()); - VERIFY_ARE_EQUAL(L"another-real.png", profile0._icon.value()); + profile0->LayerJson(profile3Json); + VERIFY_IS_FALSE(profile0->IconPath().empty()); + VERIFY_ARE_EQUAL(L"another-real.png", profile0->IconPath()); Log::Comment(NoThrowString().Format( L"Verify that layering an object _without_ the key will not clear the key")); - profile0.LayerJson(profile2Json); - VERIFY_IS_TRUE(profile0._icon.has_value()); - VERIFY_ARE_EQUAL(L"another-real.png", profile0._icon.value()); - - auto profile1 = Profile::FromJson(profile1Json); - VERIFY_IS_FALSE(profile1._icon.has_value()); - profile1.LayerJson(profile3Json); - VERIFY_IS_TRUE(profile1._icon.has_value()); - VERIFY_ARE_EQUAL(L"another-real.png", profile1._icon.value()); + profile0->LayerJson(profile2Json); + VERIFY_IS_FALSE(profile0->IconPath().empty()); + VERIFY_ARE_EQUAL(L"another-real.png", profile0->IconPath()); + + auto profile1 = implementation::Profile::FromJson(profile1Json); + VERIFY_IS_TRUE(profile1->IconPath().empty()); + profile1->LayerJson(profile3Json); + VERIFY_IS_FALSE(profile1->IconPath().empty()); + VERIFY_ARE_EQUAL(L"another-real.png", profile1->IconPath()); } void ProfileTests::LayerProfilesOnArray() @@ -284,7 +285,7 @@ namespace TerminalAppLocalTests VERIFY_IS_NOT_NULL(settings._FindMatchingProfile(profile2Json)); VERIFY_IS_NOT_NULL(settings._FindMatchingProfile(profile3Json)); VERIFY_IS_NOT_NULL(settings._FindMatchingProfile(profile4Json)); - VERIFY_ARE_EQUAL(L"profile0", settings._profiles.at(0)._name); + VERIFY_ARE_EQUAL(L"profile0", settings._profiles.at(0).Name()); settings._LayerOrCreateProfile(profile3Json); VERIFY_ARE_EQUAL(3u, settings._profiles.size()); @@ -293,7 +294,7 @@ namespace TerminalAppLocalTests VERIFY_IS_NOT_NULL(settings._FindMatchingProfile(profile2Json)); VERIFY_IS_NOT_NULL(settings._FindMatchingProfile(profile3Json)); VERIFY_IS_NOT_NULL(settings._FindMatchingProfile(profile4Json)); - VERIFY_ARE_EQUAL(L"profile3", settings._profiles.at(0)._name); + VERIFY_ARE_EQUAL(L"profile3", settings._profiles.at(0).Name()); settings._LayerOrCreateProfile(profile4Json); VERIFY_ARE_EQUAL(3u, settings._profiles.size()); @@ -302,7 +303,7 @@ namespace TerminalAppLocalTests VERIFY_IS_NOT_NULL(settings._FindMatchingProfile(profile2Json)); VERIFY_IS_NOT_NULL(settings._FindMatchingProfile(profile3Json)); VERIFY_IS_NOT_NULL(settings._FindMatchingProfile(profile4Json)); - VERIFY_ARE_EQUAL(L"profile4", settings._profiles.at(0)._name); + VERIFY_ARE_EQUAL(L"profile4", settings._profiles.at(0).Name()); } } diff --git a/src/cascadia/LocalTests_TerminalApp/SettingsTests.cpp b/src/cascadia/LocalTests_TerminalApp/SettingsTests.cpp index f72229526c0..e1dad5b8905 100644 --- a/src/cascadia/LocalTests_TerminalApp/SettingsTests.cpp +++ b/src/cascadia/LocalTests_TerminalApp/SettingsTests.cpp @@ -274,7 +274,7 @@ namespace TerminalAppLocalTests settings->_ValidateDefaultProfileExists(); VERIFY_ARE_EQUAL(static_cast(0), settings->_warnings.size()); VERIFY_ARE_EQUAL(static_cast(2), settings->_profiles.size()); - VERIFY_ARE_EQUAL(settings->_globals.DefaultProfile(), settings->_profiles.at(0).GetGuid()); + VERIFY_ARE_EQUAL(winrt::guid{ settings->_globals.DefaultProfile() }, settings->_profiles.at(0).Guid()); } { // Case 2: Bad settings @@ -288,7 +288,7 @@ namespace TerminalAppLocalTests VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::MissingDefaultProfile, settings->_warnings.at(0)); VERIFY_ARE_EQUAL(static_cast(2), settings->_profiles.size()); - VERIFY_ARE_EQUAL(settings->_globals.DefaultProfile(), settings->_profiles.at(0).GetGuid()); + VERIFY_ARE_EQUAL(winrt::guid{ settings->_globals.DefaultProfile() }, settings->_profiles.at(0).Guid()); } { // Case 2: Bad settings @@ -302,7 +302,7 @@ namespace TerminalAppLocalTests VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::MissingDefaultProfile, settings->_warnings.at(0)); VERIFY_ARE_EQUAL(static_cast(2), settings->_profiles.size()); - VERIFY_ARE_EQUAL(settings->_globals.DefaultProfile(), settings->_profiles.at(0).GetGuid()); + VERIFY_ARE_EQUAL(winrt::guid{ settings->_globals.DefaultProfile() }, settings->_profiles.at(0).Guid()); } { // Case 4: Good settings, default profile is a string @@ -314,7 +314,7 @@ namespace TerminalAppLocalTests settings->_ValidateDefaultProfileExists(); VERIFY_ARE_EQUAL(static_cast(0), settings->_warnings.size()); VERIFY_ARE_EQUAL(static_cast(2), settings->_profiles.size()); - VERIFY_ARE_EQUAL(settings->_globals.DefaultProfile(), settings->_profiles.at(1).GetGuid()); + VERIFY_ARE_EQUAL(winrt::guid{ settings->_globals.DefaultProfile() }, settings->_profiles.at(1).Guid()); } } @@ -381,20 +381,20 @@ namespace TerminalAppLocalTests } ] })" }; - Profile profile0{ Microsoft::Console::Utils::GuidFromString(L"{6239a42c-4444-49a3-80bd-e8fdd045185c}") }; - profile0._name = L"profile0"; - Profile profile1{ Microsoft::Console::Utils::GuidFromString(L"{6239a42c-5555-49a3-80bd-e8fdd045185c}") }; - profile1._name = L"profile1"; - Profile profile2{ Microsoft::Console::Utils::GuidFromString(L"{6239a42c-4444-49a3-80bd-e8fdd045185c}") }; - profile2._name = L"profile2"; - Profile profile3{ Microsoft::Console::Utils::GuidFromString(L"{6239a42c-4444-49a3-80bd-e8fdd045185c}") }; - profile3._name = L"profile3"; - Profile profile4{ Microsoft::Console::Utils::GuidFromString(L"{6239a42c-6666-49a3-80bd-e8fdd045185c}") }; - profile4._name = L"profile4"; - Profile profile5{ Microsoft::Console::Utils::GuidFromString(L"{6239a42c-5555-49a3-80bd-e8fdd045185c}") }; - profile5._name = L"profile5"; - Profile profile6{ Microsoft::Console::Utils::GuidFromString(L"{6239a42c-7777-49a3-80bd-e8fdd045185c}") }; - profile6._name = L"profile6"; + Profile profile0 = winrt::make(winrt::guid{ ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-4444-49a3-80bd-e8fdd045185c}") }); + profile0.Name(L"profile0"); + Profile profile1 = winrt::make(winrt::guid{ ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-5555-49a3-80bd-e8fdd045185c}") }); + profile1.Name(L"profile1"); + Profile profile2 = winrt::make(winrt::guid{ ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-4444-49a3-80bd-e8fdd045185c}") }); + profile2.Name(L"profile2"); + Profile profile3 = winrt::make(winrt::guid{ ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-4444-49a3-80bd-e8fdd045185c}") }); + profile3.Name(L"profile3"); + Profile profile4 = winrt::make(winrt::guid{ ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-6666-49a3-80bd-e8fdd045185c}") }); + profile4.Name(L"profile4"); + Profile profile5 = winrt::make(winrt::guid{ ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-5555-49a3-80bd-e8fdd045185c}") }); + profile5.Name(L"profile5"); + Profile profile6 = winrt::make(winrt::guid{ ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-7777-49a3-80bd-e8fdd045185c}") }); + profile6.Name(L"profile6"); { // Case 1: Good settings @@ -425,7 +425,7 @@ namespace TerminalAppLocalTests VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::DuplicateProfile, settings._warnings.at(0)); VERIFY_ARE_EQUAL(static_cast(1), settings._profiles.size()); - VERIFY_ARE_EQUAL(L"profile2", settings._profiles.at(0).GetName()); + VERIFY_ARE_EQUAL(L"profile2", settings._profiles.at(0).Name()); } { // Case 3: Very bad settings @@ -447,10 +447,10 @@ namespace TerminalAppLocalTests VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::DuplicateProfile, settings._warnings.at(0)); VERIFY_ARE_EQUAL(static_cast(4), settings._profiles.size()); - VERIFY_ARE_EQUAL(L"profile0", settings._profiles.at(0).GetName()); - VERIFY_ARE_EQUAL(L"profile1", settings._profiles.at(1).GetName()); - VERIFY_ARE_EQUAL(L"profile4", settings._profiles.at(2).GetName()); - VERIFY_ARE_EQUAL(L"profile6", settings._profiles.at(3).GetName()); + VERIFY_ARE_EQUAL(L"profile0", settings._profiles.at(0).Name()); + VERIFY_ARE_EQUAL(L"profile1", settings._profiles.at(1).Name()); + VERIFY_ARE_EQUAL(L"profile4", settings._profiles.at(2).Name()); + VERIFY_ARE_EQUAL(L"profile6", settings._profiles.at(3).Name()); } } @@ -474,10 +474,10 @@ namespace TerminalAppLocalTests } ] })" }; - Profile profile4{ Microsoft::Console::Utils::GuidFromString(L"{6239a42c-4444-49a3-80bd-e8fdd045185c}") }; - profile4._name = L"profile4"; - Profile profile5{ Microsoft::Console::Utils::GuidFromString(L"{6239a42c-4444-49a3-80bd-e8fdd045185c}") }; - profile5._name = L"profile5"; + Profile profile4 = winrt::make(winrt::guid{ ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-4444-49a3-80bd-e8fdd045185c}") }); + profile4.Name(L"profile4"); + Profile profile5 = winrt::make(winrt::guid{ ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-4444-49a3-80bd-e8fdd045185c}") }); + profile5.Name(L"profile5"); // Case 2: Bad settings Log::Comment(NoThrowString().Format( @@ -496,10 +496,10 @@ namespace TerminalAppLocalTests VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::UnknownColorScheme, settings->_warnings.at(2)); VERIFY_ARE_EQUAL(3u, settings->_profiles.size()); - VERIFY_ARE_EQUAL(settings->_globals.DefaultProfile(), settings->_profiles.at(0).GetGuid()); - VERIFY_IS_TRUE(settings->_profiles.at(0)._guid.has_value()); - VERIFY_IS_TRUE(settings->_profiles.at(1)._guid.has_value()); - VERIFY_IS_TRUE(settings->_profiles.at(2)._guid.has_value()); + VERIFY_ARE_EQUAL(winrt::guid{ settings->_globals.DefaultProfile() }, settings->_profiles.at(0).Guid()); + VERIFY_IS_TRUE(settings->_profiles.at(0).HasGuid()); + VERIFY_IS_TRUE(settings->_profiles.at(1).HasGuid()); + VERIFY_IS_TRUE(settings->_profiles.at(2).HasGuid()); } void SettingsTests::LayerGlobalProperties() @@ -591,19 +591,19 @@ namespace TerminalAppLocalTests settings._ParseJsonString(defaultProfilesString, true); settings.LayerJson(settings._defaultSettings); VERIFY_ARE_EQUAL(2u, settings._profiles.size()); - VERIFY_ARE_EQUAL(L"profile2", settings._profiles.at(0)._name); - VERIFY_ARE_EQUAL(L"profile3", settings._profiles.at(1)._name); + VERIFY_ARE_EQUAL(L"profile2", settings._profiles.at(0).Name()); + VERIFY_ARE_EQUAL(L"profile3", settings._profiles.at(1).Name()); settings._ParseJsonString(userProfiles0String, false); settings.LayerJson(settings._userSettings); VERIFY_ARE_EQUAL(2u, settings._profiles.size()); - VERIFY_ARE_EQUAL(L"profile1", settings._profiles.at(0)._name); - VERIFY_ARE_EQUAL(L"profile0", settings._profiles.at(1)._name); + VERIFY_ARE_EQUAL(L"profile1", settings._profiles.at(0).Name()); + VERIFY_ARE_EQUAL(L"profile0", settings._profiles.at(1).Name()); settings._ReorderProfilesToMatchUserSettingsOrder(); VERIFY_ARE_EQUAL(2u, settings._profiles.size()); - VERIFY_ARE_EQUAL(L"profile0", settings._profiles.at(0)._name); - VERIFY_ARE_EQUAL(L"profile1", settings._profiles.at(1)._name); + VERIFY_ARE_EQUAL(L"profile0", settings._profiles.at(0).Name()); + VERIFY_ARE_EQUAL(L"profile1", settings._profiles.at(1).Name()); } { @@ -614,21 +614,21 @@ namespace TerminalAppLocalTests settings._ParseJsonString(defaultProfilesString, true); settings.LayerJson(settings._defaultSettings); VERIFY_ARE_EQUAL(2u, settings._profiles.size()); - VERIFY_ARE_EQUAL(L"profile2", settings._profiles.at(0)._name); - VERIFY_ARE_EQUAL(L"profile3", settings._profiles.at(1)._name); + VERIFY_ARE_EQUAL(L"profile2", settings._profiles.at(0).Name()); + VERIFY_ARE_EQUAL(L"profile3", settings._profiles.at(1).Name()); settings._ParseJsonString(userProfiles1String, false); settings.LayerJson(settings._userSettings); VERIFY_ARE_EQUAL(3u, settings._profiles.size()); - VERIFY_ARE_EQUAL(L"profile2", settings._profiles.at(0)._name); - VERIFY_ARE_EQUAL(L"profile4", settings._profiles.at(1)._name); - VERIFY_ARE_EQUAL(L"profile5", settings._profiles.at(2)._name); + VERIFY_ARE_EQUAL(L"profile2", settings._profiles.at(0).Name()); + VERIFY_ARE_EQUAL(L"profile4", settings._profiles.at(1).Name()); + VERIFY_ARE_EQUAL(L"profile5", settings._profiles.at(2).Name()); settings._ReorderProfilesToMatchUserSettingsOrder(); VERIFY_ARE_EQUAL(3u, settings._profiles.size()); - VERIFY_ARE_EQUAL(L"profile4", settings._profiles.at(0)._name); - VERIFY_ARE_EQUAL(L"profile5", settings._profiles.at(1)._name); - VERIFY_ARE_EQUAL(L"profile2", settings._profiles.at(2)._name); + VERIFY_ARE_EQUAL(L"profile4", settings._profiles.at(0).Name()); + VERIFY_ARE_EQUAL(L"profile5", settings._profiles.at(1).Name()); + VERIFY_ARE_EQUAL(L"profile2", settings._profiles.at(2).Name()); } } @@ -692,24 +692,24 @@ namespace TerminalAppLocalTests settings._ParseJsonString(defaultProfilesString, true); settings.LayerJson(settings._defaultSettings); VERIFY_ARE_EQUAL(2u, settings._profiles.size()); - VERIFY_ARE_EQUAL(L"profile2", settings._profiles.at(0)._name); - VERIFY_ARE_EQUAL(L"profile3", settings._profiles.at(1)._name); - VERIFY_ARE_EQUAL(false, settings._profiles.at(0)._hidden); - VERIFY_ARE_EQUAL(false, settings._profiles.at(1)._hidden); + VERIFY_ARE_EQUAL(L"profile2", settings._profiles.at(0).Name()); + VERIFY_ARE_EQUAL(L"profile3", settings._profiles.at(1).Name()); + VERIFY_ARE_EQUAL(false, settings._profiles.at(0).Hidden()); + VERIFY_ARE_EQUAL(false, settings._profiles.at(1).Hidden()); settings._ParseJsonString(userProfiles0String, false); settings.LayerJson(settings._userSettings); VERIFY_ARE_EQUAL(2u, settings._profiles.size()); - VERIFY_ARE_EQUAL(L"profile1", settings._profiles.at(0)._name); - VERIFY_ARE_EQUAL(L"profile0", settings._profiles.at(1)._name); - VERIFY_ARE_EQUAL(false, settings._profiles.at(0)._hidden); - VERIFY_ARE_EQUAL(true, settings._profiles.at(1)._hidden); + VERIFY_ARE_EQUAL(L"profile1", settings._profiles.at(0).Name()); + VERIFY_ARE_EQUAL(L"profile0", settings._profiles.at(1).Name()); + VERIFY_ARE_EQUAL(false, settings._profiles.at(0).Hidden()); + VERIFY_ARE_EQUAL(true, settings._profiles.at(1).Hidden()); settings._ReorderProfilesToMatchUserSettingsOrder(); settings._RemoveHiddenProfiles(); VERIFY_ARE_EQUAL(1u, settings._profiles.size()); - VERIFY_ARE_EQUAL(L"profile1", settings._profiles.at(0)._name); - VERIFY_ARE_EQUAL(false, settings._profiles.at(0)._hidden); + VERIFY_ARE_EQUAL(L"profile1", settings._profiles.at(0).Name()); + VERIFY_ARE_EQUAL(false, settings._profiles.at(0).Hidden()); } { @@ -717,30 +717,30 @@ namespace TerminalAppLocalTests settings._ParseJsonString(defaultProfilesString, true); settings.LayerJson(settings._defaultSettings); VERIFY_ARE_EQUAL(2u, settings._profiles.size()); - VERIFY_ARE_EQUAL(L"profile2", settings._profiles.at(0)._name); - VERIFY_ARE_EQUAL(L"profile3", settings._profiles.at(1)._name); - VERIFY_ARE_EQUAL(false, settings._profiles.at(0)._hidden); - VERIFY_ARE_EQUAL(false, settings._profiles.at(1)._hidden); + VERIFY_ARE_EQUAL(L"profile2", settings._profiles.at(0).Name()); + VERIFY_ARE_EQUAL(L"profile3", settings._profiles.at(1).Name()); + VERIFY_ARE_EQUAL(false, settings._profiles.at(0).Hidden()); + VERIFY_ARE_EQUAL(false, settings._profiles.at(1).Hidden()); settings._ParseJsonString(userProfiles1String, false); settings.LayerJson(settings._userSettings); VERIFY_ARE_EQUAL(4u, settings._profiles.size()); - VERIFY_ARE_EQUAL(L"profile2", settings._profiles.at(0)._name); - VERIFY_ARE_EQUAL(L"profile4", settings._profiles.at(1)._name); - VERIFY_ARE_EQUAL(L"profile5", settings._profiles.at(2)._name); - VERIFY_ARE_EQUAL(L"profile6", settings._profiles.at(3)._name); - VERIFY_ARE_EQUAL(false, settings._profiles.at(0)._hidden); - VERIFY_ARE_EQUAL(true, settings._profiles.at(1)._hidden); - VERIFY_ARE_EQUAL(false, settings._profiles.at(2)._hidden); - VERIFY_ARE_EQUAL(true, settings._profiles.at(3)._hidden); + VERIFY_ARE_EQUAL(L"profile2", settings._profiles.at(0).Name()); + VERIFY_ARE_EQUAL(L"profile4", settings._profiles.at(1).Name()); + VERIFY_ARE_EQUAL(L"profile5", settings._profiles.at(2).Name()); + VERIFY_ARE_EQUAL(L"profile6", settings._profiles.at(3).Name()); + VERIFY_ARE_EQUAL(false, settings._profiles.at(0).Hidden()); + VERIFY_ARE_EQUAL(true, settings._profiles.at(1).Hidden()); + VERIFY_ARE_EQUAL(false, settings._profiles.at(2).Hidden()); + VERIFY_ARE_EQUAL(true, settings._profiles.at(3).Hidden()); settings._ReorderProfilesToMatchUserSettingsOrder(); settings._RemoveHiddenProfiles(); VERIFY_ARE_EQUAL(2u, settings._profiles.size()); - VERIFY_ARE_EQUAL(L"profile5", settings._profiles.at(0)._name); - VERIFY_ARE_EQUAL(L"profile2", settings._profiles.at(1)._name); - VERIFY_ARE_EQUAL(false, settings._profiles.at(0)._hidden); - VERIFY_ARE_EQUAL(false, settings._profiles.at(1)._hidden); + VERIFY_ARE_EQUAL(L"profile5", settings._profiles.at(0).Name()); + VERIFY_ARE_EQUAL(L"profile2", settings._profiles.at(1).Name()); + VERIFY_ARE_EQUAL(false, settings._profiles.at(0).Hidden()); + VERIFY_ARE_EQUAL(false, settings._profiles.at(1).Hidden()); } } @@ -781,62 +781,62 @@ namespace TerminalAppLocalTests const auto profile4Json = VerifyParseSucceeded(profile4String); const auto profile5Json = VerifyParseSucceeded(profile5String); - const auto profile0 = Profile::FromJson(profile0Json); - const auto profile1 = Profile::FromJson(profile1Json); - const auto profile2 = Profile::FromJson(profile2Json); - const auto profile3 = Profile::FromJson(profile3Json); - const auto profile4 = Profile::FromJson(profile4Json); - const auto profile5 = Profile::FromJson(profile5Json); + const auto profile0 = implementation::Profile::FromJson(profile0Json); + const auto profile1 = implementation::Profile::FromJson(profile1Json); + const auto profile2 = implementation::Profile::FromJson(profile2Json); + const auto profile3 = implementation::Profile::FromJson(profile3Json); + const auto profile4 = implementation::Profile::FromJson(profile4Json); + const auto profile5 = implementation::Profile::FromJson(profile5Json); - const GUID cmdGuid = Utils::GuidFromString(L"{6239a42c-1de4-49a3-80bd-e8fdd045185c}"); - const GUID nullGuid{ 0 }; + const winrt::guid cmdGuid{ Utils::GuidFromString(L"{6239a42c-1de4-49a3-80bd-e8fdd045185c}") }; + const winrt::guid nullGuid{}; - VERIFY_IS_FALSE(profile0._guid.has_value()); - VERIFY_IS_FALSE(profile1._guid.has_value()); - VERIFY_IS_FALSE(profile2._guid.has_value()); - VERIFY_IS_TRUE(profile3._guid.has_value()); - VERIFY_IS_TRUE(profile4._guid.has_value()); - VERIFY_IS_FALSE(profile5._guid.has_value()); + VERIFY_IS_FALSE(profile0->HasGuid()); + VERIFY_IS_FALSE(profile1->HasGuid()); + VERIFY_IS_FALSE(profile2->HasGuid()); + VERIFY_IS_TRUE(profile3->HasGuid()); + VERIFY_IS_TRUE(profile4->HasGuid()); + VERIFY_IS_FALSE(profile5->HasGuid()); - VERIFY_ARE_EQUAL(profile3.GetGuid(), nullGuid); - VERIFY_ARE_EQUAL(profile4.GetGuid(), cmdGuid); + VERIFY_ARE_EQUAL(profile3->Guid(), nullGuid); + VERIFY_ARE_EQUAL(profile4->Guid(), cmdGuid); CascadiaSettings settings; - settings._profiles.emplace_back(profile0); - settings._profiles.emplace_back(profile1); - settings._profiles.emplace_back(profile2); - settings._profiles.emplace_back(profile3); - settings._profiles.emplace_back(profile4); - settings._profiles.emplace_back(profile5); + settings._profiles.emplace_back(profile0.as()); + settings._profiles.emplace_back(profile1.as()); + settings._profiles.emplace_back(profile2.as()); + settings._profiles.emplace_back(profile3.as()); + settings._profiles.emplace_back(profile4.as()); + settings._profiles.emplace_back(profile5.as()); settings._ValidateProfilesHaveGuid(); - VERIFY_IS_TRUE(settings._profiles.at(0)._guid.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(1)._guid.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(2)._guid.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(3)._guid.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(4)._guid.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(5)._guid.has_value()); - - VERIFY_ARE_NOT_EQUAL(settings._profiles.at(0).GetGuid(), nullGuid); - VERIFY_ARE_NOT_EQUAL(settings._profiles.at(1).GetGuid(), nullGuid); - VERIFY_ARE_NOT_EQUAL(settings._profiles.at(2).GetGuid(), nullGuid); - VERIFY_ARE_EQUAL(settings._profiles.at(3).GetGuid(), nullGuid); - VERIFY_ARE_NOT_EQUAL(settings._profiles.at(4).GetGuid(), nullGuid); - VERIFY_ARE_NOT_EQUAL(settings._profiles.at(5).GetGuid(), nullGuid); - - VERIFY_ARE_NOT_EQUAL(settings._profiles.at(0).GetGuid(), cmdGuid); - VERIFY_ARE_NOT_EQUAL(settings._profiles.at(1).GetGuid(), cmdGuid); - VERIFY_ARE_NOT_EQUAL(settings._profiles.at(2).GetGuid(), cmdGuid); - VERIFY_ARE_NOT_EQUAL(settings._profiles.at(3).GetGuid(), cmdGuid); - VERIFY_ARE_EQUAL(settings._profiles.at(4).GetGuid(), cmdGuid); - VERIFY_ARE_NOT_EQUAL(settings._profiles.at(5).GetGuid(), cmdGuid); - - VERIFY_ARE_NOT_EQUAL(settings._profiles.at(0).GetGuid(), settings._profiles.at(2).GetGuid()); - VERIFY_ARE_NOT_EQUAL(settings._profiles.at(1).GetGuid(), settings._profiles.at(2).GetGuid()); - VERIFY_ARE_EQUAL(settings._profiles.at(2).GetGuid(), settings._profiles.at(2).GetGuid()); - VERIFY_ARE_NOT_EQUAL(settings._profiles.at(3).GetGuid(), settings._profiles.at(2).GetGuid()); - VERIFY_ARE_NOT_EQUAL(settings._profiles.at(4).GetGuid(), settings._profiles.at(2).GetGuid()); - VERIFY_ARE_EQUAL(settings._profiles.at(5).GetGuid(), settings._profiles.at(2).GetGuid()); + VERIFY_IS_TRUE(settings._profiles.at(0).HasGuid()); + VERIFY_IS_TRUE(settings._profiles.at(1).HasGuid()); + VERIFY_IS_TRUE(settings._profiles.at(2).HasGuid()); + VERIFY_IS_TRUE(settings._profiles.at(3).HasGuid()); + VERIFY_IS_TRUE(settings._profiles.at(4).HasGuid()); + VERIFY_IS_TRUE(settings._profiles.at(5).HasGuid()); + + VERIFY_ARE_NOT_EQUAL(settings._profiles.at(0).Guid(), nullGuid); + VERIFY_ARE_NOT_EQUAL(settings._profiles.at(1).Guid(), nullGuid); + VERIFY_ARE_NOT_EQUAL(settings._profiles.at(2).Guid(), nullGuid); + VERIFY_ARE_EQUAL(settings._profiles.at(3).Guid(), nullGuid); + VERIFY_ARE_NOT_EQUAL(settings._profiles.at(4).Guid(), nullGuid); + VERIFY_ARE_NOT_EQUAL(settings._profiles.at(5).Guid(), nullGuid); + + VERIFY_ARE_NOT_EQUAL(settings._profiles.at(0).Guid(), cmdGuid); + VERIFY_ARE_NOT_EQUAL(settings._profiles.at(1).Guid(), cmdGuid); + VERIFY_ARE_NOT_EQUAL(settings._profiles.at(2).Guid(), cmdGuid); + VERIFY_ARE_NOT_EQUAL(settings._profiles.at(3).Guid(), cmdGuid); + VERIFY_ARE_EQUAL(settings._profiles.at(4).Guid(), cmdGuid); + VERIFY_ARE_NOT_EQUAL(settings._profiles.at(5).Guid(), cmdGuid); + + VERIFY_ARE_NOT_EQUAL(settings._profiles.at(0).Guid(), settings._profiles.at(2).Guid()); + VERIFY_ARE_NOT_EQUAL(settings._profiles.at(1).Guid(), settings._profiles.at(2).Guid()); + VERIFY_ARE_EQUAL(settings._profiles.at(2).Guid(), settings._profiles.at(2).Guid()); + VERIFY_ARE_NOT_EQUAL(settings._profiles.at(3).Guid(), settings._profiles.at(2).Guid()); + VERIFY_ARE_NOT_EQUAL(settings._profiles.at(4).Guid(), settings._profiles.at(2).Guid()); + VERIFY_ARE_EQUAL(settings._profiles.at(5).Guid(), settings._profiles.at(2).Guid()); } void SettingsTests::GeneratedGuidRoundtrips() @@ -850,28 +850,29 @@ namespace TerminalAppLocalTests })" }; const auto profile0Json = VerifyParseSucceeded(profileWithoutGuid); - const auto profile0 = Profile::FromJson(profile0Json); + const auto profile0 = implementation::Profile::FromJson(profile0Json); const GUID nullGuid{ 0 }; - VERIFY_IS_FALSE(profile0._guid.has_value()); + VERIFY_IS_FALSE(profile0->HasGuid()); - const auto serialized0Profile = profile0.GenerateStub(); - const auto profile1 = Profile::FromJson(serialized0Profile); - VERIFY_IS_FALSE(profile0._guid.has_value()); - VERIFY_ARE_EQUAL(profile1._guid.has_value(), profile0._guid.has_value()); + const auto serialized0Profile = profile0->GenerateStub(); + const auto profile1 = implementation::Profile::FromJson(serialized0Profile); + VERIFY_IS_FALSE(profile0->HasGuid()); + VERIFY_IS_FALSE(profile1->HasGuid()); CascadiaSettings settings; - settings._profiles.emplace_back(profile1); + settings._profiles.emplace_back(profile1.as()); settings._ValidateProfilesHaveGuid(); - VERIFY_IS_TRUE(settings._profiles.at(0)._guid.has_value()); + VERIFY_IS_TRUE(settings._profiles.at(0).HasGuid()); - const auto serialized1Profile = settings._profiles.at(0).GenerateStub(); + const auto profileImpl = winrt::get_self(settings._profiles.at(0)); + const auto serialized1Profile = profileImpl->GenerateStub(); - const auto profile2 = Profile::FromJson(serialized1Profile); - VERIFY_IS_TRUE(settings._profiles.at(0)._guid.has_value()); - VERIFY_ARE_EQUAL(settings._profiles.at(0)._guid.has_value(), profile2._guid.has_value()); - VERIFY_ARE_EQUAL(settings._profiles.at(0).GetGuid(), profile2.GetGuid()); + const auto profile2 = implementation::Profile::FromJson(serialized1Profile); + VERIFY_IS_TRUE(settings._profiles.at(0).HasGuid()); + VERIFY_IS_TRUE(profile2->HasGuid()); + VERIFY_ARE_EQUAL(settings._profiles.at(0).Guid(), profile2->Guid()); } void SettingsTests::TestAllValidationsWithNullGuids() @@ -900,14 +901,14 @@ namespace TerminalAppLocalTests settings.LayerJson(settings._userSettings); VERIFY_ARE_EQUAL(2u, settings._profiles.size()); - VERIFY_IS_TRUE(settings._profiles.at(0)._guid.has_value()); - VERIFY_IS_FALSE(settings._profiles.at(1)._guid.has_value()); + VERIFY_IS_TRUE(settings._profiles.at(0).HasGuid()); + VERIFY_IS_FALSE(settings._profiles.at(1).HasGuid()); settings._ValidateSettings(); VERIFY_ARE_EQUAL(0u, settings._warnings.size()); VERIFY_ARE_EQUAL(2u, settings._profiles.size()); - VERIFY_IS_TRUE(settings._profiles.at(0)._guid.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(1)._guid.has_value()); + VERIFY_IS_TRUE(settings._profiles.at(0).HasGuid()); + VERIFY_IS_TRUE(settings._profiles.at(1).HasGuid()); } void SettingsTests::TestReorderWithNullGuids() @@ -936,35 +937,35 @@ namespace TerminalAppLocalTests settings._ParseJsonString(DefaultJson, true); settings.LayerJson(settings._defaultSettings); VERIFY_ARE_EQUAL(2u, settings._profiles.size()); - VERIFY_IS_TRUE(settings._profiles.at(0)._guid.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(1)._guid.has_value()); - VERIFY_ARE_EQUAL(L"Windows PowerShell", settings._profiles.at(0)._name); - VERIFY_ARE_EQUAL(L"Command Prompt", settings._profiles.at(1)._name); + VERIFY_IS_TRUE(settings._profiles.at(0).HasGuid()); + VERIFY_IS_TRUE(settings._profiles.at(1).HasGuid()); + VERIFY_ARE_EQUAL(L"Windows PowerShell", settings._profiles.at(0).Name()); + VERIFY_ARE_EQUAL(L"Command Prompt", settings._profiles.at(1).Name()); settings._ParseJsonString(settings0String, false); settings.LayerJson(settings._userSettings); VERIFY_ARE_EQUAL(4u, settings._profiles.size()); - VERIFY_IS_TRUE(settings._profiles.at(0)._guid.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(1)._guid.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(2)._guid.has_value()); - VERIFY_IS_FALSE(settings._profiles.at(3)._guid.has_value()); - VERIFY_ARE_EQUAL(L"Windows PowerShell", settings._profiles.at(0)._name); - VERIFY_ARE_EQUAL(L"cmdFromUserSettings", settings._profiles.at(1)._name); - VERIFY_ARE_EQUAL(L"profile0", settings._profiles.at(2)._name); - VERIFY_ARE_EQUAL(L"profile1", settings._profiles.at(3)._name); + VERIFY_IS_TRUE(settings._profiles.at(0).HasGuid()); + VERIFY_IS_TRUE(settings._profiles.at(1).HasGuid()); + VERIFY_IS_TRUE(settings._profiles.at(2).HasGuid()); + VERIFY_IS_FALSE(settings._profiles.at(3).HasGuid()); + VERIFY_ARE_EQUAL(L"Windows PowerShell", settings._profiles.at(0).Name()); + VERIFY_ARE_EQUAL(L"cmdFromUserSettings", settings._profiles.at(1).Name()); + VERIFY_ARE_EQUAL(L"profile0", settings._profiles.at(2).Name()); + VERIFY_ARE_EQUAL(L"profile1", settings._profiles.at(3).Name()); settings._ValidateSettings(); VERIFY_ARE_EQUAL(0u, settings._warnings.size()); VERIFY_ARE_EQUAL(4u, settings._profiles.size()); - VERIFY_IS_TRUE(settings._profiles.at(0)._guid.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(1)._guid.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(2)._guid.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(3)._guid.has_value()); - VERIFY_ARE_EQUAL(L"profile0", settings._profiles.at(0)._name); - VERIFY_ARE_EQUAL(L"profile1", settings._profiles.at(1)._name); - VERIFY_ARE_EQUAL(L"cmdFromUserSettings", settings._profiles.at(2)._name); - VERIFY_ARE_EQUAL(L"Windows PowerShell", settings._profiles.at(3)._name); + VERIFY_IS_TRUE(settings._profiles.at(0).HasGuid()); + VERIFY_IS_TRUE(settings._profiles.at(1).HasGuid()); + VERIFY_IS_TRUE(settings._profiles.at(2).HasGuid()); + VERIFY_IS_TRUE(settings._profiles.at(3).HasGuid()); + VERIFY_ARE_EQUAL(L"profile0", settings._profiles.at(0).Name()); + VERIFY_ARE_EQUAL(L"profile1", settings._profiles.at(1).Name()); + VERIFY_ARE_EQUAL(L"cmdFromUserSettings", settings._profiles.at(2).Name()); + VERIFY_ARE_EQUAL(L"Windows PowerShell", settings._profiles.at(3).Name()); } void SettingsTests::TestReorderingWithoutGuid() @@ -1037,35 +1038,35 @@ namespace TerminalAppLocalTests settings._ParseJsonString(DefaultJson, true); settings.LayerJson(settings._defaultSettings); VERIFY_ARE_EQUAL(2u, settings._profiles.size()); - VERIFY_IS_TRUE(settings._profiles.at(0)._guid.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(1)._guid.has_value()); - VERIFY_ARE_EQUAL(L"Windows PowerShell", settings._profiles.at(0)._name); - VERIFY_ARE_EQUAL(L"Command Prompt", settings._profiles.at(1)._name); + VERIFY_IS_TRUE(settings._profiles.at(0).HasGuid()); + VERIFY_IS_TRUE(settings._profiles.at(1).HasGuid()); + VERIFY_ARE_EQUAL(L"Windows PowerShell", settings._profiles.at(0).Name()); + VERIFY_ARE_EQUAL(L"Command Prompt", settings._profiles.at(1).Name()); settings._ParseJsonString(settings0String, false); settings.LayerJson(settings._userSettings); VERIFY_ARE_EQUAL(4u, settings._profiles.size()); - VERIFY_IS_TRUE(settings._profiles.at(0)._guid.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(1)._guid.has_value()); - VERIFY_IS_FALSE(settings._profiles.at(2)._guid.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(3)._guid.has_value()); - VERIFY_ARE_EQUAL(L"Windows PowerShell", settings._profiles.at(0)._name); - VERIFY_ARE_EQUAL(L"Command Prompt", settings._profiles.at(1)._name); - VERIFY_ARE_EQUAL(L"ThisProfileShouldNotCrash", settings._profiles.at(2)._name); - VERIFY_ARE_EQUAL(L"Ubuntu", settings._profiles.at(3)._name); + VERIFY_IS_TRUE(settings._profiles.at(0).HasGuid()); + VERIFY_IS_TRUE(settings._profiles.at(1).HasGuid()); + VERIFY_IS_FALSE(settings._profiles.at(2).HasGuid()); + VERIFY_IS_TRUE(settings._profiles.at(3).HasGuid()); + VERIFY_ARE_EQUAL(L"Windows PowerShell", settings._profiles.at(0).Name()); + VERIFY_ARE_EQUAL(L"Command Prompt", settings._profiles.at(1).Name()); + VERIFY_ARE_EQUAL(L"ThisProfileShouldNotCrash", settings._profiles.at(2).Name()); + VERIFY_ARE_EQUAL(L"Ubuntu", settings._profiles.at(3).Name()); settings._ValidateSettings(); VERIFY_ARE_EQUAL(0u, settings._warnings.size()); VERIFY_ARE_EQUAL(4u, settings._profiles.size()); - VERIFY_IS_TRUE(settings._profiles.at(0)._guid.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(1)._guid.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(2)._guid.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(3)._guid.has_value()); - VERIFY_ARE_EQUAL(L"Command Prompt", settings._profiles.at(0)._name); - VERIFY_ARE_EQUAL(L"ThisProfileShouldNotCrash", settings._profiles.at(1)._name); - VERIFY_ARE_EQUAL(L"Ubuntu", settings._profiles.at(2)._name); - VERIFY_ARE_EQUAL(L"Windows PowerShell", settings._profiles.at(3)._name); + VERIFY_IS_TRUE(settings._profiles.at(0).HasGuid()); + VERIFY_IS_TRUE(settings._profiles.at(1).HasGuid()); + VERIFY_IS_TRUE(settings._profiles.at(2).HasGuid()); + VERIFY_IS_TRUE(settings._profiles.at(3).HasGuid()); + VERIFY_ARE_EQUAL(L"Command Prompt", settings._profiles.at(0).Name()); + VERIFY_ARE_EQUAL(L"ThisProfileShouldNotCrash", settings._profiles.at(1).Name()); + VERIFY_ARE_EQUAL(L"Ubuntu", settings._profiles.at(2).Name()); + VERIFY_ARE_EQUAL(L"Windows PowerShell", settings._profiles.at(3).Name()); } void SettingsTests::TestLayeringNameOnlyProfiles() @@ -1098,10 +1099,10 @@ namespace TerminalAppLocalTests settings._ParseJsonString(DefaultJson, true); settings.LayerJson(settings._defaultSettings); VERIFY_ARE_EQUAL(2u, settings._profiles.size()); - VERIFY_IS_TRUE(settings._profiles.at(0)._guid.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(1)._guid.has_value()); - VERIFY_ARE_EQUAL(L"Windows PowerShell", settings._profiles.at(0)._name); - VERIFY_ARE_EQUAL(L"Command Prompt", settings._profiles.at(1)._name); + VERIFY_IS_TRUE(settings._profiles.at(0).HasGuid()); + VERIFY_IS_TRUE(settings._profiles.at(1).HasGuid()); + VERIFY_ARE_EQUAL(L"Windows PowerShell", settings._profiles.at(0).Name()); + VERIFY_ARE_EQUAL(L"Command Prompt", settings._profiles.at(1).Name()); Log::Comment(NoThrowString().Format( L"Parse the user settings")); @@ -1109,16 +1110,16 @@ namespace TerminalAppLocalTests settings.LayerJson(settings._userSettings); VERIFY_ARE_EQUAL(5u, settings._profiles.size()); - VERIFY_IS_TRUE(settings._profiles.at(0)._guid.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(1)._guid.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(2)._guid.has_value()); - VERIFY_IS_FALSE(settings._profiles.at(3)._guid.has_value()); - VERIFY_IS_FALSE(settings._profiles.at(4)._guid.has_value()); - VERIFY_ARE_EQUAL(L"Windows PowerShell", settings._profiles.at(0)._name); - VERIFY_ARE_EQUAL(L"Command Prompt", settings._profiles.at(1)._name); - VERIFY_ARE_EQUAL(L"ThisProfileIsGood", settings._profiles.at(2)._name); - VERIFY_ARE_EQUAL(L"ThisProfileShouldNotLayer", settings._profiles.at(3)._name); - VERIFY_ARE_EQUAL(L"NeitherShouldThisOne", settings._profiles.at(4)._name); + VERIFY_IS_TRUE(settings._profiles.at(0).HasGuid()); + VERIFY_IS_TRUE(settings._profiles.at(1).HasGuid()); + VERIFY_IS_TRUE(settings._profiles.at(2).HasGuid()); + VERIFY_IS_FALSE(settings._profiles.at(3).HasGuid()); + VERIFY_IS_FALSE(settings._profiles.at(4).HasGuid()); + VERIFY_ARE_EQUAL(L"Windows PowerShell", settings._profiles.at(0).Name()); + VERIFY_ARE_EQUAL(L"Command Prompt", settings._profiles.at(1).Name()); + VERIFY_ARE_EQUAL(L"ThisProfileIsGood", settings._profiles.at(2).Name()); + VERIFY_ARE_EQUAL(L"ThisProfileShouldNotLayer", settings._profiles.at(3).Name()); + VERIFY_ARE_EQUAL(L"NeitherShouldThisOne", settings._profiles.at(4).Name()); } void SettingsTests::TestExplodingNameOnlyProfiles() @@ -1151,10 +1152,10 @@ namespace TerminalAppLocalTests settings._ParseJsonString(DefaultJson, true); settings.LayerJson(settings._defaultSettings); VERIFY_ARE_EQUAL(2u, settings._profiles.size()); - VERIFY_IS_TRUE(settings._profiles.at(0)._guid.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(1)._guid.has_value()); - VERIFY_ARE_EQUAL(L"Windows PowerShell", settings._profiles.at(0)._name); - VERIFY_ARE_EQUAL(L"Command Prompt", settings._profiles.at(1)._name); + VERIFY_IS_TRUE(settings._profiles.at(0).HasGuid()); + VERIFY_IS_TRUE(settings._profiles.at(1).HasGuid()); + VERIFY_ARE_EQUAL(L"Windows PowerShell", settings._profiles.at(0).Name()); + VERIFY_ARE_EQUAL(L"Command Prompt", settings._profiles.at(1).Name()); Log::Comment(NoThrowString().Format( L"Parse the user settings")); @@ -1162,16 +1163,16 @@ namespace TerminalAppLocalTests settings.LayerJson(settings._userSettings); VERIFY_ARE_EQUAL(5u, settings._profiles.size()); - VERIFY_IS_TRUE(settings._profiles.at(0)._guid.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(1)._guid.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(2)._guid.has_value()); - VERIFY_IS_FALSE(settings._profiles.at(3)._guid.has_value()); - VERIFY_IS_FALSE(settings._profiles.at(4)._guid.has_value()); - VERIFY_ARE_EQUAL(L"Windows PowerShell", settings._profiles.at(0)._name); - VERIFY_ARE_EQUAL(L"Command Prompt", settings._profiles.at(1)._name); - VERIFY_ARE_EQUAL(L"ThisProfileIsGood", settings._profiles.at(2)._name); - VERIFY_ARE_EQUAL(L"ThisProfileShouldNotDuplicate", settings._profiles.at(3)._name); - VERIFY_ARE_EQUAL(L"NeitherShouldThisOne", settings._profiles.at(4)._name); + VERIFY_IS_TRUE(settings._profiles.at(0).HasGuid()); + VERIFY_IS_TRUE(settings._profiles.at(1).HasGuid()); + VERIFY_IS_TRUE(settings._profiles.at(2).HasGuid()); + VERIFY_IS_FALSE(settings._profiles.at(3).HasGuid()); + VERIFY_IS_FALSE(settings._profiles.at(4).HasGuid()); + VERIFY_ARE_EQUAL(L"Windows PowerShell", settings._profiles.at(0).Name()); + VERIFY_ARE_EQUAL(L"Command Prompt", settings._profiles.at(1).Name()); + VERIFY_ARE_EQUAL(L"ThisProfileIsGood", settings._profiles.at(2).Name()); + VERIFY_ARE_EQUAL(L"ThisProfileShouldNotDuplicate", settings._profiles.at(3).Name()); + VERIFY_ARE_EQUAL(L"NeitherShouldThisOne", settings._profiles.at(4).Name()); Log::Comment(NoThrowString().Format( L"Pretend like we're checking to append dynamic profiles to the " @@ -1195,16 +1196,16 @@ namespace TerminalAppLocalTests settings2._ParseJsonString(firstSettingsString, false); settings2.LayerJson(settings2._userSettings); VERIFY_ARE_EQUAL(5u, settings2._profiles.size()); - VERIFY_IS_TRUE(settings2._profiles.at(0)._guid.has_value()); - VERIFY_IS_TRUE(settings2._profiles.at(1)._guid.has_value()); - VERIFY_IS_TRUE(settings2._profiles.at(2)._guid.has_value()); - VERIFY_IS_FALSE(settings2._profiles.at(3)._guid.has_value()); - VERIFY_IS_FALSE(settings2._profiles.at(4)._guid.has_value()); - VERIFY_ARE_EQUAL(L"Windows PowerShell", settings2._profiles.at(0)._name); - VERIFY_ARE_EQUAL(L"Command Prompt", settings2._profiles.at(1)._name); - VERIFY_ARE_EQUAL(L"ThisProfileIsGood", settings2._profiles.at(2)._name); - VERIFY_ARE_EQUAL(L"ThisProfileShouldNotDuplicate", settings2._profiles.at(3)._name); - VERIFY_ARE_EQUAL(L"NeitherShouldThisOne", settings2._profiles.at(4)._name); + VERIFY_IS_TRUE(settings2._profiles.at(0).HasGuid()); + VERIFY_IS_TRUE(settings2._profiles.at(1).HasGuid()); + VERIFY_IS_TRUE(settings2._profiles.at(2).HasGuid()); + VERIFY_IS_FALSE(settings2._profiles.at(3).HasGuid()); + VERIFY_IS_FALSE(settings2._profiles.at(4).HasGuid()); + VERIFY_ARE_EQUAL(L"Windows PowerShell", settings2._profiles.at(0).Name()); + VERIFY_ARE_EQUAL(L"Command Prompt", settings2._profiles.at(1).Name()); + VERIFY_ARE_EQUAL(L"ThisProfileIsGood", settings2._profiles.at(2).Name()); + VERIFY_ARE_EQUAL(L"ThisProfileShouldNotDuplicate", settings2._profiles.at(3).Name()); + VERIFY_ARE_EQUAL(L"NeitherShouldThisOne", settings2._profiles.at(4).Name()); } Log::Comment(NoThrowString().Format( @@ -1212,16 +1213,16 @@ namespace TerminalAppLocalTests settings._ValidateSettings(); VERIFY_ARE_EQUAL(5u, settings._profiles.size()); - VERIFY_IS_TRUE(settings._profiles.at(0)._guid.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(1)._guid.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(2)._guid.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(3)._guid.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(4)._guid.has_value()); - VERIFY_ARE_EQUAL(L"ThisProfileIsGood", settings._profiles.at(0)._name); - VERIFY_ARE_EQUAL(L"ThisProfileShouldNotDuplicate", settings._profiles.at(1)._name); - VERIFY_ARE_EQUAL(L"NeitherShouldThisOne", settings._profiles.at(2)._name); - VERIFY_ARE_EQUAL(L"Windows PowerShell", settings._profiles.at(3)._name); - VERIFY_ARE_EQUAL(L"Command Prompt", settings._profiles.at(4)._name); + VERIFY_IS_TRUE(settings._profiles.at(0).HasGuid()); + VERIFY_IS_TRUE(settings._profiles.at(1).HasGuid()); + VERIFY_IS_TRUE(settings._profiles.at(2).HasGuid()); + VERIFY_IS_TRUE(settings._profiles.at(3).HasGuid()); + VERIFY_IS_TRUE(settings._profiles.at(4).HasGuid()); + VERIFY_ARE_EQUAL(L"ThisProfileIsGood", settings._profiles.at(0).Name()); + VERIFY_ARE_EQUAL(L"ThisProfileShouldNotDuplicate", settings._profiles.at(1).Name()); + VERIFY_ARE_EQUAL(L"NeitherShouldThisOne", settings._profiles.at(2).Name()); + VERIFY_ARE_EQUAL(L"Windows PowerShell", settings._profiles.at(3).Name()); + VERIFY_ARE_EQUAL(L"Command Prompt", settings._profiles.at(4).Name()); } void SettingsTests::TestHideAllProfiles() @@ -1331,9 +1332,9 @@ namespace TerminalAppLocalTests VERIFY_ARE_EQUAL(3u, settings._profiles.size()); VERIFY_ARE_EQUAL(2u, settings._globals._colorSchemes.size()); - VERIFY_ARE_EQUAL(L"schemeOne", settings._profiles.at(0)._schemeName.value()); - VERIFY_ARE_EQUAL(L"InvalidSchemeName", settings._profiles.at(1)._schemeName.value()); - VERIFY_ARE_EQUAL(L"Campbell", settings._profiles.at(2)._schemeName.value()); + VERIFY_ARE_EQUAL(L"schemeOne", settings._profiles.at(0).ColorSchemeName()); + VERIFY_ARE_EQUAL(L"InvalidSchemeName", settings._profiles.at(1).ColorSchemeName()); + VERIFY_ARE_EQUAL(L"Campbell", settings._profiles.at(2).ColorSchemeName()); settings._ValidateAllSchemesExist(); @@ -1343,9 +1344,9 @@ namespace TerminalAppLocalTests VERIFY_ARE_EQUAL(3u, settings._profiles.size()); VERIFY_ARE_EQUAL(2u, settings._globals._colorSchemes.size()); - VERIFY_ARE_EQUAL(L"schemeOne", settings._profiles.at(0)._schemeName.value()); - VERIFY_ARE_EQUAL(L"Campbell", settings._profiles.at(1)._schemeName.value()); - VERIFY_ARE_EQUAL(L"Campbell", settings._profiles.at(2)._schemeName.value()); + VERIFY_ARE_EQUAL(L"schemeOne", settings._profiles.at(0).ColorSchemeName()); + VERIFY_ARE_EQUAL(L"Campbell", settings._profiles.at(1).ColorSchemeName()); + VERIFY_ARE_EQUAL(L"Campbell", settings._profiles.at(2).ColorSchemeName()); } void SettingsTests::TestHelperFunctions() @@ -1378,11 +1379,11 @@ namespace TerminalAppLocalTests auto name3{ L"ThisProfileShouldNotThrow" }; auto badName{ L"DoesNotExist" }; - auto guid0{ Microsoft::Console::Utils::GuidFromString(L"{6239a42c-5555-49a3-80bd-e8fdd045185c}") }; - auto guid1{ Microsoft::Console::Utils::GuidFromString(L"{6239a42c-6666-49a3-80bd-e8fdd045185c}") }; - auto guid2{ Microsoft::Console::Utils::GuidFromString(L"{2C4DE342-38B7-51CF-B940-2309A097F518}") }; - auto fakeGuid{ Microsoft::Console::Utils::GuidFromString(L"{FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF}") }; - std::optional badGuid{}; + winrt::guid guid0{ ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-5555-49a3-80bd-e8fdd045185c}") }; + winrt::guid guid1{ ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-6666-49a3-80bd-e8fdd045185c}") }; + winrt::guid guid2{ ::Microsoft::Console::Utils::GuidFromString(L"{2C4DE342-38B7-51CF-B940-2309A097F518}") }; + winrt::guid fakeGuid{ ::Microsoft::Console::Utils::GuidFromString(L"{FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF}") }; + std::optional badGuid{}; VerifyParseSucceeded(settings0String); @@ -1403,9 +1404,9 @@ namespace TerminalAppLocalTests auto badProf{ settings.FindProfile(fakeGuid) }; VERIFY_ARE_EQUAL(badProf, nullptr); - VERIFY_ARE_EQUAL(name0, prof0->GetName()); - VERIFY_ARE_EQUAL(name1, prof1->GetName()); - VERIFY_ARE_EQUAL(name2, prof2->GetName()); + VERIFY_ARE_EQUAL(name0, prof0.Name()); + VERIFY_ARE_EQUAL(name1, prof1.Name()); + VERIFY_ARE_EQUAL(name2, prof2.Name()); } void SettingsTests::TestProfileIconWithEnvVar() @@ -1450,7 +1451,8 @@ namespace TerminalAppLocalTests VERIFY_IS_FALSE(settings._profiles.empty()); GlobalAppSettings globalSettings{}; - auto terminalSettings = settings._profiles[0].CreateTerminalSettings(globalSettings.GetColorSchemes()); + const auto profileImpl = winrt::get_self(settings._profiles[0]); + auto terminalSettings = profileImpl->CreateTerminalSettings(globalSettings.GetColorSchemes()); VERIFY_ARE_EQUAL(expectedPath, terminalSettings.BackgroundImage()); } void SettingsTests::TestCloseOnExitParsing() @@ -1481,12 +1483,12 @@ namespace TerminalAppLocalTests CascadiaSettings settings{}; settings._ParseJsonString(settingsJson, false); settings.LayerJson(settings._userSettings); - VERIFY_ARE_EQUAL(CloseOnExitMode::Graceful, settings._profiles[0].GetCloseOnExitMode()); - VERIFY_ARE_EQUAL(CloseOnExitMode::Always, settings._profiles[1].GetCloseOnExitMode()); - VERIFY_ARE_EQUAL(CloseOnExitMode::Never, settings._profiles[2].GetCloseOnExitMode()); + VERIFY_ARE_EQUAL(CloseOnExitMode::Graceful, settings._profiles[0].CloseOnExit()); + VERIFY_ARE_EQUAL(CloseOnExitMode::Always, settings._profiles[1].CloseOnExit()); + VERIFY_ARE_EQUAL(CloseOnExitMode::Never, settings._profiles[2].CloseOnExit()); // Unknown modes parse as "Graceful" - VERIFY_ARE_EQUAL(CloseOnExitMode::Graceful, settings._profiles[3].GetCloseOnExitMode()); + VERIFY_ARE_EQUAL(CloseOnExitMode::Graceful, settings._profiles[3].CloseOnExit()); } void SettingsTests::TestCloseOnExitCompatibilityShim() { @@ -1508,8 +1510,8 @@ namespace TerminalAppLocalTests CascadiaSettings settings{}; settings._ParseJsonString(settingsJson, false); settings.LayerJson(settings._userSettings); - VERIFY_ARE_EQUAL(CloseOnExitMode::Graceful, settings._profiles[0].GetCloseOnExitMode()); - VERIFY_ARE_EQUAL(CloseOnExitMode::Never, settings._profiles[1].GetCloseOnExitMode()); + VERIFY_ARE_EQUAL(CloseOnExitMode::Graceful, settings._profiles[0].CloseOnExit()); + VERIFY_ARE_EQUAL(CloseOnExitMode::Never, settings._profiles[1].CloseOnExit()); } void SettingsTests::TestLayerUserDefaultsBeforeProfiles() @@ -1555,8 +1557,8 @@ namespace TerminalAppLocalTests VERIFY_ARE_EQUAL(guid1String, settings._globals._unparsedDefaultProfile); VERIFY_ARE_EQUAL(2u, settings._profiles.size()); - VERIFY_ARE_EQUAL(2345, settings._profiles.at(0)._historySize); - VERIFY_ARE_EQUAL(1234, settings._profiles.at(1)._historySize); + VERIFY_ARE_EQUAL(2345, settings._profiles.at(0).HistorySize()); + VERIFY_ARE_EQUAL(1234, settings._profiles.at(1).HistorySize()); } } @@ -1589,8 +1591,8 @@ namespace TerminalAppLocalTests VerifyParseSucceeded(settings0String); const auto guid1String = L"{6239a42c-1111-49a3-80bd-e8fdd045185c}"; - const auto guid1 = Microsoft::Console::Utils::GuidFromString(guid1String); - const auto guid2 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-2222-49a3-80bd-e8fdd045185c}"); + const winrt::guid guid1{ ::Microsoft::Console::Utils::GuidFromString(guid1String) }; + const winrt::guid guid2{ ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-2222-49a3-80bd-e8fdd045185c}") }; { CascadiaSettings settings{ false }; @@ -1605,16 +1607,16 @@ namespace TerminalAppLocalTests Log::Comment(NoThrowString().Format( L"Ensure that cmd and powershell don't get their GUIDs overwritten")); - VERIFY_ARE_NOT_EQUAL(guid2, settings._profiles.at(0)._guid); - VERIFY_ARE_NOT_EQUAL(guid2, settings._profiles.at(1)._guid); + VERIFY_ARE_NOT_EQUAL(guid2, settings._profiles.at(0).Guid()); + VERIFY_ARE_NOT_EQUAL(guid2, settings._profiles.at(1).Guid()); settings.LayerJson(settings._userSettings); VERIFY_ARE_EQUAL(guid1String, settings._globals._unparsedDefaultProfile); VERIFY_ARE_EQUAL(4u, settings._profiles.size()); - VERIFY_ARE_EQUAL(guid1, settings._profiles.at(2)._guid); - VERIFY_IS_FALSE(settings._profiles.at(3)._guid.has_value()); + VERIFY_ARE_EQUAL(guid1, settings._profiles.at(2).Guid()); + VERIFY_IS_FALSE(settings._profiles.at(3).HasGuid()); } } @@ -1627,9 +1629,9 @@ namespace TerminalAppLocalTests // settings in defaultSettings should apply _on top_ of settings from // dynamic profiles. - GUID guid1 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-1111-49a3-80bd-e8fdd045185c}"); - GUID guid2 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-2222-49a3-80bd-e8fdd045185c}"); - GUID guid3 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-3333-49a3-80bd-e8fdd045185c}"); + winrt::guid guid1{ ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-1111-49a3-80bd-e8fdd045185c}") }; + winrt::guid guid2{ ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-2222-49a3-80bd-e8fdd045185c}") }; + winrt::guid guid3{ ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-3333-49a3-80bd-e8fdd045185c}") }; const std::string userProfiles{ R"( { @@ -1662,21 +1664,22 @@ namespace TerminalAppLocalTests auto gen0 = std::make_unique(L"Terminal.App.UnitTest.0"); gen0->pfnGenerate = [guid1, guid2]() { std::vector profiles; - Profile p0{ guid1 }; - p0.SetName(L"profile0"); // this is _profiles.at(0) - p0._historySize = 1111; + Profile p0 = winrt::make(guid1); + p0.Name(L"profile0"); // this is _profiles.at(0) + p0.HistorySize(1111); profiles.push_back(p0); return profiles; }; auto gen1 = std::make_unique(L"Terminal.App.UnitTest.1"); gen1->pfnGenerate = [guid1, guid2]() { std::vector profiles; - Profile p0{ guid1 }, p1{ guid2 }; - p0.SetName(L"profile0"); // this is _profiles.at(1) - p1.SetName(L"profile1"); // this is _profiles.at(2) - p0._historySize = 2222; + Profile p0 = winrt::make(guid1); + Profile p1 = winrt::make(guid2); + p0.Name(L"profile0"); // this is _profiles.at(1) + p1.Name(L"profile1"); // this is _profiles.at(2) + p0.HistorySize(2222); profiles.push_back(p0); - p1._historySize = 3333; + p1.HistorySize(3333); profiles.push_back(p1); return profiles; }; @@ -1695,40 +1698,40 @@ namespace TerminalAppLocalTests settings._LoadDynamicProfiles(); VERIFY_ARE_EQUAL(3u, settings._profiles.size()); - VERIFY_ARE_EQUAL(1111, settings._profiles.at(0)._historySize); - VERIFY_ARE_EQUAL(2222, settings._profiles.at(1)._historySize); - VERIFY_ARE_EQUAL(3333, settings._profiles.at(2)._historySize); + VERIFY_ARE_EQUAL(1111, settings._profiles.at(0).HistorySize()); + VERIFY_ARE_EQUAL(2222, settings._profiles.at(1).HistorySize()); + VERIFY_ARE_EQUAL(3333, settings._profiles.at(2).HistorySize()); settings._ApplyDefaultsFromUserSettings(); - VERIFY_ARE_EQUAL(1234, settings._profiles.at(0)._historySize); - VERIFY_ARE_EQUAL(1234, settings._profiles.at(1)._historySize); - VERIFY_ARE_EQUAL(1234, settings._profiles.at(2)._historySize); + VERIFY_ARE_EQUAL(1234, settings._profiles.at(0).HistorySize()); + VERIFY_ARE_EQUAL(1234, settings._profiles.at(1).HistorySize()); + VERIFY_ARE_EQUAL(1234, settings._profiles.at(2).HistorySize()); settings.LayerJson(settings._userSettings); VERIFY_ARE_EQUAL(4u, settings._profiles.size()); - VERIFY_IS_TRUE(settings._profiles.at(0)._source.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(1)._source.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(2)._source.has_value()); - VERIFY_IS_FALSE(settings._profiles.at(3)._source.has_value()); + VERIFY_IS_FALSE(settings._profiles.at(0).Source().empty()); + VERIFY_IS_FALSE(settings._profiles.at(1).Source().empty()); + VERIFY_IS_FALSE(settings._profiles.at(2).Source().empty()); + VERIFY_IS_TRUE(settings._profiles.at(3).Source().empty()); - VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.0", settings._profiles.at(0)._source.value()); - VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.1", settings._profiles.at(1)._source.value()); - VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.1", settings._profiles.at(2)._source.value()); + VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.0", settings._profiles.at(0).Source()); + VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.1", settings._profiles.at(1).Source()); + VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.1", settings._profiles.at(2).Source()); - VERIFY_IS_TRUE(settings._profiles.at(0)._guid.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(1)._guid.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(2)._guid.has_value()); + VERIFY_IS_TRUE(settings._profiles.at(0).HasGuid()); + VERIFY_IS_TRUE(settings._profiles.at(1).HasGuid()); + VERIFY_IS_TRUE(settings._profiles.at(2).HasGuid()); - VERIFY_ARE_EQUAL(guid1, settings._profiles.at(0)._guid.value()); - VERIFY_ARE_EQUAL(guid1, settings._profiles.at(1)._guid.value()); - VERIFY_ARE_EQUAL(guid2, settings._profiles.at(2)._guid.value()); + VERIFY_ARE_EQUAL(guid1, settings._profiles.at(0).Guid()); + VERIFY_ARE_EQUAL(guid1, settings._profiles.at(1).Guid()); + VERIFY_ARE_EQUAL(guid2, settings._profiles.at(2).Guid()); - VERIFY_ARE_EQUAL(L"profile0FromUserSettings", settings._profiles.at(0)._name); - VERIFY_ARE_EQUAL(L"profile0", settings._profiles.at(1)._name); - VERIFY_ARE_EQUAL(L"profile1FromUserSettings", settings._profiles.at(2)._name); - VERIFY_ARE_EQUAL(L"profile2FromUserSettings", settings._profiles.at(3)._name); + VERIFY_ARE_EQUAL(L"profile0FromUserSettings", settings._profiles.at(0).Name()); + VERIFY_ARE_EQUAL(L"profile0", settings._profiles.at(1).Name()); + VERIFY_ARE_EQUAL(L"profile1FromUserSettings", settings._profiles.at(2).Name()); + VERIFY_ARE_EQUAL(L"profile2FromUserSettings", settings._profiles.at(3).Name()); Log::Comment(NoThrowString().Format( L"This is the real meat of the test: The two dynamic profiles that " @@ -1736,10 +1739,10 @@ namespace TerminalAppLocalTests L"1234 as their historySize(from the defaultSettings).The other two" L" profiles should have their custom historySize value.")); - VERIFY_ARE_EQUAL(1234, settings._profiles.at(0)._historySize); - VERIFY_ARE_EQUAL(1234, settings._profiles.at(1)._historySize); - VERIFY_ARE_EQUAL(4444, settings._profiles.at(2)._historySize); - VERIFY_ARE_EQUAL(5555, settings._profiles.at(3)._historySize); + VERIFY_ARE_EQUAL(1234, settings._profiles.at(0).HistorySize()); + VERIFY_ARE_EQUAL(1234, settings._profiles.at(1).HistorySize()); + VERIFY_ARE_EQUAL(4444, settings._profiles.at(2).HistorySize()); + VERIFY_ARE_EQUAL(5555, settings._profiles.at(3).HistorySize()); } void SettingsTests::TestTerminalArgsForBinding() @@ -1782,8 +1785,8 @@ namespace TerminalAppLocalTests ] })" }; - const auto guid0 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-0000-49a3-80bd-e8fdd045185c}"); - const auto guid1 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-1111-49a3-80bd-e8fdd045185c}"); + const winrt::guid guid0{ ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-0000-49a3-80bd-e8fdd045185c}") }; + const winrt::guid guid1{ ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-1111-49a3-80bd-e8fdd045185c}") }; VerifyParseSucceeded(settingsJson); CascadiaSettings settings{}; @@ -1794,8 +1797,8 @@ namespace TerminalAppLocalTests auto appKeyBindings = settings._globals._keybindings; VERIFY_ARE_EQUAL(3u, settings.GetProfiles().size()); - const auto profile2Guid = settings._profiles.at(2).GetGuid(); - VERIFY_ARE_NOT_EQUAL(GUID{ 0 }, profile2Guid); + const auto profile2Guid = settings._profiles.at(2).Guid(); + VERIFY_ARE_NOT_EQUAL(winrt::guid{}, profile2Guid); VERIFY_ARE_EQUAL(12u, appKeyBindings->_keyShortcuts.size()); @@ -2066,20 +2069,20 @@ namespace TerminalAppLocalTests const auto settingsJsonObj = VerifyParseSucceeded(settingsString); auto settings = CascadiaSettings::FromJson(settingsJsonObj); - const auto guid1 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-1111-49a3-80bd-e8fdd045185c}"); - const auto guid2 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-2222-49a3-80bd-e8fdd045185c}"); - const auto guid3 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-3333-49a3-80bd-e8fdd045185c}"); + const auto guid1 = ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-1111-49a3-80bd-e8fdd045185c}"); + const auto guid2 = ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-2222-49a3-80bd-e8fdd045185c}"); + const auto guid3 = ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-3333-49a3-80bd-e8fdd045185c}"); - const Profile* const profile1 = settings->FindProfile(guid1); - const Profile* const profile2 = settings->FindProfile(guid2); - const Profile* const profile3 = settings->FindProfile(guid3); + const auto profile1 = settings->FindProfile(guid1); + const auto profile2 = settings->FindProfile(guid2); + const auto profile3 = settings->FindProfile(guid3); VERIFY_IS_NOT_NULL(profile1); VERIFY_IS_NOT_NULL(profile2); VERIFY_IS_NULL(profile3); - VERIFY_ARE_EQUAL(L"profile0", profile1->GetName()); - VERIFY_ARE_EQUAL(L"profile1", profile2->GetName()); + VERIFY_ARE_EQUAL(L"profile0", profile1.Name()); + VERIFY_ARE_EQUAL(L"profile1", profile2.Name()); } void SettingsTests::MakeSettingsForProfileThatDoesntExist() @@ -2105,9 +2108,9 @@ namespace TerminalAppLocalTests auto settings = CascadiaSettings::FromJson(settingsJsonObj); settings->_ResolveDefaultProfile(); - const auto guid1 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-1111-49a3-80bd-e8fdd045185c}"); - const auto guid2 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-2222-49a3-80bd-e8fdd045185c}"); - const auto guid3 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-3333-49a3-80bd-e8fdd045185c}"); + const auto guid1 = ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-1111-49a3-80bd-e8fdd045185c}"); + const auto guid2 = ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-2222-49a3-80bd-e8fdd045185c}"); + const auto guid3 = ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-3333-49a3-80bd-e8fdd045185c}"); try { @@ -2173,7 +2176,7 @@ namespace TerminalAppLocalTests VERIFY_ARE_EQUAL(2u, settings->_warnings.size()); VERIFY_ARE_EQUAL(2u, settings->_profiles.size()); - VERIFY_ARE_EQUAL(settings->_globals.DefaultProfile(), settings->_profiles.at(0).GetGuid()); + VERIFY_ARE_EQUAL(winrt::guid{ settings->_globals.DefaultProfile() }, settings->_profiles.at(0).Guid()); try { const auto [guid, termSettings] = settings->BuildSettings(nullptr); @@ -2240,12 +2243,12 @@ namespace TerminalAppLocalTests VERIFY_ARE_EQUAL(6u, settings._profiles.size()); VERIFY_ARE_EQUAL(2u, settings._globals._colorSchemes.size()); - auto terminalSettings0 = settings._profiles[0].CreateTerminalSettings(settings._globals._colorSchemes); - auto terminalSettings1 = settings._profiles[1].CreateTerminalSettings(settings._globals._colorSchemes); - auto terminalSettings2 = settings._profiles[2].CreateTerminalSettings(settings._globals._colorSchemes); - auto terminalSettings3 = settings._profiles[3].CreateTerminalSettings(settings._globals._colorSchemes); - auto terminalSettings4 = settings._profiles[4].CreateTerminalSettings(settings._globals._colorSchemes); - auto terminalSettings5 = settings._profiles[5].CreateTerminalSettings(settings._globals._colorSchemes); + auto terminalSettings0 = winrt::get_self(settings._profiles[0])->CreateTerminalSettings(settings._globals._colorSchemes); + auto terminalSettings1 = winrt::get_self(settings._profiles[1])->CreateTerminalSettings(settings._globals._colorSchemes); + auto terminalSettings2 = winrt::get_self(settings._profiles[2])->CreateTerminalSettings(settings._globals._colorSchemes); + auto terminalSettings3 = winrt::get_self(settings._profiles[3])->CreateTerminalSettings(settings._globals._colorSchemes); + auto terminalSettings4 = winrt::get_self(settings._profiles[4])->CreateTerminalSettings(settings._globals._colorSchemes); + auto terminalSettings5 = winrt::get_self(settings._profiles[5])->CreateTerminalSettings(settings._globals._colorSchemes); VERIFY_ARE_EQUAL(ARGB(0, 0x12, 0x34, 0x56), terminalSettings0.CursorColor()); // from color scheme VERIFY_ARE_EQUAL(DEFAULT_CURSOR_COLOR, terminalSettings1.CursorColor()); // default @@ -2448,8 +2451,8 @@ namespace TerminalAppLocalTests ] })" }; - const auto guid0 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-0000-49a3-80bd-e8fdd045185c}"); - const auto guid1 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-1111-49a3-80bd-e8fdd045185c}"); + const auto guid0 = ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-0000-49a3-80bd-e8fdd045185c}"); + const auto guid1 = ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-1111-49a3-80bd-e8fdd045185c}"); VerifyParseSucceeded(settingsJson); CascadiaSettings settings{}; @@ -2459,8 +2462,8 @@ namespace TerminalAppLocalTests VERIFY_ARE_EQUAL(3u, settings.GetProfiles().size()); - const auto profile2Guid = settings._profiles.at(2).GetGuid(); - VERIFY_ARE_NOT_EQUAL(GUID{ 0 }, profile2Guid); + const auto profile2Guid = settings._profiles.at(2).Guid(); + VERIFY_ARE_NOT_EQUAL(winrt::guid{}, profile2Guid); auto appKeyBindings = settings._globals._keybindings; VERIFY_ARE_EQUAL(5u, appKeyBindings->_keyShortcuts.size()); @@ -2650,8 +2653,8 @@ namespace TerminalAppLocalTests "schemes": [ { "name": "Campbell" } ] // This is included here to prevent settings validation errors. })" }; - const auto guid0 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-0000-49a3-80bd-e8fdd045185c}"); - const auto guid1 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-1111-49a3-80bd-e8fdd045185c}"); + const auto guid0 = ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-0000-49a3-80bd-e8fdd045185c}"); + const auto guid1 = ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-1111-49a3-80bd-e8fdd045185c}"); VerifyParseSucceeded(settingsJson); CascadiaSettings settings{}; @@ -2780,8 +2783,8 @@ namespace TerminalAppLocalTests "schemes": [ { "name": "Campbell" } ] // This is included here to prevent settings validation errors. })" }; - const auto guid0 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-0000-49a3-80bd-e8fdd045185c}"); - const auto guid1 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-1111-49a3-80bd-e8fdd045185c}"); + const auto guid0 = ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-0000-49a3-80bd-e8fdd045185c}"); + const auto guid1 = ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-1111-49a3-80bd-e8fdd045185c}"); VerifyParseSucceeded(settingsJson); CascadiaSettings settings{}; @@ -2912,8 +2915,8 @@ namespace TerminalAppLocalTests "schemes": [ { "name": "Campbell" } ] // This is included here to prevent settings validation errors. })" }; - const auto guid0 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-0000-49a3-80bd-e8fdd045185c}"); - const auto guid1 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-1111-49a3-80bd-e8fdd045185c}"); + const auto guid0 = ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-0000-49a3-80bd-e8fdd045185c}"); + const auto guid1 = ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-1111-49a3-80bd-e8fdd045185c}"); VerifyParseSucceeded(settingsJson); CascadiaSettings settings{}; diff --git a/src/cascadia/LocalTests_TerminalApp/pch.h b/src/cascadia/LocalTests_TerminalApp/pch.h index 6f134f00e4d..88e3ebcecca 100644 --- a/src/cascadia/LocalTests_TerminalApp/pch.h +++ b/src/cascadia/LocalTests_TerminalApp/pch.h @@ -15,6 +15,8 @@ Author(s): #pragma once +// Manually include til after we include Windows.Foundation to give it winrt superpowers +#define BLOCK_TIL // This includes support libraries from the CRT, STL, WIL, and GSL #include "LibraryIncludes.h" // This is inexplicable, but for whatever reason, cppwinrt conflicts with the @@ -33,12 +35,6 @@ Author(s): #include #include "consoletaeftemplates.hpp" -// Common includes for most tests: -#include "../../inc/argb.h" -#include "../../inc/conattrs.hpp" -#include "../../types/inc/utils.hpp" -#include "../../inc/DefaultSettings.h" - #include #include "winrt/Windows.UI.Xaml.Markup.h" #include @@ -63,3 +59,12 @@ Author(s): #include #include + +// Manually include til after we include Windows.Foundation to give it winrt superpowers +#include "til.h" + +// Common includes for most tests: +#include "../../inc/argb.h" +#include "../../inc/conattrs.hpp" +#include "../../types/inc/utils.hpp" +#include "../../inc/DefaultSettings.h" diff --git a/src/cascadia/TerminalApp/AzureCloudShellGenerator.cpp b/src/cascadia/TerminalApp/AzureCloudShellGenerator.cpp index b9e76dce7f0..5a5fc7ba150 100644 --- a/src/cascadia/TerminalApp/AzureCloudShellGenerator.cpp +++ b/src/cascadia/TerminalApp/AzureCloudShellGenerator.cpp @@ -14,6 +14,7 @@ #include "DefaultProfileUtils.h" using namespace ::TerminalApp; +using namespace winrt::TerminalApp; std::wstring_view AzureCloudShellGenerator::GetNamespace() { @@ -27,19 +28,19 @@ std::wstring_view AzureCloudShellGenerator::GetNamespace() // - // Return Value: // - a vector with the Azure Cloud Shell connection profile, if available. -std::vector AzureCloudShellGenerator::GenerateProfiles() +std::vector AzureCloudShellGenerator::GenerateProfiles() { - std::vector profiles; + std::vector profiles; if (winrt::Microsoft::Terminal::TerminalConnection::AzureConnection::IsAzureConnectionAvailable()) { auto azureCloudShellProfile{ CreateDefaultProfile(L"Azure Cloud Shell") }; - azureCloudShellProfile.SetCommandline(L"Azure"); - azureCloudShellProfile.SetStartingDirectory(DEFAULT_STARTING_DIRECTORY); - azureCloudShellProfile.SetColorScheme({ L"Vintage" }); - azureCloudShellProfile.SetAcrylicOpacity(0.6); - azureCloudShellProfile.SetUseAcrylic(true); - azureCloudShellProfile.SetConnectionType(AzureConnectionType); + azureCloudShellProfile.Commandline(L"Azure"); + azureCloudShellProfile.StartingDirectory(DEFAULT_STARTING_DIRECTORY); + azureCloudShellProfile.ColorSchemeName(L"Vintage"); + azureCloudShellProfile.AcrylicOpacity(0.6); + azureCloudShellProfile.UseAcrylic(true); + azureCloudShellProfile.ConnectionType(AzureConnectionType); profiles.emplace_back(azureCloudShellProfile); } diff --git a/src/cascadia/TerminalApp/AzureCloudShellGenerator.h b/src/cascadia/TerminalApp/AzureCloudShellGenerator.h index 3e752276d40..d624c856b47 100644 --- a/src/cascadia/TerminalApp/AzureCloudShellGenerator.h +++ b/src/cascadia/TerminalApp/AzureCloudShellGenerator.h @@ -18,7 +18,7 @@ Author(s): #pragma once #include "IDynamicProfileGenerator.h" -static constexpr GUID AzureConnectionType = { 0xd9fcfdfa, 0xa479, 0x412c, { 0x83, 0xb7, 0xc5, 0x64, 0xe, 0x61, 0xcd, 0x62 } }; +static constexpr winrt::guid AzureConnectionType = { 0xd9fcfdfa, 0xa479, 0x412c, { 0x83, 0xb7, 0xc5, 0x64, 0xe, 0x61, 0xcd, 0x62 } }; namespace TerminalApp { @@ -29,6 +29,6 @@ namespace TerminalApp ~AzureCloudShellGenerator() = default; std::wstring_view GetNamespace() override; - std::vector GenerateProfiles() override; + std::vector GenerateProfiles() override; }; }; diff --git a/src/cascadia/TerminalApp/CascadiaSettings.cpp b/src/cascadia/TerminalApp/CascadiaSettings.cpp index 2ecfa174543..4eda47ada1b 100644 --- a/src/cascadia/TerminalApp/CascadiaSettings.cpp +++ b/src/cascadia/TerminalApp/CascadiaSettings.cpp @@ -70,15 +70,16 @@ CascadiaSettings::CascadiaSettings(const bool addDynamicProfiles) // Return Value: // - a non-ownership pointer to the profile matching the given guid, or nullptr // if there is no match. -const Profile* CascadiaSettings::FindProfile(GUID profileGuid) const noexcept +const Profile CascadiaSettings::FindProfile(winrt::guid profileGuid) const noexcept { + const winrt::guid guid{ profileGuid }; for (auto& profile : _profiles) { try { - if (profile.GetGuid() == profileGuid) + if (profile.Guid() == guid) { - return &profile; + return profile; } } CATCH_LOG(); @@ -215,7 +216,8 @@ void CascadiaSettings::_ValidateProfilesHaveGuid() { for (auto& profile : _profiles) { - profile.GenerateGuidIfNecessary(); + auto profileImpl = winrt::get_self(profile); + profileImpl->GenerateGuidIfNecessary(); } } @@ -228,7 +230,7 @@ void CascadiaSettings::_ResolveDefaultProfile() if (unparsedDefaultProfile) { auto maybeParsedDefaultProfile{ _GetProfileGuidByName(*unparsedDefaultProfile) }; - auto defaultProfileGuid{ til::coalesce_value(maybeParsedDefaultProfile, GUID{}) }; + auto defaultProfileGuid{ til::coalesce_value(maybeParsedDefaultProfile, winrt::guid{}) }; GlobalSettings().DefaultProfile(defaultProfileGuid); } } @@ -242,12 +244,12 @@ void CascadiaSettings::_ResolveDefaultProfile() // warnings if we failed to find the default. void CascadiaSettings::_ValidateDefaultProfileExists() { - const auto defaultProfileGuid = GlobalSettings().DefaultProfile(); - const bool nullDefaultProfile = defaultProfileGuid == GUID{}; + const winrt::guid defaultProfileGuid{ GlobalSettings().DefaultProfile() }; + const bool nullDefaultProfile = defaultProfileGuid == winrt::guid{}; bool defaultProfileNotInProfiles = true; for (const auto& profile : _profiles) { - if (profile.GetGuid() == defaultProfileGuid) + if (profile.Guid() == defaultProfileGuid) { defaultProfileNotInProfiles = false; break; @@ -261,7 +263,7 @@ void CascadiaSettings::_ValidateDefaultProfileExists() // _temporarily_ set the default profile to the first profile. Because // we're adding a warning, this settings change won't be re-serialized. - GlobalSettings().DefaultProfile(_profiles[0].GetGuid()); + GlobalSettings().DefaultProfile(_profiles[0].Guid()); } } @@ -277,13 +279,13 @@ void CascadiaSettings::_ValidateNoDuplicateProfiles() std::vector indicesToDelete; - std::set uniqueGuids; + std::set uniqueGuids; // Try collecting all the unique guids. If we ever encounter a guid that's // already in the set, then we need to delete that profile. for (size_t i = 0; i < _profiles.size(); i++) { - if (!uniqueGuids.insert(_profiles.at(i).GetGuid()).second) + if (!uniqueGuids.insert(_profiles.at(i).Guid()).second) { foundDupe = true; indicesToDelete.push_back(i); @@ -314,15 +316,15 @@ void CascadiaSettings::_ValidateNoDuplicateProfiles() // - void CascadiaSettings::_ReorderProfilesToMatchUserSettingsOrder() { - std::set uniqueGuids; - std::deque guidOrder; + std::set uniqueGuids; + std::deque guidOrder; auto collectGuids = [&](const auto& json) { for (auto profileJson : _GetProfilesJsonObject(json)) { if (profileJson.isObject()) { - auto guid = Profile::GetGuidOrGenerateForJson(profileJson); + auto guid = implementation::Profile::GetGuidOrGenerateForJson(profileJson); if (uniqueGuids.insert(guid).second) { guidOrder.push_back(guid); @@ -336,7 +338,7 @@ void CascadiaSettings::_ReorderProfilesToMatchUserSettingsOrder() // Push all the defaultSettings profiles' GUIDS into the set collectGuids(_defaultSettings); - std::equal_to equals; + std::equal_to equals; // Re-order the list of _profiles to match that ordering // for (gIndex=0 -> uniqueGuids.size) // pIndex = the pIndex of the profile with guid==guids[gIndex] @@ -347,7 +349,7 @@ void CascadiaSettings::_ReorderProfilesToMatchUserSettingsOrder() const auto guid = guidOrder.at(gIndex); for (size_t pIndex = gIndex; pIndex < _profiles.size(); pIndex++) { - auto profileGuid = _profiles.at(pIndex).GetGuid(); + auto profileGuid = _profiles.at(pIndex).Guid(); if (equals(profileGuid, guid)) { std::iter_swap(_profiles.begin() + pIndex, _profiles.begin() + gIndex); @@ -373,7 +375,7 @@ void CascadiaSettings::_RemoveHiddenProfiles() // idiom](https://en.wikipedia.org/wiki/Erase%E2%80%93remove_idiom) _profiles.erase(std::remove_if(_profiles.begin(), _profiles.end(), - [](auto&& profile) { return profile.IsHidden(); }), + [](auto&& profile) { return profile.Hidden(); }), _profiles.end()); // Ensure that we still have some profiles here. If we don't, then throw an @@ -402,13 +404,13 @@ void CascadiaSettings::_ValidateAllSchemesExist() bool foundInvalidScheme = false; for (auto& profile : _profiles) { - auto schemeName = profile.GetSchemeName(); - if (schemeName.has_value()) + auto schemeName = profile.ColorSchemeName(); + if (!schemeName.empty()) { - const auto found = _globals.GetColorSchemes().find(schemeName.value()); + const auto found = _globals.GetColorSchemes().find(schemeName.c_str()); if (found == _globals.GetColorSchemes().end()) { - profile.SetColorScheme({ L"Campbell" }); + profile.ColorSchemeName({ L"Campbell" }); foundInvalidScheme = true; } } @@ -438,7 +440,7 @@ void CascadiaSettings::_ValidateMediaResources() for (auto& profile : _profiles) { - if (profile.HasBackgroundImage()) + if (!profile.BackgroundImagePath().empty()) { // Attempt to convert the path to a URI, the ctor will throw if it's invalid/unparseable. // This covers file paths on the machine, app data, URLs, and other resource paths. @@ -448,12 +450,13 @@ void CascadiaSettings::_ValidateMediaResources() } catch (...) { - profile.ResetBackgroundImagePath(); + // reset background image path + profile.BackgroundImagePath(L""); invalidBackground = true; } } - if (profile.HasIcon()) + if (!profile.IconPath().empty()) { try { @@ -461,7 +464,8 @@ void CascadiaSettings::_ValidateMediaResources() } catch (...) { - profile.ResetIconPath(); + // reset icon path + profile.IconPath(L""); invalidIcon = true; } } @@ -493,9 +497,9 @@ void CascadiaSettings::_ValidateMediaResources() // the profile. // Return Value: // - the GUID of the created profile, and a fully initialized TerminalSettings object -std::tuple CascadiaSettings::BuildSettings(const NewTerminalArgs& newTerminalArgs) const +std::tuple CascadiaSettings::BuildSettings(const NewTerminalArgs& newTerminalArgs) const { - const GUID profileGuid = _GetProfileForArgs(newTerminalArgs); + const winrt::guid profileGuid = _GetProfileForArgs(newTerminalArgs); auto settings = BuildSettings(profileGuid); if (newTerminalArgs) @@ -525,13 +529,14 @@ std::tuple CascadiaSettings::BuildSettings(const NewTerm // Arguments: // - profileGuid: The GUID of a profile to use to create a settings object for. // Return Value: -// - the GUID of the created profile, and a fully initialized TerminalSettings object -TerminalSettings CascadiaSettings::BuildSettings(GUID profileGuid) const +// - a fully initialized TerminalSettings object +TerminalSettings CascadiaSettings::BuildSettings(winrt::guid profileGuid) const { - const Profile* const profile = FindProfile(profileGuid); + const auto profile = FindProfile(profileGuid); THROW_HR_IF_NULL(E_INVALIDARG, profile); - TerminalSettings result = profile->CreateTerminalSettings(_globals.GetColorSchemes()); + const auto profileImpl = winrt::get_self(profile); + TerminalSettings result = profileImpl->CreateTerminalSettings(_globals.GetColorSchemes()); // Place our appropriate global settings into the Terminal Settings _globals.ApplyToSettings(result); @@ -555,9 +560,9 @@ TerminalSettings CascadiaSettings::BuildSettings(GUID profileGuid) const // and attempt to look the profile up by name instead. // Return Value: // - the GUID of the profile corresponding to this combination of index and NewTerminalArgs -GUID CascadiaSettings::_GetProfileForArgs(const NewTerminalArgs& newTerminalArgs) const +winrt::guid CascadiaSettings::_GetProfileForArgs(const NewTerminalArgs& newTerminalArgs) const { - std::optional profileByIndex, profileByName; + std::optional profileByIndex, profileByName; if (newTerminalArgs) { if (newTerminalArgs.ProfileIndex() != nullptr) @@ -577,7 +582,7 @@ GUID CascadiaSettings::_GetProfileForArgs(const NewTerminalArgs& newTerminalArgs // - name: a guid string _or_ the name of a profile // Return Value: // - the GUID of the profile corresponding to this name -std::optional CascadiaSettings::_GetProfileGuidByName(const std::wstring_view name) const +std::optional CascadiaSettings::_GetProfileGuidByName(const std::wstring_view name) const try { // First, try and parse the "name" as a GUID. If it's a @@ -602,12 +607,12 @@ try // lookup a profile. Instead, try using the string to look the // Profile up by name. const auto profileIterator{ std::find_if(_profiles.cbegin(), _profiles.cend(), [&](auto&& profile) { - return profile.GetName().compare(name) == 0; + return profile.Name() == name; }) }; if (profileIterator != _profiles.cend()) { - return profileIterator->GetGuid(); + return profileIterator->Guid(); } } @@ -629,7 +634,7 @@ catch (...) // If omitted, instead return the default profile's GUID // Return Value: // - the Nth profile's GUID, or the default profile's GUID -std::optional CascadiaSettings::_GetProfileGuidByIndex(std::optional index) const +std::optional CascadiaSettings::_GetProfileGuidByIndex(std::optional index) const { if (index) { @@ -639,7 +644,7 @@ std::optional CascadiaSettings::_GetProfileGuidByIndex(std::optional realIndex < gsl::narrow_cast(_profiles.size())) { const auto& selectedProfile = _profiles.at(realIndex); - return selectedProfile.GetGuid(); + return selectedProfile.Guid(); } } return std::nullopt; @@ -734,14 +739,14 @@ std::string CascadiaSettings::_ApplyFirstRunChangesToSettingsTemplate(std::strin // - profileGuid: the GUID of the profile to find the scheme for. // Return Value: // - a non-owning pointer to the scheme. -const ColorScheme CascadiaSettings::GetColorSchemeForProfile(const GUID profileGuid) const +const ColorScheme CascadiaSettings::GetColorSchemeForProfile(const winrt::guid profileGuid) const { - auto* profile = FindProfile(profileGuid); + auto profile = FindProfile(profileGuid); if (!profile) { return nullptr; } - auto schemeName = profile->GetSchemeName().has_value() ? profile->GetSchemeName().value() : L"\0"; + const std::wstring schemeName{ profile.ColorSchemeName() }; auto scheme = _globals.GetColorSchemes().find(schemeName); if (scheme != _globals.GetColorSchemes().end()) { diff --git a/src/cascadia/TerminalApp/CascadiaSettings.h b/src/cascadia/TerminalApp/CascadiaSettings.h index def568424f5..a64be8c364a 100644 --- a/src/cascadia/TerminalApp/CascadiaSettings.h +++ b/src/cascadia/TerminalApp/CascadiaSettings.h @@ -19,9 +19,9 @@ Author(s): #include #include "GlobalAppSettings.h" #include "TerminalWarnings.h" -#include "Profile.h" #include "IDynamicProfileGenerator.h" +#include "Profile.h" #include "ColorScheme.h" // fwdecl unittest classes @@ -64,12 +64,12 @@ class TerminalApp::CascadiaSettings final static const CascadiaSettings& GetCurrentAppSettings(); - std::tuple BuildSettings(const winrt::TerminalApp::NewTerminalArgs& newTerminalArgs) const; - winrt::TerminalApp::TerminalSettings BuildSettings(GUID profileGuid) const; + std::tuple BuildSettings(const winrt::TerminalApp::NewTerminalArgs& newTerminalArgs) const; + winrt::TerminalApp::TerminalSettings BuildSettings(winrt::guid profileGuid) const; GlobalAppSettings& GlobalSettings(); - gsl::span GetProfiles() const noexcept; + gsl::span GetProfiles() const noexcept; winrt::TerminalApp::AppKeyBindings GetKeybindings() const noexcept; @@ -79,8 +79,8 @@ class TerminalApp::CascadiaSettings final static std::filesystem::path GetSettingsPath(); static std::filesystem::path GetDefaultSettingsPath(); - const Profile* FindProfile(GUID profileGuid) const noexcept; - const winrt::TerminalApp::ColorScheme GetColorSchemeForProfile(const GUID profileGuid) const; + const winrt::TerminalApp::Profile FindProfile(winrt::guid profileGuid) const noexcept; + const winrt::TerminalApp::ColorScheme GetColorSchemeForProfile(const winrt::guid profileGuid) const; std::vector& GetWarnings(); @@ -88,7 +88,7 @@ class TerminalApp::CascadiaSettings final private: GlobalAppSettings _globals; - std::vector _profiles; + std::vector _profiles; std::vector _warnings; std::vector> _profileGenerators; @@ -99,7 +99,7 @@ class TerminalApp::CascadiaSettings final Json::Value _userDefaultProfileSettings{ Json::Value::null }; void _LayerOrCreateProfile(const Json::Value& profileJson); - Profile* _FindMatchingProfile(const Json::Value& profileJson); + winrt::com_ptr _FindMatchingProfile(const Json::Value& profileJson); void _LayerOrCreateColorScheme(const Json::Value& schemeJson); winrt::com_ptr _FindMatchingColorScheme(const Json::Value& schemeJson); void _ParseJsonString(std::string_view fileData, const bool isDefaultSettings); @@ -118,9 +118,9 @@ class TerminalApp::CascadiaSettings final static std::optional _ReadUserSettings(); static std::optional _ReadFile(HANDLE hFile); - std::optional _GetProfileGuidByName(const std::wstring_view) const; - std::optional _GetProfileGuidByIndex(std::optional index) const; - GUID _GetProfileForArgs(const winrt::TerminalApp::NewTerminalArgs& newTerminalArgs) const; + std::optional _GetProfileGuidByName(const std::wstring_view) const; + std::optional _GetProfileGuidByIndex(std::optional index) const; + winrt::guid _GetProfileForArgs(const winrt::TerminalApp::NewTerminalArgs& newTerminalArgs) const; void _ValidateSettings(); void _ValidateProfilesExist(); diff --git a/src/cascadia/TerminalApp/CascadiaSettingsSerialization.cpp b/src/cascadia/TerminalApp/CascadiaSettingsSerialization.cpp index 33433a3b9eb..fe68f476602 100644 --- a/src/cascadia/TerminalApp/CascadiaSettingsSerialization.cpp +++ b/src/cascadia/TerminalApp/CascadiaSettingsSerialization.cpp @@ -327,7 +327,7 @@ void CascadiaSettings::_LoadDynamicProfiles() { // If the profile did not have a GUID when it was generated, // we'll synthesize a GUID for it in _ValidateProfilesHaveGuid - profile.SetSource(generatorNamespace); + profile.Source(generatorNamespace); _profiles.emplace_back(profile); } @@ -452,7 +452,8 @@ bool CascadiaSettings::_AppendDynamicProfilesToUserSettings() { if (profileJson.isObject()) { - if (profile.ShouldBeLayered(profileJson)) + const auto profileImpl = winrt::get_self(profile); + if (profileImpl->ShouldBeLayered(profileJson)) { return true; } @@ -502,7 +503,8 @@ bool CascadiaSettings::_AppendDynamicProfilesToUserSettings() // Generate a diff for the profile, that contains the minimal set of // changes to re-create this profile. - const auto diff = profile.GenerateStub(); + const auto profileImpl = winrt::get_self(profile); + const auto diff = profileImpl->GenerateStub(); auto profileSerialization = Json::writeString(wbuilder, diff); // Add the user's indent to the start of each line @@ -605,19 +607,19 @@ void CascadiaSettings::_LayerOrCreateProfile(const Json::Value& profileJson) // If this JSON represents a dynamic profile, we _shouldn't_ create the // profile here. We only want to create profiles for profiles without a // `source`. Dynamic profiles _must_ be layered on an existing profile. - if (!Profile::IsDynamicProfileObject(profileJson)) + if (!implementation::Profile::IsDynamicProfileObject(profileJson)) { - Profile profile{}; + auto profile = winrt::make_self(); // GH#2325: If we have a set of default profile settings, apply them here. // We _won't_ have these settings yet for defaults, dynamic profiles. if (_userDefaultProfileSettings) { - profile.LayerJson(_userDefaultProfileSettings); + profile->LayerJson(_userDefaultProfileSettings); } - profile.LayerJson(profileJson); - _profiles.emplace_back(profile); + profile->LayerJson(profileJson); + _profiles.emplace_back(*profile); } } } @@ -633,17 +635,14 @@ void CascadiaSettings::_LayerOrCreateProfile(const Json::Value& profileJson) // Return Value: // - a Profile that can be layered with the given json object, iff such a // profile exists. -Profile* CascadiaSettings::_FindMatchingProfile(const Json::Value& profileJson) +winrt::com_ptr CascadiaSettings::_FindMatchingProfile(const Json::Value& profileJson) { for (auto& profile : _profiles) { - if (profile.ShouldBeLayered(profileJson)) + auto profileImpl = winrt::get_self(profile); + if (profileImpl->ShouldBeLayered(profileJson)) { - // HERE BE DRAGONS: Returning a pointer to a type in the vector is - // maybe not the _safest_ thing, but we have a mind to make Profile - // and ColorScheme winrt types in the future, so this will be safer - // then. - return &profile; + return profileImpl->get_strong(); } } return nullptr; @@ -685,7 +684,8 @@ void CascadiaSettings::_ApplyDefaultsFromUserSettings() for (auto& profile : _profiles) { - profile.LayerJson(_userDefaultProfileSettings); + auto profileImpl = winrt::get_self(profile); + profileImpl->LayerJson(_userDefaultProfileSettings); } } } diff --git a/src/cascadia/TerminalApp/Command.cpp b/src/cascadia/TerminalApp/Command.cpp index 1eeadc21494..2c66cdf7dd4 100644 --- a/src/cascadia/TerminalApp/Command.cpp +++ b/src/cascadia/TerminalApp/Command.cpp @@ -353,7 +353,7 @@ namespace winrt::TerminalApp::implementation // Return Value: // - void Command::ExpandCommands(Windows::Foundation::Collections::IMap& commands, - gsl::span profiles, + gsl::span profiles, gsl::span schemes, std::vector<::TerminalApp::SettingsLoadWarnings>& warnings) { @@ -409,7 +409,7 @@ namespace winrt::TerminalApp::implementation // - and empty vector if the command wasn't expandable, otherwise a list of // the newly-created commands. std::vector Command::_expandCommand(Command* const expandable, - gsl::span profiles, + gsl::span profiles, gsl::span schemes, std::vector<::TerminalApp::SettingsLoadWarnings>& warnings) { @@ -466,7 +466,7 @@ namespace winrt::TerminalApp::implementation // Replace all the keywords in the original json, and try and parse that // - Escape the profile name for JSON appropriately - auto escapedProfileName = _escapeForJson(til::u16u8(p.GetName())); + auto escapedProfileName = _escapeForJson(til::u16u8(p.Name())); auto escapedProfileIcon = _escapeForJson(til::u16u8(p.GetExpandedIconPath())); auto newJsonString = til::replace_needle_in_haystack(oldJsonString, ProfileNameToken, diff --git a/src/cascadia/TerminalApp/Command.h b/src/cascadia/TerminalApp/Command.h index e7aa339a41c..c98f968c6b0 100644 --- a/src/cascadia/TerminalApp/Command.h +++ b/src/cascadia/TerminalApp/Command.h @@ -41,7 +41,7 @@ namespace winrt::TerminalApp::implementation std::vector<::TerminalApp::SettingsLoadWarnings>& warnings); static void ExpandCommands(Windows::Foundation::Collections::IMap& commands, - gsl::span profiles, + gsl::span profiles, gsl::span schemes, std::vector<::TerminalApp::SettingsLoadWarnings>& warnings); @@ -69,7 +69,7 @@ namespace winrt::TerminalApp::implementation winrt::hstring _lastIconPath{}; static std::vector _expandCommand(Command* const expandable, - gsl::span profiles, + gsl::span profiles, gsl::span schemes, std::vector<::TerminalApp::SettingsLoadWarnings>& warnings); friend class TerminalAppLocalTests::SettingsTests; diff --git a/src/cascadia/TerminalApp/DefaultProfileUtils.cpp b/src/cascadia/TerminalApp/DefaultProfileUtils.cpp index 02222fdcb61..18c59ef6e88 100644 --- a/src/cascadia/TerminalApp/DefaultProfileUtils.cpp +++ b/src/cascadia/TerminalApp/DefaultProfileUtils.cpp @@ -15,19 +15,18 @@ static constexpr std::wstring_view PACKAGED_PROFILE_ICON_EXTENSION{ L".png" }; // - name: the name of the new profile. // Return Value: // - A Profile, ready to be filled in -TerminalApp::Profile CreateDefaultProfile(const std::wstring_view name) +winrt::TerminalApp::Profile CreateDefaultProfile(const std::wstring_view name) { - const auto profileGuid{ Microsoft::Console::Utils::CreateV5Uuid(TERMINAL_PROFILE_NAMESPACE_GUID, - gsl::as_bytes(gsl::make_span(name))) }; - TerminalApp::Profile newProfile{ profileGuid }; - - newProfile.SetName(name); + const winrt::guid profileGuid{ Microsoft::Console::Utils::CreateV5Uuid(TERMINAL_PROFILE_NAMESPACE_GUID, + gsl::as_bytes(gsl::make_span(name))) }; + auto newProfile = winrt::make(profileGuid); + newProfile.Name(name); std::wstring iconPath{ PACKAGED_PROFILE_ICON_PATH }; iconPath.append(Microsoft::Console::Utils::GuidToString(profileGuid)); iconPath.append(PACKAGED_PROFILE_ICON_EXTENSION); - newProfile.SetIconPath(iconPath); + newProfile.IconPath(iconPath); return newProfile; } diff --git a/src/cascadia/TerminalApp/DefaultProfileUtils.h b/src/cascadia/TerminalApp/DefaultProfileUtils.h index 16d0f99deb1..c12b7169cf0 100644 --- a/src/cascadia/TerminalApp/DefaultProfileUtils.h +++ b/src/cascadia/TerminalApp/DefaultProfileUtils.h @@ -20,4 +20,4 @@ Author(s): // uuidv5 properties: name format is UTF-16LE bytes static constexpr GUID TERMINAL_PROFILE_NAMESPACE_GUID = { 0x2bde4a90, 0xd05f, 0x401c, { 0x94, 0x92, 0xe4, 0x8, 0x84, 0xea, 0xd1, 0xd8 } }; -TerminalApp::Profile CreateDefaultProfile(const std::wstring_view name); +winrt::TerminalApp::Profile CreateDefaultProfile(const std::wstring_view name); diff --git a/src/cascadia/TerminalApp/IDynamicProfileGenerator.h b/src/cascadia/TerminalApp/IDynamicProfileGenerator.h index 740ed483c1b..22940364a26 100644 --- a/src/cascadia/TerminalApp/IDynamicProfileGenerator.h +++ b/src/cascadia/TerminalApp/IDynamicProfileGenerator.h @@ -32,6 +32,6 @@ class TerminalApp::IDynamicProfileGenerator public: virtual ~IDynamicProfileGenerator() = 0; virtual std::wstring_view GetNamespace() = 0; - virtual std::vector GenerateProfiles() = 0; + virtual std::vector GenerateProfiles() = 0; }; inline TerminalApp::IDynamicProfileGenerator::~IDynamicProfileGenerator() {} diff --git a/src/cascadia/TerminalApp/JsonUtils.h b/src/cascadia/TerminalApp/JsonUtils.h index b75c58200e1..5e639ecc73a 100644 --- a/src/cascadia/TerminalApp/JsonUtils.h +++ b/src/cascadia/TerminalApp/JsonUtils.h @@ -67,6 +67,13 @@ namespace TerminalApp::JsonUtils using Type = typename std::decay::type; static constexpr bool IsOptional = true; }; + + template<> + struct DeduceOptional<::winrt::hstring> + { + using Type = typename ::winrt::hstring; + static constexpr bool IsOptional = true; + }; } class DeserializationError : public std::runtime_error @@ -269,10 +276,25 @@ namespace TerminalApp::JsonUtils } }; - // (GUID and winrt::guid are mutually convertible!) + // GUID and winrt::guid are mutually convertible, + // but IReference throws some of this off template<> - struct ConversionTrait : public ConversionTrait + struct ConversionTrait { + winrt::guid FromJson(const Json::Value& json) const + { + return static_cast(ConversionTrait{}.FromJson(json)); + } + + bool CanConvert(const Json::Value& json) const + { + return ConversionTrait{}.CanConvert(json); + } + + std::string TypeDescription() const + { + return ConversionTrait{}.TypeDescription(); + } }; template<> @@ -300,6 +322,27 @@ namespace TerminalApp::JsonUtils } }; +#ifdef WINRT_Windows_UI_H + template<> + struct ConversionTrait + { + winrt::Windows::UI::Color FromJson(const Json::Value& json) const + { + return static_cast(ConversionTrait{}.FromJson(json)); + } + + bool CanConvert(const Json::Value& json) const + { + return ConversionTrait{}.CanConvert(json); + } + + std::string TypeDescription() const + { + return ConversionTrait{}.TypeDescription(); + } + }; +#endif + template struct EnumMapper { diff --git a/src/cascadia/TerminalApp/Pane.cpp b/src/cascadia/TerminalApp/Pane.cpp index 180100f4a97..754c7e56c52 100644 --- a/src/cascadia/TerminalApp/Pane.cpp +++ b/src/cascadia/TerminalApp/Pane.cpp @@ -323,9 +323,9 @@ void Pane::_ControlConnectionStateChangedHandler(const TermControl& /*sender*/, auto paneProfile = settings.FindProfile(_profile.value()); if (paneProfile) { - auto mode = paneProfile->GetCloseOnExitMode(); - if ((mode == CloseOnExitMode::Always) || - (mode == CloseOnExitMode::Graceful && newConnectionState == ConnectionState::Closed)) + auto mode = paneProfile.CloseOnExit(); + if ((mode == winrt::TerminalApp::CloseOnExitMode::Always) || + (mode == winrt::TerminalApp::CloseOnExitMode::Graceful && newConnectionState == ConnectionState::Closed)) { _ClosedHandlers(nullptr, nullptr); } diff --git a/src/cascadia/TerminalApp/PowershellCoreProfileGenerator.cpp b/src/cascadia/TerminalApp/PowershellCoreProfileGenerator.cpp index 2c2ba87d48a..364a42e0c19 100644 --- a/src/cascadia/TerminalApp/PowershellCoreProfileGenerator.cpp +++ b/src/cascadia/TerminalApp/PowershellCoreProfileGenerator.cpp @@ -136,6 +136,7 @@ namespace } using namespace ::TerminalApp; +using namespace winrt::TerminalApp; // Function Description: // - Finds all powershell instances with the traditional layout under a directory. @@ -286,7 +287,7 @@ static std::vector _collectPowerShellInstances() // Legacy GUIDs: // - PowerShell Core 574e775e-4f2a-5b96-ac1e-a2962a402336 -static constexpr GUID PowershellCoreGuid{ 0x574e775e, 0x4f2a, 0x5b96, { 0xac, 0x1e, 0xa2, 0x96, 0x2a, 0x40, 0x23, 0x36 } }; +static constexpr winrt::guid PowershellCoreGuid{ 0x574e775e, 0x4f2a, 0x5b96, { 0xac, 0x1e, 0xa2, 0x96, 0x2a, 0x40, 0x23, 0x36 } }; std::wstring_view PowershellCoreProfileGenerator::GetNamespace() { @@ -299,20 +300,20 @@ std::wstring_view PowershellCoreProfileGenerator::GetNamespace() // - // Return Value: // - a vector with the PowerShell Core profile, if available. -std::vector PowershellCoreProfileGenerator::GenerateProfiles() +std::vector PowershellCoreProfileGenerator::GenerateProfiles() { - std::vector profiles; + std::vector profiles; auto psInstances = _collectPowerShellInstances(); for (const auto& psI : psInstances) { const auto name = psI.Name(); auto profile{ CreateDefaultProfile(name) }; - profile.SetCommandline(psI.executablePath.wstring()); - profile.SetStartingDirectory(DEFAULT_STARTING_DIRECTORY); - profile.SetColorScheme({ L"Campbell" }); + profile.Commandline(psI.executablePath.wstring()); + profile.StartingDirectory(DEFAULT_STARTING_DIRECTORY); + profile.ColorSchemeName(L"Campbell"); - profile.SetIconPath(WI_IsFlagSet(psI.flags, PowerShellFlags::Preview) ? POWERSHELL_PREVIEW_ICON : POWERSHELL_ICON); + profile.IconPath(WI_IsFlagSet(psI.flags, PowerShellFlags::Preview) ? POWERSHELL_PREVIEW_ICON : POWERSHELL_ICON); profiles.emplace_back(std::move(profile)); } @@ -322,8 +323,8 @@ std::vector PowershellCoreProfileGenerator::GenerateProfil // This will turn the anchored default profile into "PowerShell Core Latest for Native Architecture through Store" // (or the closest approximation thereof). It may choose a preview instance as the "best" if it is a higher version. auto firstProfile = profiles.begin(); - firstProfile->SetGuid(PowershellCoreGuid); - firstProfile->SetName(POWERSHELL_PREFERRED_PROFILE_NAME); + firstProfile->Guid(PowershellCoreGuid); + firstProfile->Name(POWERSHELL_PREFERRED_PROFILE_NAME); } return profiles; diff --git a/src/cascadia/TerminalApp/PowershellCoreProfileGenerator.h b/src/cascadia/TerminalApp/PowershellCoreProfileGenerator.h index eb529358843..c32c9410c92 100644 --- a/src/cascadia/TerminalApp/PowershellCoreProfileGenerator.h +++ b/src/cascadia/TerminalApp/PowershellCoreProfileGenerator.h @@ -29,6 +29,6 @@ namespace TerminalApp ~PowershellCoreProfileGenerator() = default; std::wstring_view GetNamespace() override; - std::vector GenerateProfiles() override; + std::vector GenerateProfiles() override; }; }; diff --git a/src/cascadia/TerminalApp/Profile.cpp b/src/cascadia/TerminalApp/Profile.cpp index b1ad96ae3f2..5a594171e68 100644 --- a/src/cascadia/TerminalApp/Profile.cpp +++ b/src/cascadia/TerminalApp/Profile.cpp @@ -11,10 +11,14 @@ #include "LegacyProfileGeneratorNamespaces.h" #include "TerminalSettingsSerializationHelpers.h" +#include "Profile.g.cpp" + using namespace TerminalApp; -using namespace winrt::TerminalApp; +using namespace winrt::TerminalApp::implementation; using namespace winrt::Microsoft::Terminal::TerminalControl; +using namespace winrt::Windows::UI; using namespace winrt::Windows::UI::Xaml; +using namespace winrt::Windows::Foundation; using namespace ::Microsoft::Console; static constexpr std::string_view NameKey{ "name" }; @@ -55,77 +59,13 @@ static constexpr std::string_view RetroTerminalEffectKey{ "experimental.retroTer static constexpr std::string_view AntialiasingModeKey{ "antialiasingMode" }; static constexpr std::string_view TabColorKey{ "tabColor" }; -Profile::Profile() : - Profile(std::nullopt) -{ -} - -Profile::Profile(const std::optional& guid) : - _guid(guid), - _name{ L"Default" }, - _schemeName{ L"Campbell" }, - _hidden{ false }, - - _defaultForeground{}, - _defaultBackground{}, - _selectionBackground{}, - _cursorColor{}, - _tabTitle{}, - _suppressApplicationTitle{}, - _historySize{ DEFAULT_HISTORY_SIZE }, - _snapOnInput{ true }, - _altGrAliasing{ true }, - _cursorShape{ CursorStyle::Bar }, - _cursorHeight{ DEFAULT_CURSOR_HEIGHT }, - - _connectionType{}, - _commandline{ L"cmd.exe" }, - _startingDirectory{}, - _fontFace{ DEFAULT_FONT_FACE }, - _fontSize{ DEFAULT_FONT_SIZE }, - /* _fontWeight is initialized below because the structure won't accept a uint16_t directly */ - _acrylicTransparency{ 0.5 }, - _useAcrylic{ false }, - _scrollbarState{}, - _closeOnExitMode{ CloseOnExitMode::Graceful }, - _padding{ DEFAULT_PADDING }, - _icon{}, - _backgroundImage{}, - _backgroundImageOpacity{}, - _backgroundImageStretchMode{}, - _backgroundImageAlignment{}, - _retroTerminalEffect{}, - _antialiasingMode{ TextAntialiasingMode::Grayscale } -{ - winrt::Windows::UI::Text::FontWeight weight; - weight.Weight = DEFAULT_FONT_WEIGHT; - _fontWeight = weight; -} - -Profile::~Profile() -{ -} - -bool Profile::HasGuid() const noexcept -{ - return _guid.has_value(); -} - -bool Profile::HasSource() const noexcept -{ - return _source.has_value(); -} - -GUID Profile::GetGuid() const +Profile::Profile() { - // This can throw if we never had our guid set to a legitimate value. - THROW_HR_IF_MSG(E_FAIL, !_guid.has_value(), "Profile._guid always expected to have a value"); - return _guid.value(); } -void Profile::SetSource(std::wstring_view sourceNamespace) noexcept +Profile::Profile(guid guid) : + _Guid(guid) { - _source = sourceNamespace; } // Method Description: @@ -135,108 +75,97 @@ void Profile::SetSource(std::wstring_view sourceNamespace) noexcept // - schemes: a list of schemes to look for our color scheme in, if we have one. // Return Value: // - a new TerminalSettings object with our settings in it. -TerminalSettings Profile::CreateTerminalSettings(const std::unordered_map& schemes) const +winrt::TerminalApp::TerminalSettings Profile::CreateTerminalSettings(const std::unordered_map& schemes) const { - TerminalSettings terminalSettings{}; + winrt::TerminalApp::TerminalSettings terminalSettings{}; // Fill in the Terminal Setting's CoreSettings from the profile - terminalSettings.HistorySize(_historySize); - terminalSettings.SnapOnInput(_snapOnInput); - terminalSettings.AltGrAliasing(_altGrAliasing); - terminalSettings.CursorHeight(_cursorHeight); - terminalSettings.CursorShape(_cursorShape); + terminalSettings.HistorySize(_HistorySize); + terminalSettings.SnapOnInput(_SnapOnInput); + terminalSettings.AltGrAliasing(_AltGrAliasing); + terminalSettings.CursorHeight(_CursorHeight); + terminalSettings.CursorShape(_CursorShape); // Fill in the remaining properties from the profile - terminalSettings.ProfileName(_name); - terminalSettings.UseAcrylic(_useAcrylic); - terminalSettings.TintOpacity(_acrylicTransparency); + terminalSettings.ProfileName(_Name); + terminalSettings.UseAcrylic(_UseAcrylic); + terminalSettings.TintOpacity(_AcrylicOpacity); - terminalSettings.FontFace(_fontFace); - terminalSettings.FontSize(_fontSize); - terminalSettings.FontWeight(_fontWeight); - terminalSettings.Padding(_padding); + terminalSettings.FontFace(_FontFace); + terminalSettings.FontSize(_FontSize); + terminalSettings.FontWeight(_FontWeight); + terminalSettings.Padding(_Padding); - terminalSettings.Commandline(_commandline); + terminalSettings.Commandline(_Commandline); - if (_startingDirectory) + if (!_StartingDirectory.empty()) { - const auto evaluatedDirectory = Profile::EvaluateStartingDirectory(_startingDirectory.value()); + const auto evaluatedDirectory = Profile::EvaluateStartingDirectory(_StartingDirectory.c_str()); terminalSettings.StartingDirectory(evaluatedDirectory); } // GH#2373: Use the tabTitle as the starting title if it exists, otherwise // use the profile name - terminalSettings.StartingTitle(_tabTitle ? _tabTitle.value() : _name); + terminalSettings.StartingTitle(!_TabTitle.empty() ? _TabTitle : _Name); - if (_suppressApplicationTitle) + if (_SuppressApplicationTitle) { - terminalSettings.SuppressApplicationTitle(_suppressApplicationTitle); + terminalSettings.SuppressApplicationTitle(_SuppressApplicationTitle); } - if (_schemeName) + if (!_ColorSchemeName.empty()) { - const auto found = schemes.find(_schemeName.value()); + const auto found = schemes.find(_ColorSchemeName.c_str()); if (found != schemes.end()) { found->second.ApplyScheme(terminalSettings); } } - if (_defaultForeground) + if (_Foreground) { - terminalSettings.DefaultForeground(_defaultForeground.value()); + const til::color colorRef{ _Foreground.Value() }; + terminalSettings.DefaultForeground(static_cast(colorRef)); } - if (_defaultBackground) + if (_Background) { - terminalSettings.DefaultBackground(_defaultBackground.value()); + const til::color colorRef{ _Background.Value() }; + terminalSettings.DefaultBackground(static_cast(colorRef)); } - if (_selectionBackground) + if (_SelectionBackground) { - terminalSettings.SelectionBackground(_selectionBackground.value()); + const til::color colorRef{ _SelectionBackground.Value() }; + terminalSettings.SelectionBackground(static_cast(colorRef)); } - if (_cursorColor) + if (_CursorColor) { - terminalSettings.CursorColor(_cursorColor.value()); + const til::color colorRef{ _CursorColor.Value() }; + terminalSettings.CursorColor(static_cast(colorRef)); } - if (_scrollbarState) - { - terminalSettings.ScrollState(_scrollbarState.value()); - } + terminalSettings.ScrollState(_ScrollState); - if (HasBackgroundImage()) + if (!_BackgroundImagePath.empty()) { terminalSettings.BackgroundImage(GetExpandedBackgroundImagePath()); } - if (_backgroundImageOpacity) - { - terminalSettings.BackgroundImageOpacity(_backgroundImageOpacity.value()); - } + terminalSettings.BackgroundImageOpacity(_BackgroundImageOpacity); + terminalSettings.BackgroundImageStretchMode(_BackgroundImageStretchMode); - if (_backgroundImageStretchMode) - { - terminalSettings.BackgroundImageStretchMode(_backgroundImageStretchMode.value()); - } + const auto imageHorizontalAlignment = std::get(_BackgroundImageAlignment); + terminalSettings.BackgroundImageHorizontalAlignment(imageHorizontalAlignment); - if (_backgroundImageAlignment) - { - const auto imageHorizontalAlignment = std::get(_backgroundImageAlignment.value()); - const auto imageVerticalAlignment = std::get(_backgroundImageAlignment.value()); - terminalSettings.BackgroundImageHorizontalAlignment(imageHorizontalAlignment); - terminalSettings.BackgroundImageVerticalAlignment(imageVerticalAlignment); - } + const auto imageVerticalAlignment = std::get(_BackgroundImageAlignment); + terminalSettings.BackgroundImageVerticalAlignment(imageVerticalAlignment); - if (_retroTerminalEffect) - { - terminalSettings.RetroTerminalEffect(_retroTerminalEffect.value()); - } + terminalSettings.RetroTerminalEffect(_RetroTerminalEffect); - terminalSettings.AntialiasingMode(_antialiasingMode); + terminalSettings.AntialiasingMode(_AntialiasingMode); - if (_tabColor) + if (_TabColor) { - winrt::Windows::Foundation::IReference colorRef{ _tabColor.value() }; - terminalSettings.TabColor(colorRef); + const til::color colorRef{ _TabColor.Value() }; + terminalSettings.TabColor(static_cast(colorRef)); } return terminalSettings; @@ -258,19 +187,19 @@ Json::Value Profile::GenerateStub() const Json::Value stub; ///// Profile-specific settings ///// - if (_guid.has_value()) + if (_Guid.has_value()) { - stub[JsonKey(GuidKey)] = winrt::to_string(Utils::GuidToString(_guid.value())); + stub[JsonKey(GuidKey)] = winrt::to_string(Utils::GuidToString(*_Guid)); } - stub[JsonKey(NameKey)] = winrt::to_string(_name); + stub[JsonKey(NameKey)] = winrt::to_string(_Name); - if (_source.has_value()) + if (!_Source.empty()) { - stub[JsonKey(SourceKey)] = winrt::to_string(_source.value()); + stub[JsonKey(SourceKey)] = winrt::to_string(_Source); } - stub[JsonKey(HiddenKey)] = _hidden; + stub[JsonKey(HiddenKey)] = _Hidden; return stub; } @@ -281,12 +210,10 @@ Json::Value Profile::GenerateStub() const // - json: an object which should be a serialization of a Profile object. // Return Value: // - a new Profile instance created from the values in `json` -Profile Profile::FromJson(const Json::Value& json) +winrt::com_ptr Profile::FromJson(const Json::Value& json) { - Profile result; - - result.LayerJson(json); - + auto result = winrt::make_self(); + result->LayerJson(json); return result; } @@ -300,16 +227,16 @@ Profile Profile::FromJson(const Json::Value& json) // - true iff the json object has the same `GUID` as we do. bool Profile::ShouldBeLayered(const Json::Value& json) const { - if (!_guid.has_value()) + if (!_Guid.has_value()) { return false; } // First, check that GUIDs match. This is easy. If they don't match, they // should _definitely_ not layer. - if (const auto otherGuid{ JsonUtils::GetValueForKey>(json, GuidKey) }) + if (const auto otherGuid{ JsonUtils::GetValueForKey>(json, GuidKey) }) { - if (otherGuid != _guid) // optional compare takes care of this + if (otherGuid.value() != *_Guid) { return false; } @@ -328,12 +255,12 @@ bool Profile::ShouldBeLayered(const Json::Value& json) const // For profiles with a `source`, also check the `source` property. bool sourceMatches = false; - if (_source.has_value()) + if (!_Source.empty()) { if (otherHadSource) { // If we have a source and the other has a source, compare them! - sourceMatches = otherSource == _source; + sourceMatches = *otherSource == _Source; } else { @@ -341,9 +268,9 @@ bool Profile::ShouldBeLayered(const Json::Value& json) const // `this` is a dynamic profile with a source, and our _source is one // of the legacy DPG namespaces. We're looking to see if the other // json object has the same guid, but _no_ "source" - if (_source.value() == WslGeneratorNamespace || - _source.value() == AzureGeneratorNamespace || - _source.value() == PowershellCoreGeneratorNamespace) + if (_Source == WslGeneratorNamespace || + _Source == AzureGeneratorNamespace || + _Source == PowershellCoreGeneratorNamespace) { sourceMatches = true; } @@ -373,162 +300,51 @@ bool Profile::ShouldBeLayered(const Json::Value& json) const void Profile::LayerJson(const Json::Value& json) { // Profile-specific Settings - JsonUtils::GetValueForKey(json, NameKey, _name); - JsonUtils::GetValueForKey(json, GuidKey, _guid); - JsonUtils::GetValueForKey(json, HiddenKey, _hidden); + JsonUtils::GetValueForKey(json, NameKey, _Name); + JsonUtils::GetValueForKey(json, GuidKey, _Guid); + JsonUtils::GetValueForKey(json, HiddenKey, _Hidden); // Core Settings - JsonUtils::GetValueForKey(json, ForegroundKey, _defaultForeground); - JsonUtils::GetValueForKey(json, BackgroundKey, _defaultBackground); - JsonUtils::GetValueForKey(json, SelectionBackgroundKey, _selectionBackground); - JsonUtils::GetValueForKey(json, CursorColorKey, _cursorColor); - JsonUtils::GetValueForKey(json, ColorSchemeKey, _schemeName); + JsonUtils::GetValueForKey(json, ForegroundKey, _Foreground); + JsonUtils::GetValueForKey(json, BackgroundKey, _Background); + JsonUtils::GetValueForKey(json, SelectionBackgroundKey, _SelectionBackground); + JsonUtils::GetValueForKey(json, CursorColorKey, _CursorColor); + JsonUtils::GetValueForKey(json, ColorSchemeKey, _ColorSchemeName); // TODO:MSFT:20642297 - Use a sentinel value (-1) for "Infinite scrollback" - JsonUtils::GetValueForKey(json, HistorySizeKey, _historySize); - JsonUtils::GetValueForKey(json, SnapOnInputKey, _snapOnInput); - JsonUtils::GetValueForKey(json, AltGrAliasingKey, _altGrAliasing); - JsonUtils::GetValueForKey(json, CursorHeightKey, _cursorHeight); - JsonUtils::GetValueForKey(json, CursorShapeKey, _cursorShape); - JsonUtils::GetValueForKey(json, TabTitleKey, _tabTitle); + JsonUtils::GetValueForKey(json, HistorySizeKey, _HistorySize); + JsonUtils::GetValueForKey(json, SnapOnInputKey, _SnapOnInput); + JsonUtils::GetValueForKey(json, AltGrAliasingKey, _AltGrAliasing); + JsonUtils::GetValueForKey(json, CursorHeightKey, _CursorHeight); + JsonUtils::GetValueForKey(json, CursorShapeKey, _CursorShape); + JsonUtils::GetValueForKey(json, TabTitleKey, _TabTitle); // Control Settings - JsonUtils::GetValueForKey(json, FontWeightKey, _fontWeight); - JsonUtils::GetValueForKey(json, ConnectionTypeKey, _connectionType); - JsonUtils::GetValueForKey(json, CommandlineKey, _commandline); - JsonUtils::GetValueForKey(json, FontFaceKey, _fontFace); - JsonUtils::GetValueForKey(json, FontSizeKey, _fontSize); - JsonUtils::GetValueForKey(json, AcrylicTransparencyKey, _acrylicTransparency); - JsonUtils::GetValueForKey(json, UseAcrylicKey, _useAcrylic); - JsonUtils::GetValueForKey(json, SuppressApplicationTitleKey, _suppressApplicationTitle); - JsonUtils::GetValueForKey(json, CloseOnExitKey, _closeOnExitMode); + JsonUtils::GetValueForKey(json, FontWeightKey, _FontWeight); + JsonUtils::GetValueForKey(json, ConnectionTypeKey, _ConnectionType); + JsonUtils::GetValueForKey(json, CommandlineKey, _Commandline); + JsonUtils::GetValueForKey(json, FontFaceKey, _FontFace); + JsonUtils::GetValueForKey(json, FontSizeKey, _FontSize); + JsonUtils::GetValueForKey(json, AcrylicTransparencyKey, _AcrylicOpacity); + JsonUtils::GetValueForKey(json, UseAcrylicKey, _UseAcrylic); + JsonUtils::GetValueForKey(json, SuppressApplicationTitleKey, _SuppressApplicationTitle); + JsonUtils::GetValueForKey(json, CloseOnExitKey, _CloseOnExit); // Padding was never specified as an integer, but it was a common working mistake. // Allow it to be permissive. - JsonUtils::GetValueForKey(json, PaddingKey, _padding, JsonUtils::PermissiveStringConverter{}); - - JsonUtils::GetValueForKey(json, ScrollbarStateKey, _scrollbarState); - JsonUtils::GetValueForKey(json, StartingDirectoryKey, _startingDirectory); - JsonUtils::GetValueForKey(json, IconKey, _icon); - JsonUtils::GetValueForKey(json, BackgroundImageKey, _backgroundImage); - JsonUtils::GetValueForKey(json, BackgroundImageOpacityKey, _backgroundImageOpacity); - JsonUtils::GetValueForKey(json, BackgroundImageStretchModeKey, _backgroundImageStretchMode); - JsonUtils::GetValueForKey(json, BackgroundImageAlignmentKey, _backgroundImageAlignment); - JsonUtils::GetValueForKey(json, RetroTerminalEffectKey, _retroTerminalEffect); - JsonUtils::GetValueForKey(json, AntialiasingModeKey, _antialiasingMode); - - JsonUtils::GetValueForKey(json, TabColorKey, _tabColor); -} - -void Profile::SetFontFace(std::wstring fontFace) noexcept -{ - _fontFace = std::move(fontFace); -} - -void Profile::SetColorScheme(std::optional schemeName) noexcept -{ - _schemeName = std::move(schemeName); -} - -const std::optional& Profile::GetSchemeName() const noexcept -{ - return _schemeName; -} - -void Profile::SetAcrylicOpacity(double opacity) noexcept -{ - _acrylicTransparency = opacity; -} - -void Profile::SetCommandline(std::wstring cmdline) noexcept -{ - _commandline = std::move(cmdline); -} - -void Profile::SetStartingDirectory(std::wstring startingDirectory) noexcept -{ - _startingDirectory = std::move(startingDirectory); -} - -void Profile::SetName(const std::wstring_view name) noexcept -{ - _name = static_cast(name); -} - -void Profile::SetUseAcrylic(bool useAcrylic) noexcept -{ - _useAcrylic = useAcrylic; -} - -void Profile::SetDefaultForeground(til::color defaultForeground) noexcept -{ - _defaultForeground = defaultForeground; -} - -void Profile::SetDefaultBackground(til::color defaultBackground) noexcept -{ - _defaultBackground = defaultBackground; -} - -void Profile::SetSelectionBackground(til::color selectionBackground) noexcept -{ - _selectionBackground = selectionBackground; -} - -void Profile::SetCloseOnExitMode(CloseOnExitMode mode) noexcept -{ - _closeOnExitMode = mode; -} - -void Profile::SetConnectionType(GUID connectionType) noexcept -{ - _connectionType = connectionType; -} - -bool Profile::HasIcon() const noexcept -{ - return _icon.has_value() && !_icon.value().empty(); -} - -bool Profile::HasBackgroundImage() const noexcept -{ - return _backgroundImage.has_value() && !_backgroundImage.value().empty(); -} - -// Method Description -// - Sets this profile's tab title. -// Arguments: -// - tabTitle: the tab title -void Profile::SetTabTitle(std::wstring tabTitle) noexcept -{ - _tabTitle = std::move(tabTitle); -} - -// Method Description -// - Sets if the application title will be suppressed in this profile. -// Arguments: -// - suppressApplicationTitle: boolean -void Profile::SetSuppressApplicationTitle(bool suppressApplicationTitle) noexcept -{ - _suppressApplicationTitle = suppressApplicationTitle; -} + JsonUtils::GetValueForKey(json, PaddingKey, _Padding, JsonUtils::PermissiveStringConverter{}); -// Method Description: -// - Sets this profile's icon path. -// Arguments: -// - path: the path -void Profile::SetIconPath(std::wstring_view path) -{ - static_assert(!noexcept(_icon.emplace(path))); - _icon.emplace(path); -} + JsonUtils::GetValueForKey(json, ScrollbarStateKey, _ScrollState); + JsonUtils::GetValueForKey(json, StartingDirectoryKey, _StartingDirectory); + JsonUtils::GetValueForKey(json, IconKey, _IconPath); + JsonUtils::GetValueForKey(json, BackgroundImageKey, _BackgroundImagePath); + JsonUtils::GetValueForKey(json, BackgroundImageOpacityKey, _BackgroundImageOpacity); + JsonUtils::GetValueForKey(json, BackgroundImageStretchModeKey, _BackgroundImageStretchMode); + JsonUtils::GetValueForKey(json, BackgroundImageAlignmentKey, _BackgroundImageAlignment); + JsonUtils::GetValueForKey(json, RetroTerminalEffectKey, _RetroTerminalEffect); + JsonUtils::GetValueForKey(json, AntialiasingModeKey, _AntialiasingMode); -// Method Description: -// - Resets the std::optional holding the icon file path string. -// HasIcon() will return false after the execution of this function. -void Profile::ResetIconPath() -{ - _icon.reset(); + JsonUtils::GetValueForKey(json, TabColorKey, _TabColor); } // Method Description: @@ -539,11 +355,11 @@ void Profile::ResetIconPath() // - this profile's icon path, if one is set. Otherwise returns the empty string. winrt::hstring Profile::GetExpandedIconPath() const { - if (!HasIcon()) + if (_IconPath.empty()) { - return { L"" }; + return _IconPath; } - winrt::hstring envExpandedPath{ wil::ExpandEnvironmentStringsW(_icon.value().data()) }; + winrt::hstring envExpandedPath{ wil::ExpandEnvironmentStringsW(_IconPath.c_str()) }; return envExpandedPath; } @@ -554,68 +370,11 @@ winrt::hstring Profile::GetExpandedIconPath() const // - This profile's expanded background image path / the empty string. winrt::hstring Profile::GetExpandedBackgroundImagePath() const { - winrt::hstring result{}; - - if (HasBackgroundImage()) + if (_BackgroundImagePath.empty()) { - result = wil::ExpandEnvironmentStringsW(_backgroundImage.value().data()); + return _BackgroundImagePath; } - - return result; -} - -// Method Description: -// - Resets the std::optional holding the background image file path string. -// HasBackgroundImage() will return false after the execution of this function. -void Profile::ResetBackgroundImagePath() -{ - _backgroundImage.reset(); -} - -// Method Description: -// - Returns the name of this profile. -// Arguments: -// - -// Return Value: -// - the name of this profile -std::wstring_view Profile::GetName() const noexcept -{ - return _name; -} - -bool Profile::GetSuppressApplicationTitle() const noexcept -{ - return _suppressApplicationTitle; -} - -bool Profile::HasConnectionType() const noexcept -{ - return _connectionType.has_value(); -} - -GUID Profile::GetConnectionType() const noexcept -{ - return HasConnectionType() ? - _connectionType.value() : - _GUID{}; -} - -CloseOnExitMode Profile::GetCloseOnExitMode() const noexcept -{ - return _closeOnExitMode; -} - -// Method Description: -// - If a profile is marked hidden, it should not appear in the dropdown list of -// profiles. This setting is used to "remove" default and dynamic profiles -// from the list of profiles. -// Arguments: -// - -// Return Value: -// - true iff the profile should be hidden from the list of profiles. -bool Profile::IsHidden() const noexcept -{ - return _hidden; + return winrt::hstring{ wil::ExpandEnvironmentStringsW(_BackgroundImagePath.c_str()) }; } // Method Description: @@ -655,11 +414,11 @@ std::wstring Profile::EvaluateStartingDirectory(const std::wstring& directory) // will _not_ change the profile's GUID. void Profile::GenerateGuidIfNecessary() noexcept { - if (!_guid.has_value()) + if (!_Guid.has_value()) { // Always use the name to generate the temporary GUID. That way, across // reloads, we'll generate the same static GUID. - _guid = Profile::_GenerateGuidForProfile(_name, _source); + _Guid = Profile::_GenerateGuidForProfile(_Name, _Source); TraceLoggingWrite( g_hTerminalAppProvider, @@ -690,18 +449,18 @@ bool Profile::IsDynamicProfileObject(const Json::Value& json) // - name: The name to generate a unique GUID from // Return Value: // - a uuidv5 GUID generated from the given name. -GUID Profile::_GenerateGuidForProfile(const std::wstring& name, const std::optional& source) noexcept +winrt::guid Profile::_GenerateGuidForProfile(const hstring& name, const hstring& source) noexcept { // If we have a _source, then we can from a dynamic profile generator. Use // our source to build the namespace guid, instead of using the default GUID. - const GUID namespaceGuid = source.has_value() ? - Utils::CreateV5Uuid(RUNTIME_GENERATED_PROFILE_NAMESPACE_GUID, gsl::as_bytes(gsl::make_span(source.value()))) : + const GUID namespaceGuid = !source.empty() ? + Utils::CreateV5Uuid(RUNTIME_GENERATED_PROFILE_NAMESPACE_GUID, gsl::as_bytes(gsl::make_span(source))) : RUNTIME_GENERATED_PROFILE_NAMESPACE_GUID; // Always use the name to generate the temporary GUID. That way, across // reloads, we'll generate the same static GUID. - return Utils::CreateV5Uuid(namespaceGuid, gsl::as_bytes(gsl::make_span(name))); + return { Utils::CreateV5Uuid(namespaceGuid, gsl::as_bytes(gsl::make_span(name))) }; } // Function Description: @@ -712,20 +471,67 @@ GUID Profile::_GenerateGuidForProfile(const std::wstring& name, const std::optio // (given the `name`) // Return Value: // - The json's `guid`, or a guid synthesized for it. -GUID Profile::GetGuidOrGenerateForJson(const Json::Value& json) noexcept +winrt::guid Profile::GetGuidOrGenerateForJson(const Json::Value& json) noexcept { if (const auto guid{ JsonUtils::GetValueForKey>(json, GuidKey) }) { - return guid.value(); + return { guid.value() }; } - const auto name{ JsonUtils::GetValueForKey(json, NameKey) }; - const auto source{ JsonUtils::GetValueForKey>(json, SourceKey) }; + const auto name{ JsonUtils::GetValueForKey(json, NameKey) }; + const auto source{ JsonUtils::GetValueForKey(json, SourceKey) }; return Profile::_GenerateGuidForProfile(name, source); } -void Profile::SetRetroTerminalEffect(bool value) noexcept +const HorizontalAlignment Profile::BackgroundImageHorizontalAlignment() const noexcept +{ + return std::get(_BackgroundImageAlignment); +} + +void Profile::BackgroundImageHorizontalAlignment(const HorizontalAlignment& value) noexcept +{ + std::get(_BackgroundImageAlignment) = value; +} + +const VerticalAlignment Profile::BackgroundImageVerticalAlignment() const noexcept +{ + return std::get(_BackgroundImageAlignment); +} + +void Profile::BackgroundImageVerticalAlignment(const VerticalAlignment& value) noexcept +{ + std::get(_BackgroundImageAlignment) = value; +} + +bool Profile::HasGuid() const noexcept +{ + return _Guid.has_value(); +} + +winrt::guid Profile::Guid() const +{ + // This can throw if we never had our guid set to a legitimate value. + THROW_HR_IF_MSG(E_FAIL, !_Guid.has_value(), "Profile._guid always expected to have a value"); + return *_Guid; +} + +void Profile::Guid(winrt::guid guid) noexcept +{ + _Guid = guid; +} + +bool Profile::HasConnectionType() const noexcept +{ + return _ConnectionType.has_value(); +} + +winrt::guid Profile::ConnectionType() const noexcept +{ + return *_ConnectionType; +} + +void Profile::ConnectionType(winrt::guid conType) noexcept { - _retroTerminalEffect = value; + _ConnectionType = conType; } diff --git a/src/cascadia/TerminalApp/Profile.h b/src/cascadia/TerminalApp/Profile.h index 2ab88f0c884..823eaae42fa 100644 --- a/src/cascadia/TerminalApp/Profile.h +++ b/src/cascadia/TerminalApp/Profile.h @@ -14,8 +14,13 @@ Author(s): --*/ #pragma once + +#include "Profile.g.h" #include "ColorScheme.g.h" -#include "SettingsTypes.h" + +#include "../inc/cppwinrt_utils.h" +#include "JsonUtils.h" +#include // fwdecl unittest classes namespace TerminalAppLocalTests @@ -33,123 +38,106 @@ namespace TerminalAppUnitTests // GUID specified manually. constexpr GUID RUNTIME_GENERATED_PROFILE_NAMESPACE_GUID = { 0xf65ddb7e, 0x706b, 0x4499, { 0x8a, 0x50, 0x40, 0x31, 0x3c, 0xaf, 0x51, 0x0a } }; -namespace TerminalApp +namespace winrt::TerminalApp::implementation { - class Profile; + struct Profile : ProfileT + { + public: + Profile(); + Profile(guid guid); + + TerminalApp::TerminalSettings CreateTerminalSettings(const std::unordered_map& schemes) const; + + Json::Value GenerateStub() const; + static com_ptr FromJson(const Json::Value& json); + bool ShouldBeLayered(const Json::Value& json) const; + void LayerJson(const Json::Value& json); + static bool IsDynamicProfileObject(const Json::Value& json); + + hstring GetExpandedIconPath() const; + hstring GetExpandedBackgroundImagePath() const; + void GenerateGuidIfNecessary() noexcept; + static guid GetGuidOrGenerateForJson(const Json::Value& json) noexcept; + + bool HasGuid() const noexcept; + winrt::guid Guid() const; + void Guid(winrt::guid guid) noexcept; + + bool HasConnectionType() const noexcept; + winrt::guid ConnectionType() const noexcept; + void ConnectionType(winrt::guid conType) noexcept; + + // BackgroundImageAlignment is 1 setting saved as 2 separate values + const Windows::UI::Xaml::HorizontalAlignment BackgroundImageHorizontalAlignment() const noexcept; + void BackgroundImageHorizontalAlignment(const Windows::UI::Xaml::HorizontalAlignment& value) noexcept; + const Windows::UI::Xaml::VerticalAlignment BackgroundImageVerticalAlignment() const noexcept; + void BackgroundImageVerticalAlignment(const Windows::UI::Xaml::VerticalAlignment& value) noexcept; + + GETSET_PROPERTY(hstring, Name, L"Default"); + GETSET_PROPERTY(hstring, Source); + GETSET_PROPERTY(bool, Hidden, false); + + GETSET_PROPERTY(hstring, IconPath); + + GETSET_PROPERTY(CloseOnExitMode, CloseOnExit, CloseOnExitMode::Graceful); + GETSET_PROPERTY(hstring, TabTitle); + GETSET_PROPERTY(Windows::Foundation::IReference, TabColor); + GETSET_PROPERTY(bool, SuppressApplicationTitle, false); + + GETSET_PROPERTY(bool, UseAcrylic, false); + GETSET_PROPERTY(double, AcrylicOpacity, 0.5); + GETSET_PROPERTY(Microsoft::Terminal::TerminalControl::ScrollbarState, ScrollState, Microsoft::Terminal::TerminalControl::ScrollbarState::Visible); + + GETSET_PROPERTY(hstring, FontFace, DEFAULT_FONT_FACE); + GETSET_PROPERTY(int32_t, FontSize, DEFAULT_FONT_SIZE); + GETSET_PROPERTY(Windows::UI::Text::FontWeight, FontWeight, DEFAULT_FONT_WEIGHT); + GETSET_PROPERTY(hstring, Padding, DEFAULT_PADDING); + + GETSET_PROPERTY(hstring, Commandline, L"cmd.exe"); + GETSET_PROPERTY(hstring, StartingDirectory); + + GETSET_PROPERTY(hstring, BackgroundImagePath); + GETSET_PROPERTY(double, BackgroundImageOpacity, 1.0); + GETSET_PROPERTY(Windows::UI::Xaml::Media::Stretch, BackgroundImageStretchMode, Windows::UI::Xaml::Media::Stretch::Fill); + + GETSET_PROPERTY(Microsoft::Terminal::TerminalControl::TextAntialiasingMode, AntialiasingMode, Microsoft::Terminal::TerminalControl::TextAntialiasingMode::Grayscale); + GETSET_PROPERTY(bool, RetroTerminalEffect, false); + GETSET_PROPERTY(bool, ForceFullRepaintRendering, false); + GETSET_PROPERTY(bool, SoftwareRendering, false); + + GETSET_PROPERTY(hstring, ColorSchemeName, L"Campbell"); + GETSET_PROPERTY(Windows::Foundation::IReference, Foreground); + GETSET_PROPERTY(Windows::Foundation::IReference, Background); + GETSET_PROPERTY(Windows::Foundation::IReference, SelectionBackground); + GETSET_PROPERTY(Windows::Foundation::IReference, CursorColor); + + GETSET_PROPERTY(int32_t, HistorySize, DEFAULT_HISTORY_SIZE); + GETSET_PROPERTY(bool, SnapOnInput, true); + GETSET_PROPERTY(bool, AltGrAliasing, true); + + GETSET_PROPERTY(Microsoft::Terminal::TerminalControl::CursorStyle, CursorShape, Microsoft::Terminal::TerminalControl::CursorStyle::Bar); + GETSET_PROPERTY(uint32_t, CursorHeight, DEFAULT_CURSOR_HEIGHT); + + private: + std::optional _Guid{ std::nullopt }; + std::optional _ConnectionType{ std::nullopt }; + std::tuple _BackgroundImageAlignment{ + Windows::UI::Xaml::HorizontalAlignment::Center, + Windows::UI::Xaml::VerticalAlignment::Center + }; + + static std::wstring EvaluateStartingDirectory(const std::wstring& directory); + + static guid _GenerateGuidForProfile(const hstring& name, const hstring& source) noexcept; + + friend class TerminalAppLocalTests::SettingsTests; + friend class TerminalAppLocalTests::ProfileTests; + friend class TerminalAppUnitTests::JsonTests; + friend class TerminalAppUnitTests::DynamicProfileTests; + }; } -class TerminalApp::Profile final +namespace winrt::TerminalApp::factory_implementation { -public: - Profile(); - explicit Profile(const std::optional& guid); - - ~Profile(); - - winrt::TerminalApp::TerminalSettings CreateTerminalSettings(const std::unordered_map& schemes) const; - - Json::Value GenerateStub() const; - static Profile FromJson(const Json::Value& json); - bool ShouldBeLayered(const Json::Value& json) const; - void LayerJson(const Json::Value& json); - static bool IsDynamicProfileObject(const Json::Value& json); - - bool HasGuid() const noexcept; - bool HasSource() const noexcept; - GUID GetGuid() const; - void SetSource(std::wstring_view sourceNamespace) noexcept; - std::wstring_view GetName() const noexcept; - bool HasConnectionType() const noexcept; - GUID GetConnectionType() const noexcept; - - void SetGuid(GUID guid) noexcept { _guid = guid; } - void SetFontFace(std::wstring fontFace) noexcept; - void SetColorScheme(std::optional schemeName) noexcept; - const std::optional& GetSchemeName() const noexcept; - void SetTabTitle(std::wstring tabTitle) noexcept; - void SetSuppressApplicationTitle(bool suppressApplicationTitle) noexcept; - void SetAcrylicOpacity(double opacity) noexcept; - void SetCommandline(std::wstring cmdline) noexcept; - void SetStartingDirectory(std::wstring startingDirectory) noexcept; - void SetName(const std::wstring_view name) noexcept; - void SetUseAcrylic(bool useAcrylic) noexcept; - void SetDefaultForeground(til::color defaultForeground) noexcept; - void SetDefaultBackground(til::color defaultBackground) noexcept; - void SetSelectionBackground(til::color selectionBackground) noexcept; - void SetCloseOnExitMode(CloseOnExitMode mode) noexcept; - void SetConnectionType(GUID connectionType) noexcept; - - bool HasIcon() const noexcept; - winrt::hstring GetExpandedIconPath() const; - void SetIconPath(std::wstring_view path); - void ResetIconPath(); - - bool HasBackgroundImage() const noexcept; - winrt::hstring GetExpandedBackgroundImagePath() const; - void ResetBackgroundImagePath(); - - CloseOnExitMode GetCloseOnExitMode() const noexcept; - bool GetSuppressApplicationTitle() const noexcept; - bool IsHidden() const noexcept; - - void GenerateGuidIfNecessary() noexcept; - - static GUID GetGuidOrGenerateForJson(const Json::Value& json) noexcept; - - void SetRetroTerminalEffect(bool value) noexcept; - -private: - static std::wstring EvaluateStartingDirectory(const std::wstring& directory); - - static GUID _GenerateGuidForProfile(const std::wstring& name, const std::optional& source) noexcept; - - std::optional _guid{ std::nullopt }; - std::optional _source{ std::nullopt }; - std::wstring _name; - std::optional _connectionType; - bool _hidden; - - // If this is set, then our colors should come from the associated color scheme - std::optional _schemeName; - - std::optional _defaultForeground; - std::optional _defaultBackground; - std::optional _selectionBackground; - std::optional _cursorColor; - std::optional _tabTitle; - std::optional _tabColor; - bool _suppressApplicationTitle; - int32_t _historySize; - bool _snapOnInput; - bool _altGrAliasing; - uint32_t _cursorHeight; - winrt::Microsoft::Terminal::TerminalControl::CursorStyle _cursorShape; - - std::wstring _commandline; - std::wstring _fontFace; - std::optional _startingDirectory; - int32_t _fontSize; - winrt::Windows::UI::Text::FontWeight _fontWeight; - double _acrylicTransparency; - bool _useAcrylic; - - std::optional _backgroundImage; - std::optional _backgroundImageOpacity; - std::optional _backgroundImageStretchMode; - std::optional> _backgroundImageAlignment; - - std::optional<::winrt::Microsoft::Terminal::TerminalControl::ScrollbarState> _scrollbarState; - CloseOnExitMode _closeOnExitMode; - std::wstring _padding; - - std::optional _icon; - - winrt::Microsoft::Terminal::TerminalControl::TextAntialiasingMode _antialiasingMode; - - friend class TerminalAppLocalTests::SettingsTests; - friend class TerminalAppLocalTests::ProfileTests; - friend class TerminalAppUnitTests::JsonTests; - friend class TerminalAppUnitTests::DynamicProfileTests; - - std::optional _retroTerminalEffect; -}; + BASIC_FACTORY(Profile); +} diff --git a/src/cascadia/TerminalApp/Profile.idl b/src/cascadia/TerminalApp/Profile.idl new file mode 100644 index 00000000000..d8de2ec7d67 --- /dev/null +++ b/src/cascadia/TerminalApp/Profile.idl @@ -0,0 +1,70 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +namespace TerminalApp +{ + enum CloseOnExitMode + { + Never = 0, + Graceful, + Always + }; + + [default_interface] runtimeclass Profile { + Profile(); + Profile(Guid guid); + + String Name; + Boolean HasGuid(); + Guid Guid; + String Source; + Boolean HasConnectionType(); + Guid ConnectionType; + Boolean Hidden; + + String IconPath; + String GetExpandedIconPath(); + + CloseOnExitMode CloseOnExit; + String TabTitle; + Windows.Foundation.IReference TabColor; + Boolean SuppressApplicationTitle; + + Boolean UseAcrylic; + Double AcrylicOpacity; + Microsoft.Terminal.TerminalControl.ScrollbarState ScrollState; + + String FontFace; + Int32 FontSize; + Windows.UI.Text.FontWeight FontWeight; + String Padding; + + String Commandline; + String StartingDirectory; + + String BackgroundImagePath; + String GetExpandedBackgroundImagePath(); + Double BackgroundImageOpacity; + Windows.UI.Xaml.Media.Stretch BackgroundImageStretchMode; + Windows.UI.Xaml.HorizontalAlignment BackgroundImageHorizontalAlignment; + Windows.UI.Xaml.VerticalAlignment BackgroundImageVerticalAlignment; + + Microsoft.Terminal.TerminalControl.TextAntialiasingMode AntialiasingMode; + Boolean RetroTerminalEffect; + Boolean ForceFullRepaintRendering; + Boolean SoftwareRendering; + + String ColorSchemeName; + Windows.Foundation.IReference Foreground; + Windows.Foundation.IReference Background; + Windows.Foundation.IReference SelectionBackground; + Windows.Foundation.IReference CursorColor; + + Int32 HistorySize; + Boolean SnapOnInput; + Boolean AltGrAliasing; + + Microsoft.Terminal.TerminalControl.CursorStyle CursorShape; + UInt32 CursorHeight; + } +} diff --git a/src/cascadia/TerminalApp/SettingsTypes.h b/src/cascadia/TerminalApp/SettingsTypes.h index 5a3cc3da00c..946b1951cba 100644 --- a/src/cascadia/TerminalApp/SettingsTypes.h +++ b/src/cascadia/TerminalApp/SettingsTypes.h @@ -13,13 +13,6 @@ Module Name: namespace TerminalApp { - enum class CloseOnExitMode - { - Never = 0, - Graceful, - Always - }; - struct LaunchPosition { std::optional x; diff --git a/src/cascadia/TerminalApp/TelnetGenerator.h b/src/cascadia/TerminalApp/TelnetGenerator.h index 85282b7c4d9..c7356b65fd9 100644 --- a/src/cascadia/TerminalApp/TelnetGenerator.h +++ b/src/cascadia/TerminalApp/TelnetGenerator.h @@ -16,4 +16,4 @@ Author(s): #pragma once // {311153fb-d3f0-4ac6-b920-038de7cf5289} -static constexpr GUID TelnetConnectionType = { 0x311153fb, 0xd3f0, 0x4ac6, { 0xb9, 0x20, 0x03, 0x8d, 0xe7, 0xcf, 0x52, 0x89 } }; +static constexpr winrt::guid TelnetConnectionType = { 0x311153fb, 0xd3f0, 0x4ac6, { 0xb9, 0x20, 0x03, 0x8d, 0xe7, 0xcf, 0x52, 0x89 } }; diff --git a/src/cascadia/TerminalApp/TerminalAppLib.vcxproj b/src/cascadia/TerminalApp/TerminalAppLib.vcxproj index 807f9464445..a562ed31e30 100644 --- a/src/cascadia/TerminalApp/TerminalAppLib.vcxproj +++ b/src/cascadia/TerminalApp/TerminalAppLib.vcxproj @@ -108,7 +108,9 @@ ColorScheme.idl - + + Profile.idl + @@ -187,7 +189,9 @@ ColorScheme.idl - + + Profile.idl + @@ -276,6 +280,7 @@ + diff --git a/src/cascadia/TerminalApp/TerminalAppLib.vcxproj.filters b/src/cascadia/TerminalApp/TerminalAppLib.vcxproj.filters index 3056b71130d..3a2e600fd71 100644 --- a/src/cascadia/TerminalApp/TerminalAppLib.vcxproj.filters +++ b/src/cascadia/TerminalApp/TerminalAppLib.vcxproj.filters @@ -151,6 +151,9 @@ settings + + settings + diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index 318fe967f9d..5c62c5ade3e 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -477,13 +477,12 @@ namespace winrt::TerminalApp::implementation _SetAcceleratorForMenuItem(profileMenuItem, profileKeyChord); } - auto profileName = profile.GetName(); - winrt::hstring hName{ profileName }; - profileMenuItem.Text(hName); + auto profileName = profile.Name(); + profileMenuItem.Text(profileName); // If there's an icon set for this profile, set it as the icon for // this flyout item. - if (profile.HasIcon()) + if (!profile.IconPath().empty()) { auto iconSource = GetColoredIcon(profile.GetExpandedIconPath()); @@ -493,7 +492,7 @@ namespace winrt::TerminalApp::implementation Automation::AutomationProperties::SetAccessibilityView(iconElement, Automation::Peers::AccessibilityView::Raw); } - if (profile.GetGuid() == defaultProfileGuid) + if (profile.Guid() == winrt::guid{ defaultProfileGuid }) { // Contrast the default profile with others in font weight. profileMenuItem.FontWeight(FontWeights::Bold()); @@ -726,10 +725,10 @@ namespace winrt::TerminalApp::implementation } // Set this tab's icon to the icon from the user's profile - const auto* const profile = _settings->FindProfile(profileGuid); - if (profile != nullptr && profile->HasIcon()) + const auto profile = _settings->FindProfile(profileGuid); + if (profile != nullptr && !profile.IconPath().empty()) { - newTabImpl->UpdateIcon(profile->GetExpandedIconPath()); + newTabImpl->UpdateIcon(profile.GetExpandedIconPath()); } tabViewItem.PointerPressed({ this, &TerminalPage::_OnTabClick }); @@ -765,20 +764,21 @@ namespace winrt::TerminalApp::implementation TerminalConnection::ITerminalConnection TerminalPage::_CreateConnectionFromSettings(GUID profileGuid, TerminalApp::TerminalSettings settings) { - const auto* const profile = _settings->FindProfile(profileGuid); + const auto profile = _settings->FindProfile(profileGuid); TerminalConnection::ITerminalConnection connection{ nullptr }; - GUID connectionType{ 0 }; - GUID sessionGuid{ 0 }; + winrt::guid connectionType{}; + winrt::guid sessionGuid{}; - if (profile->HasConnectionType()) + const auto hasConnectionType = profile.HasConnectionType(); + if (hasConnectionType) { - connectionType = profile->GetConnectionType(); + connectionType = profile.ConnectionType(); } - if (profile->HasConnectionType() && - profile->GetConnectionType() == AzureConnectionType && + if (hasConnectionType && + connectionType == AzureConnectionType && TerminalConnection::AzureConnection::IsAzureConnectionAvailable()) { // TODO GH#4661: Replace this with directly using the AzCon when our VT is better @@ -793,8 +793,8 @@ namespace winrt::TerminalApp::implementation winrt::guid()); } - else if (profile->HasConnectionType() && - profile->GetConnectionType() == TelnetConnectionType) + else if (hasConnectionType && + connectionType == TelnetConnectionType) { connection = TerminalConnection::TelnetConnection(settings.Commandline()); } @@ -966,10 +966,10 @@ namespace winrt::TerminalApp::implementation if (lastFocusedProfileOpt.has_value()) { const auto lastFocusedProfile = lastFocusedProfileOpt.value(); - const auto* const matchingProfile = _settings->FindProfile(lastFocusedProfile); + const auto matchingProfile = _settings->FindProfile(lastFocusedProfile); if (matchingProfile) { - tab.UpdateIcon(matchingProfile->GetExpandedIconPath()); + tab.UpdateIcon(matchingProfile.GetExpandedIconPath()); } else { @@ -2004,7 +2004,7 @@ namespace winrt::TerminalApp::implementation auto profiles = _settings->GetProfiles(); for (auto& profile : profiles) { - const GUID profileGuid = profile.GetGuid(); + const auto profileGuid = profile.Guid(); try { @@ -2069,7 +2069,7 @@ namespace winrt::TerminalApp::implementation // Return Value: // - IMap TerminalPage::_ExpandCommands(IMapView commandsToExpand, - gsl::span profiles, + gsl::span profiles, const std::unordered_map& schemes) { std::vector<::TerminalApp::SettingsLoadWarnings> warnings; diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h index 02d0af0b53d..b30682ada54 100644 --- a/src/cascadia/TerminalApp/TerminalPage.h +++ b/src/cascadia/TerminalApp/TerminalPage.h @@ -137,7 +137,7 @@ namespace winrt::TerminalApp::implementation void _UpdateTabWidthMode(); void _UpdateCommandsForPalette(); static winrt::Windows::Foundation::Collections::IMap _ExpandCommands(Windows::Foundation::Collections::IMapView commandsToExpand, - gsl::span profiles, + gsl::span profiles, const std::unordered_map& schemes); void _DuplicateTabViewItem(); diff --git a/src/cascadia/TerminalApp/TerminalSettingsSerializationHelpers.h b/src/cascadia/TerminalApp/TerminalSettingsSerializationHelpers.h index 06054eab69a..deb7856063a 100644 --- a/src/cascadia/TerminalApp/TerminalSettingsSerializationHelpers.h +++ b/src/cascadia/TerminalApp/TerminalSettingsSerializationHelpers.h @@ -79,7 +79,7 @@ JSON_ENUM_MAPPER(::winrt::Microsoft::Terminal::TerminalControl::TextAntialiasing // Type Description: // - Helper for converting a user-specified closeOnExit value to its corresponding enum -JSON_ENUM_MAPPER(::TerminalApp::CloseOnExitMode) +JSON_ENUM_MAPPER(::winrt::TerminalApp::CloseOnExitMode) { JSON_MAPPINGS(3) = { pair_type{ "always", ValueType::Always }, @@ -88,7 +88,7 @@ JSON_ENUM_MAPPER(::TerminalApp::CloseOnExitMode) }; // Override mapping parser to add boolean parsing - CloseOnExitMode FromJson(const Json::Value& json) + ::winrt::TerminalApp::CloseOnExitMode FromJson(const Json::Value& json) { if (json.isBool()) { diff --git a/src/cascadia/TerminalApp/WslDistroGenerator.cpp b/src/cascadia/TerminalApp/WslDistroGenerator.cpp index ab63dcf92c7..3f2c655fecb 100644 --- a/src/cascadia/TerminalApp/WslDistroGenerator.cpp +++ b/src/cascadia/TerminalApp/WslDistroGenerator.cpp @@ -16,6 +16,7 @@ static constexpr std::wstring_view DockerDistributionPrefix{ L"docker-desktop" }; using namespace ::TerminalApp; +using namespace winrt::TerminalApp; // Legacy GUIDs: // - Debian 58ad8b0c-3ef8-5f4d-bc6f-13e4c00f2530 @@ -34,9 +35,9 @@ std::wstring_view WslDistroGenerator::GetNamespace() // - // Return Value: // - a vector with all distros for all the installed WSL distros -std::vector WslDistroGenerator::GenerateProfiles() +std::vector WslDistroGenerator::GenerateProfiles() { - std::vector profiles; + std::vector profiles; wil::unique_handle readPipe; wil::unique_handle writePipe; @@ -125,10 +126,10 @@ std::vector WslDistroGenerator::GenerateProfiles() } auto WSLDistro{ CreateDefaultProfile(distName) }; - WSLDistro.SetCommandline(L"wsl.exe -d " + distName); - WSLDistro.SetColorScheme({ L"Campbell" }); - WSLDistro.SetStartingDirectory(DEFAULT_STARTING_DIRECTORY); - WSLDistro.SetIconPath(L"ms-appx:///ProfileIcons/{9acb9455-ca41-5af7-950f-6bca1bc9722f}.png"); + WSLDistro.Commandline(L"wsl.exe -d " + distName); + WSLDistro.ColorSchemeName(L"Campbell"); + WSLDistro.StartingDirectory(DEFAULT_STARTING_DIRECTORY); + WSLDistro.IconPath(L"ms-appx:///ProfileIcons/{9acb9455-ca41-5af7-950f-6bca1bc9722f}.png"); profiles.emplace_back(WSLDistro); } } diff --git a/src/cascadia/TerminalApp/WslDistroGenerator.h b/src/cascadia/TerminalApp/WslDistroGenerator.h index 8f4aedea57b..323ecaaadad 100644 --- a/src/cascadia/TerminalApp/WslDistroGenerator.h +++ b/src/cascadia/TerminalApp/WslDistroGenerator.h @@ -25,6 +25,6 @@ namespace TerminalApp WslDistroGenerator() = default; ~WslDistroGenerator() = default; std::wstring_view GetNamespace() override; - std::vector GenerateProfiles() override; + std::vector GenerateProfiles() override; }; }; diff --git a/src/cascadia/ut_app/DynamicProfileTests.cpp b/src/cascadia/ut_app/DynamicProfileTests.cpp index 312bc0f1d0e..668cf7ba5ce 100644 --- a/src/cascadia/ut_app/DynamicProfileTests.cpp +++ b/src/cascadia/ut_app/DynamicProfileTests.cpp @@ -14,6 +14,7 @@ using namespace Microsoft::Console; using namespace TerminalApp; +using namespace winrt::TerminalApp; using namespace WEX::Logging; using namespace WEX::TestExecution; using namespace WEX::Common; @@ -63,7 +64,7 @@ namespace TerminalAppUnitTests gen.pfnGenerate = []() { std::vector profiles; Profile p0; - p0.SetName(L"profile0"); + p0.Name(L"profile0"); profiles.push_back(p0); return profiles; }; @@ -71,8 +72,8 @@ namespace TerminalAppUnitTests VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest", gen.GetNamespace()); std::vector profiles = gen.GenerateProfiles(); VERIFY_ARE_EQUAL(1u, profiles.size()); - VERIFY_ARE_EQUAL(L"profile0", profiles.at(0).GetName()); - VERIFY_IS_FALSE(profiles.at(0)._guid.has_value()); + VERIFY_ARE_EQUAL(L"profile0", profiles.at(0).Name()); + VERIFY_IS_FALSE(profiles.at(0).HasGuid()); } void DynamicProfileTests::TestSimpleGenerateMultipleGenerators() @@ -81,7 +82,7 @@ namespace TerminalAppUnitTests gen0->pfnGenerate = []() { std::vector profiles; Profile p0; - p0.SetName(L"profile0"); + p0.Name(L"profile0"); profiles.push_back(p0); return profiles; }; @@ -89,7 +90,7 @@ namespace TerminalAppUnitTests gen1->pfnGenerate = []() { std::vector profiles; Profile p0; - p0.SetName(L"profile1"); + p0.Name(L"profile1"); profiles.push_back(p0); return profiles; }; @@ -101,11 +102,11 @@ namespace TerminalAppUnitTests settings._LoadDynamicProfiles(); VERIFY_ARE_EQUAL(2u, settings._profiles.size()); - VERIFY_ARE_EQUAL(L"profile0", settings._profiles.at(0).GetName()); - VERIFY_IS_FALSE(settings._profiles.at(0)._guid.has_value()); + VERIFY_ARE_EQUAL(L"profile0", settings._profiles.at(0).Name()); + VERIFY_IS_FALSE(settings._profiles.at(0).HasGuid()); - VERIFY_ARE_EQUAL(L"profile1", settings._profiles.at(1).GetName()); - VERIFY_IS_FALSE(settings._profiles.at(1)._guid.has_value()); + VERIFY_ARE_EQUAL(L"profile1", settings._profiles.at(1).Name()); + VERIFY_IS_FALSE(settings._profiles.at(1).HasGuid()); } void DynamicProfileTests::TestGenGuidsForProfiles() @@ -119,7 +120,7 @@ namespace TerminalAppUnitTests gen0->pfnGenerate = []() { std::vector profiles; Profile p0; - p0.SetName(L"profile0"); // this is _profiles.at(2) + p0.Name(L"profile0"); // this is _profiles.at(2) profiles.push_back(p0); return profiles; }; @@ -127,8 +128,8 @@ namespace TerminalAppUnitTests gen1->pfnGenerate = []() { std::vector profiles; Profile p0, p1; - p0.SetName(L"profile0"); // this is _profiles.at(3) - p1.SetName(L"profile1"); // this is _profiles.at(4) + p0.Name(L"profile0"); // this is _profiles.at(3) + p1.Name(L"profile1"); // this is _profiles.at(4) profiles.push_back(p0); profiles.push_back(p1); return profiles; @@ -139,60 +140,60 @@ namespace TerminalAppUnitTests settings._profileGenerators.emplace_back(std::move(gen1)); Profile p0, p1; - p0.SetName(L"profile0"); // this is _profiles.at(0) - p1.SetName(L"profile1"); // this is _profiles.at(1) + p0.Name(L"profile0"); // this is _profiles.at(0) + p1.Name(L"profile1"); // this is _profiles.at(1) settings._profiles.push_back(p0); settings._profiles.push_back(p1); settings._LoadDynamicProfiles(); VERIFY_ARE_EQUAL(5u, settings._profiles.size()); - VERIFY_ARE_EQUAL(L"profile0", settings._profiles.at(0).GetName()); - VERIFY_IS_FALSE(settings._profiles.at(0)._guid.has_value()); - VERIFY_IS_FALSE(settings._profiles.at(0)._source.has_value()); + VERIFY_ARE_EQUAL(L"profile0", settings._profiles.at(0).Name()); + VERIFY_IS_FALSE(settings._profiles.at(0).HasGuid()); + VERIFY_IS_TRUE(settings._profiles.at(0).Source().empty()); - VERIFY_ARE_EQUAL(L"profile1", settings._profiles.at(1).GetName()); - VERIFY_IS_FALSE(settings._profiles.at(1)._guid.has_value()); - VERIFY_IS_FALSE(settings._profiles.at(1)._source.has_value()); + VERIFY_ARE_EQUAL(L"profile1", settings._profiles.at(1).Name()); + VERIFY_IS_FALSE(settings._profiles.at(1).HasGuid()); + VERIFY_IS_TRUE(settings._profiles.at(1).Source().empty()); - VERIFY_ARE_EQUAL(L"profile0", settings._profiles.at(2).GetName()); - VERIFY_IS_FALSE(settings._profiles.at(2)._guid.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(2)._source.has_value()); + VERIFY_ARE_EQUAL(L"profile0", settings._profiles.at(2).Name()); + VERIFY_IS_FALSE(settings._profiles.at(2).HasGuid()); + VERIFY_IS_FALSE(settings._profiles.at(2).Source().empty()); - VERIFY_ARE_EQUAL(L"profile0", settings._profiles.at(3).GetName()); - VERIFY_IS_FALSE(settings._profiles.at(3)._guid.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(3)._source.has_value()); + VERIFY_ARE_EQUAL(L"profile0", settings._profiles.at(3).Name()); + VERIFY_IS_FALSE(settings._profiles.at(3).HasGuid()); + VERIFY_IS_FALSE(settings._profiles.at(3).Source().empty()); - VERIFY_ARE_EQUAL(L"profile1", settings._profiles.at(4).GetName()); - VERIFY_IS_FALSE(settings._profiles.at(4)._guid.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(4)._source.has_value()); + VERIFY_ARE_EQUAL(L"profile1", settings._profiles.at(4).Name()); + VERIFY_IS_FALSE(settings._profiles.at(4).HasGuid()); + VERIFY_IS_FALSE(settings._profiles.at(4).Source().empty()); settings._ValidateProfilesHaveGuid(); - VERIFY_IS_TRUE(settings._profiles.at(0)._guid.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(1)._guid.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(2)._guid.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(3)._guid.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(4)._guid.has_value()); + VERIFY_IS_TRUE(settings._profiles.at(0).HasGuid()); + VERIFY_IS_TRUE(settings._profiles.at(1).HasGuid()); + VERIFY_IS_TRUE(settings._profiles.at(2).HasGuid()); + VERIFY_IS_TRUE(settings._profiles.at(3).HasGuid()); + VERIFY_IS_TRUE(settings._profiles.at(4).HasGuid()); - VERIFY_ARE_NOT_EQUAL(settings._profiles.at(0)._guid.value(), - settings._profiles.at(1)._guid.value()); - VERIFY_ARE_NOT_EQUAL(settings._profiles.at(0)._guid.value(), - settings._profiles.at(2)._guid.value()); - VERIFY_ARE_NOT_EQUAL(settings._profiles.at(0)._guid.value(), - settings._profiles.at(3)._guid.value()); + VERIFY_ARE_NOT_EQUAL(settings._profiles.at(0).Guid(), + settings._profiles.at(1).Guid()); + VERIFY_ARE_NOT_EQUAL(settings._profiles.at(0).Guid(), + settings._profiles.at(2).Guid()); + VERIFY_ARE_NOT_EQUAL(settings._profiles.at(0).Guid(), + settings._profiles.at(3).Guid()); - VERIFY_ARE_NOT_EQUAL(settings._profiles.at(1)._guid.value(), - settings._profiles.at(4)._guid.value()); + VERIFY_ARE_NOT_EQUAL(settings._profiles.at(1).Guid(), + settings._profiles.at(4).Guid()); - VERIFY_ARE_NOT_EQUAL(settings._profiles.at(3)._guid.value(), - settings._profiles.at(4)._guid.value()); + VERIFY_ARE_NOT_EQUAL(settings._profiles.at(3).Guid(), + settings._profiles.at(4).Guid()); } void DynamicProfileTests::DontLayerUserProfilesOnDynamicProfiles() { - GUID guid0 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-1111-49a3-80bd-e8fdd045185c}"); - GUID guid1 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-2222-49a3-80bd-e8fdd045185c}"); + winrt::guid guid0 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-1111-49a3-80bd-e8fdd045185c}"); + winrt::guid guid1 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-2222-49a3-80bd-e8fdd045185c}"); const std::string userProfiles{ R"( { @@ -211,17 +212,18 @@ namespace TerminalAppUnitTests auto gen0 = std::make_unique(L"Terminal.App.UnitTest.0"); gen0->pfnGenerate = [guid0, guid1]() { std::vector profiles; - Profile p0{ guid0 }; - p0.SetName(L"profile0"); // this is _profiles.at(0) + Profile p0 = winrt::make(guid0); + p0.Name(L"profile0"); // this is _profiles.at(0) profiles.push_back(p0); return profiles; }; auto gen1 = std::make_unique(L"Terminal.App.UnitTest.1"); gen1->pfnGenerate = [guid0, guid1]() { std::vector profiles; - Profile p0{ guid0 }, p1{ guid1 }; - p0.SetName(L"profile0"); // this is _profiles.at(1) - p1.SetName(L"profile1"); // this is _profiles.at(2) + Profile p0 = winrt::make(guid0); + Profile p1 = winrt::make(guid1); + p0.Name(L"profile0"); // this is _profiles.at(1) + p1.Name(L"profile1"); // this is _profiles.at(2) profiles.push_back(p0); profiles.push_back(p1); return profiles; @@ -243,33 +245,33 @@ namespace TerminalAppUnitTests settings.LayerJson(settings._userSettings); VERIFY_ARE_EQUAL(5u, settings._profiles.size()); - VERIFY_IS_TRUE(settings._profiles.at(0)._source.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(1)._source.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(2)._source.has_value()); - VERIFY_IS_FALSE(settings._profiles.at(3)._source.has_value()); - VERIFY_IS_FALSE(settings._profiles.at(4)._source.has_value()); - - VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.0", settings._profiles.at(0)._source.value()); - VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.1", settings._profiles.at(1)._source.value()); - VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.1", settings._profiles.at(2)._source.value()); - - VERIFY_IS_TRUE(settings._profiles.at(0)._guid.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(1)._guid.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(2)._guid.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(3)._guid.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(4)._guid.has_value()); - - VERIFY_ARE_EQUAL(guid0, settings._profiles.at(0)._guid.value()); - VERIFY_ARE_EQUAL(guid0, settings._profiles.at(1)._guid.value()); - VERIFY_ARE_EQUAL(guid1, settings._profiles.at(2)._guid.value()); - VERIFY_ARE_EQUAL(guid0, settings._profiles.at(3)._guid.value()); - VERIFY_ARE_EQUAL(guid1, settings._profiles.at(4)._guid.value()); + VERIFY_IS_FALSE(settings._profiles.at(0).Source().empty()); + VERIFY_IS_FALSE(settings._profiles.at(1).Source().empty()); + VERIFY_IS_FALSE(settings._profiles.at(2).Source().empty()); + VERIFY_IS_TRUE(settings._profiles.at(3).Source().empty()); + VERIFY_IS_TRUE(settings._profiles.at(4).Source().empty()); + + VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.0", settings._profiles.at(0).Source()); + VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.1", settings._profiles.at(1).Source()); + VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.1", settings._profiles.at(2).Source()); + + VERIFY_IS_TRUE(settings._profiles.at(0).HasGuid()); + VERIFY_IS_TRUE(settings._profiles.at(1).HasGuid()); + VERIFY_IS_TRUE(settings._profiles.at(2).HasGuid()); + VERIFY_IS_TRUE(settings._profiles.at(3).HasGuid()); + VERIFY_IS_TRUE(settings._profiles.at(4).HasGuid()); + + VERIFY_ARE_EQUAL(guid0, settings._profiles.at(0).Guid()); + VERIFY_ARE_EQUAL(guid0, settings._profiles.at(1).Guid()); + VERIFY_ARE_EQUAL(guid1, settings._profiles.at(2).Guid()); + VERIFY_ARE_EQUAL(guid0, settings._profiles.at(3).Guid()); + VERIFY_ARE_EQUAL(guid1, settings._profiles.at(4).Guid()); } void DynamicProfileTests::DoLayerUserProfilesOnDynamicsWhenSourceMatches() { - GUID guid0 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-1111-49a3-80bd-e8fdd045185c}"); - GUID guid1 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-2222-49a3-80bd-e8fdd045185c}"); + winrt::guid guid0 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-1111-49a3-80bd-e8fdd045185c}"); + winrt::guid guid1 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-2222-49a3-80bd-e8fdd045185c}"); const std::string userProfiles{ R"( { @@ -290,17 +292,18 @@ namespace TerminalAppUnitTests auto gen0 = std::make_unique(L"Terminal.App.UnitTest.0"); gen0->pfnGenerate = [guid0, guid1]() { std::vector profiles; - Profile p0{ guid0 }; - p0.SetName(L"profile0"); // this is _profiles.at(0) + Profile p0 = winrt::make(guid0); + p0.Name(L"profile0"); // this is _profiles.at(0) profiles.push_back(p0); return profiles; }; auto gen1 = std::make_unique(L"Terminal.App.UnitTest.1"); gen1->pfnGenerate = [guid0, guid1]() { std::vector profiles; - Profile p0{ guid0 }, p1{ guid1 }; - p0.SetName(L"profile0"); // this is _profiles.at(1) - p1.SetName(L"profile1"); // this is _profiles.at(2) + Profile p0 = winrt::make(guid0); + Profile p1 = winrt::make(guid1); + p0.Name(L"profile0"); // this is _profiles.at(1) + p1.Name(L"profile1"); // this is _profiles.at(2) profiles.push_back(p0); profiles.push_back(p1); return profiles; @@ -322,25 +325,25 @@ namespace TerminalAppUnitTests settings.LayerJson(settings._userSettings); VERIFY_ARE_EQUAL(3u, settings._profiles.size()); - VERIFY_IS_TRUE(settings._profiles.at(0)._source.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(1)._source.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(2)._source.has_value()); + VERIFY_IS_FALSE(settings._profiles.at(0).Source().empty()); + VERIFY_IS_FALSE(settings._profiles.at(1).Source().empty()); + VERIFY_IS_FALSE(settings._profiles.at(2).Source().empty()); - VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.0", settings._profiles.at(0)._source.value()); - VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.1", settings._profiles.at(1)._source.value()); - VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.1", settings._profiles.at(2)._source.value()); + VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.0", settings._profiles.at(0).Source()); + VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.1", settings._profiles.at(1).Source()); + VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.1", settings._profiles.at(2).Source()); - VERIFY_IS_TRUE(settings._profiles.at(0)._guid.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(1)._guid.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(2)._guid.has_value()); + VERIFY_IS_TRUE(settings._profiles.at(0).HasGuid()); + VERIFY_IS_TRUE(settings._profiles.at(1).HasGuid()); + VERIFY_IS_TRUE(settings._profiles.at(2).HasGuid()); - VERIFY_ARE_EQUAL(guid0, settings._profiles.at(0)._guid.value()); - VERIFY_ARE_EQUAL(guid0, settings._profiles.at(1)._guid.value()); - VERIFY_ARE_EQUAL(guid1, settings._profiles.at(2)._guid.value()); + VERIFY_ARE_EQUAL(guid0, settings._profiles.at(0).Guid()); + VERIFY_ARE_EQUAL(guid0, settings._profiles.at(1).Guid()); + VERIFY_ARE_EQUAL(guid1, settings._profiles.at(2).Guid()); - VERIFY_ARE_EQUAL(L"profile0FromUserSettings", settings._profiles.at(0)._name); - VERIFY_ARE_EQUAL(L"profile0", settings._profiles.at(1)._name); - VERIFY_ARE_EQUAL(L"profile1FromUserSettings", settings._profiles.at(2)._name); + VERIFY_ARE_EQUAL(L"profile0FromUserSettings", settings._profiles.at(0).Name()); + VERIFY_ARE_EQUAL(L"profile0", settings._profiles.at(1).Name()); + VERIFY_ARE_EQUAL(L"profile1FromUserSettings", settings._profiles.at(2).Name()); } void DynamicProfileTests::TestDontRunDisabledGenerators() @@ -359,7 +362,7 @@ namespace TerminalAppUnitTests auto gen0GenerateFn = []() { std::vector profiles; Profile p0; - p0.SetName(L"profile0"); + p0.Name(L"profile0"); profiles.push_back(p0); return profiles; }; @@ -367,8 +370,8 @@ namespace TerminalAppUnitTests auto gen1GenerateFn = []() { std::vector profiles; Profile p0, p1; - p0.SetName(L"profile1"); - p1.SetName(L"profile2"); + p0.Name(L"profile1"); + p1.Name(L"profile2"); profiles.push_back(p0); profiles.push_back(p1); return profiles; @@ -377,8 +380,8 @@ namespace TerminalAppUnitTests auto gen2GenerateFn = []() { std::vector profiles; Profile p0, p1; - p0.SetName(L"profile3"); - p1.SetName(L"profile4"); + p0.Name(L"profile3"); + p1.Name(L"profile4"); profiles.push_back(p0); profiles.push_back(p1); return profiles; @@ -404,18 +407,18 @@ namespace TerminalAppUnitTests settings._LoadDynamicProfiles(); VERIFY_ARE_EQUAL(4u, settings._profiles.size()); - VERIFY_IS_TRUE(settings._profiles.at(0)._source.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(1)._source.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(2)._source.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(3)._source.has_value()); - VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.1", settings._profiles.at(0)._source.value()); - VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.1", settings._profiles.at(1)._source.value()); - VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.2", settings._profiles.at(2)._source.value()); - VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.2", settings._profiles.at(3)._source.value()); - VERIFY_ARE_EQUAL(L"profile1", settings._profiles.at(0)._name); - VERIFY_ARE_EQUAL(L"profile2", settings._profiles.at(1)._name); - VERIFY_ARE_EQUAL(L"profile3", settings._profiles.at(2)._name); - VERIFY_ARE_EQUAL(L"profile4", settings._profiles.at(3)._name); + VERIFY_IS_FALSE(settings._profiles.at(0).Source().empty()); + VERIFY_IS_FALSE(settings._profiles.at(1).Source().empty()); + VERIFY_IS_FALSE(settings._profiles.at(2).Source().empty()); + VERIFY_IS_FALSE(settings._profiles.at(3).Source().empty()); + VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.1", settings._profiles.at(0).Source()); + VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.1", settings._profiles.at(1).Source()); + VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.2", settings._profiles.at(2).Source()); + VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.2", settings._profiles.at(3).Source()); + VERIFY_ARE_EQUAL(L"profile1", settings._profiles.at(0).Name()); + VERIFY_ARE_EQUAL(L"profile2", settings._profiles.at(1).Name()); + VERIFY_ARE_EQUAL(L"profile3", settings._profiles.at(2).Name()); + VERIFY_ARE_EQUAL(L"profile4", settings._profiles.at(3).Name()); } { @@ -437,22 +440,22 @@ namespace TerminalAppUnitTests settings._LoadDynamicProfiles(); VERIFY_ARE_EQUAL(2u, settings._profiles.size()); - VERIFY_IS_TRUE(settings._profiles.at(0)._source.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(1)._source.has_value()); - VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.2", settings._profiles.at(0)._source.value()); - VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.2", settings._profiles.at(1)._source.value()); - VERIFY_ARE_EQUAL(L"profile3", settings._profiles.at(0)._name); - VERIFY_ARE_EQUAL(L"profile4", settings._profiles.at(1)._name); + VERIFY_IS_FALSE(settings._profiles.at(0).Source().empty()); + VERIFY_IS_FALSE(settings._profiles.at(1).Source().empty()); + VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.2", settings._profiles.at(0).Source()); + VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.2", settings._profiles.at(1).Source()); + VERIFY_ARE_EQUAL(L"profile3", settings._profiles.at(0).Name()); + VERIFY_ARE_EQUAL(L"profile4", settings._profiles.at(1).Name()); } } void DynamicProfileTests::TestLegacyProfilesMigrate() { - GUID guid0 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-0000-49a3-80bd-e8fdd045185c}"); - GUID guid1 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-1111-49a3-80bd-e8fdd045185c}"); - GUID guid2 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-2222-49a3-80bd-e8fdd045185c}"); - GUID guid3 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-3333-49a3-80bd-e8fdd045185c}"); - GUID guid4 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-4444-49a3-80bd-e8fdd045185c}"); + winrt::guid guid0 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-0000-49a3-80bd-e8fdd045185c}"); + winrt::guid guid1 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-1111-49a3-80bd-e8fdd045185c}"); + winrt::guid guid2 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-2222-49a3-80bd-e8fdd045185c}"); + winrt::guid guid3 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-3333-49a3-80bd-e8fdd045185c}"); + winrt::guid guid4 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-4444-49a3-80bd-e8fdd045185c}"); const std::string settings0String{ R"( { @@ -489,17 +492,18 @@ namespace TerminalAppUnitTests auto gen0 = std::make_unique(L"Windows.Terminal.PowershellCore"); gen0->pfnGenerate = [guid0, guid1]() { std::vector profiles; - Profile p0{ guid0 }; - p0.SetName(L"profile0"); + Profile p0 = winrt::make(guid0); + p0.Name(L"profile0"); profiles.push_back(p0); return profiles; }; auto gen1 = std::make_unique(L"Windows.Terminal.Wsl"); gen1->pfnGenerate = [guid2, guid1]() { std::vector profiles; - Profile p0{ guid1 }, p1{ guid2 }; - p0.SetName(L"profile1"); - p1.SetName(L"profile2"); + Profile p0 = winrt::make(guid1); + Profile p1 = winrt::make(guid2); + p0.Name(L"profile1"); + p1.Name(L"profile2"); profiles.push_back(p0); profiles.push_back(p1); return profiles; @@ -507,8 +511,8 @@ namespace TerminalAppUnitTests auto gen2 = std::make_unique(L"Windows.Terminal.Azure"); gen2->pfnGenerate = [guid3]() { std::vector profiles; - Profile p0{ guid3 }; - p0.SetName(L"profile3"); + Profile p0 = winrt::make(guid3); + p0.Name(L"profile3"); profiles.push_back(p0); return profiles; }; @@ -524,43 +528,43 @@ namespace TerminalAppUnitTests settings._LoadDynamicProfiles(); VERIFY_ARE_EQUAL(4u, settings._profiles.size()); - VERIFY_IS_TRUE(settings._profiles.at(0)._source.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(1)._source.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(2)._source.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(3)._source.has_value()); - VERIFY_ARE_EQUAL(L"Windows.Terminal.PowershellCore", settings._profiles.at(0)._source.value()); - VERIFY_ARE_EQUAL(L"Windows.Terminal.Wsl", settings._profiles.at(1)._source.value()); - VERIFY_ARE_EQUAL(L"Windows.Terminal.Wsl", settings._profiles.at(2)._source.value()); - VERIFY_ARE_EQUAL(L"Windows.Terminal.Azure", settings._profiles.at(3)._source.value()); - VERIFY_ARE_EQUAL(L"profile0", settings._profiles.at(0)._name); - VERIFY_ARE_EQUAL(L"profile1", settings._profiles.at(1)._name); - VERIFY_ARE_EQUAL(L"profile2", settings._profiles.at(2)._name); - VERIFY_ARE_EQUAL(L"profile3", settings._profiles.at(3)._name); + VERIFY_IS_FALSE(settings._profiles.at(0).Source().empty()); + VERIFY_IS_FALSE(settings._profiles.at(1).Source().empty()); + VERIFY_IS_FALSE(settings._profiles.at(2).Source().empty()); + VERIFY_IS_FALSE(settings._profiles.at(3).Source().empty()); + VERIFY_ARE_EQUAL(L"Windows.Terminal.PowershellCore", settings._profiles.at(0).Source()); + VERIFY_ARE_EQUAL(L"Windows.Terminal.Wsl", settings._profiles.at(1).Source()); + VERIFY_ARE_EQUAL(L"Windows.Terminal.Wsl", settings._profiles.at(2).Source()); + VERIFY_ARE_EQUAL(L"Windows.Terminal.Azure", settings._profiles.at(3).Source()); + VERIFY_ARE_EQUAL(L"profile0", settings._profiles.at(0).Name()); + VERIFY_ARE_EQUAL(L"profile1", settings._profiles.at(1).Name()); + VERIFY_ARE_EQUAL(L"profile2", settings._profiles.at(2).Name()); + VERIFY_ARE_EQUAL(L"profile3", settings._profiles.at(3).Name()); settings.LayerJson(settings._userSettings); VERIFY_ARE_EQUAL(5u, settings._profiles.size()); - VERIFY_IS_TRUE(settings._profiles.at(0)._source.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(1)._source.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(2)._source.has_value()); - VERIFY_IS_TRUE(settings._profiles.at(3)._source.has_value()); - VERIFY_IS_FALSE(settings._profiles.at(4)._source.has_value()); - VERIFY_ARE_EQUAL(L"Windows.Terminal.PowershellCore", settings._profiles.at(0)._source.value()); - VERIFY_ARE_EQUAL(L"Windows.Terminal.Wsl", settings._profiles.at(1)._source.value()); - VERIFY_ARE_EQUAL(L"Windows.Terminal.Wsl", settings._profiles.at(2)._source.value()); - VERIFY_ARE_EQUAL(L"Windows.Terminal.Azure", settings._profiles.at(3)._source.value()); + VERIFY_IS_FALSE(settings._profiles.at(0).Source().empty()); + VERIFY_IS_FALSE(settings._profiles.at(1).Source().empty()); + VERIFY_IS_FALSE(settings._profiles.at(2).Source().empty()); + VERIFY_IS_FALSE(settings._profiles.at(3).Source().empty()); + VERIFY_IS_TRUE(settings._profiles.at(4).Source().empty()); + VERIFY_ARE_EQUAL(L"Windows.Terminal.PowershellCore", settings._profiles.at(0).Source()); + VERIFY_ARE_EQUAL(L"Windows.Terminal.Wsl", settings._profiles.at(1).Source()); + VERIFY_ARE_EQUAL(L"Windows.Terminal.Wsl", settings._profiles.at(2).Source()); + VERIFY_ARE_EQUAL(L"Windows.Terminal.Azure", settings._profiles.at(3).Source()); // settings._profiles.at(4) does not have a source - VERIFY_ARE_EQUAL(L"profile0FromUserSettings", settings._profiles.at(0)._name); - VERIFY_ARE_EQUAL(L"profile1FromUserSettings", settings._profiles.at(1)._name); - VERIFY_ARE_EQUAL(L"profile2FromUserSettings", settings._profiles.at(2)._name); - VERIFY_ARE_EQUAL(L"profile3FromUserSettings", settings._profiles.at(3)._name); - VERIFY_ARE_EQUAL(L"profile4FromUserSettings", settings._profiles.at(4)._name); + VERIFY_ARE_EQUAL(L"profile0FromUserSettings", settings._profiles.at(0).Name()); + VERIFY_ARE_EQUAL(L"profile1FromUserSettings", settings._profiles.at(1).Name()); + VERIFY_ARE_EQUAL(L"profile2FromUserSettings", settings._profiles.at(2).Name()); + VERIFY_ARE_EQUAL(L"profile3FromUserSettings", settings._profiles.at(3).Name()); + VERIFY_ARE_EQUAL(L"profile4FromUserSettings", settings._profiles.at(4).Name()); } void DynamicProfileTests::UserProfilesWithInvalidSourcesAreIgnored() { - GUID guid0 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-1111-49a3-80bd-e8fdd045185c}"); - GUID guid1 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-2222-49a3-80bd-e8fdd045185c}"); + winrt::guid guid0 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-1111-49a3-80bd-e8fdd045185c}"); + winrt::guid guid1 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-2222-49a3-80bd-e8fdd045185c}"); const std::string settings0String{ R"( { @@ -585,17 +589,18 @@ namespace TerminalAppUnitTests auto gen0 = std::make_unique(L"Terminal.App.UnitTest.0"); gen0->pfnGenerate = [guid0, guid1]() { std::vector profiles; - Profile p0{ guid0 }; - p0.SetName(L"profile0"); // this is _profiles.at(0) + Profile p0 = winrt::make(guid0); + p0.Name(L"profile0"); // this is _profiles.at(0) profiles.push_back(p0); return profiles; }; auto gen1 = std::make_unique(L"Terminal.App.UnitTest.1"); gen1->pfnGenerate = [guid0, guid1]() { std::vector profiles; - Profile p0{ guid0 }, p1{ guid1 }; - p0.SetName(L"profile0"); // this is _profiles.at(1) - p1.SetName(L"profile1"); // this is _profiles.at(2) + Profile p0 = winrt::make(guid0); + Profile p1 = winrt::make(guid1); + p0.Name(L"profile0"); // this is _profiles.at(1) + p1.Name(L"profile1"); // this is _profiles.at(2) profiles.push_back(p0); profiles.push_back(p1); return profiles; @@ -617,8 +622,8 @@ namespace TerminalAppUnitTests void DynamicProfileTests::UserProfilesFromDisabledSourcesDontAppear() { - GUID guid0 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-1111-49a3-80bd-e8fdd045185c}"); - GUID guid1 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-2222-49a3-80bd-e8fdd045185c}"); + winrt::guid guid0 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-1111-49a3-80bd-e8fdd045185c}"); + winrt::guid guid1 = Microsoft::Console::Utils::GuidFromString(L"{6239a42c-2222-49a3-80bd-e8fdd045185c}"); const std::string settings0String{ R"( { @@ -644,17 +649,18 @@ namespace TerminalAppUnitTests auto gen0 = std::make_unique(L"Terminal.App.UnitTest.0"); gen0->pfnGenerate = [guid0, guid1]() { std::vector profiles; - Profile p0{ guid0 }; - p0.SetName(L"profile0"); // this is _profiles.at(0) + Profile p0 = winrt::make(guid0); + p0.Name(L"profile0"); // this is _profiles.at(0) profiles.push_back(p0); return profiles; }; auto gen1 = std::make_unique(L"Terminal.App.UnitTest.1"); gen1->pfnGenerate = [guid0, guid1]() { std::vector profiles; - Profile p0{ guid0 }, p1{ guid1 }; - p0.SetName(L"profile0"); // this shouldn't be in the profiles at all - p1.SetName(L"profile1"); // this shouldn't be in the profiles at all + Profile p0 = winrt::make(guid0); + Profile p1 = winrt::make(guid1); + p0.Name(L"profile0"); // this shouldn't be in the profiles at all + p1.Name(L"profile1"); // this shouldn't be in the profiles at all profiles.push_back(p0); profiles.push_back(p1); return profiles; diff --git a/src/cascadia/ut_app/JsonTests.cpp b/src/cascadia/ut_app/JsonTests.cpp index c145c48c1dc..d36f97123d6 100644 --- a/src/cascadia/ut_app/JsonTests.cpp +++ b/src/cascadia/ut_app/JsonTests.cpp @@ -94,10 +94,10 @@ namespace TerminalAppUnitTests const auto schemeObject = VerifyParseSucceeded(campbellScheme); auto scheme = implementation::ColorScheme::FromJson(schemeObject); VERIFY_ARE_EQUAL(L"Campbell", scheme->Name()); - VERIFY_ARE_EQUAL(til::color(0xf2, 0xf2, 0xf2, 255), scheme->Foreground()); - VERIFY_ARE_EQUAL(til::color(0x0c, 0x0c, 0x0c, 255), scheme->Background()); - VERIFY_ARE_EQUAL(til::color(0x13, 0x13, 0x13, 255), scheme->SelectionBackground()); - VERIFY_ARE_EQUAL(til::color(0xFF, 0xFF, 0xFF, 255), scheme->CursorColor()); + VERIFY_ARE_EQUAL(til::color(0xf2, 0xf2, 0xf2, 255), til::color{ scheme->Foreground() }); + VERIFY_ARE_EQUAL(til::color(0x0c, 0x0c, 0x0c, 255), til::color{ scheme->Background() }); + VERIFY_ARE_EQUAL(til::color(0x13, 0x13, 0x13, 255), til::color{ scheme->SelectionBackground() }); + VERIFY_ARE_EQUAL(til::color(0xFF, 0xFF, 0xFF, 255), til::color{ scheme->CursorColor() }); std::array expectedCampbellTable; auto campbellSpan = gsl::span(&expectedCampbellTable[0], COLOR_TABLE_SIZE); @@ -150,21 +150,21 @@ namespace TerminalAppUnitTests const auto profile3Json = VerifyParseSucceeded(profileWithNullGuid); const auto profile4Json = VerifyParseSucceeded(profileWithGuid); - const auto profile0 = Profile::FromJson(profile0Json); - const auto profile1 = Profile::FromJson(profile1Json); - const auto profile2 = Profile::FromJson(profile2Json); - const auto profile3 = Profile::FromJson(profile3Json); - const auto profile4 = Profile::FromJson(profile4Json); - const GUID cmdGuid = Utils::GuidFromString(L"{6239a42c-1de4-49a3-80bd-e8fdd045185c}"); - const GUID nullGuid{ 0 }; - - VERIFY_IS_FALSE(profile0._guid.has_value()); - VERIFY_IS_FALSE(profile1._guid.has_value()); - VERIFY_IS_FALSE(profile2._guid.has_value()); - VERIFY_IS_TRUE(profile3._guid.has_value()); - VERIFY_IS_TRUE(profile4._guid.has_value()); - - VERIFY_ARE_EQUAL(profile3.GetGuid(), nullGuid); - VERIFY_ARE_EQUAL(profile4.GetGuid(), cmdGuid); + const auto profile0 = implementation::Profile::FromJson(profile0Json); + const auto profile1 = implementation::Profile::FromJson(profile1Json); + const auto profile2 = implementation::Profile::FromJson(profile2Json); + const auto profile3 = implementation::Profile::FromJson(profile3Json); + const auto profile4 = implementation::Profile::FromJson(profile4Json); + const winrt::guid cmdGuid = Utils::GuidFromString(L"{6239a42c-1de4-49a3-80bd-e8fdd045185c}"); + const winrt::guid nullGuid{}; + + VERIFY_IS_FALSE(profile0->HasGuid()); + VERIFY_IS_FALSE(profile1->HasGuid()); + VERIFY_IS_FALSE(profile2->HasGuid()); + VERIFY_IS_TRUE(profile3->HasGuid()); + VERIFY_IS_TRUE(profile4->HasGuid()); + + VERIFY_ARE_EQUAL(profile3->Guid(), nullGuid); + VERIFY_ARE_EQUAL(profile4->Guid(), cmdGuid); } } diff --git a/src/cascadia/ut_app/TestDynamicProfileGenerator.h b/src/cascadia/ut_app/TestDynamicProfileGenerator.h index bda1608e5cb..698af689edd 100644 --- a/src/cascadia/ut_app/TestDynamicProfileGenerator.h +++ b/src/cascadia/ut_app/TestDynamicProfileGenerator.h @@ -29,16 +29,16 @@ class TerminalAppUnitTests::TestDynamicProfileGenerator final : std::wstring_view GetNamespace() override { return _namespace; }; - std::vector GenerateProfiles() override + std::vector GenerateProfiles() override { if (pfnGenerate) { return pfnGenerate(); } - return std::vector{}; + return std::vector{}; } std::wstring _namespace; - std::function()> pfnGenerate{ nullptr }; + std::function()> pfnGenerate{ nullptr }; }; diff --git a/src/cascadia/ut_app/precomp.h b/src/cascadia/ut_app/precomp.h index 3ab75f96a8b..51ff1f4474e 100644 --- a/src/cascadia/ut_app/precomp.h +++ b/src/cascadia/ut_app/precomp.h @@ -15,6 +15,8 @@ Author(s): #pragma once +// Manually include til after we include Windows.Foundation to give it winrt superpowers +#define BLOCK_TIL // This includes support libraries from the CRT, STL, WIL, and GSL #include "LibraryIncludes.h" // This is inexplicable, but for whatever reason, cppwinrt conflicts with the @@ -29,12 +31,6 @@ Author(s): #include #include "consoletaeftemplates.hpp" -// Common includes for most tests: -#include "../../inc/argb.h" -#include "../../inc/conattrs.hpp" -#include "../../types/inc/utils.hpp" -#include "../../inc/DefaultSettings.h" - // Are you thinking about adding WinRT things here? If so, you probably want to // add your test to TerminalApp.LocalTests, not TerminalApp.UnitTests. The // UnitTests run in CI, while the LocalTests do not. However, since the CI can't @@ -48,3 +44,12 @@ Author(s): #include #include #include + +// Manually include til after we include Windows.Foundation to give it winrt superpowers +#include "til.h" + +// Common includes for most tests: +#include "../../inc/argb.h" +#include "../../inc/conattrs.hpp" +#include "../../types/inc/utils.hpp" +#include "../../inc/DefaultSettings.h" From 7803efa6fef8d2efd0d8fd93333cc958d8431882 Mon Sep 17 00:00:00 2001 From: Carlos Zamora Date: Thu, 27 Aug 2020 20:49:16 -0700 Subject: [PATCH 091/266] Make GlobalAppSettings a WinRT object (#7349) GlobalAppSettings is now a WinRT object in the TerminalApp project. ## References #7141 - GlobalAppSettings is a settings object #885 - this new settings object will be moved to a new TerminalSettingsModel project ## PR Checklist * [x] Tests passed ## Detailed Description of the Pull Request / Additional comments This one was probably the easiest thus far. The only weird thing is how we handle InitialPosition. Today, we lose a little bit of fidelity when we convert from LaunchPosition (int) --> Point (float) --> RECT (long). The current change converts LaunchPosition (optional) --> InitialPosition (long) --> RECT (long). NOTE: Though I could use LaunchPosition to go directly from TermApp to AppHost, I decided to introduce InitialPosition because LaunchPosition will be a part of TerminalSettingsModel soon. ## Validation Steps Performed - [x] Tests passed - [x] Deployment succeeded --- .../ColorSchemeTests.cpp | 46 ++--- .../LocalTests_TerminalApp/SettingsTests.cpp | 183 +++++++++--------- src/cascadia/TerminalApp/AppLogic.cpp | 10 +- src/cascadia/TerminalApp/AppLogic.h | 2 +- src/cascadia/TerminalApp/AppLogic.idl | 8 +- src/cascadia/TerminalApp/CascadiaSettings.cpp | 52 ++--- src/cascadia/TerminalApp/CascadiaSettings.h | 6 +- .../CascadiaSettingsSerialization.cpp | 10 +- src/cascadia/TerminalApp/Command.h | 2 +- .../TerminalApp/GlobalAppSettings.cpp | 60 +++--- src/cascadia/TerminalApp/GlobalAppSettings.h | 140 +++++++------- .../TerminalApp/GlobalAppSettings.idl | 59 ++++++ src/cascadia/TerminalApp/Profile.cpp | 13 +- src/cascadia/TerminalApp/Profile.h | 8 +- src/cascadia/TerminalApp/SettingsTypes.h | 8 +- .../TerminalApp/TerminalAppLib.vcxproj | 9 +- .../TerminalAppLib.vcxproj.filters | 3 + src/cascadia/TerminalApp/TerminalPage.cpp | 8 +- src/cascadia/TerminalApp/TerminalPage.h | 2 +- .../TerminalSettingsSerializationHelpers.h | 14 +- src/cascadia/WindowsTerminal/AppHost.cpp | 6 +- 21 files changed, 339 insertions(+), 310 deletions(-) create mode 100644 src/cascadia/TerminalApp/GlobalAppSettings.idl diff --git a/src/cascadia/LocalTests_TerminalApp/ColorSchemeTests.cpp b/src/cascadia/LocalTests_TerminalApp/ColorSchemeTests.cpp index ab56263cad0..e59d022f526 100644 --- a/src/cascadia/LocalTests_TerminalApp/ColorSchemeTests.cpp +++ b/src/cascadia/LocalTests_TerminalApp/ColorSchemeTests.cpp @@ -195,7 +195,7 @@ namespace TerminalAppLocalTests CascadiaSettings settings; - VERIFY_ARE_EQUAL(0u, settings._globals.GetColorSchemes().size()); + VERIFY_ARE_EQUAL(0u, settings._globals->GetColorSchemes().Size()); VERIFY_IS_NULL(settings._FindMatchingColorScheme(scheme0Json)); VERIFY_IS_NULL(settings._FindMatchingColorScheme(scheme1Json)); VERIFY_IS_NULL(settings._FindMatchingColorScheme(scheme2Json)); @@ -203,15 +203,15 @@ namespace TerminalAppLocalTests settings._LayerOrCreateColorScheme(scheme0Json); { - for (auto& kv : settings._globals._colorSchemes) + for (auto kv : settings._globals->GetColorSchemes()) { Log::Comment(NoThrowString().Format( - L"kv:%s->%s", kv.first.data(), kv.second.Name().data())); + L"kv:%s->%s", kv.Key().data(), kv.Value().Name().data())); } - VERIFY_ARE_EQUAL(1u, settings._globals.GetColorSchemes().size()); + VERIFY_ARE_EQUAL(1u, settings._globals->GetColorSchemes().Size()); - VERIFY_IS_TRUE(settings._globals._colorSchemes.find(L"scheme0") != settings._globals._colorSchemes.end()); - auto scheme0Proj = settings._globals._colorSchemes.find(L"scheme0")->second; + VERIFY_IS_TRUE(settings._globals->GetColorSchemes().HasKey(L"scheme0")); + auto scheme0Proj = settings._globals->GetColorSchemes().Lookup(L"scheme0"); auto scheme0 = winrt::get_self(scheme0Proj); VERIFY_IS_NOT_NULL(settings._FindMatchingColorScheme(scheme0Json)); @@ -225,13 +225,13 @@ namespace TerminalAppLocalTests settings._LayerOrCreateColorScheme(scheme1Json); { - VERIFY_ARE_EQUAL(2u, settings._globals.GetColorSchemes().size()); + VERIFY_ARE_EQUAL(2u, settings._globals->GetColorSchemes().Size()); - VERIFY_IS_TRUE(settings._globals._colorSchemes.find(L"scheme0") != settings._globals._colorSchemes.end()); - auto scheme0Proj = settings._globals._colorSchemes.find(L"scheme0")->second; + VERIFY_IS_TRUE(settings._globals->GetColorSchemes().HasKey(L"scheme0")); + auto scheme0Proj = settings._globals->GetColorSchemes().Lookup(L"scheme0"); auto scheme0 = winrt::get_self(scheme0Proj); - VERIFY_IS_TRUE(settings._globals._colorSchemes.find(L"scheme1") != settings._globals._colorSchemes.end()); - auto scheme1Proj = settings._globals._colorSchemes.find(L"scheme1")->second; + VERIFY_IS_TRUE(settings._globals->GetColorSchemes().HasKey(L"scheme1")); + auto scheme1Proj = settings._globals->GetColorSchemes().Lookup(L"scheme1"); auto scheme1 = winrt::get_self(scheme1Proj); VERIFY_IS_NOT_NULL(settings._FindMatchingColorScheme(scheme0Json)); @@ -246,13 +246,13 @@ namespace TerminalAppLocalTests settings._LayerOrCreateColorScheme(scheme2Json); { - VERIFY_ARE_EQUAL(2u, settings._globals.GetColorSchemes().size()); + VERIFY_ARE_EQUAL(2u, settings._globals->GetColorSchemes().Size()); - VERIFY_IS_TRUE(settings._globals._colorSchemes.find(L"scheme0") != settings._globals._colorSchemes.end()); - auto scheme0Proj = settings._globals._colorSchemes.find(L"scheme0")->second; + VERIFY_IS_TRUE(settings._globals->GetColorSchemes().HasKey(L"scheme0")); + auto scheme0Proj = settings._globals->GetColorSchemes().Lookup(L"scheme0"); auto scheme0 = winrt::get_self(scheme0Proj); - VERIFY_IS_TRUE(settings._globals._colorSchemes.find(L"scheme1") != settings._globals._colorSchemes.end()); - auto scheme1Proj = settings._globals._colorSchemes.find(L"scheme1")->second; + VERIFY_IS_TRUE(settings._globals->GetColorSchemes().HasKey(L"scheme1")); + auto scheme1Proj = settings._globals->GetColorSchemes().Lookup(L"scheme1"); auto scheme1 = winrt::get_self(scheme1Proj); VERIFY_IS_NOT_NULL(settings._FindMatchingColorScheme(scheme0Json)); @@ -267,16 +267,16 @@ namespace TerminalAppLocalTests settings._LayerOrCreateColorScheme(scheme3Json); { - VERIFY_ARE_EQUAL(3u, settings._globals.GetColorSchemes().size()); + VERIFY_ARE_EQUAL(3u, settings._globals->GetColorSchemes().Size()); - VERIFY_IS_TRUE(settings._globals._colorSchemes.find(L"scheme0") != settings._globals._colorSchemes.end()); - auto scheme0Proj = settings._globals._colorSchemes.find(L"scheme0")->second; + VERIFY_IS_TRUE(settings._globals->GetColorSchemes().HasKey(L"scheme0")); + auto scheme0Proj = settings._globals->GetColorSchemes().Lookup(L"scheme0"); auto scheme0 = winrt::get_self(scheme0Proj); - VERIFY_IS_TRUE(settings._globals._colorSchemes.find(L"scheme1") != settings._globals._colorSchemes.end()); - auto scheme1Proj = settings._globals._colorSchemes.find(L"scheme1")->second; + VERIFY_IS_TRUE(settings._globals->GetColorSchemes().HasKey(L"scheme1")); + auto scheme1Proj = settings._globals->GetColorSchemes().Lookup(L"scheme1"); auto scheme1 = winrt::get_self(scheme1Proj); - VERIFY_IS_TRUE(settings._globals._colorSchemes.find(L"") != settings._globals._colorSchemes.end()); - auto scheme2Proj = settings._globals._colorSchemes.find(L"")->second; + VERIFY_IS_TRUE(settings._globals->GetColorSchemes().HasKey(L"")); + auto scheme2Proj = settings._globals->GetColorSchemes().Lookup(L""); auto scheme2 = winrt::get_self(scheme2Proj); VERIFY_IS_NOT_NULL(settings._FindMatchingColorScheme(scheme0Json)); diff --git a/src/cascadia/LocalTests_TerminalApp/SettingsTests.cpp b/src/cascadia/LocalTests_TerminalApp/SettingsTests.cpp index e1dad5b8905..91c45987ce7 100644 --- a/src/cascadia/LocalTests_TerminalApp/SettingsTests.cpp +++ b/src/cascadia/LocalTests_TerminalApp/SettingsTests.cpp @@ -106,7 +106,7 @@ namespace TerminalAppLocalTests } private: - void _logCommandNames(winrt::Windows::Foundation::Collections::IMap& commands, const int indentation = 1) + void _logCommandNames(winrt::Windows::Foundation::Collections::IMapView commands, const int indentation = 1) { if (indentation == 1) { @@ -125,7 +125,7 @@ namespace TerminalAppLocalTests cmdImpl.copy_from(winrt::get_self(nameAndCommand.Value())); if (cmdImpl->HasNestedCommands()) { - _logCommandNames(cmdImpl->_subcommands, indentation + 2); + _logCommandNames(cmdImpl->_subcommands.GetView(), indentation + 2); } } } @@ -274,7 +274,7 @@ namespace TerminalAppLocalTests settings->_ValidateDefaultProfileExists(); VERIFY_ARE_EQUAL(static_cast(0), settings->_warnings.size()); VERIFY_ARE_EQUAL(static_cast(2), settings->_profiles.size()); - VERIFY_ARE_EQUAL(winrt::guid{ settings->_globals.DefaultProfile() }, settings->_profiles.at(0).Guid()); + VERIFY_ARE_EQUAL(settings->_globals->DefaultProfile(), settings->_profiles.at(0).Guid()); } { // Case 2: Bad settings @@ -288,7 +288,7 @@ namespace TerminalAppLocalTests VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::MissingDefaultProfile, settings->_warnings.at(0)); VERIFY_ARE_EQUAL(static_cast(2), settings->_profiles.size()); - VERIFY_ARE_EQUAL(winrt::guid{ settings->_globals.DefaultProfile() }, settings->_profiles.at(0).Guid()); + VERIFY_ARE_EQUAL(settings->_globals->DefaultProfile(), settings->_profiles.at(0).Guid()); } { // Case 2: Bad settings @@ -302,7 +302,7 @@ namespace TerminalAppLocalTests VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::MissingDefaultProfile, settings->_warnings.at(0)); VERIFY_ARE_EQUAL(static_cast(2), settings->_profiles.size()); - VERIFY_ARE_EQUAL(winrt::guid{ settings->_globals.DefaultProfile() }, settings->_profiles.at(0).Guid()); + VERIFY_ARE_EQUAL(settings->_globals->DefaultProfile(), settings->_profiles.at(0).Guid()); } { // Case 4: Good settings, default profile is a string @@ -314,7 +314,7 @@ namespace TerminalAppLocalTests settings->_ValidateDefaultProfileExists(); VERIFY_ARE_EQUAL(static_cast(0), settings->_warnings.size()); VERIFY_ARE_EQUAL(static_cast(2), settings->_profiles.size()); - VERIFY_ARE_EQUAL(winrt::guid{ settings->_globals.DefaultProfile() }, settings->_profiles.at(1).Guid()); + VERIFY_ARE_EQUAL(settings->_globals->DefaultProfile(), settings->_profiles.at(1).Guid()); } } @@ -381,19 +381,19 @@ namespace TerminalAppLocalTests } ] })" }; - Profile profile0 = winrt::make(winrt::guid{ ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-4444-49a3-80bd-e8fdd045185c}") }); + Profile profile0 = winrt::make(::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-4444-49a3-80bd-e8fdd045185c}")); profile0.Name(L"profile0"); - Profile profile1 = winrt::make(winrt::guid{ ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-5555-49a3-80bd-e8fdd045185c}") }); + Profile profile1 = winrt::make(::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-5555-49a3-80bd-e8fdd045185c}")); profile1.Name(L"profile1"); - Profile profile2 = winrt::make(winrt::guid{ ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-4444-49a3-80bd-e8fdd045185c}") }); + Profile profile2 = winrt::make(::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-4444-49a3-80bd-e8fdd045185c}")); profile2.Name(L"profile2"); - Profile profile3 = winrt::make(winrt::guid{ ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-4444-49a3-80bd-e8fdd045185c}") }); + Profile profile3 = winrt::make(::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-4444-49a3-80bd-e8fdd045185c}")); profile3.Name(L"profile3"); - Profile profile4 = winrt::make(winrt::guid{ ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-6666-49a3-80bd-e8fdd045185c}") }); + Profile profile4 = winrt::make(::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-6666-49a3-80bd-e8fdd045185c}")); profile4.Name(L"profile4"); - Profile profile5 = winrt::make(winrt::guid{ ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-5555-49a3-80bd-e8fdd045185c}") }); + Profile profile5 = winrt::make(::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-5555-49a3-80bd-e8fdd045185c}")); profile5.Name(L"profile5"); - Profile profile6 = winrt::make(winrt::guid{ ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-7777-49a3-80bd-e8fdd045185c}") }); + Profile profile6 = winrt::make(::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-7777-49a3-80bd-e8fdd045185c}")); profile6.Name(L"profile6"); { @@ -474,9 +474,9 @@ namespace TerminalAppLocalTests } ] })" }; - Profile profile4 = winrt::make(winrt::guid{ ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-4444-49a3-80bd-e8fdd045185c}") }); + Profile profile4 = winrt::make(::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-4444-49a3-80bd-e8fdd045185c}")); profile4.Name(L"profile4"); - Profile profile5 = winrt::make(winrt::guid{ ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-4444-49a3-80bd-e8fdd045185c}") }); + Profile profile5 = winrt::make(::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-4444-49a3-80bd-e8fdd045185c}")); profile5.Name(L"profile5"); // Case 2: Bad settings @@ -496,7 +496,7 @@ namespace TerminalAppLocalTests VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::UnknownColorScheme, settings->_warnings.at(2)); VERIFY_ARE_EQUAL(3u, settings->_profiles.size()); - VERIFY_ARE_EQUAL(winrt::guid{ settings->_globals.DefaultProfile() }, settings->_profiles.at(0).Guid()); + VERIFY_ARE_EQUAL(settings->_globals->DefaultProfile(), settings->_profiles.at(0).Guid()); VERIFY_IS_TRUE(settings->_profiles.at(0).HasGuid()); VERIFY_IS_TRUE(settings->_profiles.at(1).HasGuid()); VERIFY_IS_TRUE(settings->_profiles.at(2).HasGuid()); @@ -522,16 +522,16 @@ namespace TerminalAppLocalTests CascadiaSettings settings; settings.LayerJson(settings0Json); - VERIFY_ARE_EQUAL(true, settings._globals._AlwaysShowTabs); - VERIFY_ARE_EQUAL(120, settings._globals._InitialCols); - VERIFY_ARE_EQUAL(30, settings._globals._InitialRows); - VERIFY_ARE_EQUAL(true, settings._globals._ShowTabsInTitlebar); + VERIFY_ARE_EQUAL(true, settings._globals->AlwaysShowTabs()); + VERIFY_ARE_EQUAL(120, settings._globals->InitialCols()); + VERIFY_ARE_EQUAL(30, settings._globals->InitialRows()); + VERIFY_ARE_EQUAL(true, settings._globals->ShowTabsInTitlebar()); settings.LayerJson(settings1Json); - VERIFY_ARE_EQUAL(true, settings._globals._AlwaysShowTabs); - VERIFY_ARE_EQUAL(240, settings._globals._InitialCols); - VERIFY_ARE_EQUAL(60, settings._globals._InitialRows); - VERIFY_ARE_EQUAL(false, settings._globals._ShowTabsInTitlebar); + VERIFY_ARE_EQUAL(true, settings._globals->AlwaysShowTabs()); + VERIFY_ARE_EQUAL(240, settings._globals->InitialCols()); + VERIFY_ARE_EQUAL(60, settings._globals->InitialRows()); + VERIFY_ARE_EQUAL(false, settings._globals->ShowTabsInTitlebar()); } void SettingsTests::ValidateProfileOrdering() @@ -1330,7 +1330,7 @@ namespace TerminalAppLocalTests settings.LayerJson(settings._userSettings); VERIFY_ARE_EQUAL(3u, settings._profiles.size()); - VERIFY_ARE_EQUAL(2u, settings._globals._colorSchemes.size()); + VERIFY_ARE_EQUAL(2u, settings._globals->GetColorSchemes().Size()); VERIFY_ARE_EQUAL(L"schemeOne", settings._profiles.at(0).ColorSchemeName()); VERIFY_ARE_EQUAL(L"InvalidSchemeName", settings._profiles.at(1).ColorSchemeName()); @@ -1342,7 +1342,7 @@ namespace TerminalAppLocalTests VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::UnknownColorScheme, settings._warnings.at(0)); VERIFY_ARE_EQUAL(3u, settings._profiles.size()); - VERIFY_ARE_EQUAL(2u, settings._globals._colorSchemes.size()); + VERIFY_ARE_EQUAL(2u, settings._globals->GetColorSchemes().Size()); VERIFY_ARE_EQUAL(L"schemeOne", settings._profiles.at(0).ColorSchemeName()); VERIFY_ARE_EQUAL(L"Campbell", settings._profiles.at(1).ColorSchemeName()); @@ -1379,11 +1379,11 @@ namespace TerminalAppLocalTests auto name3{ L"ThisProfileShouldNotThrow" }; auto badName{ L"DoesNotExist" }; - winrt::guid guid0{ ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-5555-49a3-80bd-e8fdd045185c}") }; - winrt::guid guid1{ ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-6666-49a3-80bd-e8fdd045185c}") }; - winrt::guid guid2{ ::Microsoft::Console::Utils::GuidFromString(L"{2C4DE342-38B7-51CF-B940-2309A097F518}") }; - winrt::guid fakeGuid{ ::Microsoft::Console::Utils::GuidFromString(L"{FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF}") }; - std::optional badGuid{}; + const winrt::guid guid0{ ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-5555-49a3-80bd-e8fdd045185c}") }; + const winrt::guid guid1{ ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-6666-49a3-80bd-e8fdd045185c}") }; + const winrt::guid guid2{ ::Microsoft::Console::Utils::GuidFromString(L"{2C4DE342-38B7-51CF-B940-2309A097F518}") }; + const winrt::guid fakeGuid{ ::Microsoft::Console::Utils::GuidFromString(L"{FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF}") }; + const std::optional badGuid{}; VerifyParseSucceeded(settings0String); @@ -1450,7 +1450,7 @@ namespace TerminalAppLocalTests settings.LayerJson(settings._userSettings); VERIFY_IS_FALSE(settings._profiles.empty()); - GlobalAppSettings globalSettings{}; + auto globalSettings{ winrt::make() }; const auto profileImpl = winrt::get_self(settings._profiles[0]); auto terminalSettings = profileImpl->CreateTerminalSettings(globalSettings.GetColorSchemes()); VERIFY_ARE_EQUAL(expectedPath, terminalSettings.BackgroundImage()); @@ -1554,7 +1554,7 @@ namespace TerminalAppLocalTests VERIFY_IS_FALSE(settings._userDefaultProfileSettings == Json::Value::null); settings.LayerJson(settings._userSettings); - VERIFY_ARE_EQUAL(guid1String, settings._globals._unparsedDefaultProfile); + VERIFY_ARE_EQUAL(guid1String, settings._globals->UnparsedDefaultProfile()); VERIFY_ARE_EQUAL(2u, settings._profiles.size()); VERIFY_ARE_EQUAL(2345, settings._profiles.at(0).HistorySize()); @@ -1612,7 +1612,7 @@ namespace TerminalAppLocalTests settings.LayerJson(settings._userSettings); - VERIFY_ARE_EQUAL(guid1String, settings._globals._unparsedDefaultProfile); + VERIFY_ARE_EQUAL(guid1String, settings._globals->UnparsedDefaultProfile()); VERIFY_ARE_EQUAL(4u, settings._profiles.size()); VERIFY_ARE_EQUAL(guid1, settings._profiles.at(2).Guid()); @@ -1629,9 +1629,9 @@ namespace TerminalAppLocalTests // settings in defaultSettings should apply _on top_ of settings from // dynamic profiles. - winrt::guid guid1{ ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-1111-49a3-80bd-e8fdd045185c}") }; - winrt::guid guid2{ ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-2222-49a3-80bd-e8fdd045185c}") }; - winrt::guid guid3{ ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-3333-49a3-80bd-e8fdd045185c}") }; + const winrt::guid guid1{ ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-1111-49a3-80bd-e8fdd045185c}") }; + const winrt::guid guid2{ ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-2222-49a3-80bd-e8fdd045185c}") }; + const winrt::guid guid3{ ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-3333-49a3-80bd-e8fdd045185c}") }; const std::string userProfiles{ R"( { @@ -1794,12 +1794,13 @@ namespace TerminalAppLocalTests settings.LayerJson(settings._userSettings); settings._ValidateSettings(); - auto appKeyBindings = settings._globals._keybindings; + auto appKeyBindingsProj = settings._globals->GetKeybindings(); VERIFY_ARE_EQUAL(3u, settings.GetProfiles().size()); const auto profile2Guid = settings._profiles.at(2).Guid(); VERIFY_ARE_NOT_EQUAL(winrt::guid{}, profile2Guid); + const auto appKeyBindings = winrt::get_self(appKeyBindingsProj); VERIFY_ARE_EQUAL(12u, appKeyBindings->_keyShortcuts.size()); { @@ -2176,7 +2177,7 @@ namespace TerminalAppLocalTests VERIFY_ARE_EQUAL(2u, settings->_warnings.size()); VERIFY_ARE_EQUAL(2u, settings->_profiles.size()); - VERIFY_ARE_EQUAL(winrt::guid{ settings->_globals.DefaultProfile() }, settings->_profiles.at(0).Guid()); + VERIFY_ARE_EQUAL(settings->_globals->DefaultProfile(), settings->_profiles.at(0).Guid()); try { const auto [guid, termSettings] = settings->BuildSettings(nullptr); @@ -2241,14 +2242,14 @@ namespace TerminalAppLocalTests settings.LayerJson(settings._userSettings); VERIFY_ARE_EQUAL(6u, settings._profiles.size()); - VERIFY_ARE_EQUAL(2u, settings._globals._colorSchemes.size()); + VERIFY_ARE_EQUAL(2u, settings._globals->GetColorSchemes().Size()); - auto terminalSettings0 = winrt::get_self(settings._profiles[0])->CreateTerminalSettings(settings._globals._colorSchemes); - auto terminalSettings1 = winrt::get_self(settings._profiles[1])->CreateTerminalSettings(settings._globals._colorSchemes); - auto terminalSettings2 = winrt::get_self(settings._profiles[2])->CreateTerminalSettings(settings._globals._colorSchemes); - auto terminalSettings3 = winrt::get_self(settings._profiles[3])->CreateTerminalSettings(settings._globals._colorSchemes); - auto terminalSettings4 = winrt::get_self(settings._profiles[4])->CreateTerminalSettings(settings._globals._colorSchemes); - auto terminalSettings5 = winrt::get_self(settings._profiles[5])->CreateTerminalSettings(settings._globals._colorSchemes); + auto terminalSettings0 = winrt::get_self(settings._profiles[0])->CreateTerminalSettings(settings._globals->GetColorSchemes()); + auto terminalSettings1 = winrt::get_self(settings._profiles[1])->CreateTerminalSettings(settings._globals->GetColorSchemes()); + auto terminalSettings2 = winrt::get_self(settings._profiles[2])->CreateTerminalSettings(settings._globals->GetColorSchemes()); + auto terminalSettings3 = winrt::get_self(settings._profiles[3])->CreateTerminalSettings(settings._globals->GetColorSchemes()); + auto terminalSettings4 = winrt::get_self(settings._profiles[4])->CreateTerminalSettings(settings._globals->GetColorSchemes()); + auto terminalSettings5 = winrt::get_self(settings._profiles[5])->CreateTerminalSettings(settings._globals->GetColorSchemes()); VERIFY_ARE_EQUAL(ARGB(0, 0x12, 0x34, 0x56), terminalSettings0.CursorColor()); // from color scheme VERIFY_ARE_EQUAL(DEFAULT_CURSOR_COLOR, terminalSettings1.CursorColor()); // default @@ -2283,12 +2284,12 @@ namespace TerminalAppLocalTests const auto settingsObject = VerifyParseSucceeded(badSettings); auto settings = CascadiaSettings::FromJson(settingsObject); - VERIFY_ARE_EQUAL(0u, settings->_globals._keybindings->_keyShortcuts.size()); + VERIFY_ARE_EQUAL(0u, settings->_globals->_keybindings->_keyShortcuts.size()); - VERIFY_ARE_EQUAL(3u, settings->_globals._keybindingsWarnings.size()); - VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::TooManyKeysForChord, settings->_globals._keybindingsWarnings.at(0)); - VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::MissingRequiredParameter, settings->_globals._keybindingsWarnings.at(1)); - VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::MissingRequiredParameter, settings->_globals._keybindingsWarnings.at(2)); + VERIFY_ARE_EQUAL(3u, settings->_globals->_keybindingsWarnings.size()); + VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::TooManyKeysForChord, settings->_globals->_keybindingsWarnings.at(0)); + VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::MissingRequiredParameter, settings->_globals->_keybindingsWarnings.at(1)); + VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::MissingRequiredParameter, settings->_globals->_keybindingsWarnings.at(2)); settings->_ValidateKeybindings(); @@ -2325,17 +2326,17 @@ namespace TerminalAppLocalTests auto settings = CascadiaSettings::FromJson(settingsObject); - VERIFY_ARE_EQUAL(0u, settings->_globals._keybindings->_keyShortcuts.size()); + VERIFY_ARE_EQUAL(0u, settings->_globals->_keybindings->_keyShortcuts.size()); - for (const auto& warning : settings->_globals._keybindingsWarnings) + for (const auto& warning : settings->_globals->_keybindingsWarnings) { Log::Comment(NoThrowString().Format( L"warning:%d", warning)); } - VERIFY_ARE_EQUAL(3u, settings->_globals._keybindingsWarnings.size()); - VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::MissingRequiredParameter, settings->_globals._keybindingsWarnings.at(0)); - VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::MissingRequiredParameter, settings->_globals._keybindingsWarnings.at(1)); - VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::MissingRequiredParameter, settings->_globals._keybindingsWarnings.at(2)); + VERIFY_ARE_EQUAL(3u, settings->_globals->_keybindingsWarnings.size()); + VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::MissingRequiredParameter, settings->_globals->_keybindingsWarnings.at(0)); + VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::MissingRequiredParameter, settings->_globals->_keybindingsWarnings.at(1)); + VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::MissingRequiredParameter, settings->_globals->_keybindingsWarnings.at(2)); settings->_ValidateKeybindings(); @@ -2465,13 +2466,13 @@ namespace TerminalAppLocalTests const auto profile2Guid = settings._profiles.at(2).Guid(); VERIFY_ARE_NOT_EQUAL(winrt::guid{}, profile2Guid); - auto appKeyBindings = settings._globals._keybindings; + auto appKeyBindings = winrt::get_self(settings._globals->GetKeybindings()); VERIFY_ARE_EQUAL(5u, appKeyBindings->_keyShortcuts.size()); // A/D, B, C, E will be in the list of commands, for 4 total. // * A and D share the same name, so they'll only generate a single action. // * F's name is set manually to `null` - auto commands = settings._globals.GetCommands(); + auto commands = settings._globals->GetCommands(); VERIFY_ARE_EQUAL(4u, commands.Size()); { @@ -2665,7 +2666,7 @@ namespace TerminalAppLocalTests VERIFY_ARE_EQUAL(3u, settings.GetProfiles().size()); - auto& commands = settings._globals.GetCommands(); + auto commands = settings._globals->GetCommands(); VERIFY_ARE_EQUAL(1u, commands.Size()); { @@ -2686,8 +2687,8 @@ namespace TerminalAppLocalTests VERIFY_ARE_EQUAL(L"${profile.name}", realArgs.TerminalArgs().Profile()); } - auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands.GetView(), settings.GetProfiles(), settings._globals.GetColorSchemes()); - _logCommandNames(expandedCommands); + auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands, settings.GetProfiles(), settings._globals->GetColorSchemes()); + _logCommandNames(expandedCommands.GetView()); VERIFY_ARE_EQUAL(0u, settings._warnings.size()); VERIFY_ARE_EQUAL(3u, expandedCommands.Size()); @@ -2795,7 +2796,7 @@ namespace TerminalAppLocalTests VERIFY_ARE_EQUAL(3u, settings.GetProfiles().size()); - auto& commands = settings._globals.GetCommands(); + auto commands = settings._globals->GetCommands(); VERIFY_ARE_EQUAL(1u, commands.Size()); { @@ -2816,8 +2817,8 @@ namespace TerminalAppLocalTests VERIFY_ARE_EQUAL(L"${profile.name}", realArgs.TerminalArgs().Profile()); } - auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands.GetView(), settings.GetProfiles(), settings._globals.GetColorSchemes()); - _logCommandNames(expandedCommands); + auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands, settings.GetProfiles(), settings._globals->GetColorSchemes()); + _logCommandNames(expandedCommands.GetView()); VERIFY_ARE_EQUAL(0u, settings._warnings.size()); VERIFY_ARE_EQUAL(3u, expandedCommands.Size()); @@ -2927,7 +2928,7 @@ namespace TerminalAppLocalTests VERIFY_ARE_EQUAL(3u, settings.GetProfiles().size()); - auto& commands = settings._globals.GetCommands(); + auto commands = settings._globals->GetCommands(); VERIFY_ARE_EQUAL(1u, commands.Size()); { @@ -2949,8 +2950,8 @@ namespace TerminalAppLocalTests } settings._ValidateSettings(); - auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands.GetView(), settings.GetProfiles(), settings._globals.GetColorSchemes()); - _logCommandNames(expandedCommands); + auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands, settings.GetProfiles(), settings._globals->GetColorSchemes()); + _logCommandNames(expandedCommands.GetView()); VERIFY_ARE_EQUAL(0u, settings._warnings.size()); VERIFY_ARE_EQUAL(3u, expandedCommands.Size()); @@ -3068,10 +3069,10 @@ namespace TerminalAppLocalTests VERIFY_ARE_EQUAL(0u, settings._warnings.size()); VERIFY_ARE_EQUAL(3u, settings.GetProfiles().size()); - auto& commands = settings._globals.GetCommands(); + auto commands = settings._globals->GetCommands(); settings._ValidateSettings(); - auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands.GetView(), settings.GetProfiles(), settings._globals.GetColorSchemes()); - _logCommandNames(expandedCommands); + auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands, settings.GetProfiles(), settings._globals->GetColorSchemes()); + _logCommandNames(expandedCommands.GetView()); VERIFY_ARE_EQUAL(0u, settings._warnings.size()); VERIFY_ARE_EQUAL(1u, expandedCommands.Size()); @@ -3176,10 +3177,10 @@ namespace TerminalAppLocalTests VERIFY_ARE_EQUAL(0u, settings._warnings.size()); VERIFY_ARE_EQUAL(3u, settings.GetProfiles().size()); - auto& commands = settings._globals.GetCommands(); + auto commands = settings._globals->GetCommands(); settings._ValidateSettings(); - auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands.GetView(), settings.GetProfiles(), settings._globals.GetColorSchemes()); - _logCommandNames(expandedCommands); + auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands, settings.GetProfiles(), settings._globals->GetColorSchemes()); + _logCommandNames(expandedCommands.GetView()); VERIFY_ARE_EQUAL(0u, settings._warnings.size()); VERIFY_ARE_EQUAL(1u, expandedCommands.Size()); @@ -3315,10 +3316,10 @@ namespace TerminalAppLocalTests VERIFY_ARE_EQUAL(0u, settings._warnings.size()); VERIFY_ARE_EQUAL(3u, settings.GetProfiles().size()); - auto& commands = settings._globals.GetCommands(); + auto commands = settings._globals->GetCommands(); settings._ValidateSettings(); - auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands.GetView(), settings.GetProfiles(), settings._globals.GetColorSchemes()); - _logCommandNames(expandedCommands); + auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands, settings.GetProfiles(), settings._globals->GetColorSchemes()); + _logCommandNames(expandedCommands.GetView()); VERIFY_ARE_EQUAL(0u, settings._warnings.size()); @@ -3337,7 +3338,7 @@ namespace TerminalAppLocalTests VERIFY_IS_TRUE(commandImpl->HasNestedCommands()); VERIFY_ARE_EQUAL(3u, commandImpl->_subcommands.Size()); - _logCommandNames(commandImpl->_subcommands); + _logCommandNames(commandImpl->_subcommands.GetView()); { winrt::hstring childCommandName{ fmt::format(L"Split pane, profile: {}", name) }; auto childCommandProj = commandImpl->_subcommands.Lookup(childCommandName); @@ -3468,10 +3469,10 @@ namespace TerminalAppLocalTests VERIFY_ARE_EQUAL(0u, settings._warnings.size()); VERIFY_ARE_EQUAL(3u, settings.GetProfiles().size()); - auto& commands = settings._globals.GetCommands(); + auto commands = settings._globals->GetCommands(); settings._ValidateSettings(); - auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands.GetView(), settings.GetProfiles(), settings._globals.GetColorSchemes()); - _logCommandNames(expandedCommands); + auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands, settings.GetProfiles(), settings._globals->GetColorSchemes()); + _logCommandNames(expandedCommands.GetView()); VERIFY_ARE_EQUAL(0u, settings._warnings.size()); VERIFY_ARE_EQUAL(1u, expandedCommands.Size()); @@ -3581,10 +3582,10 @@ namespace TerminalAppLocalTests VERIFY_ARE_EQUAL(0u, settings._warnings.size()); VERIFY_ARE_EQUAL(3u, settings.GetProfiles().size()); - auto& commands = settings._globals.GetCommands(); + auto commands = settings._globals->GetCommands(); settings._ValidateSettings(); - auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands.GetView(), settings.GetProfiles(), settings._globals.GetColorSchemes()); - _logCommandNames(expandedCommands); + auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands, settings.GetProfiles(), settings._globals->GetColorSchemes()); + _logCommandNames(expandedCommands.GetView()); VERIFY_ARE_EQUAL(0u, settings._warnings.size()); VERIFY_ARE_EQUAL(1u, expandedCommands.Size()); @@ -3613,7 +3614,7 @@ namespace TerminalAppLocalTests VERIFY_IS_TRUE(commandImpl->HasNestedCommands()); VERIFY_ARE_EQUAL(3u, commandImpl->_subcommands.Size()); - _logCommandNames(commandImpl->_subcommands); + _logCommandNames(commandImpl->_subcommands.GetView()); { winrt::hstring childCommandName{ fmt::format(L"Split pane, profile: {}", name) }; auto childCommandProj = commandImpl->_subcommands.Lookup(childCommandName); @@ -3742,7 +3743,7 @@ namespace TerminalAppLocalTests VERIFY_ARE_EQUAL(0u, settings._warnings.size()); VERIFY_ARE_EQUAL(3u, settings.GetProfiles().size()); - auto& commands = settings._globals.GetCommands(); + auto commands = settings._globals->GetCommands(); settings._ValidateSettings(); _logCommandNames(commands); @@ -3819,7 +3820,7 @@ namespace TerminalAppLocalTests VERIFY_ARE_EQUAL(0u, settings._warnings.size()); VERIFY_ARE_EQUAL(3u, settings.GetProfiles().size()); - auto& commands = settings._globals.GetCommands(); + auto commands = settings._globals->GetCommands(); settings._ValidateSettings(); _logCommandNames(commands); @@ -3902,7 +3903,7 @@ namespace TerminalAppLocalTests VERIFY_ARE_EQUAL(0u, settings._warnings.size()); VERIFY_ARE_EQUAL(3u, settings.GetProfiles().size()); - auto& commands = settings._globals.GetCommands(); + auto commands = settings._globals->GetCommands(); settings._ValidateSettings(); _logCommandNames(commands); @@ -3998,7 +3999,7 @@ namespace TerminalAppLocalTests VERIFY_ARE_EQUAL(3u, settings.GetProfiles().size()); - auto& commands = settings._globals.GetCommands(); + auto commands = settings._globals->GetCommands(); VERIFY_ARE_EQUAL(1u, commands.Size()); { @@ -4019,8 +4020,8 @@ namespace TerminalAppLocalTests VERIFY_ARE_EQUAL(L"${scheme.name}", realArgs.TerminalArgs().Profile()); } - auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands.GetView(), settings.GetProfiles(), settings._globals.GetColorSchemes()); - _logCommandNames(expandedCommands); + auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands, settings.GetProfiles(), settings._globals->GetColorSchemes()); + _logCommandNames(expandedCommands.GetView()); VERIFY_ARE_EQUAL(0u, settings._warnings.size()); VERIFY_ARE_EQUAL(3u, expandedCommands.Size()); diff --git a/src/cascadia/TerminalApp/AppLogic.cpp b/src/cascadia/TerminalApp/AppLogic.cpp index d7adb4f2456..2a02e80dd13 100644 --- a/src/cascadia/TerminalApp/AppLogic.cpp +++ b/src/cascadia/TerminalApp/AppLogic.cpp @@ -561,7 +561,7 @@ namespace winrt::TerminalApp::implementation // - defaultInitialY: the system default y coordinate value // Return Value: // - a point containing the requested initial position in pixels. - winrt::Windows::Foundation::Point AppLogic::GetLaunchInitialPositions(int32_t defaultInitialX, int32_t defaultInitialY) + TerminalApp::InitialPosition AppLogic::GetInitialPosition(int64_t defaultInitialX, int64_t defaultInitialY) { if (!_loadedInitialSettings) { @@ -570,12 +570,10 @@ namespace winrt::TerminalApp::implementation } const auto initialPosition{ _settings->GlobalSettings().InitialPosition() }; - winrt::Windows::Foundation::Point point{ - /* X */ gsl::narrow_cast(initialPosition.x.value_or(defaultInitialX)), - /* Y */ gsl::narrow_cast(initialPosition.y.value_or(defaultInitialY)) + return { + initialPosition.X ? initialPosition.X.Value() : defaultInitialX, + initialPosition.Y ? initialPosition.Y.Value() : defaultInitialY }; - - return point; } winrt::Windows::UI::Xaml::ElementTheme AppLogic::GetRequestedTheme() diff --git a/src/cascadia/TerminalApp/AppLogic.h b/src/cascadia/TerminalApp/AppLogic.h index c0c75952b1a..a5e811a886b 100644 --- a/src/cascadia/TerminalApp/AppLogic.h +++ b/src/cascadia/TerminalApp/AppLogic.h @@ -38,7 +38,7 @@ namespace winrt::TerminalApp::implementation bool AlwaysOnTop() const; Windows::Foundation::Size GetLaunchDimensions(uint32_t dpi); - winrt::Windows::Foundation::Point GetLaunchInitialPositions(int32_t defaultInitialX, int32_t defaultInitialY); + TerminalApp::InitialPosition GetInitialPosition(int64_t defaultInitialX, int64_t defaultInitialY); winrt::Windows::UI::Xaml::ElementTheme GetRequestedTheme(); LaunchMode GetLaunchMode(); bool GetShowTabsInTitlebar(); diff --git a/src/cascadia/TerminalApp/AppLogic.idl b/src/cascadia/TerminalApp/AppLogic.idl index 73b77b54413..838b40e1a67 100644 --- a/src/cascadia/TerminalApp/AppLogic.idl +++ b/src/cascadia/TerminalApp/AppLogic.idl @@ -7,6 +7,12 @@ import "IDirectKeyListener.idl"; namespace TerminalApp { + struct InitialPosition + { + Int64 X; + Int64 Y; + }; + enum LaunchMode { DefaultMode, @@ -47,7 +53,7 @@ namespace TerminalApp Windows.Foundation.Size GetLaunchDimensions(UInt32 dpi); - Windows.Foundation.Point GetLaunchInitialPositions(Int32 defaultInitialX, Int32 defaultInitialY); + InitialPosition GetInitialPosition(Int64 defaultInitialX, Int64 defaultInitialY); Windows.UI.Xaml.ElementTheme GetRequestedTheme(); LaunchMode GetLaunchMode(); Boolean GetShowTabsInTitlebar(); diff --git a/src/cascadia/TerminalApp/CascadiaSettings.cpp b/src/cascadia/TerminalApp/CascadiaSettings.cpp index 4eda47ada1b..73bcc0e903c 100644 --- a/src/cascadia/TerminalApp/CascadiaSettings.cpp +++ b/src/cascadia/TerminalApp/CascadiaSettings.cpp @@ -52,7 +52,8 @@ CascadiaSettings::CascadiaSettings() : // generators. Set this to `false` for unit testing. // Arguments: // - addDynamicProfiles: if true, we'll add the built-in DPGs. -CascadiaSettings::CascadiaSettings(const bool addDynamicProfiles) +CascadiaSettings::CascadiaSettings(const bool addDynamicProfiles) : + _globals{ winrt::make_self() } { if (addDynamicProfiles) { @@ -106,7 +107,7 @@ gsl::span CascadiaSettings::GetProfiles() const noexcept // - the globally configured keybindings AppKeyBindings CascadiaSettings::GetKeybindings() const noexcept { - return _globals.GetKeybindings(); + return _globals->GetKeybindings(); } // Method Description: @@ -115,9 +116,9 @@ AppKeyBindings CascadiaSettings::GetKeybindings() const noexcept // - // Return Value: // - a reference to our global settings -GlobalAppSettings& CascadiaSettings::GlobalSettings() +winrt::TerminalApp::GlobalAppSettings CascadiaSettings::GlobalSettings() { - return _globals; + return *_globals; } // Method Description: @@ -227,9 +228,9 @@ void CascadiaSettings::_ValidateProfilesHaveGuid() void CascadiaSettings::_ResolveDefaultProfile() { const auto unparsedDefaultProfile{ GlobalSettings().UnparsedDefaultProfile() }; - if (unparsedDefaultProfile) + if (!unparsedDefaultProfile.empty()) { - auto maybeParsedDefaultProfile{ _GetProfileGuidByName(*unparsedDefaultProfile) }; + auto maybeParsedDefaultProfile{ _GetProfileGuidByName(unparsedDefaultProfile) }; auto defaultProfileGuid{ til::coalesce_value(maybeParsedDefaultProfile, winrt::guid{}) }; GlobalSettings().DefaultProfile(defaultProfileGuid); } @@ -404,15 +405,11 @@ void CascadiaSettings::_ValidateAllSchemesExist() bool foundInvalidScheme = false; for (auto& profile : _profiles) { - auto schemeName = profile.ColorSchemeName(); - if (!schemeName.empty()) + const auto schemeName = profile.ColorSchemeName(); + if (!_globals->GetColorSchemes().HasKey(schemeName)) { - const auto found = _globals.GetColorSchemes().find(schemeName.c_str()); - if (found == _globals.GetColorSchemes().end()) - { - profile.ColorSchemeName({ L"Campbell" }); - foundInvalidScheme = true; - } + profile.ColorSchemeName({ L"Campbell" }); + foundInvalidScheme = true; } } @@ -536,10 +533,10 @@ TerminalSettings CascadiaSettings::BuildSettings(winrt::guid profileGuid) const THROW_HR_IF_NULL(E_INVALIDARG, profile); const auto profileImpl = winrt::get_self(profile); - TerminalSettings result = profileImpl->CreateTerminalSettings(_globals.GetColorSchemes()); + TerminalSettings result = profileImpl->CreateTerminalSettings(_globals->GetColorSchemes()); // Place our appropriate global settings into the Terminal Settings - _globals.ApplyToSettings(result); + _globals->ApplyToSettings(result); return result; } @@ -573,7 +570,7 @@ winrt::guid CascadiaSettings::_GetProfileForArgs(const NewTerminalArgs& newTermi profileByName = _GetProfileGuidByName(newTerminalArgs.Profile()); } - return til::coalesce_value(profileByName, profileByIndex, _globals.DefaultProfile()); + return til::coalesce_value(profileByName, profileByIndex, _globals->DefaultProfile()); } // Method Description: @@ -661,7 +658,7 @@ std::optional CascadiaSettings::_GetProfileGuidByIndex(std::optiona // - void CascadiaSettings::_ValidateKeybindings() { - auto keybindingWarnings = _globals.GetKeybindingsWarnings(); + auto keybindingWarnings = _globals->GetKeybindingsWarnings(); if (!keybindingWarnings.empty()) { @@ -746,16 +743,8 @@ const ColorScheme CascadiaSettings::GetColorSchemeForProfile(const winrt::guid p { return nullptr; } - const std::wstring schemeName{ profile.ColorSchemeName() }; - auto scheme = _globals.GetColorSchemes().find(schemeName); - if (scheme != _globals.GetColorSchemes().end()) - { - return scheme->second; - } - else - { - return nullptr; - } + const auto schemeName = profile.ColorSchemeName(); + return _globals->GetColorSchemes().TryLookup(schemeName); } // Method Description: @@ -768,13 +757,10 @@ const ColorScheme CascadiaSettings::GetColorSchemeForProfile(const winrt::guid p // Return Value: // - true iff we found a matching scheme for the name schemeName bool CascadiaSettings::ApplyColorScheme(winrt::Microsoft::Terminal::TerminalControl::IControlSettings& settings, - std::wstring_view schemeName) + winrt::hstring schemeName) { - std::wstring name{ schemeName }; - auto schemeAndName = _globals.GetColorSchemes().find(name); - if (schemeAndName != _globals.GetColorSchemes().end()) + if (auto scheme{ _globals->GetColorSchemes().TryLookup(schemeName) }) { - const auto& scheme = schemeAndName->second; scheme.ApplyScheme(settings); return true; } diff --git a/src/cascadia/TerminalApp/CascadiaSettings.h b/src/cascadia/TerminalApp/CascadiaSettings.h index a64be8c364a..b2c0d3d87c6 100644 --- a/src/cascadia/TerminalApp/CascadiaSettings.h +++ b/src/cascadia/TerminalApp/CascadiaSettings.h @@ -67,7 +67,7 @@ class TerminalApp::CascadiaSettings final std::tuple BuildSettings(const winrt::TerminalApp::NewTerminalArgs& newTerminalArgs) const; winrt::TerminalApp::TerminalSettings BuildSettings(winrt::guid profileGuid) const; - GlobalAppSettings& GlobalSettings(); + winrt::TerminalApp::GlobalAppSettings GlobalSettings(); gsl::span GetProfiles() const noexcept; @@ -84,10 +84,10 @@ class TerminalApp::CascadiaSettings final std::vector& GetWarnings(); - bool ApplyColorScheme(winrt::Microsoft::Terminal::TerminalControl::IControlSettings& settings, std::wstring_view schemeName); + bool ApplyColorScheme(winrt::Microsoft::Terminal::TerminalControl::IControlSettings& settings, winrt::hstring schemeName); private: - GlobalAppSettings _globals; + winrt::com_ptr _globals; std::vector _profiles; std::vector _warnings; diff --git a/src/cascadia/TerminalApp/CascadiaSettingsSerialization.cpp b/src/cascadia/TerminalApp/CascadiaSettingsSerialization.cpp index fe68f476602..06dc5e55bd9 100644 --- a/src/cascadia/TerminalApp/CascadiaSettingsSerialization.cpp +++ b/src/cascadia/TerminalApp/CascadiaSettingsSerialization.cpp @@ -560,7 +560,7 @@ std::unique_ptr CascadiaSettings::FromJson(const Json::Value& // void CascadiaSettings::LayerJson(const Json::Value& json) { - _globals.LayerJson(json); + _globals->LayerJson(json); if (auto schemes{ json[SchemesKey.data()] }) { @@ -709,7 +709,7 @@ void CascadiaSettings::_LayerOrCreateColorScheme(const Json::Value& schemeJson) else { const auto scheme = implementation::ColorScheme::FromJson(schemeJson); - _globals.AddColorScheme(*scheme); + _globals->AddColorScheme(*scheme); } } @@ -728,11 +728,9 @@ winrt::com_ptr CascadiaSettings::_FindMatchingColor { if (auto schemeName = implementation::ColorScheme::GetNameFromJson(schemeJson)) { - auto& schemes = _globals.GetColorSchemes(); - auto iterator = schemes.find(*schemeName); - if (iterator != schemes.end()) + if (auto scheme{ _globals->GetColorSchemes().TryLookup(*schemeName) }) { - return winrt::get_self(iterator->second)->get_strong(); + return winrt::get_self(scheme)->get_strong(); } } return nullptr; diff --git a/src/cascadia/TerminalApp/Command.h b/src/cascadia/TerminalApp/Command.h index c98f968c6b0..6f3d374c1d1 100644 --- a/src/cascadia/TerminalApp/Command.h +++ b/src/cascadia/TerminalApp/Command.h @@ -60,7 +60,7 @@ namespace winrt::TerminalApp::implementation OBSERVABLE_GETSET_PROPERTY(winrt::hstring, KeyChordText, _PropertyChangedHandlers); OBSERVABLE_GETSET_PROPERTY(winrt::Windows::UI::Xaml::Controls::IconSource, IconSource, _PropertyChangedHandlers, nullptr); - GETSET_PROPERTY(::TerminalApp::ExpandCommandType, IterateOn, ::TerminalApp::ExpandCommandType::None); + GETSET_PROPERTY(ExpandCommandType, IterateOn, ExpandCommandType::None); private: Json::Value _originalJson; diff --git a/src/cascadia/TerminalApp/GlobalAppSettings.cpp b/src/cascadia/TerminalApp/GlobalAppSettings.cpp index 4cbba508b1f..7507e83bdc6 100644 --- a/src/cascadia/TerminalApp/GlobalAppSettings.cpp +++ b/src/cascadia/TerminalApp/GlobalAppSettings.cpp @@ -9,8 +9,10 @@ #include "JsonUtils.h" #include "TerminalSettingsSerializationHelpers.h" +#include "GlobalAppSettings.g.cpp" + using namespace TerminalApp; -using namespace winrt::TerminalApp; +using namespace winrt::TerminalApp::implementation; using namespace winrt::Windows::UI::Xaml; using namespace ::Microsoft::Console; using namespace winrt::Microsoft::UI::Xaml::Controls; @@ -51,52 +53,40 @@ static constexpr bool debugFeaturesDefault{ false }; #endif GlobalAppSettings::GlobalAppSettings() : - _keybindings{ winrt::make_self() }, + _keybindings{ winrt::make_self() }, _keybindingsWarnings{}, - _colorSchemes{}, - _unparsedDefaultProfile{ std::nullopt }, + _unparsedDefaultProfile{}, _defaultProfile{}, - _InitialRows{ DEFAULT_ROWS }, - _InitialCols{ DEFAULT_COLS }, - _WordDelimiters{ DEFAULT_WORD_DELIMITERS }, _DebugFeaturesEnabled{ debugFeaturesDefault } { _commands = winrt::single_threaded_map(); + _colorSchemes = winrt::single_threaded_map(); } -GlobalAppSettings::~GlobalAppSettings() -{ -} - -std::unordered_map& GlobalAppSettings::GetColorSchemes() noexcept -{ - return _colorSchemes; -} - -const std::unordered_map& GlobalAppSettings::GetColorSchemes() const noexcept +winrt::Windows::Foundation::Collections::IMapView GlobalAppSettings::GetColorSchemes() noexcept { - return _colorSchemes; + return _colorSchemes.GetView(); } -void GlobalAppSettings::DefaultProfile(const GUID defaultProfile) noexcept +void GlobalAppSettings::DefaultProfile(const winrt::guid& defaultProfile) noexcept { - _unparsedDefaultProfile.reset(); + _unparsedDefaultProfile.clear(); _defaultProfile = defaultProfile; } -GUID GlobalAppSettings::DefaultProfile() const +winrt::guid GlobalAppSettings::DefaultProfile() const { // If we have an unresolved default profile, we should likely explode. - THROW_HR_IF(E_INVALIDARG, _unparsedDefaultProfile.has_value()); + THROW_HR_IF(E_INVALIDARG, !_unparsedDefaultProfile.empty()); return _defaultProfile; } -std::optional GlobalAppSettings::UnparsedDefaultProfile() const +winrt::hstring GlobalAppSettings::UnparsedDefaultProfile() const { return _unparsedDefaultProfile; } -AppKeyBindings GlobalAppSettings::GetKeybindings() const noexcept +winrt::TerminalApp::AppKeyBindings GlobalAppSettings::GetKeybindings() const noexcept { return *_keybindings; } @@ -107,7 +97,7 @@ AppKeyBindings GlobalAppSettings::GetKeybindings() const noexcept // - settings: a TerminalSettings object to add global property values to. // Return Value: // - -void GlobalAppSettings::ApplyToSettings(TerminalSettings& settings) const noexcept +void GlobalAppSettings::ApplyToSettings(const TerminalApp::TerminalSettings& settings) const noexcept { settings.KeyBindings(GetKeybindings()); settings.InitialRows(_InitialRows); @@ -126,10 +116,10 @@ void GlobalAppSettings::ApplyToSettings(TerminalSettings& settings) const noexce // - json: an object which should be a serialization of a GlobalAppSettings object. // Return Value: // - a new GlobalAppSettings instance created from the values in `json` -GlobalAppSettings GlobalAppSettings::FromJson(const Json::Value& json) +winrt::com_ptr GlobalAppSettings::FromJson(const Json::Value& json) { - GlobalAppSettings result; - result.LayerJson(json); + auto result = winrt::make_self(); + result->LayerJson(json); return result; } @@ -214,10 +204,9 @@ void GlobalAppSettings::LayerJson(const Json::Value& json) // - scheme: the color scheme to add // Return Value: // - -void GlobalAppSettings::AddColorScheme(ColorScheme scheme) +void GlobalAppSettings::AddColorScheme(const winrt::TerminalApp::ColorScheme& scheme) { - std::wstring name{ scheme.Name() }; - _colorSchemes[name] = std::move(scheme); + _colorSchemes.Insert(scheme.Name(), scheme); } // Method Description: @@ -234,12 +223,7 @@ std::vector GlobalAppSettings::GetKeybindings return _keybindingsWarnings; } -const winrt::Windows::Foundation::Collections::IMap& GlobalAppSettings::GetCommands() const noexcept -{ - return _commands; -} - -winrt::Windows::Foundation::Collections::IMap& GlobalAppSettings::GetCommands() noexcept +winrt::Windows::Foundation::Collections::IMapView GlobalAppSettings::GetCommands() noexcept { - return _commands; + return _commands.GetView(); } diff --git a/src/cascadia/TerminalApp/GlobalAppSettings.h b/src/cascadia/TerminalApp/GlobalAppSettings.h index d78d15a8e34..82d385a9434 100644 --- a/src/cascadia/TerminalApp/GlobalAppSettings.h +++ b/src/cascadia/TerminalApp/GlobalAppSettings.h @@ -14,11 +14,12 @@ Author(s): --*/ #pragma once + +#include "GlobalAppSettings.g.h" + #include "AppKeyBindings.h" #include "Command.h" -#include "SettingsTypes.h" - -#include "ColorScheme.g.h" +#include "ColorScheme.h" // fwdecl unittest classes namespace TerminalAppLocalTests @@ -27,73 +28,68 @@ namespace TerminalAppLocalTests class ColorSchemeTests; }; -namespace TerminalApp +namespace winrt::TerminalApp::implementation { - class GlobalAppSettings; -}; - -class TerminalApp::GlobalAppSettings final -{ -public: - GlobalAppSettings(); - ~GlobalAppSettings(); - - std::unordered_map& GetColorSchemes() noexcept; - const std::unordered_map& GetColorSchemes() const noexcept; - void AddColorScheme(winrt::TerminalApp::ColorScheme scheme); - - winrt::TerminalApp::AppKeyBindings GetKeybindings() const noexcept; - - static GlobalAppSettings FromJson(const Json::Value& json); - void LayerJson(const Json::Value& json); - - void ApplyToSettings(winrt::TerminalApp::TerminalSettings& settings) const noexcept; - - std::vector GetKeybindingsWarnings() const; - - const winrt::Windows::Foundation::Collections::IMap& GetCommands() const noexcept; - winrt::Windows::Foundation::Collections::IMap& GetCommands() noexcept; - - // These are implemented manually to handle the string/GUID exchange - // by higher layers in the app. - void DefaultProfile(const GUID defaultProfile) noexcept; - GUID DefaultProfile() const; - std::optional UnparsedDefaultProfile() const; - - GETSET_PROPERTY(int32_t, InitialRows); // default value set in constructor - GETSET_PROPERTY(int32_t, InitialCols); // default value set in constructor - GETSET_PROPERTY(bool, AlwaysShowTabs, true); - GETSET_PROPERTY(bool, ShowTitleInTitlebar, true); - GETSET_PROPERTY(bool, ConfirmCloseAllTabs, true); - GETSET_PROPERTY(winrt::Windows::UI::Xaml::ElementTheme, Theme, winrt::Windows::UI::Xaml::ElementTheme::Default); - GETSET_PROPERTY(winrt::Microsoft::UI::Xaml::Controls::TabViewWidthMode, TabWidthMode, winrt::Microsoft::UI::Xaml::Controls::TabViewWidthMode::Equal); - GETSET_PROPERTY(bool, ShowTabsInTitlebar, true); - GETSET_PROPERTY(std::wstring, WordDelimiters); // default value set in constructor - GETSET_PROPERTY(bool, CopyOnSelect, false); - GETSET_PROPERTY(winrt::Microsoft::Terminal::TerminalControl::CopyFormat, CopyFormatting, 0); - GETSET_PROPERTY(bool, WarnAboutLargePaste, true); - GETSET_PROPERTY(bool, WarnAboutMultiLinePaste, true); - GETSET_PROPERTY(LaunchPosition, InitialPosition); - GETSET_PROPERTY(winrt::TerminalApp::LaunchMode, LaunchMode, winrt::TerminalApp::LaunchMode::DefaultMode); - GETSET_PROPERTY(bool, SnapToGridOnResize, true); - GETSET_PROPERTY(bool, ForceFullRepaintRendering, false); - GETSET_PROPERTY(bool, SoftwareRendering, false); - GETSET_PROPERTY(bool, ForceVTInput, false); - GETSET_PROPERTY(bool, DebugFeaturesEnabled); // default value set in constructor - GETSET_PROPERTY(bool, StartOnUserLogin, false); - GETSET_PROPERTY(bool, AlwaysOnTop, false); - GETSET_PROPERTY(bool, UseTabSwitcher, true); - -private: - std::optional _unparsedDefaultProfile; - GUID _defaultProfile; - - winrt::com_ptr _keybindings; - std::vector<::TerminalApp::SettingsLoadWarnings> _keybindingsWarnings; - - std::unordered_map _colorSchemes; - winrt::Windows::Foundation::Collections::IMap _commands; - - friend class TerminalAppLocalTests::SettingsTests; - friend class TerminalAppLocalTests::ColorSchemeTests; -}; + struct GlobalAppSettings : GlobalAppSettingsT + { + public: + GlobalAppSettings(); + + Windows::Foundation::Collections::IMapView GetColorSchemes() noexcept; + void AddColorScheme(const TerminalApp::ColorScheme& scheme); + + TerminalApp::AppKeyBindings GetKeybindings() const noexcept; + + static com_ptr FromJson(const Json::Value& json); + void LayerJson(const Json::Value& json); + + void ApplyToSettings(const TerminalApp::TerminalSettings& settings) const noexcept; + + std::vector<::TerminalApp::SettingsLoadWarnings> GetKeybindingsWarnings() const; + + Windows::Foundation::Collections::IMapView GetCommands() noexcept; + + // These are implemented manually to handle the string/GUID exchange + // by higher layers in the app. + void DefaultProfile(const guid& defaultProfile) noexcept; + guid DefaultProfile() const; + hstring UnparsedDefaultProfile() const; + + GETSET_PROPERTY(int32_t, InitialRows, DEFAULT_ROWS); + GETSET_PROPERTY(int32_t, InitialCols, DEFAULT_COLS); + GETSET_PROPERTY(bool, AlwaysShowTabs, true); + GETSET_PROPERTY(bool, ShowTitleInTitlebar, true); + GETSET_PROPERTY(bool, ConfirmCloseAllTabs, true); + GETSET_PROPERTY(winrt::Windows::UI::Xaml::ElementTheme, Theme, winrt::Windows::UI::Xaml::ElementTheme::Default); + GETSET_PROPERTY(winrt::Microsoft::UI::Xaml::Controls::TabViewWidthMode, TabWidthMode, winrt::Microsoft::UI::Xaml::Controls::TabViewWidthMode::Equal); + GETSET_PROPERTY(bool, ShowTabsInTitlebar, true); + GETSET_PROPERTY(hstring, WordDelimiters, DEFAULT_WORD_DELIMITERS); + GETSET_PROPERTY(bool, CopyOnSelect, false); + GETSET_PROPERTY(winrt::Microsoft::Terminal::TerminalControl::CopyFormat, CopyFormatting, 0); + GETSET_PROPERTY(bool, WarnAboutLargePaste, true); + GETSET_PROPERTY(bool, WarnAboutMultiLinePaste, true); + GETSET_PROPERTY(winrt::TerminalApp::LaunchPosition, InitialPosition, nullptr, nullptr); + GETSET_PROPERTY(winrt::TerminalApp::LaunchMode, LaunchMode, winrt::TerminalApp::LaunchMode::DefaultMode); + GETSET_PROPERTY(bool, SnapToGridOnResize, true); + GETSET_PROPERTY(bool, ForceFullRepaintRendering, false); + GETSET_PROPERTY(bool, SoftwareRendering, false); + GETSET_PROPERTY(bool, ForceVTInput, false); + GETSET_PROPERTY(bool, DebugFeaturesEnabled); // default value set in constructor + GETSET_PROPERTY(bool, StartOnUserLogin, false); + GETSET_PROPERTY(bool, AlwaysOnTop, false); + GETSET_PROPERTY(bool, UseTabSwitcher, true); + + private: + hstring _unparsedDefaultProfile; + guid _defaultProfile; + + com_ptr _keybindings; + std::vector<::TerminalApp::SettingsLoadWarnings> _keybindingsWarnings; + + Windows::Foundation::Collections::IMap _colorSchemes; + Windows::Foundation::Collections::IMap _commands; + + friend class TerminalAppLocalTests::SettingsTests; + friend class TerminalAppLocalTests::ColorSchemeTests; + }; +} diff --git a/src/cascadia/TerminalApp/GlobalAppSettings.idl b/src/cascadia/TerminalApp/GlobalAppSettings.idl new file mode 100644 index 00000000000..6b0de0440ab --- /dev/null +++ b/src/cascadia/TerminalApp/GlobalAppSettings.idl @@ -0,0 +1,59 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import "AppLogic.idl"; +import "ColorScheme.idl"; +import "AppKeybindings.idl"; +import "Command.idl"; +import "TerminalSettings.idl"; + +namespace TerminalApp +{ + // MIDL 3 allows for structs to hold nullable types + // Though IReference is a WinRT object, MIDL 3 + // handles all of the ownership logic for us. + // Docs: https://docs.microsoft.com/en-us/uwp/midl-3/intro#types + struct LaunchPosition + { + Windows.Foundation.IReference X; + Windows.Foundation.IReference Y; + }; + + [default_interface] runtimeclass GlobalAppSettings { + Guid DefaultProfile; + String UnparsedDefaultProfile(); + + Int32 InitialRows; + Int32 InitialCols; + Boolean AlwaysShowTabs; + Boolean ShowTitleInTitlebar; + Boolean ConfirmCloseAllTabs; + Windows.UI.Xaml.ElementTheme Theme; + Microsoft.UI.Xaml.Controls.TabViewWidthMode TabWidthMode; + Boolean ShowTabsInTitlebar; + String WordDelimiters; + Boolean CopyOnSelect; + Microsoft.Terminal.TerminalControl.CopyFormat CopyFormatting; + Boolean WarnAboutLargePaste; + Boolean WarnAboutMultiLinePaste; + LaunchPosition InitialPosition; + LaunchMode LaunchMode; + Boolean SnapToGridOnResize; + Boolean ForceFullRepaintRendering; + Boolean SoftwareRendering; + Boolean ForceVTInput; + Boolean DebugFeaturesEnabled; + Boolean StartOnUserLogin; + Boolean AlwaysOnTop; + Boolean UseTabSwitcher; + + Windows.Foundation.Collections.IMapView GetColorSchemes(); + void AddColorScheme(ColorScheme scheme); + + AppKeyBindings GetKeybindings(); + + Windows.Foundation.Collections.IMapView GetCommands(); + + void ApplyToSettings(TerminalSettings settings); + } +} diff --git a/src/cascadia/TerminalApp/Profile.cpp b/src/cascadia/TerminalApp/Profile.cpp index 5a594171e68..c515c4cd414 100644 --- a/src/cascadia/TerminalApp/Profile.cpp +++ b/src/cascadia/TerminalApp/Profile.cpp @@ -75,9 +75,9 @@ Profile::Profile(guid guid) : // - schemes: a list of schemes to look for our color scheme in, if we have one. // Return Value: // - a new TerminalSettings object with our settings in it. -winrt::TerminalApp::TerminalSettings Profile::CreateTerminalSettings(const std::unordered_map& schemes) const +winrt::TerminalApp::TerminalSettings Profile::CreateTerminalSettings(const Collections::IMapView& schemes) const { - winrt::TerminalApp::TerminalSettings terminalSettings{}; + auto terminalSettings = winrt::make(); // Fill in the Terminal Setting's CoreSettings from the profile terminalSettings.HistorySize(_HistorySize); @@ -115,10 +115,9 @@ winrt::TerminalApp::TerminalSettings Profile::CreateTerminalSettings(const std:: if (!_ColorSchemeName.empty()) { - const auto found = schemes.find(_ColorSchemeName.c_str()); - if (found != schemes.end()) + if (const auto found{ schemes.TryLookup(_ColorSchemeName) }) { - found->second.ApplyScheme(terminalSettings); + found.ApplyScheme(terminalSettings); } } if (_Foreground) @@ -516,7 +515,7 @@ winrt::guid Profile::Guid() const return *_Guid; } -void Profile::Guid(winrt::guid guid) noexcept +void Profile::Guid(const winrt::guid& guid) noexcept { _Guid = guid; } @@ -531,7 +530,7 @@ winrt::guid Profile::ConnectionType() const noexcept return *_ConnectionType; } -void Profile::ConnectionType(winrt::guid conType) noexcept +void Profile::ConnectionType(const winrt::guid& conType) noexcept { _ConnectionType = conType; } diff --git a/src/cascadia/TerminalApp/Profile.h b/src/cascadia/TerminalApp/Profile.h index 823eaae42fa..8286043c725 100644 --- a/src/cascadia/TerminalApp/Profile.h +++ b/src/cascadia/TerminalApp/Profile.h @@ -16,7 +16,7 @@ Author(s): #pragma once #include "Profile.g.h" -#include "ColorScheme.g.h" +#include "TerminalSettings.h" #include "../inc/cppwinrt_utils.h" #include "JsonUtils.h" @@ -46,7 +46,7 @@ namespace winrt::TerminalApp::implementation Profile(); Profile(guid guid); - TerminalApp::TerminalSettings CreateTerminalSettings(const std::unordered_map& schemes) const; + TerminalApp::TerminalSettings CreateTerminalSettings(const Windows::Foundation::Collections::IMapView& schemes) const; Json::Value GenerateStub() const; static com_ptr FromJson(const Json::Value& json); @@ -61,11 +61,11 @@ namespace winrt::TerminalApp::implementation bool HasGuid() const noexcept; winrt::guid Guid() const; - void Guid(winrt::guid guid) noexcept; + void Guid(const winrt::guid& guid) noexcept; bool HasConnectionType() const noexcept; winrt::guid ConnectionType() const noexcept; - void ConnectionType(winrt::guid conType) noexcept; + void ConnectionType(const winrt::guid& conType) noexcept; // BackgroundImageAlignment is 1 setting saved as 2 separate values const Windows::UI::Xaml::HorizontalAlignment BackgroundImageHorizontalAlignment() const noexcept; diff --git a/src/cascadia/TerminalApp/SettingsTypes.h b/src/cascadia/TerminalApp/SettingsTypes.h index 946b1951cba..0fc1fa0bb6a 100644 --- a/src/cascadia/TerminalApp/SettingsTypes.h +++ b/src/cascadia/TerminalApp/SettingsTypes.h @@ -11,14 +11,8 @@ Module Name: #pragma once -namespace TerminalApp +namespace winrt::TerminalApp { - struct LaunchPosition - { - std::optional x; - std::optional y; - }; - enum class ExpandCommandType : uint32_t { None = 0, diff --git a/src/cascadia/TerminalApp/TerminalAppLib.vcxproj b/src/cascadia/TerminalApp/TerminalAppLib.vcxproj index a562ed31e30..f4a0ee3c25e 100644 --- a/src/cascadia/TerminalApp/TerminalAppLib.vcxproj +++ b/src/cascadia/TerminalApp/TerminalAppLib.vcxproj @@ -107,7 +107,9 @@ ColorScheme.idl - + + GlobalAppSettings.idl + Profile.idl @@ -188,7 +190,9 @@ ColorScheme.idl - + + GlobalAppSettings.idl + Profile.idl @@ -281,6 +285,7 @@ + diff --git a/src/cascadia/TerminalApp/TerminalAppLib.vcxproj.filters b/src/cascadia/TerminalApp/TerminalAppLib.vcxproj.filters index 3a2e600fd71..347c2e138cd 100644 --- a/src/cascadia/TerminalApp/TerminalAppLib.vcxproj.filters +++ b/src/cascadia/TerminalApp/TerminalAppLib.vcxproj.filters @@ -154,6 +154,9 @@ settings + + settings + diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index 5c62c5ade3e..0023ccd285f 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -2070,16 +2070,16 @@ namespace winrt::TerminalApp::implementation // - IMap TerminalPage::_ExpandCommands(IMapView commandsToExpand, gsl::span profiles, - const std::unordered_map& schemes) + IMapView schemes) { std::vector<::TerminalApp::SettingsLoadWarnings> warnings; std::vector sortedSchemes; - sortedSchemes.reserve(schemes.size()); + sortedSchemes.reserve(schemes.Size()); for (const auto& nameAndScheme : schemes) { - sortedSchemes.push_back(nameAndScheme.second); + sortedSchemes.push_back(nameAndScheme.Value()); } std::sort(sortedSchemes.begin(), sortedSchemes.end(), @@ -2108,7 +2108,7 @@ namespace winrt::TerminalApp::implementation // - void TerminalPage::_UpdateCommandsForPalette() { - IMap copyOfCommands = _ExpandCommands(_settings->GlobalSettings().GetCommands().GetView(), + IMap copyOfCommands = _ExpandCommands(_settings->GlobalSettings().GetCommands(), _settings->GetProfiles(), _settings->GlobalSettings().GetColorSchemes()); diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h index b30682ada54..00f18a4cc1c 100644 --- a/src/cascadia/TerminalApp/TerminalPage.h +++ b/src/cascadia/TerminalApp/TerminalPage.h @@ -138,7 +138,7 @@ namespace winrt::TerminalApp::implementation void _UpdateCommandsForPalette(); static winrt::Windows::Foundation::Collections::IMap _ExpandCommands(Windows::Foundation::Collections::IMapView commandsToExpand, gsl::span profiles, - const std::unordered_map& schemes); + Windows::Foundation::Collections::IMapView schemes); void _DuplicateTabViewItem(); void _RemoveTabViewItem(const Microsoft::UI::Xaml::Controls::TabViewItem& tabViewItem); diff --git a/src/cascadia/TerminalApp/TerminalSettingsSerializationHelpers.h b/src/cascadia/TerminalApp/TerminalSettingsSerializationHelpers.h index deb7856063a..47e2c681025 100644 --- a/src/cascadia/TerminalApp/TerminalSettingsSerializationHelpers.h +++ b/src/cascadia/TerminalApp/TerminalSettingsSerializationHelpers.h @@ -184,7 +184,7 @@ JSON_ENUM_MAPPER(::winrt::Microsoft::UI::Xaml::Controls::TabViewWidthMode) }; }; -JSON_ENUM_MAPPER(::TerminalApp::ExpandCommandType) +JSON_ENUM_MAPPER(winrt::TerminalApp::ExpandCommandType) { JSON_MAPPINGS(2) = { pair_type{ "profiles", ValueType::Profiles }, @@ -226,11 +226,11 @@ JSON_FLAG_MAPPER(::winrt::Microsoft::Terminal::TerminalControl::CopyFormat) // (abc, 100): if a value is not valid, we treat it as default // (100, 100, 100): we only read the first two values, this is equivalent to (100, 100) template<> -struct ::TerminalApp::JsonUtils::ConversionTrait<::TerminalApp::LaunchPosition> +struct ::TerminalApp::JsonUtils::ConversionTrait<::winrt::TerminalApp::LaunchPosition> { - ::TerminalApp::LaunchPosition FromJson(const Json::Value& json) + ::winrt::TerminalApp::LaunchPosition FromJson(const Json::Value& json) { - ::TerminalApp::LaunchPosition ret; + ::winrt::TerminalApp::LaunchPosition ret; std::string initialPosition{ json.asString() }; static constexpr char singleCharDelim = ','; std::stringstream tokenStream(initialPosition); @@ -244,15 +244,15 @@ struct ::TerminalApp::JsonUtils::ConversionTrait<::TerminalApp::LaunchPosition> { try { - int32_t position = std::stoi(token); + int64_t position = std::stol(token); if (initialPosIndex == 0) { - ret.x.emplace(position); + ret.X = position; } if (initialPosIndex == 1) { - ret.y.emplace(position); + ret.Y = position; } } catch (...) diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index 0ae788956a5..d7896b6aa32 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -241,9 +241,9 @@ void AppHost::_HandleCreateWindow(const HWND hwnd, RECT proposedRect, winrt::Ter launchMode = _logic.GetLaunchMode(); // Acquire the actual initial position - winrt::Windows::Foundation::Point initialPosition = _logic.GetLaunchInitialPositions(proposedRect.left, proposedRect.top); - proposedRect.left = gsl::narrow_cast(initialPosition.X); - proposedRect.top = gsl::narrow_cast(initialPosition.Y); + auto initialPos = _logic.GetInitialPosition(proposedRect.left, proposedRect.top); + proposedRect.left = static_cast(initialPos.X); + proposedRect.top = static_cast(initialPos.Y); long adjustedHeight = 0; long adjustedWidth = 0; From 614507b95b3ae7be05fdc9478c82932b4b2207d9 Mon Sep 17 00:00:00 2001 From: PankajBhojwani Date: Thu, 3 Sep 2020 13:52:39 -0400 Subject: [PATCH 092/266] OSC 8 support for conhost and terminal (#7251) ## Summary of the Pull Request Conhost can now support OSC8 sequences (as specified [here](https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda)). Terminal also supports those sequences and additionally hyperlinks can be opened by Ctrl+LeftClicking on them. ## References #204 ## PR Checklist * [X] Closes #204 * [ ] 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 ## Detailed Description of the Pull Request / Additional comments Added support to: - parse OSC8 sequences and extract URIs from them (conhost and terminal) - add hyperlink uri data to textbuffer/screeninformation, associated with a hyperlink id (conhost and terminal) - attach hyperlink ids to text to allow for uri extraction from the textbuffer/screeninformation (conhost and terminal) - process ctrl+leftclick to open a hyperlink in the clicked region if present ## Validation Steps Performed Open up a PowerShell tab and type ```PowerShell ${ESC}=[char]27 Write-Host "${ESC}]8;;https://github.com/microsoft/terminal${ESC}\This is a link!${ESC}]8;;${ESC}\" ``` Ctrl+LeftClick on the link correctly brings you to the terminal page on github ![hyperlink](https://user-images.githubusercontent.com/26824113/89953536-45a6f580-dbfd-11ea-8e0d-8a3cd25c634a.gif) --- .../actions/spell-check/dictionary/apis.txt | 1 + .../spell-check/dictionary/dictionary.txt | 1 + src/buffer/out/AttrRow.cpp | 17 ++ src/buffer/out/AttrRow.hpp | 2 + src/buffer/out/TextAttribute.cpp | 41 ++++- src/buffer/out/TextAttribute.hpp | 24 ++- src/buffer/out/textBuffer.cpp | 150 +++++++++++++++++- src/buffer/out/textBuffer.hpp | 13 ++ src/cascadia/TerminalApp/TerminalPage.cpp | 15 ++ src/cascadia/TerminalApp/TerminalPage.h | 3 + src/cascadia/TerminalControl/TermControl.cpp | 19 ++- src/cascadia/TerminalControl/TermControl.h | 16 ++ src/cascadia/TerminalControl/TermControl.idl | 6 + src/cascadia/TerminalCore/ITerminalApi.hpp | 3 + src/cascadia/TerminalCore/Terminal.cpp | 15 ++ src/cascadia/TerminalCore/Terminal.hpp | 7 + src/cascadia/TerminalCore/TerminalApi.cpp | 29 ++++ .../TerminalCore/TerminalDispatch.cpp | 21 +++ .../TerminalCore/TerminalDispatch.hpp | 3 + .../TerminalCore/TerminalDispatchGraphics.cpp | 2 +- .../TerminalCore/terminalrenderdata.cpp | 10 ++ .../ConptyRoundtripTests.cpp | 69 ++++++++ .../TerminalApiTest.cpp | 57 +++++++ src/host/getset.cpp | 18 +++ src/host/getset.h | 6 + src/host/outputStream.cpp | 19 +++ src/host/outputStream.hpp | 3 + src/host/renderData.cpp | 24 +++ src/host/renderData.hpp | 3 + src/host/ut_host/ScreenBufferTests.cpp | 51 ++++++ src/host/ut_host/TextBufferTests.cpp | 79 +++++++++ src/host/ut_host/VtIoTests.cpp | 10 ++ src/renderer/inc/IRenderData.hpp | 3 + src/renderer/vt/VtSequences.cpp | 43 +++++ src/renderer/vt/Xterm256Engine.cpp | 33 +++- src/renderer/vt/Xterm256Engine.hpp | 2 + src/renderer/vt/vtrenderer.hpp | 2 + src/terminal/adapter/ITermDispatch.hpp | 3 + src/terminal/adapter/adaptDispatch.cpp | 20 +++ src/terminal/adapter/adaptDispatch.hpp | 3 + .../adapter/adaptDispatchGraphics.cpp | 2 +- src/terminal/adapter/conGetSet.hpp | 3 + src/terminal/adapter/termDispatch.hpp | 3 + .../adapter/ut_adapter/adapterTest.cpp | 14 ++ .../parser/OutputStateMachineEngine.cpp | 54 +++++++ .../parser/OutputStateMachineEngine.hpp | 6 + .../parser/ft_fuzzer/VTCommandFuzzer.cpp | 70 +++++++- .../parser/ut_parser/OutputEngineTest.cpp | 57 +++++++ 48 files changed, 1040 insertions(+), 15 deletions(-) diff --git a/.github/actions/spell-check/dictionary/apis.txt b/.github/actions/spell-check/dictionary/apis.txt index 96d302a13c3..6e450ee12bb 100644 --- a/.github/actions/spell-check/dictionary/apis.txt +++ b/.github/actions/spell-check/dictionary/apis.txt @@ -50,5 +50,6 @@ syscall tmp tx userenv +wcstoui XDocument XElement diff --git a/.github/actions/spell-check/dictionary/dictionary.txt b/.github/actions/spell-check/dictionary/dictionary.txt index e1b7da0f86a..7344a626ea2 100644 --- a/.github/actions/spell-check/dictionary/dictionary.txt +++ b/.github/actions/spell-check/dictionary/dictionary.txt @@ -186988,6 +186988,7 @@ hyperleucocytotic hyperleukocytosis hyperlexis hyperlink +hyperlinks hyperlinking hyperlipaemia hyperlipaemic diff --git a/src/buffer/out/AttrRow.cpp b/src/buffer/out/AttrRow.cpp index 5df4da3978d..ffd95ad3f09 100644 --- a/src/buffer/out/AttrRow.cpp +++ b/src/buffer/out/AttrRow.cpp @@ -175,6 +175,23 @@ size_t ATTR_ROW::FindAttrIndex(const size_t index, size_t* const pApplies) const return runPos - _list.cbegin(); } +// Routine Description: +// - Finds the hyperlink IDs present in this row and returns them +// Return value: +// - An unordered set containing the hyperlink IDs present in this row +std::unordered_set ATTR_ROW::GetHyperlinks() +{ + std::unordered_set ids; + for (const auto& run : _list) + { + if (run.GetAttributes().IsHyperlink()) + { + ids.emplace(run.GetAttributes().GetHyperlinkId()); + } + } + return ids; +} + // Routine Description: // - Sets the attributes (colors) of all character positions from the given position through the end of the row. // Arguments: diff --git a/src/buffer/out/AttrRow.hpp b/src/buffer/out/AttrRow.hpp index 2f0a07794c3..a0802a74591 100644 --- a/src/buffer/out/AttrRow.hpp +++ b/src/buffer/out/AttrRow.hpp @@ -41,6 +41,8 @@ class ATTR_ROW final size_t FindAttrIndex(const size_t index, size_t* const pApplies) const; + std::unordered_set GetHyperlinks(); + bool SetAttrToEnd(const UINT iStart, const TextAttribute attr); void ReplaceAttrs(const TextAttribute& toBeReplacedAttr, const TextAttribute& replaceWith) noexcept; diff --git a/src/buffer/out/TextAttribute.cpp b/src/buffer/out/TextAttribute.cpp index 06c94184432..8053ece1352 100644 --- a/src/buffer/out/TextAttribute.cpp +++ b/src/buffer/out/TextAttribute.cpp @@ -112,6 +112,17 @@ std::pair TextAttribute::CalculateRgbColors(const gsl::span< return { fg, bg }; } +// Method description: +// - Tells us whether the text is a hyperlink or not +// Return value: +// - True if it is a hyperlink, false otherwise +bool TextAttribute::IsHyperlink() const noexcept +{ + // All non-hyperlink text have a default hyperlinkId of 0 while + // all hyperlink text have a non-zero hyperlinkId + return _hyperlinkId != 0; +} + TextColor TextAttribute::GetForeground() const noexcept { return _foreground; @@ -122,6 +133,15 @@ TextColor TextAttribute::GetBackground() const noexcept return _background; } +// Method description: +// - Retrieves the hyperlink ID of the text +// Return value: +// - The hyperlink ID +uint16_t TextAttribute::GetHyperlinkId() const noexcept +{ + return _hyperlinkId; +} + void TextAttribute::SetForeground(const TextColor foreground) noexcept { _foreground = foreground; @@ -174,6 +194,15 @@ void TextAttribute::SetColor(const COLORREF rgbColor, const bool fIsForeground) } } +// Method description: +// - Sets the hyperlink ID of the text +// Arguments: +// - id - the id we wish to set +void TextAttribute::SetHyperlinkId(uint16_t id) noexcept +{ + _hyperlinkId = id; +} + bool TextAttribute::IsLeadingByte() const noexcept { return WI_IsFlagSet(_wAttrLegacy, COMMON_LVB_LEADING_BYTE); @@ -336,6 +365,14 @@ void TextAttribute::SetDefaultBackground() noexcept _background = TextColor(); } +// Method description: +// - Resets only the meta and extended attributes +void TextAttribute::SetDefaultMetaAttrs() noexcept +{ + _extendedAttrs = ExtendedAttributes::Normal; + _wAttrLegacy = 0; +} + // Method Description: // - Returns true if this attribute indicates its background is the "default" // background. Its _rgbBackground will contain the actual value of the @@ -356,6 +393,6 @@ bool TextAttribute::BackgroundIsDefault() const noexcept // requires for most erasing and filling operations. void TextAttribute::SetStandardErase() noexcept { - _extendedAttrs = ExtendedAttributes::Normal; - _wAttrLegacy = 0; + SetDefaultMetaAttrs(); + _hyperlinkId = 0; } diff --git a/src/buffer/out/TextAttribute.hpp b/src/buffer/out/TextAttribute.hpp index 22c61a6aa91..b3d28f443fb 100644 --- a/src/buffer/out/TextAttribute.hpp +++ b/src/buffer/out/TextAttribute.hpp @@ -36,7 +36,8 @@ class TextAttribute final _wAttrLegacy{ 0 }, _foreground{}, _background{}, - _extendedAttrs{ ExtendedAttributes::Normal } + _extendedAttrs{ ExtendedAttributes::Normal }, + _hyperlinkId{ 0 } { } @@ -44,7 +45,8 @@ class TextAttribute final _wAttrLegacy{ gsl::narrow_cast(wLegacyAttr & META_ATTRS) }, _foreground{ s_LegacyIndexOrDefault(wLegacyAttr & FG_ATTRS, s_legacyDefaultForeground) }, _background{ s_LegacyIndexOrDefault((wLegacyAttr & BG_ATTRS) >> 4, s_legacyDefaultBackground) }, - _extendedAttrs{ ExtendedAttributes::Normal } + _extendedAttrs{ ExtendedAttributes::Normal }, + _hyperlinkId{ 0 } { // If we're given lead/trailing byte information with the legacy color, strip it. WI_ClearAllFlags(_wAttrLegacy, COMMON_LVB_SBCSDBCS); @@ -55,7 +57,8 @@ class TextAttribute final _wAttrLegacy{ 0 }, _foreground{ rgbForeground }, _background{ rgbBackground }, - _extendedAttrs{ ExtendedAttributes::Normal } + _extendedAttrs{ ExtendedAttributes::Normal }, + _hyperlinkId{ 0 } { } @@ -112,8 +115,11 @@ class TextAttribute final ExtendedAttributes GetExtendedAttributes() const noexcept; + bool IsHyperlink() const noexcept; + TextColor GetForeground() const noexcept; TextColor GetBackground() const noexcept; + uint16_t GetHyperlinkId() const noexcept; void SetForeground(const TextColor foreground) noexcept; void SetBackground(const TextColor background) noexcept; void SetForeground(const COLORREF rgbForeground) noexcept; @@ -123,9 +129,11 @@ class TextAttribute final void SetIndexedForeground256(const BYTE fgIndex) noexcept; void SetIndexedBackground256(const BYTE bgIndex) noexcept; void SetColor(const COLORREF rgbColor, const bool fIsForeground) noexcept; + void SetHyperlinkId(uint16_t id) noexcept; void SetDefaultForeground() noexcept; void SetDefaultBackground() noexcept; + void SetDefaultMetaAttrs() noexcept; bool BackgroundIsDefault() const noexcept; @@ -147,7 +155,8 @@ class TextAttribute final (_wAttrLegacy & META_ATTRS) == (other._wAttrLegacy & META_ATTRS) && ((checkForeground && _foreground == other._foreground) || (!checkForeground && _background == other._background)) && - _extendedAttrs == other._extendedAttrs; + _extendedAttrs == other._extendedAttrs && + IsHyperlink() == other.IsHyperlink(); } constexpr bool IsAnyGridLineEnabled() const noexcept @@ -169,6 +178,8 @@ class TextAttribute final TextColor _background; ExtendedAttributes _extendedAttrs; + uint16_t _hyperlinkId; + #ifdef UNIT_TESTING friend class TextBufferTests; friend class TextAttributeTests; @@ -182,7 +193,7 @@ class TextAttribute final // 4 for _foreground // 4 for _background // 1 for _extendedAttrs -static_assert(sizeof(TextAttribute) <= 11 * sizeof(BYTE), "We should only need 11B for an entire TextColor. Any more than that is just waste"); +static_assert(sizeof(TextAttribute) <= 13 * sizeof(BYTE), "We should only need 13B for an entire TextAttribute. We may need to increment this in the future as we add additional attributes"); enum class TextAttributeBehavior { @@ -196,7 +207,8 @@ constexpr bool operator==(const TextAttribute& a, const TextAttribute& b) noexce return a._wAttrLegacy == b._wAttrLegacy && a._foreground == b._foreground && a._background == b._background && - a._extendedAttrs == b._extendedAttrs; + a._extendedAttrs == b._extendedAttrs && + a._hyperlinkId == b._hyperlinkId; } constexpr bool operator!=(const TextAttribute& a, const TextAttribute& b) noexcept diff --git a/src/buffer/out/textBuffer.cpp b/src/buffer/out/textBuffer.cpp index 6ecb989f2f0..294813a3f55 100644 --- a/src/buffer/out/textBuffer.cpp +++ b/src/buffer/out/textBuffer.cpp @@ -34,7 +34,8 @@ TextBuffer::TextBuffer(const COORD screenBufferSize, _storage{}, _unicodeStorage{}, _renderTarget{ renderTarget }, - _size{} + _size{}, + _currentHyperlinkId{ 1 } { // initialize ROWs for (size_t i = 0; i < static_cast(screenBufferSize.Y); ++i) @@ -551,7 +552,10 @@ bool TextBuffer::IncrementCircularBuffer(const bool inVtMode) // to the logical position 0 in the window (cursor coordinates and all other coordinates). _renderTarget.TriggerCircling(); - // First, clean out the old "first row" as it will become the "last row" of the buffer after the circle is performed. + // Prune hyperlinks to delete obsolete references + _PruneHyperlinks(); + + // Second, clean out the old "first row" as it will become the "last row" of the buffer after the circle is performed. auto fillAttributes = _currentAttributes; if (inVtMode) { @@ -1185,6 +1189,46 @@ const COORD TextBuffer::_GetWordEndForSelection(const COORD target, const std::w return result; } +void TextBuffer::_PruneHyperlinks() +{ + // Check the old first row for hyperlink references + // If there are any, search the entire buffer for the same reference + // If the buffer does not contain the same reference, we can remove that hyperlink from our map + // This way, obsolete hyperlink references are cleared from our hyperlink map instead of hanging around + // Get all the hyperlink references in the row we're erasing + auto firstRowRefs = _storage.at(_firstRow).GetAttrRow().GetHyperlinks(); + if (!firstRowRefs.empty()) + { + const auto total = TotalRowCount(); + // Loop through all the rows in the buffer except the first row - + // we have found all hyperlink references in the first row and put them in refs, + // now we need to search the rest of the buffer (i.e. all the rows except the first) + // to see if those references are anywhere else + for (size_t i = 1; i != total; ++i) + { + const auto nextRowRefs = GetRowByOffset(i).GetAttrRow().GetHyperlinks(); + for (auto id : nextRowRefs) + { + if (firstRowRefs.find(id) != firstRowRefs.end()) + { + firstRowRefs.erase(id); + } + } + if (firstRowRefs.empty()) + { + // No more hyperlink references left to search for, terminate early + break; + } + } + } + + // Now delete obsolete references from our map + for (auto hyperlinkReference : firstRowRefs) + { + RemoveHyperlinkFromMap(hyperlinkReference); + } +} + // Method Description: // - Update pos to be the position of the first character of the next word. This is used for accessibility // Arguments: @@ -2142,6 +2186,7 @@ HRESULT TextBuffer::Reflow(TextBuffer& oldBuffer, { // Finish copying remaining parameters from the old text buffer to the new one newBuffer.CopyProperties(oldBuffer); + newBuffer.CopyHyperlinkMaps(oldBuffer); // If we found where to put the cursor while placing characters into the buffer, // just put the cursor there. Otherwise we have to advance manually. @@ -2207,3 +2252,104 @@ HRESULT TextBuffer::Reflow(TextBuffer& oldBuffer, return hr; } + +// Method Description: +// - Adds or updates a hyperlink in our hyperlink table +// Arguments: +// - The hyperlink URI, the hyperlink id (could be new or old) +void TextBuffer::AddHyperlinkToMap(std::wstring_view uri, uint16_t id) +{ + _hyperlinkMap[id] = uri; +} + +// Method Description: +// - Retrieves the URI associated with a particular hyperlink ID +// Arguments: +// - The hyperlink ID +// Return Value: +// - The URI +std::wstring TextBuffer::GetHyperlinkUriFromId(uint16_t id) const +{ + return _hyperlinkMap.at(id); +} + +// Method description: +// - Provides the hyperlink ID to be assigned as a text attribute, based on the optional custom id provided +// Arguments: +// - The user-defined id +// Return value: +// - The internal hyperlink ID +uint16_t TextBuffer::GetHyperlinkId(std::wstring_view params) +{ + uint16_t id = 0; + if (params.empty()) + { + // no custom id specified, return our internal count + id = _currentHyperlinkId; + ++_currentHyperlinkId; + } + else + { + // assign _currentHyperlinkId if the custom id does not already exist + const auto result = _hyperlinkCustomIdMap.emplace(params, _currentHyperlinkId); + if (result.second) + { + // the custom id did not already exist + ++_currentHyperlinkId; + } + id = (*(result.first)).second; + } + // _currentHyperlinkId could overflow, make sure its not 0 + if (_currentHyperlinkId == 0) + { + ++_currentHyperlinkId; + } + return id; +} + +// Method Description: +// - Removes a hyperlink from the hyperlink map and the associated +// user defined id from the custom id map (if there is one) +// Arguments: +// - The ID of the hyperlink to be removed +void TextBuffer::RemoveHyperlinkFromMap(uint16_t id) +{ + _hyperlinkMap.erase(id); + for (const auto& customIdPair : _hyperlinkCustomIdMap) + { + if (customIdPair.second == id) + { + _hyperlinkCustomIdMap.erase(customIdPair.first); + break; + } + } +} + +// Method Description: +// - Obtains the custom ID, if there was one, associated with the +// uint16_t id of a hyperlink +// Arguments: +// - The uint16_t id of the hyperlink +// Return Value: +// - The custom ID if there was one, empty string otherwise +std::wstring TextBuffer::GetCustomIdFromId(uint16_t id) const +{ + for (auto customIdPair : _hyperlinkCustomIdMap) + { + if (customIdPair.second == id) + { + return customIdPair.first; + } + } + return {}; +} + +// Method Description: +// - Copies the hyperlink/customID maps of the old buffer into this one +// Arguments: +// - The other buffer +void TextBuffer::CopyHyperlinkMaps(const TextBuffer& other) +{ + _hyperlinkMap = other._hyperlinkMap; + _hyperlinkCustomIdMap = other._hyperlinkCustomIdMap; +} diff --git a/src/buffer/out/textBuffer.hpp b/src/buffer/out/textBuffer.hpp index 9ed2ce8b1af..56a3c59f3b0 100644 --- a/src/buffer/out/textBuffer.hpp +++ b/src/buffer/out/textBuffer.hpp @@ -141,6 +141,13 @@ class TextBuffer final const std::vector GetTextRects(COORD start, COORD end, bool blockSelection = false) const; + void AddHyperlinkToMap(std::wstring_view uri, uint16_t id); + std::wstring GetHyperlinkUriFromId(uint16_t id) const; + uint16_t GetHyperlinkId(std::wstring_view params); + void RemoveHyperlinkFromMap(uint16_t id); + std::wstring GetCustomIdFromId(uint16_t id) const; + void CopyHyperlinkMaps(const TextBuffer& OtherBuffer); + class TextAndColor { public: @@ -188,6 +195,10 @@ class TextBuffer final // storage location for glyphs that can't fit into the buffer normally UnicodeStorage _unicodeStorage; + std::unordered_map _hyperlinkMap; + std::unordered_map _hyperlinkCustomIdMap; + uint16_t _currentHyperlinkId; + void _RefreshRowIDs(std::optional newRowWidth); Microsoft::Console::Render::IRenderTarget& _renderTarget; @@ -216,6 +227,8 @@ class TextBuffer final const COORD _GetWordEndForAccessibility(const COORD target, const std::wstring_view wordDelimiters) const; const COORD _GetWordEndForSelection(const COORD target, const std::wstring_view wordDelimiters) const; + void _PruneHyperlinks(); + #ifdef UNIT_TESTING friend class TextBufferTests; friend class UiaTextRangeTests; diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index 0023ccd285f..ceb86a52481 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -1136,6 +1136,8 @@ namespace winrt::TerminalApp::implementation // Add an event handler when the terminal wants to paste data from the Clipboard. term.PasteFromClipboard({ this, &TerminalPage::_PasteFromClipboardHandler }); + term.OpenHyperlink({ this, &TerminalPage::_OpenHyperlinkHandler }); + // Bind Tab events to the TermControl and the Tab's Pane hostingTab.Initialize(term); @@ -1794,6 +1796,19 @@ namespace winrt::TerminalApp::implementation CATCH_LOG(); } + void TerminalPage::_OpenHyperlinkHandler(const IInspectable /*sender*/, const Microsoft::Terminal::TerminalControl::OpenHyperlinkEventArgs eventArgs) + { + try + { + auto parsed = winrt::Windows::Foundation::Uri(eventArgs.Uri().c_str()); + if (parsed.SchemeName() == L"http" || parsed.SchemeName() == L"https") + { + ShellExecute(nullptr, L"open", eventArgs.Uri().c_str(), nullptr, nullptr, SW_SHOWNORMAL); + } + } + CATCH_LOG(); + } + // Method Description: // - Copy text from the focused terminal to the Windows Clipboard // Arguments: diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h index 00f18a4cc1c..ac68997afae 100644 --- a/src/cascadia/TerminalApp/TerminalPage.h +++ b/src/cascadia/TerminalApp/TerminalPage.h @@ -171,7 +171,10 @@ namespace winrt::TerminalApp::implementation winrt::fire_and_forget _CopyToClipboardHandler(const IInspectable sender, const winrt::Microsoft::Terminal::TerminalControl::CopyToClipboardEventArgs copiedData); winrt::fire_and_forget _PasteFromClipboardHandler(const IInspectable sender, const Microsoft::Terminal::TerminalControl::PasteFromClipboardEventArgs eventArgs); + + void _OpenHyperlinkHandler(const IInspectable sender, const Microsoft::Terminal::TerminalControl::OpenHyperlinkEventArgs eventArgs); bool _CopyText(const bool singleLine, const Windows::Foundation::IReference& formats); + void _PasteText(); fire_and_forget _LaunchSettings(const winrt::TerminalApp::SettingsTarget target); diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index 6c86ac93e36..e1dc47f6554 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -1083,6 +1083,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation // macro directly with a VirtualKeyModifiers const auto altEnabled = WI_IsFlagSet(modifiers, static_cast(VirtualKeyModifiers::Menu)); const auto shiftEnabled = WI_IsFlagSet(modifiers, static_cast(VirtualKeyModifiers::Shift)); + const auto ctrlEnabled = WI_IsFlagSet(modifiers, static_cast(VirtualKeyModifiers::Control)); if (_CanSendVTMouseInput()) { @@ -1123,7 +1124,12 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation } // Update the selection appropriately - if (shiftEnabled && _terminal->IsSelectionActive()) + if (ctrlEnabled && multiClickMapper == 1 && + !(_terminal->GetHyperlinkAtPosition(terminalPosition).empty())) + { + _HyperlinkHandler(_terminal->GetHyperlinkAtPosition(terminalPosition)); + } + else if (shiftEnabled && _terminal->IsSelectionActive()) { // Shift+Click: only set expand on the "end" selection point _terminal->SetSelectionEnd(terminalPosition, mode); @@ -2839,6 +2845,16 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation e.DragUIOverride().IsGlyphVisible(false); } + // Method description: + // - Checks if the uri is valid and sends an event if so + // Arguments: + // - The uri + void TermControl::_HyperlinkHandler(const std::wstring_view uri) + { + auto hyperlinkArgs = winrt::make_self(winrt::hstring{ uri }); + _openHyperlinkHandlers(*this, *hyperlinkArgs); + } + // Method Description: // - Produces the error dialog that notifies the user that rendering cannot proceed. winrt::fire_and_forget TermControl::_RendererEnteredErrorState() @@ -2884,5 +2900,6 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(TermControl, PasteFromClipboard, _clipboardPasteHandlers, TerminalControl::TermControl, TerminalControl::PasteFromClipboardEventArgs); DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(TermControl, CopyToClipboard, _clipboardCopyHandlers, TerminalControl::TermControl, TerminalControl::CopyToClipboardEventArgs); + DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(TermControl, OpenHyperlink, _openHyperlinkHandlers, TerminalControl::TermControl, TerminalControl::OpenHyperlinkEventArgs); // clang-format on } diff --git a/src/cascadia/TerminalControl/TermControl.h b/src/cascadia/TerminalControl/TermControl.h index 2f9de1d7f07..2e3160958b4 100644 --- a/src/cascadia/TerminalControl/TermControl.h +++ b/src/cascadia/TerminalControl/TermControl.h @@ -6,6 +6,7 @@ #include "TermControl.g.h" #include "CopyToClipboardEventArgs.g.h" #include "PasteFromClipboardEventArgs.g.h" +#include "OpenHyperlinkEventArgs.g.h" #include #include "../../renderer/base/Renderer.hpp" #include "../../renderer/dx/DxRenderer.hpp" @@ -67,6 +68,19 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation std::function m_clipboardDataHandler; }; + struct OpenHyperlinkEventArgs : + public OpenHyperlinkEventArgsT + { + public: + OpenHyperlinkEventArgs(hstring uri) : + _uri(uri) {} + + hstring Uri() { return _uri; }; + + private: + hstring _uri; + }; + struct TermControl : TermControlT { TermControl(IControlSettings settings, TerminalConnection::ITerminalConnection connection); @@ -133,6 +147,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(PasteFromClipboard, _clipboardPasteHandlers, TerminalControl::TermControl, TerminalControl::PasteFromClipboardEventArgs); DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(CopyToClipboard, _clipboardCopyHandlers, TerminalControl::TermControl, TerminalControl::CopyToClipboardEventArgs); + DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(OpenHyperlink, _openHyperlinkHandlers, TerminalControl::TermControl, TerminalControl::OpenHyperlinkEventArgs); TYPED_EVENT(ConnectionStateChanged, TerminalControl::TermControl, IInspectable); TYPED_EVENT(Initialized, TerminalControl::TermControl, Windows::UI::Xaml::RoutedEventArgs); @@ -228,6 +243,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation void _LostFocusHandler(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& e); winrt::fire_and_forget _DragDropHandler(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::DragEventArgs const e); void _DragOverHandler(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::DragEventArgs const& e); + void _HyperlinkHandler(const std::wstring_view uri); void _CursorTimerTick(Windows::Foundation::IInspectable const& sender, Windows::Foundation::IInspectable const& e); void _SetEndSelectionPointAtCursor(Windows::Foundation::Point const& cursorPosition); diff --git a/src/cascadia/TerminalControl/TermControl.idl b/src/cascadia/TerminalControl/TermControl.idl index e7f9c958802..8c570838b82 100644 --- a/src/cascadia/TerminalControl/TermControl.idl +++ b/src/cascadia/TerminalControl/TermControl.idl @@ -40,6 +40,11 @@ namespace Microsoft.Terminal.TerminalControl void HandleClipboardData(String data); } + runtimeclass OpenHyperlinkEventArgs + { + String Uri { get; }; + } + [default_interface] runtimeclass TermControl : Windows.UI.Xaml.Controls.UserControl, IDirectKeyListener, IMouseWheelListener { TermControl(Microsoft.Terminal.TerminalControl.IControlSettings settings, Microsoft.Terminal.TerminalConnection.ITerminalConnection connection); @@ -54,6 +59,7 @@ namespace Microsoft.Terminal.TerminalControl event FontSizeChangedEventArgs FontSizeChanged; event Windows.Foundation.TypedEventHandler CopyToClipboard; event Windows.Foundation.TypedEventHandler PasteFromClipboard; + event Windows.Foundation.TypedEventHandler OpenHyperlink; event Windows.Foundation.TypedEventHandler Initialized; // This is an event handler forwarder for the underlying connection. diff --git a/src/cascadia/TerminalCore/ITerminalApi.hpp b/src/cascadia/TerminalCore/ITerminalApi.hpp index 98945de1cfe..9661a2db51d 100644 --- a/src/cascadia/TerminalCore/ITerminalApi.hpp +++ b/src/cascadia/TerminalCore/ITerminalApi.hpp @@ -59,6 +59,9 @@ namespace Microsoft::Terminal::Core virtual bool CopyToClipboard(std::wstring_view content) noexcept = 0; + virtual bool AddHyperlink(std::wstring_view uri, std::wstring_view params) noexcept = 0; + virtual bool EndHyperlink() noexcept = 0; + protected: ITerminalApi() = default; }; diff --git a/src/cascadia/TerminalCore/Terminal.cpp b/src/cascadia/TerminalCore/Terminal.cpp index 55d238d401b..03afa6c0084 100644 --- a/src/cascadia/TerminalCore/Terminal.cpp +++ b/src/cascadia/TerminalCore/Terminal.cpp @@ -406,6 +406,21 @@ bool Terminal::IsTrackingMouseInput() const noexcept return _terminalInput->IsTrackingMouseInput(); } +// Method Description: +// - If the clicked text is a hyperlink, open it +// Arguments: +// - The position of the clicked text +std::wstring Terminal::GetHyperlinkAtPosition(const COORD position) +{ + auto attr = _buffer->GetCellDataAt(_ConvertToBufferCell(position))->TextAttr(); + if (attr.IsHyperlink()) + { + auto uri = _buffer->GetHyperlinkUriFromId(attr.GetHyperlinkId()); + return uri; + } + return {}; +} + // Method Description: // - Send this particular (non-character) key event to the terminal. // - The terminal will translate the key and the modifiers pressed into the diff --git a/src/cascadia/TerminalCore/Terminal.hpp b/src/cascadia/TerminalCore/Terminal.hpp index df70bc0184c..6b0eea1eba4 100644 --- a/src/cascadia/TerminalCore/Terminal.hpp +++ b/src/cascadia/TerminalCore/Terminal.hpp @@ -111,6 +111,9 @@ class Microsoft::Terminal::Core::Terminal final : bool IsVtInputEnabled() const noexcept override; bool CopyToClipboard(std::wstring_view content) noexcept override; + + bool AddHyperlink(std::wstring_view uri, std::wstring_view params) noexcept override; + bool EndHyperlink() noexcept override; #pragma endregion #pragma region ITerminalInput @@ -125,6 +128,8 @@ class Microsoft::Terminal::Core::Terminal final : void TrySnapOnInput() override; bool IsTrackingMouseInput() const noexcept; + + std::wstring GetHyperlinkAtPosition(const COORD position); #pragma endregion #pragma region IBaseData(base to IRenderData and IUiaData) @@ -152,6 +157,8 @@ class Microsoft::Terminal::Core::Terminal final : bool IsScreenReversed() const noexcept override; const std::vector GetOverlays() const noexcept override; const bool IsGridLineDrawingAllowed() noexcept override; + const std::wstring GetHyperlinkUri(uint16_t id) const noexcept override; + const std::wstring GetHyperlinkCustomId(uint16_t id) const noexcept override; #pragma endregion #pragma region IUiaData diff --git a/src/cascadia/TerminalCore/TerminalApi.cpp b/src/cascadia/TerminalCore/TerminalApi.cpp index 1e27a59702c..92149471f69 100644 --- a/src/cascadia/TerminalCore/TerminalApi.cpp +++ b/src/cascadia/TerminalCore/TerminalApi.cpp @@ -560,3 +560,32 @@ try return true; } CATCH_LOG_RETURN_FALSE() + +// Method Description: +// - Updates the buffer's current text attributes to start a hyperlink +// Arguments: +// - The hyperlink URI +// - The customID provided (if there was one) +// Return Value: +// - true +bool Terminal::AddHyperlink(std::wstring_view uri, std::wstring_view params) noexcept +{ + auto attr = _buffer->GetCurrentAttributes(); + const auto id = _buffer->GetHyperlinkId(params); + attr.SetHyperlinkId(id); + _buffer->SetCurrentAttributes(attr); + _buffer->AddHyperlinkToMap(uri, id); + return true; +} + +// Method Description: +// - Updates the buffer's current text attributes to end a hyperlink +// Return Value: +// - true +bool Terminal::EndHyperlink() noexcept +{ + auto attr = _buffer->GetCurrentAttributes(); + attr.SetHyperlinkId(0); + _buffer->SetCurrentAttributes(attr); + return true; +} diff --git a/src/cascadia/TerminalCore/TerminalDispatch.cpp b/src/cascadia/TerminalCore/TerminalDispatch.cpp index f119cc266c7..06874b38889 100644 --- a/src/cascadia/TerminalCore/TerminalDispatch.cpp +++ b/src/cascadia/TerminalCore/TerminalDispatch.cpp @@ -371,6 +371,27 @@ bool TerminalDispatch::ResetPrivateModes(const gsl::span /*params*/) noexcept override; // DECSET bool ResetPrivateModes(const gsl::span /*params*/) noexcept override; // DECRST + bool AddHyperlink(const std::wstring_view uri, const std::wstring_view params) noexcept override; + bool EndHyperlink() noexcept override; + private: ::Microsoft::Terminal::Core::ITerminalApi& _terminalApi; diff --git a/src/cascadia/TerminalCore/TerminalDispatchGraphics.cpp b/src/cascadia/TerminalCore/TerminalDispatchGraphics.cpp index 635d9bded26..bbc0984296b 100644 --- a/src/cascadia/TerminalCore/TerminalDispatchGraphics.cpp +++ b/src/cascadia/TerminalCore/TerminalDispatchGraphics.cpp @@ -107,7 +107,7 @@ bool TerminalDispatch::SetGraphicsRendition(const gsl::spanGetHyperlinkUriFromId(id); +} + +const std::wstring Microsoft::Terminal::Core::Terminal::GetHyperlinkCustomId(uint16_t id) const noexcept +{ + return _buffer->GetCustomIdFromId(id); +} + std::vector Terminal::GetSelectionRects() noexcept try { diff --git a/src/cascadia/UnitTests_TerminalCore/ConptyRoundtripTests.cpp b/src/cascadia/UnitTests_TerminalCore/ConptyRoundtripTests.cpp index a68aa213db1..204e2fb93e6 100644 --- a/src/cascadia/UnitTests_TerminalCore/ConptyRoundtripTests.cpp +++ b/src/cascadia/UnitTests_TerminalCore/ConptyRoundtripTests.cpp @@ -214,6 +214,8 @@ class TerminalCoreUnitTests::ConptyRoundtripTests final TEST_METHOD(DeleteWrappedWord); + TEST_METHOD(HyperlinkIdConsistency); + private: bool _writeCallback(const char* const pch, size_t const cch); void _flushFirstFrame(); @@ -3471,3 +3473,70 @@ void ConptyRoundtripTests::DeleteWrappedWord() Log::Comment(L"========== Checking the terminal buffer state (after) =========="); verifyBuffer(*termTb, term->_mutableViewport.ToInclusive(), true); } + +// This test checks that upon conpty rendering again, terminal still maintains +// the same hyperlink IDs +void ConptyRoundtripTests::HyperlinkIdConsistency() +{ + Log::Comment(NoThrowString().Format( + L"Write a link - the text will simply be 'Link' and the uri will be 'http://example.com'")); + + auto& g = ServiceLocator::LocateGlobals(); + auto& renderer = *g.pRender; + auto& gci = g.getConsoleInformation(); + auto& si = gci.GetActiveOutputBuffer(); + auto& hostSm = si.GetStateMachine(); + auto& hostTb = si.GetTextBuffer(); + auto& termTb = *term->_buffer; + + _flushFirstFrame(); + + hostSm.ProcessString(L"\x1b]8;;http://example.com\x1b/Link\x1b]8;;\x1b/"); + + // For self-generated IDs, conpty will send a custom ID of the form + // {sessionID}-{self-generated ID} + // self-generated IDs begin at 1 and increment from there + const std::string fmt{ "\x1b]8;id={}-1;http://example.com\x1b\\" }; + auto s = fmt::format(fmt, GetCurrentProcessId()); + expectedOutput.push_back(s); + expectedOutput.push_back("Link"); + expectedOutput.push_back("\x1b]8;;\x1b\\"); + + // Force a frame + VERIFY_SUCCEEDED(renderer.PaintFrame()); + + // Move the cursor down + hostSm.ProcessString(L"\x1b[2;1H"); + expectedOutput.push_back("\r\n"); + + // Force a frame + VERIFY_SUCCEEDED(renderer.PaintFrame()); + + // Move the cursor to somewhere in the link text + hostSm.ProcessString(L"\x1b[1;2H"); + expectedOutput.push_back("\x1b[1;2H"); + expectedOutput.push_back("\x1b[?25h"); + + // Force a frame + VERIFY_SUCCEEDED(renderer.PaintFrame()); + + // Move the cursor off the link + hostSm.ProcessString(L"\x1b[2;1H"); + expectedOutput.push_back("\r\n"); + + // Force a frame + VERIFY_SUCCEEDED(renderer.PaintFrame()); + + auto verifyData = [](TextBuffer& tb) { + // Check that all the linked cells still have the same ID + auto attrRow = tb.GetRowByOffset(0).GetAttrRow(); + auto id = attrRow.GetAttrByColumn(0).GetHyperlinkId(); + for (auto i = 1; i < 4; ++i) + { + VERIFY_ARE_EQUAL(id, attrRow.GetAttrByColumn(i).GetHyperlinkId()); + } + }; + + verifyData(hostTb); + verifyData(termTb); +} diff --git a/src/cascadia/UnitTests_TerminalCore/TerminalApiTest.cpp b/src/cascadia/UnitTests_TerminalCore/TerminalApiTest.cpp index c3c4d1bcdd9..fc3db8a8164 100644 --- a/src/cascadia/UnitTests_TerminalCore/TerminalApiTest.cpp +++ b/src/cascadia/UnitTests_TerminalCore/TerminalApiTest.cpp @@ -34,6 +34,9 @@ namespace TerminalCoreUnitTests // PrintString() is called with more code units than the buffer width. TEST_METHOD(PrintStringOfSurrogatePairs); TEST_METHOD(CheckDoubleWidthCursor); + + TEST_METHOD(AddHyperlink); + TEST_METHOD(AddHyperlinkCustomId); }; }; @@ -251,3 +254,57 @@ void TerminalApiTest::CheckDoubleWidthCursor() term.SetCursorPosition(1, 1); VERIFY_IS_TRUE(term.IsCursorDoubleWidth()); } + +void TerminalCoreUnitTests::TerminalApiTest::AddHyperlink() +{ + // This is a nearly literal copy-paste of ScreenBufferTests::TestAddHyperlink, adapted for the Terminal + + Terminal term; + DummyRenderTarget emptyRT; + term.Create({ 100, 100 }, 0, emptyRT); + + auto& tbi = *(term._buffer); + auto& stateMachine = *(term._stateMachine); + + // Process the opening osc 8 sequence + stateMachine.ProcessString(L"\x1b]8;;test.url\x9c"); + VERIFY_IS_TRUE(tbi.GetCurrentAttributes().IsHyperlink()); + VERIFY_ARE_EQUAL(tbi.GetHyperlinkUriFromId(tbi.GetCurrentAttributes().GetHyperlinkId()), L"test.url"); + + // Send any other text + stateMachine.ProcessString(L"Hello World"); + VERIFY_IS_TRUE(tbi.GetCurrentAttributes().IsHyperlink()); + VERIFY_ARE_EQUAL(tbi.GetHyperlinkUriFromId(tbi.GetCurrentAttributes().GetHyperlinkId()), L"test.url"); + + // Process the closing osc 8 sequences + stateMachine.ProcessString(L"\x1b]8;;\x9c"); + VERIFY_IS_FALSE(tbi.GetCurrentAttributes().IsHyperlink()); +} + +void TerminalCoreUnitTests::TerminalApiTest::AddHyperlinkCustomId() +{ + // This is a nearly literal copy-paste of ScreenBufferTests::TestAddHyperlinkCustomId, adapted for the Terminal + + Terminal term; + DummyRenderTarget emptyRT; + term.Create({ 100, 100 }, 0, emptyRT); + + auto& tbi = *(term._buffer); + auto& stateMachine = *(term._stateMachine); + + // Process the opening osc 8 sequence + stateMachine.ProcessString(L"\x1b]8;id=myId;test.url\x9c"); + VERIFY_IS_TRUE(tbi.GetCurrentAttributes().IsHyperlink()); + VERIFY_ARE_EQUAL(tbi.GetHyperlinkUriFromId(tbi.GetCurrentAttributes().GetHyperlinkId()), L"test.url"); + VERIFY_ARE_EQUAL(tbi.GetHyperlinkId(L"myId"), tbi.GetCurrentAttributes().GetHyperlinkId()); + + // Send any other text + stateMachine.ProcessString(L"Hello World"); + VERIFY_IS_TRUE(tbi.GetCurrentAttributes().IsHyperlink()); + VERIFY_ARE_EQUAL(tbi.GetHyperlinkUriFromId(tbi.GetCurrentAttributes().GetHyperlinkId()), L"test.url"); + VERIFY_ARE_EQUAL(tbi.GetHyperlinkId(L"myId"), tbi.GetCurrentAttributes().GetHyperlinkId()); + + // Process the closing osc 8 sequences + stateMachine.ProcessString(L"\x1b]8;;\x9c"); + VERIFY_IS_FALSE(tbi.GetCurrentAttributes().IsHyperlink()); +} diff --git a/src/host/getset.cpp b/src/host/getset.cpp index 9c2d0e26494..b7c8e254a0e 100644 --- a/src/host/getset.cpp +++ b/src/host/getset.cpp @@ -1562,6 +1562,24 @@ void DoSrvSetCursorColor(SCREEN_INFORMATION& screenInfo, screenInfo.GetActiveBuffer().GetTextBuffer().GetCursor().SetColor(cursorColor); } +void DoSrvAddHyperlink(SCREEN_INFORMATION& screenInfo, + const std::wstring_view uri, + const std::wstring_view params) +{ + auto attr = screenInfo.GetAttributes(); + const auto id = screenInfo.GetTextBuffer().GetHyperlinkId(params); + attr.SetHyperlinkId(id); + screenInfo.GetTextBuffer().SetCurrentAttributes(attr); + screenInfo.GetTextBuffer().AddHyperlinkToMap(uri, id); +} + +void DoSrvEndHyperlink(SCREEN_INFORMATION& screenInfo) +{ + auto attr = screenInfo.GetAttributes(); + attr.SetHyperlinkId(0); + screenInfo.GetTextBuffer().SetCurrentAttributes(attr); +} + // Routine Description: // - A private API call for forcing the renderer to repaint the screen. If the // input screen buffer is not the active one, then just do nothing. We only diff --git a/src/host/getset.h b/src/host/getset.h index e6d43474a72..43b8d5fefe5 100644 --- a/src/host/getset.h +++ b/src/host/getset.h @@ -49,6 +49,12 @@ void DoSrvSetCursorStyle(SCREEN_INFORMATION& screenInfo, void DoSrvSetCursorColor(SCREEN_INFORMATION& screenInfo, const COLORREF cursorColor); +void DoSrvAddHyperlink(SCREEN_INFORMATION& screenInfo, + const std::wstring_view uri, + const std::wstring_view params); + +void DoSrvEndHyperlink(SCREEN_INFORMATION& screenInfo); + void DoSrvPrivateRefreshWindow(const SCREEN_INFORMATION& screenInfo); [[nodiscard]] HRESULT DoSrvSetConsoleOutputCodePage(const unsigned int codepage); diff --git a/src/host/outputStream.cpp b/src/host/outputStream.cpp index a4aa4c57de2..d98a40b2a67 100644 --- a/src/host/outputStream.cpp +++ b/src/host/outputStream.cpp @@ -770,3 +770,22 @@ bool ConhostInternalGetSet::PrivateIsVtInputEnabled() const { return _io.GetActiveInputBuffer()->IsInVirtualTerminalInputMode(); } + +// Method Description: +// - Updates the buffer's current text attributes depending on whether we are +// starting/ending a hyperlink +// Arguments: +// - The hyperlink URI +// Return Value: +// - true +bool ConhostInternalGetSet::PrivateAddHyperlink(const std::wstring_view uri, const std::wstring_view params) const +{ + DoSrvAddHyperlink(_io.GetActiveOutputBuffer(), uri, params); + return true; +} + +bool ConhostInternalGetSet::PrivateEndHyperlink() const +{ + DoSrvEndHyperlink(_io.GetActiveOutputBuffer()); + return true; +} diff --git a/src/host/outputStream.hpp b/src/host/outputStream.hpp index a2671396583..8e3274f16cc 100644 --- a/src/host/outputStream.hpp +++ b/src/host/outputStream.hpp @@ -145,6 +145,9 @@ class ConhostInternalGetSet final : public Microsoft::Console::VirtualTerminal:: bool PrivateIsVtInputEnabled() const override; + bool PrivateAddHyperlink(const std::wstring_view uri, const std::wstring_view params) const override; + bool PrivateEndHyperlink() const override; + private: Microsoft::Console::IIoProvider& _io; }; diff --git a/src/host/renderData.cpp b/src/host/renderData.cpp index b8397cbbb00..33ae6fa3485 100644 --- a/src/host/renderData.cpp +++ b/src/host/renderData.cpp @@ -324,6 +324,30 @@ const std::wstring RenderData::GetConsoleTitle() const noexcept return gci.GetTitleAndPrefix(); } +// Method Description: +// - Get the hyperlink URI associated with a hyperlink ID +// Arguments: +// - The hyperlink ID +// Return Value: +// - The URI +const std::wstring RenderData::GetHyperlinkUri(uint16_t id) const noexcept +{ + const CONSOLE_INFORMATION& gci = ServiceLocator::LocateGlobals().getConsoleInformation(); + return gci.GetActiveOutputBuffer().GetTextBuffer().GetHyperlinkUriFromId(id); +} + +// Method Description: +// - Get the custom ID associated with a hyperlink ID +// Arguments: +// - The hyperlink ID +// Return Value: +// - The custom ID if there was one, empty string otherwise +const std::wstring RenderData::GetHyperlinkCustomId(uint16_t id) const noexcept +{ + const CONSOLE_INFORMATION& gci = ServiceLocator::LocateGlobals().getConsoleInformation(); + return gci.GetActiveOutputBuffer().GetTextBuffer().GetCustomIdFromId(id); +} + // Routine Description: // - Converts a text attribute into the RGB values that should be presented, applying // relevant table translation information and preferences. diff --git a/src/host/renderData.hpp b/src/host/renderData.hpp index 4b2bf2e3b58..2e8fa68790c 100644 --- a/src/host/renderData.hpp +++ b/src/host/renderData.hpp @@ -55,6 +55,9 @@ class RenderData final : const bool IsGridLineDrawingAllowed() noexcept override; const std::wstring GetConsoleTitle() const noexcept override; + + const std::wstring GetHyperlinkUri(uint16_t id) const noexcept override; + const std::wstring GetHyperlinkCustomId(uint16_t id) const noexcept override; #pragma endregion #pragma region IUiaData diff --git a/src/host/ut_host/ScreenBufferTests.cpp b/src/host/ut_host/ScreenBufferTests.cpp index 0b5453877b5..1e559505914 100644 --- a/src/host/ut_host/ScreenBufferTests.cpp +++ b/src/host/ut_host/ScreenBufferTests.cpp @@ -211,6 +211,9 @@ class ScreenBufferTests TEST_METHOD(TestCursorIsOn); + TEST_METHOD(TestAddHyperlink); + TEST_METHOD(TestAddHyperlinkCustomId); + TEST_METHOD(UpdateVirtualBottomWhenCursorMovesBelowIt); TEST_METHOD(TestWriteConsoleVTQuirkMode); @@ -5918,6 +5921,54 @@ void ScreenBufferTests::TestCursorIsOn() VERIFY_IS_FALSE(cursor.IsVisible()); } +void ScreenBufferTests::TestAddHyperlink() +{ + auto& g = ServiceLocator::LocateGlobals(); + auto& gci = g.getConsoleInformation(); + auto& si = gci.GetActiveOutputBuffer(); + auto& tbi = si.GetTextBuffer(); + auto& stateMachine = si.GetStateMachine(); + + // Process the opening osc 8 sequence with no custom id + stateMachine.ProcessString(L"\x1b]8;;test.url\x9c"); + VERIFY_IS_TRUE(tbi.GetCurrentAttributes().IsHyperlink()); + VERIFY_ARE_EQUAL(tbi.GetHyperlinkUriFromId(tbi.GetCurrentAttributes().GetHyperlinkId()), L"test.url"); + + // Send any other text + stateMachine.ProcessString(L"Hello World"); + VERIFY_IS_TRUE(tbi.GetCurrentAttributes().IsHyperlink()); + VERIFY_ARE_EQUAL(tbi.GetHyperlinkUriFromId(tbi.GetCurrentAttributes().GetHyperlinkId()), L"test.url"); + + // Process the closing osc 8 sequences + stateMachine.ProcessString(L"\x1b]8;;\x9c"); + VERIFY_IS_FALSE(tbi.GetCurrentAttributes().IsHyperlink()); +} + +void ScreenBufferTests::TestAddHyperlinkCustomId() +{ + auto& g = ServiceLocator::LocateGlobals(); + auto& gci = g.getConsoleInformation(); + auto& si = gci.GetActiveOutputBuffer(); + auto& tbi = si.GetTextBuffer(); + auto& stateMachine = si.GetStateMachine(); + + // Process the opening osc 8 sequence with a custom id + stateMachine.ProcessString(L"\x1b]8;id=myId;test.url\x9c"); + VERIFY_IS_TRUE(tbi.GetCurrentAttributes().IsHyperlink()); + VERIFY_ARE_EQUAL(tbi.GetHyperlinkUriFromId(tbi.GetCurrentAttributes().GetHyperlinkId()), L"test.url"); + VERIFY_ARE_EQUAL(tbi.GetHyperlinkId(L"myId"), tbi.GetCurrentAttributes().GetHyperlinkId()); + + // Send any other text + stateMachine.ProcessString(L"Hello World"); + VERIFY_IS_TRUE(tbi.GetCurrentAttributes().IsHyperlink()); + VERIFY_ARE_EQUAL(tbi.GetHyperlinkUriFromId(tbi.GetCurrentAttributes().GetHyperlinkId()), L"test.url"); + VERIFY_ARE_EQUAL(tbi.GetHyperlinkId(L"myId"), tbi.GetCurrentAttributes().GetHyperlinkId()); + + // Process the closing osc 8 sequences + stateMachine.ProcessString(L"\x1b]8;;\x9c"); + VERIFY_IS_FALSE(tbi.GetCurrentAttributes().IsHyperlink()); +} + void ScreenBufferTests::UpdateVirtualBottomWhenCursorMovesBelowIt() { auto& g = ServiceLocator::LocateGlobals(); diff --git a/src/host/ut_host/TextBufferTests.cpp b/src/host/ut_host/TextBufferTests.cpp index 6f4351b6c26..1ee79447b08 100644 --- a/src/host/ut_host/TextBufferTests.cpp +++ b/src/host/ut_host/TextBufferTests.cpp @@ -152,6 +152,9 @@ class TextBufferTests TEST_METHOD(GetTextRects); TEST_METHOD(GetText); + + TEST_METHOD(HyperlinkTrim); + TEST_METHOD(NoHyperlinkTrim); }; void TextBufferTests::TestBufferCreate() @@ -2443,3 +2446,79 @@ void TextBufferTests::GetText() VERIFY_ARE_EQUAL(expectedText, result); } } + +// This tests that when we increment the circular buffer, obsolete hyperlink references +// are removed from the hyperlink map +void TextBufferTests::HyperlinkTrim() +{ + // Set up a text buffer for us + const COORD bufferSize{ 80, 10 }; + const UINT cursorSize = 12; + const TextAttribute attr{ 0x7f }; + auto _buffer = std::make_unique(bufferSize, attr, cursorSize, _renderTarget); + + const auto url = L"test.url"; + const auto otherUrl = L"other.url"; + const auto customId = L"CustomId"; + const auto otherCustomId = L"OtherCustomId"; + + // Set a hyperlink id in the first row and add a hyperlink to our map + const COORD pos{ 70, 0 }; + const auto id = _buffer->GetHyperlinkId(customId); + TextAttribute newAttr{ 0x7f }; + newAttr.SetHyperlinkId(id); + _buffer->GetRowByOffset(pos.Y).GetAttrRow().SetAttrToEnd(pos.X, newAttr); + _buffer->AddHyperlinkToMap(url, id); + + // Set a different hyperlink id somewhere else in the buffer + const COORD otherPos{ 70, 5 }; + const auto otherId = _buffer->GetHyperlinkId(otherCustomId); + newAttr.SetHyperlinkId(otherId); + _buffer->GetRowByOffset(otherPos.Y).GetAttrRow().SetAttrToEnd(otherPos.X, newAttr); + _buffer->AddHyperlinkToMap(otherUrl, otherId); + + // Increment the circular buffer + _buffer->IncrementCircularBuffer(); + + // The hyperlink reference that was only in the first row should be deleted from the map + VERIFY_ARE_EQUAL(_buffer->_hyperlinkMap.find(id), _buffer->_hyperlinkMap.end()); + // Since there was a custom id, that should be deleted as well + VERIFY_ARE_EQUAL(_buffer->_hyperlinkCustomIdMap.find(customId), _buffer->_hyperlinkCustomIdMap.end()); + + // The other hyperlink reference should not be deleted + VERIFY_ARE_EQUAL(_buffer->_hyperlinkMap[otherId], otherUrl); + VERIFY_ARE_EQUAL(_buffer->_hyperlinkCustomIdMap[otherCustomId], otherId); +} + +// This tests that when we increment the circular buffer, non-obsolete hyperlink references +// do not get removed from the hyperlink map +void TextBufferTests::NoHyperlinkTrim() +{ + // Set up a text buffer for us + const COORD bufferSize{ 80, 10 }; + const UINT cursorSize = 12; + const TextAttribute attr{ 0x7f }; + auto _buffer = std::make_unique(bufferSize, attr, cursorSize, _renderTarget); + + const auto url = L"test.url"; + const auto customId = L"CustomId"; + + // Set a hyperlink id in the first row and add a hyperlink to our map + const COORD pos{ 70, 0 }; + const auto id = _buffer->GetHyperlinkId(customId); + TextAttribute newAttr{ 0x7f }; + newAttr.SetHyperlinkId(id); + _buffer->GetRowByOffset(pos.Y).GetAttrRow().SetAttrToEnd(pos.X, newAttr); + _buffer->AddHyperlinkToMap(url, id); + + // Set the same hyperlink id somewhere else in the buffer + const COORD otherPos{ 70, 5 }; + _buffer->GetRowByOffset(otherPos.Y).GetAttrRow().SetAttrToEnd(otherPos.X, newAttr); + + // Increment the circular buffer + _buffer->IncrementCircularBuffer(); + + // The hyperlink reference should not be deleted from the map since it is still present in the buffer + VERIFY_ARE_EQUAL(_buffer->GetHyperlinkUriFromId(id), url); + VERIFY_ARE_EQUAL(_buffer->_hyperlinkCustomIdMap[customId], id); +} diff --git a/src/host/ut_host/VtIoTests.cpp b/src/host/ut_host/VtIoTests.cpp index 599a29caec4..0e20bbcb3f5 100644 --- a/src/host/ut_host/VtIoTests.cpp +++ b/src/host/ut_host/VtIoTests.cpp @@ -391,6 +391,16 @@ class MockRenderData : public IRenderData, IUiaData void ColorSelection(const COORD /*coordSelectionStart*/, const COORD /*coordSelectionEnd*/, const TextAttribute /*attr*/) { } + + const std::wstring GetHyperlinkUri(uint16_t /*id*/) const noexcept + { + return {}; + } + + const std::wstring GetHyperlinkCustomId(uint16_t /*id*/) const noexcept + { + return {}; + } }; void VtIoTests::RendererDtorAndThread() diff --git a/src/renderer/inc/IRenderData.hpp b/src/renderer/inc/IRenderData.hpp index 5e0f1c77d8a..11b347e657e 100644 --- a/src/renderer/inc/IRenderData.hpp +++ b/src/renderer/inc/IRenderData.hpp @@ -66,6 +66,9 @@ namespace Microsoft::Console::Render virtual const bool IsGridLineDrawingAllowed() noexcept = 0; virtual const std::wstring GetConsoleTitle() const noexcept = 0; + virtual const std::wstring GetHyperlinkUri(uint16_t id) const noexcept = 0; + virtual const std::wstring GetHyperlinkCustomId(uint16_t id) const noexcept = 0; + protected: IRenderData() = default; }; diff --git a/src/renderer/vt/VtSequences.cpp b/src/renderer/vt/VtSequences.cpp index c67093280d7..b1ae2870bec 100644 --- a/src/renderer/vt/VtSequences.cpp +++ b/src/renderer/vt/VtSequences.cpp @@ -456,3 +456,46 @@ using namespace Microsoft::Console::Render; { return _Write("\x1b[?9001h"); } + +// Method Description: +// - Formats and writes a sequence to add a hyperlink to the terminal buffer +// Arguments: +// - The hyperlink URI +// Return Value: +// - S_OK if we succeeded, else an appropriate HRESULT for failing to allocate or write. +[[nodiscard]] HRESULT VtEngine::_SetHyperlink(const std::wstring_view& uri, const std::wstring_view& customId, const uint16_t& numberId) noexcept +{ + // Opening OSC8 sequence + if (customId.empty()) + { + // This is the case of auto-assigned IDs: + // send the auto-assigned ID, prefixed with the PID of this session + // (we do this so different conpty sessions do not overwrite each other's hyperlinks) + const auto sessionID = GetCurrentProcessId(); + const std::string fmt{ "\x1b]8;id={}-{};{}\x1b\\" }; + const std::string uri_str{ til::u16u8(uri) }; + auto s = fmt::format(fmt, sessionID, numberId, uri_str); + return _Write(s); + } + else + { + // This is the case of user-defined IDs: + // send the user-defined ID, prefixed with a "u" + // (we do this so no application can accidentally override a user defined ID) + const std::string fmt{ "\x1b]8;id=u-{};{}\x1b\\" }; + const std::string uri_str{ til::u16u8(uri) }; + const std::string customId_str{ til::u16u8(customId) }; + auto s = fmt::format(fmt, customId_str, uri_str); + return _Write(s); + } +} + +// Method Description: +// - Formats and writes a sequence to end a hyperlink to the terminal buffer +// Return Value: +// - S_OK if we succeeded, else an appropriate HRESULT for failing to allocate or write. +[[nodiscard]] HRESULT VtEngine::_EndHyperlink() noexcept +{ + // Closing OSC8 sequence + return _Write("\x1b]8;;\x1b\\"); +} diff --git a/src/renderer/vt/Xterm256Engine.cpp b/src/renderer/vt/Xterm256Engine.cpp index 0dee6be535e..91e220c33f2 100644 --- a/src/renderer/vt/Xterm256Engine.cpp +++ b/src/renderer/vt/Xterm256Engine.cpp @@ -25,10 +25,13 @@ Xterm256Engine::Xterm256Engine(_In_ wil::unique_hfile hPipe, // Return Value: // - S_OK if we succeeded, else an appropriate HRESULT for failing to allocate or write. [[nodiscard]] HRESULT Xterm256Engine::UpdateDrawingBrushes(const TextAttribute& textAttributes, - const gsl::not_null /*pData*/, + const gsl::not_null pData, const bool /*isSettingDefaultBrushes*/) noexcept { RETURN_IF_FAILED(VtEngine::_RgbUpdateDrawingBrushes(textAttributes)); + + RETURN_IF_FAILED(_UpdateHyperlinkAttr(textAttributes, pData)); + // Only do extended attributes in xterm-256color, as to not break telnet.exe. return _UpdateExtendedAttrs(textAttributes); } @@ -128,6 +131,34 @@ Xterm256Engine::Xterm256Engine(_In_ wil::unique_hfile hPipe, return S_OK; } +// Routine Description: +// - Write a VT sequence to start/stop a hyperlink +// Arguments: +// - textAttributes - Text attributes to use for the hyperlink ID +// - pData - The interface to console data structures required for rendering +// Return Value: +// - S_OK if we succeeded, else an appropriate HRESULT for failing to allocate or write. +HRESULT Microsoft::Console::Render::Xterm256Engine::_UpdateHyperlinkAttr(const TextAttribute& textAttributes, + const gsl::not_null pData) noexcept +{ + if (textAttributes.GetHyperlinkId() != _lastTextAttributes.GetHyperlinkId()) + { + if (textAttributes.IsHyperlink()) + { + const auto id = textAttributes.GetHyperlinkId(); + const auto customId = pData->GetHyperlinkCustomId(id); + RETURN_IF_FAILED(_SetHyperlink(pData->GetHyperlinkUri(id), customId, id)); + } + else + { + RETURN_IF_FAILED(_EndHyperlink()); + } + _lastTextAttributes.SetHyperlinkId(textAttributes.GetHyperlinkId()); + } + + return S_OK; +} + // Method Description: // - Manually emit a "Erase Scrollback" sequence to the connected terminal. We // need to do this in certain cases that we've identified where we believe the diff --git a/src/renderer/vt/Xterm256Engine.hpp b/src/renderer/vt/Xterm256Engine.hpp index fe07065e024..b1ed02332eb 100644 --- a/src/renderer/vt/Xterm256Engine.hpp +++ b/src/renderer/vt/Xterm256Engine.hpp @@ -36,6 +36,8 @@ namespace Microsoft::Console::Render private: [[nodiscard]] HRESULT _UpdateExtendedAttrs(const TextAttribute& textAttributes) noexcept; + [[nodiscard]] HRESULT _UpdateHyperlinkAttr(const TextAttribute& textAttributes, + const gsl::not_null pData) noexcept; #ifdef UNIT_TESTING friend class VtRendererTest; diff --git a/src/renderer/vt/vtrenderer.hpp b/src/renderer/vt/vtrenderer.hpp index 084592be0a6..887e1ce8b70 100644 --- a/src/renderer/vt/vtrenderer.hpp +++ b/src/renderer/vt/vtrenderer.hpp @@ -195,6 +195,8 @@ namespace Microsoft::Console::Render [[nodiscard]] HRESULT _SetInvisible(const bool isInvisible) noexcept; [[nodiscard]] HRESULT _SetCrossedOut(const bool isCrossedOut) noexcept; [[nodiscard]] HRESULT _SetReverseVideo(const bool isReversed) noexcept; + [[nodiscard]] HRESULT _SetHyperlink(const std::wstring_view& uri, const std::wstring_view& customId, const uint16_t& numberId) noexcept; + [[nodiscard]] HRESULT _EndHyperlink() noexcept; [[nodiscard]] HRESULT _RequestCursor() noexcept; diff --git a/src/terminal/adapter/ITermDispatch.hpp b/src/terminal/adapter/ITermDispatch.hpp index b90705ac4a9..60639e67c3d 100644 --- a/src/terminal/adapter/ITermDispatch.hpp +++ b/src/terminal/adapter/ITermDispatch.hpp @@ -117,6 +117,9 @@ class Microsoft::Console::VirtualTerminal::ITermDispatch // DTTERM_WindowManipulation virtual bool WindowManipulation(const DispatchTypes::WindowManipulationType function, const gsl::span parameters) = 0; + + virtual bool AddHyperlink(const std::wstring_view uri, const std::wstring_view params) = 0; + virtual bool EndHyperlink() = 0; }; inline Microsoft::Console::VirtualTerminal::ITermDispatch::~ITermDispatch() {} #pragma warning(pop) diff --git a/src/terminal/adapter/adaptDispatch.cpp b/src/terminal/adapter/adaptDispatch.cpp index d435498c322..c1524021e65 100644 --- a/src/terminal/adapter/adaptDispatch.cpp +++ b/src/terminal/adapter/adaptDispatch.cpp @@ -2341,6 +2341,26 @@ bool AdaptDispatch::WindowManipulation(const DispatchTypes::WindowManipulationTy return success; } +// Method Description: +// - Starts a hyperlink +// Arguments: +// - The hyperlink URI, optional additional parameters +// Return Value: +// - true +bool AdaptDispatch::AddHyperlink(const std::wstring_view uri, const std::wstring_view params) +{ + return _pConApi->PrivateAddHyperlink(uri, params); +} + +// Method Description: +// - Ends a hyperlink +// Return Value: +// - true +bool AdaptDispatch::EndHyperlink() +{ + return _pConApi->PrivateEndHyperlink(); +} + // Routine Description: // - Determines whether we should pass any sequence that manipulates // TerminalInput's input generator through the PTY. It encapsulates diff --git a/src/terminal/adapter/adaptDispatch.hpp b/src/terminal/adapter/adaptDispatch.hpp index 2e5f27a7823..1d893e61ef8 100644 --- a/src/terminal/adapter/adaptDispatch.hpp +++ b/src/terminal/adapter/adaptDispatch.hpp @@ -118,6 +118,9 @@ namespace Microsoft::Console::VirtualTerminal bool WindowManipulation(const DispatchTypes::WindowManipulationType function, const gsl::span parameters) override; // DTTERM_WindowManipulation + bool AddHyperlink(const std::wstring_view uri, const std::wstring_view params) override; + bool EndHyperlink() override; + private: enum class ScrollDirection { diff --git a/src/terminal/adapter/adaptDispatchGraphics.cpp b/src/terminal/adapter/adaptDispatchGraphics.cpp index de873012193..13fc8a17ad6 100644 --- a/src/terminal/adapter/adaptDispatchGraphics.cpp +++ b/src/terminal/adapter/adaptDispatchGraphics.cpp @@ -116,7 +116,7 @@ bool AdaptDispatch::SetGraphicsRendition(const gsl::span clipRect, const COORD destinationOrigin, const bool standardFillAttrs) = 0; + + virtual bool PrivateAddHyperlink(const std::wstring_view uri, const std::wstring_view params) const = 0; + virtual bool PrivateEndHyperlink() const = 0; }; } diff --git a/src/terminal/adapter/termDispatch.hpp b/src/terminal/adapter/termDispatch.hpp index 47ecd990784..31070f85623 100644 --- a/src/terminal/adapter/termDispatch.hpp +++ b/src/terminal/adapter/termDispatch.hpp @@ -111,4 +111,7 @@ class Microsoft::Console::VirtualTerminal::TermDispatch : public Microsoft::Cons // DTTERM_WindowManipulation bool WindowManipulation(const DispatchTypes::WindowManipulationType /*function*/, const gsl::span /*params*/) noexcept override { return false; } + + bool AddHyperlink(const std::wstring_view /*uri*/, const std::wstring_view /*params*/) noexcept override { return false; } + bool EndHyperlink() noexcept override { return false; } }; diff --git a/src/terminal/adapter/ut_adapter/adapterTest.cpp b/src/terminal/adapter/ut_adapter/adapterTest.cpp index 92b295667ab..3d9128e496a 100644 --- a/src/terminal/adapter/ut_adapter/adapterTest.cpp +++ b/src/terminal/adapter/ut_adapter/adapterTest.cpp @@ -706,6 +706,20 @@ class TestGetSet final : public ConGetSet } } + bool PrivateAddHyperlink(const std::wstring_view /*uri*/, const std::wstring_view /*params*/) const + { + Log::Comment(L"PrivateAddHyperlink MOCK called..."); + + return TRUE; + } + + bool PrivateEndHyperlink() const + { + Log::Comment(L"PrivateEndHyperlink MOCK called..."); + + return TRUE; + } + void _SetMarginsHelper(SMALL_RECT* rect, SHORT top, SHORT bottom) { rect->Top = top; diff --git a/src/terminal/parser/OutputStateMachineEngine.cpp b/src/terminal/parser/OutputStateMachineEngine.cpp index cdecc28bbd8..15e946602fa 100644 --- a/src/terminal/parser/OutputStateMachineEngine.cpp +++ b/src/terminal/parser/OutputStateMachineEngine.cpp @@ -136,6 +136,7 @@ bool OutputStateMachineEngine::ActionPrintString(const std::wstring_view string) { return true; } + // Stash the last character of the string, if it's a graphical character const wchar_t wch = string.back(); if (wch >= AsciiChars::SPC) @@ -730,6 +731,8 @@ bool OutputStateMachineEngine::ActionOscDispatch(const wchar_t /*wch*/, bool success = false; std::wstring title; std::wstring setClipboardContent; + std::wstring params; + std::wstring uri; bool queryClipboard = false; size_t tableIndex = 0; DWORD color = 0; @@ -757,6 +760,9 @@ bool OutputStateMachineEngine::ActionOscDispatch(const wchar_t /*wch*/, color = 0xffffffff; success = true; break; + case OscActionCodes::Hyperlink: + success = _ParseHyperlink(string, params, uri); + break; default: // If no functions to call, overall dispatch was a failure. success = false; @@ -799,6 +805,16 @@ bool OutputStateMachineEngine::ActionOscDispatch(const wchar_t /*wch*/, success = _dispatch->SetCursorColor(color); TermTelemetry::Instance().Log(TermTelemetry::Codes::OSCRCC); break; + case OscActionCodes::Hyperlink: + if (uri.empty()) + { + success = _dispatch->EndHyperlink(); + } + else + { + success = _dispatch->AddHyperlink(uri, params); + } + break; default: // If no functions to call, overall dispatch was a failure. success = false; @@ -1574,6 +1590,44 @@ bool OutputStateMachineEngine::_GetOscSetColorTable(const std::wstring_view stri return success; } +// Routine Description: +// - Given a hyperlink string, attempts to parse the URI encoded. An 'id' parameter +// may be provided. +// If there is a URI, the well formatted string looks like: +// ";" +// If there is no URI, we need to close the hyperlink and the string looks like: +// ";" +// Arguments: +// - string - the string containing the parameters and URI +// - params - where to store the parameters +// - uri - where to store the uri +// Return Value: +// - True if a URI was successfully parsed or if we are meant to close a hyperlink +bool OutputStateMachineEngine::_ParseHyperlink(const std::wstring_view string, + std::wstring& params, + std::wstring& uri) const +{ + params.clear(); + uri.clear(); + const auto len = string.size(); + const size_t midPos = string.find(';'); + if (midPos != std::wstring::npos) + { + if (len != 1) + { + uri = string.substr(midPos + 1); + const auto paramStr = string.substr(0, midPos); + const auto idPos = paramStr.find(hyperlinkIDParameter); + if (idPos != std::wstring::npos) + { + params = paramStr.substr(idPos + hyperlinkIDParameter.size()); + } + } + return true; + } + return false; +} + // Routine Description: // - OSC 10, 11, 12 ; spec ST // spec: a color in the following format: diff --git a/src/terminal/parser/OutputStateMachineEngine.hpp b/src/terminal/parser/OutputStateMachineEngine.hpp index e6332a076e1..e96803ef36f 100644 --- a/src/terminal/parser/OutputStateMachineEngine.hpp +++ b/src/terminal/parser/OutputStateMachineEngine.hpp @@ -160,6 +160,7 @@ namespace Microsoft::Console::VirtualTerminal SetWindowTitle = 2, SetWindowProperty = 3, // Not implemented SetColor = 4, + Hyperlink = 8, SetForegroundColor = 10, SetBackgroundColor = 11, SetCursorColor = 12, @@ -250,6 +251,11 @@ namespace Microsoft::Console::VirtualTerminal std::wstring& content, bool& queryClipboard) const noexcept; + static constexpr std::wstring_view hyperlinkIDParameter{ L"id=" }; + bool _ParseHyperlink(const std::wstring_view string, + std::wstring& params, + std::wstring& uri) const; + void _ClearLastChar() noexcept; }; } diff --git a/src/terminal/parser/ft_fuzzer/VTCommandFuzzer.cpp b/src/terminal/parser/ft_fuzzer/VTCommandFuzzer.cpp index 70c823efe12..5a61e49f654 100644 --- a/src/terminal/parser/ft_fuzzer/VTCommandFuzzer.cpp +++ b/src/terminal/parser/ft_fuzzer/VTCommandFuzzer.cpp @@ -40,6 +40,7 @@ static std::string GenerateSoftResetToken(); static std::string GenerateOscColorTableToken(); static std::string GenerateVt52Token(); static std::string GenerateVt52CursorAddressToken(); +static std::string GenerateOscHyperlinkToken(); const fuzz::_fuzz_type_entry g_repeatMap[] = { { 4, [](BYTE) { return CFuzzChance::GetRandom(2, 0xF); } }, @@ -62,7 +63,8 @@ const std::function g_tokenGenerators[] = { GenerateSoftResetToken, GenerateOscColorTableToken, GenerateVt52Token, - GenerateVt52CursorAddressToken + GenerateVt52CursorAddressToken, + GenerateOscHyperlinkToken }; std::string GenerateTokenLowProbability() @@ -534,6 +536,72 @@ std::string GenerateVt52CursorAddressToken() return cux; } +// Osc Hyperlink String. An Osc followed by 8, followed by some optional key-value pairs, +// followed by a ";", followed by a string, and BEL terminated. +std::string GenerateOscHyperlinkToken() +{ + const LPSTR tokens[] = { "\x7" }; + const _fuzz_type_entry map[] = { + { 100, + [](std::string) { + std::string s; + AppendFormat(s, "%d", 8); + s.append(";"); + + // Maybe append some key-value pairs + SHORT numPairs = CFuzzChance::GetRandom(0, 5); + for (SHORT i = 0; i < numPairs; i++) + { + // usually add an id + SHORT limit = CFuzzChance::GetRandom(0, 10); + switch (limit) + { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + s.append("id="); + break; + case 7: + s.append("rgb="); + break; + case 8: + s.append("cmyk="); + break; + default: + // append some characters for the string + limit = CFuzzChance::GetRandom(); + for (SHORT j = 0; j < limit; j++) + { + AppendFormat(s, "%c", CFuzzChance::GetRandom()); + } + s.append("="); + } + // append some characters for the value + limit = CFuzzChance::GetRandom(); + for (SHORT j = 0; j < limit; j++) + { + AppendFormat(s, "%c", CFuzzChance::GetRandom()); + } + } + + s.append(";"); + // append some characters for the uri + SHORT limit = CFuzzChance::GetRandom(); + for (SHORT i = 0; i < limit; i++) + { + AppendFormat(s, "%c", CFuzzChance::GetRandom()); + } + return s; + } } + }; + + return GenerateFuzzedOscToken(FUZZ_MAP(map), tokens, ARRAYSIZE(tokens)); +} + int __cdecl wmain(int argc, WCHAR* argv[]) { if (argc != 3) diff --git a/src/terminal/parser/ut_parser/OutputEngineTest.cpp b/src/terminal/parser/ut_parser/OutputEngineTest.cpp index 166578b8055..aafb0cafbe3 100644 --- a/src/terminal/parser/ut_parser/OutputEngineTest.cpp +++ b/src/terminal/parser/ut_parser/OutputEngineTest.cpp @@ -816,6 +816,7 @@ class StatefulDispatch final : public TermDispatch _isDECCOLMAllowed{ false }, _windowWidth{ 80 }, _win32InputMode{ false }, + _hyperlinkMode{ false }, _options{ s_cMaxOptions, static_cast(s_uiGraphicsCleared) } // fill with cleared option { } @@ -1168,6 +1169,25 @@ class StatefulDispatch final : public TermDispatch return true; } + bool AddHyperlink(std::wstring_view uri, std::wstring_view params) noexcept override + { + _hyperlinkMode = true; + _uri = uri; + if (!params.empty()) + { + _customId = params; + } + return true; + } + + bool EndHyperlink() noexcept override + { + _hyperlinkMode = false; + _uri.clear(); + _customId.clear(); + return true; + } + size_t _cursorDistance; size_t _line; size_t _column; @@ -1214,7 +1234,10 @@ class StatefulDispatch final : public TermDispatch bool _isDECCOLMAllowed; size_t _windowWidth; bool _win32InputMode; + bool _hyperlinkMode; std::wstring _copyContent; + std::wstring _uri; + std::wstring _customId; static const size_t s_cMaxOptions = 16; static const size_t s_uiGraphicsCleared = UINT_MAX; @@ -2460,4 +2483,38 @@ class StateMachineExternalTest final pDispatch->ClearState(); } + + TEST_METHOD(TestAddHyperlink) + { + auto dispatch = std::make_unique(); + auto pDispatch = dispatch.get(); + auto engine = std::make_unique(std::move(dispatch)); + StateMachine mach(std::move(engine)); + + // First we test with no custom id + // Process the opening osc 8 sequence + mach.ProcessString(L"\x1b]8;;test.url\x9c"); + VERIFY_IS_TRUE(pDispatch->_hyperlinkMode); + VERIFY_ARE_EQUAL(pDispatch->_uri, L"test.url"); + VERIFY_IS_TRUE(pDispatch->_customId.empty()); + + // Process the closing osc 8 sequences + mach.ProcessString(L"\x1b]8;;\x9c"); + VERIFY_IS_FALSE(pDispatch->_hyperlinkMode); + VERIFY_IS_TRUE(pDispatch->_uri.empty()); + + // Next we test with a custom id + // Process the opening osc 8 sequence + mach.ProcessString(L"\x1b]8;id=testId;test2.url\x9c"); + VERIFY_IS_TRUE(pDispatch->_hyperlinkMode); + VERIFY_ARE_EQUAL(pDispatch->_uri, L"test2.url"); + VERIFY_ARE_EQUAL(pDispatch->_customId, L"testId"); + + // Process the closing osc 8 sequence + mach.ProcessString(L"\x1b]8;;\x9c"); + VERIFY_IS_FALSE(pDispatch->_hyperlinkMode); + VERIFY_IS_TRUE(pDispatch->_uri.empty()); + + pDispatch->ClearState(); + } }; From c808ed94a5df253faed6e1739d8c3276081c5eb3 Mon Sep 17 00:00:00 2001 From: Bill Dengler Date: Thu, 3 Sep 2020 14:06:43 -0400 Subject: [PATCH 093/266] Prevent crash when attempting to select an out-of-bounds UIA text range (#7504) When attempting to select a text range from a different text buffer (such as a standard text range when in alt mode), conhost crashes. This PR checks for this case and returns `E_FAIL` instead, preventing this crash. ## PR Checklist * [x] Closes unfiled crash issue * [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA * [x] Passes manual test below * [ ] 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 ## Validation Steps Performed Ran the following lines in the NVDA Python console (NVDA+control+z) before and after this PR, and observed that Conhost no longer crashes after the change: ``` Python console >>> # SSH to a remote Linux system >>> ti=nav.makeTextInfo("caret") >>> ti.move("line", -2) -2 >>> # Switch away from the NVDA Python console, and run Nano in conhost. Then: >>> ti.updateSelection() # Calls select() on the underlying UIA text range Traceback (most recent call last): File "", line 1, in File "NVDAObjects\UIA\__init__.pyc", line 790, in updateSelection File "comtypesMonkeyPatches.pyc", line 26, in __call__ _ctypes.COMError: (-2147220991, 'An event was unable to invoke any of the subscribers', (None, None, None, 0, None)) ``` --- src/types/UiaTextRangeBase.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/types/UiaTextRangeBase.cpp b/src/types/UiaTextRangeBase.cpp index 7d12fb42762..1de46851558 100644 --- a/src/types/UiaTextRangeBase.cpp +++ b/src/types/UiaTextRangeBase.cpp @@ -702,8 +702,13 @@ try } else { + const auto bufferSize = _pData->GetTextBuffer().GetSize(); + if (!bufferSize.IsInBounds(_start, true) || !bufferSize.IsInBounds(_end, true)) + { + return E_FAIL; + } auto inclusiveEnd = _end; - _pData->GetTextBuffer().GetSize().DecrementInBounds(inclusiveEnd); + bufferSize.DecrementInBounds(inclusiveEnd); _pData->SelectNewRegion(_start, inclusiveEnd); } From 4c75ffb32783b34166461150c2d9882962d29afd Mon Sep 17 00:00:00 2001 From: Dustin Howett Date: Thu, 3 Sep 2020 21:38:04 +0000 Subject: [PATCH 094/266] Merged PR 5131018: [Git2Git] Migrate OS changes to console property sheet manifest Retrieved from https://microsoft.visualstudio.com os.2020 OS official/rs_onecore_dep_uxp dd0c54d9abd94dea1ffe956373a4c20b30a6151e Related work items: MSFT-26187783 --- src/propsheet/console.man | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/propsheet/console.man b/src/propsheet/console.man index e7c4ed11632..8adf3a83cba 100644 --- a/src/propsheet/console.man +++ b/src/propsheet/console.man @@ -59,7 +59,10 @@ /> - + Date: Thu, 3 Sep 2020 16:35:41 -0700 Subject: [PATCH 095/266] Add profiles to the Jumplist (#7515) This commit introduces Jumplist customization and an item for each profile to the Jumplist. Selecting an entry in the jumplist will pretty much just execute `wt.exe -p "{profile guid}"`, and so a new Terminal will open with the selected profile. Closes #576 --- .../spell-check/dictionary/microsoft.txt | 1 + src/cascadia/TerminalApp/AppLogic.cpp | 4 + src/cascadia/TerminalApp/AppLogic.h | 1 + src/cascadia/TerminalApp/Jumplist.cpp | 131 ++++++++++++++++++ src/cascadia/TerminalApp/Jumplist.h | 29 ++++ .../TerminalApp/TerminalAppLib.vcxproj | 2 + 6 files changed, 168 insertions(+) create mode 100644 src/cascadia/TerminalApp/Jumplist.cpp create mode 100644 src/cascadia/TerminalApp/Jumplist.h diff --git a/.github/actions/spell-check/dictionary/microsoft.txt b/.github/actions/spell-check/dictionary/microsoft.txt index 0e94847f887..2f520a5c2f3 100644 --- a/.github/actions/spell-check/dictionary/microsoft.txt +++ b/.github/actions/spell-check/dictionary/microsoft.txt @@ -18,6 +18,7 @@ pgo pgosweep powerrename powershell +propkey pscustomobject robocopy SACLs diff --git a/src/cascadia/TerminalApp/AppLogic.cpp b/src/cascadia/TerminalApp/AppLogic.cpp index 2a02e80dd13..2c217e50b7c 100644 --- a/src/cascadia/TerminalApp/AppLogic.cpp +++ b/src/cascadia/TerminalApp/AppLogic.cpp @@ -693,6 +693,8 @@ namespace winrt::TerminalApp::implementation // Register for directory change notification. _RegisterSettingsChange(); + + Jumplist::UpdateJumplist(*_settings); } // Method Description: @@ -851,6 +853,8 @@ namespace winrt::TerminalApp::implementation _RefreshThemeRoutine(); _ApplyStartupTaskStateChange(); + + Jumplist::UpdateJumplist(*_settings); } // Method Description: diff --git a/src/cascadia/TerminalApp/AppLogic.h b/src/cascadia/TerminalApp/AppLogic.h index a5e811a886b..18204401fdc 100644 --- a/src/cascadia/TerminalApp/AppLogic.h +++ b/src/cascadia/TerminalApp/AppLogic.h @@ -8,6 +8,7 @@ #include "Tab.h" #include "CascadiaSettings.h" #include "TerminalPage.h" +#include "Jumplist.h" #include "../../cascadia/inc/cppwinrt_utils.h" namespace winrt::TerminalApp::implementation diff --git a/src/cascadia/TerminalApp/Jumplist.cpp b/src/cascadia/TerminalApp/Jumplist.cpp new file mode 100644 index 00000000000..625367c7410 --- /dev/null +++ b/src/cascadia/TerminalApp/Jumplist.cpp @@ -0,0 +1,131 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +#include "pch.h" +#include "Jumplist.h" + +#include +#include + +using namespace winrt::TerminalApp; + +// This property key isn't already defined in propkey.h, but is used by UWP Jumplist to determine the icon of the jumplist item. +// IShellLink's SetIconLocation isn't going to read "ms-appx://" icon paths, so we'll need to use this to set the icon. +DEFINE_PROPERTYKEY(PKEY_AppUserModel_DestListLogoUri, 0x9F4C2855, 0x9F79, 0x4B39, 0xA8, 0xD0, 0xE1, 0xD4, 0x2D, 0xE1, 0xD5, 0xF3, 29); +#define INIT_PKEY_AppUserModel_DestListLogoUri \ + { \ + { 0x9F4C2855, 0x9F79, 0x4B39, 0xA8, 0xD0, 0xE1, 0xD4, 0x2D, 0xE1, 0xD5, 0xF3 }, 29 \ + } + +// Method Description: +// - Updates the items of the Jumplist based on the given settings. +// Arguments: +// - settings - The settings object to update the jumplist with. +// Return Value: +// - +HRESULT Jumplist::UpdateJumplist(const TerminalApp::CascadiaSettings& settings) noexcept +{ + try + { + auto jumplistInstance = winrt::create_instance(CLSID_DestinationList, CLSCTX_ALL); + + // Start the Jumplist edit transaction + uint32_t slots; + winrt::com_ptr jumplistItems; + jumplistItems.capture(jumplistInstance, &ICustomDestinationList::BeginList, &slots); + + // It's easier to clear the list and re-add everything. The settings aren't + // updated often, and there likely isn't a huge amount of items to add. + RETURN_IF_FAILED(jumplistItems->Clear()); + + // Update the list of profiles. + RETURN_IF_FAILED(_updateProfiles(jumplistItems.get(), settings.GetProfiles())); + + // TODO GH#1571: Add items from the future customizable new tab dropdown as well. + // This could either replace the default profiles, or be added alongside them. + + // Add the items to the jumplist Task section. + // The Tasks section is immutable by the user, unlike the destinations + // section that can have its items pinned and removed. + RETURN_IF_FAILED(jumplistInstance->AddUserTasks(jumplistItems.get())); + + RETURN_IF_FAILED(jumplistInstance->CommitList()); + + return S_OK; + } + CATCH_RETURN(); +} + +// Method Description: +// - Creates and adds a ShellLink object to the Jumplist for each profile. +// Arguments: +// - jumplistItems - The jumplist item list +// - profiles - The profiles to add to the jumplist +// Return Value: +// - S_OK or HRESULT failure code. +[[nodiscard]] HRESULT Jumplist::_updateProfiles(IObjectCollection* jumplistItems, const gsl::span& profiles) noexcept +{ + try + { + for (const auto& profile : profiles) + { + // Craft the arguments following "wt.exe" + auto args = fmt::format(L"-p {}", to_hstring(profile.Guid())); + + // Create the shell link object for the profile + winrt::com_ptr shLink; + RETURN_IF_FAILED(_createShellLink(profile.Name(), profile.GetExpandedIconPath(), args, shLink.put())); + + RETURN_IF_FAILED(jumplistItems->AddObject(shLink.get())); + } + + return S_OK; + } + CATCH_RETURN(); +} + +// Method Description: +// - Creates a ShellLink object. Each item in a jumplist is a ShellLink, which is sort of +// like a shortcut. It requires the path to the application (wt.exe), the arguments to pass, +// and the path to the icon for the jumplist item. The path to the application isn't passed +// into this function, as we'll determine it with GetModuleFileName. +// Arguments: +// - name: The name of the item displayed in the jumplist. +// - path: The path to the icon for the jumplist item. +// - args: The arguments to pass along with wt.exe +// - shLink: The shell link object to return. +// Return Value: +// - S_OK or HRESULT failure code. +[[nodiscard]] HRESULT Jumplist::_createShellLink(const std::wstring_view name, + const std::wstring_view path, + const std::wstring_view args, + IShellLinkW** shLink) noexcept +{ + try + { + auto sh = winrt::create_instance(CLSID_ShellLink, CLSCTX_ALL); + + std::filesystem::path module{ wil::GetModuleFileNameW(nullptr) }; + RETURN_IF_FAILED(sh->SetPath(module.c_str())); + RETURN_IF_FAILED(sh->SetArguments(args.data())); + + PROPVARIANT titleProp; + titleProp.vt = VT_LPWSTR; + titleProp.pwszVal = const_cast(name.data()); + + PROPVARIANT iconProp; + iconProp.vt = VT_LPWSTR; + iconProp.pwszVal = const_cast(path.data()); + + auto propStore{ sh.as() }; + RETURN_IF_FAILED(propStore->SetValue(PKEY_Title, titleProp)); + RETURN_IF_FAILED(propStore->SetValue(PKEY_AppUserModel_DestListLogoUri, iconProp)); + + RETURN_IF_FAILED(propStore->Commit()); + + *shLink = sh.detach(); + + return S_OK; + } + CATCH_RETURN(); +} diff --git a/src/cascadia/TerminalApp/Jumplist.h b/src/cascadia/TerminalApp/Jumplist.h new file mode 100644 index 00000000000..ba3649c0311 --- /dev/null +++ b/src/cascadia/TerminalApp/Jumplist.h @@ -0,0 +1,29 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. +// +// Module Name: +// - Jumplist.h +// +// Abstract: +// - The Jumplist is the menu that pops up when right clicking a pinned +// item in the taskbar. This class handles updating the Terminal's jumplist +// using the Terminal's settings. +// + +#pragma once + +#include "CascadiaSettings.h" +#include "Profile.h" + +struct IObjectCollection; +struct IShellLinkW; + +class Jumplist +{ +public: + static HRESULT UpdateJumplist(const TerminalApp::CascadiaSettings& settings) noexcept; + +private: + [[nodiscard]] static HRESULT _updateProfiles(IObjectCollection* jumplistItems, const gsl::span& profiles) noexcept; + [[nodiscard]] static HRESULT _createShellLink(const std::wstring_view name, const std::wstring_view path, const std::wstring_view args, IShellLinkW** shLink) noexcept; +}; diff --git a/src/cascadia/TerminalApp/TerminalAppLib.vcxproj b/src/cascadia/TerminalApp/TerminalAppLib.vcxproj index f4a0ee3c25e..85d3a858790 100644 --- a/src/cascadia/TerminalApp/TerminalAppLib.vcxproj +++ b/src/cascadia/TerminalApp/TerminalAppLib.vcxproj @@ -72,6 +72,7 @@ + MinMaxCloseControl.xaml @@ -155,6 +156,7 @@ + MinMaxCloseControl.xaml From 5330759c0f3d98b92209813c48e781a664fe22eb Mon Sep 17 00:00:00 2001 From: Marcel Wagner Date: Fri, 4 Sep 2020 22:00:40 +0200 Subject: [PATCH 096/266] Update to a newer MUX prerelease; remove workaround for compact sizing (#7447) Update the WinUI version which allows us to remove the workaround. Closes #6681 --- src/cascadia/CascadiaPackage/CascadiaPackage.wapproj | 4 ++-- .../TerminalApp.LocalTests.vcxproj | 4 ++-- .../TestHostApp/TestHostApp.vcxproj | 2 +- src/cascadia/TerminalApp/TerminalAppLib.vcxproj | 4 ++-- src/cascadia/TerminalApp/TerminalPage.cpp | 10 ---------- src/cascadia/TerminalApp/dll/TerminalApp.vcxproj | 4 ++-- src/cascadia/TerminalApp/packages.config | 2 +- src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj | 4 ++-- src/cascadia/WindowsTerminal/packages.config | 2 +- .../WindowsTerminalUniversal.vcxproj | 4 ++-- src/cascadia/ut_app/TerminalApp.UnitTests.vcxproj | 2 +- 11 files changed, 16 insertions(+), 26 deletions(-) diff --git a/src/cascadia/CascadiaPackage/CascadiaPackage.wapproj b/src/cascadia/CascadiaPackage/CascadiaPackage.wapproj index 237963a6428..3956e256859 100644 --- a/src/cascadia/CascadiaPackage/CascadiaPackage.wapproj +++ b/src/cascadia/CascadiaPackage/CascadiaPackage.wapproj @@ -147,12 +147,12 @@ - + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + diff --git a/src/cascadia/LocalTests_TerminalApp/TerminalApp.LocalTests.vcxproj b/src/cascadia/LocalTests_TerminalApp/TerminalApp.LocalTests.vcxproj index 67952867d7d..3bfbd065759 100644 --- a/src/cascadia/LocalTests_TerminalApp/TerminalApp.LocalTests.vcxproj +++ b/src/cascadia/LocalTests_TerminalApp/TerminalApp.LocalTests.vcxproj @@ -114,11 +114,11 @@ x86 $(Platform) - <_MUXBinRoot>"$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\runtimes\win10-$(Native-Platform)\native\" + <_MUXBinRoot>"$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.5.0-prerelease.200812001\runtimes\win10-$(Native-Platform)\native\" - + diff --git a/src/cascadia/LocalTests_TerminalApp/TestHostApp/TestHostApp.vcxproj b/src/cascadia/LocalTests_TerminalApp/TestHostApp/TestHostApp.vcxproj index b6d85e9ae04..d335d47396b 100644 --- a/src/cascadia/LocalTests_TerminalApp/TestHostApp/TestHostApp.vcxproj +++ b/src/cascadia/LocalTests_TerminalApp/TestHostApp/TestHostApp.vcxproj @@ -121,7 +121,7 @@ - + diff --git a/src/cascadia/TerminalApp/TerminalAppLib.vcxproj b/src/cascadia/TerminalApp/TerminalAppLib.vcxproj index 85d3a858790..421f4dbadf1 100644 --- a/src/cascadia/TerminalApp/TerminalAppLib.vcxproj +++ b/src/cascadia/TerminalApp/TerminalAppLib.vcxproj @@ -355,13 +355,13 @@ - + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index ceb86a52481..22aab3e6df5 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -713,16 +713,6 @@ namespace winrt::TerminalApp::implementation auto tabViewItem = newTabImpl->GetTabViewItem(); _tabView.TabItems().Append(tabViewItem); - // GH#6570 - // The TabView does not apply compact sizing to items added after Compact is enabled. - // By forcibly reapplying compact sizing every time we add a new tab, we'll make sure - // that it works. - // Workaround from https://github.com/microsoft/microsoft-ui-xaml/issues/2711 - if (_tabView.TabWidthMode() == MUX::Controls::TabViewWidthMode::Compact) - { - _tabView.UpdateLayout(); - _tabView.TabWidthMode(MUX::Controls::TabViewWidthMode::Compact); - } // Set this tab's icon to the icon from the user's profile const auto profile = _settings->FindProfile(profileGuid); diff --git a/src/cascadia/TerminalApp/dll/TerminalApp.vcxproj b/src/cascadia/TerminalApp/dll/TerminalApp.vcxproj index 8d8962cca79..49ccdf39099 100644 --- a/src/cascadia/TerminalApp/dll/TerminalApp.vcxproj +++ b/src/cascadia/TerminalApp/dll/TerminalApp.vcxproj @@ -78,13 +78,13 @@ - + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + diff --git a/src/cascadia/TerminalApp/packages.config b/src/cascadia/TerminalApp/packages.config index 1f023409c8d..ff1e310ee51 100644 --- a/src/cascadia/TerminalApp/packages.config +++ b/src/cascadia/TerminalApp/packages.config @@ -1,6 +1,6 @@  - + diff --git a/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj b/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj index 395c76d9e8e..358a5bfc457 100644 --- a/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj +++ b/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj @@ -94,14 +94,14 @@ - + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + diff --git a/src/cascadia/WindowsTerminal/packages.config b/src/cascadia/WindowsTerminal/packages.config index 166f8861ffa..797852c2795 100644 --- a/src/cascadia/WindowsTerminal/packages.config +++ b/src/cascadia/WindowsTerminal/packages.config @@ -2,7 +2,7 @@ - + \ No newline at end of file diff --git a/src/cascadia/WindowsTerminalUniversal/WindowsTerminalUniversal.vcxproj b/src/cascadia/WindowsTerminalUniversal/WindowsTerminalUniversal.vcxproj index 0a749357a56..35c303bd5d8 100644 --- a/src/cascadia/WindowsTerminalUniversal/WindowsTerminalUniversal.vcxproj +++ b/src/cascadia/WindowsTerminalUniversal/WindowsTerminalUniversal.vcxproj @@ -154,7 +154,7 @@ - + @@ -162,7 +162,7 @@ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + diff --git a/src/cascadia/ut_app/TerminalApp.UnitTests.vcxproj b/src/cascadia/ut_app/TerminalApp.UnitTests.vcxproj index 868002a5fd2..2bb6093e8e5 100644 --- a/src/cascadia/ut_app/TerminalApp.UnitTests.vcxproj +++ b/src/cascadia/ut_app/TerminalApp.UnitTests.vcxproj @@ -98,7 +98,7 @@ x86 $(Platform) - <_MUXBinRoot>"$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\runtimes\win10-$(Native-Platform)\native\" + <_MUXBinRoot>"$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.5.0-prerelease.200812001\runtimes\win10-$(Native-Platform)\native\" From 5ba992a8036a2d1c0d373f93faed6c9c2c050afd Mon Sep 17 00:00:00 2001 From: Marcel Wagner Date: Fri, 4 Sep 2020 22:01:51 +0200 Subject: [PATCH 097/266] docs: use unlikely example versions in nuget package script (#7448) * Update doc * Change last digit --- doc/building.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/building.md b/doc/building.md index 27c1e7d806e..9a3eba6c6d6 100644 --- a/doc/building.md +++ b/doc/building.md @@ -67,12 +67,12 @@ To update the version of a given package, use the following snippet where: - `$PackageName` is the name of the package, e.g. Microsoft.UI.Xaml -- `$OldVersionNumber` is the version number currently used, e.g. 2.5.0-prerelease.200609001 -- `$NewVersionNumber` is the version number you want to migrate to, e.g. 2.4.200117003-prerelease +- `$OldVersionNumber` is the version number currently used, e.g. 2.4.0-prerelease.200506002 +- `$NewVersionNumber` is the version number you want to migrate to, e.g. 2.5.0-prerelease.200812002 Example usage: -`git grep -z -l Microsoft.UI.Xaml | xargs -0 sed -i -e 's/2.5.0-prerelease.200609001/2.4.200117003-prerelease/g'` +`git grep -z -l Microsoft.UI.Xaml | xargs -0 sed -i -e 's/2.4.0-prerelease.200506002/2.5.0-prerelease.200812002/g'` ## Using .nupkg files instead of downloaded Nuget packages If you want to use .nupkg files instead of the downloaded Nuget package, you can do this with the following steps: From 7ab4d45a9d035c354b0fdf8aa9fe2d4ef498a45a Mon Sep 17 00:00:00 2001 From: Chester Liu Date: Sat, 5 Sep 2020 04:36:09 +0800 Subject: [PATCH 098/266] Add support for DECSCUSR "0" to restore cursor to user default (#7379) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR is about the behavior of DECSCUSR. This PR changes the meaning of DECSCUSR 0 to restore the cursor style back to user default. This differs from what VT spec says but it’s used in popular terminal emulators like iTerm2 and VTE-based ones. See #1604. Another change is that for parameter greater than 6, DECSCUSR should be ignored, instead of restoring the cursor to legacy. This PR fixes it. See #7382. Fixes #1604. --- src/cascadia/TerminalCore/Terminal.cpp | 2 ++ src/cascadia/TerminalCore/Terminal.hpp | 1 + src/cascadia/TerminalCore/TerminalApi.cpp | 11 +++++++---- src/host/outputStream.cpp | 13 +++++++++++++ src/host/outputStream.hpp | 1 + src/terminal/adapter/DispatchTypes.hpp | 4 ++-- src/terminal/adapter/adaptDispatch.cpp | 9 ++++++++- src/terminal/adapter/conGetSet.hpp | 1 + src/terminal/adapter/ut_adapter/adapterTest.cpp | 6 ++++++ src/terminal/parser/OutputStateMachineEngine.hpp | 2 +- 10 files changed, 42 insertions(+), 8 deletions(-) diff --git a/src/cascadia/TerminalCore/Terminal.cpp b/src/cascadia/TerminalCore/Terminal.cpp index 03afa6c0084..55f8a5b3f8a 100644 --- a/src/cascadia/TerminalCore/Terminal.cpp +++ b/src/cascadia/TerminalCore/Terminal.cpp @@ -134,6 +134,8 @@ void Terminal::UpdateSettings(ICoreSettings settings) cursorShape); } + _defaultCursorShape = cursorShape; + for (int i = 0; i < 16; i++) { _colorTable.at(i) = settings.GetColorTableEntry(i); diff --git a/src/cascadia/TerminalCore/Terminal.hpp b/src/cascadia/TerminalCore/Terminal.hpp index 6b0eea1eba4..ff295fea537 100644 --- a/src/cascadia/TerminalCore/Terminal.hpp +++ b/src/cascadia/TerminalCore/Terminal.hpp @@ -221,6 +221,7 @@ class Microsoft::Terminal::Core::Terminal final : std::array _colorTable; COLORREF _defaultFg; COLORREF _defaultBg; + CursorType _defaultCursorShape; bool _screenReversed; bool _snapOnInput; diff --git a/src/cascadia/TerminalCore/TerminalApi.cpp b/src/cascadia/TerminalCore/TerminalApi.cpp index 92149471f69..9a7e896fe95 100644 --- a/src/cascadia/TerminalCore/TerminalApi.cpp +++ b/src/cascadia/TerminalCore/TerminalApi.cpp @@ -389,8 +389,10 @@ bool Terminal::SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle) noex switch (cursorStyle) { - case DispatchTypes::CursorStyle::BlinkingBlockDefault: - [[fallthrough]]; + case DispatchTypes::CursorStyle::UserDefault: + finalCursorType = _defaultCursorShape; + shouldBlink = true; + break; case DispatchTypes::CursorStyle::BlinkingBlock: finalCursorType = CursorType::FullBox; shouldBlink = true; @@ -415,9 +417,10 @@ bool Terminal::SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle) noex finalCursorType = CursorType::VerticalBar; shouldBlink = false; break; + default: - finalCursorType = CursorType::Legacy; - shouldBlink = false; + // Invalid argument should be ignored. + return true; } _buffer->GetCursor().SetType(finalCursorType); diff --git a/src/host/outputStream.cpp b/src/host/outputStream.cpp index d98a40b2a67..53aed7ad1ee 100644 --- a/src/host/outputStream.cpp +++ b/src/host/outputStream.cpp @@ -513,6 +513,19 @@ bool ConhostInternalGetSet::PrivateEraseAll() return SUCCEEDED(DoSrvPrivateEraseAll(_io.GetActiveOutputBuffer())); } +// Method Description: +// - Retrieves the current user default cursor style. +// Arguments: +// - style - Structure to receive cursor style. +// Return Value: +// - true if successful. false otherwise. +bool ConhostInternalGetSet::GetUserDefaultCursorStyle(CursorType& style) +{ + const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation(); + style = gci.GetCursorType(); + return true; +} + // Routine Description: // - Connects the SetCursorStyle call directly into our Driver Message servicing call inside Conhost.exe // SetCursorStyle is an internal-only "API" call that the vt commands can execute, diff --git a/src/host/outputStream.hpp b/src/host/outputStream.hpp index 8e3274f16cc..da8838b5053 100644 --- a/src/host/outputStream.hpp +++ b/src/host/outputStream.hpp @@ -107,6 +107,7 @@ class ConhostInternalGetSet final : public Microsoft::Console::VirtualTerminal:: bool PrivatePrependConsoleInput(std::deque>& events, size_t& eventsWritten) override; + bool GetUserDefaultCursorStyle(CursorType& style) override; bool SetCursorStyle(CursorType const style) override; bool SetCursorColor(COLORREF const color) override; diff --git a/src/terminal/adapter/DispatchTypes.hpp b/src/terminal/adapter/DispatchTypes.hpp index 1454ed279e4..0eccfff2220 100644 --- a/src/terminal/adapter/DispatchTypes.hpp +++ b/src/terminal/adapter/DispatchTypes.hpp @@ -216,8 +216,8 @@ namespace Microsoft::Console::VirtualTerminal::DispatchTypes enum class CursorStyle : unsigned int { - BlinkingBlock = 0, - BlinkingBlockDefault = 1, + UserDefault = 0, // Implemented as "restore cursor to user default". + BlinkingBlock = 1, SteadyBlock = 2, BlinkingUnderline = 3, SteadyUnderline = 4, diff --git a/src/terminal/adapter/adaptDispatch.cpp b/src/terminal/adapter/adaptDispatch.cpp index c1524021e65..5dec740da5a 100644 --- a/src/terminal/adapter/adaptDispatch.cpp +++ b/src/terminal/adapter/adaptDispatch.cpp @@ -2160,8 +2160,11 @@ bool AdaptDispatch::SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle) switch (cursorStyle) { + case DispatchTypes::CursorStyle::UserDefault: + _pConApi->GetUserDefaultCursorStyle(actualType); + fEnableBlinking = true; + break; case DispatchTypes::CursorStyle::BlinkingBlock: - case DispatchTypes::CursorStyle::BlinkingBlockDefault: fEnableBlinking = true; actualType = CursorType::FullBox; break; @@ -2187,6 +2190,10 @@ bool AdaptDispatch::SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle) fEnableBlinking = false; actualType = CursorType::VerticalBar; break; + + default: + // Invalid argument should be handled by the connected terminal. + return false; } bool success = _pConApi->SetCursorStyle(actualType); diff --git a/src/terminal/adapter/conGetSet.hpp b/src/terminal/adapter/conGetSet.hpp index 63011cd617a..8eb97bffcc0 100644 --- a/src/terminal/adapter/conGetSet.hpp +++ b/src/terminal/adapter/conGetSet.hpp @@ -70,6 +70,7 @@ namespace Microsoft::Console::VirtualTerminal virtual bool PrivateEnableAnyEventMouseMode(const bool enabled) = 0; virtual bool PrivateEnableAlternateScroll(const bool enabled) = 0; virtual bool PrivateEraseAll() = 0; + virtual bool GetUserDefaultCursorStyle(CursorType& style) = 0; virtual bool SetCursorStyle(const CursorType style) = 0; virtual bool SetCursorColor(const COLORREF color) = 0; virtual bool PrivatePrependConsoleInput(std::deque>& events, diff --git a/src/terminal/adapter/ut_adapter/adapterTest.cpp b/src/terminal/adapter/ut_adapter/adapterTest.cpp index 3d9128e496a..862c035468a 100644 --- a/src/terminal/adapter/ut_adapter/adapterTest.cpp +++ b/src/terminal/adapter/ut_adapter/adapterTest.cpp @@ -434,6 +434,12 @@ class TestGetSet final : public ConGetSet return TRUE; } + bool GetUserDefaultCursorStyle(CursorType& style) override + { + style = CursorType::Legacy; + return true; + } + bool SetCursorStyle(const CursorType cursorType) override { Log::Comment(L"SetCursorStyle MOCK called..."); diff --git a/src/terminal/parser/OutputStateMachineEngine.hpp b/src/terminal/parser/OutputStateMachineEngine.hpp index e96803ef36f..794a9d59f9e 100644 --- a/src/terminal/parser/OutputStateMachineEngine.hpp +++ b/src/terminal/parser/OutputStateMachineEngine.hpp @@ -239,7 +239,7 @@ namespace Microsoft::Console::VirtualTerminal bool _GetOscSetColor(const std::wstring_view string, DWORD& rgb) const noexcept; - static constexpr DispatchTypes::CursorStyle DefaultCursorStyle = DispatchTypes::CursorStyle::BlinkingBlockDefault; + static constexpr DispatchTypes::CursorStyle DefaultCursorStyle = DispatchTypes::CursorStyle::UserDefault; bool _GetCursorStyle(const gsl::span parameters, DispatchTypes::CursorStyle& cursorStyle) const noexcept; From 7a03f75ee9b905bd796d4d6a02f7cff3d5b1e472 Mon Sep 17 00:00:00 2001 From: Bill Dengler Date: Fri, 4 Sep 2020 16:59:38 -0400 Subject: [PATCH 099/266] Keep degenerate UIA text ranges degenerate after movement (#7530) Conhost expands UIA text ranges when moved. This means that degenerate ranges become non-degenerate after movement, leading to odd behaviour from UIA clients. This PR doesn't expand degenerate ranges, but rather keeps them degenerate by moving `_end` to the newly-changed `_start`. Tested in the NVDA Python console (cases with `setEndPoint` and `compareEndPoints` described in #7342). Also ran the logic by @michaeldcurran. Closes #7342 Almost definitely addresses nvaccess/nvda#11288 (although I'll need to test with my Braille display). Also fixes an issue privately reported to me by @simon818 with copy/paste from review cursor which originally lead me to believe the issue was with `moveEndPointByRange`. --- .../UiaTextRangeTests.cpp | 26 ++++++++++++++++++- src/types/UiaTextRangeBase.cpp | 14 ++++++++-- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/interactivity/win32/ut_interactivity_win32/UiaTextRangeTests.cpp b/src/interactivity/win32/ut_interactivity_win32/UiaTextRangeTests.cpp index 4101aebfe09..414d3f52e68 100644 --- a/src/interactivity/win32/ut_interactivity_win32/UiaTextRangeTests.cpp +++ b/src/interactivity/win32/ut_interactivity_win32/UiaTextRangeTests.cpp @@ -583,7 +583,7 @@ class UiaTextRangeTests { 5, {4 , 0 + 1}, - {5 , 0 + 1} + {4 , 0 + 1} } }, @@ -694,6 +694,30 @@ class UiaTextRangeTests {0, bottomRow}, {0, bottomRow} } + }, + + MoveTest{ + L"can move to a new row when necessary when moving forward", + { lastColumnIndex, 0 }, + { lastColumnIndex, 0 }, + 5, + { + 5, + {0, 0 + 5}, + {0, 0 + 5} + } + }, + + MoveTest{ + L"can move to a new row when necessary when moving backward", + { 0, 7 }, + { 0, 7 }, + -5, + { + -5, + {0, 7 - 5}, + {0, 7 - 5} + } } }; // clang-format on diff --git a/src/types/UiaTextRangeBase.cpp b/src/types/UiaTextRangeBase.cpp index 1de46851558..506b25cb104 100644 --- a/src/types/UiaTextRangeBase.cpp +++ b/src/types/UiaTextRangeBase.cpp @@ -579,6 +579,7 @@ IFACEMETHODIMP UiaTextRangeBase::Move(_In_ TextUnit unit, // We can abstract this movement by moving _start, but disallowing moving to the end of the buffer constexpr auto endpoint = TextPatternRangeEndpoint::TextPatternRangeEndpoint_Start; constexpr auto preventBufferEnd = true; + const auto wasDegenerate = IsDegenerate(); try { if (unit == TextUnit::TextUnit_Character) @@ -603,8 +604,17 @@ IFACEMETHODIMP UiaTextRangeBase::Move(_In_ TextUnit unit, // If we actually moved... if (*pRetVal != 0) { - // then just expand to get our _end - ExpandToEnclosingUnit(unit); + if (wasDegenerate) + { + // GH#7342: The range was degenerate before the move. + // To keep it that way, move _end to the new _start. + _end = _start; + } + else + { + // then just expand to get our _end + ExpandToEnclosingUnit(unit); + } } UiaTracing::TextRange::Move(unit, count, *pRetVal, *this); From 230b86c9905e0f91f07741664b0814cf43c3a483 Mon Sep 17 00:00:00 2001 From: Dustin Howett Date: Tue, 8 Sep 2020 09:25:30 -0700 Subject: [PATCH 100/266] Revert "Update to a newer MUX prerelease; remove workaround for compact sizing (#7447)" This reverts commit 5330759c0f3d98b92209813c48e781a664fe22eb. Fixes #7553 --- src/cascadia/CascadiaPackage/CascadiaPackage.wapproj | 4 ++-- .../TerminalApp.LocalTests.vcxproj | 4 ++-- .../TestHostApp/TestHostApp.vcxproj | 2 +- src/cascadia/TerminalApp/TerminalAppLib.vcxproj | 4 ++-- src/cascadia/TerminalApp/TerminalPage.cpp | 10 ++++++++++ src/cascadia/TerminalApp/dll/TerminalApp.vcxproj | 4 ++-- src/cascadia/TerminalApp/packages.config | 2 +- src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj | 4 ++-- src/cascadia/WindowsTerminal/packages.config | 2 +- .../WindowsTerminalUniversal.vcxproj | 4 ++-- src/cascadia/ut_app/TerminalApp.UnitTests.vcxproj | 2 +- 11 files changed, 26 insertions(+), 16 deletions(-) diff --git a/src/cascadia/CascadiaPackage/CascadiaPackage.wapproj b/src/cascadia/CascadiaPackage/CascadiaPackage.wapproj index 3956e256859..237963a6428 100644 --- a/src/cascadia/CascadiaPackage/CascadiaPackage.wapproj +++ b/src/cascadia/CascadiaPackage/CascadiaPackage.wapproj @@ -147,12 +147,12 @@ - + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + diff --git a/src/cascadia/LocalTests_TerminalApp/TerminalApp.LocalTests.vcxproj b/src/cascadia/LocalTests_TerminalApp/TerminalApp.LocalTests.vcxproj index 3bfbd065759..67952867d7d 100644 --- a/src/cascadia/LocalTests_TerminalApp/TerminalApp.LocalTests.vcxproj +++ b/src/cascadia/LocalTests_TerminalApp/TerminalApp.LocalTests.vcxproj @@ -114,11 +114,11 @@ x86 $(Platform) - <_MUXBinRoot>"$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.5.0-prerelease.200812001\runtimes\win10-$(Native-Platform)\native\" + <_MUXBinRoot>"$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\runtimes\win10-$(Native-Platform)\native\" - + diff --git a/src/cascadia/LocalTests_TerminalApp/TestHostApp/TestHostApp.vcxproj b/src/cascadia/LocalTests_TerminalApp/TestHostApp/TestHostApp.vcxproj index d335d47396b..b6d85e9ae04 100644 --- a/src/cascadia/LocalTests_TerminalApp/TestHostApp/TestHostApp.vcxproj +++ b/src/cascadia/LocalTests_TerminalApp/TestHostApp/TestHostApp.vcxproj @@ -121,7 +121,7 @@ - + diff --git a/src/cascadia/TerminalApp/TerminalAppLib.vcxproj b/src/cascadia/TerminalApp/TerminalAppLib.vcxproj index 421f4dbadf1..85d3a858790 100644 --- a/src/cascadia/TerminalApp/TerminalAppLib.vcxproj +++ b/src/cascadia/TerminalApp/TerminalAppLib.vcxproj @@ -355,13 +355,13 @@ - + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index 22aab3e6df5..ceb86a52481 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -713,6 +713,16 @@ namespace winrt::TerminalApp::implementation auto tabViewItem = newTabImpl->GetTabViewItem(); _tabView.TabItems().Append(tabViewItem); + // GH#6570 + // The TabView does not apply compact sizing to items added after Compact is enabled. + // By forcibly reapplying compact sizing every time we add a new tab, we'll make sure + // that it works. + // Workaround from https://github.com/microsoft/microsoft-ui-xaml/issues/2711 + if (_tabView.TabWidthMode() == MUX::Controls::TabViewWidthMode::Compact) + { + _tabView.UpdateLayout(); + _tabView.TabWidthMode(MUX::Controls::TabViewWidthMode::Compact); + } // Set this tab's icon to the icon from the user's profile const auto profile = _settings->FindProfile(profileGuid); diff --git a/src/cascadia/TerminalApp/dll/TerminalApp.vcxproj b/src/cascadia/TerminalApp/dll/TerminalApp.vcxproj index 49ccdf39099..8d8962cca79 100644 --- a/src/cascadia/TerminalApp/dll/TerminalApp.vcxproj +++ b/src/cascadia/TerminalApp/dll/TerminalApp.vcxproj @@ -78,13 +78,13 @@ - + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + diff --git a/src/cascadia/TerminalApp/packages.config b/src/cascadia/TerminalApp/packages.config index ff1e310ee51..1f023409c8d 100644 --- a/src/cascadia/TerminalApp/packages.config +++ b/src/cascadia/TerminalApp/packages.config @@ -1,6 +1,6 @@  - + diff --git a/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj b/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj index 358a5bfc457..395c76d9e8e 100644 --- a/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj +++ b/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj @@ -94,14 +94,14 @@ - + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + diff --git a/src/cascadia/WindowsTerminal/packages.config b/src/cascadia/WindowsTerminal/packages.config index 797852c2795..166f8861ffa 100644 --- a/src/cascadia/WindowsTerminal/packages.config +++ b/src/cascadia/WindowsTerminal/packages.config @@ -2,7 +2,7 @@ - + \ No newline at end of file diff --git a/src/cascadia/WindowsTerminalUniversal/WindowsTerminalUniversal.vcxproj b/src/cascadia/WindowsTerminalUniversal/WindowsTerminalUniversal.vcxproj index 35c303bd5d8..0a749357a56 100644 --- a/src/cascadia/WindowsTerminalUniversal/WindowsTerminalUniversal.vcxproj +++ b/src/cascadia/WindowsTerminalUniversal/WindowsTerminalUniversal.vcxproj @@ -154,7 +154,7 @@ - + @@ -162,7 +162,7 @@ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + diff --git a/src/cascadia/ut_app/TerminalApp.UnitTests.vcxproj b/src/cascadia/ut_app/TerminalApp.UnitTests.vcxproj index 2bb6093e8e5..868002a5fd2 100644 --- a/src/cascadia/ut_app/TerminalApp.UnitTests.vcxproj +++ b/src/cascadia/ut_app/TerminalApp.UnitTests.vcxproj @@ -98,7 +98,7 @@ x86 $(Platform) - <_MUXBinRoot>"$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.5.0-prerelease.200812001\runtimes\win10-$(Native-Platform)\native\" + <_MUXBinRoot>"$(OpenConsoleDir)packages\Microsoft.UI.Xaml.2.5.0-prerelease.200609001\runtimes\win10-$(Native-Platform)\native\" From b2cfd0adad0ee105a7c572a0bfe2d1aa174fac82 Mon Sep 17 00:00:00 2001 From: "Dustin L. Howett" Date: Tue, 8 Sep 2020 12:19:12 -0700 Subject: [PATCH 101/266] jumplist: prefer the app execution alias in %LOCALAPPDATA% (#7567) By setting the jumplist entries to launch `WindowsTerminal.exe` out of the package root, we've inadvertently made WindowsTerminalDev emit jump list entries that launch the _unpackaged_ version of Terminal. We can fix this by copying the code from the shell extension that determines which version of the executable to launch -- wt, wtd or WindowsTerminal -- depending on the context under which it was invoked. Fixes #7554 --- src/cascadia/TerminalApp/Jumplist.cpp | 66 +++++++++++++++++++++++++-- 1 file changed, 63 insertions(+), 3 deletions(-) diff --git a/src/cascadia/TerminalApp/Jumplist.cpp b/src/cascadia/TerminalApp/Jumplist.cpp index 625367c7410..9020ac35d30 100644 --- a/src/cascadia/TerminalApp/Jumplist.cpp +++ b/src/cascadia/TerminalApp/Jumplist.cpp @@ -17,6 +17,66 @@ DEFINE_PROPERTYKEY(PKEY_AppUserModel_DestListLogoUri, 0x9F4C2855, 0x9F79, 0x4B39 { 0x9F4C2855, 0x9F79, 0x4B39, 0xA8, 0xD0, 0xE1, 0xD4, 0x2D, 0xE1, 0xD5, 0xF3 }, 29 \ } +// Function Description: +// - Helper function for getting the path to the appropriate executable to use +// for this instance of the jumplist. For the dev build, it should be `wtd.exe`, +// but if we're preview or release, we want to make sure to get the correct +// `wt.exe` that corresponds to _us_. +// - If we're unpackaged, this needs to get us `WindowsTerminal.exe`, because +// the `wt*exe` alias won't have been installed for this install. +// Arguments: +// - +// Return Value: +// - the full path to the exe, one of `wt.exe`, `wtd.exe`, or `WindowsTerminal.exe`. +static std::wstring_view _getExePath() +{ + static constexpr std::wstring_view WtExe{ L"wt.exe" }; + static constexpr std::wstring_view WindowsTerminalExe{ L"WindowsTerminal.exe" }; + static constexpr std::wstring_view WtdExe{ L"wtd.exe" }; + + static constexpr std::wstring_view LocalAppDataAppsPath{ L"%LOCALAPPDATA%\\Microsoft\\WindowsApps\\" }; + + // use C++11 magic statics to make sure we only do this once. + static const std::wstring exePath = []() -> std::wstring { + // First, check a packaged location for the exe. If we've got a package + // family name, that means we're one of the packaged Dev build, packaged + // Release build, or packaged Preview build. + // + // If we're the preview or release build, there's no way of knowing if the + // `wt.exe` on the %PATH% is us or not. Fortunately, _our_ execution alias + // is located in "%LOCALAPPDATA%\Microsoft\WindowsApps\", _always_, so we can use that to look up the exe easier. + try + { + const auto package{ winrt::Windows::ApplicationModel::Package::Current() }; + const auto id{ package.Id() }; + const std::wstring pfn{ id.FamilyName() }; + const auto isDevPackage{ pfn.rfind(L"WindowsTerminalDev") == 0 }; + if (!pfn.empty()) + { + const std::filesystem::path windowsAppsPath{ wil::ExpandEnvironmentStringsW(LocalAppDataAppsPath.data()) }; + const std::filesystem::path wtPath{ windowsAppsPath / pfn / (isDevPackage ? WtdExe : WtExe) }; + return wtPath; + } + } + CATCH_LOG(); + + // If we're here, then we couldn't resolve our exe from the package. This + // means we're running unpackaged. We should just use the + // WindowsTerminal.exe that's sitting in the directory next to us. + try + { + std::filesystem::path module{ wil::GetModuleFileNameW(nullptr) }; + module.replace_filename(WindowsTerminalExe); + return module; + } + CATCH_LOG(); + + return std::wstring{ WtExe }; + }(); + return exePath; +} + // Method Description: // - Updates the items of the Jumplist based on the given settings. // Arguments: @@ -88,7 +148,7 @@ HRESULT Jumplist::UpdateJumplist(const TerminalApp::CascadiaSettings& settings) // - Creates a ShellLink object. Each item in a jumplist is a ShellLink, which is sort of // like a shortcut. It requires the path to the application (wt.exe), the arguments to pass, // and the path to the icon for the jumplist item. The path to the application isn't passed -// into this function, as we'll determine it with GetModuleFileName. +// into this function, as we'll determine it with _getExePath // Arguments: // - name: The name of the item displayed in the jumplist. // - path: The path to the icon for the jumplist item. @@ -105,8 +165,8 @@ HRESULT Jumplist::UpdateJumplist(const TerminalApp::CascadiaSettings& settings) { auto sh = winrt::create_instance(CLSID_ShellLink, CLSCTX_ALL); - std::filesystem::path module{ wil::GetModuleFileNameW(nullptr) }; - RETURN_IF_FAILED(sh->SetPath(module.c_str())); + const auto module{ _getExePath() }; + RETURN_IF_FAILED(sh->SetPath(module.data())); RETURN_IF_FAILED(sh->SetArguments(args.data())); PROPVARIANT titleProp; From c28efc3c4f8df78af9a4b4957cd4b9dc398b97a8 Mon Sep 17 00:00:00 2001 From: Casper Verhaar Date: Wed, 9 Sep 2020 02:13:53 +0200 Subject: [PATCH 102/266] Remove AcrylicOpacity from AzureCloudShellGenerator (#7573) Removed Acrylic Opacity from AzureCloudShellGenerator. ## PR Checklist * [x] Closes #7245 * [x] CLA signed * [x] I've discussed this with core contributors already --- src/cascadia/TerminalApp/AzureCloudShellGenerator.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/cascadia/TerminalApp/AzureCloudShellGenerator.cpp b/src/cascadia/TerminalApp/AzureCloudShellGenerator.cpp index 5a5fc7ba150..1c962370b44 100644 --- a/src/cascadia/TerminalApp/AzureCloudShellGenerator.cpp +++ b/src/cascadia/TerminalApp/AzureCloudShellGenerator.cpp @@ -38,8 +38,6 @@ std::vector AzureCloudShellGenerator::GenerateProfiles() azureCloudShellProfile.Commandline(L"Azure"); azureCloudShellProfile.StartingDirectory(DEFAULT_STARTING_DIRECTORY); azureCloudShellProfile.ColorSchemeName(L"Vintage"); - azureCloudShellProfile.AcrylicOpacity(0.6); - azureCloudShellProfile.UseAcrylic(true); azureCloudShellProfile.ConnectionType(AzureConnectionType); profiles.emplace_back(azureCloudShellProfile); } From c5cf7b817a272408bd816ab22b7b4d103ea13c38 Mon Sep 17 00:00:00 2001 From: Carlos Zamora Date: Wed, 9 Sep 2020 13:49:53 -0700 Subject: [PATCH 103/266] Make CascadiaSettings a WinRT object (#7457) CascadiaSettings is now a WinRT object in the TerminalApp project. ## References #7141 - CascadiaSettings is a settings object #885 - this new settings object will be moved to a new TerminalSettingsModel project This one _looks_ big, but most of it is really just propagating the changes to the tests. In fact, you can probably save yourself some time because the tests were about an hour of Find&Replace. `CascadiaSettings::GetCurrentAppSettings()` was only being used in Pane.cpp. So I ripped out the 3 lines of code and stuffed them in there. Follow-up work: - There's a few places in AppLogic where I `get_self` to be able to get the warnings out. This will go away in the next PR (wrapping up #885) ## Validation Steps Performed - [x] Tests passed - [X] Deployment succeeded Closes #7141 --- .../ColorSchemeTests.cpp | 94 +- .../LocalTests_TerminalApp/ProfileTests.cpp | 102 +- .../LocalTests_TerminalApp/SettingsTests.cpp | 1311 +++++++++-------- .../LocalTests_TerminalApp/TabTests.cpp | 20 +- .../TerminalApp/AppActionHandlers.cpp | 3 +- src/cascadia/TerminalApp/AppLogic.cpp | 53 +- src/cascadia/TerminalApp/AppLogic.h | 5 +- src/cascadia/TerminalApp/CascadiaSettings.cpp | 113 +- src/cascadia/TerminalApp/CascadiaSettings.h | 190 +-- src/cascadia/TerminalApp/CascadiaSettings.idl | 23 + .../CascadiaSettingsSerialization.cpp | 49 +- src/cascadia/TerminalApp/Command.cpp | 4 +- src/cascadia/TerminalApp/Command.h | 4 +- src/cascadia/TerminalApp/Jumplist.cpp | 6 +- src/cascadia/TerminalApp/Jumplist.h | 5 +- src/cascadia/TerminalApp/Pane.cpp | 4 +- .../TerminalApp/TerminalAppLib.vcxproj | 13 +- src/cascadia/TerminalApp/TerminalPage.cpp | 90 +- src/cascadia/TerminalApp/TerminalPage.h | 6 +- src/cascadia/ut_app/DynamicProfileTests.cpp | 428 +++--- 20 files changed, 1297 insertions(+), 1226 deletions(-) create mode 100644 src/cascadia/TerminalApp/CascadiaSettings.idl diff --git a/src/cascadia/LocalTests_TerminalApp/ColorSchemeTests.cpp b/src/cascadia/LocalTests_TerminalApp/ColorSchemeTests.cpp index e59d022f526..10e070db90a 100644 --- a/src/cascadia/LocalTests_TerminalApp/ColorSchemeTests.cpp +++ b/src/cascadia/LocalTests_TerminalApp/ColorSchemeTests.cpp @@ -193,96 +193,96 @@ namespace TerminalAppLocalTests const auto scheme2Json = VerifyParseSucceeded(scheme2String); const auto scheme3Json = VerifyParseSucceeded(scheme3String); - CascadiaSettings settings; + auto settings = winrt::make_self(); - VERIFY_ARE_EQUAL(0u, settings._globals->GetColorSchemes().Size()); - VERIFY_IS_NULL(settings._FindMatchingColorScheme(scheme0Json)); - VERIFY_IS_NULL(settings._FindMatchingColorScheme(scheme1Json)); - VERIFY_IS_NULL(settings._FindMatchingColorScheme(scheme2Json)); - VERIFY_IS_NULL(settings._FindMatchingColorScheme(scheme3Json)); + VERIFY_ARE_EQUAL(0u, settings->_globals->GetColorSchemes().Size()); + VERIFY_IS_NULL(settings->_FindMatchingColorScheme(scheme0Json)); + VERIFY_IS_NULL(settings->_FindMatchingColorScheme(scheme1Json)); + VERIFY_IS_NULL(settings->_FindMatchingColorScheme(scheme2Json)); + VERIFY_IS_NULL(settings->_FindMatchingColorScheme(scheme3Json)); - settings._LayerOrCreateColorScheme(scheme0Json); + settings->_LayerOrCreateColorScheme(scheme0Json); { - for (auto kv : settings._globals->GetColorSchemes()) + for (auto kv : settings->_globals->GetColorSchemes()) { Log::Comment(NoThrowString().Format( L"kv:%s->%s", kv.Key().data(), kv.Value().Name().data())); } - VERIFY_ARE_EQUAL(1u, settings._globals->GetColorSchemes().Size()); + VERIFY_ARE_EQUAL(1u, settings->_globals->GetColorSchemes().Size()); - VERIFY_IS_TRUE(settings._globals->GetColorSchemes().HasKey(L"scheme0")); - auto scheme0Proj = settings._globals->GetColorSchemes().Lookup(L"scheme0"); + VERIFY_IS_TRUE(settings->_globals->GetColorSchemes().HasKey(L"scheme0")); + auto scheme0Proj = settings->_globals->GetColorSchemes().Lookup(L"scheme0"); auto scheme0 = winrt::get_self(scheme0Proj); - VERIFY_IS_NOT_NULL(settings._FindMatchingColorScheme(scheme0Json)); - VERIFY_IS_NULL(settings._FindMatchingColorScheme(scheme1Json)); - VERIFY_IS_NOT_NULL(settings._FindMatchingColorScheme(scheme2Json)); - VERIFY_IS_NULL(settings._FindMatchingColorScheme(scheme3Json)); + VERIFY_IS_NOT_NULL(settings->_FindMatchingColorScheme(scheme0Json)); + VERIFY_IS_NULL(settings->_FindMatchingColorScheme(scheme1Json)); + VERIFY_IS_NOT_NULL(settings->_FindMatchingColorScheme(scheme2Json)); + VERIFY_IS_NULL(settings->_FindMatchingColorScheme(scheme3Json)); VERIFY_ARE_EQUAL(ARGB(0, 0, 0, 0), scheme0->_defaultForeground); VERIFY_ARE_EQUAL(ARGB(0, 1, 1, 1), scheme0->_defaultBackground); } - settings._LayerOrCreateColorScheme(scheme1Json); + settings->_LayerOrCreateColorScheme(scheme1Json); { - VERIFY_ARE_EQUAL(2u, settings._globals->GetColorSchemes().Size()); + VERIFY_ARE_EQUAL(2u, settings->_globals->GetColorSchemes().Size()); - VERIFY_IS_TRUE(settings._globals->GetColorSchemes().HasKey(L"scheme0")); - auto scheme0Proj = settings._globals->GetColorSchemes().Lookup(L"scheme0"); + VERIFY_IS_TRUE(settings->_globals->GetColorSchemes().HasKey(L"scheme0")); + auto scheme0Proj = settings->_globals->GetColorSchemes().Lookup(L"scheme0"); auto scheme0 = winrt::get_self(scheme0Proj); - VERIFY_IS_TRUE(settings._globals->GetColorSchemes().HasKey(L"scheme1")); - auto scheme1Proj = settings._globals->GetColorSchemes().Lookup(L"scheme1"); + VERIFY_IS_TRUE(settings->_globals->GetColorSchemes().HasKey(L"scheme1")); + auto scheme1Proj = settings->_globals->GetColorSchemes().Lookup(L"scheme1"); auto scheme1 = winrt::get_self(scheme1Proj); - VERIFY_IS_NOT_NULL(settings._FindMatchingColorScheme(scheme0Json)); - VERIFY_IS_NOT_NULL(settings._FindMatchingColorScheme(scheme1Json)); - VERIFY_IS_NOT_NULL(settings._FindMatchingColorScheme(scheme2Json)); - VERIFY_IS_NULL(settings._FindMatchingColorScheme(scheme3Json)); + VERIFY_IS_NOT_NULL(settings->_FindMatchingColorScheme(scheme0Json)); + VERIFY_IS_NOT_NULL(settings->_FindMatchingColorScheme(scheme1Json)); + VERIFY_IS_NOT_NULL(settings->_FindMatchingColorScheme(scheme2Json)); + VERIFY_IS_NULL(settings->_FindMatchingColorScheme(scheme3Json)); VERIFY_ARE_EQUAL(ARGB(0, 0, 0, 0), scheme0->_defaultForeground); VERIFY_ARE_EQUAL(ARGB(0, 1, 1, 1), scheme0->_defaultBackground); VERIFY_ARE_EQUAL(ARGB(0, 2, 2, 2), scheme1->_defaultForeground); VERIFY_ARE_EQUAL(ARGB(0, 3, 3, 3), scheme1->_defaultBackground); } - settings._LayerOrCreateColorScheme(scheme2Json); + settings->_LayerOrCreateColorScheme(scheme2Json); { - VERIFY_ARE_EQUAL(2u, settings._globals->GetColorSchemes().Size()); + VERIFY_ARE_EQUAL(2u, settings->_globals->GetColorSchemes().Size()); - VERIFY_IS_TRUE(settings._globals->GetColorSchemes().HasKey(L"scheme0")); - auto scheme0Proj = settings._globals->GetColorSchemes().Lookup(L"scheme0"); + VERIFY_IS_TRUE(settings->_globals->GetColorSchemes().HasKey(L"scheme0")); + auto scheme0Proj = settings->_globals->GetColorSchemes().Lookup(L"scheme0"); auto scheme0 = winrt::get_self(scheme0Proj); - VERIFY_IS_TRUE(settings._globals->GetColorSchemes().HasKey(L"scheme1")); - auto scheme1Proj = settings._globals->GetColorSchemes().Lookup(L"scheme1"); + VERIFY_IS_TRUE(settings->_globals->GetColorSchemes().HasKey(L"scheme1")); + auto scheme1Proj = settings->_globals->GetColorSchemes().Lookup(L"scheme1"); auto scheme1 = winrt::get_self(scheme1Proj); - VERIFY_IS_NOT_NULL(settings._FindMatchingColorScheme(scheme0Json)); - VERIFY_IS_NOT_NULL(settings._FindMatchingColorScheme(scheme1Json)); - VERIFY_IS_NOT_NULL(settings._FindMatchingColorScheme(scheme2Json)); - VERIFY_IS_NULL(settings._FindMatchingColorScheme(scheme3Json)); + VERIFY_IS_NOT_NULL(settings->_FindMatchingColorScheme(scheme0Json)); + VERIFY_IS_NOT_NULL(settings->_FindMatchingColorScheme(scheme1Json)); + VERIFY_IS_NOT_NULL(settings->_FindMatchingColorScheme(scheme2Json)); + VERIFY_IS_NULL(settings->_FindMatchingColorScheme(scheme3Json)); VERIFY_ARE_EQUAL(ARGB(0, 4, 4, 4), scheme0->_defaultForeground); VERIFY_ARE_EQUAL(ARGB(0, 5, 5, 5), scheme0->_defaultBackground); VERIFY_ARE_EQUAL(ARGB(0, 2, 2, 2), scheme1->_defaultForeground); VERIFY_ARE_EQUAL(ARGB(0, 3, 3, 3), scheme1->_defaultBackground); } - settings._LayerOrCreateColorScheme(scheme3Json); + settings->_LayerOrCreateColorScheme(scheme3Json); { - VERIFY_ARE_EQUAL(3u, settings._globals->GetColorSchemes().Size()); + VERIFY_ARE_EQUAL(3u, settings->_globals->GetColorSchemes().Size()); - VERIFY_IS_TRUE(settings._globals->GetColorSchemes().HasKey(L"scheme0")); - auto scheme0Proj = settings._globals->GetColorSchemes().Lookup(L"scheme0"); + VERIFY_IS_TRUE(settings->_globals->GetColorSchemes().HasKey(L"scheme0")); + auto scheme0Proj = settings->_globals->GetColorSchemes().Lookup(L"scheme0"); auto scheme0 = winrt::get_self(scheme0Proj); - VERIFY_IS_TRUE(settings._globals->GetColorSchemes().HasKey(L"scheme1")); - auto scheme1Proj = settings._globals->GetColorSchemes().Lookup(L"scheme1"); + VERIFY_IS_TRUE(settings->_globals->GetColorSchemes().HasKey(L"scheme1")); + auto scheme1Proj = settings->_globals->GetColorSchemes().Lookup(L"scheme1"); auto scheme1 = winrt::get_self(scheme1Proj); - VERIFY_IS_TRUE(settings._globals->GetColorSchemes().HasKey(L"")); - auto scheme2Proj = settings._globals->GetColorSchemes().Lookup(L""); + VERIFY_IS_TRUE(settings->_globals->GetColorSchemes().HasKey(L"")); + auto scheme2Proj = settings->_globals->GetColorSchemes().Lookup(L""); auto scheme2 = winrt::get_self(scheme2Proj); - VERIFY_IS_NOT_NULL(settings._FindMatchingColorScheme(scheme0Json)); - VERIFY_IS_NOT_NULL(settings._FindMatchingColorScheme(scheme1Json)); - VERIFY_IS_NOT_NULL(settings._FindMatchingColorScheme(scheme2Json)); - VERIFY_IS_NULL(settings._FindMatchingColorScheme(scheme3Json)); + VERIFY_IS_NOT_NULL(settings->_FindMatchingColorScheme(scheme0Json)); + VERIFY_IS_NOT_NULL(settings->_FindMatchingColorScheme(scheme1Json)); + VERIFY_IS_NOT_NULL(settings->_FindMatchingColorScheme(scheme2Json)); + VERIFY_IS_NULL(settings->_FindMatchingColorScheme(scheme3Json)); VERIFY_ARE_EQUAL(ARGB(0, 4, 4, 4), scheme0->_defaultForeground); VERIFY_ARE_EQUAL(ARGB(0, 5, 5, 5), scheme0->_defaultBackground); VERIFY_ARE_EQUAL(ARGB(0, 2, 2, 2), scheme1->_defaultForeground); diff --git a/src/cascadia/LocalTests_TerminalApp/ProfileTests.cpp b/src/cascadia/LocalTests_TerminalApp/ProfileTests.cpp index e3cf469f031..73517070af7 100644 --- a/src/cascadia/LocalTests_TerminalApp/ProfileTests.cpp +++ b/src/cascadia/LocalTests_TerminalApp/ProfileTests.cpp @@ -253,57 +253,57 @@ namespace TerminalAppLocalTests const auto profile3Json = VerifyParseSucceeded(profile3String); const auto profile4Json = VerifyParseSucceeded(profile4String); - CascadiaSettings settings; - - VERIFY_ARE_EQUAL(0u, settings._profiles.size()); - VERIFY_IS_NULL(settings._FindMatchingProfile(profile0Json)); - VERIFY_IS_NULL(settings._FindMatchingProfile(profile1Json)); - VERIFY_IS_NULL(settings._FindMatchingProfile(profile2Json)); - VERIFY_IS_NULL(settings._FindMatchingProfile(profile3Json)); - VERIFY_IS_NULL(settings._FindMatchingProfile(profile4Json)); - - settings._LayerOrCreateProfile(profile0Json); - VERIFY_ARE_EQUAL(1u, settings._profiles.size()); - VERIFY_IS_NOT_NULL(settings._FindMatchingProfile(profile0Json)); - VERIFY_IS_NULL(settings._FindMatchingProfile(profile1Json)); - VERIFY_IS_NULL(settings._FindMatchingProfile(profile2Json)); - VERIFY_IS_NOT_NULL(settings._FindMatchingProfile(profile3Json)); - VERIFY_IS_NOT_NULL(settings._FindMatchingProfile(profile4Json)); - - settings._LayerOrCreateProfile(profile1Json); - VERIFY_ARE_EQUAL(2u, settings._profiles.size()); - VERIFY_IS_NOT_NULL(settings._FindMatchingProfile(profile0Json)); - VERIFY_IS_NOT_NULL(settings._FindMatchingProfile(profile1Json)); - VERIFY_IS_NULL(settings._FindMatchingProfile(profile2Json)); - VERIFY_IS_NOT_NULL(settings._FindMatchingProfile(profile3Json)); - VERIFY_IS_NOT_NULL(settings._FindMatchingProfile(profile4Json)); - - settings._LayerOrCreateProfile(profile2Json); - VERIFY_ARE_EQUAL(3u, settings._profiles.size()); - VERIFY_IS_NOT_NULL(settings._FindMatchingProfile(profile0Json)); - VERIFY_IS_NOT_NULL(settings._FindMatchingProfile(profile1Json)); - VERIFY_IS_NOT_NULL(settings._FindMatchingProfile(profile2Json)); - VERIFY_IS_NOT_NULL(settings._FindMatchingProfile(profile3Json)); - VERIFY_IS_NOT_NULL(settings._FindMatchingProfile(profile4Json)); - VERIFY_ARE_EQUAL(L"profile0", settings._profiles.at(0).Name()); - - settings._LayerOrCreateProfile(profile3Json); - VERIFY_ARE_EQUAL(3u, settings._profiles.size()); - VERIFY_IS_NOT_NULL(settings._FindMatchingProfile(profile0Json)); - VERIFY_IS_NOT_NULL(settings._FindMatchingProfile(profile1Json)); - VERIFY_IS_NOT_NULL(settings._FindMatchingProfile(profile2Json)); - VERIFY_IS_NOT_NULL(settings._FindMatchingProfile(profile3Json)); - VERIFY_IS_NOT_NULL(settings._FindMatchingProfile(profile4Json)); - VERIFY_ARE_EQUAL(L"profile3", settings._profiles.at(0).Name()); - - settings._LayerOrCreateProfile(profile4Json); - VERIFY_ARE_EQUAL(3u, settings._profiles.size()); - VERIFY_IS_NOT_NULL(settings._FindMatchingProfile(profile0Json)); - VERIFY_IS_NOT_NULL(settings._FindMatchingProfile(profile1Json)); - VERIFY_IS_NOT_NULL(settings._FindMatchingProfile(profile2Json)); - VERIFY_IS_NOT_NULL(settings._FindMatchingProfile(profile3Json)); - VERIFY_IS_NOT_NULL(settings._FindMatchingProfile(profile4Json)); - VERIFY_ARE_EQUAL(L"profile4", settings._profiles.at(0).Name()); + auto settings = winrt::make_self(); + + VERIFY_ARE_EQUAL(0u, settings->_profiles.Size()); + VERIFY_IS_NULL(settings->_FindMatchingProfile(profile0Json)); + VERIFY_IS_NULL(settings->_FindMatchingProfile(profile1Json)); + VERIFY_IS_NULL(settings->_FindMatchingProfile(profile2Json)); + VERIFY_IS_NULL(settings->_FindMatchingProfile(profile3Json)); + VERIFY_IS_NULL(settings->_FindMatchingProfile(profile4Json)); + + settings->_LayerOrCreateProfile(profile0Json); + VERIFY_ARE_EQUAL(1u, settings->_profiles.Size()); + VERIFY_IS_NOT_NULL(settings->_FindMatchingProfile(profile0Json)); + VERIFY_IS_NULL(settings->_FindMatchingProfile(profile1Json)); + VERIFY_IS_NULL(settings->_FindMatchingProfile(profile2Json)); + VERIFY_IS_NOT_NULL(settings->_FindMatchingProfile(profile3Json)); + VERIFY_IS_NOT_NULL(settings->_FindMatchingProfile(profile4Json)); + + settings->_LayerOrCreateProfile(profile1Json); + VERIFY_ARE_EQUAL(2u, settings->_profiles.Size()); + VERIFY_IS_NOT_NULL(settings->_FindMatchingProfile(profile0Json)); + VERIFY_IS_NOT_NULL(settings->_FindMatchingProfile(profile1Json)); + VERIFY_IS_NULL(settings->_FindMatchingProfile(profile2Json)); + VERIFY_IS_NOT_NULL(settings->_FindMatchingProfile(profile3Json)); + VERIFY_IS_NOT_NULL(settings->_FindMatchingProfile(profile4Json)); + + settings->_LayerOrCreateProfile(profile2Json); + VERIFY_ARE_EQUAL(3u, settings->_profiles.Size()); + VERIFY_IS_NOT_NULL(settings->_FindMatchingProfile(profile0Json)); + VERIFY_IS_NOT_NULL(settings->_FindMatchingProfile(profile1Json)); + VERIFY_IS_NOT_NULL(settings->_FindMatchingProfile(profile2Json)); + VERIFY_IS_NOT_NULL(settings->_FindMatchingProfile(profile3Json)); + VERIFY_IS_NOT_NULL(settings->_FindMatchingProfile(profile4Json)); + VERIFY_ARE_EQUAL(L"profile0", settings->_profiles.GetAt(0).Name()); + + settings->_LayerOrCreateProfile(profile3Json); + VERIFY_ARE_EQUAL(3u, settings->_profiles.Size()); + VERIFY_IS_NOT_NULL(settings->_FindMatchingProfile(profile0Json)); + VERIFY_IS_NOT_NULL(settings->_FindMatchingProfile(profile1Json)); + VERIFY_IS_NOT_NULL(settings->_FindMatchingProfile(profile2Json)); + VERIFY_IS_NOT_NULL(settings->_FindMatchingProfile(profile3Json)); + VERIFY_IS_NOT_NULL(settings->_FindMatchingProfile(profile4Json)); + VERIFY_ARE_EQUAL(L"profile3", settings->_profiles.GetAt(0).Name()); + + settings->_LayerOrCreateProfile(profile4Json); + VERIFY_ARE_EQUAL(3u, settings->_profiles.Size()); + VERIFY_IS_NOT_NULL(settings->_FindMatchingProfile(profile0Json)); + VERIFY_IS_NOT_NULL(settings->_FindMatchingProfile(profile1Json)); + VERIFY_IS_NOT_NULL(settings->_FindMatchingProfile(profile2Json)); + VERIFY_IS_NOT_NULL(settings->_FindMatchingProfile(profile3Json)); + VERIFY_IS_NOT_NULL(settings->_FindMatchingProfile(profile4Json)); + VERIFY_ARE_EQUAL(L"profile4", settings->_profiles.GetAt(0).Name()); } } diff --git a/src/cascadia/LocalTests_TerminalApp/SettingsTests.cpp b/src/cascadia/LocalTests_TerminalApp/SettingsTests.cpp index 91c45987ce7..f317ba1fb35 100644 --- a/src/cascadia/LocalTests_TerminalApp/SettingsTests.cpp +++ b/src/cascadia/LocalTests_TerminalApp/SettingsTests.cpp @@ -165,13 +165,13 @@ namespace TerminalAppLocalTests { // Case 1: Good settings const auto settingsObject = VerifyParseSucceeded(settingsWithProfiles); - auto settings = CascadiaSettings::FromJson(settingsObject); + auto settings = implementation::CascadiaSettings::FromJson(settingsObject); settings->_ValidateProfilesExist(); } { // Case 2: Bad settings const auto settingsObject = VerifyParseSucceeded(settingsWithoutProfiles); - auto settings = CascadiaSettings::FromJson(settingsObject); + auto settings = implementation::CascadiaSettings::FromJson(settingsObject); bool caughtExpectedException = false; try { @@ -187,7 +187,7 @@ namespace TerminalAppLocalTests { // Case 3: Bad settings const auto settingsObject = VerifyParseSucceeded(settingsWithEmptyProfiles); - auto settings = CascadiaSettings::FromJson(settingsObject); + auto settings = implementation::CascadiaSettings::FromJson(settingsObject); bool caughtExpectedException = false; try { @@ -269,52 +269,52 @@ namespace TerminalAppLocalTests Log::Comment(NoThrowString().Format( L"Testing a pair of profiles with unique guids, and the defaultProfile is one of those guids")); const auto settingsObject = VerifyParseSucceeded(goodProfiles); - auto settings = CascadiaSettings::FromJson(settingsObject); + auto settings = implementation::CascadiaSettings::FromJson(settingsObject); settings->_ResolveDefaultProfile(); settings->_ValidateDefaultProfileExists(); VERIFY_ARE_EQUAL(static_cast(0), settings->_warnings.size()); - VERIFY_ARE_EQUAL(static_cast(2), settings->_profiles.size()); - VERIFY_ARE_EQUAL(settings->_globals->DefaultProfile(), settings->_profiles.at(0).Guid()); + VERIFY_ARE_EQUAL(static_cast(2), settings->_profiles.Size()); + VERIFY_ARE_EQUAL(settings->_globals->DefaultProfile(), settings->_profiles.GetAt(0).Guid()); } { // Case 2: Bad settings Log::Comment(NoThrowString().Format( L"Testing a pair of profiles with unique guids, but the defaultProfile is NOT one of those guids")); const auto settingsObject = VerifyParseSucceeded(badProfiles); - auto settings = CascadiaSettings::FromJson(settingsObject); + auto settings = implementation::CascadiaSettings::FromJson(settingsObject); settings->_ResolveDefaultProfile(); settings->_ValidateDefaultProfileExists(); VERIFY_ARE_EQUAL(static_cast(1), settings->_warnings.size()); VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::MissingDefaultProfile, settings->_warnings.at(0)); - VERIFY_ARE_EQUAL(static_cast(2), settings->_profiles.size()); - VERIFY_ARE_EQUAL(settings->_globals->DefaultProfile(), settings->_profiles.at(0).Guid()); + VERIFY_ARE_EQUAL(static_cast(2), settings->_profiles.Size()); + VERIFY_ARE_EQUAL(settings->_globals->DefaultProfile(), settings->_profiles.GetAt(0).Guid()); } { // Case 2: Bad settings Log::Comment(NoThrowString().Format( L"Testing a pair of profiles with unique guids, and no defaultProfile at all")); const auto settingsObject = VerifyParseSucceeded(badProfiles); - auto settings = CascadiaSettings::FromJson(settingsObject); + auto settings = implementation::CascadiaSettings::FromJson(settingsObject); settings->_ResolveDefaultProfile(); settings->_ValidateDefaultProfileExists(); VERIFY_ARE_EQUAL(static_cast(1), settings->_warnings.size()); VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::MissingDefaultProfile, settings->_warnings.at(0)); - VERIFY_ARE_EQUAL(static_cast(2), settings->_profiles.size()); - VERIFY_ARE_EQUAL(settings->_globals->DefaultProfile(), settings->_profiles.at(0).Guid()); + VERIFY_ARE_EQUAL(static_cast(2), settings->_profiles.Size()); + VERIFY_ARE_EQUAL(settings->_globals->DefaultProfile(), settings->_profiles.GetAt(0).Guid()); } { // Case 4: Good settings, default profile is a string Log::Comment(NoThrowString().Format( L"Testing a pair of profiles with unique guids, and the defaultProfile is one of the profile names")); const auto settingsObject = VerifyParseSucceeded(goodProfilesSpecifiedByName); - auto settings = CascadiaSettings::FromJson(settingsObject); + auto settings = implementation::CascadiaSettings::FromJson(settingsObject); settings->_ResolveDefaultProfile(); settings->_ValidateDefaultProfileExists(); VERIFY_ARE_EQUAL(static_cast(0), settings->_warnings.size()); - VERIFY_ARE_EQUAL(static_cast(2), settings->_profiles.size()); - VERIFY_ARE_EQUAL(settings->_globals->DefaultProfile(), settings->_profiles.at(1).Guid()); + VERIFY_ARE_EQUAL(static_cast(2), settings->_profiles.Size()); + VERIFY_ARE_EQUAL(settings->_globals->DefaultProfile(), settings->_profiles.GetAt(1).Guid()); } } @@ -401,56 +401,56 @@ namespace TerminalAppLocalTests Log::Comment(NoThrowString().Format( L"Testing a pair of profiles with unique guids")); - CascadiaSettings settings; - settings._profiles.push_back(profile0); - settings._profiles.push_back(profile1); + auto settings = winrt::make_self(); + settings->_profiles.Append(profile0); + settings->_profiles.Append(profile1); - settings._ValidateNoDuplicateProfiles(); + settings->_ValidateNoDuplicateProfiles(); - VERIFY_ARE_EQUAL(static_cast(0), settings._warnings.size()); - VERIFY_ARE_EQUAL(static_cast(2), settings._profiles.size()); + VERIFY_ARE_EQUAL(static_cast(0), settings->_warnings.size()); + VERIFY_ARE_EQUAL(static_cast(2), settings->_profiles.Size()); } { // Case 2: Bad settings Log::Comment(NoThrowString().Format( L"Testing a pair of profiles with the same guid")); - CascadiaSettings settings; - settings._profiles.push_back(profile2); - settings._profiles.push_back(profile3); + auto settings = winrt::make_self(); + settings->_profiles.Append(profile2); + settings->_profiles.Append(profile3); - settings._ValidateNoDuplicateProfiles(); + settings->_ValidateNoDuplicateProfiles(); - VERIFY_ARE_EQUAL(static_cast(1), settings._warnings.size()); - VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::DuplicateProfile, settings._warnings.at(0)); + VERIFY_ARE_EQUAL(static_cast(1), settings->_warnings.size()); + VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::DuplicateProfile, settings->_warnings.at(0)); - VERIFY_ARE_EQUAL(static_cast(1), settings._profiles.size()); - VERIFY_ARE_EQUAL(L"profile2", settings._profiles.at(0).Name()); + VERIFY_ARE_EQUAL(static_cast(1), settings->_profiles.Size()); + VERIFY_ARE_EQUAL(L"profile2", settings->_profiles.GetAt(0).Name()); } { // Case 3: Very bad settings Log::Comment(NoThrowString().Format( L"Testing a set of profiles, many of which with duplicated guids")); - CascadiaSettings settings; - settings._profiles.push_back(profile0); - settings._profiles.push_back(profile1); - settings._profiles.push_back(profile2); - settings._profiles.push_back(profile3); - settings._profiles.push_back(profile4); - settings._profiles.push_back(profile5); - settings._profiles.push_back(profile6); + auto settings = winrt::make_self(); + settings->_profiles.Append(profile0); + settings->_profiles.Append(profile1); + settings->_profiles.Append(profile2); + settings->_profiles.Append(profile3); + settings->_profiles.Append(profile4); + settings->_profiles.Append(profile5); + settings->_profiles.Append(profile6); - settings._ValidateNoDuplicateProfiles(); + settings->_ValidateNoDuplicateProfiles(); - VERIFY_ARE_EQUAL(static_cast(1), settings._warnings.size()); - VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::DuplicateProfile, settings._warnings.at(0)); + VERIFY_ARE_EQUAL(static_cast(1), settings->_warnings.size()); + VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::DuplicateProfile, settings->_warnings.at(0)); - VERIFY_ARE_EQUAL(static_cast(4), settings._profiles.size()); - VERIFY_ARE_EQUAL(L"profile0", settings._profiles.at(0).Name()); - VERIFY_ARE_EQUAL(L"profile1", settings._profiles.at(1).Name()); - VERIFY_ARE_EQUAL(L"profile4", settings._profiles.at(2).Name()); - VERIFY_ARE_EQUAL(L"profile6", settings._profiles.at(3).Name()); + VERIFY_ARE_EQUAL(static_cast(4), settings->_profiles.Size()); + VERIFY_ARE_EQUAL(L"profile0", settings->_profiles.GetAt(0).Name()); + VERIFY_ARE_EQUAL(L"profile1", settings->_profiles.GetAt(1).Name()); + VERIFY_ARE_EQUAL(L"profile4", settings->_profiles.GetAt(2).Name()); + VERIFY_ARE_EQUAL(L"profile6", settings->_profiles.GetAt(3).Name()); } } @@ -483,10 +483,10 @@ namespace TerminalAppLocalTests Log::Comment(NoThrowString().Format( L"Testing a pair of profiles with the same guid")); const auto settingsObject = VerifyParseSucceeded(badProfiles); - auto settings = CascadiaSettings::FromJson(settingsObject); + auto settings = implementation::CascadiaSettings::FromJson(settingsObject); - settings->_profiles.push_back(profile4); - settings->_profiles.push_back(profile5); + settings->_profiles.Append(profile4); + settings->_profiles.Append(profile5); settings->_ValidateSettings(); @@ -495,11 +495,11 @@ namespace TerminalAppLocalTests VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::MissingDefaultProfile, settings->_warnings.at(1)); VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::UnknownColorScheme, settings->_warnings.at(2)); - VERIFY_ARE_EQUAL(3u, settings->_profiles.size()); - VERIFY_ARE_EQUAL(settings->_globals->DefaultProfile(), settings->_profiles.at(0).Guid()); - VERIFY_IS_TRUE(settings->_profiles.at(0).HasGuid()); - VERIFY_IS_TRUE(settings->_profiles.at(1).HasGuid()); - VERIFY_IS_TRUE(settings->_profiles.at(2).HasGuid()); + VERIFY_ARE_EQUAL(3u, settings->_profiles.Size()); + VERIFY_ARE_EQUAL(settings->_globals->DefaultProfile(), settings->_profiles.GetAt(0).Guid()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(0).HasGuid()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(1).HasGuid()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(2).HasGuid()); } void SettingsTests::LayerGlobalProperties() @@ -519,19 +519,19 @@ namespace TerminalAppLocalTests const auto settings0Json = VerifyParseSucceeded(settings0String); const auto settings1Json = VerifyParseSucceeded(settings1String); - CascadiaSettings settings; + auto settings = winrt::make_self(); - settings.LayerJson(settings0Json); - VERIFY_ARE_EQUAL(true, settings._globals->AlwaysShowTabs()); - VERIFY_ARE_EQUAL(120, settings._globals->InitialCols()); - VERIFY_ARE_EQUAL(30, settings._globals->InitialRows()); - VERIFY_ARE_EQUAL(true, settings._globals->ShowTabsInTitlebar()); + settings->LayerJson(settings0Json); + VERIFY_ARE_EQUAL(true, settings->_globals->AlwaysShowTabs()); + VERIFY_ARE_EQUAL(120, settings->_globals->InitialCols()); + VERIFY_ARE_EQUAL(30, settings->_globals->InitialRows()); + VERIFY_ARE_EQUAL(true, settings->_globals->ShowTabsInTitlebar()); - settings.LayerJson(settings1Json); - VERIFY_ARE_EQUAL(true, settings._globals->AlwaysShowTabs()); - VERIFY_ARE_EQUAL(240, settings._globals->InitialCols()); - VERIFY_ARE_EQUAL(60, settings._globals->InitialRows()); - VERIFY_ARE_EQUAL(false, settings._globals->ShowTabsInTitlebar()); + settings->LayerJson(settings1Json); + VERIFY_ARE_EQUAL(true, settings->_globals->AlwaysShowTabs()); + VERIFY_ARE_EQUAL(240, settings->_globals->InitialCols()); + VERIFY_ARE_EQUAL(60, settings->_globals->InitialRows()); + VERIFY_ARE_EQUAL(false, settings->_globals->ShowTabsInTitlebar()); } void SettingsTests::ValidateProfileOrdering() @@ -587,48 +587,48 @@ namespace TerminalAppLocalTests L"Case 1: Simple swapping of the ordering. The user has the " L"default profiles in the opposite order of the default ordering.")); - CascadiaSettings settings; - settings._ParseJsonString(defaultProfilesString, true); - settings.LayerJson(settings._defaultSettings); - VERIFY_ARE_EQUAL(2u, settings._profiles.size()); - VERIFY_ARE_EQUAL(L"profile2", settings._profiles.at(0).Name()); - VERIFY_ARE_EQUAL(L"profile3", settings._profiles.at(1).Name()); - - settings._ParseJsonString(userProfiles0String, false); - settings.LayerJson(settings._userSettings); - VERIFY_ARE_EQUAL(2u, settings._profiles.size()); - VERIFY_ARE_EQUAL(L"profile1", settings._profiles.at(0).Name()); - VERIFY_ARE_EQUAL(L"profile0", settings._profiles.at(1).Name()); - - settings._ReorderProfilesToMatchUserSettingsOrder(); - VERIFY_ARE_EQUAL(2u, settings._profiles.size()); - VERIFY_ARE_EQUAL(L"profile0", settings._profiles.at(0).Name()); - VERIFY_ARE_EQUAL(L"profile1", settings._profiles.at(1).Name()); + auto settings = winrt::make_self(); + settings->_ParseJsonString(defaultProfilesString, true); + settings->LayerJson(settings->_defaultSettings); + VERIFY_ARE_EQUAL(2u, settings->_profiles.Size()); + VERIFY_ARE_EQUAL(L"profile2", settings->_profiles.GetAt(0).Name()); + VERIFY_ARE_EQUAL(L"profile3", settings->_profiles.GetAt(1).Name()); + + settings->_ParseJsonString(userProfiles0String, false); + settings->LayerJson(settings->_userSettings); + VERIFY_ARE_EQUAL(2u, settings->_profiles.Size()); + VERIFY_ARE_EQUAL(L"profile1", settings->_profiles.GetAt(0).Name()); + VERIFY_ARE_EQUAL(L"profile0", settings->_profiles.GetAt(1).Name()); + + settings->_ReorderProfilesToMatchUserSettingsOrder(); + VERIFY_ARE_EQUAL(2u, settings->_profiles.Size()); + VERIFY_ARE_EQUAL(L"profile0", settings->_profiles.GetAt(0).Name()); + VERIFY_ARE_EQUAL(L"profile1", settings->_profiles.GetAt(1).Name()); } { Log::Comment(NoThrowString().Format( L"Case 2: Make sure all the user's profiles appear before the defaults.")); - CascadiaSettings settings; - settings._ParseJsonString(defaultProfilesString, true); - settings.LayerJson(settings._defaultSettings); - VERIFY_ARE_EQUAL(2u, settings._profiles.size()); - VERIFY_ARE_EQUAL(L"profile2", settings._profiles.at(0).Name()); - VERIFY_ARE_EQUAL(L"profile3", settings._profiles.at(1).Name()); - - settings._ParseJsonString(userProfiles1String, false); - settings.LayerJson(settings._userSettings); - VERIFY_ARE_EQUAL(3u, settings._profiles.size()); - VERIFY_ARE_EQUAL(L"profile2", settings._profiles.at(0).Name()); - VERIFY_ARE_EQUAL(L"profile4", settings._profiles.at(1).Name()); - VERIFY_ARE_EQUAL(L"profile5", settings._profiles.at(2).Name()); - - settings._ReorderProfilesToMatchUserSettingsOrder(); - VERIFY_ARE_EQUAL(3u, settings._profiles.size()); - VERIFY_ARE_EQUAL(L"profile4", settings._profiles.at(0).Name()); - VERIFY_ARE_EQUAL(L"profile5", settings._profiles.at(1).Name()); - VERIFY_ARE_EQUAL(L"profile2", settings._profiles.at(2).Name()); + auto settings = winrt::make_self(); + settings->_ParseJsonString(defaultProfilesString, true); + settings->LayerJson(settings->_defaultSettings); + VERIFY_ARE_EQUAL(2u, settings->_profiles.Size()); + VERIFY_ARE_EQUAL(L"profile2", settings->_profiles.GetAt(0).Name()); + VERIFY_ARE_EQUAL(L"profile3", settings->_profiles.GetAt(1).Name()); + + settings->_ParseJsonString(userProfiles1String, false); + settings->LayerJson(settings->_userSettings); + VERIFY_ARE_EQUAL(3u, settings->_profiles.Size()); + VERIFY_ARE_EQUAL(L"profile2", settings->_profiles.GetAt(0).Name()); + VERIFY_ARE_EQUAL(L"profile4", settings->_profiles.GetAt(1).Name()); + VERIFY_ARE_EQUAL(L"profile5", settings->_profiles.GetAt(2).Name()); + + settings->_ReorderProfilesToMatchUserSettingsOrder(); + VERIFY_ARE_EQUAL(3u, settings->_profiles.Size()); + VERIFY_ARE_EQUAL(L"profile4", settings->_profiles.GetAt(0).Name()); + VERIFY_ARE_EQUAL(L"profile5", settings->_profiles.GetAt(1).Name()); + VERIFY_ARE_EQUAL(L"profile2", settings->_profiles.GetAt(2).Name()); } } @@ -688,59 +688,59 @@ namespace TerminalAppLocalTests const auto defaultProfilesJson = VerifyParseSucceeded(defaultProfilesString); { - CascadiaSettings settings; - settings._ParseJsonString(defaultProfilesString, true); - settings.LayerJson(settings._defaultSettings); - VERIFY_ARE_EQUAL(2u, settings._profiles.size()); - VERIFY_ARE_EQUAL(L"profile2", settings._profiles.at(0).Name()); - VERIFY_ARE_EQUAL(L"profile3", settings._profiles.at(1).Name()); - VERIFY_ARE_EQUAL(false, settings._profiles.at(0).Hidden()); - VERIFY_ARE_EQUAL(false, settings._profiles.at(1).Hidden()); - - settings._ParseJsonString(userProfiles0String, false); - settings.LayerJson(settings._userSettings); - VERIFY_ARE_EQUAL(2u, settings._profiles.size()); - VERIFY_ARE_EQUAL(L"profile1", settings._profiles.at(0).Name()); - VERIFY_ARE_EQUAL(L"profile0", settings._profiles.at(1).Name()); - VERIFY_ARE_EQUAL(false, settings._profiles.at(0).Hidden()); - VERIFY_ARE_EQUAL(true, settings._profiles.at(1).Hidden()); - - settings._ReorderProfilesToMatchUserSettingsOrder(); - settings._RemoveHiddenProfiles(); - VERIFY_ARE_EQUAL(1u, settings._profiles.size()); - VERIFY_ARE_EQUAL(L"profile1", settings._profiles.at(0).Name()); - VERIFY_ARE_EQUAL(false, settings._profiles.at(0).Hidden()); - } - - { - CascadiaSettings settings; - settings._ParseJsonString(defaultProfilesString, true); - settings.LayerJson(settings._defaultSettings); - VERIFY_ARE_EQUAL(2u, settings._profiles.size()); - VERIFY_ARE_EQUAL(L"profile2", settings._profiles.at(0).Name()); - VERIFY_ARE_EQUAL(L"profile3", settings._profiles.at(1).Name()); - VERIFY_ARE_EQUAL(false, settings._profiles.at(0).Hidden()); - VERIFY_ARE_EQUAL(false, settings._profiles.at(1).Hidden()); - - settings._ParseJsonString(userProfiles1String, false); - settings.LayerJson(settings._userSettings); - VERIFY_ARE_EQUAL(4u, settings._profiles.size()); - VERIFY_ARE_EQUAL(L"profile2", settings._profiles.at(0).Name()); - VERIFY_ARE_EQUAL(L"profile4", settings._profiles.at(1).Name()); - VERIFY_ARE_EQUAL(L"profile5", settings._profiles.at(2).Name()); - VERIFY_ARE_EQUAL(L"profile6", settings._profiles.at(3).Name()); - VERIFY_ARE_EQUAL(false, settings._profiles.at(0).Hidden()); - VERIFY_ARE_EQUAL(true, settings._profiles.at(1).Hidden()); - VERIFY_ARE_EQUAL(false, settings._profiles.at(2).Hidden()); - VERIFY_ARE_EQUAL(true, settings._profiles.at(3).Hidden()); - - settings._ReorderProfilesToMatchUserSettingsOrder(); - settings._RemoveHiddenProfiles(); - VERIFY_ARE_EQUAL(2u, settings._profiles.size()); - VERIFY_ARE_EQUAL(L"profile5", settings._profiles.at(0).Name()); - VERIFY_ARE_EQUAL(L"profile2", settings._profiles.at(1).Name()); - VERIFY_ARE_EQUAL(false, settings._profiles.at(0).Hidden()); - VERIFY_ARE_EQUAL(false, settings._profiles.at(1).Hidden()); + auto settings = winrt::make_self(); + settings->_ParseJsonString(defaultProfilesString, true); + settings->LayerJson(settings->_defaultSettings); + VERIFY_ARE_EQUAL(2u, settings->_profiles.Size()); + VERIFY_ARE_EQUAL(L"profile2", settings->_profiles.GetAt(0).Name()); + VERIFY_ARE_EQUAL(L"profile3", settings->_profiles.GetAt(1).Name()); + VERIFY_ARE_EQUAL(false, settings->_profiles.GetAt(0).Hidden()); + VERIFY_ARE_EQUAL(false, settings->_profiles.GetAt(1).Hidden()); + + settings->_ParseJsonString(userProfiles0String, false); + settings->LayerJson(settings->_userSettings); + VERIFY_ARE_EQUAL(2u, settings->_profiles.Size()); + VERIFY_ARE_EQUAL(L"profile1", settings->_profiles.GetAt(0).Name()); + VERIFY_ARE_EQUAL(L"profile0", settings->_profiles.GetAt(1).Name()); + VERIFY_ARE_EQUAL(false, settings->_profiles.GetAt(0).Hidden()); + VERIFY_ARE_EQUAL(true, settings->_profiles.GetAt(1).Hidden()); + + settings->_ReorderProfilesToMatchUserSettingsOrder(); + settings->_RemoveHiddenProfiles(); + VERIFY_ARE_EQUAL(1u, settings->_profiles.Size()); + VERIFY_ARE_EQUAL(L"profile1", settings->_profiles.GetAt(0).Name()); + VERIFY_ARE_EQUAL(false, settings->_profiles.GetAt(0).Hidden()); + } + + { + auto settings = winrt::make_self(); + settings->_ParseJsonString(defaultProfilesString, true); + settings->LayerJson(settings->_defaultSettings); + VERIFY_ARE_EQUAL(2u, settings->_profiles.Size()); + VERIFY_ARE_EQUAL(L"profile2", settings->_profiles.GetAt(0).Name()); + VERIFY_ARE_EQUAL(L"profile3", settings->_profiles.GetAt(1).Name()); + VERIFY_ARE_EQUAL(false, settings->_profiles.GetAt(0).Hidden()); + VERIFY_ARE_EQUAL(false, settings->_profiles.GetAt(1).Hidden()); + + settings->_ParseJsonString(userProfiles1String, false); + settings->LayerJson(settings->_userSettings); + VERIFY_ARE_EQUAL(4u, settings->_profiles.Size()); + VERIFY_ARE_EQUAL(L"profile2", settings->_profiles.GetAt(0).Name()); + VERIFY_ARE_EQUAL(L"profile4", settings->_profiles.GetAt(1).Name()); + VERIFY_ARE_EQUAL(L"profile5", settings->_profiles.GetAt(2).Name()); + VERIFY_ARE_EQUAL(L"profile6", settings->_profiles.GetAt(3).Name()); + VERIFY_ARE_EQUAL(false, settings->_profiles.GetAt(0).Hidden()); + VERIFY_ARE_EQUAL(true, settings->_profiles.GetAt(1).Hidden()); + VERIFY_ARE_EQUAL(false, settings->_profiles.GetAt(2).Hidden()); + VERIFY_ARE_EQUAL(true, settings->_profiles.GetAt(3).Hidden()); + + settings->_ReorderProfilesToMatchUserSettingsOrder(); + settings->_RemoveHiddenProfiles(); + VERIFY_ARE_EQUAL(2u, settings->_profiles.Size()); + VERIFY_ARE_EQUAL(L"profile5", settings->_profiles.GetAt(0).Name()); + VERIFY_ARE_EQUAL(L"profile2", settings->_profiles.GetAt(1).Name()); + VERIFY_ARE_EQUAL(false, settings->_profiles.GetAt(0).Hidden()); + VERIFY_ARE_EQUAL(false, settings->_profiles.GetAt(1).Hidden()); } } @@ -801,42 +801,42 @@ namespace TerminalAppLocalTests VERIFY_ARE_EQUAL(profile3->Guid(), nullGuid); VERIFY_ARE_EQUAL(profile4->Guid(), cmdGuid); - CascadiaSettings settings; - settings._profiles.emplace_back(profile0.as()); - settings._profiles.emplace_back(profile1.as()); - settings._profiles.emplace_back(profile2.as()); - settings._profiles.emplace_back(profile3.as()); - settings._profiles.emplace_back(profile4.as()); - settings._profiles.emplace_back(profile5.as()); - - settings._ValidateProfilesHaveGuid(); - VERIFY_IS_TRUE(settings._profiles.at(0).HasGuid()); - VERIFY_IS_TRUE(settings._profiles.at(1).HasGuid()); - VERIFY_IS_TRUE(settings._profiles.at(2).HasGuid()); - VERIFY_IS_TRUE(settings._profiles.at(3).HasGuid()); - VERIFY_IS_TRUE(settings._profiles.at(4).HasGuid()); - VERIFY_IS_TRUE(settings._profiles.at(5).HasGuid()); - - VERIFY_ARE_NOT_EQUAL(settings._profiles.at(0).Guid(), nullGuid); - VERIFY_ARE_NOT_EQUAL(settings._profiles.at(1).Guid(), nullGuid); - VERIFY_ARE_NOT_EQUAL(settings._profiles.at(2).Guid(), nullGuid); - VERIFY_ARE_EQUAL(settings._profiles.at(3).Guid(), nullGuid); - VERIFY_ARE_NOT_EQUAL(settings._profiles.at(4).Guid(), nullGuid); - VERIFY_ARE_NOT_EQUAL(settings._profiles.at(5).Guid(), nullGuid); - - VERIFY_ARE_NOT_EQUAL(settings._profiles.at(0).Guid(), cmdGuid); - VERIFY_ARE_NOT_EQUAL(settings._profiles.at(1).Guid(), cmdGuid); - VERIFY_ARE_NOT_EQUAL(settings._profiles.at(2).Guid(), cmdGuid); - VERIFY_ARE_NOT_EQUAL(settings._profiles.at(3).Guid(), cmdGuid); - VERIFY_ARE_EQUAL(settings._profiles.at(4).Guid(), cmdGuid); - VERIFY_ARE_NOT_EQUAL(settings._profiles.at(5).Guid(), cmdGuid); - - VERIFY_ARE_NOT_EQUAL(settings._profiles.at(0).Guid(), settings._profiles.at(2).Guid()); - VERIFY_ARE_NOT_EQUAL(settings._profiles.at(1).Guid(), settings._profiles.at(2).Guid()); - VERIFY_ARE_EQUAL(settings._profiles.at(2).Guid(), settings._profiles.at(2).Guid()); - VERIFY_ARE_NOT_EQUAL(settings._profiles.at(3).Guid(), settings._profiles.at(2).Guid()); - VERIFY_ARE_NOT_EQUAL(settings._profiles.at(4).Guid(), settings._profiles.at(2).Guid()); - VERIFY_ARE_EQUAL(settings._profiles.at(5).Guid(), settings._profiles.at(2).Guid()); + auto settings = winrt::make_self(); + settings->_profiles.Append(*profile0); + settings->_profiles.Append(*profile1); + settings->_profiles.Append(*profile2); + settings->_profiles.Append(*profile3); + settings->_profiles.Append(*profile4); + settings->_profiles.Append(*profile5); + + settings->_ValidateProfilesHaveGuid(); + VERIFY_IS_TRUE(settings->_profiles.GetAt(0).HasGuid()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(1).HasGuid()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(2).HasGuid()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(3).HasGuid()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(4).HasGuid()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(5).HasGuid()); + + VERIFY_ARE_NOT_EQUAL(settings->_profiles.GetAt(0).Guid(), nullGuid); + VERIFY_ARE_NOT_EQUAL(settings->_profiles.GetAt(1).Guid(), nullGuid); + VERIFY_ARE_NOT_EQUAL(settings->_profiles.GetAt(2).Guid(), nullGuid); + VERIFY_ARE_EQUAL(settings->_profiles.GetAt(3).Guid(), nullGuid); + VERIFY_ARE_NOT_EQUAL(settings->_profiles.GetAt(4).Guid(), nullGuid); + VERIFY_ARE_NOT_EQUAL(settings->_profiles.GetAt(5).Guid(), nullGuid); + + VERIFY_ARE_NOT_EQUAL(settings->_profiles.GetAt(0).Guid(), cmdGuid); + VERIFY_ARE_NOT_EQUAL(settings->_profiles.GetAt(1).Guid(), cmdGuid); + VERIFY_ARE_NOT_EQUAL(settings->_profiles.GetAt(2).Guid(), cmdGuid); + VERIFY_ARE_NOT_EQUAL(settings->_profiles.GetAt(3).Guid(), cmdGuid); + VERIFY_ARE_EQUAL(settings->_profiles.GetAt(4).Guid(), cmdGuid); + VERIFY_ARE_NOT_EQUAL(settings->_profiles.GetAt(5).Guid(), cmdGuid); + + VERIFY_ARE_NOT_EQUAL(settings->_profiles.GetAt(0).Guid(), settings->_profiles.GetAt(2).Guid()); + VERIFY_ARE_NOT_EQUAL(settings->_profiles.GetAt(1).Guid(), settings->_profiles.GetAt(2).Guid()); + VERIFY_ARE_EQUAL(settings->_profiles.GetAt(2).Guid(), settings->_profiles.GetAt(2).Guid()); + VERIFY_ARE_NOT_EQUAL(settings->_profiles.GetAt(3).Guid(), settings->_profiles.GetAt(2).Guid()); + VERIFY_ARE_NOT_EQUAL(settings->_profiles.GetAt(4).Guid(), settings->_profiles.GetAt(2).Guid()); + VERIFY_ARE_EQUAL(settings->_profiles.GetAt(5).Guid(), settings->_profiles.GetAt(2).Guid()); } void SettingsTests::GeneratedGuidRoundtrips() @@ -860,19 +860,19 @@ namespace TerminalAppLocalTests VERIFY_IS_FALSE(profile0->HasGuid()); VERIFY_IS_FALSE(profile1->HasGuid()); - CascadiaSettings settings; - settings._profiles.emplace_back(profile1.as()); - settings._ValidateProfilesHaveGuid(); + auto settings = winrt::make_self(); + settings->_profiles.Append(*profile1); + settings->_ValidateProfilesHaveGuid(); - VERIFY_IS_TRUE(settings._profiles.at(0).HasGuid()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(0).HasGuid()); - const auto profileImpl = winrt::get_self(settings._profiles.at(0)); + const auto profileImpl = winrt::get_self(settings->_profiles.GetAt(0)); const auto serialized1Profile = profileImpl->GenerateStub(); const auto profile2 = implementation::Profile::FromJson(serialized1Profile); - VERIFY_IS_TRUE(settings._profiles.at(0).HasGuid()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(0).HasGuid()); VERIFY_IS_TRUE(profile2->HasGuid()); - VERIFY_ARE_EQUAL(settings._profiles.at(0).Guid(), profile2->Guid()); + VERIFY_ARE_EQUAL(settings->_profiles.GetAt(0).Guid(), profile2->Guid()); } void SettingsTests::TestAllValidationsWithNullGuids() @@ -896,19 +896,19 @@ namespace TerminalAppLocalTests const auto settings0Json = VerifyParseSucceeded(settings0String); - CascadiaSettings settings; - settings._ParseJsonString(settings0String, false); - settings.LayerJson(settings._userSettings); + auto settings = winrt::make_self(); + settings->_ParseJsonString(settings0String, false); + settings->LayerJson(settings->_userSettings); - VERIFY_ARE_EQUAL(2u, settings._profiles.size()); - VERIFY_IS_TRUE(settings._profiles.at(0).HasGuid()); - VERIFY_IS_FALSE(settings._profiles.at(1).HasGuid()); + VERIFY_ARE_EQUAL(2u, settings->_profiles.Size()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(0).HasGuid()); + VERIFY_IS_FALSE(settings->_profiles.GetAt(1).HasGuid()); - settings._ValidateSettings(); - VERIFY_ARE_EQUAL(0u, settings._warnings.size()); - VERIFY_ARE_EQUAL(2u, settings._profiles.size()); - VERIFY_IS_TRUE(settings._profiles.at(0).HasGuid()); - VERIFY_IS_TRUE(settings._profiles.at(1).HasGuid()); + settings->_ValidateSettings(); + VERIFY_ARE_EQUAL(0u, settings->_warnings.size()); + VERIFY_ARE_EQUAL(2u, settings->_profiles.Size()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(0).HasGuid()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(1).HasGuid()); } void SettingsTests::TestReorderWithNullGuids() @@ -933,39 +933,39 @@ namespace TerminalAppLocalTests const auto settings0Json = VerifyParseSucceeded(settings0String); - CascadiaSettings settings; - settings._ParseJsonString(DefaultJson, true); - settings.LayerJson(settings._defaultSettings); - VERIFY_ARE_EQUAL(2u, settings._profiles.size()); - VERIFY_IS_TRUE(settings._profiles.at(0).HasGuid()); - VERIFY_IS_TRUE(settings._profiles.at(1).HasGuid()); - VERIFY_ARE_EQUAL(L"Windows PowerShell", settings._profiles.at(0).Name()); - VERIFY_ARE_EQUAL(L"Command Prompt", settings._profiles.at(1).Name()); - - settings._ParseJsonString(settings0String, false); - settings.LayerJson(settings._userSettings); - - VERIFY_ARE_EQUAL(4u, settings._profiles.size()); - VERIFY_IS_TRUE(settings._profiles.at(0).HasGuid()); - VERIFY_IS_TRUE(settings._profiles.at(1).HasGuid()); - VERIFY_IS_TRUE(settings._profiles.at(2).HasGuid()); - VERIFY_IS_FALSE(settings._profiles.at(3).HasGuid()); - VERIFY_ARE_EQUAL(L"Windows PowerShell", settings._profiles.at(0).Name()); - VERIFY_ARE_EQUAL(L"cmdFromUserSettings", settings._profiles.at(1).Name()); - VERIFY_ARE_EQUAL(L"profile0", settings._profiles.at(2).Name()); - VERIFY_ARE_EQUAL(L"profile1", settings._profiles.at(3).Name()); - - settings._ValidateSettings(); - VERIFY_ARE_EQUAL(0u, settings._warnings.size()); - VERIFY_ARE_EQUAL(4u, settings._profiles.size()); - VERIFY_IS_TRUE(settings._profiles.at(0).HasGuid()); - VERIFY_IS_TRUE(settings._profiles.at(1).HasGuid()); - VERIFY_IS_TRUE(settings._profiles.at(2).HasGuid()); - VERIFY_IS_TRUE(settings._profiles.at(3).HasGuid()); - VERIFY_ARE_EQUAL(L"profile0", settings._profiles.at(0).Name()); - VERIFY_ARE_EQUAL(L"profile1", settings._profiles.at(1).Name()); - VERIFY_ARE_EQUAL(L"cmdFromUserSettings", settings._profiles.at(2).Name()); - VERIFY_ARE_EQUAL(L"Windows PowerShell", settings._profiles.at(3).Name()); + auto settings = winrt::make_self(); + settings->_ParseJsonString(DefaultJson, true); + settings->LayerJson(settings->_defaultSettings); + VERIFY_ARE_EQUAL(2u, settings->_profiles.Size()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(0).HasGuid()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(1).HasGuid()); + VERIFY_ARE_EQUAL(L"Windows PowerShell", settings->_profiles.GetAt(0).Name()); + VERIFY_ARE_EQUAL(L"Command Prompt", settings->_profiles.GetAt(1).Name()); + + settings->_ParseJsonString(settings0String, false); + settings->LayerJson(settings->_userSettings); + + VERIFY_ARE_EQUAL(4u, settings->_profiles.Size()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(0).HasGuid()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(1).HasGuid()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(2).HasGuid()); + VERIFY_IS_FALSE(settings->_profiles.GetAt(3).HasGuid()); + VERIFY_ARE_EQUAL(L"Windows PowerShell", settings->_profiles.GetAt(0).Name()); + VERIFY_ARE_EQUAL(L"cmdFromUserSettings", settings->_profiles.GetAt(1).Name()); + VERIFY_ARE_EQUAL(L"profile0", settings->_profiles.GetAt(2).Name()); + VERIFY_ARE_EQUAL(L"profile1", settings->_profiles.GetAt(3).Name()); + + settings->_ValidateSettings(); + VERIFY_ARE_EQUAL(0u, settings->_warnings.size()); + VERIFY_ARE_EQUAL(4u, settings->_profiles.Size()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(0).HasGuid()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(1).HasGuid()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(2).HasGuid()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(3).HasGuid()); + VERIFY_ARE_EQUAL(L"profile0", settings->_profiles.GetAt(0).Name()); + VERIFY_ARE_EQUAL(L"profile1", settings->_profiles.GetAt(1).Name()); + VERIFY_ARE_EQUAL(L"cmdFromUserSettings", settings->_profiles.GetAt(2).Name()); + VERIFY_ARE_EQUAL(L"Windows PowerShell", settings->_profiles.GetAt(3).Name()); } void SettingsTests::TestReorderingWithoutGuid() @@ -1034,39 +1034,39 @@ namespace TerminalAppLocalTests const auto settings0Json = VerifyParseSucceeded(settings0String); - CascadiaSettings settings; - settings._ParseJsonString(DefaultJson, true); - settings.LayerJson(settings._defaultSettings); - VERIFY_ARE_EQUAL(2u, settings._profiles.size()); - VERIFY_IS_TRUE(settings._profiles.at(0).HasGuid()); - VERIFY_IS_TRUE(settings._profiles.at(1).HasGuid()); - VERIFY_ARE_EQUAL(L"Windows PowerShell", settings._profiles.at(0).Name()); - VERIFY_ARE_EQUAL(L"Command Prompt", settings._profiles.at(1).Name()); - - settings._ParseJsonString(settings0String, false); - settings.LayerJson(settings._userSettings); - - VERIFY_ARE_EQUAL(4u, settings._profiles.size()); - VERIFY_IS_TRUE(settings._profiles.at(0).HasGuid()); - VERIFY_IS_TRUE(settings._profiles.at(1).HasGuid()); - VERIFY_IS_FALSE(settings._profiles.at(2).HasGuid()); - VERIFY_IS_TRUE(settings._profiles.at(3).HasGuid()); - VERIFY_ARE_EQUAL(L"Windows PowerShell", settings._profiles.at(0).Name()); - VERIFY_ARE_EQUAL(L"Command Prompt", settings._profiles.at(1).Name()); - VERIFY_ARE_EQUAL(L"ThisProfileShouldNotCrash", settings._profiles.at(2).Name()); - VERIFY_ARE_EQUAL(L"Ubuntu", settings._profiles.at(3).Name()); - - settings._ValidateSettings(); - VERIFY_ARE_EQUAL(0u, settings._warnings.size()); - VERIFY_ARE_EQUAL(4u, settings._profiles.size()); - VERIFY_IS_TRUE(settings._profiles.at(0).HasGuid()); - VERIFY_IS_TRUE(settings._profiles.at(1).HasGuid()); - VERIFY_IS_TRUE(settings._profiles.at(2).HasGuid()); - VERIFY_IS_TRUE(settings._profiles.at(3).HasGuid()); - VERIFY_ARE_EQUAL(L"Command Prompt", settings._profiles.at(0).Name()); - VERIFY_ARE_EQUAL(L"ThisProfileShouldNotCrash", settings._profiles.at(1).Name()); - VERIFY_ARE_EQUAL(L"Ubuntu", settings._profiles.at(2).Name()); - VERIFY_ARE_EQUAL(L"Windows PowerShell", settings._profiles.at(3).Name()); + auto settings = winrt::make_self(); + settings->_ParseJsonString(DefaultJson, true); + settings->LayerJson(settings->_defaultSettings); + VERIFY_ARE_EQUAL(2u, settings->_profiles.Size()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(0).HasGuid()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(1).HasGuid()); + VERIFY_ARE_EQUAL(L"Windows PowerShell", settings->_profiles.GetAt(0).Name()); + VERIFY_ARE_EQUAL(L"Command Prompt", settings->_profiles.GetAt(1).Name()); + + settings->_ParseJsonString(settings0String, false); + settings->LayerJson(settings->_userSettings); + + VERIFY_ARE_EQUAL(4u, settings->_profiles.Size()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(0).HasGuid()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(1).HasGuid()); + VERIFY_IS_FALSE(settings->_profiles.GetAt(2).HasGuid()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(3).HasGuid()); + VERIFY_ARE_EQUAL(L"Windows PowerShell", settings->_profiles.GetAt(0).Name()); + VERIFY_ARE_EQUAL(L"Command Prompt", settings->_profiles.GetAt(1).Name()); + VERIFY_ARE_EQUAL(L"ThisProfileShouldNotCrash", settings->_profiles.GetAt(2).Name()); + VERIFY_ARE_EQUAL(L"Ubuntu", settings->_profiles.GetAt(3).Name()); + + settings->_ValidateSettings(); + VERIFY_ARE_EQUAL(0u, settings->_warnings.size()); + VERIFY_ARE_EQUAL(4u, settings->_profiles.Size()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(0).HasGuid()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(1).HasGuid()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(2).HasGuid()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(3).HasGuid()); + VERIFY_ARE_EQUAL(L"Command Prompt", settings->_profiles.GetAt(0).Name()); + VERIFY_ARE_EQUAL(L"ThisProfileShouldNotCrash", settings->_profiles.GetAt(1).Name()); + VERIFY_ARE_EQUAL(L"Ubuntu", settings->_profiles.GetAt(2).Name()); + VERIFY_ARE_EQUAL(L"Windows PowerShell", settings->_profiles.GetAt(3).Name()); } void SettingsTests::TestLayeringNameOnlyProfiles() @@ -1095,31 +1095,31 @@ namespace TerminalAppLocalTests const auto settings0Json = VerifyParseSucceeded(settings0String); - CascadiaSettings settings; - settings._ParseJsonString(DefaultJson, true); - settings.LayerJson(settings._defaultSettings); - VERIFY_ARE_EQUAL(2u, settings._profiles.size()); - VERIFY_IS_TRUE(settings._profiles.at(0).HasGuid()); - VERIFY_IS_TRUE(settings._profiles.at(1).HasGuid()); - VERIFY_ARE_EQUAL(L"Windows PowerShell", settings._profiles.at(0).Name()); - VERIFY_ARE_EQUAL(L"Command Prompt", settings._profiles.at(1).Name()); + auto settings = winrt::make_self(); + settings->_ParseJsonString(DefaultJson, true); + settings->LayerJson(settings->_defaultSettings); + VERIFY_ARE_EQUAL(2u, settings->_profiles.Size()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(0).HasGuid()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(1).HasGuid()); + VERIFY_ARE_EQUAL(L"Windows PowerShell", settings->_profiles.GetAt(0).Name()); + VERIFY_ARE_EQUAL(L"Command Prompt", settings->_profiles.GetAt(1).Name()); Log::Comment(NoThrowString().Format( L"Parse the user settings")); - settings._ParseJsonString(settings0String, false); - settings.LayerJson(settings._userSettings); - - VERIFY_ARE_EQUAL(5u, settings._profiles.size()); - VERIFY_IS_TRUE(settings._profiles.at(0).HasGuid()); - VERIFY_IS_TRUE(settings._profiles.at(1).HasGuid()); - VERIFY_IS_TRUE(settings._profiles.at(2).HasGuid()); - VERIFY_IS_FALSE(settings._profiles.at(3).HasGuid()); - VERIFY_IS_FALSE(settings._profiles.at(4).HasGuid()); - VERIFY_ARE_EQUAL(L"Windows PowerShell", settings._profiles.at(0).Name()); - VERIFY_ARE_EQUAL(L"Command Prompt", settings._profiles.at(1).Name()); - VERIFY_ARE_EQUAL(L"ThisProfileIsGood", settings._profiles.at(2).Name()); - VERIFY_ARE_EQUAL(L"ThisProfileShouldNotLayer", settings._profiles.at(3).Name()); - VERIFY_ARE_EQUAL(L"NeitherShouldThisOne", settings._profiles.at(4).Name()); + settings->_ParseJsonString(settings0String, false); + settings->LayerJson(settings->_userSettings); + + VERIFY_ARE_EQUAL(5u, settings->_profiles.Size()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(0).HasGuid()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(1).HasGuid()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(2).HasGuid()); + VERIFY_IS_FALSE(settings->_profiles.GetAt(3).HasGuid()); + VERIFY_IS_FALSE(settings->_profiles.GetAt(4).HasGuid()); + VERIFY_ARE_EQUAL(L"Windows PowerShell", settings->_profiles.GetAt(0).Name()); + VERIFY_ARE_EQUAL(L"Command Prompt", settings->_profiles.GetAt(1).Name()); + VERIFY_ARE_EQUAL(L"ThisProfileIsGood", settings->_profiles.GetAt(2).Name()); + VERIFY_ARE_EQUAL(L"ThisProfileShouldNotLayer", settings->_profiles.GetAt(3).Name()); + VERIFY_ARE_EQUAL(L"NeitherShouldThisOne", settings->_profiles.GetAt(4).Name()); } void SettingsTests::TestExplodingNameOnlyProfiles() @@ -1148,81 +1148,81 @@ namespace TerminalAppLocalTests const auto settings0Json = VerifyParseSucceeded(settings0String); - CascadiaSettings settings; - settings._ParseJsonString(DefaultJson, true); - settings.LayerJson(settings._defaultSettings); - VERIFY_ARE_EQUAL(2u, settings._profiles.size()); - VERIFY_IS_TRUE(settings._profiles.at(0).HasGuid()); - VERIFY_IS_TRUE(settings._profiles.at(1).HasGuid()); - VERIFY_ARE_EQUAL(L"Windows PowerShell", settings._profiles.at(0).Name()); - VERIFY_ARE_EQUAL(L"Command Prompt", settings._profiles.at(1).Name()); + auto settings = winrt::make_self(); + settings->_ParseJsonString(DefaultJson, true); + settings->LayerJson(settings->_defaultSettings); + VERIFY_ARE_EQUAL(2u, settings->_profiles.Size()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(0).HasGuid()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(1).HasGuid()); + VERIFY_ARE_EQUAL(L"Windows PowerShell", settings->_profiles.GetAt(0).Name()); + VERIFY_ARE_EQUAL(L"Command Prompt", settings->_profiles.GetAt(1).Name()); Log::Comment(NoThrowString().Format( L"Parse the user settings")); - settings._ParseJsonString(settings0String, false); - settings.LayerJson(settings._userSettings); - - VERIFY_ARE_EQUAL(5u, settings._profiles.size()); - VERIFY_IS_TRUE(settings._profiles.at(0).HasGuid()); - VERIFY_IS_TRUE(settings._profiles.at(1).HasGuid()); - VERIFY_IS_TRUE(settings._profiles.at(2).HasGuid()); - VERIFY_IS_FALSE(settings._profiles.at(3).HasGuid()); - VERIFY_IS_FALSE(settings._profiles.at(4).HasGuid()); - VERIFY_ARE_EQUAL(L"Windows PowerShell", settings._profiles.at(0).Name()); - VERIFY_ARE_EQUAL(L"Command Prompt", settings._profiles.at(1).Name()); - VERIFY_ARE_EQUAL(L"ThisProfileIsGood", settings._profiles.at(2).Name()); - VERIFY_ARE_EQUAL(L"ThisProfileShouldNotDuplicate", settings._profiles.at(3).Name()); - VERIFY_ARE_EQUAL(L"NeitherShouldThisOne", settings._profiles.at(4).Name()); + settings->_ParseJsonString(settings0String, false); + settings->LayerJson(settings->_userSettings); + + VERIFY_ARE_EQUAL(5u, settings->_profiles.Size()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(0).HasGuid()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(1).HasGuid()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(2).HasGuid()); + VERIFY_IS_FALSE(settings->_profiles.GetAt(3).HasGuid()); + VERIFY_IS_FALSE(settings->_profiles.GetAt(4).HasGuid()); + VERIFY_ARE_EQUAL(L"Windows PowerShell", settings->_profiles.GetAt(0).Name()); + VERIFY_ARE_EQUAL(L"Command Prompt", settings->_profiles.GetAt(1).Name()); + VERIFY_ARE_EQUAL(L"ThisProfileIsGood", settings->_profiles.GetAt(2).Name()); + VERIFY_ARE_EQUAL(L"ThisProfileShouldNotDuplicate", settings->_profiles.GetAt(3).Name()); + VERIFY_ARE_EQUAL(L"NeitherShouldThisOne", settings->_profiles.GetAt(4).Name()); Log::Comment(NoThrowString().Format( L"Pretend like we're checking to append dynamic profiles to the " L"user's settings file. We absolutely _shouldn't_ be adding anything here.")); - bool const needToWriteFile = settings._AppendDynamicProfilesToUserSettings(); + bool const needToWriteFile = settings->_AppendDynamicProfilesToUserSettings(); VERIFY_IS_FALSE(needToWriteFile); - VERIFY_ARE_EQUAL(settings0String.size(), settings._userSettingsString.size()); + VERIFY_ARE_EQUAL(settings0String.size(), settings->_userSettingsString.size()); Log::Comment(NoThrowString().Format( L"Re-parse the settings file. We should have the _same_ settings as before.")); Log::Comment(NoThrowString().Format( L"Do this to a _new_ settings object, to make sure it turns out the same.")); { - CascadiaSettings settings2; - settings2._ParseJsonString(DefaultJson, true); - settings2.LayerJson(settings2._defaultSettings); - VERIFY_ARE_EQUAL(2u, settings2._profiles.size()); + auto settings2 = winrt::make_self(); + settings2->_ParseJsonString(DefaultJson, true); + settings2->LayerJson(settings2->_defaultSettings); + VERIFY_ARE_EQUAL(2u, settings2->_profiles.Size()); // Initialize the second settings object from the first settings // object's settings string, the one that we synthesized. - const auto firstSettingsString = settings._userSettingsString; - settings2._ParseJsonString(firstSettingsString, false); - settings2.LayerJson(settings2._userSettings); - VERIFY_ARE_EQUAL(5u, settings2._profiles.size()); - VERIFY_IS_TRUE(settings2._profiles.at(0).HasGuid()); - VERIFY_IS_TRUE(settings2._profiles.at(1).HasGuid()); - VERIFY_IS_TRUE(settings2._profiles.at(2).HasGuid()); - VERIFY_IS_FALSE(settings2._profiles.at(3).HasGuid()); - VERIFY_IS_FALSE(settings2._profiles.at(4).HasGuid()); - VERIFY_ARE_EQUAL(L"Windows PowerShell", settings2._profiles.at(0).Name()); - VERIFY_ARE_EQUAL(L"Command Prompt", settings2._profiles.at(1).Name()); - VERIFY_ARE_EQUAL(L"ThisProfileIsGood", settings2._profiles.at(2).Name()); - VERIFY_ARE_EQUAL(L"ThisProfileShouldNotDuplicate", settings2._profiles.at(3).Name()); - VERIFY_ARE_EQUAL(L"NeitherShouldThisOne", settings2._profiles.at(4).Name()); + const auto firstSettingsString = settings->_userSettingsString; + settings2->_ParseJsonString(firstSettingsString, false); + settings2->LayerJson(settings2->_userSettings); + VERIFY_ARE_EQUAL(5u, settings2->_profiles.Size()); + VERIFY_IS_TRUE(settings2->_profiles.GetAt(0).HasGuid()); + VERIFY_IS_TRUE(settings2->_profiles.GetAt(1).HasGuid()); + VERIFY_IS_TRUE(settings2->_profiles.GetAt(2).HasGuid()); + VERIFY_IS_FALSE(settings2->_profiles.GetAt(3).HasGuid()); + VERIFY_IS_FALSE(settings2->_profiles.GetAt(4).HasGuid()); + VERIFY_ARE_EQUAL(L"Windows PowerShell", settings2->_profiles.GetAt(0).Name()); + VERIFY_ARE_EQUAL(L"Command Prompt", settings2->_profiles.GetAt(1).Name()); + VERIFY_ARE_EQUAL(L"ThisProfileIsGood", settings2->_profiles.GetAt(2).Name()); + VERIFY_ARE_EQUAL(L"ThisProfileShouldNotDuplicate", settings2->_profiles.GetAt(3).Name()); + VERIFY_ARE_EQUAL(L"NeitherShouldThisOne", settings2->_profiles.GetAt(4).Name()); } Log::Comment(NoThrowString().Format( L"Validate the settings. All the profiles we have should be valid.")); - settings._ValidateSettings(); - - VERIFY_ARE_EQUAL(5u, settings._profiles.size()); - VERIFY_IS_TRUE(settings._profiles.at(0).HasGuid()); - VERIFY_IS_TRUE(settings._profiles.at(1).HasGuid()); - VERIFY_IS_TRUE(settings._profiles.at(2).HasGuid()); - VERIFY_IS_TRUE(settings._profiles.at(3).HasGuid()); - VERIFY_IS_TRUE(settings._profiles.at(4).HasGuid()); - VERIFY_ARE_EQUAL(L"ThisProfileIsGood", settings._profiles.at(0).Name()); - VERIFY_ARE_EQUAL(L"ThisProfileShouldNotDuplicate", settings._profiles.at(1).Name()); - VERIFY_ARE_EQUAL(L"NeitherShouldThisOne", settings._profiles.at(2).Name()); - VERIFY_ARE_EQUAL(L"Windows PowerShell", settings._profiles.at(3).Name()); - VERIFY_ARE_EQUAL(L"Command Prompt", settings._profiles.at(4).Name()); + settings->_ValidateSettings(); + + VERIFY_ARE_EQUAL(5u, settings->_profiles.Size()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(0).HasGuid()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(1).HasGuid()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(2).HasGuid()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(3).HasGuid()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(4).HasGuid()); + VERIFY_ARE_EQUAL(L"ThisProfileIsGood", settings->_profiles.GetAt(0).Name()); + VERIFY_ARE_EQUAL(L"ThisProfileShouldNotDuplicate", settings->_profiles.GetAt(1).Name()); + VERIFY_ARE_EQUAL(L"NeitherShouldThisOne", settings->_profiles.GetAt(2).Name()); + VERIFY_ARE_EQUAL(L"Windows PowerShell", settings->_profiles.GetAt(3).Name()); + VERIFY_ARE_EQUAL(L"Command Prompt", settings->_profiles.GetAt(4).Name()); } void SettingsTests::TestHideAllProfiles() @@ -1260,26 +1260,25 @@ namespace TerminalAppLocalTests { // Case 1: Good settings - CascadiaSettings settings; - settings._ParseJsonString(settingsWithProfiles, false); - settings.LayerJson(settings._userSettings); + auto settings = winrt::make_self(); + settings->_ParseJsonString(settingsWithProfiles, false); + settings->LayerJson(settings->_userSettings); - settings._RemoveHiddenProfiles(); + settings->_RemoveHiddenProfiles(); Log::Comment(NoThrowString().Format( L"settingsWithProfiles successfully parsed and validated")); - VERIFY_ARE_EQUAL(1u, settings._profiles.size()); + VERIFY_ARE_EQUAL(1u, settings->_profiles.Size()); } { // Case 2: Bad settings - - CascadiaSettings settings; - settings._ParseJsonString(settingsWithoutProfiles, false); - settings.LayerJson(settings._userSettings); + auto settings = winrt::make_self(); + settings->_ParseJsonString(settingsWithoutProfiles, false); + settings->LayerJson(settings->_userSettings); bool caughtExpectedException = false; try { - settings._RemoveHiddenProfiles(); + settings->_RemoveHiddenProfiles(); } catch (const ::TerminalApp::SettingsException& ex) { @@ -1325,28 +1324,28 @@ namespace TerminalAppLocalTests VerifyParseSucceeded(settings0String); - CascadiaSettings settings; - settings._ParseJsonString(settings0String, false); - settings.LayerJson(settings._userSettings); + auto settings = winrt::make_self(); + settings->_ParseJsonString(settings0String, false); + settings->LayerJson(settings->_userSettings); - VERIFY_ARE_EQUAL(3u, settings._profiles.size()); - VERIFY_ARE_EQUAL(2u, settings._globals->GetColorSchemes().Size()); + VERIFY_ARE_EQUAL(3u, settings->_profiles.Size()); + VERIFY_ARE_EQUAL(2u, settings->_globals->GetColorSchemes().Size()); - VERIFY_ARE_EQUAL(L"schemeOne", settings._profiles.at(0).ColorSchemeName()); - VERIFY_ARE_EQUAL(L"InvalidSchemeName", settings._profiles.at(1).ColorSchemeName()); - VERIFY_ARE_EQUAL(L"Campbell", settings._profiles.at(2).ColorSchemeName()); + VERIFY_ARE_EQUAL(L"schemeOne", settings->_profiles.GetAt(0).ColorSchemeName()); + VERIFY_ARE_EQUAL(L"InvalidSchemeName", settings->_profiles.GetAt(1).ColorSchemeName()); + VERIFY_ARE_EQUAL(L"Campbell", settings->_profiles.GetAt(2).ColorSchemeName()); - settings._ValidateAllSchemesExist(); + settings->_ValidateAllSchemesExist(); - VERIFY_ARE_EQUAL(1u, settings._warnings.size()); - VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::UnknownColorScheme, settings._warnings.at(0)); + VERIFY_ARE_EQUAL(1u, settings->_warnings.size()); + VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::UnknownColorScheme, settings->_warnings.at(0)); - VERIFY_ARE_EQUAL(3u, settings._profiles.size()); - VERIFY_ARE_EQUAL(2u, settings._globals->GetColorSchemes().Size()); + VERIFY_ARE_EQUAL(3u, settings->_profiles.Size()); + VERIFY_ARE_EQUAL(2u, settings->_globals->GetColorSchemes().Size()); - VERIFY_ARE_EQUAL(L"schemeOne", settings._profiles.at(0).ColorSchemeName()); - VERIFY_ARE_EQUAL(L"Campbell", settings._profiles.at(1).ColorSchemeName()); - VERIFY_ARE_EQUAL(L"Campbell", settings._profiles.at(2).ColorSchemeName()); + VERIFY_ARE_EQUAL(L"schemeOne", settings->_profiles.GetAt(0).ColorSchemeName()); + VERIFY_ARE_EQUAL(L"Campbell", settings->_profiles.GetAt(1).ColorSchemeName()); + VERIFY_ARE_EQUAL(L"Campbell", settings->_profiles.GetAt(2).ColorSchemeName()); } void SettingsTests::TestHelperFunctions() @@ -1387,21 +1386,21 @@ namespace TerminalAppLocalTests VerifyParseSucceeded(settings0String); - CascadiaSettings settings; - settings._ParseJsonString(settings0String, false); - settings.LayerJson(settings._userSettings); + auto settings = winrt::make_self(); + settings->_ParseJsonString(settings0String, false); + settings->LayerJson(settings->_userSettings); - VERIFY_ARE_EQUAL(guid0, settings._GetProfileGuidByName(name0)); - VERIFY_ARE_EQUAL(guid1, settings._GetProfileGuidByName(name1)); - VERIFY_ARE_EQUAL(guid2, settings._GetProfileGuidByName(name2)); - VERIFY_ARE_EQUAL(badGuid, settings._GetProfileGuidByName(name3)); - VERIFY_ARE_EQUAL(badGuid, settings._GetProfileGuidByName(badName)); + VERIFY_ARE_EQUAL(guid0, settings->_GetProfileGuidByName(name0)); + VERIFY_ARE_EQUAL(guid1, settings->_GetProfileGuidByName(name1)); + VERIFY_ARE_EQUAL(guid2, settings->_GetProfileGuidByName(name2)); + VERIFY_ARE_EQUAL(badGuid, settings->_GetProfileGuidByName(name3)); + VERIFY_ARE_EQUAL(badGuid, settings->_GetProfileGuidByName(badName)); - auto prof0{ settings.FindProfile(guid0) }; - auto prof1{ settings.FindProfile(guid1) }; - auto prof2{ settings.FindProfile(guid2) }; + auto prof0{ settings->FindProfile(guid0) }; + auto prof1{ settings->FindProfile(guid1) }; + auto prof2{ settings->FindProfile(guid2) }; - auto badProf{ settings.FindProfile(fakeGuid) }; + auto badProf{ settings->FindProfile(fakeGuid) }; VERIFY_ARE_EQUAL(badProf, nullptr); VERIFY_ARE_EQUAL(name0, prof0.Name()); @@ -1424,11 +1423,12 @@ namespace TerminalAppLocalTests })" }; VerifyParseSucceeded(settingsJson); - CascadiaSettings settings{}; - settings._ParseJsonString(settingsJson, false); - settings.LayerJson(settings._userSettings); - VERIFY_IS_FALSE(settings._profiles.empty()); - VERIFY_ARE_EQUAL(expectedPath, settings._profiles[0].GetExpandedIconPath()); + + auto settings = winrt::make_self(); + settings->_ParseJsonString(settingsJson, false); + settings->LayerJson(settings->_userSettings); + VERIFY_ARE_NOT_EQUAL(0u, settings->_profiles.Size()); + VERIFY_ARE_EQUAL(expectedPath, settings->_profiles.GetAt(0).GetExpandedIconPath()); } void SettingsTests::TestProfileBackgroundImageWithEnvVar() { @@ -1445,13 +1445,14 @@ namespace TerminalAppLocalTests })" }; VerifyParseSucceeded(settingsJson); - CascadiaSettings settings{}; - settings._ParseJsonString(settingsJson, false); - settings.LayerJson(settings._userSettings); - VERIFY_IS_FALSE(settings._profiles.empty()); + + auto settings = winrt::make_self(); + settings->_ParseJsonString(settingsJson, false); + settings->LayerJson(settings->_userSettings); + VERIFY_ARE_NOT_EQUAL(0u, settings->_profiles.Size()); auto globalSettings{ winrt::make() }; - const auto profileImpl = winrt::get_self(settings._profiles[0]); + const auto profileImpl = winrt::get_self(settings->_profiles.GetAt(0)); auto terminalSettings = profileImpl->CreateTerminalSettings(globalSettings.GetColorSchemes()); VERIFY_ARE_EQUAL(expectedPath, terminalSettings.BackgroundImage()); } @@ -1480,15 +1481,16 @@ namespace TerminalAppLocalTests })" }; VerifyParseSucceeded(settingsJson); - CascadiaSettings settings{}; - settings._ParseJsonString(settingsJson, false); - settings.LayerJson(settings._userSettings); - VERIFY_ARE_EQUAL(CloseOnExitMode::Graceful, settings._profiles[0].CloseOnExit()); - VERIFY_ARE_EQUAL(CloseOnExitMode::Always, settings._profiles[1].CloseOnExit()); - VERIFY_ARE_EQUAL(CloseOnExitMode::Never, settings._profiles[2].CloseOnExit()); + + auto settings = winrt::make_self(); + settings->_ParseJsonString(settingsJson, false); + settings->LayerJson(settings->_userSettings); + VERIFY_ARE_EQUAL(CloseOnExitMode::Graceful, settings->_profiles.GetAt(0).CloseOnExit()); + VERIFY_ARE_EQUAL(CloseOnExitMode::Always, settings->_profiles.GetAt(1).CloseOnExit()); + VERIFY_ARE_EQUAL(CloseOnExitMode::Never, settings->_profiles.GetAt(2).CloseOnExit()); // Unknown modes parse as "Graceful" - VERIFY_ARE_EQUAL(CloseOnExitMode::Graceful, settings._profiles[3].CloseOnExit()); + VERIFY_ARE_EQUAL(CloseOnExitMode::Graceful, settings->_profiles.GetAt(3).CloseOnExit()); } void SettingsTests::TestCloseOnExitCompatibilityShim() { @@ -1507,11 +1509,12 @@ namespace TerminalAppLocalTests })" }; VerifyParseSucceeded(settingsJson); - CascadiaSettings settings{}; - settings._ParseJsonString(settingsJson, false); - settings.LayerJson(settings._userSettings); - VERIFY_ARE_EQUAL(CloseOnExitMode::Graceful, settings._profiles[0].CloseOnExit()); - VERIFY_ARE_EQUAL(CloseOnExitMode::Never, settings._profiles[1].CloseOnExit()); + + auto settings = winrt::make_self(); + settings->_ParseJsonString(settingsJson, false); + settings->LayerJson(settings->_userSettings); + VERIFY_ARE_EQUAL(CloseOnExitMode::Graceful, settings->_profiles.GetAt(0).CloseOnExit()); + VERIFY_ARE_EQUAL(CloseOnExitMode::Never, settings->_profiles.GetAt(1).CloseOnExit()); } void SettingsTests::TestLayerUserDefaultsBeforeProfiles() @@ -1547,18 +1550,18 @@ namespace TerminalAppLocalTests const auto guid1String = L"{6239a42c-1111-49a3-80bd-e8fdd045185c}"; { - CascadiaSettings settings{ false }; - settings._ParseJsonString(settings0String, false); - VERIFY_IS_TRUE(settings._userDefaultProfileSettings == Json::Value::null); - settings._ApplyDefaultsFromUserSettings(); - VERIFY_IS_FALSE(settings._userDefaultProfileSettings == Json::Value::null); - settings.LayerJson(settings._userSettings); + auto settings = winrt::make_self(false); + settings->_ParseJsonString(settings0String, false); + VERIFY_IS_TRUE(settings->_userDefaultProfileSettings == Json::Value::null); + settings->_ApplyDefaultsFromUserSettings(); + VERIFY_IS_FALSE(settings->_userDefaultProfileSettings == Json::Value::null); + settings->LayerJson(settings->_userSettings); - VERIFY_ARE_EQUAL(guid1String, settings._globals->UnparsedDefaultProfile()); - VERIFY_ARE_EQUAL(2u, settings._profiles.size()); + VERIFY_ARE_EQUAL(guid1String, settings->_globals->UnparsedDefaultProfile()); + VERIFY_ARE_EQUAL(2u, settings->_profiles.Size()); - VERIFY_ARE_EQUAL(2345, settings._profiles.at(0).HistorySize()); - VERIFY_ARE_EQUAL(1234, settings._profiles.at(1).HistorySize()); + VERIFY_ARE_EQUAL(2345, settings->_profiles.GetAt(0).HistorySize()); + VERIFY_ARE_EQUAL(1234, settings->_profiles.GetAt(1).HistorySize()); } } @@ -1595,28 +1598,28 @@ namespace TerminalAppLocalTests const winrt::guid guid2{ ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-2222-49a3-80bd-e8fdd045185c}") }; { - CascadiaSettings settings{ false }; - settings._ParseJsonString(DefaultJson, true); - settings.LayerJson(settings._defaultSettings); - VERIFY_ARE_EQUAL(2u, settings._profiles.size()); + auto settings = winrt::make_self(false); + settings->_ParseJsonString(DefaultJson, true); + settings->LayerJson(settings->_defaultSettings); + VERIFY_ARE_EQUAL(2u, settings->_profiles.Size()); - settings._ParseJsonString(settings0String, false); - VERIFY_IS_TRUE(settings._userDefaultProfileSettings == Json::Value::null); - settings._ApplyDefaultsFromUserSettings(); - VERIFY_IS_FALSE(settings._userDefaultProfileSettings == Json::Value::null); + settings->_ParseJsonString(settings0String, false); + VERIFY_IS_TRUE(settings->_userDefaultProfileSettings == Json::Value::null); + settings->_ApplyDefaultsFromUserSettings(); + VERIFY_IS_FALSE(settings->_userDefaultProfileSettings == Json::Value::null); Log::Comment(NoThrowString().Format( L"Ensure that cmd and powershell don't get their GUIDs overwritten")); - VERIFY_ARE_NOT_EQUAL(guid2, settings._profiles.at(0).Guid()); - VERIFY_ARE_NOT_EQUAL(guid2, settings._profiles.at(1).Guid()); + VERIFY_ARE_NOT_EQUAL(guid2, settings->_profiles.GetAt(0).Guid()); + VERIFY_ARE_NOT_EQUAL(guid2, settings->_profiles.GetAt(1).Guid()); - settings.LayerJson(settings._userSettings); + settings->LayerJson(settings->_userSettings); - VERIFY_ARE_EQUAL(guid1String, settings._globals->UnparsedDefaultProfile()); - VERIFY_ARE_EQUAL(4u, settings._profiles.size()); + VERIFY_ARE_EQUAL(guid1String, settings->_globals->UnparsedDefaultProfile()); + VERIFY_ARE_EQUAL(4u, settings->_profiles.Size()); - VERIFY_ARE_EQUAL(guid1, settings._profiles.at(2).Guid()); - VERIFY_IS_FALSE(settings._profiles.at(3).HasGuid()); + VERIFY_ARE_EQUAL(guid1, settings->_profiles.GetAt(2).Guid()); + VERIFY_IS_FALSE(settings->_profiles.GetAt(3).HasGuid()); } } @@ -1642,18 +1645,18 @@ namespace TerminalAppLocalTests }, "list": [ { - "name" : "profile0FromUserSettings", // this is _profiles.at(0) + "name" : "profile0FromUserSettings", // this is _profiles.GetAt(0) "guid": "{6239a42c-1111-49a3-80bd-e8fdd045185c}", "source": "Terminal.App.UnitTest.0" }, { - "name" : "profile1FromUserSettings", // this is _profiles.at(2) + "name" : "profile1FromUserSettings", // this is _profiles.GetAt(2) "guid": "{6239a42c-2222-49a3-80bd-e8fdd045185c}", "source": "Terminal.App.UnitTest.1", "historySize": 4444 }, { - "name" : "profile2FromUserSettings", // this is _profiles.at(3) + "name" : "profile2FromUserSettings", // this is _profiles.GetAt(3) "guid": "{6239a42c-3333-49a3-80bd-e8fdd045185c}", "historySize": 5555 } @@ -1665,7 +1668,7 @@ namespace TerminalAppLocalTests gen0->pfnGenerate = [guid1, guid2]() { std::vector profiles; Profile p0 = winrt::make(guid1); - p0.Name(L"profile0"); // this is _profiles.at(0) + p0.Name(L"profile0"); // this is _profiles.GetAt(0) p0.HistorySize(1111); profiles.push_back(p0); return profiles; @@ -1675,8 +1678,8 @@ namespace TerminalAppLocalTests std::vector profiles; Profile p0 = winrt::make(guid1); Profile p1 = winrt::make(guid2); - p0.Name(L"profile0"); // this is _profiles.at(1) - p1.Name(L"profile1"); // this is _profiles.at(2) + p0.Name(L"profile0"); // this is _profiles.GetAt(1) + p1.Name(L"profile1"); // this is _profiles.GetAt(2) p0.HistorySize(2222); profiles.push_back(p0); p1.HistorySize(3333); @@ -1684,54 +1687,54 @@ namespace TerminalAppLocalTests return profiles; }; - CascadiaSettings settings{ false }; - settings._profileGenerators.emplace_back(std::move(gen0)); - settings._profileGenerators.emplace_back(std::move(gen1)); + auto settings = winrt::make_self(false); + settings->_profileGenerators.emplace_back(std::move(gen0)); + settings->_profileGenerators.emplace_back(std::move(gen1)); Log::Comment(NoThrowString().Format( L"All profiles with the same name have the same GUID. However, they" L" will not be layered, because they have different source's")); // parse userProfiles as the user settings - settings._ParseJsonString(userProfiles, false); - VERIFY_ARE_EQUAL(0u, settings._profiles.size(), L"Just parsing the user settings doesn't actually layer them"); - settings._LoadDynamicProfiles(); - VERIFY_ARE_EQUAL(3u, settings._profiles.size()); + settings->_ParseJsonString(userProfiles, false); + VERIFY_ARE_EQUAL(0u, settings->_profiles.Size(), L"Just parsing the user settings doesn't actually layer them"); + settings->_LoadDynamicProfiles(); + VERIFY_ARE_EQUAL(3u, settings->_profiles.Size()); - VERIFY_ARE_EQUAL(1111, settings._profiles.at(0).HistorySize()); - VERIFY_ARE_EQUAL(2222, settings._profiles.at(1).HistorySize()); - VERIFY_ARE_EQUAL(3333, settings._profiles.at(2).HistorySize()); + VERIFY_ARE_EQUAL(1111, settings->_profiles.GetAt(0).HistorySize()); + VERIFY_ARE_EQUAL(2222, settings->_profiles.GetAt(1).HistorySize()); + VERIFY_ARE_EQUAL(3333, settings->_profiles.GetAt(2).HistorySize()); - settings._ApplyDefaultsFromUserSettings(); + settings->_ApplyDefaultsFromUserSettings(); - VERIFY_ARE_EQUAL(1234, settings._profiles.at(0).HistorySize()); - VERIFY_ARE_EQUAL(1234, settings._profiles.at(1).HistorySize()); - VERIFY_ARE_EQUAL(1234, settings._profiles.at(2).HistorySize()); + VERIFY_ARE_EQUAL(1234, settings->_profiles.GetAt(0).HistorySize()); + VERIFY_ARE_EQUAL(1234, settings->_profiles.GetAt(1).HistorySize()); + VERIFY_ARE_EQUAL(1234, settings->_profiles.GetAt(2).HistorySize()); - settings.LayerJson(settings._userSettings); - VERIFY_ARE_EQUAL(4u, settings._profiles.size()); + settings->LayerJson(settings->_userSettings); + VERIFY_ARE_EQUAL(4u, settings->_profiles.Size()); - VERIFY_IS_FALSE(settings._profiles.at(0).Source().empty()); - VERIFY_IS_FALSE(settings._profiles.at(1).Source().empty()); - VERIFY_IS_FALSE(settings._profiles.at(2).Source().empty()); - VERIFY_IS_TRUE(settings._profiles.at(3).Source().empty()); + VERIFY_IS_FALSE(settings->_profiles.GetAt(0).Source().empty()); + VERIFY_IS_FALSE(settings->_profiles.GetAt(1).Source().empty()); + VERIFY_IS_FALSE(settings->_profiles.GetAt(2).Source().empty()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(3).Source().empty()); - VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.0", settings._profiles.at(0).Source()); - VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.1", settings._profiles.at(1).Source()); - VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.1", settings._profiles.at(2).Source()); + VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.0", settings->_profiles.GetAt(0).Source()); + VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.1", settings->_profiles.GetAt(1).Source()); + VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.1", settings->_profiles.GetAt(2).Source()); - VERIFY_IS_TRUE(settings._profiles.at(0).HasGuid()); - VERIFY_IS_TRUE(settings._profiles.at(1).HasGuid()); - VERIFY_IS_TRUE(settings._profiles.at(2).HasGuid()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(0).HasGuid()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(1).HasGuid()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(2).HasGuid()); - VERIFY_ARE_EQUAL(guid1, settings._profiles.at(0).Guid()); - VERIFY_ARE_EQUAL(guid1, settings._profiles.at(1).Guid()); - VERIFY_ARE_EQUAL(guid2, settings._profiles.at(2).Guid()); + VERIFY_ARE_EQUAL(guid1, settings->_profiles.GetAt(0).Guid()); + VERIFY_ARE_EQUAL(guid1, settings->_profiles.GetAt(1).Guid()); + VERIFY_ARE_EQUAL(guid2, settings->_profiles.GetAt(2).Guid()); - VERIFY_ARE_EQUAL(L"profile0FromUserSettings", settings._profiles.at(0).Name()); - VERIFY_ARE_EQUAL(L"profile0", settings._profiles.at(1).Name()); - VERIFY_ARE_EQUAL(L"profile1FromUserSettings", settings._profiles.at(2).Name()); - VERIFY_ARE_EQUAL(L"profile2FromUserSettings", settings._profiles.at(3).Name()); + VERIFY_ARE_EQUAL(L"profile0FromUserSettings", settings->_profiles.GetAt(0).Name()); + VERIFY_ARE_EQUAL(L"profile0", settings->_profiles.GetAt(1).Name()); + VERIFY_ARE_EQUAL(L"profile1FromUserSettings", settings->_profiles.GetAt(2).Name()); + VERIFY_ARE_EQUAL(L"profile2FromUserSettings", settings->_profiles.GetAt(3).Name()); Log::Comment(NoThrowString().Format( L"This is the real meat of the test: The two dynamic profiles that " @@ -1739,10 +1742,10 @@ namespace TerminalAppLocalTests L"1234 as their historySize(from the defaultSettings).The other two" L" profiles should have their custom historySize value.")); - VERIFY_ARE_EQUAL(1234, settings._profiles.at(0).HistorySize()); - VERIFY_ARE_EQUAL(1234, settings._profiles.at(1).HistorySize()); - VERIFY_ARE_EQUAL(4444, settings._profiles.at(2).HistorySize()); - VERIFY_ARE_EQUAL(5555, settings._profiles.at(3).HistorySize()); + VERIFY_ARE_EQUAL(1234, settings->_profiles.GetAt(0).HistorySize()); + VERIFY_ARE_EQUAL(1234, settings->_profiles.GetAt(1).HistorySize()); + VERIFY_ARE_EQUAL(4444, settings->_profiles.GetAt(2).HistorySize()); + VERIFY_ARE_EQUAL(5555, settings->_profiles.GetAt(3).HistorySize()); } void SettingsTests::TestTerminalArgsForBinding() @@ -1789,15 +1792,16 @@ namespace TerminalAppLocalTests const winrt::guid guid1{ ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-1111-49a3-80bd-e8fdd045185c}") }; VerifyParseSucceeded(settingsJson); - CascadiaSettings settings{}; - settings._ParseJsonString(settingsJson, false); - settings.LayerJson(settings._userSettings); - settings._ValidateSettings(); - auto appKeyBindingsProj = settings._globals->GetKeybindings(); - VERIFY_ARE_EQUAL(3u, settings.GetProfiles().size()); + auto settings = winrt::make_self(); + settings->_ParseJsonString(settingsJson, false); + settings->LayerJson(settings->_userSettings); + settings->_ValidateSettings(); - const auto profile2Guid = settings._profiles.at(2).Guid(); + auto appKeyBindingsProj = settings->_globals->GetKeybindings(); + VERIFY_ARE_EQUAL(3u, settings->_profiles.Size()); + + const auto profile2Guid = settings->_profiles.GetAt(2).Guid(); VERIFY_ARE_NOT_EQUAL(winrt::guid{}, profile2Guid); const auto appKeyBindings = winrt::get_self(appKeyBindingsProj); @@ -1817,7 +1821,7 @@ namespace TerminalAppLocalTests VERIFY_IS_TRUE(realArgs.TerminalArgs().TabTitle().empty()); VERIFY_IS_TRUE(realArgs.TerminalArgs().Profile().empty()); - const auto [guid, termSettings] = settings.BuildSettings(realArgs.TerminalArgs()); + const auto [guid, termSettings] = settings->BuildSettings(realArgs.TerminalArgs()); VERIFY_ARE_EQUAL(guid0, guid); VERIFY_ARE_EQUAL(L"cmd.exe", termSettings.Commandline()); VERIFY_ARE_EQUAL(1, termSettings.HistorySize()); @@ -1837,7 +1841,7 @@ namespace TerminalAppLocalTests VERIFY_IS_FALSE(realArgs.TerminalArgs().Profile().empty()); VERIFY_ARE_EQUAL(L"{6239a42c-1111-49a3-80bd-e8fdd045185c}", realArgs.TerminalArgs().Profile()); - const auto [guid, termSettings] = settings.BuildSettings(realArgs.TerminalArgs()); + const auto [guid, termSettings] = settings->BuildSettings(realArgs.TerminalArgs()); VERIFY_ARE_EQUAL(guid1, guid); VERIFY_ARE_EQUAL(L"pwsh.exe", termSettings.Commandline()); VERIFY_ARE_EQUAL(2, termSettings.HistorySize()); @@ -1857,7 +1861,7 @@ namespace TerminalAppLocalTests VERIFY_IS_FALSE(realArgs.TerminalArgs().Profile().empty()); VERIFY_ARE_EQUAL(L"profile1", realArgs.TerminalArgs().Profile()); - const auto [guid, termSettings] = settings.BuildSettings(realArgs.TerminalArgs()); + const auto [guid, termSettings] = settings->BuildSettings(realArgs.TerminalArgs()); VERIFY_ARE_EQUAL(guid1, guid); VERIFY_ARE_EQUAL(L"pwsh.exe", termSettings.Commandline()); VERIFY_ARE_EQUAL(2, termSettings.HistorySize()); @@ -1877,7 +1881,7 @@ namespace TerminalAppLocalTests VERIFY_IS_FALSE(realArgs.TerminalArgs().Profile().empty()); VERIFY_ARE_EQUAL(L"profile2", realArgs.TerminalArgs().Profile()); - const auto [guid, termSettings] = settings.BuildSettings(realArgs.TerminalArgs()); + const auto [guid, termSettings] = settings->BuildSettings(realArgs.TerminalArgs()); VERIFY_ARE_EQUAL(profile2Guid, guid); VERIFY_ARE_EQUAL(L"wsl.exe", termSettings.Commandline()); VERIFY_ARE_EQUAL(3, termSettings.HistorySize()); @@ -1897,7 +1901,7 @@ namespace TerminalAppLocalTests VERIFY_IS_TRUE(realArgs.TerminalArgs().Profile().empty()); VERIFY_ARE_EQUAL(L"foo.exe", realArgs.TerminalArgs().Commandline()); - const auto [guid, termSettings] = settings.BuildSettings(realArgs.TerminalArgs()); + const auto [guid, termSettings] = settings->BuildSettings(realArgs.TerminalArgs()); VERIFY_ARE_EQUAL(guid0, guid); VERIFY_ARE_EQUAL(L"foo.exe", termSettings.Commandline()); VERIFY_ARE_EQUAL(1, termSettings.HistorySize()); @@ -1918,7 +1922,7 @@ namespace TerminalAppLocalTests VERIFY_ARE_EQUAL(L"profile1", realArgs.TerminalArgs().Profile()); VERIFY_ARE_EQUAL(L"foo.exe", realArgs.TerminalArgs().Commandline()); - const auto [guid, termSettings] = settings.BuildSettings(realArgs.TerminalArgs()); + const auto [guid, termSettings] = settings->BuildSettings(realArgs.TerminalArgs()); VERIFY_ARE_EQUAL(guid1, guid); VERIFY_ARE_EQUAL(L"foo.exe", termSettings.Commandline()); VERIFY_ARE_EQUAL(2, termSettings.HistorySize()); @@ -1936,7 +1940,7 @@ namespace TerminalAppLocalTests VERIFY_IS_TRUE(realArgs.TerminalArgs().TabTitle().empty()); VERIFY_IS_TRUE(realArgs.TerminalArgs().Profile().empty()); - const auto [guid, termSettings] = settings.BuildSettings(realArgs.TerminalArgs()); + const auto [guid, termSettings] = settings->BuildSettings(realArgs.TerminalArgs()); VERIFY_ARE_EQUAL(guid0, guid); VERIFY_ARE_EQUAL(L"cmd.exe", termSettings.Commandline()); VERIFY_ARE_EQUAL(1, termSettings.HistorySize()); @@ -1955,7 +1959,7 @@ namespace TerminalAppLocalTests VERIFY_IS_TRUE(realArgs.TerminalArgs().Profile().empty()); VERIFY_ARE_EQUAL(L"c:\\foo", realArgs.TerminalArgs().StartingDirectory()); - const auto [guid, termSettings] = settings.BuildSettings(realArgs.TerminalArgs()); + const auto [guid, termSettings] = settings->BuildSettings(realArgs.TerminalArgs()); VERIFY_ARE_EQUAL(guid0, guid); VERIFY_ARE_EQUAL(L"cmd.exe", termSettings.Commandline()); VERIFY_ARE_EQUAL(L"c:\\foo", termSettings.StartingDirectory()); @@ -1976,7 +1980,7 @@ namespace TerminalAppLocalTests VERIFY_ARE_EQUAL(L"c:\\foo", realArgs.TerminalArgs().StartingDirectory()); VERIFY_ARE_EQUAL(L"profile2", realArgs.TerminalArgs().Profile()); - const auto [guid, termSettings] = settings.BuildSettings(realArgs.TerminalArgs()); + const auto [guid, termSettings] = settings->BuildSettings(realArgs.TerminalArgs()); VERIFY_ARE_EQUAL(profile2Guid, guid); VERIFY_ARE_EQUAL(L"wsl.exe", termSettings.Commandline()); VERIFY_ARE_EQUAL(L"c:\\foo", termSettings.StartingDirectory()); @@ -1996,7 +2000,7 @@ namespace TerminalAppLocalTests VERIFY_IS_TRUE(realArgs.TerminalArgs().Profile().empty()); VERIFY_ARE_EQUAL(L"bar", realArgs.TerminalArgs().TabTitle()); - const auto [guid, termSettings] = settings.BuildSettings(realArgs.TerminalArgs()); + const auto [guid, termSettings] = settings->BuildSettings(realArgs.TerminalArgs()); VERIFY_ARE_EQUAL(guid0, guid); VERIFY_ARE_EQUAL(L"cmd.exe", termSettings.Commandline()); VERIFY_ARE_EQUAL(L"bar", termSettings.StartingTitle()); @@ -2017,7 +2021,7 @@ namespace TerminalAppLocalTests VERIFY_ARE_EQUAL(L"bar", realArgs.TerminalArgs().TabTitle()); VERIFY_ARE_EQUAL(L"profile2", realArgs.TerminalArgs().Profile()); - const auto [guid, termSettings] = settings.BuildSettings(realArgs.TerminalArgs()); + const auto [guid, termSettings] = settings->BuildSettings(realArgs.TerminalArgs()); VERIFY_ARE_EQUAL(profile2Guid, guid); VERIFY_ARE_EQUAL(L"wsl.exe", termSettings.Commandline()); VERIFY_ARE_EQUAL(L"bar", termSettings.StartingTitle()); @@ -2040,7 +2044,7 @@ namespace TerminalAppLocalTests VERIFY_ARE_EQUAL(L"bar", realArgs.TerminalArgs().TabTitle()); VERIFY_ARE_EQUAL(L"profile1", realArgs.TerminalArgs().Profile()); - const auto [guid, termSettings] = settings.BuildSettings(realArgs.TerminalArgs()); + const auto [guid, termSettings] = settings->BuildSettings(realArgs.TerminalArgs()); VERIFY_ARE_EQUAL(guid1, guid); VERIFY_ARE_EQUAL(L"foo.exe", termSettings.Commandline()); VERIFY_ARE_EQUAL(L"bar", termSettings.StartingTitle()); @@ -2068,7 +2072,7 @@ namespace TerminalAppLocalTests ] })" }; const auto settingsJsonObj = VerifyParseSucceeded(settingsString); - auto settings = CascadiaSettings::FromJson(settingsJsonObj); + auto settings = implementation::CascadiaSettings::FromJson(settingsJsonObj); const auto guid1 = ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-1111-49a3-80bd-e8fdd045185c}"); const auto guid2 = ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-2222-49a3-80bd-e8fdd045185c}"); @@ -2106,7 +2110,7 @@ namespace TerminalAppLocalTests ] })" }; const auto settingsJsonObj = VerifyParseSucceeded(settingsString); - auto settings = CascadiaSettings::FromJson(settingsJsonObj); + auto settings = implementation::CascadiaSettings::FromJson(settingsJsonObj); settings->_ResolveDefaultProfile(); const auto guid1 = ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-1111-49a3-80bd-e8fdd045185c}"); @@ -2172,12 +2176,12 @@ namespace TerminalAppLocalTests ] })" }; const auto settingsJsonObj = VerifyParseSucceeded(settingsString); - auto settings = CascadiaSettings::FromJson(settingsJsonObj); + auto settings = implementation::CascadiaSettings::FromJson(settingsJsonObj); settings->_ValidateSettings(); VERIFY_ARE_EQUAL(2u, settings->_warnings.size()); - VERIFY_ARE_EQUAL(2u, settings->_profiles.size()); - VERIFY_ARE_EQUAL(settings->_globals->DefaultProfile(), settings->_profiles.at(0).Guid()); + VERIFY_ARE_EQUAL(2u, settings->_profiles.Size()); + VERIFY_ARE_EQUAL(settings->_globals->DefaultProfile(), settings->_profiles.GetAt(0).Guid()); try { const auto [guid, termSettings] = settings->BuildSettings(nullptr); @@ -2237,19 +2241,19 @@ namespace TerminalAppLocalTests VerifyParseSucceeded(settings0String); - CascadiaSettings settings; - settings._ParseJsonString(settings0String, false); - settings.LayerJson(settings._userSettings); + auto settings = winrt::make_self(); + settings->_ParseJsonString(settings0String, false); + settings->LayerJson(settings->_userSettings); - VERIFY_ARE_EQUAL(6u, settings._profiles.size()); - VERIFY_ARE_EQUAL(2u, settings._globals->GetColorSchemes().Size()); + VERIFY_ARE_EQUAL(6u, settings->_profiles.Size()); + VERIFY_ARE_EQUAL(2u, settings->_globals->GetColorSchemes().Size()); - auto terminalSettings0 = winrt::get_self(settings._profiles[0])->CreateTerminalSettings(settings._globals->GetColorSchemes()); - auto terminalSettings1 = winrt::get_self(settings._profiles[1])->CreateTerminalSettings(settings._globals->GetColorSchemes()); - auto terminalSettings2 = winrt::get_self(settings._profiles[2])->CreateTerminalSettings(settings._globals->GetColorSchemes()); - auto terminalSettings3 = winrt::get_self(settings._profiles[3])->CreateTerminalSettings(settings._globals->GetColorSchemes()); - auto terminalSettings4 = winrt::get_self(settings._profiles[4])->CreateTerminalSettings(settings._globals->GetColorSchemes()); - auto terminalSettings5 = winrt::get_self(settings._profiles[5])->CreateTerminalSettings(settings._globals->GetColorSchemes()); + auto terminalSettings0 = winrt::get_self(settings->_profiles.GetAt(0))->CreateTerminalSettings(settings->_globals->GetColorSchemes()); + auto terminalSettings1 = winrt::get_self(settings->_profiles.GetAt(1))->CreateTerminalSettings(settings->_globals->GetColorSchemes()); + auto terminalSettings2 = winrt::get_self(settings->_profiles.GetAt(2))->CreateTerminalSettings(settings->_globals->GetColorSchemes()); + auto terminalSettings3 = winrt::get_self(settings->_profiles.GetAt(3))->CreateTerminalSettings(settings->_globals->GetColorSchemes()); + auto terminalSettings4 = winrt::get_self(settings->_profiles.GetAt(4))->CreateTerminalSettings(settings->_globals->GetColorSchemes()); + auto terminalSettings5 = winrt::get_self(settings->_profiles.GetAt(5))->CreateTerminalSettings(settings->_globals->GetColorSchemes()); VERIFY_ARE_EQUAL(ARGB(0, 0x12, 0x34, 0x56), terminalSettings0.CursorColor()); // from color scheme VERIFY_ARE_EQUAL(DEFAULT_CURSOR_COLOR, terminalSettings1.CursorColor()); // default @@ -2282,7 +2286,7 @@ namespace TerminalAppLocalTests })" }; const auto settingsObject = VerifyParseSucceeded(badSettings); - auto settings = CascadiaSettings::FromJson(settingsObject); + auto settings = implementation::CascadiaSettings::FromJson(settingsObject); VERIFY_ARE_EQUAL(0u, settings->_globals->_keybindings->_keyShortcuts.size()); @@ -2324,7 +2328,7 @@ namespace TerminalAppLocalTests const auto settingsObject = VerifyParseSucceeded(badSettings); - auto settings = CascadiaSettings::FromJson(settingsObject); + auto settings = implementation::CascadiaSettings::FromJson(settingsObject); VERIFY_ARE_EQUAL(0u, settings->_globals->_keybindings->_keyShortcuts.size()); @@ -2367,20 +2371,20 @@ namespace TerminalAppLocalTests })" }; // Create the default settings - CascadiaSettings settings; - settings._ParseJsonString(DefaultJson, true); - settings.LayerJson(settings._defaultSettings); + auto settings = winrt::make_self(); + settings->_ParseJsonString(DefaultJson, true); + settings->LayerJson(settings->_defaultSettings); - settings._ValidateNoGlobalsKey(); - VERIFY_ARE_EQUAL(0u, settings._warnings.size()); + settings->_ValidateNoGlobalsKey(); + VERIFY_ARE_EQUAL(0u, settings->_warnings.size()); // Now layer on the user's settings - settings._ParseJsonString(badSettings, false); - settings.LayerJson(settings._userSettings); + settings->_ParseJsonString(badSettings, false); + settings->LayerJson(settings->_userSettings); - settings._ValidateNoGlobalsKey(); - VERIFY_ARE_EQUAL(1u, settings._warnings.size()); - VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::LegacyGlobalsProperty, settings._warnings.at(0)); + settings->_ValidateNoGlobalsKey(); + VERIFY_ARE_EQUAL(1u, settings->_warnings.size()); + VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::LegacyGlobalsProperty, settings->_warnings.at(0)); } void SettingsTests::TestTrailingCommas() @@ -2402,15 +2406,15 @@ namespace TerminalAppLocalTests })" }; // Create the default settings - CascadiaSettings settings; - settings._ParseJsonString(DefaultJson, true); - settings.LayerJson(settings._defaultSettings); + auto settings = winrt::make_self(); + settings->_ParseJsonString(DefaultJson, true); + settings->LayerJson(settings->_defaultSettings); // Now layer on the user's settings try { - settings._ParseJsonString(badSettings, false); - settings.LayerJson(settings._userSettings); + settings->_ParseJsonString(badSettings, false); + settings->LayerJson(settings->_userSettings); } catch (...) { @@ -2456,23 +2460,24 @@ namespace TerminalAppLocalTests const auto guid1 = ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-1111-49a3-80bd-e8fdd045185c}"); VerifyParseSucceeded(settingsJson); - CascadiaSettings settings{}; - settings._ParseJsonString(settingsJson, false); - settings.LayerJson(settings._userSettings); - settings._ValidateSettings(); - VERIFY_ARE_EQUAL(3u, settings.GetProfiles().size()); + auto settings = winrt::make_self(); + settings->_ParseJsonString(settingsJson, false); + settings->LayerJson(settings->_userSettings); + settings->_ValidateSettings(); - const auto profile2Guid = settings._profiles.at(2).Guid(); + VERIFY_ARE_EQUAL(3u, settings->_profiles.Size()); + + const auto profile2Guid = settings->_profiles.GetAt(2).Guid(); VERIFY_ARE_NOT_EQUAL(winrt::guid{}, profile2Guid); - auto appKeyBindings = winrt::get_self(settings._globals->GetKeybindings()); + auto appKeyBindings = winrt::get_self(settings->_globals->GetKeybindings()); VERIFY_ARE_EQUAL(5u, appKeyBindings->_keyShortcuts.size()); // A/D, B, C, E will be in the list of commands, for 4 total. // * A and D share the same name, so they'll only generate a single action. // * F's name is set manually to `null` - auto commands = settings._globals->GetCommands(); + auto commands = settings->_globals->GetCommands(); VERIFY_ARE_EQUAL(4u, commands.Size()); { @@ -2658,15 +2663,16 @@ namespace TerminalAppLocalTests const auto guid1 = ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-1111-49a3-80bd-e8fdd045185c}"); VerifyParseSucceeded(settingsJson); - CascadiaSettings settings{}; - settings._ParseJsonString(settingsJson, false); - settings.LayerJson(settings._userSettings); - VERIFY_ARE_EQUAL(0u, settings._warnings.size()); + auto settings = winrt::make_self(); + settings->_ParseJsonString(settingsJson, false); + settings->LayerJson(settings->_userSettings); + + VERIFY_ARE_EQUAL(0u, settings->_warnings.size()); - VERIFY_ARE_EQUAL(3u, settings.GetProfiles().size()); + VERIFY_ARE_EQUAL(3u, settings->_profiles.Size()); - auto commands = settings._globals->GetCommands(); + auto commands = settings->_globals->GetCommands(); VERIFY_ARE_EQUAL(1u, commands.Size()); { @@ -2687,10 +2693,10 @@ namespace TerminalAppLocalTests VERIFY_ARE_EQUAL(L"${profile.name}", realArgs.TerminalArgs().Profile()); } - auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands, settings.GetProfiles(), settings._globals->GetColorSchemes()); + auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands, settings->Profiles().GetView(), settings->_globals->GetColorSchemes()); _logCommandNames(expandedCommands.GetView()); - VERIFY_ARE_EQUAL(0u, settings._warnings.size()); + VERIFY_ARE_EQUAL(0u, settings->_warnings.size()); VERIFY_ARE_EQUAL(3u, expandedCommands.Size()); { @@ -2788,15 +2794,16 @@ namespace TerminalAppLocalTests const auto guid1 = ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-1111-49a3-80bd-e8fdd045185c}"); VerifyParseSucceeded(settingsJson); - CascadiaSettings settings{}; - settings._ParseJsonString(settingsJson, false); - settings.LayerJson(settings._userSettings); - VERIFY_ARE_EQUAL(0u, settings._warnings.size()); + auto settings = winrt::make_self(); + settings->_ParseJsonString(settingsJson, false); + settings->LayerJson(settings->_userSettings); + + VERIFY_ARE_EQUAL(0u, settings->_warnings.size()); - VERIFY_ARE_EQUAL(3u, settings.GetProfiles().size()); + VERIFY_ARE_EQUAL(3u, settings->_profiles.Size()); - auto commands = settings._globals->GetCommands(); + auto commands = settings->_globals->GetCommands(); VERIFY_ARE_EQUAL(1u, commands.Size()); { @@ -2817,10 +2824,10 @@ namespace TerminalAppLocalTests VERIFY_ARE_EQUAL(L"${profile.name}", realArgs.TerminalArgs().Profile()); } - auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands, settings.GetProfiles(), settings._globals->GetColorSchemes()); + auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands, settings->Profiles().GetView(), settings->_globals->GetColorSchemes()); _logCommandNames(expandedCommands.GetView()); - VERIFY_ARE_EQUAL(0u, settings._warnings.size()); + VERIFY_ARE_EQUAL(0u, settings->_warnings.size()); VERIFY_ARE_EQUAL(3u, expandedCommands.Size()); { @@ -2920,15 +2927,16 @@ namespace TerminalAppLocalTests const auto guid1 = ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-1111-49a3-80bd-e8fdd045185c}"); VerifyParseSucceeded(settingsJson); - CascadiaSettings settings{}; - settings._ParseJsonString(settingsJson, false); - settings.LayerJson(settings._userSettings); - VERIFY_ARE_EQUAL(0u, settings._warnings.size()); + auto settings = winrt::make_self(); + settings->_ParseJsonString(settingsJson, false); + settings->LayerJson(settings->_userSettings); - VERIFY_ARE_EQUAL(3u, settings.GetProfiles().size()); + VERIFY_ARE_EQUAL(0u, settings->_warnings.size()); - auto commands = settings._globals->GetCommands(); + VERIFY_ARE_EQUAL(3u, settings->_profiles.Size()); + + auto commands = settings->_globals->GetCommands(); VERIFY_ARE_EQUAL(1u, commands.Size()); { @@ -2949,11 +2957,11 @@ namespace TerminalAppLocalTests VERIFY_ARE_EQUAL(L"${profile.name}", realArgs.TerminalArgs().Profile()); } - settings._ValidateSettings(); - auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands, settings.GetProfiles(), settings._globals->GetColorSchemes()); + settings->_ValidateSettings(); + auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands, settings->Profiles().GetView(), settings->_globals->GetColorSchemes()); _logCommandNames(expandedCommands.GetView()); - VERIFY_ARE_EQUAL(0u, settings._warnings.size()); + VERIFY_ARE_EQUAL(0u, settings->_warnings.size()); VERIFY_ARE_EQUAL(3u, expandedCommands.Size()); { @@ -3062,19 +3070,20 @@ namespace TerminalAppLocalTests })" }; VerifyParseSucceeded(settingsJson); - CascadiaSettings settings{}; - settings._ParseJsonString(settingsJson, false); - settings.LayerJson(settings._userSettings); - VERIFY_ARE_EQUAL(0u, settings._warnings.size()); - VERIFY_ARE_EQUAL(3u, settings.GetProfiles().size()); + auto settings = winrt::make_self(); + settings->_ParseJsonString(settingsJson, false); + settings->LayerJson(settings->_userSettings); + + VERIFY_ARE_EQUAL(0u, settings->_warnings.size()); + VERIFY_ARE_EQUAL(3u, settings->_profiles.Size()); - auto commands = settings._globals->GetCommands(); - settings._ValidateSettings(); - auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands, settings.GetProfiles(), settings._globals->GetColorSchemes()); + auto commands = settings->_globals->GetCommands(); + settings->_ValidateSettings(); + auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands, settings->Profiles().GetView(), settings->_globals->GetColorSchemes()); _logCommandNames(expandedCommands.GetView()); - VERIFY_ARE_EQUAL(0u, settings._warnings.size()); + VERIFY_ARE_EQUAL(0u, settings->_warnings.size()); VERIFY_ARE_EQUAL(1u, expandedCommands.Size()); auto rootCommandProj = expandedCommands.Lookup(L"Connect to ssh..."); @@ -3170,19 +3179,20 @@ namespace TerminalAppLocalTests })" }; VerifyParseSucceeded(settingsJson); - CascadiaSettings settings{}; - settings._ParseJsonString(settingsJson, false); - settings.LayerJson(settings._userSettings); - VERIFY_ARE_EQUAL(0u, settings._warnings.size()); - VERIFY_ARE_EQUAL(3u, settings.GetProfiles().size()); + auto settings = winrt::make_self(); + settings->_ParseJsonString(settingsJson, false); + settings->LayerJson(settings->_userSettings); + + VERIFY_ARE_EQUAL(0u, settings->_warnings.size()); + VERIFY_ARE_EQUAL(3u, settings->_profiles.Size()); - auto commands = settings._globals->GetCommands(); - settings._ValidateSettings(); - auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands, settings.GetProfiles(), settings._globals->GetColorSchemes()); + auto commands = settings->_globals->GetCommands(); + settings->_ValidateSettings(); + auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands, settings->Profiles().GetView(), settings->_globals->GetColorSchemes()); _logCommandNames(expandedCommands.GetView()); - VERIFY_ARE_EQUAL(0u, settings._warnings.size()); + VERIFY_ARE_EQUAL(0u, settings->_warnings.size()); VERIFY_ARE_EQUAL(1u, expandedCommands.Size()); auto grandparentCommandProj = expandedCommands.Lookup(L"grandparent"); @@ -3309,19 +3319,20 @@ namespace TerminalAppLocalTests })" }; VerifyParseSucceeded(settingsJson); - CascadiaSettings settings{}; - settings._ParseJsonString(settingsJson, false); - settings.LayerJson(settings._userSettings); - VERIFY_ARE_EQUAL(0u, settings._warnings.size()); - VERIFY_ARE_EQUAL(3u, settings.GetProfiles().size()); + auto settings = winrt::make_self(); + settings->_ParseJsonString(settingsJson, false); + settings->LayerJson(settings->_userSettings); - auto commands = settings._globals->GetCommands(); - settings._ValidateSettings(); - auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands, settings.GetProfiles(), settings._globals->GetColorSchemes()); + VERIFY_ARE_EQUAL(0u, settings->_warnings.size()); + VERIFY_ARE_EQUAL(3u, settings->_profiles.Size()); + + auto commands = settings->_globals->GetCommands(); + settings->_ValidateSettings(); + auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands, settings->Profiles().GetView(), settings->_globals->GetColorSchemes()); _logCommandNames(expandedCommands.GetView()); - VERIFY_ARE_EQUAL(0u, settings._warnings.size()); + VERIFY_ARE_EQUAL(0u, settings->_warnings.size()); VERIFY_ARE_EQUAL(3u, expandedCommands.Size()); @@ -3462,19 +3473,20 @@ namespace TerminalAppLocalTests })" }; VerifyParseSucceeded(settingsJson); - CascadiaSettings settings{}; - settings._ParseJsonString(settingsJson, false); - settings.LayerJson(settings._userSettings); - VERIFY_ARE_EQUAL(0u, settings._warnings.size()); - VERIFY_ARE_EQUAL(3u, settings.GetProfiles().size()); + auto settings = winrt::make_self(); + settings->_ParseJsonString(settingsJson, false); + settings->LayerJson(settings->_userSettings); - auto commands = settings._globals->GetCommands(); - settings._ValidateSettings(); - auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands, settings.GetProfiles(), settings._globals->GetColorSchemes()); + VERIFY_ARE_EQUAL(0u, settings->_warnings.size()); + VERIFY_ARE_EQUAL(3u, settings->_profiles.Size()); + + auto commands = settings->_globals->GetCommands(); + settings->_ValidateSettings(); + auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands, settings->Profiles().GetView(), settings->_globals->GetColorSchemes()); _logCommandNames(expandedCommands.GetView()); - VERIFY_ARE_EQUAL(0u, settings._warnings.size()); + VERIFY_ARE_EQUAL(0u, settings->_warnings.size()); VERIFY_ARE_EQUAL(1u, expandedCommands.Size()); auto rootCommandProj = expandedCommands.Lookup(L"New Tab With Profile..."); @@ -3575,19 +3587,20 @@ namespace TerminalAppLocalTests })" }; VerifyParseSucceeded(settingsJson); - CascadiaSettings settings{}; - settings._ParseJsonString(settingsJson, false); - settings.LayerJson(settings._userSettings); - VERIFY_ARE_EQUAL(0u, settings._warnings.size()); - VERIFY_ARE_EQUAL(3u, settings.GetProfiles().size()); + auto settings = winrt::make_self(); + settings->_ParseJsonString(settingsJson, false); + settings->LayerJson(settings->_userSettings); + + VERIFY_ARE_EQUAL(0u, settings->_warnings.size()); + VERIFY_ARE_EQUAL(3u, settings->_profiles.Size()); - auto commands = settings._globals->GetCommands(); - settings._ValidateSettings(); - auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands, settings.GetProfiles(), settings._globals->GetColorSchemes()); + auto commands = settings->_globals->GetCommands(); + settings->_ValidateSettings(); + auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands, settings->Profiles().GetView(), settings->_globals->GetColorSchemes()); _logCommandNames(expandedCommands.GetView()); - VERIFY_ARE_EQUAL(0u, settings._warnings.size()); + VERIFY_ARE_EQUAL(0u, settings->_warnings.size()); VERIFY_ARE_EQUAL(1u, expandedCommands.Size()); auto rootCommandProj = expandedCommands.Lookup(L"New Pane..."); @@ -3736,18 +3749,19 @@ namespace TerminalAppLocalTests })" }; VerifyParseSucceeded(settingsJson); - CascadiaSettings settings{}; - settings._ParseJsonString(settingsJson, false); - settings.LayerJson(settings._userSettings); - VERIFY_ARE_EQUAL(0u, settings._warnings.size()); - VERIFY_ARE_EQUAL(3u, settings.GetProfiles().size()); + auto settings = winrt::make_self(); + settings->_ParseJsonString(settingsJson, false); + settings->LayerJson(settings->_userSettings); + + VERIFY_ARE_EQUAL(0u, settings->_warnings.size()); + VERIFY_ARE_EQUAL(3u, settings->_profiles.Size()); - auto commands = settings._globals->GetCommands(); - settings._ValidateSettings(); + auto commands = settings->_globals->GetCommands(); + settings->_ValidateSettings(); _logCommandNames(commands); - VERIFY_ARE_EQUAL(0u, settings._warnings.size()); + VERIFY_ARE_EQUAL(0u, settings->_warnings.size()); // Because the "parent" command didn't have a name, it couldn't be // placed into the list of commands. It and it's children are just @@ -3813,27 +3827,27 @@ namespace TerminalAppLocalTests VerifyParseSucceeded(settingsJson); VerifyParseSucceeded(settings1Json); - CascadiaSettings settings{}; - settings._ParseJsonString(settingsJson, false); - settings.LayerJson(settings._userSettings); + auto settings = winrt::make_self(); + settings->_ParseJsonString(settingsJson, false); + settings->LayerJson(settings->_userSettings); - VERIFY_ARE_EQUAL(0u, settings._warnings.size()); - VERIFY_ARE_EQUAL(3u, settings.GetProfiles().size()); + VERIFY_ARE_EQUAL(0u, settings->_warnings.size()); + VERIFY_ARE_EQUAL(3u, settings->_profiles.Size()); - auto commands = settings._globals->GetCommands(); - settings._ValidateSettings(); + auto commands = settings->_globals->GetCommands(); + settings->_ValidateSettings(); _logCommandNames(commands); - VERIFY_ARE_EQUAL(0u, settings._warnings.size()); + VERIFY_ARE_EQUAL(0u, settings->_warnings.size()); VERIFY_ARE_EQUAL(1u, commands.Size()); Log::Comment(L"Layer second bit of json, to unbind the original command."); - settings._ParseJsonString(settings1Json, false); - settings.LayerJson(settings._userSettings); - settings._ValidateSettings(); + settings->_ParseJsonString(settings1Json, false); + settings->LayerJson(settings->_userSettings); + settings->_ValidateSettings(); _logCommandNames(commands); - VERIFY_ARE_EQUAL(0u, settings._warnings.size()); + VERIFY_ARE_EQUAL(0u, settings->_warnings.size()); VERIFY_ARE_EQUAL(0u, commands.Size()); } @@ -3896,18 +3910,18 @@ namespace TerminalAppLocalTests VerifyParseSucceeded(settingsJson); VerifyParseSucceeded(settings1Json); - CascadiaSettings settings{}; - settings._ParseJsonString(settingsJson, false); - settings.LayerJson(settings._userSettings); + auto settings = winrt::make_self(); + settings->_ParseJsonString(settingsJson, false); + settings->LayerJson(settings->_userSettings); - VERIFY_ARE_EQUAL(0u, settings._warnings.size()); - VERIFY_ARE_EQUAL(3u, settings.GetProfiles().size()); + VERIFY_ARE_EQUAL(0u, settings->_warnings.size()); + VERIFY_ARE_EQUAL(3u, settings->_profiles.Size()); - auto commands = settings._globals->GetCommands(); - settings._ValidateSettings(); + auto commands = settings->_globals->GetCommands(); + settings->_ValidateSettings(); _logCommandNames(commands); - VERIFY_ARE_EQUAL(0u, settings._warnings.size()); + VERIFY_ARE_EQUAL(0u, settings->_warnings.size()); VERIFY_ARE_EQUAL(1u, commands.Size()); { @@ -3923,11 +3937,11 @@ namespace TerminalAppLocalTests } Log::Comment(L"Layer second bit of json, to unbind the original command."); - settings._ParseJsonString(settings1Json, false); - settings.LayerJson(settings._userSettings); - settings._ValidateSettings(); + settings->_ParseJsonString(settings1Json, false); + settings->LayerJson(settings->_userSettings); + settings->_ValidateSettings(); _logCommandNames(commands); - VERIFY_ARE_EQUAL(0u, settings._warnings.size()); + VERIFY_ARE_EQUAL(0u, settings->_warnings.size()); VERIFY_ARE_EQUAL(1u, commands.Size()); { @@ -3991,15 +4005,16 @@ namespace TerminalAppLocalTests })" }; VerifyParseSucceeded(settingsJson); - CascadiaSettings settings{}; - settings._ParseJsonString(settingsJson, false); - settings.LayerJson(settings._userSettings); - VERIFY_ARE_EQUAL(0u, settings._warnings.size()); + auto settings = winrt::make_self(); + settings->_ParseJsonString(settingsJson, false); + settings->LayerJson(settings->_userSettings); + + VERIFY_ARE_EQUAL(0u, settings->_warnings.size()); - VERIFY_ARE_EQUAL(3u, settings.GetProfiles().size()); + VERIFY_ARE_EQUAL(3u, settings->_profiles.Size()); - auto commands = settings._globals->GetCommands(); + auto commands = settings->_globals->GetCommands(); VERIFY_ARE_EQUAL(1u, commands.Size()); { @@ -4020,10 +4035,10 @@ namespace TerminalAppLocalTests VERIFY_ARE_EQUAL(L"${scheme.name}", realArgs.TerminalArgs().Profile()); } - auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands, settings.GetProfiles(), settings._globals->GetColorSchemes()); + auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands, settings->Profiles().GetView(), settings->_globals->GetColorSchemes()); _logCommandNames(expandedCommands.GetView()); - VERIFY_ARE_EQUAL(0u, settings._warnings.size()); + VERIFY_ARE_EQUAL(0u, settings->_warnings.size()); VERIFY_ARE_EQUAL(3u, expandedCommands.Size()); // Yes, this test is testing splitPane with profiles named after each diff --git a/src/cascadia/LocalTests_TerminalApp/TabTests.cpp b/src/cascadia/LocalTests_TerminalApp/TabTests.cpp index e9042847628..4b98b1a9552 100644 --- a/src/cascadia/LocalTests_TerminalApp/TabTests.cpp +++ b/src/cascadia/LocalTests_TerminalApp/TabTests.cpp @@ -75,7 +75,7 @@ namespace TerminalAppLocalTests private: void _initializeTerminalPage(winrt::com_ptr& page, - std::shared_ptr initialSettings); + winrt::com_ptr& initialSettings); }; void TabTests::EnsureTestsActivate() @@ -190,7 +190,7 @@ namespace TerminalAppLocalTests // Return Value: // - void TabTests::_initializeTerminalPage(winrt::com_ptr& page, - std::shared_ptr initialSettings) + winrt::com_ptr& initialSettings) { // This is super wacky, but we can't just initialize the // com_ptr in the lambda and assign it back out of @@ -206,7 +206,7 @@ namespace TerminalAppLocalTests auto result = RunOnUIThread([&projectedPage, &page, initialSettings]() { projectedPage = winrt::TerminalApp::TerminalPage(); page.copy_from(winrt::get_self(projectedPage)); - page->_settings = initialSettings; + page->_settings = *initialSettings; }); VERIFY_SUCCEEDED(result); @@ -277,7 +277,7 @@ namespace TerminalAppLocalTests })" }; VerifyParseSucceeded(settingsJson0); - auto settings0 = std::make_shared(false); + auto settings0 = winrt::make_self(false); VERIFY_IS_NOT_NULL(settings0); settings0->_ParseJsonString(settingsJson0, false); settings0->LayerJson(settings0->_userSettings); @@ -339,14 +339,14 @@ namespace TerminalAppLocalTests })" }; VerifyParseSucceeded(settingsJson0); - auto settings0 = std::make_shared(false); + auto settings0 = winrt::make_self(false); VERIFY_IS_NOT_NULL(settings0); settings0->_ParseJsonString(settingsJson0, false); settings0->LayerJson(settings0->_userSettings); settings0->_ValidateSettings(); VerifyParseSucceeded(settingsJson1); - auto settings1 = std::make_shared(false); + auto settings1 = winrt::make_self(false); VERIFY_IS_NOT_NULL(settings1); settings1->_ParseJsonString(settingsJson1, false); settings1->LayerJson(settings1->_userSettings); @@ -383,7 +383,7 @@ namespace TerminalAppLocalTests L"Change the settings of the TerminalPage so the first profile is " L"no longer in the list of profiles")); result = RunOnUIThread([&page, settings1]() { - page->_settings = settings1; + page->_settings = *settings1; }); VERIFY_SUCCEEDED(result); @@ -434,14 +434,14 @@ namespace TerminalAppLocalTests })" }; VerifyParseSucceeded(settingsJson0); - auto settings0 = std::make_shared(false); + auto settings0 = winrt::make_self(false); VERIFY_IS_NOT_NULL(settings0); settings0->_ParseJsonString(settingsJson0, false); settings0->LayerJson(settings0->_userSettings); settings0->_ValidateSettings(); VerifyParseSucceeded(settingsJson1); - auto settings1 = std::make_shared(false); + auto settings1 = winrt::make_self(false); VERIFY_IS_NOT_NULL(settings1); settings1->_ParseJsonString(settingsJson1, false); settings1->LayerJson(settings1->_userSettings); @@ -488,7 +488,7 @@ namespace TerminalAppLocalTests L"Change the settings of the TerminalPage so the first profile is " L"no longer in the list of profiles")); result = RunOnUIThread([&page, settings1]() { - page->_settings = settings1; + page->_settings = *settings1; }); VERIFY_SUCCEEDED(result); diff --git a/src/cascadia/TerminalApp/AppActionHandlers.cpp b/src/cascadia/TerminalApp/AppActionHandlers.cpp index 8770f6037dc..4860b9d9135 100644 --- a/src/cascadia/TerminalApp/AppActionHandlers.cpp +++ b/src/cascadia/TerminalApp/AppActionHandlers.cpp @@ -320,7 +320,8 @@ namespace winrt::TerminalApp::implementation if (auto activeControl = activeTab->GetActiveTerminalControl()) { auto controlSettings = activeControl.Settings(); - if (_settings->ApplyColorScheme(controlSettings, realArgs.SchemeName())) + const auto settingsImpl{ winrt::get_self(_settings) }; + if (settingsImpl->ApplyColorScheme(controlSettings, realArgs.SchemeName())) { activeControl.UpdateSettings(controlSettings); args.Handled(true); diff --git a/src/cascadia/TerminalApp/AppLogic.cpp b/src/cascadia/TerminalApp/AppLogic.cpp index 2c217e50b7c..1b9c1304113 100644 --- a/src/cascadia/TerminalApp/AppLogic.cpp +++ b/src/cascadia/TerminalApp/AppLogic.cpp @@ -165,6 +165,17 @@ namespace winrt::TerminalApp::implementation return nullptr; } + // Method Description: + // - Returns the settings currently in use by the entire Terminal application. + // Throws: + // - HR E_INVALIDARG if the app isn't up and running. + const TerminalApp::CascadiaSettings AppLogic::CurrentAppSettings() + { + auto appLogic{ ::winrt::TerminalApp::implementation::AppLogic::Current() }; + THROW_HR_IF_NULL(E_INVALIDARG, appLogic); + return appLogic->GetSettings(); + } + AppLogic::AppLogic() : _dialogLock{}, _loadedInitialSettings{ false }, @@ -238,7 +249,7 @@ namespace winrt::TerminalApp::implementation // so this setting is overridden to false no matter what the preference is. if (_isUwp) { - _settings->GlobalSettings().ShowTabsInTitlebar(false); + _settings.GlobalSettings().ShowTabsInTitlebar(false); } _root->SetSettings(_settings, false); @@ -256,14 +267,14 @@ namespace winrt::TerminalApp::implementation }); _root->Create(); - _ApplyTheme(_settings->GlobalSettings().Theme()); + _ApplyTheme(_settings.GlobalSettings().Theme()); _ApplyStartupTaskStateChange(); TraceLoggingWrite( g_hTerminalAppProvider, "AppCreated", TraceLoggingDescription("Event emitted when the application is started"), - TraceLoggingBool(_settings->GlobalSettings().ShowTabsInTitlebar(), "TabsInTitlebar"), + TraceLoggingBool(_settings.GlobalSettings().ShowTabsInTitlebar(), "TabsInTitlebar"), TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance)); } @@ -310,7 +321,7 @@ namespace winrt::TerminalApp::implementation // details here, but it does have the desired effect. // It's not enough to set the theme on the dialog alone. auto themingLambda{ [this](const Windows::Foundation::IInspectable& sender, const RoutedEventArgs&) { - auto theme{ _settings->GlobalSettings().Theme() }; + auto theme{ _settings.GlobalSettings().Theme() }; auto element{ sender.try_as() }; while (element) { @@ -400,7 +411,8 @@ namespace winrt::TerminalApp::implementation // Make sure the lines of text wrap warningsTextBlock.TextWrapping(TextWrapping::Wrap); - const auto& warnings = _settings->GetWarnings(); + const auto settingsImpl{ winrt::get_self(_settings) }; + const auto& warnings = settingsImpl->GetWarnings(); for (const auto& warning : warnings) { // Try looking up the warning message key for each warning. @@ -483,7 +495,8 @@ namespace winrt::TerminalApp::implementation } // Use the default profile to determine how big of a window we need. - const auto [_, settings] = _settings->BuildSettings(nullptr); + const auto settingsImpl{ winrt::get_self(_settings) }; + const auto [_, settings] = settingsImpl->BuildSettings(nullptr); auto proposedSize = TermControl::GetProposedDimensions(settings, dpi); @@ -492,7 +505,7 @@ namespace winrt::TerminalApp::implementation // GH#2061 - If the global setting "Always show tab bar" is // set or if "Show tabs in title bar" is set, then we'll need to add // the height of the tab bar here. - if (_settings->GlobalSettings().ShowTabsInTitlebar()) + if (_settings.GlobalSettings().ShowTabsInTitlebar()) { // If we're showing the tabs in the titlebar, we need to use a // TitlebarControl here to calculate how much space to reserve. @@ -506,7 +519,7 @@ namespace winrt::TerminalApp::implementation titlebar.Measure({ SHRT_MAX, SHRT_MAX }); proposedSize.Height += (titlebar.DesiredSize().Height) * scale; } - else if (_settings->GlobalSettings().AlwaysShowTabs()) + else if (_settings.GlobalSettings().AlwaysShowTabs()) { // Otherwise, let's use a TabRowControl to calculate how much extra // space we'll need. @@ -544,7 +557,7 @@ namespace winrt::TerminalApp::implementation // GH#4620/#5801 - If the user passed --maximized or --fullscreen on the // commandline, then use that to override the value from the settings. - const auto valueFromSettings = _settings->GlobalSettings().LaunchMode(); + const auto valueFromSettings = _settings.GlobalSettings().LaunchMode(); const auto valueFromCommandlineArgs = _appArgs.GetLaunchMode(); return valueFromCommandlineArgs.has_value() ? valueFromCommandlineArgs.value() : @@ -569,7 +582,7 @@ namespace winrt::TerminalApp::implementation LoadSettings(); } - const auto initialPosition{ _settings->GlobalSettings().InitialPosition() }; + const auto initialPosition{ _settings.GlobalSettings().InitialPosition() }; return { initialPosition.X ? initialPosition.X.Value() : defaultInitialX, initialPosition.Y ? initialPosition.Y.Value() : defaultInitialY @@ -584,7 +597,7 @@ namespace winrt::TerminalApp::implementation LoadSettings(); } - return _settings->GlobalSettings().Theme(); + return _settings.GlobalSettings().Theme(); } bool AppLogic::GetShowTabsInTitlebar() @@ -595,7 +608,7 @@ namespace winrt::TerminalApp::implementation LoadSettings(); } - return _settings->GlobalSettings().ShowTabsInTitlebar(); + return _settings.GlobalSettings().ShowTabsInTitlebar(); } // Method Description: @@ -616,8 +629,10 @@ namespace winrt::TerminalApp::implementation try { auto newSettings = _isUwp ? CascadiaSettings::LoadUniversal() : CascadiaSettings::LoadAll(); - _settings = std::move(newSettings); - const auto& warnings = _settings->GetWarnings(); + _settings = newSettings; + + const auto settingsImpl{ winrt::get_self(_settings) }; + const auto& warnings = settingsImpl->GetWarnings(); hr = warnings.size() == 0 ? S_OK : S_FALSE; } catch (const winrt::hresult_error& e) @@ -694,7 +709,7 @@ namespace winrt::TerminalApp::implementation // Register for directory change notification. _RegisterSettingsChange(); - Jumplist::UpdateJumplist(*_settings); + Jumplist::UpdateJumplist(_settings); } // Method Description: @@ -773,7 +788,7 @@ namespace winrt::TerminalApp::implementation co_await winrt::resume_foreground(_root->Dispatcher()); // Refresh the UI theme - _ApplyTheme(_settings->GlobalSettings().Theme()); + _ApplyTheme(_settings.GlobalSettings().Theme()); } fire_and_forget AppLogic::_ApplyStartupTaskStateChange() @@ -792,7 +807,7 @@ namespace winrt::TerminalApp::implementation if (auto page{ weakThis.get() }) { StartupTaskState state; - bool tryEnableStartupTask = _settings->GlobalSettings().StartOnUserLogin(); + bool tryEnableStartupTask = _settings.GlobalSettings().StartOnUserLogin(); StartupTask task = co_await StartupTask::GetAsync(StartupTaskName); state = task.State(); @@ -854,12 +869,12 @@ namespace winrt::TerminalApp::implementation _RefreshThemeRoutine(); _ApplyStartupTaskStateChange(); - Jumplist::UpdateJumplist(*_settings); + Jumplist::UpdateJumplist(_settings); } // Method Description: // - Returns a pointer to the global shared settings. - [[nodiscard]] std::shared_ptr<::TerminalApp::CascadiaSettings> AppLogic::GetSettings() const noexcept + [[nodiscard]] TerminalApp::CascadiaSettings AppLogic::GetSettings() const noexcept { return _settings; } diff --git a/src/cascadia/TerminalApp/AppLogic.h b/src/cascadia/TerminalApp/AppLogic.h index 18204401fdc..192f7330ce3 100644 --- a/src/cascadia/TerminalApp/AppLogic.h +++ b/src/cascadia/TerminalApp/AppLogic.h @@ -17,6 +17,7 @@ namespace winrt::TerminalApp::implementation { public: static AppLogic* Current() noexcept; + static const TerminalApp::CascadiaSettings CurrentAppSettings(); AppLogic(); ~AppLogic() = default; @@ -26,7 +27,7 @@ namespace winrt::TerminalApp::implementation void RunAsUwp(); bool IsElevated() const noexcept; void LoadSettings(); - [[nodiscard]] std::shared_ptr<::TerminalApp::CascadiaSettings> GetSettings() const noexcept; + [[nodiscard]] TerminalApp::CascadiaSettings GetSettings() const noexcept; int32_t SetStartupCommandline(array_view actions); winrt::hstring ParseCommandlineMessage(); @@ -69,7 +70,7 @@ namespace winrt::TerminalApp::implementation // updated in _ApplyTheme. The root currently is _root. winrt::com_ptr _root{ nullptr }; - std::shared_ptr<::TerminalApp::CascadiaSettings> _settings{ nullptr }; + TerminalApp::CascadiaSettings _settings{ nullptr }; HRESULT _settingsLoadedResult; winrt::hstring _settingsLoadExceptionText{}; diff --git a/src/cascadia/TerminalApp/CascadiaSettings.cpp b/src/cascadia/TerminalApp/CascadiaSettings.cpp index 73bcc0e903c..66e2f8a2607 100644 --- a/src/cascadia/TerminalApp/CascadiaSettings.cpp +++ b/src/cascadia/TerminalApp/CascadiaSettings.cpp @@ -17,9 +17,12 @@ #include "WslDistroGenerator.h" #include "AzureCloudShellGenerator.h" +#include "CascadiaSettings.g.cpp" + using namespace ::TerminalApp; using namespace winrt::Microsoft::Terminal::TerminalControl; -using namespace winrt::TerminalApp; +using namespace winrt::TerminalApp::implementation; +using namespace winrt::Windows::Foundation::Collections; using namespace Microsoft::Console; static constexpr std::wstring_view PACKAGED_PROFILE_ICON_PATH{ L"ms-appx:///ProfileIcons/" }; @@ -30,17 +33,6 @@ static constexpr std::wstring_view DEFAULT_LINUX_ICON_GUID{ L"{9acb9455-ca41-5af // make sure this matches defaults.json. static constexpr std::wstring_view DEFAULT_WINDOWS_POWERSHELL_GUID{ L"{61c54bbd-c2c6-5271-96e7-009a87ff44bf}" }; -// Method Description: -// - Returns the settings currently in use by the entire Terminal application. -// Throws: -// - HR E_INVALIDARG if the app isn't up and running. -const CascadiaSettings& CascadiaSettings::GetCurrentAppSettings() -{ - auto appLogic{ ::winrt::TerminalApp::implementation::AppLogic::Current() }; - THROW_HR_IF_NULL(E_INVALIDARG, appLogic); - return *(appLogic->GetSettings()); -} - CascadiaSettings::CascadiaSettings() : CascadiaSettings(true) { @@ -53,7 +45,8 @@ CascadiaSettings::CascadiaSettings() : // Arguments: // - addDynamicProfiles: if true, we'll add the built-in DPGs. CascadiaSettings::CascadiaSettings(const bool addDynamicProfiles) : - _globals{ winrt::make_self() } + _globals{ winrt::make_self() }, + _profiles{ winrt::single_threaded_observable_vector() } { if (addDynamicProfiles) { @@ -71,10 +64,10 @@ CascadiaSettings::CascadiaSettings(const bool addDynamicProfiles) : // Return Value: // - a non-ownership pointer to the profile matching the given guid, or nullptr // if there is no match. -const Profile CascadiaSettings::FindProfile(winrt::guid profileGuid) const noexcept +winrt::TerminalApp::Profile CascadiaSettings::FindProfile(winrt::guid profileGuid) const noexcept { const winrt::guid guid{ profileGuid }; - for (auto& profile : _profiles) + for (auto profile : _profiles) { try { @@ -94,9 +87,9 @@ const Profile CascadiaSettings::FindProfile(winrt::guid profileGuid) const noexc // - // Return Value: // - an iterable collection of all of our Profiles. -gsl::span CascadiaSettings::GetProfiles() const noexcept +IObservableVector CascadiaSettings::Profiles() const noexcept { - return { &_profiles[0], _profiles.size() }; + return _profiles; } // Method Description: @@ -105,7 +98,7 @@ gsl::span CascadiaSettings::GetProfiles() const noexcept // - // Return Value: // - the globally configured keybindings -AppKeyBindings CascadiaSettings::GetKeybindings() const noexcept +winrt::TerminalApp::AppKeyBindings CascadiaSettings::Keybindings() const noexcept { return _globals->GetKeybindings(); } @@ -196,7 +189,7 @@ void CascadiaSettings::_ValidateSettings() // profiles at all, we'll throw an error if there aren't any profiles. void CascadiaSettings::_ValidateProfilesExist() { - const bool hasProfiles = !_profiles.empty(); + const bool hasProfiles = _profiles.Size() > 0; if (!hasProfiles) { // Throw an exception. This is an invalid state, and we want the app to @@ -215,7 +208,7 @@ void CascadiaSettings::_ValidateProfilesExist() // temporary runtime GUID for it. This validation does not add any warnings. void CascadiaSettings::_ValidateProfilesHaveGuid() { - for (auto& profile : _profiles) + for (auto profile : _profiles) { auto profileImpl = winrt::get_self(profile); profileImpl->GenerateGuidIfNecessary(); @@ -264,7 +257,7 @@ void CascadiaSettings::_ValidateDefaultProfileExists() // _temporarily_ set the default profile to the first profile. Because // we're adding a warning, this settings change won't be re-serialized. - GlobalSettings().DefaultProfile(_profiles[0].Guid()); + GlobalSettings().DefaultProfile(_profiles.GetAt(0).Guid()); } } @@ -278,15 +271,15 @@ void CascadiaSettings::_ValidateNoDuplicateProfiles() { bool foundDupe = false; - std::vector indicesToDelete; + std::vector indicesToDelete; std::set uniqueGuids; // Try collecting all the unique guids. If we ever encounter a guid that's // already in the set, then we need to delete that profile. - for (size_t i = 0; i < _profiles.size(); i++) + for (uint32_t i = 0; i < _profiles.Size(); i++) { - if (!uniqueGuids.insert(_profiles.at(i).Guid()).second) + if (!uniqueGuids.insert(_profiles.GetAt(i).Guid()).second) { foundDupe = true; indicesToDelete.push_back(i); @@ -297,7 +290,7 @@ void CascadiaSettings::_ValidateNoDuplicateProfiles() // Walk backwards, so we don't accidentally shift any of the elements for (auto iter = indicesToDelete.rbegin(); iter != indicesToDelete.rend(); iter++) { - _profiles.erase(_profiles.begin() + *iter); + _profiles.RemoveAt(*iter); } if (foundDupe) @@ -345,15 +338,17 @@ void CascadiaSettings::_ReorderProfilesToMatchUserSettingsOrder() // pIndex = the pIndex of the profile with guid==guids[gIndex] // profiles.swap(pIndex <-> gIndex) // This is O(N^2), which is kinda rough. I'm sure there's a better way - for (size_t gIndex = 0; gIndex < guidOrder.size(); gIndex++) + for (uint32_t gIndex = 0; gIndex < guidOrder.size(); gIndex++) { const auto guid = guidOrder.at(gIndex); - for (size_t pIndex = gIndex; pIndex < _profiles.size(); pIndex++) + for (uint32_t pIndex = gIndex; pIndex < _profiles.Size(); pIndex++) { - auto profileGuid = _profiles.at(pIndex).Guid(); + auto profileGuid = _profiles.GetAt(pIndex).Guid(); if (equals(profileGuid, guid)) { - std::iter_swap(_profiles.begin() + pIndex, _profiles.begin() + gIndex); + auto prof1 = _profiles.GetAt(pIndex); + _profiles.SetAt(pIndex, _profiles.GetAt(gIndex)); + _profiles.SetAt(gIndex, prof1); break; } } @@ -369,19 +364,22 @@ void CascadiaSettings::_ReorderProfilesToMatchUserSettingsOrder() // - void CascadiaSettings::_RemoveHiddenProfiles() { - // remove_if will move all the profiles where the lambda is true to the end - // of the list, then return a iterator to the point in the list where those - // profiles start. The erase call will then remove all of those profiles - // from the list. This is the [erase-remove - // idiom](https://en.wikipedia.org/wiki/Erase%E2%80%93remove_idiom) - _profiles.erase(std::remove_if(_profiles.begin(), - _profiles.end(), - [](auto&& profile) { return profile.Hidden(); }), - _profiles.end()); + for (uint32_t i = 0; i < _profiles.Size();) + { + if (_profiles.GetAt(i).Hidden()) + { + // remove hidden profile, don't increment 'i' + _profiles.RemoveAt(i); + } + else + { + ++i; + } + } // Ensure that we still have some profiles here. If we don't, then throw an // exception, so the app can use the defaults. - const bool hasProfiles = !_profiles.empty(); + const bool hasProfiles = _profiles.Size() > 0; if (!hasProfiles) { // Throw an exception. This is an invalid state, and we want the app to @@ -403,7 +401,7 @@ void CascadiaSettings::_RemoveHiddenProfiles() void CascadiaSettings::_ValidateAllSchemesExist() { bool foundInvalidScheme = false; - for (auto& profile : _profiles) + for (auto profile : _profiles) { const auto schemeName = profile.ColorSchemeName(); if (!_globals->GetColorSchemes().HasKey(schemeName)) @@ -435,7 +433,7 @@ void CascadiaSettings::_ValidateMediaResources() bool invalidBackground{ false }; bool invalidIcon{ false }; - for (auto& profile : _profiles) + for (auto profile : _profiles) { if (!profile.BackgroundImagePath().empty()) { @@ -494,7 +492,7 @@ void CascadiaSettings::_ValidateMediaResources() // the profile. // Return Value: // - the GUID of the created profile, and a fully initialized TerminalSettings object -std::tuple CascadiaSettings::BuildSettings(const NewTerminalArgs& newTerminalArgs) const +std::tuple CascadiaSettings::BuildSettings(const winrt::TerminalApp::NewTerminalArgs& newTerminalArgs) const { const winrt::guid profileGuid = _GetProfileForArgs(newTerminalArgs); auto settings = BuildSettings(profileGuid); @@ -527,13 +525,13 @@ std::tuple CascadiaSettings::BuildSettings(const // - profileGuid: The GUID of a profile to use to create a settings object for. // Return Value: // - a fully initialized TerminalSettings object -TerminalSettings CascadiaSettings::BuildSettings(winrt::guid profileGuid) const +winrt::TerminalApp::TerminalSettings CascadiaSettings::BuildSettings(winrt::guid profileGuid) const { const auto profile = FindProfile(profileGuid); THROW_HR_IF_NULL(E_INVALIDARG, profile); - const auto profileImpl = winrt::get_self(profile); - TerminalSettings result = profileImpl->CreateTerminalSettings(_globals->GetColorSchemes()); + const auto profileImpl = winrt::get_self(profile); + auto result = profileImpl->CreateTerminalSettings(_globals->GetColorSchemes()); // Place our appropriate global settings into the Terminal Settings _globals->ApplyToSettings(result); @@ -557,7 +555,7 @@ TerminalSettings CascadiaSettings::BuildSettings(winrt::guid profileGuid) const // and attempt to look the profile up by name instead. // Return Value: // - the GUID of the profile corresponding to this combination of index and NewTerminalArgs -winrt::guid CascadiaSettings::_GetProfileForArgs(const NewTerminalArgs& newTerminalArgs) const +winrt::guid CascadiaSettings::_GetProfileForArgs(const winrt::TerminalApp::NewTerminalArgs& newTerminalArgs) const { std::optional profileByIndex, profileByName; if (newTerminalArgs) @@ -579,7 +577,7 @@ winrt::guid CascadiaSettings::_GetProfileForArgs(const NewTerminalArgs& newTermi // - name: a guid string _or_ the name of a profile // Return Value: // - the GUID of the profile corresponding to this name -std::optional CascadiaSettings::_GetProfileGuidByName(const std::wstring_view name) const +std::optional CascadiaSettings::_GetProfileGuidByName(const winrt::hstring name) const try { // First, try and parse the "name" as a GUID. If it's a @@ -603,13 +601,12 @@ try // Here, we were unable to use the profile string as a GUID to // lookup a profile. Instead, try using the string to look the // Profile up by name. - const auto profileIterator{ std::find_if(_profiles.cbegin(), _profiles.cend(), [&](auto&& profile) { - return profile.Name() == name; - }) }; - - if (profileIterator != _profiles.cend()) + for (auto profile : _profiles) { - return profileIterator->Guid(); + if (profile.Name() == name) + { + return profile.Guid(); + } } } @@ -638,9 +635,9 @@ std::optional CascadiaSettings::_GetProfileGuidByIndex(std::optiona const auto realIndex{ index.value() }; // If we don't have that many profiles, then do nothing. if (realIndex >= 0 && - realIndex < gsl::narrow_cast(_profiles.size())) + realIndex < gsl::narrow_cast(_profiles.Size())) { - const auto& selectedProfile = _profiles.at(realIndex); + const auto& selectedProfile = _profiles.GetAt(realIndex); return selectedProfile.Guid(); } } @@ -703,7 +700,7 @@ std::string CascadiaSettings::_ApplyFirstRunChangesToSettingsTemplate(std::strin std::string finalSettings{ settingsTemplate }; std::wstring defaultProfileGuid{ DEFAULT_WINDOWS_POWERSHELL_GUID }; - if (const auto psCoreProfileGuid{ _GetProfileGuidByName(PowershellCoreProfileGenerator::GetPreferredPowershellProfileName()) }) + if (const auto psCoreProfileGuid{ _GetProfileGuidByName(hstring{ PowershellCoreProfileGenerator::GetPreferredPowershellProfileName() }) }) { defaultProfileGuid = Utils::GuidToString(*psCoreProfileGuid); } @@ -736,7 +733,7 @@ std::string CascadiaSettings::_ApplyFirstRunChangesToSettingsTemplate(std::strin // - profileGuid: the GUID of the profile to find the scheme for. // Return Value: // - a non-owning pointer to the scheme. -const ColorScheme CascadiaSettings::GetColorSchemeForProfile(const winrt::guid profileGuid) const +winrt::TerminalApp::ColorScheme CascadiaSettings::GetColorSchemeForProfile(const winrt::guid profileGuid) const { auto profile = FindProfile(profileGuid); if (!profile) @@ -756,7 +753,7 @@ const ColorScheme CascadiaSettings::GetColorSchemeForProfile(const winrt::guid p // - name: the name of the scheme to apply // Return Value: // - true iff we found a matching scheme for the name schemeName -bool CascadiaSettings::ApplyColorScheme(winrt::Microsoft::Terminal::TerminalControl::IControlSettings& settings, +bool CascadiaSettings::ApplyColorScheme(winrt::Microsoft::Terminal::TerminalControl::IControlSettings settings, winrt::hstring schemeName) { if (auto scheme{ _globals->GetColorSchemes().TryLookup(schemeName) }) diff --git a/src/cascadia/TerminalApp/CascadiaSettings.h b/src/cascadia/TerminalApp/CascadiaSettings.h index b2c0d3d87c6..d02704e30c6 100644 --- a/src/cascadia/TerminalApp/CascadiaSettings.h +++ b/src/cascadia/TerminalApp/CascadiaSettings.h @@ -16,6 +16,9 @@ Author(s): --*/ #pragma once + +#include "CascadiaSettings.g.h" + #include #include "GlobalAppSettings.h" #include "TerminalWarnings.h" @@ -42,7 +45,6 @@ namespace TerminalAppUnitTests namespace TerminalApp { class SettingsTypedDeserializationException; - class CascadiaSettings; }; class TerminalApp::SettingsTypedDeserializationException final : public std::runtime_error @@ -52,94 +54,100 @@ class TerminalApp::SettingsTypedDeserializationException final : public std::run runtime_error(description.data()) {} }; -class TerminalApp::CascadiaSettings final +namespace winrt::TerminalApp::implementation { -public: - CascadiaSettings(); - explicit CascadiaSettings(const bool addDynamicProfiles); - - static std::unique_ptr LoadDefaults(); - static std::unique_ptr LoadAll(); - static std::unique_ptr LoadUniversal(); - - static const CascadiaSettings& GetCurrentAppSettings(); - - std::tuple BuildSettings(const winrt::TerminalApp::NewTerminalArgs& newTerminalArgs) const; - winrt::TerminalApp::TerminalSettings BuildSettings(winrt::guid profileGuid) const; - - winrt::TerminalApp::GlobalAppSettings GlobalSettings(); - - gsl::span GetProfiles() const noexcept; - - winrt::TerminalApp::AppKeyBindings GetKeybindings() const noexcept; - - static std::unique_ptr FromJson(const Json::Value& json); - void LayerJson(const Json::Value& json); - - static std::filesystem::path GetSettingsPath(); - static std::filesystem::path GetDefaultSettingsPath(); - - const winrt::TerminalApp::Profile FindProfile(winrt::guid profileGuid) const noexcept; - const winrt::TerminalApp::ColorScheme GetColorSchemeForProfile(const winrt::guid profileGuid) const; - - std::vector& GetWarnings(); - - bool ApplyColorScheme(winrt::Microsoft::Terminal::TerminalControl::IControlSettings& settings, winrt::hstring schemeName); - -private: - winrt::com_ptr _globals; - std::vector _profiles; - std::vector _warnings; - - std::vector> _profileGenerators; - - std::string _userSettingsString; - Json::Value _userSettings; - Json::Value _defaultSettings; - Json::Value _userDefaultProfileSettings{ Json::Value::null }; - - void _LayerOrCreateProfile(const Json::Value& profileJson); - winrt::com_ptr _FindMatchingProfile(const Json::Value& profileJson); - void _LayerOrCreateColorScheme(const Json::Value& schemeJson); - winrt::com_ptr _FindMatchingColorScheme(const Json::Value& schemeJson); - void _ParseJsonString(std::string_view fileData, const bool isDefaultSettings); - static const Json::Value& _GetProfilesJsonObject(const Json::Value& json); - static const Json::Value& _GetDisabledProfileSourcesJsonObject(const Json::Value& json); - bool _PrependSchemaDirective(); - bool _AppendDynamicProfilesToUserSettings(); - std::string _ApplyFirstRunChangesToSettingsTemplate(std::string_view settingsTemplate) const; - - void _ApplyDefaultsFromUserSettings(); - - void _LoadDynamicProfiles(); - - static bool _IsPackaged(); - static void _WriteSettings(const std::string_view content); - static std::optional _ReadUserSettings(); - static std::optional _ReadFile(HANDLE hFile); - - std::optional _GetProfileGuidByName(const std::wstring_view) const; - std::optional _GetProfileGuidByIndex(std::optional index) const; - winrt::guid _GetProfileForArgs(const winrt::TerminalApp::NewTerminalArgs& newTerminalArgs) const; - - void _ValidateSettings(); - void _ValidateProfilesExist(); - void _ValidateProfilesHaveGuid(); - void _ValidateDefaultProfileExists(); - void _ValidateNoDuplicateProfiles(); - void _ResolveDefaultProfile(); - void _ReorderProfilesToMatchUserSettingsOrder(); - void _RemoveHiddenProfiles(); - void _ValidateAllSchemesExist(); - void _ValidateMediaResources(); - void _ValidateKeybindings(); - void _ValidateNoGlobalsKey(); - - friend class TerminalAppLocalTests::SettingsTests; - friend class TerminalAppLocalTests::ProfileTests; - friend class TerminalAppLocalTests::ColorSchemeTests; - friend class TerminalAppLocalTests::KeyBindingsTests; - friend class TerminalAppLocalTests::TabTests; - friend class TerminalAppUnitTests::DynamicProfileTests; - friend class TerminalAppUnitTests::JsonTests; -}; + struct CascadiaSettings : CascadiaSettingsT + { + public: + CascadiaSettings(); + explicit CascadiaSettings(const bool addDynamicProfiles); + + static TerminalApp::CascadiaSettings LoadDefaults(); + static TerminalApp::CascadiaSettings LoadAll(); + static TerminalApp::CascadiaSettings LoadUniversal(); + + std::tuple BuildSettings(const TerminalApp::NewTerminalArgs& newTerminalArgs) const; + TerminalApp::TerminalSettings BuildSettings(guid profileGuid) const; + + TerminalApp::GlobalAppSettings GlobalSettings(); + + Windows::Foundation::Collections::IObservableVector Profiles() const noexcept; + + TerminalApp::AppKeyBindings Keybindings() const noexcept; + + static std::unique_ptr FromJson(const Json::Value& json); + void LayerJson(const Json::Value& json); + + static std::filesystem::path GetSettingsPath(); + static std::filesystem::path GetDefaultSettingsPath(); + + TerminalApp::Profile FindProfile(guid profileGuid) const noexcept; + TerminalApp::ColorScheme GetColorSchemeForProfile(const guid profileGuid) const; + + std::vector<::TerminalApp::SettingsLoadWarnings>& GetWarnings(); + + bool ApplyColorScheme(Microsoft::Terminal::TerminalControl::IControlSettings settings, hstring schemeName); + + private: + com_ptr _globals; + Windows::Foundation::Collections::IObservableVector _profiles; + std::vector<::TerminalApp::SettingsLoadWarnings> _warnings; + + std::vector> _profileGenerators; + + std::string _userSettingsString; + Json::Value _userSettings; + Json::Value _defaultSettings; + Json::Value _userDefaultProfileSettings{ Json::Value::null }; + + void _LayerOrCreateProfile(const Json::Value& profileJson); + winrt::com_ptr _FindMatchingProfile(const Json::Value& profileJson); + void _LayerOrCreateColorScheme(const Json::Value& schemeJson); + winrt::com_ptr _FindMatchingColorScheme(const Json::Value& schemeJson); + void _ParseJsonString(std::string_view fileData, const bool isDefaultSettings); + static const Json::Value& _GetProfilesJsonObject(const Json::Value& json); + static const Json::Value& _GetDisabledProfileSourcesJsonObject(const Json::Value& json); + bool _PrependSchemaDirective(); + bool _AppendDynamicProfilesToUserSettings(); + std::string _ApplyFirstRunChangesToSettingsTemplate(std::string_view settingsTemplate) const; + + void _ApplyDefaultsFromUserSettings(); + + void _LoadDynamicProfiles(); + + static bool _IsPackaged(); + static void _WriteSettings(const std::string_view content); + static std::optional _ReadUserSettings(); + static std::optional _ReadFile(HANDLE hFile); + + std::optional _GetProfileGuidByName(const hstring) const; + std::optional _GetProfileGuidByIndex(std::optional index) const; + guid _GetProfileForArgs(const winrt::TerminalApp::NewTerminalArgs& newTerminalArgs) const; + + void _ValidateSettings(); + void _ValidateProfilesExist(); + void _ValidateProfilesHaveGuid(); + void _ValidateDefaultProfileExists(); + void _ValidateNoDuplicateProfiles(); + void _ResolveDefaultProfile(); + void _ReorderProfilesToMatchUserSettingsOrder(); + void _RemoveHiddenProfiles(); + void _ValidateAllSchemesExist(); + void _ValidateMediaResources(); + void _ValidateKeybindings(); + void _ValidateNoGlobalsKey(); + + friend class TerminalAppLocalTests::SettingsTests; + friend class TerminalAppLocalTests::ProfileTests; + friend class TerminalAppLocalTests::ColorSchemeTests; + friend class TerminalAppLocalTests::KeyBindingsTests; + friend class TerminalAppLocalTests::TabTests; + friend class TerminalAppUnitTests::DynamicProfileTests; + friend class TerminalAppUnitTests::JsonTests; + }; +} + +namespace winrt::TerminalApp::factory_implementation +{ + BASIC_FACTORY(CascadiaSettings); +} diff --git a/src/cascadia/TerminalApp/CascadiaSettings.idl b/src/cascadia/TerminalApp/CascadiaSettings.idl new file mode 100644 index 00000000000..58695b9dc31 --- /dev/null +++ b/src/cascadia/TerminalApp/CascadiaSettings.idl @@ -0,0 +1,23 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import "GlobalAppSettings.idl"; +import "Profile.idl"; + +namespace TerminalApp +{ + [default_interface] runtimeclass CascadiaSettings { + static CascadiaSettings LoadDefaults(); + static CascadiaSettings LoadAll(); + static CascadiaSettings LoadUniversal(); + + GlobalAppSettings GlobalSettings { get; }; + + Windows.Foundation.Collections.IObservableVector Profiles { get; }; + + AppKeyBindings Keybindings { get; }; + + Profile FindProfile(Guid profileGuid); + ColorScheme GetColorSchemeForProfile(Guid profileGuid); + } +} diff --git a/src/cascadia/TerminalApp/CascadiaSettingsSerialization.cpp b/src/cascadia/TerminalApp/CascadiaSettingsSerialization.cpp index 06dc5e55bd9..e34d10e25e8 100644 --- a/src/cascadia/TerminalApp/CascadiaSettingsSerialization.cpp +++ b/src/cascadia/TerminalApp/CascadiaSettingsSerialization.cpp @@ -19,7 +19,7 @@ // "Generated Files" directory. using namespace ::TerminalApp; -using namespace winrt::TerminalApp; +using namespace winrt::TerminalApp::implementation; using namespace ::Microsoft::Console; static constexpr std::wstring_view SettingsFilename{ L"settings.json" }; @@ -101,9 +101,10 @@ static void _CatchRethrowSerializationExceptionWithLocationInfo(std::string_view // profiles inserted into their list of profiles. // Return Value: // - a unique_ptr containing a new CascadiaSettings object. -std::unique_ptr CascadiaSettings::LoadAll() +winrt::TerminalApp::CascadiaSettings CascadiaSettings::LoadAll() { - auto resultPtr = LoadDefaults(); + auto settings = LoadDefaults(); + auto resultPtr = winrt::get_self(settings); // GH 3588, we need this below to know if the user chose something that wasn't our default. // Collect it up here in case it gets modified by any of the other layers between now and when @@ -218,7 +219,7 @@ std::unique_ptr CascadiaSettings::LoadAll() // Run it through the object so we can parse it apart and then only serialize the fields we're interested in // and avoid extraneous data. - auto akb = winrt::make_self(); + auto akb = winrt::make_self(); akb->LayerJson(userKeybindings); auto value = akb->ToJson(); @@ -240,7 +241,7 @@ std::unique_ptr CascadiaSettings::LoadAll() } } - return resultPtr; + return *resultPtr; } // Function Description: @@ -249,13 +250,13 @@ std::unique_ptr CascadiaSettings::LoadAll() // - // Return Value: // - a unique_ptr to a CascadiaSettings with the connection types and settings for Universal terminal -std::unique_ptr CascadiaSettings::LoadUniversal() +winrt::TerminalApp::CascadiaSettings CascadiaSettings::LoadUniversal() { // We're going to do this ourselves because we want to exclude almost everything // from the special Universal-for-developers configuration // Create settings and get the universal defaults loaded up. - auto resultPtr = std::make_unique(); + auto resultPtr = winrt::make_self(); resultPtr->_ParseJsonString(DefaultUniversalJson, true); resultPtr->LayerJson(resultPtr->_defaultSettings); @@ -263,7 +264,7 @@ std::unique_ptr CascadiaSettings::LoadUniversal() // If this throws, the app will catch it and use the default settings resultPtr->_ValidateSettings(); - return resultPtr; + return *resultPtr; } // Function Description: @@ -273,9 +274,9 @@ std::unique_ptr CascadiaSettings::LoadUniversal() // - // Return Value: // - a unique_ptr to a CascadiaSettings with the settings from defaults.json -std::unique_ptr CascadiaSettings::LoadDefaults() +winrt::TerminalApp::CascadiaSettings CascadiaSettings::LoadDefaults() { - auto resultPtr = std::make_unique(); + auto resultPtr = winrt::make_self(); // We already have the defaults in memory, because we stamp them into a // header as part of the build process. We don't need to bother with reading @@ -284,7 +285,7 @@ std::unique_ptr CascadiaSettings::LoadDefaults() resultPtr->LayerJson(resultPtr->_defaultSettings); resultPtr->_ResolveDefaultProfile(); - return resultPtr; + return *resultPtr; } // Method Description: @@ -329,7 +330,7 @@ void CascadiaSettings::_LoadDynamicProfiles() // we'll synthesize a GUID for it in _ValidateProfilesHaveGuid profile.Source(generatorNamespace); - _profiles.emplace_back(profile); + _profiles.Append(profile); } } CATCH_LOG_MSG("Dynamic Profile Namespace: \"%ls\"", generatorNamespace.data()); @@ -607,9 +608,9 @@ void CascadiaSettings::_LayerOrCreateProfile(const Json::Value& profileJson) // If this JSON represents a dynamic profile, we _shouldn't_ create the // profile here. We only want to create profiles for profiles without a // `source`. Dynamic profiles _must_ be layered on an existing profile. - if (!implementation::Profile::IsDynamicProfileObject(profileJson)) + if (!Profile::IsDynamicProfileObject(profileJson)) { - auto profile = winrt::make_self(); + auto profile = winrt::make_self(); // GH#2325: If we have a set of default profile settings, apply them here. // We _won't_ have these settings yet for defaults, dynamic profiles. @@ -619,7 +620,7 @@ void CascadiaSettings::_LayerOrCreateProfile(const Json::Value& profileJson) } profile->LayerJson(profileJson); - _profiles.emplace_back(*profile); + _profiles.Append(*profile); } } } @@ -635,11 +636,11 @@ void CascadiaSettings::_LayerOrCreateProfile(const Json::Value& profileJson) // Return Value: // - a Profile that can be layered with the given json object, iff such a // profile exists. -winrt::com_ptr CascadiaSettings::_FindMatchingProfile(const Json::Value& profileJson) +winrt::com_ptr CascadiaSettings::_FindMatchingProfile(const Json::Value& profileJson) { - for (auto& profile : _profiles) + for (auto profile : _profiles) { - auto profileImpl = winrt::get_self(profile); + auto profileImpl = winrt::get_self(profile); if (profileImpl->ShouldBeLayered(profileJson)) { return profileImpl->get_strong(); @@ -682,9 +683,9 @@ void CascadiaSettings::_ApplyDefaultsFromUserSettings() // hyper-explode, so just don't let them do that. _userDefaultProfileSettings.removeMember({ "guid" }); - for (auto& profile : _profiles) + for (auto profile : _profiles) { - auto profileImpl = winrt::get_self(profile); + auto profileImpl = winrt::get_self(profile); profileImpl->LayerJson(_userDefaultProfileSettings); } } @@ -708,7 +709,7 @@ void CascadiaSettings::_LayerOrCreateColorScheme(const Json::Value& schemeJson) } else { - const auto scheme = implementation::ColorScheme::FromJson(schemeJson); + const auto scheme = ColorScheme::FromJson(schemeJson); _globals->AddColorScheme(*scheme); } } @@ -724,13 +725,13 @@ void CascadiaSettings::_LayerOrCreateColorScheme(const Json::Value& schemeJson) // Return Value: // - a ColorScheme that can be layered with the given json object, iff such a // color scheme exists. -winrt::com_ptr CascadiaSettings::_FindMatchingColorScheme(const Json::Value& schemeJson) +winrt::com_ptr CascadiaSettings::_FindMatchingColorScheme(const Json::Value& schemeJson) { - if (auto schemeName = implementation::ColorScheme::GetNameFromJson(schemeJson)) + if (auto schemeName = ColorScheme::GetNameFromJson(schemeJson)) { if (auto scheme{ _globals->GetColorSchemes().TryLookup(*schemeName) }) { - return winrt::get_self(scheme)->get_strong(); + return winrt::get_self(scheme)->get_strong(); } } return nullptr; diff --git a/src/cascadia/TerminalApp/Command.cpp b/src/cascadia/TerminalApp/Command.cpp index 2c66cdf7dd4..014058d4bca 100644 --- a/src/cascadia/TerminalApp/Command.cpp +++ b/src/cascadia/TerminalApp/Command.cpp @@ -353,7 +353,7 @@ namespace winrt::TerminalApp::implementation // Return Value: // - void Command::ExpandCommands(Windows::Foundation::Collections::IMap& commands, - gsl::span profiles, + Windows::Foundation::Collections::IVectorView profiles, gsl::span schemes, std::vector<::TerminalApp::SettingsLoadWarnings>& warnings) { @@ -409,7 +409,7 @@ namespace winrt::TerminalApp::implementation // - and empty vector if the command wasn't expandable, otherwise a list of // the newly-created commands. std::vector Command::_expandCommand(Command* const expandable, - gsl::span profiles, + Windows::Foundation::Collections::IVectorView profiles, gsl::span schemes, std::vector<::TerminalApp::SettingsLoadWarnings>& warnings) { diff --git a/src/cascadia/TerminalApp/Command.h b/src/cascadia/TerminalApp/Command.h index 6f3d374c1d1..2b8e62a6044 100644 --- a/src/cascadia/TerminalApp/Command.h +++ b/src/cascadia/TerminalApp/Command.h @@ -41,7 +41,7 @@ namespace winrt::TerminalApp::implementation std::vector<::TerminalApp::SettingsLoadWarnings>& warnings); static void ExpandCommands(Windows::Foundation::Collections::IMap& commands, - gsl::span profiles, + Windows::Foundation::Collections::IVectorView profiles, gsl::span schemes, std::vector<::TerminalApp::SettingsLoadWarnings>& warnings); @@ -69,7 +69,7 @@ namespace winrt::TerminalApp::implementation winrt::hstring _lastIconPath{}; static std::vector _expandCommand(Command* const expandable, - gsl::span profiles, + Windows::Foundation::Collections::IVectorView profiles, gsl::span schemes, std::vector<::TerminalApp::SettingsLoadWarnings>& warnings); friend class TerminalAppLocalTests::SettingsTests; diff --git a/src/cascadia/TerminalApp/Jumplist.cpp b/src/cascadia/TerminalApp/Jumplist.cpp index 9020ac35d30..57010ec6719 100644 --- a/src/cascadia/TerminalApp/Jumplist.cpp +++ b/src/cascadia/TerminalApp/Jumplist.cpp @@ -83,7 +83,7 @@ static std::wstring_view _getExePath() // - settings - The settings object to update the jumplist with. // Return Value: // - -HRESULT Jumplist::UpdateJumplist(const TerminalApp::CascadiaSettings& settings) noexcept +HRESULT Jumplist::UpdateJumplist(const CascadiaSettings& settings) noexcept { try { @@ -99,7 +99,7 @@ HRESULT Jumplist::UpdateJumplist(const TerminalApp::CascadiaSettings& settings) RETURN_IF_FAILED(jumplistItems->Clear()); // Update the list of profiles. - RETURN_IF_FAILED(_updateProfiles(jumplistItems.get(), settings.GetProfiles())); + RETURN_IF_FAILED(_updateProfiles(jumplistItems.get(), settings.Profiles().GetView())); // TODO GH#1571: Add items from the future customizable new tab dropdown as well. // This could either replace the default profiles, or be added alongside them. @@ -123,7 +123,7 @@ HRESULT Jumplist::UpdateJumplist(const TerminalApp::CascadiaSettings& settings) // - profiles - The profiles to add to the jumplist // Return Value: // - S_OK or HRESULT failure code. -[[nodiscard]] HRESULT Jumplist::_updateProfiles(IObjectCollection* jumplistItems, const gsl::span& profiles) noexcept +[[nodiscard]] HRESULT Jumplist::_updateProfiles(IObjectCollection* jumplistItems, winrt::Windows::Foundation::Collections::IVectorView profiles) noexcept { try { diff --git a/src/cascadia/TerminalApp/Jumplist.h b/src/cascadia/TerminalApp/Jumplist.h index ba3649c0311..5bd024f49b9 100644 --- a/src/cascadia/TerminalApp/Jumplist.h +++ b/src/cascadia/TerminalApp/Jumplist.h @@ -13,7 +13,6 @@ #pragma once #include "CascadiaSettings.h" -#include "Profile.h" struct IObjectCollection; struct IShellLinkW; @@ -21,9 +20,9 @@ struct IShellLinkW; class Jumplist { public: - static HRESULT UpdateJumplist(const TerminalApp::CascadiaSettings& settings) noexcept; + static HRESULT UpdateJumplist(const winrt::TerminalApp::CascadiaSettings& settings) noexcept; private: - [[nodiscard]] static HRESULT _updateProfiles(IObjectCollection* jumplistItems, const gsl::span& profiles) noexcept; + [[nodiscard]] static HRESULT _updateProfiles(IObjectCollection* jumplistItems, winrt::Windows::Foundation::Collections::IVectorView profiles) noexcept; [[nodiscard]] static HRESULT _createShellLink(const std::wstring_view name, const std::wstring_view path, const std::wstring_view args, IShellLinkW** shLink) noexcept; }; diff --git a/src/cascadia/TerminalApp/Pane.cpp b/src/cascadia/TerminalApp/Pane.cpp index 754c7e56c52..c58de58b59d 100644 --- a/src/cascadia/TerminalApp/Pane.cpp +++ b/src/cascadia/TerminalApp/Pane.cpp @@ -4,7 +4,7 @@ #include "pch.h" #include "Pane.h" #include "Profile.h" -#include "CascadiaSettings.h" +#include "AppLogic.h" using namespace winrt::Windows::Foundation; using namespace winrt::Windows::Graphics::Display; @@ -319,7 +319,7 @@ void Pane::_ControlConnectionStateChangedHandler(const TermControl& /*sender*/, return; } - const auto& settings = CascadiaSettings::GetCurrentAppSettings(); + const auto settings{ winrt::TerminalApp::implementation::AppLogic::CurrentAppSettings() }; auto paneProfile = settings.FindProfile(_profile.value()); if (paneProfile) { diff --git a/src/cascadia/TerminalApp/TerminalAppLib.vcxproj b/src/cascadia/TerminalApp/TerminalAppLib.vcxproj index 85d3a858790..46cc4bd46bc 100644 --- a/src/cascadia/TerminalApp/TerminalAppLib.vcxproj +++ b/src/cascadia/TerminalApp/TerminalAppLib.vcxproj @@ -114,7 +114,9 @@ Profile.idl - + + CascadiaSettings.idl + @@ -198,8 +200,12 @@ Profile.idl - - + + CascadiaSettings.idl + + + CascadiaSettings.idl + @@ -288,6 +294,7 @@ + diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index ceb86a52481..cf06e3d0fd3 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -59,7 +59,7 @@ namespace winrt::TerminalApp::implementation // Arguments: // - settings: The settings who's keybindings we should use to look up the key chords from // - commands: The list of commands to label. - static void _recursiveUpdateCommandKeybindingLabels(std::shared_ptr<::TerminalApp::CascadiaSettings> settings, + static void _recursiveUpdateCommandKeybindingLabels(TerminalApp::CascadiaSettings settings, IMapView commands) { for (const auto& nameAndCmd : commands) @@ -70,7 +70,7 @@ namespace winrt::TerminalApp::implementation // part of the command in the UI. Each Command's KeyChordText is // unset by default, so we don't need to worry about clearing it // if there isn't a key associated with it. - auto keyChord{ settings->GetKeybindings().GetKeyBindingForActionWithArgs(command.Action()) }; + auto keyChord{ settings.Keybindings().GetKeyBindingForActionWithArgs(command.Action()) }; if (keyChord) { @@ -101,8 +101,7 @@ namespace winrt::TerminalApp::implementation } } - winrt::fire_and_forget TerminalPage::SetSettings(std::shared_ptr<::TerminalApp::CascadiaSettings> settings, - bool needRefreshUI) + winrt::fire_and_forget TerminalPage::SetSettings(TerminalApp::CascadiaSettings settings, bool needRefreshUI) { _settings = settings; if (needRefreshUI) @@ -115,14 +114,14 @@ namespace winrt::TerminalApp::implementation if (auto page{ weakThis.get() }) { _UpdateCommandsForPalette(); - CommandPalette().SetKeyBindings(_settings->GetKeybindings()); + CommandPalette().SetKeyBindings(_settings.Keybindings()); } } void TerminalPage::Create() { // Hookup the key bindings - _HookupKeyBindings(_settings->GetKeybindings()); + _HookupKeyBindings(_settings.Keybindings()); _tabContent = this->TabContent(); _tabRow = this->TabRow(); @@ -178,7 +177,7 @@ namespace winrt::TerminalApp::implementation auto tabRowImpl = winrt::get_self(_tabRow); _newTabButton = tabRowImpl->NewTabButton(); - if (_settings->GlobalSettings().ShowTabsInTitlebar()) + if (_settings.GlobalSettings().ShowTabsInTitlebar()) { // Remove the TabView from the page. We'll hang on to it, we need to // put it in the titlebar. @@ -207,7 +206,7 @@ namespace winrt::TerminalApp::implementation WI_IsFlagSet(rAltState, CoreVirtualKeyStates::Down); // Check for DebugTap - bool debugTap = page->_settings->GlobalSettings().DebugFeaturesEnabled() && + bool debugTap = page->_settings.GlobalSettings().DebugFeaturesEnabled() && WI_IsFlagSet(lAltState, CoreVirtualKeyStates::Down) && WI_IsFlagSet(rAltState, CoreVirtualKeyStates::Down); @@ -449,14 +448,14 @@ namespace winrt::TerminalApp::implementation void TerminalPage::_CreateNewTabFlyout() { auto newTabFlyout = WUX::Controls::MenuFlyout{}; - auto keyBindings = _settings->GetKeybindings(); + auto keyBindings = _settings.Keybindings(); - const GUID defaultProfileGuid = _settings->GlobalSettings().DefaultProfile(); + const auto defaultProfileGuid = _settings.GlobalSettings().DefaultProfile(); // the number of profiles should not change in the loop for this to work - auto const profileCount = gsl::narrow_cast(_settings->GetProfiles().size()); + auto const profileCount = gsl::narrow_cast(_settings.Profiles().Size()); for (int profileIndex = 0; profileIndex < profileCount; profileIndex++) { - const auto& profile = _settings->GetProfiles()[profileIndex]; + const auto profile = _settings.Profiles().GetAt(profileIndex); auto profileMenuItem = WUX::Controls::MenuFlyoutItem{}; // Add the keyboard shortcuts based on the number of profiles defined @@ -492,7 +491,7 @@ namespace winrt::TerminalApp::implementation Automation::AutomationProperties::SetAccessibilityView(iconElement, Automation::Peers::AccessibilityView::Raw); } - if (profile.Guid() == winrt::guid{ defaultProfileGuid }) + if (profile.Guid() == defaultProfileGuid) { // Contrast the default profile with others in font weight. profileMenuItem.FontWeight(FontWeights::Bold()); @@ -512,7 +511,7 @@ namespace winrt::TerminalApp::implementation WI_IsFlagSet(rAltState, CoreVirtualKeyStates::Down); // Check for DebugTap - bool debugTap = page->_settings->GlobalSettings().DebugFeaturesEnabled() && + bool debugTap = page->_settings.GlobalSettings().DebugFeaturesEnabled() && WI_IsFlagSet(lAltState, CoreVirtualKeyStates::Down) && WI_IsFlagSet(rAltState, CoreVirtualKeyStates::Down); @@ -617,7 +616,8 @@ namespace winrt::TerminalApp::implementation void TerminalPage::_OpenNewTab(const winrt::TerminalApp::NewTerminalArgs& newTerminalArgs) try { - const auto [profileGuid, settings] = _settings->BuildSettings(newTerminalArgs); + const auto settingsImpl{ winrt::get_self(_settings) }; + const auto [profileGuid, settings] = settingsImpl->BuildSettings(newTerminalArgs); _CreateNewTabFromSettings(profileGuid, settings); @@ -627,7 +627,7 @@ namespace winrt::TerminalApp::implementation newTerminalArgs.Profile().empty()); // Lookup the name of the color scheme used by this profile. - const auto scheme = _settings->GetColorSchemeForProfile(profileGuid); + const auto scheme = _settings.GetColorSchemeForProfile(profileGuid); // If they explicitly specified `null` as the scheme (indicating _no_ scheme), log // that as the empty string. const auto schemeName = scheme ? scheme.Name() : L"\0"; @@ -669,7 +669,7 @@ namespace winrt::TerminalApp::implementation auto connection = _CreateConnectionFromSettings(profileGuid, settings); TerminalConnection::ITerminalConnection debugConnection{ nullptr }; - if (_settings->GlobalSettings().DebugFeaturesEnabled()) + if (_settings.GlobalSettings().DebugFeaturesEnabled()) { const CoreWindow window = CoreWindow::GetForCurrentThread(); const auto rAltState = window.GetKeyState(VirtualKey::RightMenu); @@ -725,7 +725,7 @@ namespace winrt::TerminalApp::implementation } // Set this tab's icon to the icon from the user's profile - const auto profile = _settings->FindProfile(profileGuid); + const auto profile = _settings.FindProfile(profileGuid); if (profile != nullptr && !profile.IconPath().empty()) { newTabImpl->UpdateIcon(profile.GetExpandedIconPath()); @@ -764,7 +764,7 @@ namespace winrt::TerminalApp::implementation TerminalConnection::ITerminalConnection TerminalPage::_CreateConnectionFromSettings(GUID profileGuid, TerminalApp::TerminalSettings settings) { - const auto profile = _settings->FindProfile(profileGuid); + const auto profile = _settings.FindProfile(profileGuid); TerminalConnection::ITerminalConnection connection{ nullptr }; @@ -948,7 +948,7 @@ namespace winrt::TerminalApp::implementation { auto newTabTitle = tab.GetActiveTitle(); - if (_settings->GlobalSettings().ShowTitleInTitlebar() && + if (_settings.GlobalSettings().ShowTitleInTitlebar() && tab.IsFocused()) { _titleChangeHandlers(*this, newTabTitle); @@ -966,7 +966,7 @@ namespace winrt::TerminalApp::implementation if (lastFocusedProfileOpt.has_value()) { const auto lastFocusedProfile = lastFocusedProfileOpt.value(); - const auto matchingProfile = _settings->FindProfile(lastFocusedProfile); + const auto matchingProfile = _settings.FindProfile(lastFocusedProfile); if (matchingProfile) { tab.UpdateIcon(matchingProfile.GetExpandedIconPath()); @@ -982,7 +982,7 @@ namespace winrt::TerminalApp::implementation // - Handle changes to the tab width set by the user void TerminalPage::_UpdateTabWidthMode() { - _tabView.TabWidthMode(_settings->GlobalSettings().TabWidthMode()); + _tabView.TabWidthMode(_settings.GlobalSettings().TabWidthMode()); } // Method Description: @@ -993,9 +993,9 @@ namespace winrt::TerminalApp::implementation // Show tabs when there's more than 1, or the user has chosen to always // show the tab bar. const bool isVisible = (!_isFullscreen && !_isInFocusMode) && - (_settings->GlobalSettings().ShowTabsInTitlebar() || + (_settings.GlobalSettings().ShowTabsInTitlebar() || (_tabs.Size() > 1) || - _settings->GlobalSettings().AlwaysShowTabs()); + _settings.GlobalSettings().AlwaysShowTabs()); // collapse/show the tabs themselves _tabView.Visibility(isVisible ? Visibility::Visible : Visibility::Collapsed); @@ -1030,7 +1030,8 @@ namespace winrt::TerminalApp::implementation const auto& profileGuid = focusedTab->GetFocusedProfile(); if (profileGuid.has_value()) { - const auto settings = _settings->BuildSettings(profileGuid.value()); + const auto settingsImpl{ winrt::get_self(_settings) }; + const auto settings = settingsImpl->BuildSettings(profileGuid.value()); _CreateNewTabFromSettings(profileGuid.value(), settings); } } @@ -1199,7 +1200,7 @@ namespace winrt::TerminalApp::implementation // leftward from 0 to tabCount - 1. const auto newTabIndex = ((tabCount + *index + (bMoveRight ? 1 : -1)) % tabCount); - if (_settings->GlobalSettings().UseTabSwitcher()) + if (_settings.GlobalSettings().UseTabSwitcher()) { if (CommandPalette().Visibility() == Visibility::Visible) { @@ -1387,7 +1388,7 @@ namespace winrt::TerminalApp::implementation // than one tab opened, show a warning dialog. void TerminalPage::CloseWindow() { - if (_tabs.Size() > 1 && _settings->GlobalSettings().ConfirmCloseAllTabs()) + if (_tabs.Size() > 1 && _settings.GlobalSettings().ConfirmCloseAllTabs()) { _ShowCloseWarningDialog(); } @@ -1465,7 +1466,8 @@ namespace winrt::TerminalApp::implementation if (current_guid) { profileFound = true; - controlSettings = _settings->BuildSettings(current_guid.value()); + const auto settingsImpl{ winrt::get_self(_settings) }; + controlSettings = settingsImpl->BuildSettings(current_guid.value()); realGuid = current_guid.value(); } // TODO: GH#5047 - In the future, we should get the Profile of @@ -1483,7 +1485,8 @@ namespace winrt::TerminalApp::implementation } if (!profileFound) { - std::tie(realGuid, controlSettings) = _settings->BuildSettings(newTerminalArgs); + const auto settingsImpl{ winrt::get_self(_settings) }; + std::tie(realGuid, controlSettings) = settingsImpl->BuildSettings(newTerminalArgs); } const auto controlConnection = _CreateConnectionFromSettings(realGuid, controlSettings); @@ -1567,7 +1570,7 @@ namespace winrt::TerminalApp::implementation // - the title of the focused control if there is one, else "Windows Terminal" hstring TerminalPage::Title() { - if (_settings->GlobalSettings().ShowTitleInTitlebar()) + if (_settings.GlobalSettings().ShowTitleInTitlebar()) { auto selectedIndex = _tabView.SelectedIndex(); if (selectedIndex >= 0) @@ -1662,7 +1665,7 @@ namespace winrt::TerminalApp::implementation // - See Pane::CalcSnappedDimension float TerminalPage::CalcSnappedDimension(const bool widthOrHeight, const float dimension) const { - if (_settings->GlobalSettings().SnapToGridOnResize()) + if (_settings.GlobalSettings().SnapToGridOnResize()) { if (auto index{ _GetFocusedTabIndex() }) { @@ -1690,7 +1693,7 @@ namespace winrt::TerminalApp::implementation // iff it is set bool useGlobal = copiedData.Formats() == nullptr; auto copyFormats = useGlobal ? - _settings->GlobalSettings().CopyFormatting() : + _settings.GlobalSettings().CopyFormatting() : copiedData.Formats().Value(); // copy text to dataPack @@ -1764,11 +1767,11 @@ namespace winrt::TerminalApp::implementation } const bool hasNewLine = std::find(text.cbegin(), text.cend(), L'\n') != text.cend(); - const bool warnMultiLine = hasNewLine && _settings->GlobalSettings().WarnAboutMultiLinePaste(); + const bool warnMultiLine = hasNewLine && _settings.GlobalSettings().WarnAboutMultiLinePaste(); constexpr const std::size_t minimumSizeForWarning = 1024 * 5; // 5 KiB const bool warnLargeText = text.size() > minimumSizeForWarning && - _settings->GlobalSettings().WarnAboutLargePaste(); + _settings.GlobalSettings().WarnAboutLargePaste(); if (warnMultiLine || warnLargeText) { @@ -2013,11 +2016,11 @@ namespace winrt::TerminalApp::implementation { // Re-wire the keybindings to their handlers, as we'll have created a // new AppKeyBindings object. - _HookupKeyBindings(_settings->GetKeybindings()); + _HookupKeyBindings(_settings.Keybindings()); // Refresh UI elements - auto profiles = _settings->GetProfiles(); - for (auto& profile : profiles) + auto profiles = _settings.Profiles(); + for (const auto& profile : profiles) { const auto profileGuid = profile.Guid(); @@ -2025,7 +2028,8 @@ namespace winrt::TerminalApp::implementation { // BuildSettings can throw an exception if the profileGuid does // not belong to an actual profile in the list of profiles. - const auto settings = _settings->BuildSettings(profileGuid); + const auto settingsImpl{ winrt::get_self(_settings) }; + const auto settings = settingsImpl->BuildSettings(profileGuid); for (auto tab : _tabs) { @@ -2065,7 +2069,7 @@ namespace winrt::TerminalApp::implementation // Reload the current value of alwaysOnTop from the settings file. This // will let the user hot-reload this setting, but any runtime changes to // the alwaysOnTop setting will be lost. - _isAlwaysOnTop = _settings->GlobalSettings().AlwaysOnTop(); + _isAlwaysOnTop = _settings.GlobalSettings().AlwaysOnTop(); _alwaysOnTopChangedHandlers(*this, nullptr); } @@ -2084,7 +2088,7 @@ namespace winrt::TerminalApp::implementation // Return Value: // - IMap TerminalPage::_ExpandCommands(IMapView commandsToExpand, - gsl::span profiles, + IVectorView profiles, IMapView schemes) { std::vector<::TerminalApp::SettingsLoadWarnings> warnings; @@ -2123,9 +2127,9 @@ namespace winrt::TerminalApp::implementation // - void TerminalPage::_UpdateCommandsForPalette() { - IMap copyOfCommands = _ExpandCommands(_settings->GlobalSettings().GetCommands(), - _settings->GetProfiles(), - _settings->GlobalSettings().GetColorSchemes()); + IMap copyOfCommands = _ExpandCommands(_settings.GlobalSettings().GetCommands(), + _settings.Profiles().GetView(), + _settings.GlobalSettings().GetColorSchemes()); _recursiveUpdateCommandKeybindingLabels(_settings, copyOfCommands.GetView()); _recursiveUpdateCommandIcons(copyOfCommands.GetView()); diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h index ac68997afae..e47904228cd 100644 --- a/src/cascadia/TerminalApp/TerminalPage.h +++ b/src/cascadia/TerminalApp/TerminalPage.h @@ -33,7 +33,7 @@ namespace winrt::TerminalApp::implementation public: TerminalPage(); - winrt::fire_and_forget SetSettings(std::shared_ptr<::TerminalApp::CascadiaSettings> settings, bool needRefreshUI); + winrt::fire_and_forget SetSettings(TerminalApp::CascadiaSettings settings, bool needRefreshUI); void Create(); @@ -86,7 +86,7 @@ namespace winrt::TerminalApp::implementation Windows::UI::Xaml::Controls::Grid _tabContent{ nullptr }; Microsoft::UI::Xaml::Controls::SplitButton _newTabButton{ nullptr }; - std::shared_ptr<::TerminalApp::CascadiaSettings> _settings{ nullptr }; + TerminalApp::CascadiaSettings _settings{ nullptr }; Windows::Foundation::Collections::IObservableVector _tabs; winrt::com_ptr _GetStrongTabImpl(const uint32_t index) const; @@ -137,7 +137,7 @@ namespace winrt::TerminalApp::implementation void _UpdateTabWidthMode(); void _UpdateCommandsForPalette(); static winrt::Windows::Foundation::Collections::IMap _ExpandCommands(Windows::Foundation::Collections::IMapView commandsToExpand, - gsl::span profiles, + Windows::Foundation::Collections::IVectorView profiles, Windows::Foundation::Collections::IMapView schemes); void _DuplicateTabViewItem(); diff --git a/src/cascadia/ut_app/DynamicProfileTests.cpp b/src/cascadia/ut_app/DynamicProfileTests.cpp index 668cf7ba5ce..65c877dced4 100644 --- a/src/cascadia/ut_app/DynamicProfileTests.cpp +++ b/src/cascadia/ut_app/DynamicProfileTests.cpp @@ -95,18 +95,18 @@ namespace TerminalAppUnitTests return profiles; }; - CascadiaSettings settings{ false }; - settings._profileGenerators.emplace_back(std::move(gen0)); - settings._profileGenerators.emplace_back(std::move(gen1)); + auto settings = winrt::make_self(false); + settings->_profileGenerators.emplace_back(std::move(gen0)); + settings->_profileGenerators.emplace_back(std::move(gen1)); - settings._LoadDynamicProfiles(); - VERIFY_ARE_EQUAL(2u, settings._profiles.size()); + settings->_LoadDynamicProfiles(); + VERIFY_ARE_EQUAL(2u, settings->_profiles.Size()); - VERIFY_ARE_EQUAL(L"profile0", settings._profiles.at(0).Name()); - VERIFY_IS_FALSE(settings._profiles.at(0).HasGuid()); + VERIFY_ARE_EQUAL(L"profile0", settings->_profiles.GetAt(0).Name()); + VERIFY_IS_FALSE(settings->_profiles.GetAt(0).HasGuid()); - VERIFY_ARE_EQUAL(L"profile1", settings._profiles.at(1).Name()); - VERIFY_IS_FALSE(settings._profiles.at(1).HasGuid()); + VERIFY_ARE_EQUAL(L"profile1", settings->_profiles.GetAt(1).Name()); + VERIFY_IS_FALSE(settings->_profiles.GetAt(1).HasGuid()); } void DynamicProfileTests::TestGenGuidsForProfiles() @@ -135,59 +135,59 @@ namespace TerminalAppUnitTests return profiles; }; - CascadiaSettings settings{ false }; - settings._profileGenerators.emplace_back(std::move(gen0)); - settings._profileGenerators.emplace_back(std::move(gen1)); + auto settings = winrt::make_self(false); + settings->_profileGenerators.emplace_back(std::move(gen0)); + settings->_profileGenerators.emplace_back(std::move(gen1)); Profile p0, p1; - p0.Name(L"profile0"); // this is _profiles.at(0) - p1.Name(L"profile1"); // this is _profiles.at(1) - settings._profiles.push_back(p0); - settings._profiles.push_back(p1); - - settings._LoadDynamicProfiles(); - VERIFY_ARE_EQUAL(5u, settings._profiles.size()); - - VERIFY_ARE_EQUAL(L"profile0", settings._profiles.at(0).Name()); - VERIFY_IS_FALSE(settings._profiles.at(0).HasGuid()); - VERIFY_IS_TRUE(settings._profiles.at(0).Source().empty()); - - VERIFY_ARE_EQUAL(L"profile1", settings._profiles.at(1).Name()); - VERIFY_IS_FALSE(settings._profiles.at(1).HasGuid()); - VERIFY_IS_TRUE(settings._profiles.at(1).Source().empty()); - - VERIFY_ARE_EQUAL(L"profile0", settings._profiles.at(2).Name()); - VERIFY_IS_FALSE(settings._profiles.at(2).HasGuid()); - VERIFY_IS_FALSE(settings._profiles.at(2).Source().empty()); - - VERIFY_ARE_EQUAL(L"profile0", settings._profiles.at(3).Name()); - VERIFY_IS_FALSE(settings._profiles.at(3).HasGuid()); - VERIFY_IS_FALSE(settings._profiles.at(3).Source().empty()); - - VERIFY_ARE_EQUAL(L"profile1", settings._profiles.at(4).Name()); - VERIFY_IS_FALSE(settings._profiles.at(4).HasGuid()); - VERIFY_IS_FALSE(settings._profiles.at(4).Source().empty()); - - settings._ValidateProfilesHaveGuid(); - - VERIFY_IS_TRUE(settings._profiles.at(0).HasGuid()); - VERIFY_IS_TRUE(settings._profiles.at(1).HasGuid()); - VERIFY_IS_TRUE(settings._profiles.at(2).HasGuid()); - VERIFY_IS_TRUE(settings._profiles.at(3).HasGuid()); - VERIFY_IS_TRUE(settings._profiles.at(4).HasGuid()); - - VERIFY_ARE_NOT_EQUAL(settings._profiles.at(0).Guid(), - settings._profiles.at(1).Guid()); - VERIFY_ARE_NOT_EQUAL(settings._profiles.at(0).Guid(), - settings._profiles.at(2).Guid()); - VERIFY_ARE_NOT_EQUAL(settings._profiles.at(0).Guid(), - settings._profiles.at(3).Guid()); - - VERIFY_ARE_NOT_EQUAL(settings._profiles.at(1).Guid(), - settings._profiles.at(4).Guid()); - - VERIFY_ARE_NOT_EQUAL(settings._profiles.at(3).Guid(), - settings._profiles.at(4).Guid()); + p0.Name(L"profile0"); // this is _profiles.GetAt(0) + p1.Name(L"profile1"); // this is _profiles.GetAt(1) + settings->_profiles.Append(p0); + settings->_profiles.Append(p1); + + settings->_LoadDynamicProfiles(); + VERIFY_ARE_EQUAL(5u, settings->_profiles.Size()); + + VERIFY_ARE_EQUAL(L"profile0", settings->_profiles.GetAt(0).Name()); + VERIFY_IS_FALSE(settings->_profiles.GetAt(0).HasGuid()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(0).Source().empty()); + + VERIFY_ARE_EQUAL(L"profile1", settings->_profiles.GetAt(1).Name()); + VERIFY_IS_FALSE(settings->_profiles.GetAt(1).HasGuid()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(1).Source().empty()); + + VERIFY_ARE_EQUAL(L"profile0", settings->_profiles.GetAt(2).Name()); + VERIFY_IS_FALSE(settings->_profiles.GetAt(2).HasGuid()); + VERIFY_IS_FALSE(settings->_profiles.GetAt(2).Source().empty()); + + VERIFY_ARE_EQUAL(L"profile0", settings->_profiles.GetAt(3).Name()); + VERIFY_IS_FALSE(settings->_profiles.GetAt(3).HasGuid()); + VERIFY_IS_FALSE(settings->_profiles.GetAt(3).Source().empty()); + + VERIFY_ARE_EQUAL(L"profile1", settings->_profiles.GetAt(4).Name()); + VERIFY_IS_FALSE(settings->_profiles.GetAt(4).HasGuid()); + VERIFY_IS_FALSE(settings->_profiles.GetAt(4).Source().empty()); + + settings->_ValidateProfilesHaveGuid(); + + VERIFY_IS_TRUE(settings->_profiles.GetAt(0).HasGuid()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(1).HasGuid()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(2).HasGuid()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(3).HasGuid()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(4).HasGuid()); + + VERIFY_ARE_NOT_EQUAL(settings->_profiles.GetAt(0).Guid(), + settings->_profiles.GetAt(1).Guid()); + VERIFY_ARE_NOT_EQUAL(settings->_profiles.GetAt(0).Guid(), + settings->_profiles.GetAt(2).Guid()); + VERIFY_ARE_NOT_EQUAL(settings->_profiles.GetAt(0).Guid(), + settings->_profiles.GetAt(3).Guid()); + + VERIFY_ARE_NOT_EQUAL(settings->_profiles.GetAt(1).Guid(), + settings->_profiles.GetAt(4).Guid()); + + VERIFY_ARE_NOT_EQUAL(settings->_profiles.GetAt(3).Guid(), + settings->_profiles.GetAt(4).Guid()); } void DynamicProfileTests::DontLayerUserProfilesOnDynamicProfiles() @@ -229,43 +229,43 @@ namespace TerminalAppUnitTests return profiles; }; - CascadiaSettings settings{ false }; - settings._profileGenerators.emplace_back(std::move(gen0)); - settings._profileGenerators.emplace_back(std::move(gen1)); + auto settings = winrt::make_self(false); + settings->_profileGenerators.emplace_back(std::move(gen0)); + settings->_profileGenerators.emplace_back(std::move(gen1)); Log::Comment(NoThrowString().Format( L"All profiles with the same name have the same GUID. However, they" L" will not be layered, because they have different sources")); // parse userProfiles as the user settings - settings._ParseJsonString(userProfiles, false); - VERIFY_ARE_EQUAL(0u, settings._profiles.size(), L"Just parsing the user settings doesn't actually layer them"); - settings._LoadDynamicProfiles(); - VERIFY_ARE_EQUAL(3u, settings._profiles.size()); - settings.LayerJson(settings._userSettings); - VERIFY_ARE_EQUAL(5u, settings._profiles.size()); - - VERIFY_IS_FALSE(settings._profiles.at(0).Source().empty()); - VERIFY_IS_FALSE(settings._profiles.at(1).Source().empty()); - VERIFY_IS_FALSE(settings._profiles.at(2).Source().empty()); - VERIFY_IS_TRUE(settings._profiles.at(3).Source().empty()); - VERIFY_IS_TRUE(settings._profiles.at(4).Source().empty()); - - VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.0", settings._profiles.at(0).Source()); - VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.1", settings._profiles.at(1).Source()); - VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.1", settings._profiles.at(2).Source()); - - VERIFY_IS_TRUE(settings._profiles.at(0).HasGuid()); - VERIFY_IS_TRUE(settings._profiles.at(1).HasGuid()); - VERIFY_IS_TRUE(settings._profiles.at(2).HasGuid()); - VERIFY_IS_TRUE(settings._profiles.at(3).HasGuid()); - VERIFY_IS_TRUE(settings._profiles.at(4).HasGuid()); - - VERIFY_ARE_EQUAL(guid0, settings._profiles.at(0).Guid()); - VERIFY_ARE_EQUAL(guid0, settings._profiles.at(1).Guid()); - VERIFY_ARE_EQUAL(guid1, settings._profiles.at(2).Guid()); - VERIFY_ARE_EQUAL(guid0, settings._profiles.at(3).Guid()); - VERIFY_ARE_EQUAL(guid1, settings._profiles.at(4).Guid()); + settings->_ParseJsonString(userProfiles, false); + VERIFY_ARE_EQUAL(0u, settings->_profiles.Size(), L"Just parsing the user settings doesn't actually layer them"); + settings->_LoadDynamicProfiles(); + VERIFY_ARE_EQUAL(3u, settings->_profiles.Size()); + settings->LayerJson(settings->_userSettings); + VERIFY_ARE_EQUAL(5u, settings->_profiles.Size()); + + VERIFY_IS_FALSE(settings->_profiles.GetAt(0).Source().empty()); + VERIFY_IS_FALSE(settings->_profiles.GetAt(1).Source().empty()); + VERIFY_IS_FALSE(settings->_profiles.GetAt(2).Source().empty()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(3).Source().empty()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(4).Source().empty()); + + VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.0", settings->_profiles.GetAt(0).Source()); + VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.1", settings->_profiles.GetAt(1).Source()); + VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.1", settings->_profiles.GetAt(2).Source()); + + VERIFY_IS_TRUE(settings->_profiles.GetAt(0).HasGuid()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(1).HasGuid()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(2).HasGuid()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(3).HasGuid()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(4).HasGuid()); + + VERIFY_ARE_EQUAL(guid0, settings->_profiles.GetAt(0).Guid()); + VERIFY_ARE_EQUAL(guid0, settings->_profiles.GetAt(1).Guid()); + VERIFY_ARE_EQUAL(guid1, settings->_profiles.GetAt(2).Guid()); + VERIFY_ARE_EQUAL(guid0, settings->_profiles.GetAt(3).Guid()); + VERIFY_ARE_EQUAL(guid1, settings->_profiles.GetAt(4).Guid()); } void DynamicProfileTests::DoLayerUserProfilesOnDynamicsWhenSourceMatches() @@ -309,41 +309,41 @@ namespace TerminalAppUnitTests return profiles; }; - CascadiaSettings settings{ false }; - settings._profileGenerators.emplace_back(std::move(gen0)); - settings._profileGenerators.emplace_back(std::move(gen1)); + auto settings = winrt::make_self(false); + settings->_profileGenerators.emplace_back(std::move(gen0)); + settings->_profileGenerators.emplace_back(std::move(gen1)); Log::Comment(NoThrowString().Format( L"All profiles with the same name have the same GUID. However, they" L" will not be layered, because they have different source's")); // parse userProfiles as the user settings - settings._ParseJsonString(userProfiles, false); - VERIFY_ARE_EQUAL(0u, settings._profiles.size(), L"Just parsing the user settings doesn't actually layer them"); - settings._LoadDynamicProfiles(); - VERIFY_ARE_EQUAL(3u, settings._profiles.size()); - settings.LayerJson(settings._userSettings); - VERIFY_ARE_EQUAL(3u, settings._profiles.size()); - - VERIFY_IS_FALSE(settings._profiles.at(0).Source().empty()); - VERIFY_IS_FALSE(settings._profiles.at(1).Source().empty()); - VERIFY_IS_FALSE(settings._profiles.at(2).Source().empty()); - - VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.0", settings._profiles.at(0).Source()); - VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.1", settings._profiles.at(1).Source()); - VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.1", settings._profiles.at(2).Source()); - - VERIFY_IS_TRUE(settings._profiles.at(0).HasGuid()); - VERIFY_IS_TRUE(settings._profiles.at(1).HasGuid()); - VERIFY_IS_TRUE(settings._profiles.at(2).HasGuid()); - - VERIFY_ARE_EQUAL(guid0, settings._profiles.at(0).Guid()); - VERIFY_ARE_EQUAL(guid0, settings._profiles.at(1).Guid()); - VERIFY_ARE_EQUAL(guid1, settings._profiles.at(2).Guid()); - - VERIFY_ARE_EQUAL(L"profile0FromUserSettings", settings._profiles.at(0).Name()); - VERIFY_ARE_EQUAL(L"profile0", settings._profiles.at(1).Name()); - VERIFY_ARE_EQUAL(L"profile1FromUserSettings", settings._profiles.at(2).Name()); + settings->_ParseJsonString(userProfiles, false); + VERIFY_ARE_EQUAL(0u, settings->_profiles.Size(), L"Just parsing the user settings doesn't actually layer them"); + settings->_LoadDynamicProfiles(); + VERIFY_ARE_EQUAL(3u, settings->_profiles.Size()); + settings->LayerJson(settings->_userSettings); + VERIFY_ARE_EQUAL(3u, settings->_profiles.Size()); + + VERIFY_IS_FALSE(settings->_profiles.GetAt(0).Source().empty()); + VERIFY_IS_FALSE(settings->_profiles.GetAt(1).Source().empty()); + VERIFY_IS_FALSE(settings->_profiles.GetAt(2).Source().empty()); + + VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.0", settings->_profiles.GetAt(0).Source()); + VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.1", settings->_profiles.GetAt(1).Source()); + VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.1", settings->_profiles.GetAt(2).Source()); + + VERIFY_IS_TRUE(settings->_profiles.GetAt(0).HasGuid()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(1).HasGuid()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(2).HasGuid()); + + VERIFY_ARE_EQUAL(guid0, settings->_profiles.GetAt(0).Guid()); + VERIFY_ARE_EQUAL(guid0, settings->_profiles.GetAt(1).Guid()); + VERIFY_ARE_EQUAL(guid1, settings->_profiles.GetAt(2).Guid()); + + VERIFY_ARE_EQUAL(L"profile0FromUserSettings", settings->_profiles.GetAt(0).Name()); + VERIFY_ARE_EQUAL(L"profile0", settings->_profiles.GetAt(1).Name()); + VERIFY_ARE_EQUAL(L"profile1FromUserSettings", settings->_profiles.GetAt(2).Name()); } void DynamicProfileTests::TestDontRunDisabledGenerators() @@ -390,7 +390,7 @@ namespace TerminalAppUnitTests { Log::Comment(NoThrowString().Format( L"Case 1: Disable a single profile generator")); - CascadiaSettings settings{ false }; + auto settings = winrt::make_self(false); auto gen0 = std::make_unique(L"Terminal.App.UnitTest.0"); auto gen1 = std::make_unique(L"Terminal.App.UnitTest.1"); @@ -398,54 +398,54 @@ namespace TerminalAppUnitTests gen0->pfnGenerate = gen0GenerateFn; gen1->pfnGenerate = gen1GenerateFn; gen2->pfnGenerate = gen2GenerateFn; - settings._profileGenerators.emplace_back(std::move(gen0)); - settings._profileGenerators.emplace_back(std::move(gen1)); - settings._profileGenerators.emplace_back(std::move(gen2)); + settings->_profileGenerators.emplace_back(std::move(gen0)); + settings->_profileGenerators.emplace_back(std::move(gen1)); + settings->_profileGenerators.emplace_back(std::move(gen2)); // Parse as the user settings: - settings._ParseJsonString(settings0String, false); - settings._LoadDynamicProfiles(); - - VERIFY_ARE_EQUAL(4u, settings._profiles.size()); - VERIFY_IS_FALSE(settings._profiles.at(0).Source().empty()); - VERIFY_IS_FALSE(settings._profiles.at(1).Source().empty()); - VERIFY_IS_FALSE(settings._profiles.at(2).Source().empty()); - VERIFY_IS_FALSE(settings._profiles.at(3).Source().empty()); - VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.1", settings._profiles.at(0).Source()); - VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.1", settings._profiles.at(1).Source()); - VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.2", settings._profiles.at(2).Source()); - VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.2", settings._profiles.at(3).Source()); - VERIFY_ARE_EQUAL(L"profile1", settings._profiles.at(0).Name()); - VERIFY_ARE_EQUAL(L"profile2", settings._profiles.at(1).Name()); - VERIFY_ARE_EQUAL(L"profile3", settings._profiles.at(2).Name()); - VERIFY_ARE_EQUAL(L"profile4", settings._profiles.at(3).Name()); + settings->_ParseJsonString(settings0String, false); + settings->_LoadDynamicProfiles(); + + VERIFY_ARE_EQUAL(4u, settings->_profiles.Size()); + VERIFY_IS_FALSE(settings->_profiles.GetAt(0).Source().empty()); + VERIFY_IS_FALSE(settings->_profiles.GetAt(1).Source().empty()); + VERIFY_IS_FALSE(settings->_profiles.GetAt(2).Source().empty()); + VERIFY_IS_FALSE(settings->_profiles.GetAt(3).Source().empty()); + VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.1", settings->_profiles.GetAt(0).Source()); + VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.1", settings->_profiles.GetAt(1).Source()); + VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.2", settings->_profiles.GetAt(2).Source()); + VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.2", settings->_profiles.GetAt(3).Source()); + VERIFY_ARE_EQUAL(L"profile1", settings->_profiles.GetAt(0).Name()); + VERIFY_ARE_EQUAL(L"profile2", settings->_profiles.GetAt(1).Name()); + VERIFY_ARE_EQUAL(L"profile3", settings->_profiles.GetAt(2).Name()); + VERIFY_ARE_EQUAL(L"profile4", settings->_profiles.GetAt(3).Name()); } { Log::Comment(NoThrowString().Format( L"Case 2: Disable multiple profile generators")); - CascadiaSettings settings{ false }; + auto settings = winrt::make_self(false); auto gen0 = std::make_unique(L"Terminal.App.UnitTest.0"); auto gen1 = std::make_unique(L"Terminal.App.UnitTest.1"); auto gen2 = std::make_unique(L"Terminal.App.UnitTest.2"); gen0->pfnGenerate = gen0GenerateFn; gen1->pfnGenerate = gen1GenerateFn; gen2->pfnGenerate = gen2GenerateFn; - settings._profileGenerators.emplace_back(std::move(gen0)); - settings._profileGenerators.emplace_back(std::move(gen1)); - settings._profileGenerators.emplace_back(std::move(gen2)); + settings->_profileGenerators.emplace_back(std::move(gen0)); + settings->_profileGenerators.emplace_back(std::move(gen1)); + settings->_profileGenerators.emplace_back(std::move(gen2)); // Parse as the user settings: - settings._ParseJsonString(settings1String, false); - settings._LoadDynamicProfiles(); - - VERIFY_ARE_EQUAL(2u, settings._profiles.size()); - VERIFY_IS_FALSE(settings._profiles.at(0).Source().empty()); - VERIFY_IS_FALSE(settings._profiles.at(1).Source().empty()); - VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.2", settings._profiles.at(0).Source()); - VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.2", settings._profiles.at(1).Source()); - VERIFY_ARE_EQUAL(L"profile3", settings._profiles.at(0).Name()); - VERIFY_ARE_EQUAL(L"profile4", settings._profiles.at(1).Name()); + settings->_ParseJsonString(settings1String, false); + settings->_LoadDynamicProfiles(); + + VERIFY_ARE_EQUAL(2u, settings->_profiles.Size()); + VERIFY_IS_FALSE(settings->_profiles.GetAt(0).Source().empty()); + VERIFY_IS_FALSE(settings->_profiles.GetAt(1).Source().empty()); + VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.2", settings->_profiles.GetAt(0).Source()); + VERIFY_ARE_EQUAL(L"Terminal.App.UnitTest.2", settings->_profiles.GetAt(1).Source()); + VERIFY_ARE_EQUAL(L"profile3", settings->_profiles.GetAt(0).Name()); + VERIFY_ARE_EQUAL(L"profile4", settings->_profiles.GetAt(1).Name()); } } @@ -517,48 +517,48 @@ namespace TerminalAppUnitTests return profiles; }; - CascadiaSettings settings{ false }; - settings._profileGenerators.emplace_back(std::move(gen0)); - settings._profileGenerators.emplace_back(std::move(gen1)); - settings._profileGenerators.emplace_back(std::move(gen2)); - - settings._ParseJsonString(settings0String, false); - VERIFY_ARE_EQUAL(0u, settings._profiles.size()); - - settings._LoadDynamicProfiles(); - VERIFY_ARE_EQUAL(4u, settings._profiles.size()); - - VERIFY_IS_FALSE(settings._profiles.at(0).Source().empty()); - VERIFY_IS_FALSE(settings._profiles.at(1).Source().empty()); - VERIFY_IS_FALSE(settings._profiles.at(2).Source().empty()); - VERIFY_IS_FALSE(settings._profiles.at(3).Source().empty()); - VERIFY_ARE_EQUAL(L"Windows.Terminal.PowershellCore", settings._profiles.at(0).Source()); - VERIFY_ARE_EQUAL(L"Windows.Terminal.Wsl", settings._profiles.at(1).Source()); - VERIFY_ARE_EQUAL(L"Windows.Terminal.Wsl", settings._profiles.at(2).Source()); - VERIFY_ARE_EQUAL(L"Windows.Terminal.Azure", settings._profiles.at(3).Source()); - VERIFY_ARE_EQUAL(L"profile0", settings._profiles.at(0).Name()); - VERIFY_ARE_EQUAL(L"profile1", settings._profiles.at(1).Name()); - VERIFY_ARE_EQUAL(L"profile2", settings._profiles.at(2).Name()); - VERIFY_ARE_EQUAL(L"profile3", settings._profiles.at(3).Name()); - - settings.LayerJson(settings._userSettings); - VERIFY_ARE_EQUAL(5u, settings._profiles.size()); - - VERIFY_IS_FALSE(settings._profiles.at(0).Source().empty()); - VERIFY_IS_FALSE(settings._profiles.at(1).Source().empty()); - VERIFY_IS_FALSE(settings._profiles.at(2).Source().empty()); - VERIFY_IS_FALSE(settings._profiles.at(3).Source().empty()); - VERIFY_IS_TRUE(settings._profiles.at(4).Source().empty()); - VERIFY_ARE_EQUAL(L"Windows.Terminal.PowershellCore", settings._profiles.at(0).Source()); - VERIFY_ARE_EQUAL(L"Windows.Terminal.Wsl", settings._profiles.at(1).Source()); - VERIFY_ARE_EQUAL(L"Windows.Terminal.Wsl", settings._profiles.at(2).Source()); - VERIFY_ARE_EQUAL(L"Windows.Terminal.Azure", settings._profiles.at(3).Source()); - // settings._profiles.at(4) does not have a source - VERIFY_ARE_EQUAL(L"profile0FromUserSettings", settings._profiles.at(0).Name()); - VERIFY_ARE_EQUAL(L"profile1FromUserSettings", settings._profiles.at(1).Name()); - VERIFY_ARE_EQUAL(L"profile2FromUserSettings", settings._profiles.at(2).Name()); - VERIFY_ARE_EQUAL(L"profile3FromUserSettings", settings._profiles.at(3).Name()); - VERIFY_ARE_EQUAL(L"profile4FromUserSettings", settings._profiles.at(4).Name()); + auto settings = winrt::make_self(false); + settings->_profileGenerators.emplace_back(std::move(gen0)); + settings->_profileGenerators.emplace_back(std::move(gen1)); + settings->_profileGenerators.emplace_back(std::move(gen2)); + + settings->_ParseJsonString(settings0String, false); + VERIFY_ARE_EQUAL(0u, settings->_profiles.Size()); + + settings->_LoadDynamicProfiles(); + VERIFY_ARE_EQUAL(4u, settings->_profiles.Size()); + + VERIFY_IS_FALSE(settings->_profiles.GetAt(0).Source().empty()); + VERIFY_IS_FALSE(settings->_profiles.GetAt(1).Source().empty()); + VERIFY_IS_FALSE(settings->_profiles.GetAt(2).Source().empty()); + VERIFY_IS_FALSE(settings->_profiles.GetAt(3).Source().empty()); + VERIFY_ARE_EQUAL(L"Windows.Terminal.PowershellCore", settings->_profiles.GetAt(0).Source()); + VERIFY_ARE_EQUAL(L"Windows.Terminal.Wsl", settings->_profiles.GetAt(1).Source()); + VERIFY_ARE_EQUAL(L"Windows.Terminal.Wsl", settings->_profiles.GetAt(2).Source()); + VERIFY_ARE_EQUAL(L"Windows.Terminal.Azure", settings->_profiles.GetAt(3).Source()); + VERIFY_ARE_EQUAL(L"profile0", settings->_profiles.GetAt(0).Name()); + VERIFY_ARE_EQUAL(L"profile1", settings->_profiles.GetAt(1).Name()); + VERIFY_ARE_EQUAL(L"profile2", settings->_profiles.GetAt(2).Name()); + VERIFY_ARE_EQUAL(L"profile3", settings->_profiles.GetAt(3).Name()); + + settings->LayerJson(settings->_userSettings); + VERIFY_ARE_EQUAL(5u, settings->_profiles.Size()); + + VERIFY_IS_FALSE(settings->_profiles.GetAt(0).Source().empty()); + VERIFY_IS_FALSE(settings->_profiles.GetAt(1).Source().empty()); + VERIFY_IS_FALSE(settings->_profiles.GetAt(2).Source().empty()); + VERIFY_IS_FALSE(settings->_profiles.GetAt(3).Source().empty()); + VERIFY_IS_TRUE(settings->_profiles.GetAt(4).Source().empty()); + VERIFY_ARE_EQUAL(L"Windows.Terminal.PowershellCore", settings->_profiles.GetAt(0).Source()); + VERIFY_ARE_EQUAL(L"Windows.Terminal.Wsl", settings->_profiles.GetAt(1).Source()); + VERIFY_ARE_EQUAL(L"Windows.Terminal.Wsl", settings->_profiles.GetAt(2).Source()); + VERIFY_ARE_EQUAL(L"Windows.Terminal.Azure", settings->_profiles.GetAt(3).Source()); + // settings->_profiles.GetAt(4) does not have a source + VERIFY_ARE_EQUAL(L"profile0FromUserSettings", settings->_profiles.GetAt(0).Name()); + VERIFY_ARE_EQUAL(L"profile1FromUserSettings", settings->_profiles.GetAt(1).Name()); + VERIFY_ARE_EQUAL(L"profile2FromUserSettings", settings->_profiles.GetAt(2).Name()); + VERIFY_ARE_EQUAL(L"profile3FromUserSettings", settings->_profiles.GetAt(3).Name()); + VERIFY_ARE_EQUAL(L"profile4FromUserSettings", settings->_profiles.GetAt(4).Name()); } void DynamicProfileTests::UserProfilesWithInvalidSourcesAreIgnored() @@ -606,18 +606,18 @@ namespace TerminalAppUnitTests return profiles; }; - CascadiaSettings settings{ false }; - settings._profileGenerators.emplace_back(std::move(gen0)); - settings._profileGenerators.emplace_back(std::move(gen1)); + auto settings = winrt::make_self(false); + settings->_profileGenerators.emplace_back(std::move(gen0)); + settings->_profileGenerators.emplace_back(std::move(gen1)); - settings._ParseJsonString(settings0String, false); - VERIFY_ARE_EQUAL(0u, settings._profiles.size()); + settings->_ParseJsonString(settings0String, false); + VERIFY_ARE_EQUAL(0u, settings->_profiles.Size()); - settings._LoadDynamicProfiles(); - VERIFY_ARE_EQUAL(3u, settings._profiles.size()); + settings->_LoadDynamicProfiles(); + VERIFY_ARE_EQUAL(3u, settings->_profiles.Size()); - settings.LayerJson(settings._userSettings); - VERIFY_ARE_EQUAL(4u, settings._profiles.size()); + settings->LayerJson(settings->_userSettings); + VERIFY_ARE_EQUAL(4u, settings->_profiles.Size()); } void DynamicProfileTests::UserProfilesFromDisabledSourcesDontAppear() @@ -666,18 +666,18 @@ namespace TerminalAppUnitTests return profiles; }; - CascadiaSettings settings{ false }; - settings._profileGenerators.emplace_back(std::move(gen0)); - settings._profileGenerators.emplace_back(std::move(gen1)); + auto settings = winrt::make_self(false); + settings->_profileGenerators.emplace_back(std::move(gen0)); + settings->_profileGenerators.emplace_back(std::move(gen1)); - settings._ParseJsonString(settings0String, false); - VERIFY_ARE_EQUAL(0u, settings._profiles.size()); + settings->_ParseJsonString(settings0String, false); + VERIFY_ARE_EQUAL(0u, settings->_profiles.Size()); - settings._LoadDynamicProfiles(); - VERIFY_ARE_EQUAL(1u, settings._profiles.size()); + settings->_LoadDynamicProfiles(); + VERIFY_ARE_EQUAL(1u, settings->_profiles.Size()); - settings.LayerJson(settings._userSettings); - VERIFY_ARE_EQUAL(2u, settings._profiles.size()); + settings->LayerJson(settings->_userSettings); + VERIFY_ARE_EQUAL(2u, settings->_profiles.Size()); } }; From 1c7ee65c5f2e7a8ee4b7d5e3f6bc2c83092a9934 Mon Sep 17 00:00:00 2001 From: Kayla Cinnamon Date: Wed, 9 Sep 2020 16:11:27 -0700 Subject: [PATCH 104/266] Add initial settings UI spec (#6720) ## Summary of the Pull Request This is the spec for the overall functionality of the settings UI - #1564. There are proposals for the launch method and editing and saving settings that we should discuss. ## Detailed Description of the Pull Request / Additional comments ### [spec.md](https://github.com/microsoft/terminal/blob/cinnamon/spec-settings-ui/doc/specs/%231564%20-%20Settings%20UI/spec.md) ### [design.md](https://github.com/microsoft/terminal/blob/cinnamon/spec-settings-ui/doc/specs/%231564%20-%20Settings%20UI/design.md) --- doc/specs/#1564 - Settings UI/appearance.png | Bin 0 -> 280842 bytes doc/specs/#1564 - Settings UI/design.md | 112 ++++++++++++++++ .../keyboard-modal-add.png | Bin 0 -> 220030 bytes .../keyboard-modal-args.png | Bin 0 -> 221300 bytes .../#1564 - Settings UI/keyboard-modal.png | Bin 0 -> 218441 bytes doc/specs/#1564 - Settings UI/keyboard.png | Bin 0 -> 216210 bytes .../#1564 - Settings UI/navigation-2.png | Bin 0 -> 228407 bytes doc/specs/#1564 - Settings UI/navigation.png | Bin 0 -> 47683 bytes doc/specs/#1564 - Settings UI/spec.md | 122 ++++++++++++++++++ 9 files changed, 234 insertions(+) create mode 100644 doc/specs/#1564 - Settings UI/appearance.png create mode 100644 doc/specs/#1564 - Settings UI/design.md create mode 100644 doc/specs/#1564 - Settings UI/keyboard-modal-add.png create mode 100644 doc/specs/#1564 - Settings UI/keyboard-modal-args.png create mode 100644 doc/specs/#1564 - Settings UI/keyboard-modal.png create mode 100644 doc/specs/#1564 - Settings UI/keyboard.png create mode 100644 doc/specs/#1564 - Settings UI/navigation-2.png create mode 100644 doc/specs/#1564 - Settings UI/navigation.png create mode 100644 doc/specs/#1564 - Settings UI/spec.md diff --git a/doc/specs/#1564 - Settings UI/appearance.png b/doc/specs/#1564 - Settings UI/appearance.png new file mode 100644 index 0000000000000000000000000000000000000000..f83029745e8602d266e8f9093a39e141f9feec15 GIT binary patch literal 280842 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®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�~ITKH6(}hR*M4eho+P=;l;CrKc-=zi+)BOB9im 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

4e$*P@GlMs91aNH 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%0A5Ofu2a5D~?DEg=D+!D-5P}FKKn4=|1d`wa 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%0DnG* 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 z diff --git a/src/common.build.tests.props b/src/common.build.tests.props index 79410878836..02dc8706ef7 100644 --- a/src/common.build.tests.props +++ b/src/common.build.tests.props @@ -5,11 +5,11 @@ INLINE_TEST_METHOD_MARKUP;UNIT_TESTING;%(PreprocessorDefinitions) - + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + diff --git a/src/host/ft_uia/Host.Tests.UIA.csproj b/src/host/ft_uia/Host.Tests.UIA.csproj index c963f3d9624..d85b269e2e9 100644 --- a/src/host/ft_uia/Host.Tests.UIA.csproj +++ b/src/host/ft_uia/Host.Tests.UIA.csproj @@ -53,7 +53,10 @@ - ..\..\..\packages\Taef.Redist.Wlk.10.51.200127004\lib\net45\TE.Managed.dll + ..\..\..\packages\Taef.Redist.Wlk.10.57.200731005-develop\lib\net45\TE.Managed.dll + + + ..\..\..\packages\Taef.Redist.Wlk.10.57.200731005-develop\lib\net45\TE.Model.Managed.dll @@ -64,10 +67,10 @@ ..\..\..\packages\Selenium.Support.3.5.0\lib\net40\WebDriver.Support.dll - ..\..\..\packages\Taef.Redist.Wlk.10.51.200127004\lib\net45\Wex.Common.Managed.dll + ..\..\..\packages\Taef.Redist.Wlk.10.57.200731005-develop\lib\net45\Wex.Common.Managed.dll - ..\..\..\packages\Taef.Redist.Wlk.10.51.200127004\lib\net45\Wex.Logger.Interop.dll + ..\..\..\packages\Taef.Redist.Wlk.10.57.200731005-develop\lib\net45\Wex.Logger.Interop.dll @@ -142,11 +145,11 @@ copy $(SolutionDir)\dep\WinAppDriver\* $(OutDir)\ - + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + - + \ No newline at end of file diff --git a/src/host/ft_uia/app.config b/src/host/ft_uia/app.config index bf061caaf76..5d6775b6725 100644 --- a/src/host/ft_uia/app.config +++ b/src/host/ft_uia/app.config @@ -8,7 +8,7 @@ - + diff --git a/src/host/ft_uia/packages.config b/src/host/ft_uia/packages.config index 6629afad84b..101824b09d4 100644 --- a/src/host/ft_uia/packages.config +++ b/src/host/ft_uia/packages.config @@ -5,5 +5,5 @@ - - + + \ No newline at end of file diff --git a/src/terminal/parser/ut_parser/Parser.UnitTests.vcxproj b/src/terminal/parser/ut_parser/Parser.UnitTests.vcxproj index 02e923f575e..df36be81a1b 100644 --- a/src/terminal/parser/ut_parser/Parser.UnitTests.vcxproj +++ b/src/terminal/parser/ut_parser/Parser.UnitTests.vcxproj @@ -6,15 +6,12 @@ ParserUnitTests TerminalParser.UnitTests ConParser.Unit.Tests - DynamicLibrary + DynamicLibrary - - - @@ -26,13 +23,11 @@ Create - ..;%(AdditionalIncludeDirectories) - {18d09a24-8240-42d6-8cb6-236eee820263} @@ -44,9 +39,17 @@ {3ae13314-1939-4dfa-9c14-38ca0834050c} - - + + + - + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + \ No newline at end of file diff --git a/src/terminal/parser/ut_parser/Parser.UnitTests.vcxproj.filters b/src/terminal/parser/ut_parser/Parser.UnitTests.vcxproj.filters index adc0b0fec1f..40253dffc1c 100644 --- a/src/terminal/parser/ut_parser/Parser.UnitTests.vcxproj.filters +++ b/src/terminal/parser/ut_parser/Parser.UnitTests.vcxproj.filters @@ -36,4 +36,10 @@ Header Files - + + + + + + + \ No newline at end of file diff --git a/src/terminal/parser/ut_parser/packages.config b/src/terminal/parser/ut_parser/packages.config index 42477ca456a..3a630c09c2c 100644 --- a/src/terminal/parser/ut_parser/packages.config +++ b/src/terminal/parser/ut_parser/packages.config @@ -1,4 +1,4 @@  - - + + \ No newline at end of file diff --git a/tools/OpenConsole.psm1 b/tools/OpenConsole.psm1 index bef3078a0d2..78c5416eddb 100644 --- a/tools/OpenConsole.psm1 +++ b/tools/OpenConsole.psm1 @@ -189,7 +189,7 @@ function Invoke-OpenConsoleTests() } $OpenConsolePath = "$env:OpenConsoleroot\bin\$OpenConsolePlatform\$Configuration\OpenConsole.exe" $RunTePath = "$env:OpenConsoleRoot\tools\runte.cmd" - $TaefExePath = "$env:OpenConsoleRoot\packages\Taef.Redist.Wlk.10.51.200127004\build\Binaries\$Platform\te.exe" + $TaefExePath = "$env:OpenConsoleRoot\packages\Taef.Redist.Wlk.10.57.200731005-develop\build\Binaries\$Platform\te.exe" $BinDir = "$env:OpenConsoleRoot\bin\$OpenConsolePlatform\$Configuration" [xml]$TestConfig = Get-Content "$env:OpenConsoleRoot\tools\tests.xml" diff --git a/tools/razzle.cmd b/tools/razzle.cmd index 0851160f9ef..9dedd23caca 100644 --- a/tools/razzle.cmd +++ b/tools/razzle.cmd @@ -104,7 +104,7 @@ shift goto :ARGS_LOOP :POST_ARGS_LOOP -set TAEF=%OPENCON%\packages\Taef.Redist.Wlk.10.51.200127004\build\Binaries\%ARCH%\TE.exe +set TAEF=%OPENCON%\packages\Taef.Redist.Wlk.10.57.200731005-develop\build\Binaries\%ARCH%\TE.exe rem Set this envvar so setup won't repeat itself set OpenConBuild=true From 7bf9225c155ea7062c9dd0825078417e0045ac81 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Mon, 3 Aug 2020 16:13:30 -0500 Subject: [PATCH 019/266] Research how many characters users are typing before dismissing the cmdpal (#7165) Add some user research to determine what the average number of characters a user types before executing a cmdpal action. This might need to be modified when it merges with #6732 --- src/cascadia/TerminalApp/CommandPalette.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/cascadia/TerminalApp/CommandPalette.cpp b/src/cascadia/TerminalApp/CommandPalette.cpp index 0e67a0c2c2e..fd0a139281b 100644 --- a/src/cascadia/TerminalApp/CommandPalette.cpp +++ b/src/cascadia/TerminalApp/CommandPalette.cpp @@ -187,15 +187,16 @@ namespace winrt::TerminalApp::implementation { const auto actionAndArgs = command.Action(); _dispatch.DoAction(actionAndArgs); - _close(); TraceLoggingWrite( g_hTerminalAppProvider, // handle to TerminalApp tracelogging provider "CommandPaletteDispatchedAction", TraceLoggingDescription("Event emitted when the user selects an action in the Command Palette"), - TraceLoggingUInt32(_searchBox().Text().size(), "Number of characters in the search string"), + TraceLoggingUInt32(_searchBox().Text().size(), "SearchTextLength", "Number of characters in the search string"), TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance)); + + _close(); } } From eb8bb09e5be661ca7e717f0cb94b5712a27a97fb Mon Sep 17 00:00:00 2001 From: Carlos Zamora Date: Mon, 3 Aug 2020 15:54:22 -0700 Subject: [PATCH 020/266] Move TerminalSettings object to TermApp Project (#7163) Move TerminalSettings object from TerminalSettings project (Microsoft.Terminal.Settings) to TerminalApp project. `TerminalSettings` specifically operates as a bridge that exposes any necessary information to a TerminalControl. Closes #7139 Related Epic: #885 Related Spec: #6904 ## PR Checklist * [X] Closes #7139 * [X] CLA signed * [X] Tests ~added~/passed (no additional tests necessary) * [X] ~Documentation updated~ * [X] ~Schema updated~ ## Validation Steps Performed Deployed Windows Terminal and opened a few new tabs. --- .../LocalTests_TerminalApp/SettingsTests.cpp | 2 +- src/cascadia/LocalTests_TerminalApp/TabTests.cpp | 4 ++-- src/cascadia/TerminalApp/CascadiaSettings.h | 4 ++-- src/cascadia/TerminalApp/ColorScheme.cpp | 4 ++-- src/cascadia/TerminalApp/ColorScheme.h | 4 ++-- src/cascadia/TerminalApp/GlobalAppSettings.h | 2 +- src/cascadia/TerminalApp/Pane.h | 2 +- src/cascadia/TerminalApp/Profile.cpp | 1 + src/cascadia/TerminalApp/Profile.h | 2 +- src/cascadia/TerminalApp/Tab.h | 2 +- src/cascadia/TerminalApp/TerminalPage.cpp | 7 +++---- src/cascadia/TerminalApp/TerminalPage.h | 4 ++-- .../TerminalSettings.cpp | 2 +- .../TerminalSettings.h} | 12 ++++++------ .../TerminalSettings.idl | 9 +++------ src/cascadia/TerminalApp/lib/TerminalAppLib.vcxproj | 7 +++++++ .../TerminalApp/lib/TerminalAppLib.vcxproj.filters | 12 ++++++++---- src/cascadia/TerminalControl/TermControl.cpp | 5 ----- src/cascadia/TerminalControl/TermControl.h | 1 - src/cascadia/TerminalControl/TermControl.idl | 1 - .../TerminalSettings/TerminalSettings.vcxproj | 12 +----------- 21 files changed, 45 insertions(+), 54 deletions(-) rename src/cascadia/{TerminalSettings => TerminalApp}/TerminalSettings.cpp (87%) rename src/cascadia/{TerminalSettings/terminalsettings.h => TerminalApp/TerminalSettings.h} (84%) rename src/cascadia/{TerminalSettings => TerminalApp}/TerminalSettings.idl (75%) diff --git a/src/cascadia/LocalTests_TerminalApp/SettingsTests.cpp b/src/cascadia/LocalTests_TerminalApp/SettingsTests.cpp index cdfb08415f5..f1eeddc2641 100644 --- a/src/cascadia/LocalTests_TerminalApp/SettingsTests.cpp +++ b/src/cascadia/LocalTests_TerminalApp/SettingsTests.cpp @@ -93,7 +93,7 @@ namespace TerminalAppLocalTests void SettingsTests::TryCreateWinRTType() { - winrt::Microsoft::Terminal::Settings::TerminalSettings settings; + TerminalSettings settings; VERIFY_IS_NOT_NULL(settings); auto oldFontSize = settings.FontSize(); settings.FontSize(oldFontSize + 5); diff --git a/src/cascadia/LocalTests_TerminalApp/TabTests.cpp b/src/cascadia/LocalTests_TerminalApp/TabTests.cpp index b515eacd93e..3c417174c59 100644 --- a/src/cascadia/LocalTests_TerminalApp/TabTests.cpp +++ b/src/cascadia/LocalTests_TerminalApp/TabTests.cpp @@ -84,7 +84,7 @@ namespace TerminalAppLocalTests { // Verify we can create a WinRT type we authored // Just creating it is enough to know that everything is working. - winrt::Microsoft::Terminal::Settings::TerminalSettings settings; + TerminalSettings settings; VERIFY_IS_NOT_NULL(settings); auto oldFontSize = settings.FontSize(); settings.FontSize(oldFontSize + 5); @@ -140,7 +140,7 @@ namespace TerminalAppLocalTests // 4. one of our types that uses MUX/Xaml in this dll (Tab). // Just creating all of them is enough to know that everything is working. const auto profileGuid{ Utils::CreateGuid() }; - winrt::Microsoft::Terminal::Settings::TerminalSettings settings{}; + TerminalSettings settings{}; VERIFY_IS_NOT_NULL(settings); winrt::Microsoft::Terminal::TerminalConnection::EchoConnection conn{}; VERIFY_IS_NOT_NULL(conn); diff --git a/src/cascadia/TerminalApp/CascadiaSettings.h b/src/cascadia/TerminalApp/CascadiaSettings.h index 004f3809423..08a65fba5d7 100644 --- a/src/cascadia/TerminalApp/CascadiaSettings.h +++ b/src/cascadia/TerminalApp/CascadiaSettings.h @@ -54,8 +54,8 @@ class TerminalApp::CascadiaSettings final static const CascadiaSettings& GetCurrentAppSettings(); - std::tuple BuildSettings(const winrt::TerminalApp::NewTerminalArgs& newTerminalArgs) const; - winrt::Microsoft::Terminal::Settings::TerminalSettings BuildSettings(GUID profileGuid) const; + std::tuple BuildSettings(const winrt::TerminalApp::NewTerminalArgs& newTerminalArgs) const; + winrt::TerminalApp::TerminalSettings BuildSettings(GUID profileGuid) const; GlobalAppSettings& GlobalSettings(); diff --git a/src/cascadia/TerminalApp/ColorScheme.cpp b/src/cascadia/TerminalApp/ColorScheme.cpp index 525d8ec95cd..1659013809c 100644 --- a/src/cascadia/TerminalApp/ColorScheme.cpp +++ b/src/cascadia/TerminalApp/ColorScheme.cpp @@ -2,6 +2,7 @@ // Licensed under the MIT license. #include "pch.h" +#include #include "ColorScheme.h" #include "DefaultSettings.h" #include "../../types/inc/Utils.hpp" @@ -10,8 +11,7 @@ using namespace ::Microsoft::Console; using namespace TerminalApp; -using namespace winrt::Microsoft::Terminal::Settings; -using namespace winrt::Microsoft::Terminal::TerminalControl; +using namespace winrt::TerminalApp; static constexpr std::string_view NameKey{ "name" }; static constexpr std::string_view ForegroundKey{ "foreground" }; diff --git a/src/cascadia/TerminalApp/ColorScheme.h b/src/cascadia/TerminalApp/ColorScheme.h index 92f8f4f6d70..dca0f53759a 100644 --- a/src/cascadia/TerminalApp/ColorScheme.h +++ b/src/cascadia/TerminalApp/ColorScheme.h @@ -15,8 +15,8 @@ Author(s): --*/ #pragma once -#include #include +#include "TerminalSettings.h" #include "../../inc/conattrs.hpp" // fwdecl unittest classes @@ -38,7 +38,7 @@ class TerminalApp::ColorScheme ColorScheme(std::wstring name, til::color defaultFg, til::color defaultBg, til::color cursorColor); ~ColorScheme(); - void ApplyScheme(winrt::Microsoft::Terminal::Settings::TerminalSettings terminalSettings) const; + void ApplyScheme(winrt::TerminalApp::TerminalSettings terminalSettings) const; static ColorScheme FromJson(const Json::Value& json); bool ShouldBeLayered(const Json::Value& json) const; diff --git a/src/cascadia/TerminalApp/GlobalAppSettings.h b/src/cascadia/TerminalApp/GlobalAppSettings.h index 7491b433f41..78222106716 100644 --- a/src/cascadia/TerminalApp/GlobalAppSettings.h +++ b/src/cascadia/TerminalApp/GlobalAppSettings.h @@ -46,7 +46,7 @@ class TerminalApp::GlobalAppSettings final static GlobalAppSettings FromJson(const Json::Value& json); void LayerJson(const Json::Value& json); - void ApplyToSettings(winrt::Microsoft::Terminal::Settings::TerminalSettings& settings) const noexcept; + void ApplyToSettings(winrt::TerminalApp::TerminalSettings& settings) const noexcept; std::vector GetKeybindingsWarnings() const; diff --git a/src/cascadia/TerminalApp/Pane.h b/src/cascadia/TerminalApp/Pane.h index a9c7bd9cebb..dfbcf1e7bc2 100644 --- a/src/cascadia/TerminalApp/Pane.h +++ b/src/cascadia/TerminalApp/Pane.h @@ -51,7 +51,7 @@ class Pane : public std::enable_shared_from_this void ClearActive(); void SetActive(); - void UpdateSettings(const winrt::Microsoft::Terminal::Settings::TerminalSettings& settings, + void UpdateSettings(const winrt::TerminalApp::TerminalSettings& settings, const GUID& profile); void ResizeContent(const winrt::Windows::Foundation::Size& newSize); void Relayout(); diff --git a/src/cascadia/TerminalApp/Profile.cpp b/src/cascadia/TerminalApp/Profile.cpp index 7cd80a65b11..b98efb9f691 100644 --- a/src/cascadia/TerminalApp/Profile.cpp +++ b/src/cascadia/TerminalApp/Profile.cpp @@ -12,6 +12,7 @@ #include "TerminalSettingsSerializationHelpers.h" using namespace TerminalApp; +using namespace winrt::TerminalApp; using namespace winrt::Microsoft::Terminal::Settings; using namespace winrt::Windows::UI::Xaml; using namespace ::Microsoft::Console; diff --git a/src/cascadia/TerminalApp/Profile.h b/src/cascadia/TerminalApp/Profile.h index 17edad98bb6..1e145e669c7 100644 --- a/src/cascadia/TerminalApp/Profile.h +++ b/src/cascadia/TerminalApp/Profile.h @@ -46,7 +46,7 @@ class TerminalApp::Profile final ~Profile(); - winrt::Microsoft::Terminal::Settings::TerminalSettings CreateTerminalSettings(const std::unordered_map& schemes) const; + winrt::TerminalApp::TerminalSettings CreateTerminalSettings(const std::unordered_map& schemes) const; Json::Value GenerateStub() const; static Profile FromJson(const Json::Value& json); diff --git a/src/cascadia/TerminalApp/Tab.h b/src/cascadia/TerminalApp/Tab.h index a6752fe6bbe..055d631c421 100644 --- a/src/cascadia/TerminalApp/Tab.h +++ b/src/cascadia/TerminalApp/Tab.h @@ -46,7 +46,7 @@ namespace winrt::TerminalApp::implementation void ResizePane(const winrt::TerminalApp::Direction& direction); void NavigateFocus(const winrt::TerminalApp::Direction& direction); - void UpdateSettings(const winrt::Microsoft::Terminal::Settings::TerminalSettings& settings, const GUID& profile); + void UpdateSettings(const winrt::TerminalApp::TerminalSettings& settings, const GUID& profile); winrt::hstring GetActiveTitle() const; void Shutdown(); diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index fd613d8a82e..30689891f04 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -32,7 +32,6 @@ using namespace winrt::Windows::UI::Text; using namespace winrt::Microsoft::Terminal; using namespace winrt::Microsoft::Terminal::TerminalControl; using namespace winrt::Microsoft::Terminal::TerminalConnection; -using namespace winrt::Microsoft::Terminal::Settings; using namespace ::TerminalApp; using namespace ::Microsoft::Console; @@ -626,7 +625,7 @@ namespace winrt::TerminalApp::implementation // currently displayed, it will be shown. // Arguments: // - settings: the TerminalSettings object to use to create the TerminalControl with. - void TerminalPage::_CreateNewTabFromSettings(GUID profileGuid, TerminalSettings settings) + void TerminalPage::_CreateNewTabFromSettings(GUID profileGuid, TerminalApp::TerminalSettings settings) { // Initialize the new tab @@ -727,7 +726,7 @@ namespace winrt::TerminalApp::implementation // Return value: // - the desired connection TerminalConnection::ITerminalConnection TerminalPage::_CreateConnectionFromSettings(GUID profileGuid, - winrt::Microsoft::Terminal::Settings::TerminalSettings settings) + TerminalApp::TerminalSettings settings) { const auto* const profile = _settings->FindProfile(profileGuid); @@ -1368,7 +1367,7 @@ namespace winrt::TerminalApp::implementation try { auto focusedTab = _GetStrongTabImpl(*indexOpt); - winrt::Microsoft::Terminal::Settings::TerminalSettings controlSettings; + TerminalApp::TerminalSettings controlSettings; GUID realGuid; bool profileFound = false; diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h index f78cfe86f23..021be7a3e16 100644 --- a/src/cascadia/TerminalApp/TerminalPage.h +++ b/src/cascadia/TerminalApp/TerminalPage.h @@ -118,8 +118,8 @@ namespace winrt::TerminalApp::implementation void _CreateNewTabFlyout(); void _OpenNewTabDropdown(); void _OpenNewTab(const winrt::TerminalApp::NewTerminalArgs& newTerminalArgs); - void _CreateNewTabFromSettings(GUID profileGuid, winrt::Microsoft::Terminal::Settings::TerminalSettings settings); - winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection _CreateConnectionFromSettings(GUID profileGuid, winrt::Microsoft::Terminal::Settings::TerminalSettings settings); + void _CreateNewTabFromSettings(GUID profileGuid, TerminalApp::TerminalSettings settings); + winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection _CreateConnectionFromSettings(GUID profileGuid, TerminalApp::TerminalSettings settings); void _SettingsButtonOnClick(const IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& eventArgs); void _FeedbackButtonOnClick(const IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& eventArgs); diff --git a/src/cascadia/TerminalSettings/TerminalSettings.cpp b/src/cascadia/TerminalApp/TerminalSettings.cpp similarity index 87% rename from src/cascadia/TerminalSettings/TerminalSettings.cpp rename to src/cascadia/TerminalApp/TerminalSettings.cpp index 02d8f452e8f..3313736e653 100644 --- a/src/cascadia/TerminalSettings/TerminalSettings.cpp +++ b/src/cascadia/TerminalApp/TerminalSettings.cpp @@ -6,7 +6,7 @@ #include "TerminalSettings.g.cpp" -namespace winrt::Microsoft::Terminal::Settings::implementation +namespace winrt::TerminalApp::implementation { uint32_t TerminalSettings::GetColorTableEntry(int32_t index) const noexcept { diff --git a/src/cascadia/TerminalSettings/terminalsettings.h b/src/cascadia/TerminalApp/TerminalSettings.h similarity index 84% rename from src/cascadia/TerminalSettings/terminalsettings.h rename to src/cascadia/TerminalApp/TerminalSettings.h index 1bd1aad98ae..02998373e7d 100644 --- a/src/cascadia/TerminalSettings/terminalsettings.h +++ b/src/cascadia/TerminalApp/TerminalSettings.h @@ -19,7 +19,7 @@ Author(s): #include #include -namespace winrt::Microsoft::Terminal::Settings::implementation +namespace winrt::TerminalApp::implementation { struct TerminalSettings : TerminalSettingsT { @@ -49,7 +49,7 @@ namespace winrt::Microsoft::Terminal::Settings::implementation GETSET_PROPERTY(bool, SnapOnInput, true); GETSET_PROPERTY(bool, AltGrAliasing, true); GETSET_PROPERTY(uint32_t, CursorColor, DEFAULT_CURSOR_COLOR); - GETSET_PROPERTY(CursorStyle, CursorShape, CursorStyle::Vintage); + GETSET_PROPERTY(Microsoft::Terminal::Settings::CursorStyle, CursorShape, Microsoft::Terminal::Settings::CursorStyle::Vintage); GETSET_PROPERTY(uint32_t, CursorHeight, DEFAULT_CURSOR_HEIGHT); GETSET_PROPERTY(hstring, WordDelimiters, DEFAULT_WORD_DELIMITERS); GETSET_PROPERTY(bool, CopyOnSelect, false); @@ -78,7 +78,7 @@ namespace winrt::Microsoft::Terminal::Settings::implementation BackgroundImageVerticalAlignment, winrt::Windows::UI::Xaml::VerticalAlignment::Center); - GETSET_PROPERTY(IKeyBindings, KeyBindings, nullptr); + GETSET_PROPERTY(Microsoft::Terminal::Settings::IKeyBindings, KeyBindings, nullptr); GETSET_PROPERTY(hstring, Commandline); GETSET_PROPERTY(hstring, StartingDirectory); @@ -86,9 +86,9 @@ namespace winrt::Microsoft::Terminal::Settings::implementation GETSET_PROPERTY(bool, SuppressApplicationTitle); GETSET_PROPERTY(hstring, EnvironmentVariables); - GETSET_PROPERTY(ScrollbarState, ScrollState, ScrollbarState::Visible); + GETSET_PROPERTY(Microsoft::Terminal::Settings::ScrollbarState, ScrollState, Microsoft::Terminal::Settings::ScrollbarState::Visible); - GETSET_PROPERTY(TextAntialiasingMode, AntialiasingMode, TextAntialiasingMode::Grayscale); + GETSET_PROPERTY(Microsoft::Terminal::Settings::TextAntialiasingMode, AntialiasingMode, Microsoft::Terminal::Settings::TextAntialiasingMode::Grayscale); GETSET_PROPERTY(bool, RetroTerminalEffect, false); GETSET_PROPERTY(bool, ForceFullRepaintRendering, false); @@ -102,7 +102,7 @@ namespace winrt::Microsoft::Terminal::Settings::implementation }; } -namespace winrt::Microsoft::Terminal::Settings::factory_implementation +namespace winrt::TerminalApp::factory_implementation { BASIC_FACTORY(TerminalSettings); } diff --git a/src/cascadia/TerminalSettings/TerminalSettings.idl b/src/cascadia/TerminalApp/TerminalSettings.idl similarity index 75% rename from src/cascadia/TerminalSettings/TerminalSettings.idl rename to src/cascadia/TerminalApp/TerminalSettings.idl index 15d265b1a9e..3d7d4880107 100644 --- a/src/cascadia/TerminalSettings/TerminalSettings.idl +++ b/src/cascadia/TerminalApp/TerminalSettings.idl @@ -1,10 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import "ICoreSettings.idl"; -import "IControlSettings.idl"; - -namespace Microsoft.Terminal.Settings +namespace TerminalApp { // Class Description: // TerminalSettings encapsulates all settings that control the @@ -15,8 +12,8 @@ namespace Microsoft.Terminal.Settings // The TerminalControl will pull settings it requires from this object, // and pass along the Core properties to the terminal core. [default_interface] - runtimeclass TerminalSettings : ICoreSettings, - IControlSettings + runtimeclass TerminalSettings : Microsoft.Terminal.Settings.ICoreSettings, + Microsoft.Terminal.Settings.IControlSettings { TerminalSettings(); }; diff --git a/src/cascadia/TerminalApp/lib/TerminalAppLib.vcxproj b/src/cascadia/TerminalApp/lib/TerminalAppLib.vcxproj index 0fb6b823c4c..2ceada4ea37 100644 --- a/src/cascadia/TerminalApp/lib/TerminalAppLib.vcxproj +++ b/src/cascadia/TerminalApp/lib/TerminalAppLib.vcxproj @@ -117,6 +117,9 @@ + + ../TerminalSettings.idl + ../ShortcutActionDispatch.idl @@ -186,6 +189,9 @@ + + ../TerminalSettings.idl + Create @@ -256,6 +262,7 @@ + diff --git a/src/cascadia/TerminalApp/lib/TerminalAppLib.vcxproj.filters b/src/cascadia/TerminalApp/lib/TerminalAppLib.vcxproj.filters index d716860a4af..fea379bc66c 100644 --- a/src/cascadia/TerminalApp/lib/TerminalAppLib.vcxproj.filters +++ b/src/cascadia/TerminalApp/lib/TerminalAppLib.vcxproj.filters @@ -59,7 +59,7 @@ - + settings @@ -119,7 +119,7 @@ profileGeneration - + settings @@ -139,10 +139,14 @@ tab - commandPalette + + + + settings + @@ -198,4 +202,4 @@ app - + \ No newline at end of file diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index 784275fa324..62bc7a948e2 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -56,11 +56,6 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation return initialized; } - TermControl::TermControl() : - TermControl(Settings::TerminalSettings{}, TerminalConnection::ITerminalConnection{ nullptr }) - { - } - TermControl::TermControl(Settings::IControlSettings settings, TerminalConnection::ITerminalConnection connection) : _connection{ connection }, _initializedTerminal{ false }, diff --git a/src/cascadia/TerminalControl/TermControl.h b/src/cascadia/TerminalControl/TermControl.h index 783ca85d967..4499c589efc 100644 --- a/src/cascadia/TerminalControl/TermControl.h +++ b/src/cascadia/TerminalControl/TermControl.h @@ -56,7 +56,6 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation struct TermControl : TermControlT { - TermControl(); TermControl(Settings::IControlSettings settings, TerminalConnection::ITerminalConnection connection); winrt::fire_and_forget UpdateSettings(Settings::IControlSettings newSettings); diff --git a/src/cascadia/TerminalControl/TermControl.idl b/src/cascadia/TerminalControl/TermControl.idl index d5454e50578..d9a2ac5cdff 100644 --- a/src/cascadia/TerminalControl/TermControl.idl +++ b/src/cascadia/TerminalControl/TermControl.idl @@ -32,7 +32,6 @@ namespace Microsoft.Terminal.TerminalControl [default_interface] runtimeclass TermControl : Windows.UI.Xaml.Controls.UserControl, IDirectKeyListener, IMouseWheelListener { - TermControl(); TermControl(Microsoft.Terminal.Settings.IControlSettings settings, Microsoft.Terminal.TerminalConnection.ITerminalConnection connection); static Windows.Foundation.Size GetProposedDimensions(Microsoft.Terminal.Settings.IControlSettings settings, UInt32 dpi); diff --git a/src/cascadia/TerminalSettings/TerminalSettings.vcxproj b/src/cascadia/TerminalSettings/TerminalSettings.vcxproj index 982de90ec25..eef3fe672f4 100644 --- a/src/cascadia/TerminalSettings/TerminalSettings.vcxproj +++ b/src/cascadia/TerminalSettings/TerminalSettings.vcxproj @@ -17,18 +17,13 @@ --> true - - KeyChord.idl - - TerminalSettings.idl - @@ -37,13 +32,9 @@ KeyChord.idl - - TerminalSettings.idl - - @@ -53,6 +44,5 @@ - - + \ No newline at end of file From d29be591a8ffd74777b3d3d0e417434981ceee58 Mon Sep 17 00:00:00 2001 From: "Dustin L. Howett" Date: Mon, 3 Aug 2020 18:43:17 -0700 Subject: [PATCH 021/266] Fix VT mouse capture issues in Terminal and conhost (#7166) This pull request fixes capture and event generation in VT mouse mode for both conhost and terminal. Fixes #6401. [1/3] Terminal: clamp mouse events to the viewport, don't throw them away gnome-terminal (at least) sends mouse events whose x/y are at the extreme ends of the buffer when a drag starts inside the terminal and then exits it. We would previously discard any mouse events that exited the borders of the viewport. Now we will keep emitting events where X/Y=0/w/h. [2/3] conhost: clamp VT mouse to viewport, capture pointer This is the same as (1), but for conhost. conhost wasn't already capturing the pointer when VT mouse mode was in use. By capturing, we ensure that events that happen outside the screen still result in events sent to an application (like a release after a drag) [3/3] wpf: capture the pointer when VT mouse is enabled This is the same as (2), but for the WPF control. Clamping is handled in TerminalCore in (1), so we didn't need to do it in WPF. --- .../PublicTerminalCore/HwndTerminal.cpp | 27 ++++++++++++++++-- src/cascadia/TerminalCore/Terminal.cpp | 16 +++++------ src/interactivity/win32/windowio.cpp | 28 ++++++++++++++++++- 3 files changed, 60 insertions(+), 11 deletions(-) diff --git a/src/cascadia/PublicTerminalCore/HwndTerminal.cpp b/src/cascadia/PublicTerminalCore/HwndTerminal.cpp index 27775bb314d..3c3e1600192 100644 --- a/src/cascadia/PublicTerminalCore/HwndTerminal.cpp +++ b/src/cascadia/PublicTerminalCore/HwndTerminal.cpp @@ -55,10 +55,29 @@ try if (terminal) { - if (_IsMouseMessage(uMsg) && terminal->_CanSendVTMouseInput()) + if (_IsMouseMessage(uMsg)) { - if (terminal->_SendMouseEvent(uMsg, wParam, lParam)) + if (terminal->_CanSendVTMouseInput() && terminal->_SendMouseEvent(uMsg, wParam, lParam)) { + // GH#6401: Capturing the mouse ensures that we get drag/release events + // even if the user moves outside the window. + // _SendMouseEvent returns false if the terminal's not in VT mode, so we'll + // fall through to release the capture. + switch (uMsg) + { + case WM_LBUTTONDOWN: + case WM_MBUTTONDOWN: + case WM_RBUTTONDOWN: + SetCapture(hwnd); + break; + case WM_LBUTTONUP: + case WM_MBUTTONUP: + case WM_RBUTTONUP: + ReleaseCapture(); + break; + } + + // Suppress all mouse events that made it into the terminal. return 0; } } @@ -76,6 +95,10 @@ try return 0; case WM_LBUTTONUP: terminal->_singleClickTouchdownPos = std::nullopt; + [[fallthrough]]; + case WM_MBUTTONUP: + case WM_RBUTTONUP: + ReleaseCapture(); break; case WM_MOUSEMOVE: if (WI_IsFlagSet(wParam, MK_LBUTTON)) diff --git a/src/cascadia/TerminalCore/Terminal.cpp b/src/cascadia/TerminalCore/Terminal.cpp index e7719507099..b71471fc7ef 100644 --- a/src/cascadia/TerminalCore/Terminal.cpp +++ b/src/cascadia/TerminalCore/Terminal.cpp @@ -486,14 +486,14 @@ bool Terminal::SendKeyEvent(const WORD vkey, // - false if we did not translate the key, and it should be processed into a character. bool Terminal::SendMouseEvent(const COORD viewportPos, const unsigned int uiButton, const ControlKeyStates states, const short wheelDelta) { - // viewportPos must be within the dimensions of the viewport - const auto viewportDimensions = _mutableViewport.Dimensions(); - if (viewportPos.X < 0 || viewportPos.X >= viewportDimensions.X || viewportPos.Y < 0 || viewportPos.Y >= viewportDimensions.Y) - { - return false; - } - - return _terminalInput->HandleMouse(viewportPos, uiButton, GET_KEYSTATE_WPARAM(states.Value()), wheelDelta); + // GH#6401: VT applications should be able to receive mouse events from outside the + // terminal buffer. This is likely to happen when the user drags the cursor offscreen. + // We shouldn't throw away perfectly good events when they're offscreen, so we just + // clamp them to be within the range [(0, 0), (W, H)]. +#pragma warning(suppress : 26496) // analysis can't tell we're assigning through a reference below + auto clampedPos{ viewportPos }; + _mutableViewport.ToOrigin().Clamp(clampedPos); + return _terminalInput->HandleMouse(clampedPos, uiButton, GET_KEYSTATE_WPARAM(states.Value()), wheelDelta); } // Method Description: diff --git a/src/interactivity/win32/windowio.cpp b/src/interactivity/win32/windowio.cpp index 023b14a8598..2b65f515047 100644 --- a/src/interactivity/win32/windowio.cpp +++ b/src/interactivity/win32/windowio.cpp @@ -123,7 +123,14 @@ bool HandleTerminalMouseEvent(const COORD cMousePosition, // Virtual terminal input mode if (IsInVirtualTerminalInputMode()) { - fWasHandled = gci.GetActiveInputBuffer()->GetTerminalInput().HandleMouse(cMousePosition, uiButton, sModifierKeystate, sWheelDelta); + // GH#6401: VT applications should be able to receive mouse events from outside the + // terminal buffer. This is likely to happen when the user drags the cursor offscreen. + // We shouldn't throw away perfectly good events when they're offscreen, so we just + // clamp them to be within the range [(0, 0), (W, H)]. + auto clampedPosition{ cMousePosition }; + const auto clampViewport{ gci.GetActiveOutputBuffer().GetViewport().ToOrigin() }; + clampViewport.Clamp(clampedPosition); + fWasHandled = gci.GetActiveInputBuffer()->GetTerminalInput().HandleMouse(clampedPosition, uiButton, sModifierKeystate, sWheelDelta); } return fWasHandled; @@ -635,6 +642,25 @@ BOOL HandleMouseEvent(const SCREEN_INFORMATION& ScreenInfo, if (HandleTerminalMouseEvent(MousePosition, Message, GET_KEYSTATE_WPARAM(wParam), sDelta)) { + // GH#6401: Capturing the mouse ensures that we get drag/release events + // even if the user moves outside the window. + // HandleTerminalMouseEvent returns false if the terminal's not in VT mode, + // so capturing/releasing here should not impact other console mouse event + // consumers. + switch (Message) + { + case WM_LBUTTONDOWN: + case WM_MBUTTONDOWN: + case WM_RBUTTONDOWN: + SetCapture(ServiceLocator::LocateConsoleWindow()->GetWindowHandle()); + break; + case WM_LBUTTONUP: + case WM_MBUTTONUP: + case WM_RBUTTONUP: + ReleaseCapture(); + break; + } + return FALSE; } } From cd7235661edb65e4327e7683df1b31fa967eb9d1 Mon Sep 17 00:00:00 2001 From: "Dustin L. Howett" Date: Tue, 4 Aug 2020 10:38:34 -0700 Subject: [PATCH 022/266] wpf: fixup mouse wheel events from screen coords (#7168) I found this while crawling through conhost's WindowIo. Mouse wheel events come in in screen coordinates, unlike literally every other mouse event. The WPF control was doing it wrong. --- src/cascadia/PublicTerminalCore/HwndTerminal.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/cascadia/PublicTerminalCore/HwndTerminal.cpp b/src/cascadia/PublicTerminalCore/HwndTerminal.cpp index 3c3e1600192..bb7112efb1b 100644 --- a/src/cascadia/PublicTerminalCore/HwndTerminal.cpp +++ b/src/cascadia/PublicTerminalCore/HwndTerminal.cpp @@ -21,7 +21,7 @@ static constexpr bool _IsMouseMessage(UINT uMsg) return uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONUP || uMsg == WM_LBUTTONDBLCLK || uMsg == WM_MBUTTONDOWN || uMsg == WM_MBUTTONUP || uMsg == WM_MBUTTONDBLCLK || uMsg == WM_RBUTTONDOWN || uMsg == WM_RBUTTONUP || uMsg == WM_RBUTTONDBLCLK || - uMsg == WM_MOUSEMOVE || uMsg == WM_MOUSEWHEEL; + uMsg == WM_MOUSEMOVE || uMsg == WM_MOUSEWHEEL || uMsg == WM_MOUSEHWHEEL; } // Helper static function to ensure that all ambiguous-width glyphs are reported as narrow. @@ -628,16 +628,21 @@ bool HwndTerminal::_CanSendVTMouseInput() const noexcept bool HwndTerminal::_SendMouseEvent(UINT uMsg, WPARAM wParam, LPARAM lParam) noexcept try { - const til::point cursorPosition{ + til::point cursorPosition{ GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), }; const til::size fontSize{ this->_actualFont.GetSize() }; short wheelDelta{ 0 }; - if (uMsg == WM_MOUSEWHEEL) + if (uMsg == WM_MOUSEWHEEL || uMsg == WM_MOUSEHWHEEL) { wheelDelta = HIWORD(wParam); + + // If it's a *WHEEL event, it's in screen coordinates, not window (?!) + POINT coordsToTransform = cursorPosition; + ScreenToClient(_hwnd.get(), &coordsToTransform); + cursorPosition = coordsToTransform; } return _terminal->SendMouseEvent(cursorPosition / fontSize, uMsg, getControlKeyState(), wheelDelta); From b617c434a171f0349395038a532d1f6630fb441d Mon Sep 17 00:00:00 2001 From: Leonard Hecker Date: Thu, 6 Aug 2020 03:03:58 +0200 Subject: [PATCH 023/266] Fix #7064: Ignore key events without scan code (#7145) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Up until #4999 we deferred all key events to the character event handler for which `ToUnicodeEx` returned a valid character and alternatively those who aren't a special key combination as listed in `TerminalInput`'s implementation. Since #4999 we started acknowledging/handling all key events no matter whether they're actually a known key combination. Given non-ASCII inputs the Win32 `SendInput()` method generates certain sequences that aren't recognizable combinations though and if they're handled by the key event handler no follow up character event is sent containing the unicode character. This PR adds another condition and defers all key events without scan code (i.e. those not representable by the current keyboard layout) to the character event handler. I'm absolutely not certain that this PR doesn't have a negative effect on other kinds of inputs. Is it common for key events to not contain a scan code? I personally haven't seen it happen before AutoHotKey/SendInput. Before this PR is merged it'd be nice to have a good testing plan in place in order to ensure nothing breaks. ## Validation Steps Performed Remapped `AltGr+8` to `»` using AutoHotKey using `<^>!8::SendInput {Raw}»`. Ensured `»` is printed if `AltGr+8` is pressed. Closes #7064 Closes #7120 --- src/cascadia/TerminalCore/Terminal.cpp | 13 +++++++++++++ src/cascadia/UnitTests_TerminalCore/InputTest.cpp | 11 +++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/cascadia/TerminalCore/Terminal.cpp b/src/cascadia/TerminalCore/Terminal.cpp index b71471fc7ef..7f106ba1f90 100644 --- a/src/cascadia/TerminalCore/Terminal.cpp +++ b/src/cascadia/TerminalCore/Terminal.cpp @@ -430,6 +430,19 @@ bool Terminal::SendKeyEvent(const WORD vkey, _StoreKeyEvent(vkey, scanCode); + // As a Terminal we're mostly interested in getting key events from physical hardware (mouse & keyboard). + // We're thus ignoring events whose values are outside the valid range and unlikely to be generated by the current keyboard. + // It's very likely that a proper followup character event will be sent to us. + // This prominently happens using AutoHotKey's keyboard remapping feature, + // which sends input events whose vkey is 0xff and scanCode is 0. + // We need to check for this early, as _CharacterFromKeyEvent() always returns 0 for such invalid values, + // making us believe that this is an actual non-character input, while it usually isn't. + // GH#7064 + if (vkey == 0 || vkey >= 0xff || scanCode == 0) + { + return false; + } + const auto isAltOnlyPressed = states.IsAltPressed() && !states.IsCtrlPressed(); const auto isSuppressedAltGrAlias = !_altGrAliasing && states.IsAltPressed() && states.IsCtrlPressed(); diff --git a/src/cascadia/UnitTests_TerminalCore/InputTest.cpp b/src/cascadia/UnitTests_TerminalCore/InputTest.cpp index 037c81db45b..9745b0e6b2d 100644 --- a/src/cascadia/UnitTests_TerminalCore/InputTest.cpp +++ b/src/cascadia/UnitTests_TerminalCore/InputTest.cpp @@ -30,6 +30,7 @@ namespace TerminalCoreUnitTests TEST_METHOD(AltShiftKey); TEST_METHOD(AltSpace); + TEST_METHOD(InvalidKeyEvent); void _VerifyExpectedInput(std::wstring& actualInput) { @@ -65,4 +66,14 @@ namespace TerminalCoreUnitTests VERIFY_IS_FALSE(term.SendKeyEvent(L' ', 0, ControlKeyStates::LeftAltPressed, false)); VERIFY_IS_FALSE(term.SendCharEvent(L' ', 0, ControlKeyStates::LeftAltPressed)); } + + void InputTest::InvalidKeyEvent() + { + // Certain applications like AutoHotKey and its keyboard remapping feature, + // send us key events using SendInput() whose values are outside of the valid range. + // We don't want to handle those events as we're probably going to get a proper followup character event. + VERIFY_IS_FALSE(term.SendKeyEvent(0, 123, {}, true)); + VERIFY_IS_FALSE(term.SendKeyEvent(255, 123, {}, true)); + VERIFY_IS_FALSE(term.SendKeyEvent(123, 0, {}, true)); + } } From f215b56ca3344cfd5fdec72d8c73a664c31ece46 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Thu, 6 Aug 2020 16:23:54 -0500 Subject: [PATCH 024/266] Add a "shell vs terminal" section to Niksa.md (#7202) I've typed this up way too many times now. I'm sticking this comment in Niksa.md, and if it's ever an insufficient explanation of the differences, we can elaborate. --- doc/Niksa.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/doc/Niksa.md b/doc/Niksa.md index 4ad72148cf6..e543191a6c7 100644 --- a/doc/Niksa.md +++ b/doc/Niksa.md @@ -9,6 +9,8 @@ This document serves as a storage point for those posts. - [Output Processing between "Far East" and "Western"](#fesb) - [Why do we not backport things?](#backport) - [Why can't we have mixed elevated and non-elevated tabs in the Terminal?](#elevation) +- [What's the difference between a shell and a terminal?](#shell-vs-terminal) + ## Why do we avoid changing CMD.exe? `setlocal` doesn't behave the same way as an environment variable. It's a thing that would have to be put in at the top of the batch script that is `somefile.cmd` as one of its first commands to adjust the way that one specific batch file is processed by the `cmd.exe` engine. That's probably not suitable for your needs, but that's the way we have to go. @@ -179,3 +181,20 @@ Other platforms have accepted that risk in preference for user convenience. They Original Source: https://github.com/microsoft/terminal/issues/632#issuecomment-519375707 +## What's the difference between a shell and a terminal? + +_guest speaker @zadjii-msft_ + +I think there might be a bit of a misunderstanding here - there are two different kinds of applications we're talking about here: +* shell applications, like `cmd.exe`, `powershell`, `zsh`, etc. These are text-only applications that emit streams of characters. They don't care at all about how they're eventually rendered to the user. These are also sometimes referred to as "commandline client" applications. +* terminal applications, like the Windows Terminal, gnome-terminal, xterm, iterm2, hyper. These are graphical applications that can be used to render the output of commandline clients. + +On Windows, if you just run `cmd.exe` directly, the OS will create an instance of `conhost.exe` as the _terminal_ for `cmd.exe`. The same thing happens for `powershell.exe`, the system will creates a new conhost window for any client that's not already connected to a terminal of some sort. This has lead to an enormous amount of confusion for people thinking that a conhost window is actually a "`cmd` window". `cmd` can't have a window, it's just a commandline application. Its window is always some other terminal. + +Any terminal can run any commandline client application. So you can use the Windows Terminal to run whatever shell you want. I use mine for both `cmd` and `powershell`, and also WSL: + +![image](https://user-images.githubusercontent.com/18356694/89556758-79d27e80-d7d7-11ea-84e2-10710e09ef4a.png) + +It's not the Terminal's responsibility to remember the commands executed by a commandline client. That's the responsibility of the _shell_. How would the terminal remember commands executed by something like `emacs` or `vim`? Those are both applications where the user is typing input and hitting enter, like they would at a cmd prompt, but without something that resembles a command history. + +Original Source: https://github.com/microsoft/terminal/issues/6500#issuecomment-670035468 From 0a30b856a98cc6383fb125f21c8ac6b137fbd4ee Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Thu, 6 Aug 2020 16:47:50 -0500 Subject: [PATCH 025/266] Add `closeOtherTabs`, `closeTabsAfter` actions (#7176) ## Summary of the Pull Request Adds support for two actions, `closeOtherTabs` and `closeTabsAfter`. Both these actions accept an `index` parameter. * `closeOtherTabs`: Close tabs other than `index` * `closeTabsAfter`: Close tabs after `index` (This is also "Close tabs to the right") ## References * This PR is being made to unblock @RahulRavishankar in #1912 ## PR Checklist * [x] I work here * [ ] Tests added/passed * [x] Requires documentation to be updated * [ ] We should file an issue for "add an `index` param to `closeTab`" to add similar support to the close tab action * [ ] We should file an issue for "make the `index` param to `closeOtherTabs`, `closeTabsAfter` optional" to make them both work on the _active_ tab when there's no `index` provided ## Validation Steps Performed * _Verified that_ closing all tabs when I have the `index`'th tab selected _works as expected_ * _Verified that_ closing all tabs when I have a tab other than the `index`'th tab selected _works as expected_ * _Verified that_ closing tabs to the right when I have the `index`'th tab selected _works as expected_ * _Verified that_ closing tabs to the right when I have a tab other than the `index`'th tab selected _works as expected_ - This one has one caveat: for whatever reason, if you run this action when the tab that's currently focused is _before_ the `index` param, then the tabs will expand to fill the entire width of the tab row, until you mouse over them. Probably has something to do with tabs not resizing down until there's a mouse exit event. --- doc/cascadia/profiles.schema.json | 38 ++++++++++++ src/cascadia/TerminalApp/ActionAndArgs.cpp | 10 ++++ src/cascadia/TerminalApp/ActionArgs.cpp | 17 ++++++ src/cascadia/TerminalApp/ActionArgs.h | 58 +++++++++++++++++++ src/cascadia/TerminalApp/ActionArgs.idl | 10 ++++ .../TerminalApp/AppActionHandlers.cpp | 45 ++++++++++++++ .../Resources/en-US/Resources.resw | 12 +++- .../TerminalApp/ShortcutActionDispatch.cpp | 11 ++++ .../TerminalApp/ShortcutActionDispatch.h | 2 + .../TerminalApp/ShortcutActionDispatch.idl | 6 +- src/cascadia/TerminalApp/TerminalPage.cpp | 2 + src/cascadia/TerminalApp/TerminalPage.h | 2 + 12 files changed, 210 insertions(+), 3 deletions(-) diff --git a/doc/cascadia/profiles.schema.json b/doc/cascadia/profiles.schema.json index 0ca40b685bd..a4dbd3d806d 100644 --- a/doc/cascadia/profiles.schema.json +++ b/doc/cascadia/profiles.schema.json @@ -64,6 +64,8 @@ "renameTab", "commandPalette", "wt", + "closeOtherTabs", + "closeTabsAfter", "unbound" ], "type": "string" @@ -298,6 +300,40 @@ ], "required": [ "commandline" ] }, + "CloseOtherTabsAction": { + "description": "Arguments for a closeOtherTabs action", + "allOf": [ + { "$ref": "#/definitions/ShortcutAction" }, + { + "properties": { + "action": { "type": "string", "pattern": "closeOtherTabs" }, + "index": { + "type": "integer", + "default": "", + "description": "close the tabs following the tab at this index" + } + } + } + ], + "required": [ "index" ] + }, + "CloseTabsAfterAction": { + "description": "Arguments for a closeTabsAfter action", + "allOf": [ + { "$ref": "#/definitions/ShortcutAction" }, + { + "properties": { + "action": { "type": "string", "pattern": "closeTabsAfter" }, + "index": { + "type": "integer", + "default": "", + "description": "close the tabs other than the one at this index" + } + } + } + ], + "required": [ "index" ] + }, "Keybinding": { "additionalProperties": false, "properties": { @@ -315,6 +351,8 @@ { "$ref": "#/definitions/OpenSettingsAction" }, { "$ref": "#/definitions/SetTabColorAction" }, { "$ref": "#/definitions/WtAction" }, + { "$ref": "#/definitions/CloseOtherTabsAction" }, + { "$ref": "#/definitions/CloseTabsAfterAction" }, { "type": "null" } ] }, diff --git a/src/cascadia/TerminalApp/ActionAndArgs.cpp b/src/cascadia/TerminalApp/ActionAndArgs.cpp index f28bfcca8a6..2f8966810fe 100644 --- a/src/cascadia/TerminalApp/ActionAndArgs.cpp +++ b/src/cascadia/TerminalApp/ActionAndArgs.cpp @@ -40,6 +40,8 @@ static constexpr std::string_view OpenTabColorPickerKey{ "openTabColorPicker" }; static constexpr std::string_view RenameTabKey{ "renameTab" }; static constexpr std::string_view ExecuteCommandlineKey{ "wt" }; static constexpr std::string_view ToggleCommandPaletteKey{ "commandPalette" }; +static constexpr std::string_view CloseOtherTabsKey{ "closeOtherTabs" }; +static constexpr std::string_view CloseTabsAfterKey{ "closeTabsAfter" }; static constexpr std::string_view ActionKey{ "action" }; @@ -92,6 +94,8 @@ namespace winrt::TerminalApp::implementation { RenameTabKey, ShortcutAction::RenameTab }, { ExecuteCommandlineKey, ShortcutAction::ExecuteCommandline }, { ToggleCommandPaletteKey, ShortcutAction::ToggleCommandPalette }, + { CloseOtherTabsKey, ShortcutAction::CloseOtherTabs }, + { CloseTabsAfterKey, ShortcutAction::CloseTabsAfter }, }; using ParseResult = std::tuple>; @@ -125,6 +129,10 @@ namespace winrt::TerminalApp::implementation { ShortcutAction::ExecuteCommandline, winrt::TerminalApp::implementation::ExecuteCommandlineArgs::FromJson }, + { ShortcutAction::CloseOtherTabs, winrt::TerminalApp::implementation::CloseOtherTabsArgs::FromJson }, + + { ShortcutAction::CloseTabsAfter, winrt::TerminalApp::implementation::CloseTabsAfterArgs::FromJson }, + { ShortcutAction::Invalid, nullptr }, }; @@ -274,6 +282,8 @@ namespace winrt::TerminalApp::implementation { ShortcutAction::RenameTab, RS_(L"ResetTabNameCommandKey") }, { ShortcutAction::ExecuteCommandline, RS_(L"ExecuteCommandlineCommandKey") }, { ShortcutAction::ToggleCommandPalette, RS_(L"ToggleCommandPaletteCommandKey") }, + { ShortcutAction::CloseOtherTabs, L"" }, // Intentionally omitted, must be generated by GenerateName + { ShortcutAction::CloseTabsAfter, L"" }, // Intentionally omitted, must be generated by GenerateName }; }(); diff --git a/src/cascadia/TerminalApp/ActionArgs.cpp b/src/cascadia/TerminalApp/ActionArgs.cpp index a5a83203afa..27425c58fc7 100644 --- a/src/cascadia/TerminalApp/ActionArgs.cpp +++ b/src/cascadia/TerminalApp/ActionArgs.cpp @@ -272,4 +272,21 @@ namespace winrt::TerminalApp::implementation return L""; } + winrt::hstring CloseOtherTabsArgs::GenerateName() const + { + // "Close tabs other than index {0}" + return winrt::hstring{ + fmt::format(std::wstring_view(RS_(L"CloseOtherTabsCommandKey")), + _Index) + }; + } + + winrt::hstring CloseTabsAfterArgs::GenerateName() const + { + // "Close tabs after index {0}" + return winrt::hstring{ + fmt::format(std::wstring_view(RS_(L"CloseTabsAfterCommandKey")), + _Index) + }; + } } diff --git a/src/cascadia/TerminalApp/ActionArgs.h b/src/cascadia/TerminalApp/ActionArgs.h index 091774230d1..941b4716a8f 100644 --- a/src/cascadia/TerminalApp/ActionArgs.h +++ b/src/cascadia/TerminalApp/ActionArgs.h @@ -18,6 +18,8 @@ #include "SetTabColorArgs.g.h" #include "RenameTabArgs.g.h" #include "ExecuteCommandlineArgs.g.h" +#include "CloseOtherTabsArgs.g.h" +#include "CloseTabsAfterArgs.g.h" #include "../../cascadia/inc/cppwinrt_utils.h" #include "Utils.h" @@ -421,6 +423,62 @@ namespace winrt::TerminalApp::implementation } }; + struct CloseOtherTabsArgs : public CloseOtherTabsArgsT + { + CloseOtherTabsArgs() = default; + GETSET_PROPERTY(uint32_t, Index, 0); + + static constexpr std::string_view IndexKey{ "index" }; + + public: + hstring GenerateName() const; + + bool Equals(const IActionArgs& other) + { + auto otherAsUs = other.try_as(); + if (otherAsUs) + { + return otherAsUs->_Index == _Index; + } + return false; + }; + static FromJsonResult FromJson(const Json::Value& json) + { + // LOAD BEARING: Not using make_self here _will_ break you in the future! + auto args = winrt::make_self(); + JsonUtils::GetValueForKey(json, IndexKey, args->_Index); + return { *args, {} }; + } + }; + + struct CloseTabsAfterArgs : public CloseTabsAfterArgsT + { + CloseTabsAfterArgs() = default; + GETSET_PROPERTY(uint32_t, Index, 0); + + static constexpr std::string_view IndexKey{ "index" }; + + public: + hstring GenerateName() const; + + bool Equals(const IActionArgs& other) + { + auto otherAsUs = other.try_as(); + if (otherAsUs) + { + return otherAsUs->_Index == _Index; + } + return false; + }; + static FromJsonResult FromJson(const Json::Value& json) + { + // LOAD BEARING: Not using make_self here _will_ break you in the future! + auto args = winrt::make_self(); + JsonUtils::GetValueForKey(json, IndexKey, args->_Index); + return { *args, {} }; + } + }; + } namespace winrt::TerminalApp::factory_implementation diff --git a/src/cascadia/TerminalApp/ActionArgs.idl b/src/cascadia/TerminalApp/ActionArgs.idl index 84e5588bf2d..bfeee27d3f6 100644 --- a/src/cascadia/TerminalApp/ActionArgs.idl +++ b/src/cascadia/TerminalApp/ActionArgs.idl @@ -120,4 +120,14 @@ namespace TerminalApp { String Commandline; }; + + [default_interface] runtimeclass CloseOtherTabsArgs : IActionArgs + { + UInt32 Index { get; }; + }; + + [default_interface] runtimeclass CloseTabsAfterArgs : IActionArgs + { + UInt32 Index { get; }; + }; } diff --git a/src/cascadia/TerminalApp/AppActionHandlers.cpp b/src/cascadia/TerminalApp/AppActionHandlers.cpp index 63a2743d80b..afb72b94506 100644 --- a/src/cascadia/TerminalApp/AppActionHandlers.cpp +++ b/src/cascadia/TerminalApp/AppActionHandlers.cpp @@ -351,4 +351,49 @@ namespace winrt::TerminalApp::implementation } } } + + void TerminalPage::_HandleCloseOtherTabs(const IInspectable& /*sender*/, + const TerminalApp::ActionEventArgs& actionArgs) + { + if (const auto& realArgs = actionArgs.ActionArgs().try_as()) + { + uint32_t index = realArgs.Index(); + + // Remove tabs after the current one + while (_tabs.Size() > index + 1) + { + _RemoveTabViewItemByIndex(_tabs.Size() - 1); + } + + // Remove all of them leading up to the selected tab + while (_tabs.Size() > 1) + { + _RemoveTabViewItemByIndex(0); + } + + actionArgs.Handled(true); + } + } + void TerminalPage::_HandleCloseTabsAfter(const IInspectable& /*sender*/, + const TerminalApp::ActionEventArgs& actionArgs) + { + if (const auto& realArgs = actionArgs.ActionArgs().try_as()) + { + uint32_t index = realArgs.Index(); + + // Remove tabs after the current one + while (_tabs.Size() > index + 1) + { + _RemoveTabViewItemByIndex(_tabs.Size() - 1); + } + + // TODO:GH#7182 For whatever reason, if you run this action + // when the tab that's currently focused is _before_ the `index` + // param, then the tabs will expand to fill the entire width of the + // tab row, until you mouse over them. Probably has something to do + // with tabs not resizing down until there's a mouse exit event. + + actionArgs.Handled(true); + } + } } diff --git a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw index 6ca22a39ff0..d1cb5606c07 100644 --- a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw +++ b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw @@ -538,14 +538,22 @@ Rename tab to "{0}" - {0} will be replaced with user-defined string + {0} will be replaced with a user-defined string Reset tab title Run commandline "{0}" in this window - {0} will be replaced with user-defined commandline + {0} will be replaced with a user-defined commandline + + + Close tabs other than index {0} + {0} will be replaced with a number + + + Close tabs after index {0} + {0} will be replaced with a number Crimson diff --git a/src/cascadia/TerminalApp/ShortcutActionDispatch.cpp b/src/cascadia/TerminalApp/ShortcutActionDispatch.cpp index 571b4589516..1ea1bb7fae2 100644 --- a/src/cascadia/TerminalApp/ShortcutActionDispatch.cpp +++ b/src/cascadia/TerminalApp/ShortcutActionDispatch.cpp @@ -197,6 +197,17 @@ namespace winrt::TerminalApp::implementation case ShortcutAction::ExecuteCommandline: { _ExecuteCommandlineHandlers(*this, *eventArgs); + break; + } + case ShortcutAction::CloseOtherTabs: + { + _CloseOtherTabsHandlers(*this, *eventArgs); + break; + } + case ShortcutAction::CloseTabsAfter: + { + _CloseTabsAfterHandlers(*this, *eventArgs); + break; } default: return false; diff --git a/src/cascadia/TerminalApp/ShortcutActionDispatch.h b/src/cascadia/TerminalApp/ShortcutActionDispatch.h index 9c1dff1575c..7ed978d9b80 100644 --- a/src/cascadia/TerminalApp/ShortcutActionDispatch.h +++ b/src/cascadia/TerminalApp/ShortcutActionDispatch.h @@ -55,6 +55,8 @@ namespace winrt::TerminalApp::implementation TYPED_EVENT(OpenTabColorPicker, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs); TYPED_EVENT(RenameTab, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs); TYPED_EVENT(ExecuteCommandline, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs); + TYPED_EVENT(CloseOtherTabs, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs); + TYPED_EVENT(CloseTabsAfter, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs); // clang-format on private: diff --git a/src/cascadia/TerminalApp/ShortcutActionDispatch.idl b/src/cascadia/TerminalApp/ShortcutActionDispatch.idl index 8306c04fc46..026fa4aa2ba 100644 --- a/src/cascadia/TerminalApp/ShortcutActionDispatch.idl +++ b/src/cascadia/TerminalApp/ShortcutActionDispatch.idl @@ -40,7 +40,9 @@ namespace TerminalApp OpenTabColorPicker, RenameTab, ExecuteCommandline, - ToggleCommandPalette + ToggleCommandPalette, + CloseOtherTabs, + CloseTabsAfter }; [default_interface] runtimeclass ActionAndArgs { @@ -86,5 +88,7 @@ namespace TerminalApp event Windows.Foundation.TypedEventHandler OpenTabColorPicker; event Windows.Foundation.TypedEventHandler RenameTab; event Windows.Foundation.TypedEventHandler ExecuteCommandline; + event Windows.Foundation.TypedEventHandler CloseOtherTabs; + event Windows.Foundation.TypedEventHandler CloseTabsAfter; } } diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index 30689891f04..201eeda0854 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -893,6 +893,8 @@ namespace winrt::TerminalApp::implementation _actionDispatch->OpenTabColorPicker({ this, &TerminalPage::_HandleOpenTabColorPicker }); _actionDispatch->RenameTab({ this, &TerminalPage::_HandleRenameTab }); _actionDispatch->ExecuteCommandline({ this, &TerminalPage::_HandleExecuteCommandline }); + _actionDispatch->CloseOtherTabs({ this, &TerminalPage::_HandleCloseOtherTabs }); + _actionDispatch->CloseTabsAfter({ this, &TerminalPage::_HandleCloseTabsAfter }); } // Method Description: diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h index 021be7a3e16..174ee77d597 100644 --- a/src/cascadia/TerminalApp/TerminalPage.h +++ b/src/cascadia/TerminalApp/TerminalPage.h @@ -224,6 +224,8 @@ namespace winrt::TerminalApp::implementation void _HandleRenameTab(const IInspectable& sender, const TerminalApp::ActionEventArgs& args); void _HandleExecuteCommandline(const IInspectable& sender, const TerminalApp::ActionEventArgs& args); void _HandleToggleCommandPalette(const IInspectable& sender, const TerminalApp::ActionEventArgs& args); + void _HandleCloseOtherTabs(const IInspectable& sender, const TerminalApp::ActionEventArgs& args); + void _HandleCloseTabsAfter(const IInspectable& sender, const TerminalApp::ActionEventArgs& args); // Make sure to hook new actions up in _RegisterActionCallbacks! #pragma endregion From 858905f4925f045fc33b47654b14bf22f6448715 Mon Sep 17 00:00:00 2001 From: "Dustin L. Howett" Date: Thu, 6 Aug 2020 16:55:07 -0700 Subject: [PATCH 026/266] Disable MinimalCoreWin when OpenConsoleUniversalApp is false (#7203) This fixes the build the rest of the way in VS 16.7. Something about the way we were using the Store/Container flags caused some of our projects to end up linking kernel32.lib only (MinimalCoreWin==KernelOnly). The best way to solve it once and for all is to make sure MinimalCoreWin is always set. References 313568d0e5c. --- src/cppwinrt.build.pre.props | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/cppwinrt.build.pre.props b/src/cppwinrt.build.pre.props index cd89880fdd6..c7ac9550f61 100644 --- a/src/cppwinrt.build.pre.props +++ b/src/cppwinrt.build.pre.props @@ -22,12 +22,20 @@ at the winmd we build to generate type info. In general, cppwinrt projects all want this. --> - + true true true Windows Store + + + false + - diff --git a/src/cascadia/LocalTests_TerminalApp/TestHostApp/TestHostApp.vcxproj b/src/cascadia/LocalTests_TerminalApp/TestHostApp/TestHostApp.vcxproj index c1745442044..f035d8a74d1 100644 --- a/src/cascadia/LocalTests_TerminalApp/TestHostApp/TestHostApp.vcxproj +++ b/src/cascadia/LocalTests_TerminalApp/TestHostApp/TestHostApp.vcxproj @@ -45,11 +45,11 @@ "taef.png" is actually in the package. taef.png will get copied to the OutputPath when taef is run, but if this isn't set to false, then the CI will try and make sure taef.png is in the OutputPath at build time.--> - + false - + 4453;%(DisableSpecificWarnings) @@ -94,7 +94,6 @@ {CA5CAD1A-C46D-4588-B1C0-40F31AE9100B} - diff --git a/src/cascadia/LocalTests_TerminalApp/TestUtils.h b/src/cascadia/LocalTests_TerminalApp/TestUtils.h index ea1df508e1f..c34552b019a 100644 --- a/src/cascadia/LocalTests_TerminalApp/TestUtils.h +++ b/src/cascadia/LocalTests_TerminalApp/TestUtils.h @@ -24,18 +24,18 @@ class TerminalAppLocalTests::TestUtils // Return Value: // - The ActionAndArgs bound to the given key, or nullptr if nothing is bound to it. static const winrt::TerminalApp::ActionAndArgs GetActionAndArgs(const winrt::TerminalApp::implementation::AppKeyBindings& bindings, - const winrt::Microsoft::Terminal::Settings::KeyChord& kc) + const winrt::Microsoft::Terminal::TerminalControl::KeyChord& kc) { std::wstring buffer{ L"" }; - if (WI_IsFlagSet(kc.Modifiers(), winrt::Microsoft::Terminal::Settings::KeyModifiers::Ctrl)) + if (WI_IsFlagSet(kc.Modifiers(), winrt::Microsoft::Terminal::TerminalControl::KeyModifiers::Ctrl)) { buffer += L"Ctrl+"; } - if (WI_IsFlagSet(kc.Modifiers(), winrt::Microsoft::Terminal::Settings::KeyModifiers::Shift)) + if (WI_IsFlagSet(kc.Modifiers(), winrt::Microsoft::Terminal::TerminalControl::KeyModifiers::Shift)) { buffer += L"Shift+"; } - if (WI_IsFlagSet(kc.Modifiers(), winrt::Microsoft::Terminal::Settings::KeyModifiers::Alt)) + if (WI_IsFlagSet(kc.Modifiers(), winrt::Microsoft::Terminal::TerminalControl::KeyModifiers::Alt)) { buffer += L"Alt+"; } diff --git a/src/cascadia/TerminalApp/AppActionHandlers.cpp b/src/cascadia/TerminalApp/AppActionHandlers.cpp index afb72b94506..5d260ef94c4 100644 --- a/src/cascadia/TerminalApp/AppActionHandlers.cpp +++ b/src/cascadia/TerminalApp/AppActionHandlers.cpp @@ -14,7 +14,6 @@ using namespace winrt::Windows::UI::Core; using namespace winrt::Windows::Foundation::Collections; using namespace winrt::Windows::System; using namespace winrt::Microsoft::Terminal; -using namespace winrt::Microsoft::Terminal::Settings; using namespace winrt::Microsoft::Terminal::TerminalControl; using namespace winrt::Microsoft::Terminal::TerminalConnection; using namespace ::TerminalApp; diff --git a/src/cascadia/TerminalApp/AppKeyBindings.cpp b/src/cascadia/TerminalApp/AppKeyBindings.cpp index 58821ac5a6a..4ac3f012c2c 100644 --- a/src/cascadia/TerminalApp/AppKeyBindings.cpp +++ b/src/cascadia/TerminalApp/AppKeyBindings.cpp @@ -9,12 +9,12 @@ using namespace winrt::Microsoft::Terminal; using namespace winrt::TerminalApp; -using namespace winrt::Microsoft::Terminal::Settings; +using namespace winrt::Microsoft::Terminal::TerminalControl; namespace winrt::TerminalApp::implementation { void AppKeyBindings::SetKeyBinding(const TerminalApp::ActionAndArgs& actionAndArgs, - const Settings::KeyChord& chord) + const KeyChord& chord) { _keyShortcuts[chord] = actionAndArgs; } @@ -25,7 +25,7 @@ namespace winrt::TerminalApp::implementation // - chord: the keystroke to remove the action for. // Return Value: // - - void AppKeyBindings::ClearKeyBinding(const Settings::KeyChord& chord) + void AppKeyBindings::ClearKeyBinding(const KeyChord& chord) { _keyShortcuts.erase(chord); } @@ -67,7 +67,7 @@ namespace winrt::TerminalApp::implementation return { nullptr }; } - bool AppKeyBindings::TryKeyChord(const Settings::KeyChord& kc) + bool AppKeyBindings::TryKeyChord(const KeyChord& kc) { const auto keyIter = _keyShortcuts.find(kc); if (keyIter != _keyShortcuts.end()) @@ -87,19 +87,19 @@ namespace winrt::TerminalApp::implementation // - Takes the KeyModifier flags from Terminal and maps them to the WinRT types which are used by XAML // Return Value: // - a Windows::System::VirtualKeyModifiers object with the flags of which modifiers used. - Windows::System::VirtualKeyModifiers AppKeyBindings::ConvertVKModifiers(Settings::KeyModifiers modifiers) + Windows::System::VirtualKeyModifiers AppKeyBindings::ConvertVKModifiers(KeyModifiers modifiers) { Windows::System::VirtualKeyModifiers keyModifiers = Windows::System::VirtualKeyModifiers::None; - if (WI_IsFlagSet(modifiers, Settings::KeyModifiers::Ctrl)) + if (WI_IsFlagSet(modifiers, KeyModifiers::Ctrl)) { keyModifiers |= Windows::System::VirtualKeyModifiers::Control; } - if (WI_IsFlagSet(modifiers, Settings::KeyModifiers::Shift)) + if (WI_IsFlagSet(modifiers, KeyModifiers::Shift)) { keyModifiers |= Windows::System::VirtualKeyModifiers::Shift; } - if (WI_IsFlagSet(modifiers, Settings::KeyModifiers::Alt)) + if (WI_IsFlagSet(modifiers, KeyModifiers::Alt)) { // note: Menu is the Alt VK_MENU keyModifiers |= Windows::System::VirtualKeyModifiers::Menu; diff --git a/src/cascadia/TerminalApp/AppKeyBindings.h b/src/cascadia/TerminalApp/AppKeyBindings.h index 63df542a75a..4feb7e8968a 100644 --- a/src/cascadia/TerminalApp/AppKeyBindings.h +++ b/src/cascadia/TerminalApp/AppKeyBindings.h @@ -20,10 +20,10 @@ namespace winrt::TerminalApp::implementation { struct KeyChordHash { - std::size_t operator()(const winrt::Microsoft::Terminal::Settings::KeyChord& key) const + std::size_t operator()(const winrt::Microsoft::Terminal::TerminalControl::KeyChord& key) const { std::hash keyHash; - std::hash modifiersHash; + std::hash modifiersHash; std::size_t hashedKey = keyHash(key.Vkey()); std::size_t hashedMods = modifiersHash(key.Modifiers()); return hashedKey ^ hashedMods; @@ -32,7 +32,7 @@ namespace winrt::TerminalApp::implementation struct KeyChordEquality { - bool operator()(const winrt::Microsoft::Terminal::Settings::KeyChord& lhs, const winrt::Microsoft::Terminal::Settings::KeyChord& rhs) const + bool operator()(const winrt::Microsoft::Terminal::TerminalControl::KeyChord& lhs, const winrt::Microsoft::Terminal::TerminalControl::KeyChord& rhs) const { return lhs.Modifiers() == rhs.Modifiers() && lhs.Vkey() == rhs.Vkey(); } @@ -42,15 +42,15 @@ namespace winrt::TerminalApp::implementation { AppKeyBindings() = default; - bool TryKeyChord(winrt::Microsoft::Terminal::Settings::KeyChord const& kc); + bool TryKeyChord(winrt::Microsoft::Terminal::TerminalControl::KeyChord const& kc); void SetKeyBinding(TerminalApp::ActionAndArgs const& actionAndArgs, - winrt::Microsoft::Terminal::Settings::KeyChord const& chord); - void ClearKeyBinding(winrt::Microsoft::Terminal::Settings::KeyChord const& chord); - Microsoft::Terminal::Settings::KeyChord GetKeyBindingForAction(TerminalApp::ShortcutAction const& action); - Microsoft::Terminal::Settings::KeyChord GetKeyBindingForActionWithArgs(TerminalApp::ActionAndArgs const& actionAndArgs); + winrt::Microsoft::Terminal::TerminalControl::KeyChord const& chord); + void ClearKeyBinding(winrt::Microsoft::Terminal::TerminalControl::KeyChord const& chord); + Microsoft::Terminal::TerminalControl::KeyChord GetKeyBindingForAction(TerminalApp::ShortcutAction const& action); + Microsoft::Terminal::TerminalControl::KeyChord GetKeyBindingForActionWithArgs(TerminalApp::ActionAndArgs const& actionAndArgs); - static Windows::System::VirtualKeyModifiers ConvertVKModifiers(winrt::Microsoft::Terminal::Settings::KeyModifiers modifiers); + static Windows::System::VirtualKeyModifiers ConvertVKModifiers(winrt::Microsoft::Terminal::TerminalControl::KeyModifiers modifiers); // Defined in AppKeyBindingsSerialization.cpp std::vector<::TerminalApp::SettingsLoadWarnings> LayerJson(const Json::Value& json); @@ -59,7 +59,7 @@ namespace winrt::TerminalApp::implementation void SetDispatch(const winrt::TerminalApp::ShortcutActionDispatch& dispatch); private: - std::unordered_map _keyShortcuts; + std::unordered_map _keyShortcuts; winrt::TerminalApp::ShortcutActionDispatch _dispatch{ nullptr }; diff --git a/src/cascadia/TerminalApp/AppKeyBindings.idl b/src/cascadia/TerminalApp/AppKeyBindings.idl index db287b79267..0dcba935591 100644 --- a/src/cascadia/TerminalApp/AppKeyBindings.idl +++ b/src/cascadia/TerminalApp/AppKeyBindings.idl @@ -5,15 +5,15 @@ import "../ShortcutActionDispatch.idl"; namespace TerminalApp { - [default_interface] runtimeclass AppKeyBindings : Microsoft.Terminal.Settings.IKeyBindings + [default_interface] runtimeclass AppKeyBindings : Microsoft.Terminal.TerminalControl.IKeyBindings { AppKeyBindings(); - void SetKeyBinding(ActionAndArgs actionAndArgs, Microsoft.Terminal.Settings.KeyChord chord); - void ClearKeyBinding(Microsoft.Terminal.Settings.KeyChord chord); + void SetKeyBinding(ActionAndArgs actionAndArgs, Microsoft.Terminal.TerminalControl.KeyChord chord); + void ClearKeyBinding(Microsoft.Terminal.TerminalControl.KeyChord chord); - Microsoft.Terminal.Settings.KeyChord GetKeyBindingForAction(ShortcutAction action); - Microsoft.Terminal.Settings.KeyChord GetKeyBindingForActionWithArgs(ActionAndArgs actionAndArgs); + Microsoft.Terminal.TerminalControl.KeyChord GetKeyBindingForAction(ShortcutAction action); + Microsoft.Terminal.TerminalControl.KeyChord GetKeyBindingForActionWithArgs(ActionAndArgs actionAndArgs); void SetDispatch(ShortcutActionDispatch dispatch); } diff --git a/src/cascadia/TerminalApp/AppKeyBindingsSerialization.cpp b/src/cascadia/TerminalApp/AppKeyBindingsSerialization.cpp index 6be18ca683e..2bb507ec86f 100644 --- a/src/cascadia/TerminalApp/AppKeyBindingsSerialization.cpp +++ b/src/cascadia/TerminalApp/AppKeyBindingsSerialization.cpp @@ -12,9 +12,8 @@ #include "KeyChordSerialization.h" #include "Utils.h" #include "JsonUtils.h" -#include -using namespace winrt::Microsoft::Terminal::Settings; +using namespace winrt::Microsoft::Terminal::TerminalControl; using namespace winrt::TerminalApp; static constexpr std::string_view KeysKey{ "keys" }; diff --git a/src/cascadia/TerminalApp/AppLogic.cpp b/src/cascadia/TerminalApp/AppLogic.cpp index 5a6ec188703..b0257b431a6 100644 --- a/src/cascadia/TerminalApp/AppLogic.cpp +++ b/src/cascadia/TerminalApp/AppLogic.cpp @@ -15,7 +15,6 @@ using namespace winrt::Windows::UI::Xaml::Controls; using namespace winrt::Windows::UI::Core; using namespace winrt::Windows::System; using namespace winrt::Microsoft::Terminal; -using namespace winrt::Microsoft::Terminal::Settings; using namespace winrt::Microsoft::Terminal::TerminalControl; using namespace ::TerminalApp; diff --git a/src/cascadia/TerminalApp/CascadiaSettings.cpp b/src/cascadia/TerminalApp/CascadiaSettings.cpp index 96e947e952d..29c8d750d02 100644 --- a/src/cascadia/TerminalApp/CascadiaSettings.cpp +++ b/src/cascadia/TerminalApp/CascadiaSettings.cpp @@ -17,7 +17,6 @@ #include "WslDistroGenerator.h" #include "AzureCloudShellGenerator.h" -using namespace winrt::Microsoft::Terminal::Settings; using namespace ::TerminalApp; using namespace winrt::Microsoft::Terminal::TerminalControl; using namespace winrt::TerminalApp; diff --git a/src/cascadia/TerminalApp/ColorScheme.cpp b/src/cascadia/TerminalApp/ColorScheme.cpp index 1659013809c..b04090b6e03 100644 --- a/src/cascadia/TerminalApp/ColorScheme.cpp +++ b/src/cascadia/TerminalApp/ColorScheme.cpp @@ -2,7 +2,6 @@ // Licensed under the MIT license. #include "pch.h" -#include #include "ColorScheme.h" #include "DefaultSettings.h" #include "../../types/inc/Utils.hpp" diff --git a/src/cascadia/TerminalApp/ColorScheme.h b/src/cascadia/TerminalApp/ColorScheme.h index dca0f53759a..4eafdc75b7c 100644 --- a/src/cascadia/TerminalApp/ColorScheme.h +++ b/src/cascadia/TerminalApp/ColorScheme.h @@ -15,7 +15,6 @@ Author(s): --*/ #pragma once -#include #include "TerminalSettings.h" #include "../../inc/conattrs.hpp" diff --git a/src/cascadia/TerminalApp/Command.cpp b/src/cascadia/TerminalApp/Command.cpp index f3fe1219126..6d164bc7445 100644 --- a/src/cascadia/TerminalApp/Command.cpp +++ b/src/cascadia/TerminalApp/Command.cpp @@ -10,7 +10,6 @@ #include "JsonUtils.h" #include -using namespace winrt::Microsoft::Terminal::Settings; using namespace winrt::TerminalApp; using namespace ::TerminalApp; diff --git a/src/cascadia/TerminalApp/CommandPalette.cpp b/src/cascadia/TerminalApp/CommandPalette.cpp index fd0a139281b..f6fdfa9567b 100644 --- a/src/cascadia/TerminalApp/CommandPalette.cpp +++ b/src/cascadia/TerminalApp/CommandPalette.cpp @@ -5,7 +5,6 @@ #include "CommandPalette.h" #include "CommandPalette.g.cpp" -#include using namespace winrt; using namespace winrt::TerminalApp; diff --git a/src/cascadia/TerminalApp/GlobalAppSettings.cpp b/src/cascadia/TerminalApp/GlobalAppSettings.cpp index dd3b17ae723..00ce2cc3310 100644 --- a/src/cascadia/TerminalApp/GlobalAppSettings.cpp +++ b/src/cascadia/TerminalApp/GlobalAppSettings.cpp @@ -10,7 +10,6 @@ #include "TerminalSettingsSerializationHelpers.h" using namespace TerminalApp; -using namespace winrt::Microsoft::Terminal::Settings; using namespace winrt::TerminalApp; using namespace winrt::Windows::UI::Xaml; using namespace ::Microsoft::Console; diff --git a/src/cascadia/TerminalApp/KeyChordSerialization.cpp b/src/cascadia/TerminalApp/KeyChordSerialization.cpp index b825c251047..69625004d14 100644 --- a/src/cascadia/TerminalApp/KeyChordSerialization.cpp +++ b/src/cascadia/TerminalApp/KeyChordSerialization.cpp @@ -4,7 +4,7 @@ #include "pch.h" #include "KeyChordSerialization.h" -using namespace winrt::Microsoft::Terminal::Settings; +using namespace winrt::Microsoft::Terminal::TerminalControl; static constexpr std::wstring_view CTRL_KEY{ L"ctrl" }; static constexpr std::wstring_view SHIFT_KEY{ L"shift" }; @@ -99,7 +99,7 @@ static const std::unordered_map vkeyNamePairs { // - hstr: the string to parse into a keychord. // Return Value: // - a newly constructed KeyChord -winrt::Microsoft::Terminal::Settings::KeyChord KeyChordSerialization::FromString(const winrt::hstring& hstr) +KeyChord KeyChordSerialization::FromString(const winrt::hstring& hstr) { std::wstring wstr{ hstr }; @@ -201,7 +201,7 @@ winrt::Microsoft::Terminal::Settings::KeyChord KeyChordSerialization::FromString } } - return winrt::Microsoft::Terminal::Settings::KeyChord{ modifiers, vkey }; + return KeyChord{ modifiers, vkey }; } // Function Description: diff --git a/src/cascadia/TerminalApp/KeyChordSerialization.h b/src/cascadia/TerminalApp/KeyChordSerialization.h index 8f9cf4f26ee..4da2f0020a7 100644 --- a/src/cascadia/TerminalApp/KeyChordSerialization.h +++ b/src/cascadia/TerminalApp/KeyChordSerialization.h @@ -2,11 +2,11 @@ // Licensed under the MIT license. #pragma once -#include +#include class KeyChordSerialization final { public: - static winrt::Microsoft::Terminal::Settings::KeyChord FromString(const winrt::hstring& str); - static winrt::hstring ToString(const winrt::Microsoft::Terminal::Settings::KeyChord& chord); + static winrt::Microsoft::Terminal::TerminalControl::KeyChord FromString(const winrt::hstring& str); + static winrt::hstring ToString(const winrt::Microsoft::Terminal::TerminalControl::KeyChord& chord); }; diff --git a/src/cascadia/TerminalApp/Pane.cpp b/src/cascadia/TerminalApp/Pane.cpp index f8e61ae8379..40438f81f51 100644 --- a/src/cascadia/TerminalApp/Pane.cpp +++ b/src/cascadia/TerminalApp/Pane.cpp @@ -12,7 +12,6 @@ using namespace winrt::Windows::UI; using namespace winrt::Windows::UI::Xaml; using namespace winrt::Windows::UI::Core; using namespace winrt::Windows::UI::Xaml::Media; -using namespace winrt::Microsoft::Terminal::Settings; using namespace winrt::Microsoft::Terminal::TerminalControl; using namespace winrt::Microsoft::Terminal::TerminalConnection; using namespace winrt::TerminalApp; diff --git a/src/cascadia/TerminalApp/Profile.cpp b/src/cascadia/TerminalApp/Profile.cpp index b98efb9f691..9829474297a 100644 --- a/src/cascadia/TerminalApp/Profile.cpp +++ b/src/cascadia/TerminalApp/Profile.cpp @@ -13,7 +13,7 @@ using namespace TerminalApp; using namespace winrt::TerminalApp; -using namespace winrt::Microsoft::Terminal::Settings; +using namespace winrt::Microsoft::Terminal::TerminalControl; using namespace winrt::Windows::UI::Xaml; using namespace ::Microsoft::Console; diff --git a/src/cascadia/TerminalApp/Profile.h b/src/cascadia/TerminalApp/Profile.h index 1e145e669c7..422b139883e 100644 --- a/src/cascadia/TerminalApp/Profile.h +++ b/src/cascadia/TerminalApp/Profile.h @@ -122,7 +122,7 @@ class TerminalApp::Profile final bool _snapOnInput; bool _altGrAliasing; uint32_t _cursorHeight; - winrt::Microsoft::Terminal::Settings::CursorStyle _cursorShape; + winrt::Microsoft::Terminal::TerminalControl::CursorStyle _cursorShape; std::wstring _commandline; std::wstring _fontFace; @@ -137,13 +137,13 @@ class TerminalApp::Profile final std::optional _backgroundImageStretchMode; std::optional> _backgroundImageAlignment; - std::optional<::winrt::Microsoft::Terminal::Settings::ScrollbarState> _scrollbarState; + std::optional<::winrt::Microsoft::Terminal::TerminalControl::ScrollbarState> _scrollbarState; CloseOnExitMode _closeOnExitMode; std::wstring _padding; std::optional _icon; - winrt::Microsoft::Terminal::Settings::TextAntialiasingMode _antialiasingMode; + winrt::Microsoft::Terminal::TerminalControl::TextAntialiasingMode _antialiasingMode; friend class TerminalAppLocalTests::SettingsTests; friend class TerminalAppLocalTests::ProfileTests; diff --git a/src/cascadia/TerminalApp/Tab.cpp b/src/cascadia/TerminalApp/Tab.cpp index 51e54be09ee..5e7521bbdfe 100644 --- a/src/cascadia/TerminalApp/Tab.cpp +++ b/src/cascadia/TerminalApp/Tab.cpp @@ -12,7 +12,6 @@ using namespace winrt; using namespace winrt::Windows::UI::Xaml; using namespace winrt::Windows::UI::Core; -using namespace winrt::Microsoft::Terminal::Settings; using namespace winrt::Microsoft::Terminal::TerminalControl; using namespace winrt::Windows::System; diff --git a/src/cascadia/TerminalApp/TerminalApp.vcxproj b/src/cascadia/TerminalApp/TerminalApp.vcxproj index 320c20a299a..a19fa271c79 100644 --- a/src/cascadia/TerminalApp/TerminalApp.vcxproj +++ b/src/cascadia/TerminalApp/TerminalApp.vcxproj @@ -67,7 +67,6 @@ - - - $(_BinRoot)TerminalSettings\Microsoft.Terminal.Settings.winmd - true - false - false - $(_BinRoot)TerminalConnection\Microsoft.Terminal.TerminalConnection.winmd true diff --git a/src/cascadia/TerminalSettings/IControlSettings.idl b/src/cascadia/TerminalControl/IControlSettings.idl similarity index 85% rename from src/cascadia/TerminalSettings/IControlSettings.idl rename to src/cascadia/TerminalControl/IControlSettings.idl index 47484d99b4a..2f140a0a3f8 100644 --- a/src/cascadia/TerminalSettings/IControlSettings.idl +++ b/src/cascadia/TerminalControl/IControlSettings.idl @@ -2,9 +2,8 @@ // Licensed under the MIT license. import "IKeyBindings.idl"; -import "ICoreSettings.idl"; -namespace Microsoft.Terminal.Settings +namespace Microsoft.Terminal.TerminalControl { enum ScrollbarState { @@ -24,7 +23,7 @@ namespace Microsoft.Terminal.Settings // TermControl's behavior. In these settings there is both the entirety // of the Core ITerminalSettings interface, and any additional settings // for specifically the control. - interface IControlSettings requires Microsoft.Terminal.Settings.ICoreSettings + interface IControlSettings requires ICoreSettings { String ProfileName; @@ -37,7 +36,7 @@ namespace Microsoft.Terminal.Settings Windows.UI.Text.FontWeight FontWeight; String Padding; - IKeyBindings KeyBindings; + Microsoft.Terminal.TerminalControl.IKeyBindings KeyBindings; Boolean CopyOnSelect; diff --git a/src/cascadia/TerminalSettings/IKeyBindings.idl b/src/cascadia/TerminalControl/IKeyBindings.idl similarity index 78% rename from src/cascadia/TerminalSettings/IKeyBindings.idl rename to src/cascadia/TerminalControl/IKeyBindings.idl index 5c43e6dd376..6d3992c5d0a 100644 --- a/src/cascadia/TerminalSettings/IKeyBindings.idl +++ b/src/cascadia/TerminalControl/IKeyBindings.idl @@ -3,7 +3,7 @@ import "KeyChord.idl"; -namespace Microsoft.Terminal.Settings +namespace Microsoft.Terminal.TerminalControl { // [default_interface] interface IKeyBindings diff --git a/src/cascadia/TerminalSettings/KeyChord.cpp b/src/cascadia/TerminalControl/KeyChord.cpp similarity index 51% rename from src/cascadia/TerminalSettings/KeyChord.cpp rename to src/cascadia/TerminalControl/KeyChord.cpp index 6c3523497e0..c265b061312 100644 --- a/src/cascadia/TerminalSettings/KeyChord.cpp +++ b/src/cascadia/TerminalControl/KeyChord.cpp @@ -6,7 +6,7 @@ #include "KeyChord.g.cpp" -namespace winrt::Microsoft::Terminal::Settings::implementation +namespace winrt::Microsoft::Terminal::TerminalControl::implementation { KeyChord::KeyChord() noexcept : _modifiers{ 0 }, @@ -15,25 +15,25 @@ namespace winrt::Microsoft::Terminal::Settings::implementation } KeyChord::KeyChord(bool ctrl, bool alt, bool shift, int32_t vkey) noexcept : - _modifiers{ (ctrl ? Settings::KeyModifiers::Ctrl : Settings::KeyModifiers::None) | - (alt ? Settings::KeyModifiers::Alt : Settings::KeyModifiers::None) | - (shift ? Settings::KeyModifiers::Shift : Settings::KeyModifiers::None) }, + _modifiers{ (ctrl ? TerminalControl::KeyModifiers::Ctrl : TerminalControl::KeyModifiers::None) | + (alt ? TerminalControl::KeyModifiers::Alt : TerminalControl::KeyModifiers::None) | + (shift ? TerminalControl::KeyModifiers::Shift : TerminalControl::KeyModifiers::None) }, _vkey{ vkey } { } - KeyChord::KeyChord(Settings::KeyModifiers const& modifiers, int32_t vkey) noexcept : + KeyChord::KeyChord(TerminalControl::KeyModifiers const& modifiers, int32_t vkey) noexcept : _modifiers{ modifiers }, _vkey{ vkey } { } - Settings::KeyModifiers KeyChord::Modifiers() noexcept + TerminalControl::KeyModifiers KeyChord::Modifiers() noexcept { return _modifiers; } - void KeyChord::Modifiers(Settings::KeyModifiers const& value) noexcept + void KeyChord::Modifiers(TerminalControl::KeyModifiers const& value) noexcept { _modifiers = value; } diff --git a/src/cascadia/TerminalSettings/KeyChord.h b/src/cascadia/TerminalControl/KeyChord.h similarity index 53% rename from src/cascadia/TerminalSettings/KeyChord.h rename to src/cascadia/TerminalControl/KeyChord.h index e948c1afcd9..910eb6ca15f 100644 --- a/src/cascadia/TerminalSettings/KeyChord.h +++ b/src/cascadia/TerminalControl/KeyChord.h @@ -5,26 +5,26 @@ #include "KeyChord.g.h" -namespace winrt::Microsoft::Terminal::Settings::implementation +namespace winrt::Microsoft::Terminal::TerminalControl::implementation { struct KeyChord : KeyChordT { KeyChord() noexcept; - KeyChord(Settings::KeyModifiers const& modifiers, int32_t vkey) noexcept; + KeyChord(TerminalControl::KeyModifiers const& modifiers, int32_t vkey) noexcept; KeyChord(bool ctrl, bool alt, bool shift, int32_t vkey) noexcept; - Settings::KeyModifiers Modifiers() noexcept; - void Modifiers(Settings::KeyModifiers const& value) noexcept; + TerminalControl::KeyModifiers Modifiers() noexcept; + void Modifiers(TerminalControl::KeyModifiers const& value) noexcept; int32_t Vkey() noexcept; void Vkey(int32_t value) noexcept; private: - Settings::KeyModifiers _modifiers; + TerminalControl::KeyModifiers _modifiers; int32_t _vkey; }; } -namespace winrt::Microsoft::Terminal::Settings::factory_implementation +namespace winrt::Microsoft::Terminal::TerminalControl::factory_implementation { struct KeyChord : KeyChordT { diff --git a/src/cascadia/TerminalSettings/KeyChord.idl b/src/cascadia/TerminalControl/KeyChord.idl similarity index 87% rename from src/cascadia/TerminalSettings/KeyChord.idl rename to src/cascadia/TerminalControl/KeyChord.idl index c02459144b3..4952688a602 100644 --- a/src/cascadia/TerminalSettings/KeyChord.idl +++ b/src/cascadia/TerminalControl/KeyChord.idl @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -namespace Microsoft.Terminal.Settings +namespace Microsoft.Terminal.TerminalControl { [flags] enum KeyModifiers diff --git a/src/cascadia/TerminalControl/TSFInputControl.cpp b/src/cascadia/TerminalControl/TSFInputControl.cpp index 1eb56878c8a..23bd9bcbec2 100644 --- a/src/cascadia/TerminalControl/TSFInputControl.cpp +++ b/src/cascadia/TerminalControl/TSFInputControl.cpp @@ -31,14 +31,14 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation InitializeComponent(); // Create a CoreTextEditingContext for since we are acting like a custom edit control - auto manager = Core::CoreTextServicesManager::GetForCurrentView(); + auto manager = CoreTextServicesManager::GetForCurrentView(); _editContext = manager.CreateEditContext(); // InputPane is manually shown inside of TermControl. - _editContext.InputPaneDisplayPolicy(Core::CoreTextInputPaneDisplayPolicy::Manual); + _editContext.InputPaneDisplayPolicy(CoreTextInputPaneDisplayPolicy::Manual); // set the input scope to Text because this control is for any text. - _editContext.InputScope(Core::CoreTextInputScope::Text); + _editContext.InputScope(CoreTextInputScope::Text); _textRequestedRevoker = _editContext.TextRequested(winrt::auto_revoke, { this, &TSFInputControl::_textRequestedHandler }); diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index 62bc7a948e2..e99e0d2153d 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -25,7 +25,6 @@ using namespace winrt::Windows::UI::Core; using namespace winrt::Windows::UI::ViewManagement; using namespace winrt::Windows::UI::Input; using namespace winrt::Windows::System; -using namespace winrt::Microsoft::Terminal::Settings; using namespace winrt::Windows::ApplicationModel::DataTransfer; // The minimum delay between updates to the scroll bar's values. @@ -56,7 +55,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation return initialized; } - TermControl::TermControl(Settings::IControlSettings settings, TerminalConnection::ITerminalConnection connection) : + TermControl::TermControl(IControlSettings settings, TerminalConnection::ITerminalConnection connection) : _connection{ connection }, _initializedTerminal{ false }, _settings{ settings }, @@ -237,7 +236,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation // - newSettings: New settings values for the profile in this terminal. // Return Value: // - - winrt::fire_and_forget TermControl::UpdateSettings(Settings::IControlSettings newSettings) + winrt::fire_and_forget TermControl::UpdateSettings(IControlSettings newSettings) { _settings = newSettings; auto weakThis{ get_weak() }; @@ -2320,7 +2319,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation const int32_t& fontHeight, const winrt::Windows::UI::Text::FontWeight& fontWeight, const winrt::hstring& fontFace, - const Microsoft::Terminal::Settings::ScrollbarState& scrollState, + const ScrollbarState& scrollState, const winrt::hstring& padding, const uint32_t dpi) { diff --git a/src/cascadia/TerminalControl/TermControl.h b/src/cascadia/TerminalControl/TermControl.h index 4499c589efc..ce9a8a49d2d 100644 --- a/src/cascadia/TerminalControl/TermControl.h +++ b/src/cascadia/TerminalControl/TermControl.h @@ -7,7 +7,6 @@ #include "CopyToClipboardEventArgs.g.h" #include "PasteFromClipboardEventArgs.g.h" #include -#include #include "../../renderer/base/Renderer.hpp" #include "../../renderer/dx/DxRenderer.hpp" #include "../../renderer/uia/UiaRenderer.hpp" @@ -56,9 +55,9 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation struct TermControl : TermControlT { - TermControl(Settings::IControlSettings settings, TerminalConnection::ITerminalConnection connection); + TermControl(IControlSettings settings, TerminalConnection::ITerminalConnection connection); - winrt::fire_and_forget UpdateSettings(Settings::IControlSettings newSettings); + winrt::fire_and_forget UpdateSettings(IControlSettings newSettings); hstring Title(); hstring GetProfileName() const; @@ -99,12 +98,12 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation TerminalConnection::ConnectionState ConnectionState() const; - static Windows::Foundation::Size GetProposedDimensions(Microsoft::Terminal::Settings::IControlSettings const& settings, const uint32_t dpi); + static Windows::Foundation::Size GetProposedDimensions(IControlSettings const& settings, const uint32_t dpi); static Windows::Foundation::Size GetProposedDimensions(const winrt::Windows::Foundation::Size& initialSizeInChars, const int32_t& fontSize, const winrt::Windows::UI::Text::FontWeight& fontWeight, const winrt::hstring& fontFace, - const Microsoft::Terminal::Settings::ScrollbarState& scrollState, + const ScrollbarState& scrollState, const winrt::hstring& padding, const uint32_t dpi); @@ -137,7 +136,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation std::unique_ptr<::Microsoft::Console::Render::DxEngine> _renderEngine; std::unique_ptr<::Microsoft::Console::Render::UiaEngine> _uiaEngine; - Settings::IControlSettings _settings; + IControlSettings _settings; bool _focused; std::atomic _closing; diff --git a/src/cascadia/TerminalControl/TermControl.idl b/src/cascadia/TerminalControl/TermControl.idl index d9a2ac5cdff..e729c38659c 100644 --- a/src/cascadia/TerminalControl/TermControl.idl +++ b/src/cascadia/TerminalControl/TermControl.idl @@ -2,6 +2,7 @@ // Licensed under the MIT license. import "IMouseWheelListener.idl"; +import "IControlSettings.idl"; namespace Microsoft.Terminal.TerminalControl { @@ -32,11 +33,11 @@ namespace Microsoft.Terminal.TerminalControl [default_interface] runtimeclass TermControl : Windows.UI.Xaml.Controls.UserControl, IDirectKeyListener, IMouseWheelListener { - TermControl(Microsoft.Terminal.Settings.IControlSettings settings, Microsoft.Terminal.TerminalConnection.ITerminalConnection connection); + TermControl(Microsoft.Terminal.TerminalControl.IControlSettings settings, Microsoft.Terminal.TerminalConnection.ITerminalConnection connection); - static Windows.Foundation.Size GetProposedDimensions(Microsoft.Terminal.Settings.IControlSettings settings, UInt32 dpi); + static Windows.Foundation.Size GetProposedDimensions(Microsoft.Terminal.TerminalControl.IControlSettings settings, UInt32 dpi); - void UpdateSettings(Microsoft.Terminal.Settings.IControlSettings newSettings); + void UpdateSettings(Microsoft.Terminal.TerminalControl.IControlSettings newSettings); event TitleChangedEventArgs TitleChanged; event FontSizeChangedEventArgs FontSizeChanged; diff --git a/src/cascadia/TerminalControl/TerminalControl.vcxproj b/src/cascadia/TerminalControl/TerminalControl.vcxproj index bdad948d0b4..14992abab81 100644 --- a/src/cascadia/TerminalControl/TerminalControl.vcxproj +++ b/src/cascadia/TerminalControl/TerminalControl.vcxproj @@ -19,7 +19,6 @@ projects compile properly when they depend on this "Microsoft.winmd." --> 3 - + + $(MarkupCompilePass1DependsOn);OpenConsoleStripDuplicateWinmdFromReferencesBeforePass1 + $(MarkupCompilePass2DependsOn);OpenConsoleStripDuplicateWinmdFromReferencesBeforePass2 + + + + + + + + + + + + + + + + + + + + diff --git a/src/cascadia/TerminalControl/TerminalControl.vcxproj.filters b/src/cascadia/TerminalControl/TerminalControl.vcxproj.filters index f4bdeb33de2..d9eaaf778d3 100644 --- a/src/cascadia/TerminalControl/TerminalControl.vcxproj.filters +++ b/src/cascadia/TerminalControl/TerminalControl.vcxproj.filters @@ -15,8 +15,6 @@ - - @@ -26,15 +24,15 @@ - - + + @@ -42,6 +40,8 @@ + + @@ -51,4 +51,4 @@ Resources - + \ No newline at end of file diff --git a/src/cascadia/TerminalSettings/ICoreSettings.idl b/src/cascadia/TerminalCore/ICoreSettings.idl similarity index 91% rename from src/cascadia/TerminalSettings/ICoreSettings.idl rename to src/cascadia/TerminalCore/ICoreSettings.idl index 3bc4834592d..99fe24e7930 100644 --- a/src/cascadia/TerminalSettings/ICoreSettings.idl +++ b/src/cascadia/TerminalCore/ICoreSettings.idl @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -namespace Microsoft.Terminal.Settings +namespace Microsoft.Terminal.TerminalControl { enum CursorStyle { diff --git a/src/cascadia/TerminalCore/Terminal.cpp b/src/cascadia/TerminalCore/Terminal.cpp index 7f106ba1f90..6d4a4208567 100644 --- a/src/cascadia/TerminalCore/Terminal.cpp +++ b/src/cascadia/TerminalCore/Terminal.cpp @@ -10,9 +10,9 @@ #include "../../inc/argb.h" #include "../../types/inc/utils.hpp" -#include "winrt/Microsoft.Terminal.Settings.h" +#include -using namespace winrt::Microsoft::Terminal::Settings; +using namespace winrt::Microsoft::Terminal::TerminalControl; using namespace Microsoft::Terminal::Core; using namespace Microsoft::Console; using namespace Microsoft::Console::Render; @@ -84,8 +84,8 @@ void Terminal::Create(COORD viewportSize, SHORT scrollbackLines, IRenderTarget& // Arguments: // - settings: the set of CoreSettings we need to use to initialize the terminal // - renderTarget: A render target the terminal can use for paint invalidation. -void Terminal::CreateFromSettings(winrt::Microsoft::Terminal::Settings::ICoreSettings settings, - Microsoft::Console::Render::IRenderTarget& renderTarget) +void Terminal::CreateFromSettings(ICoreSettings settings, + IRenderTarget& renderTarget) { const COORD viewportSize{ Utils::ClampToShortMax(settings.InitialCols(), 1), Utils::ClampToShortMax(settings.InitialRows(), 1) }; @@ -101,7 +101,7 @@ void Terminal::CreateFromSettings(winrt::Microsoft::Terminal::Settings::ICoreSet // CoreSettings object. // Arguments: // - settings: an ICoreSettings with new settings values for us to use. -void Terminal::UpdateSettings(winrt::Microsoft::Terminal::Settings::ICoreSettings settings) +void Terminal::UpdateSettings(ICoreSettings settings) { _defaultFg = settings.DefaultForeground(); _defaultBg = settings.DefaultBackground(); @@ -344,7 +344,7 @@ void Terminal::UpdateSettings(winrt::Microsoft::Terminal::Settings::ICoreSetting // If the old scrolloffset was 0, then we weren't scrolled back at all // before, and shouldn't be now either. - _scrollOffset = originalOffsetWasZero ? 0 : ::base::ClampSub(_mutableViewport.Top(), newVisibleTop); + _scrollOffset = originalOffsetWasZero ? 0 : static_cast(::base::ClampSub(_mutableViewport.Top(), newVisibleTop)); // GH#5029 - make sure to InvalidateAll here, so that we'll paint the entire visible viewport. try diff --git a/src/cascadia/TerminalCore/Terminal.hpp b/src/cascadia/TerminalCore/Terminal.hpp index ac8d59d3e02..351b7c7f8a5 100644 --- a/src/cascadia/TerminalCore/Terminal.hpp +++ b/src/cascadia/TerminalCore/Terminal.hpp @@ -19,7 +19,7 @@ // You have to forward decl the ICoreSettings here, instead of including the header. // If you include the header, there will be compilation errors with other // headers that include Terminal.hpp -namespace winrt::Microsoft::Terminal::Settings +namespace winrt::Microsoft::Terminal::TerminalControl { struct ICoreSettings; } @@ -58,10 +58,10 @@ class Microsoft::Terminal::Core::Terminal final : SHORT scrollbackLines, Microsoft::Console::Render::IRenderTarget& renderTarget); - void CreateFromSettings(winrt::Microsoft::Terminal::Settings::ICoreSettings settings, + void CreateFromSettings(winrt::Microsoft::Terminal::TerminalControl::ICoreSettings settings, Microsoft::Console::Render::IRenderTarget& renderTarget); - void UpdateSettings(winrt::Microsoft::Terminal::Settings::ICoreSettings settings); + void UpdateSettings(winrt::Microsoft::Terminal::TerminalControl::ICoreSettings settings); // Write goes through the parser void Write(std::wstring_view stringView); diff --git a/src/cascadia/TerminalCore/lib/terminalcore-lib.vcxproj b/src/cascadia/TerminalCore/lib/terminalcore-lib.vcxproj index 1acf771a692..42006cbda86 100644 --- a/src/cascadia/TerminalCore/lib/terminalcore-lib.vcxproj +++ b/src/cascadia/TerminalCore/lib/terminalcore-lib.vcxproj @@ -7,16 +7,22 @@ TerminalCore StaticLibrary 10.0.17763.0 - Microsoft.Terminal.Core + Microsoft.Terminal.TerminalControl + + true - "$(SolutionDir)\src\cascadia\TerminalSettings\Generated Files\winrt";$(SolutionDir)src\cascadia\TerminalSettings;$(CAExcludePath) + "$(SolutionDir)\src\cascadia\TerminalCore\Generated Files\winrt";$(SolutionDir)src\cascadia\TerminalCore;$(CAExcludePath) - + - + @@ -40,20 +46,23 @@ + + + pch.h - $(WinRT_IncludePath)\..\cppwinrt\winrt;"$(OpenConsoleDir)src\cascadia\TerminalSettings\Generated Files";%(AdditionalIncludeDirectories); + $(WinRT_IncludePath)\..\cppwinrt\winrt;"$(OpenConsoleDir)src\cascadia\TerminalCore\Generated Files";%(AdditionalIncludeDirectories); - - + + diff --git a/src/cascadia/TerminalSettings/TerminalSettings.def b/src/cascadia/TerminalSettings/TerminalSettings.def deleted file mode 100644 index 8c1a02932d0..00000000000 --- a/src/cascadia/TerminalSettings/TerminalSettings.def +++ /dev/null @@ -1,3 +0,0 @@ -EXPORTS -DllCanUnloadNow = WINRT_CanUnloadNow PRIVATE -DllGetActivationFactory = WINRT_GetActivationFactory PRIVATE diff --git a/src/cascadia/TerminalSettings/TerminalSettings.vcxproj b/src/cascadia/TerminalSettings/TerminalSettings.vcxproj deleted file mode 100644 index eef3fe672f4..00000000000 --- a/src/cascadia/TerminalSettings/TerminalSettings.vcxproj +++ /dev/null @@ -1,48 +0,0 @@ - - - - {CA5CAD1A-d7ec-4107-b7c6-79cb77ae2907} - TerminalSettings - Microsoft.Terminal.Settings - - - DynamicLibrary - Console - - true - - true - - - - - - - KeyChord.idl - - - - - Create - - - KeyChord.idl - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/cascadia/TerminalSettings/packages.config b/src/cascadia/TerminalSettings/packages.config deleted file mode 100644 index 8db4233e6a9..00000000000 --- a/src/cascadia/TerminalSettings/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/cascadia/TerminalSettings/pch.h b/src/cascadia/TerminalSettings/pch.h deleted file mode 100644 index 012b411e47d..00000000000 --- a/src/cascadia/TerminalSettings/pch.h +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. -// -// pch.h -// Header for platform projection include files -// - -#pragma once - -#define WIN32_LEAN_AND_MEAN - -#include -// This is inexplicable, but for whatever reason, cppwinrt conflicts with the -// SDK definition of this function, so the only fix is to undef it. -// from WinBase.h -// Windows::UI::Xaml::Media::Animation::IStoryboard::GetCurrentTime -#ifdef GetCurrentTime -#undef GetCurrentTime -#endif - -#include -#include -#include diff --git a/src/cascadia/UnitTests_TerminalCore/ConptyRoundtripTests.cpp b/src/cascadia/UnitTests_TerminalCore/ConptyRoundtripTests.cpp index f4cc7a24063..95812c957a8 100644 --- a/src/cascadia/UnitTests_TerminalCore/ConptyRoundtripTests.cpp +++ b/src/cascadia/UnitTests_TerminalCore/ConptyRoundtripTests.cpp @@ -8,7 +8,7 @@ // `renderer.PaintFrame()` is called, the tests will validate the expected // output, and then flush the output of the VtEngine straight to the Terminal. -#include "precomp.h" +#include "pch.h" #include #include "../../inc/consoletaeftemplates.hpp" #include "../../types/inc/Viewport.hpp" diff --git a/src/cascadia/UnitTests_TerminalCore/InputTest.cpp b/src/cascadia/UnitTests_TerminalCore/InputTest.cpp index 9745b0e6b2d..27b114793f7 100644 --- a/src/cascadia/UnitTests_TerminalCore/InputTest.cpp +++ b/src/cascadia/UnitTests_TerminalCore/InputTest.cpp @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -#include "precomp.h" +#include "pch.h" #include #include "../cascadia/TerminalCore/Terminal.hpp" diff --git a/src/cascadia/UnitTests_TerminalCore/MockTermSettings.h b/src/cascadia/UnitTests_TerminalCore/MockTermSettings.h index 9d91488075c..8ddc223ee36 100644 --- a/src/cascadia/UnitTests_TerminalCore/MockTermSettings.h +++ b/src/cascadia/UnitTests_TerminalCore/MockTermSettings.h @@ -1,13 +1,13 @@ #pragma once -#include "precomp.h" +#include "pch.h" #include #include "DefaultSettings.h" -#include "winrt/Microsoft.Terminal.Settings.h" +#include -using namespace winrt::Microsoft::Terminal::Settings; +using namespace winrt::Microsoft::Terminal::TerminalControl; namespace TerminalCoreUnitTests { diff --git a/src/cascadia/UnitTests_TerminalCore/ScreenSizeLimitsTest.cpp b/src/cascadia/UnitTests_TerminalCore/ScreenSizeLimitsTest.cpp index aa7f28365ff..11a6d1021b3 100644 --- a/src/cascadia/UnitTests_TerminalCore/ScreenSizeLimitsTest.cpp +++ b/src/cascadia/UnitTests_TerminalCore/ScreenSizeLimitsTest.cpp @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -#include "precomp.h" +#include "pch.h" #include #include "../cascadia/TerminalCore/Terminal.hpp" @@ -9,7 +9,7 @@ #include "../renderer/inc/DummyRenderTarget.hpp" #include "consoletaeftemplates.hpp" -using namespace winrt::Microsoft::Terminal::Settings; +using namespace winrt::Microsoft::Terminal::TerminalControl; using namespace Microsoft::Terminal::Core; using namespace WEX::Logging; using namespace WEX::TestExecution; diff --git a/src/cascadia/UnitTests_TerminalCore/ScrollTest.cpp b/src/cascadia/UnitTests_TerminalCore/ScrollTest.cpp index bf786ea6ca2..5e0aa4e86e5 100644 --- a/src/cascadia/UnitTests_TerminalCore/ScrollTest.cpp +++ b/src/cascadia/UnitTests_TerminalCore/ScrollTest.cpp @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -#include "precomp.h" +#include "pch.h" #include #include @@ -16,7 +16,7 @@ #include "consoletaeftemplates.hpp" #include "TestUtils.h" -using namespace winrt::Microsoft::Terminal::Settings; +using namespace winrt::Microsoft::Terminal::TerminalControl; using namespace Microsoft::Terminal::Core; using namespace ::Microsoft::Console::Types; diff --git a/src/cascadia/UnitTests_TerminalCore/SelectionTest.cpp b/src/cascadia/UnitTests_TerminalCore/SelectionTest.cpp index 39f78b0b41c..325cb073972 100644 --- a/src/cascadia/UnitTests_TerminalCore/SelectionTest.cpp +++ b/src/cascadia/UnitTests_TerminalCore/SelectionTest.cpp @@ -5,7 +5,7 @@ * This File was generated using the VisualTAEF C++ Project Wizard. * Class Name: SelectionTest */ -#include "precomp.h" +#include "pch.h" #include #include "../cascadia/TerminalCore/Terminal.hpp" @@ -17,7 +17,7 @@ using namespace WEX::Logging; using namespace WEX::TestExecution; using namespace Microsoft::Terminal::Core; -using namespace winrt::Microsoft::Terminal::Settings; +using namespace winrt::Microsoft::Terminal::TerminalControl; namespace TerminalCoreUnitTests { diff --git a/src/cascadia/UnitTests_TerminalCore/TerminalApiTest.cpp b/src/cascadia/UnitTests_TerminalCore/TerminalApiTest.cpp index b236765bb43..c3c4d1bcdd9 100644 --- a/src/cascadia/UnitTests_TerminalCore/TerminalApiTest.cpp +++ b/src/cascadia/UnitTests_TerminalCore/TerminalApiTest.cpp @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -#include "precomp.h" +#include "pch.h" #include #include "../cascadia/TerminalCore/Terminal.hpp" @@ -9,7 +9,7 @@ #include "../renderer/inc/DummyRenderTarget.hpp" #include "consoletaeftemplates.hpp" -using namespace winrt::Microsoft::Terminal::Settings; +using namespace winrt::Microsoft::Terminal::TerminalControl; using namespace Microsoft::Terminal::Core; using namespace WEX::Logging; diff --git a/src/cascadia/UnitTests_TerminalCore/TerminalBufferTests.cpp b/src/cascadia/UnitTests_TerminalCore/TerminalBufferTests.cpp index c3bca20d903..5fbc2d7403d 100644 --- a/src/cascadia/UnitTests_TerminalCore/TerminalBufferTests.cpp +++ b/src/cascadia/UnitTests_TerminalCore/TerminalBufferTests.cpp @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -#include "precomp.h" +#include "pch.h" #include #include "../renderer/inc/DummyRenderTarget.hpp" @@ -10,7 +10,7 @@ #include "consoletaeftemplates.hpp" #include "TestUtils.h" -using namespace winrt::Microsoft::Terminal::Settings; +using namespace winrt::Microsoft::Terminal::TerminalControl; using namespace Microsoft::Terminal::Core; using namespace WEX::Common; diff --git a/src/cascadia/UnitTests_TerminalCore/UnitTests.vcxproj b/src/cascadia/UnitTests_TerminalCore/UnitTests.vcxproj index 48734244141..59a1b747b3e 100644 --- a/src/cascadia/UnitTests_TerminalCore/UnitTests.vcxproj +++ b/src/cascadia/UnitTests_TerminalCore/UnitTests.vcxproj @@ -7,14 +7,15 @@ UnitTests_TerminalCore Terminal.Core.Unit.Tests DynamicLibrary + false - + - + Create @@ -83,18 +84,18 @@ - + - ..;$(SolutionDir)src\inc;$(SolutionDir)src\inc\test;$(WinRT_IncludePath)\..\cppwinrt\winrt;"$(OpenConsoleDir)\src\cascadia\TerminalSettings\Generated Files";$(OpenConsoleDir)\src\host;%(AdditionalIncludeDirectories) - precomp.h + ..;$(SolutionDir)src\inc;$(SolutionDir)src\inc\test;$(WinRT_IncludePath)\..\cppwinrt\winrt;"$(OpenConsoleDir)\src\cascadia\TerminalControl\Generated Files";$(OpenConsoleDir)\src\host;%(AdditionalIncludeDirectories) + pch.h WindowsApp.lib;%(AdditionalDependencies) - + diff --git a/src/cascadia/TerminalSettings/pch.cpp b/src/cascadia/UnitTests_TerminalCore/pch.cpp similarity index 100% rename from src/cascadia/TerminalSettings/pch.cpp rename to src/cascadia/UnitTests_TerminalCore/pch.cpp diff --git a/src/cascadia/UnitTests_TerminalCore/precomp.h b/src/cascadia/UnitTests_TerminalCore/pch.h similarity index 95% rename from src/cascadia/UnitTests_TerminalCore/precomp.h rename to src/cascadia/UnitTests_TerminalCore/pch.h index 53dbb752420..b63aeadb8a0 100644 --- a/src/cascadia/UnitTests_TerminalCore/precomp.h +++ b/src/cascadia/UnitTests_TerminalCore/pch.h @@ -3,7 +3,7 @@ Copyright (c) Microsoft Corporation Licensed under the MIT license. Module Name: -- precomp.h +- pch.h Abstract: - Contains external headers to include in the precompile phase of console build diff --git a/src/cascadia/UnitTests_TerminalCore/precomp.cpp b/src/cascadia/UnitTests_TerminalCore/precomp.cpp deleted file mode 100644 index 6a6fa8e5af1..00000000000 --- a/src/cascadia/UnitTests_TerminalCore/precomp.cpp +++ /dev/null @@ -1,4 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. - -#include "precomp.h" \ No newline at end of file diff --git a/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj b/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj index 782d9703990..b940f569e23 100644 --- a/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj +++ b/src/cascadia/WindowsTerminal/WindowsTerminal.vcxproj @@ -33,12 +33,6 @@ $(OpenConsoleDir)\src\inc;$(OpenConsoleDir)\dep;$(OpenConsoleDir)\dep\Console;$(OpenConsoleDir)\dep\Win32K;$(OpenConsoleDir)\dep\gsl\include;%(AdditionalIncludeDirectories); - - - "$(OpenConsoleDir)src\cascadia\TerminalCore\lib\Generated Files";%(AdditionalIncludeDirectories); - gdi32.lib;dwmapi.lib;Shcore.lib;UxTheme.lib;%(AdditionalDependencies) @@ -78,7 +72,6 @@ - diff --git a/src/cascadia/WindowsTerminalUniversal/WindowsTerminalUniversal.vcxproj b/src/cascadia/WindowsTerminalUniversal/WindowsTerminalUniversal.vcxproj index 84e99be6046..f001359816c 100644 --- a/src/cascadia/WindowsTerminalUniversal/WindowsTerminalUniversal.vcxproj +++ b/src/cascadia/WindowsTerminalUniversal/WindowsTerminalUniversal.vcxproj @@ -89,12 +89,6 @@ $(OpenConsoleDir)\src\inc;$(OpenConsoleDir)\dep;$(OpenConsoleDir)\dep\Console;$(OpenConsoleDir)\dep\Win32K;$(OpenConsoleDir)\dep\gsl\include;$(OpenConsoleDir)\dep\wil\include;$(SolutionDir)\oss\chromium;$(SolutionDir)\oss\fmt\include;$(SolutionDir)\oss\dynamic_bitset;$(SolutionDir)\oss\libpopcnt;%(AdditionalIncludeDirectories); - - - "$(OpenConsoleDir)src\cascadia\TerminalCore\lib\Generated Files";"$(OpenConsoleDir)src\cascadia\TerminalApp\lib\Generated Files";%(AdditionalIncludeDirectories); - gdi32.lib;dwmapi.lib;Shcore.lib;%(AdditionalDependencies) @@ -149,7 +143,6 @@ - diff --git a/src/cascadia/ut_app/JsonTests.cpp b/src/cascadia/ut_app/JsonTests.cpp index 1afbeaeddff..f18579b1d0d 100644 --- a/src/cascadia/ut_app/JsonTests.cpp +++ b/src/cascadia/ut_app/JsonTests.cpp @@ -14,7 +14,7 @@ using namespace WEX::Logging; using namespace WEX::TestExecution; using namespace WEX::Common; using namespace winrt::TerminalApp; -using namespace winrt::Microsoft::Terminal::Settings; +using namespace winrt::Microsoft::Terminal::TerminalControl; namespace TerminalAppUnitTests { diff --git a/src/cppwinrt.build.pre.props b/src/cppwinrt.build.pre.props index c7ac9550f61..835797a2d6b 100644 --- a/src/cppwinrt.build.pre.props +++ b/src/cppwinrt.build.pre.props @@ -97,7 +97,7 @@ _WINRT_DLL;%(PreprocessorDefinitions) - $(ProjectName).def + $(ProjectName).def diff --git a/src/inc/test/CommonState.hpp b/src/inc/test/CommonState.hpp index b493babe4e4..2a4ddeab47e 100644 --- a/src/inc/test/CommonState.hpp +++ b/src/inc/test/CommonState.hpp @@ -303,7 +303,7 @@ class CommonState const CONSOLE_INFORMATION& gci = Microsoft::Console::Interactivity::ServiceLocator::LocateGlobals().getConsoleInformation(); // length 80 string of text with bisecting characters at the beginning and end. // positions of き(\x304d) are at 0, 27-28, 39-40, 67-68, 79 - PWCHAR pwszText = + auto pwszText = L"\x304d" L"ABCDEFGHIJKLMNOPQRSTUVWXYZ" L"\x304d\x304d" From 60b44c856ef0d1a95d6611c5be53d0f7efd6166b Mon Sep 17 00:00:00 2001 From: Moshe Schorr Date: Fri, 7 Aug 2020 22:04:53 +0300 Subject: [PATCH 028/266] Batch RTL runs to ensure proper draw order (#7190) Consecutive RTL GlyphRuns are drawn from the last to the first. References #538, #7149, all those issues asking for RTL closed as dupes. As @miniksa suggested in a comment on #7149 -- handle the thingy on the render side. If we have GlyphRuns abcdEFGh, where EFG are RTL, we draw them now in order abcdGFEh. This has ransom-noting, because I didn't touch the font scaling at all. This should fix the majority of RTL issues, except it *doesn't* fix issues with colors, because those get split in the TextBuffer phase in the renderer I think, so they show up separately by the GlyphRun phase. --- ...1ff90dc512c83c902762b02f284c1c61603b4a.txt | 10 ++ .github/actions/spell-check/expect/expect.txt | 33 ----- src/renderer/dx/CustomTextLayout.cpp | 140 ++++++++++++------ src/renderer/dx/CustomTextLayout.h | 4 + 4 files changed, 112 insertions(+), 75 deletions(-) create mode 100644 .github/actions/spell-check/expect/af1ff90dc512c83c902762b02f284c1c61603b4a.txt diff --git a/.github/actions/spell-check/expect/af1ff90dc512c83c902762b02f284c1c61603b4a.txt b/.github/actions/spell-check/expect/af1ff90dc512c83c902762b02f284c1c61603b4a.txt new file mode 100644 index 00000000000..66fb99de72d --- /dev/null +++ b/.github/actions/spell-check/expect/af1ff90dc512c83c902762b02f284c1c61603b4a.txt @@ -0,0 +1,10 @@ +abcd +dst +EFG +EFGh +EMPTYBOX +GFEh +nrcs +Remoting +Scs +Shobjidl diff --git a/.github/actions/spell-check/expect/expect.txt b/.github/actions/spell-check/expect/expect.txt index 01b64c42d78..5a74915444a 100644 --- a/.github/actions/spell-check/expect/expect.txt +++ b/.github/actions/spell-check/expect/expect.txt @@ -99,7 +99,6 @@ AStomps ASYNCWINDOWPOS atch ATest -atg attr ATTRCOLOR aumid @@ -160,7 +159,6 @@ bitsavers bitset BKCOLOR BKGND -BKMK Bksp blog Blt @@ -295,7 +293,6 @@ codepage codepoint codeproject COINIT -colo colorizing colororacle colorref @@ -352,7 +349,6 @@ conpty conptylib consecteturadipiscingelit conserv -consoleaccessibility consoleapi CONSOLECONTROL CONSOLEENDTASK @@ -640,7 +636,6 @@ DROPDOWNLIST DROPFILES drv dsm -Dst DSwap DTest dtor @@ -683,7 +678,6 @@ Elems elif elseif emacs -emptybox enabledelayedexpansion endian endif @@ -752,7 +746,6 @@ fdw fea fesb FFDE -FFF FFrom FGCOLOR fgetc @@ -769,7 +762,6 @@ FILETYPE FILEW FILLATTR FILLCONSOLEOUTPUT -Filledbox FILTERONPASTE finalizer FINDCASE @@ -821,7 +813,6 @@ fsproj fstream fte Ftm -fullcolor fullscreen fullwidth func @@ -1011,7 +1002,6 @@ hwheel hwnd HWNDPARENT hxx -hyperlink IAccessibility IAction IApi @@ -1034,7 +1024,6 @@ ICore IData IDCANCEL IDD -IDefault IDesktop IDictionary IDISHWND @@ -1384,7 +1373,6 @@ mincore mindbogglingly mingw minkernel -minmax minwin minwindef Mip @@ -1545,7 +1533,6 @@ NOYIELD NOZORDER NPM npos -NRCS NSTATUS ntapi ntcon @@ -1722,7 +1709,6 @@ pguid pgup PHANDLE phhook -phsl phwnd pid pidl @@ -1752,7 +1738,6 @@ POBJECT Podcast POINTSLIST POLYTEXTW -popclip popd POPF poppack @@ -1935,7 +1920,6 @@ REGSTR reingest Relayout RELBINPATH -remoting renderengine rendersize reparent @@ -1943,7 +1927,6 @@ reparenting replatformed Replymessage repositorypath -rerendered rescap Resequence Reserialize @@ -1989,7 +1972,6 @@ RMENU roadmap robomac roundtrip -ROWSTOSCROLL rparen RRF RRRGGGBB @@ -2051,7 +2033,6 @@ SCROLLSCALE SCROLLSCREENBUFFER Scrollup Scrolluppage -SCS scursor sddl sdeleted @@ -2121,7 +2102,6 @@ Shl shlguid shlobj shlwapi -shobjidl SHORTPATH SHOWCURSOR SHOWMAXIMIZED @@ -2194,14 +2174,11 @@ STARTWPARMSW Statusline stdafx STDAPI -stdarg stdcall -stddef stderr stdexcept stdin stdio -stdlib STDMETHODCALLTYPE STDMETHODIMP stdout @@ -2295,7 +2272,6 @@ telnetd telnetpp templated terminalcore -terminalnuget TERMINALSCROLLING terminfo TEs @@ -2351,7 +2327,6 @@ TMult tmultiple tmux todo -Tofill tofrom tokenhelpers tokenized @@ -2447,7 +2422,6 @@ undef Unescape unexpand Unfocus -unfocuses unhighlighting unhosted unicode @@ -2753,33 +2727,26 @@ WWith wx wxh xa -xab xact xamarin xaml Xamlmeta xargs xaz -xb -xbc xbf xbutton XBUTTONDBLCLK XBUTTONDOWN XBUTTONUP -xca XCast -xce XCENTER XColors xcopy XCount -xdd xdy xe XEncoding xff -xffff XFile xlang XManifest diff --git a/src/renderer/dx/CustomTextLayout.cpp b/src/renderer/dx/CustomTextLayout.cpp index c9f30c039a7..43b491cb54e 100644 --- a/src/renderer/dx/CustomTextLayout.cpp +++ b/src/renderer/dx/CustomTextLayout.cpp @@ -847,57 +847,113 @@ CATCH_RETURN(); auto mutableOrigin = origin; // Draw each run separately. - for (UINT32 runIndex = 0; runIndex < _runs.size(); ++runIndex) + for (INT32 runIndex = 0; runIndex < gsl::narrow(_runs.size()); ++runIndex) { // Get the run const Run& run = _runs.at(runIndex); - // Prepare the glyph run and description objects by converting our - // internal storage representation into something that matches DWrite's structures. - DWRITE_GLYPH_RUN glyphRun; - glyphRun.bidiLevel = run.bidiLevel; - glyphRun.fontEmSize = _format->GetFontSize() * run.fontScale; - glyphRun.fontFace = run.fontFace.Get(); - glyphRun.glyphAdvances = &_glyphAdvances.at(run.glyphStart); - glyphRun.glyphCount = run.glyphCount; - glyphRun.glyphIndices = &_glyphIndices.at(run.glyphStart); - glyphRun.glyphOffsets = &_glyphOffsets.at(run.glyphStart); - glyphRun.isSideways = false; - - DWRITE_GLYPH_RUN_DESCRIPTION glyphRunDescription; - glyphRunDescription.clusterMap = _glyphClusters.data(); - glyphRunDescription.localeName = _localeName.data(); - glyphRunDescription.string = _text.data(); - glyphRunDescription.stringLength = run.textLength; - glyphRunDescription.textPosition = run.textStart; - - // Calculate the origin for the next run based on the amount of space - // that would be consumed. We are doing this calculation now, not after, - // because if the text is RTL then we need to advance immediately, before the - // write call since DirectX expects the origin to the RIGHT of the text for RTL. - const auto postOriginX = std::accumulate(_glyphAdvances.begin() + run.glyphStart, - _glyphAdvances.begin() + run.glyphStart + run.glyphCount, - mutableOrigin.x); - - // Check for RTL, if it is, apply space adjustment. - if (WI_IsFlagSet(glyphRun.bidiLevel, 1)) + if (!WI_IsFlagSet(run.bidiLevel, 1)) { - mutableOrigin.x = postOriginX; + RETURN_IF_FAILED(_DrawGlyphRun(clientDrawingContext, renderer, mutableOrigin, run)); } + // This is the RTL behavior. We will advance to the last contiguous RTL run, draw that, + // and then keep on going backwards from there, and then move runIndex beyond. + // Let's say we have runs abcdEFGh, where runs EFG are RTL. + // Then we will draw them in the order abcdGFEh + else + { + const INT32 originalRunIndex = runIndex; + INT32 lastIndexRTL = runIndex; + + // Step 1: Get to the last contiguous RTL run from here + while (lastIndexRTL < gsl::narrow(_runs.size()) - 1) // only could ever advance if there's something left + { + const Run& nextRun = _runs.at(gsl::narrow_cast(lastIndexRTL + 1)); + if (WI_IsFlagSet(nextRun.bidiLevel, 1)) + { + lastIndexRTL++; + } + else + { + break; + } + } + + // Go from the last to the first and draw + for (runIndex = lastIndexRTL; runIndex >= originalRunIndex; runIndex--) + { + const Run& currentRun = _runs.at(runIndex); + RETURN_IF_FAILED(_DrawGlyphRun(clientDrawingContext, renderer, mutableOrigin, currentRun)); + } + runIndex = lastIndexRTL; // and the for loop will take the increment to the last one + } + } + } + CATCH_RETURN(); + return S_OK; +} - // Try to draw it - RETURN_IF_FAILED(renderer->DrawGlyphRun(clientDrawingContext, - mutableOrigin.x, - mutableOrigin.y, - DWRITE_MEASURING_MODE_NATURAL, - &glyphRun, - &glyphRunDescription, - run.drawingEffect.Get())); - - // Either way, we should be at this point by the end of writing this sequence, - // whether it was LTR or RTL. +// Routine Description: +// - Draw the given run +// - The origin is updated to be after the run. +// Arguments: +// - clientDrawingContext - Optional pointer to information that the renderer might need +// while attempting to graphically place the text onto the screen +// - renderer - The interface to be used for actually putting text onto the screen +// - origin - pixel point of top left corner on final surface for drawing +// - run - the run to be drawn +[[nodiscard]] HRESULT CustomTextLayout::_DrawGlyphRun(_In_opt_ void* clientDrawingContext, + gsl::not_null renderer, + D2D_POINT_2F& mutableOrigin, + const Run& run) noexcept +{ + try + { + // Prepare the glyph run and description objects by converting our + // internal storage representation into something that matches DWrite's structures. + DWRITE_GLYPH_RUN glyphRun; + glyphRun.bidiLevel = run.bidiLevel; + glyphRun.fontEmSize = _format->GetFontSize() * run.fontScale; + glyphRun.fontFace = run.fontFace.Get(); + glyphRun.glyphAdvances = &_glyphAdvances.at(run.glyphStart); + glyphRun.glyphCount = run.glyphCount; + glyphRun.glyphIndices = &_glyphIndices.at(run.glyphStart); + glyphRun.glyphOffsets = &_glyphOffsets.at(run.glyphStart); + glyphRun.isSideways = false; + + DWRITE_GLYPH_RUN_DESCRIPTION glyphRunDescription; + glyphRunDescription.clusterMap = _glyphClusters.data(); + glyphRunDescription.localeName = _localeName.data(); + glyphRunDescription.string = _text.data(); + glyphRunDescription.stringLength = run.textLength; + glyphRunDescription.textPosition = run.textStart; + + // Calculate the origin for the next run based on the amount of space + // that would be consumed. We are doing this calculation now, not after, + // because if the text is RTL then we need to advance immediately, before the + // write call since DirectX expects the origin to the RIGHT of the text for RTL. + const auto postOriginX = std::accumulate(_glyphAdvances.begin() + run.glyphStart, + _glyphAdvances.begin() + run.glyphStart + run.glyphCount, + mutableOrigin.x); + + // Check for RTL, if it is, apply space adjustment. + if (WI_IsFlagSet(glyphRun.bidiLevel, 1)) + { mutableOrigin.x = postOriginX; } + + // Try to draw it + RETURN_IF_FAILED(renderer->DrawGlyphRun(clientDrawingContext, + mutableOrigin.x, + mutableOrigin.y, + DWRITE_MEASURING_MODE_NATURAL, + &glyphRun, + &glyphRunDescription, + run.drawingEffect.Get())); + + // Either way, we should be at this point by the end of writing this sequence, + // whether it was LTR or RTL. + mutableOrigin.x = postOriginX; } CATCH_RETURN(); return S_OK; diff --git a/src/renderer/dx/CustomTextLayout.h b/src/renderer/dx/CustomTextLayout.h index cf2a63b574b..fe197425794 100644 --- a/src/renderer/dx/CustomTextLayout.h +++ b/src/renderer/dx/CustomTextLayout.h @@ -147,6 +147,10 @@ namespace Microsoft::Console::Render [[nodiscard]] HRESULT _DrawGlyphRuns(_In_opt_ void* clientDrawingContext, IDWriteTextRenderer* renderer, const D2D_POINT_2F origin) noexcept; + [[nodiscard]] HRESULT _DrawGlyphRun(_In_opt_ void* clientDrawingContext, + gsl::not_null renderer, + D2D_POINT_2F& mutableOrigin, + const Run& run) noexcept; [[nodiscard]] static constexpr UINT32 _EstimateGlyphCount(const UINT32 textLength) noexcept; From 4e0f31337d9514ba4743c3ab195715ef50e3c83d Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Fri, 7 Aug 2020 18:07:42 -0500 Subject: [PATCH 029/266] Add support for per-profile tab colors (#7162) This PR adds support for per-profile tab colors, in accordance with #7134. This adds a single `tabColor` property, that when set, specifies the background color for profile's tab. This color can be overridden by the color picker, and clearing the color with the color picker will revert to this default color set for the tab. * Full theming is covered in #3327 & #5772 Validation: Played with setting this color, both on launch and via hot-reload Specified in #7134 Closes #1337 --- .../TerminalApp/AppActionHandlers.cpp | 4 +- src/cascadia/TerminalApp/CascadiaSettings.cpp | 4 +- src/cascadia/TerminalApp/Profile.cpp | 9 + src/cascadia/TerminalApp/Profile.h | 1 + src/cascadia/TerminalApp/Tab.cpp | 225 ++++++++++++------ src/cascadia/TerminalApp/Tab.h | 11 +- src/cascadia/TerminalApp/TerminalPage.cpp | 11 - src/cascadia/TerminalApp/TerminalSettings.h | 2 + src/cascadia/TerminalControl/TermControl.cpp | 13 + src/cascadia/TerminalControl/TermControl.h | 4 + src/cascadia/TerminalControl/TermControl.idl | 3 + src/cascadia/TerminalCore/ICoreSettings.idl | 2 + src/cascadia/TerminalCore/Terminal.cpp | 23 ++ src/cascadia/TerminalCore/Terminal.hpp | 5 + src/cascadia/TerminalCore/pch.h | 1 + .../ConptyRoundtripTests.cpp | 2 - .../UnitTests_TerminalCore/MockTermSettings.h | 3 + src/cascadia/UnitTests_TerminalCore/pch.h | 53 +++-- src/inc/test/CommonState.hpp | 1 - src/inc/til.h | 1 + src/inc/til/coalesce.h | 61 +++++ src/til/ut_til/CoalesceTests.cpp | 84 +++++++ src/til/ut_til/til.unit.tests.vcxproj | 3 +- src/types/inc/utils.hpp | 28 --- 24 files changed, 408 insertions(+), 146 deletions(-) create mode 100644 src/inc/til/coalesce.h create mode 100644 src/til/ut_til/CoalesceTests.cpp diff --git a/src/cascadia/TerminalApp/AppActionHandlers.cpp b/src/cascadia/TerminalApp/AppActionHandlers.cpp index 5d260ef94c4..71bea71051f 100644 --- a/src/cascadia/TerminalApp/AppActionHandlers.cpp +++ b/src/cascadia/TerminalApp/AppActionHandlers.cpp @@ -289,11 +289,11 @@ namespace winrt::TerminalApp::implementation { if (tabColor.has_value()) { - activeTab->SetTabColor(tabColor.value()); + activeTab->SetRuntimeTabColor(tabColor.value()); } else { - activeTab->ResetTabColor(); + activeTab->ResetRuntimeTabColor(); } } args.Handled(true); diff --git a/src/cascadia/TerminalApp/CascadiaSettings.cpp b/src/cascadia/TerminalApp/CascadiaSettings.cpp index 29c8d750d02..1206437256f 100644 --- a/src/cascadia/TerminalApp/CascadiaSettings.cpp +++ b/src/cascadia/TerminalApp/CascadiaSettings.cpp @@ -226,7 +226,7 @@ void CascadiaSettings::_ResolveDefaultProfile() { const auto unparsedDefaultProfile{ GlobalSettings().UnparsedDefaultProfile() }; auto maybeParsedDefaultProfile{ _GetProfileGuidByName(unparsedDefaultProfile) }; - auto defaultProfileGuid{ Utils::CoalesceOptionals(maybeParsedDefaultProfile, GUID{}) }; + auto defaultProfileGuid{ til::coalesce_value(maybeParsedDefaultProfile, GUID{}) }; GlobalSettings().DefaultProfile(defaultProfileGuid); } @@ -565,7 +565,7 @@ GUID CascadiaSettings::_GetProfileForArgs(const NewTerminalArgs& newTerminalArgs profileByName = _GetProfileGuidByName(newTerminalArgs.Profile()); } - return Utils::CoalesceOptionals(profileByName, profileByIndex, _globals.DefaultProfile()); + return til::coalesce_value(profileByName, profileByIndex, _globals.DefaultProfile()); } // Method Description: diff --git a/src/cascadia/TerminalApp/Profile.cpp b/src/cascadia/TerminalApp/Profile.cpp index 9829474297a..22e627ad896 100644 --- a/src/cascadia/TerminalApp/Profile.cpp +++ b/src/cascadia/TerminalApp/Profile.cpp @@ -53,6 +53,7 @@ static constexpr std::string_view BackgroundImageStretchModeKey{ "backgroundImag static constexpr std::string_view BackgroundImageAlignmentKey{ "backgroundImageAlignment" }; static constexpr std::string_view RetroTerminalEffectKey{ "experimental.retroTerminalEffect" }; static constexpr std::string_view AntialiasingModeKey{ "antialiasingMode" }; +static constexpr std::string_view TabColorKey{ "tabColor" }; Profile::Profile() : Profile(std::nullopt) @@ -232,6 +233,12 @@ TerminalSettings Profile::CreateTerminalSettings(const std::unordered_map colorRef{ _tabColor.value() }; + terminalSettings.TabColor(colorRef); + } + return terminalSettings; } @@ -405,6 +412,8 @@ void Profile::LayerJson(const Json::Value& json) JsonUtils::GetValueForKey(json, BackgroundImageAlignmentKey, _backgroundImageAlignment); JsonUtils::GetValueForKey(json, RetroTerminalEffectKey, _retroTerminalEffect); JsonUtils::GetValueForKey(json, AntialiasingModeKey, _antialiasingMode); + + JsonUtils::GetValueForKey(json, TabColorKey, _tabColor); } void Profile::SetFontFace(std::wstring fontFace) noexcept diff --git a/src/cascadia/TerminalApp/Profile.h b/src/cascadia/TerminalApp/Profile.h index 422b139883e..a6794bbcc07 100644 --- a/src/cascadia/TerminalApp/Profile.h +++ b/src/cascadia/TerminalApp/Profile.h @@ -117,6 +117,7 @@ class TerminalApp::Profile final std::optional _selectionBackground; std::optional _cursorColor; std::optional _tabTitle; + std::optional _tabColor; bool _suppressApplicationTitle; int32_t _historySize; bool _snapOnInput; diff --git a/src/cascadia/TerminalApp/Tab.cpp b/src/cascadia/TerminalApp/Tab.cpp index 5e7521bbdfe..77e3371104f 100644 --- a/src/cascadia/TerminalApp/Tab.cpp +++ b/src/cascadia/TerminalApp/Tab.cpp @@ -54,6 +54,7 @@ namespace winrt::TerminalApp::implementation }); _UpdateTitle(); + _RecalculateAndApplyTabColor(); } // Method Description: @@ -435,6 +436,16 @@ namespace winrt::TerminalApp::implementation _rootPane->Relayout(); } }); + + control.TabColorChanged([weakThis](auto&&, auto&&) { + if (auto tab{ weakThis.get() }) + { + // The control's tabColor changed, but it is not necessarily the + // active control in this tab. We'll just recalculate the + // current color anyways. + tab->_RecalculateAndApplyTabColor(); + } + }); } // Method Description: @@ -479,6 +490,7 @@ namespace winrt::TerminalApp::implementation if (tab && sender != tab->_activePane) { tab->_UpdateActivePane(sender); + tab->_RecalculateAndApplyTabColor(); } }); } @@ -529,14 +541,14 @@ namespace winrt::TerminalApp::implementation _tabColorPickup.ColorSelected([weakThis](auto newTabColor) { if (auto tab{ weakThis.get() }) { - tab->SetTabColor(newTabColor); + tab->SetRuntimeTabColor(newTabColor); } }); _tabColorPickup.ColorCleared([weakThis]() { if (auto tab{ weakThis.get() }) { - tab->ResetTabColor(); + tab->ResetRuntimeTabColor(); } }); @@ -706,114 +718,179 @@ namespace winrt::TerminalApp::implementation // - The tab's color, if any std::optional Tab::GetTabColor() { - return _tabColor; + const auto currControlColor{ GetActiveTerminalControl().TabColor() }; + std::optional controlTabColor; + if (currControlColor != nullptr) + { + controlTabColor = currControlColor.Value(); + } + + // A Tab's color will be the result of layering a variety of sources, + // from the bottom up: + // + // Color | | Set by + // -------------------- | -- | -- + // Runtime Color | _optional_ | Color Picker / `setTabColor` action + // Control Tab Color | _optional_ | Profile's `tabColor`, or a color set by VT + // Theme Tab Background | _optional_ | `tab.backgroundColor` in the theme + // Tab Default Color | **default** | TabView in XAML + // + // coalesce will get us the first of these values that's + // actually set, with nullopt being our sentinel for "use the default + // tabview color" (and clear out any colors we've set). + + return til::coalesce(_runtimeTabColor, + controlTabColor, + _themeTabColor, + std::optional(std::nullopt)); } // Method Description: - // - Sets the tab background color to the color chosen by the user + // - Sets the runtime tab background color to the color chosen by the user // - Sets the tab foreground color depending on the luminance of // the background color // Arguments: - // - color: the shiny color the user picked for their tab + // - color: the color the user picked for their tab // Return Value: // - - void Tab::SetTabColor(const winrt::Windows::UI::Color& color) + void Tab::SetRuntimeTabColor(const winrt::Windows::UI::Color& color) + { + _runtimeTabColor.emplace(color); + _RecalculateAndApplyTabColor(); + } + + // Method Description: + // - This function dispatches a function to the UI thread to recalculate + // what this tab's current background color should be. If a color is set, + // it will apply the given color to the tab's background. Otherwise, it + // will clear the tab's background color. + // Arguments: + // - + // Return Value: + // - + void Tab::_RecalculateAndApplyTabColor() { auto weakThis{ get_weak() }; - _tabViewItem.Dispatcher().RunAsync(CoreDispatcherPriority::Normal, [weakThis, color]() { + _tabViewItem.Dispatcher().RunAsync(CoreDispatcherPriority::Normal, [weakThis]() { auto ptrTab = weakThis.get(); if (!ptrTab) return; auto tab{ ptrTab }; - Media::SolidColorBrush selectedTabBrush{}; - Media::SolidColorBrush deselectedTabBrush{}; - Media::SolidColorBrush fontBrush{}; - Media::SolidColorBrush hoverTabBrush{}; - // calculate the luminance of the current color and select a font - // color based on that - // see https://www.w3.org/TR/WCAG20/#relativeluminancedef - if (TerminalApp::ColorHelper::IsBrightColor(color)) + + std::optional currentColor = tab->GetTabColor(); + if (currentColor.has_value()) { - fontBrush.Color(winrt::Windows::UI::Colors::Black()); + tab->_ApplyTabColor(currentColor.value()); } else { - fontBrush.Color(winrt::Windows::UI::Colors::White()); + tab->_ClearTabBackgroundColor(); } - - hoverTabBrush.Color(TerminalApp::ColorHelper::GetAccentColor(color)); - selectedTabBrush.Color(color); - - // currently if a tab has a custom color, a deselected state is - // signified by using the same color with a bit ot transparency - auto deselectedTabColor = color; - deselectedTabColor.A = 64; - deselectedTabBrush.Color(deselectedTabColor); - - // currently if a tab has a custom color, a deselected state is - // signified by using the same color with a bit ot transparency - tab->_tabViewItem.Resources().Insert(winrt::box_value(L"TabViewItemHeaderBackgroundSelected"), selectedTabBrush); - tab->_tabViewItem.Resources().Insert(winrt::box_value(L"TabViewItemHeaderBackground"), deselectedTabBrush); - tab->_tabViewItem.Resources().Insert(winrt::box_value(L"TabViewItemHeaderBackgroundPointerOver"), hoverTabBrush); - tab->_tabViewItem.Resources().Insert(winrt::box_value(L"TabViewItemHeaderBackgroundPressed"), selectedTabBrush); - tab->_tabViewItem.Resources().Insert(winrt::box_value(L"TabViewItemHeaderForeground"), fontBrush); - tab->_tabViewItem.Resources().Insert(winrt::box_value(L"TabViewItemHeaderForegroundSelected"), fontBrush); - tab->_tabViewItem.Resources().Insert(winrt::box_value(L"TabViewItemHeaderForegroundPointerOver"), fontBrush); - tab->_tabViewItem.Resources().Insert(winrt::box_value(L"TabViewItemHeaderForegroundPressed"), fontBrush); - tab->_tabViewItem.Resources().Insert(winrt::box_value(L"TabViewButtonForegroundActiveTab"), fontBrush); - - tab->_RefreshVisualState(); - - tab->_tabColor.emplace(color); - tab->_colorSelected(color); }); } // Method Description: - // Clear the custom color of the tab, if any + // - Applies the given color to the background of this tab's TabViewItem. + // - Sets the tab foreground color depending on the luminance of // the background color + // - This method should only be called on the UI thread. + // Arguments: + // - color: the color the user picked for their tab + // Return Value: + // - + void Tab::_ApplyTabColor(const winrt::Windows::UI::Color& color) + { + Media::SolidColorBrush selectedTabBrush{}; + Media::SolidColorBrush deselectedTabBrush{}; + Media::SolidColorBrush fontBrush{}; + Media::SolidColorBrush hoverTabBrush{}; + // calculate the luminance of the current color and select a font + // color based on that + // see https://www.w3.org/TR/WCAG20/#relativeluminancedef + if (TerminalApp::ColorHelper::IsBrightColor(color)) + { + fontBrush.Color(winrt::Windows::UI::Colors::Black()); + } + else + { + fontBrush.Color(winrt::Windows::UI::Colors::White()); + } + + hoverTabBrush.Color(TerminalApp::ColorHelper::GetAccentColor(color)); + selectedTabBrush.Color(color); + + // currently if a tab has a custom color, a deselected state is + // signified by using the same color with a bit ot transparency + auto deselectedTabColor = color; + deselectedTabColor.A = 64; + deselectedTabBrush.Color(deselectedTabColor); + + // currently if a tab has a custom color, a deselected state is + // signified by using the same color with a bit ot transparency + _tabViewItem.Resources().Insert(winrt::box_value(L"TabViewItemHeaderBackgroundSelected"), selectedTabBrush); + _tabViewItem.Resources().Insert(winrt::box_value(L"TabViewItemHeaderBackground"), deselectedTabBrush); + _tabViewItem.Resources().Insert(winrt::box_value(L"TabViewItemHeaderBackgroundPointerOver"), hoverTabBrush); + _tabViewItem.Resources().Insert(winrt::box_value(L"TabViewItemHeaderBackgroundPressed"), selectedTabBrush); + _tabViewItem.Resources().Insert(winrt::box_value(L"TabViewItemHeaderForeground"), fontBrush); + _tabViewItem.Resources().Insert(winrt::box_value(L"TabViewItemHeaderForegroundSelected"), fontBrush); + _tabViewItem.Resources().Insert(winrt::box_value(L"TabViewItemHeaderForegroundPointerOver"), fontBrush); + _tabViewItem.Resources().Insert(winrt::box_value(L"TabViewItemHeaderForegroundPressed"), fontBrush); + _tabViewItem.Resources().Insert(winrt::box_value(L"TabViewButtonForegroundActiveTab"), fontBrush); + + _RefreshVisualState(); + + _colorSelected(color); + } + + // Method Description: + // - Clear the custom runtime color of the tab, if any color is set. This + // will re-apply whatever the tab's base color should be (either the color + // from the control, the theme, or the default tab color.) // Arguments: // - // Return Value: // - - void Tab::ResetTabColor() + void Tab::ResetRuntimeTabColor() { - auto weakThis{ get_weak() }; + _runtimeTabColor.reset(); + _RecalculateAndApplyTabColor(); + } - _tabViewItem.Dispatcher().RunAsync(CoreDispatcherPriority::Normal, [weakThis]() { - auto ptrTab = weakThis.get(); - if (!ptrTab) - return; + // Method Description: + // - Clear out any color we've set for the TabViewItem. + // - This method should only be called on the UI thread. + // Arguments: + // - + // Return Value: + // - + void Tab::_ClearTabBackgroundColor() + { + winrt::hstring keys[] = { + L"TabViewItemHeaderBackground", + L"TabViewItemHeaderBackgroundSelected", + L"TabViewItemHeaderBackgroundPointerOver", + L"TabViewItemHeaderForeground", + L"TabViewItemHeaderForegroundSelected", + L"TabViewItemHeaderForegroundPointerOver", + L"TabViewItemHeaderBackgroundPressed", + L"TabViewItemHeaderForegroundPressed", + L"TabViewButtonForegroundActiveTab" + }; - auto tab{ ptrTab }; - winrt::hstring keys[] = { - L"TabViewItemHeaderBackground", - L"TabViewItemHeaderBackgroundSelected", - L"TabViewItemHeaderBackgroundPointerOver", - L"TabViewItemHeaderForeground", - L"TabViewItemHeaderForegroundSelected", - L"TabViewItemHeaderForegroundPointerOver", - L"TabViewItemHeaderBackgroundPressed", - L"TabViewItemHeaderForegroundPressed", - L"TabViewButtonForegroundActiveTab" - }; - - // simply clear any of the colors in the tab's dict - for (auto keyString : keys) + // simply clear any of the colors in the tab's dict + for (auto keyString : keys) + { + auto key = winrt::box_value(keyString); + if (_tabViewItem.Resources().HasKey(key)) { - auto key = winrt::box_value(keyString); - if (tab->_tabViewItem.Resources().HasKey(key)) - { - tab->_tabViewItem.Resources().Remove(key); - } + _tabViewItem.Resources().Remove(key); } + } - tab->_RefreshVisualState(); - tab->_tabColor.reset(); - tab->_colorCleared(); - }); + _RefreshVisualState(); + _colorCleared(); } // Method Description: diff --git a/src/cascadia/TerminalApp/Tab.h b/src/cascadia/TerminalApp/Tab.h index 055d631c421..a53326b04f6 100644 --- a/src/cascadia/TerminalApp/Tab.h +++ b/src/cascadia/TerminalApp/Tab.h @@ -57,8 +57,8 @@ namespace winrt::TerminalApp::implementation std::optional GetTabColor(); - void SetTabColor(const winrt::Windows::UI::Color& color); - void ResetTabColor(); + void SetRuntimeTabColor(const winrt::Windows::UI::Color& color); + void ResetRuntimeTabColor(); void ActivateColorPicker(); WINRT_CALLBACK(Closed, winrt::Windows::Foundation::EventHandler); @@ -75,7 +75,8 @@ namespace winrt::TerminalApp::implementation std::shared_ptr _activePane{ nullptr }; winrt::hstring _lastIconPath{}; winrt::TerminalApp::ColorPickupFlyout _tabColorPickup{}; - std::optional _tabColor{}; + std::optional _themeTabColor{}; + std::optional _runtimeTabColor{}; bool _focused{ false }; winrt::Microsoft::UI::Xaml::Controls::TabViewItem _tabViewItem{ nullptr }; @@ -102,6 +103,10 @@ namespace winrt::TerminalApp::implementation winrt::fire_and_forget _UpdateTitle(); void _ConstructTabRenameBox(const winrt::hstring& tabText); + void _RecalculateAndApplyTabColor(); + void _ApplyTabColor(const winrt::Windows::UI::Color& color); + void _ClearTabBackgroundColor(); + friend class ::TerminalAppLocalTests::TabTests; }; } diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index b2c859f3218..b19710a8194 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -1818,17 +1818,6 @@ namespace winrt::TerminalApp::implementation // Raise an event that our title changed _titleChangeHandlers(*this, tab->GetActiveTitle()); - - // Raise an event that our titlebar color changed - std::optional color = tab->GetTabColor(); - if (color.has_value()) - { - _SetNonClientAreaColors(color.value()); - } - else - { - _ClearNonClientAreaColors(); - } } CATCH_LOG(); } diff --git a/src/cascadia/TerminalApp/TerminalSettings.h b/src/cascadia/TerminalApp/TerminalSettings.h index e3e2aec0bfc..53a4ab3201d 100644 --- a/src/cascadia/TerminalApp/TerminalSettings.h +++ b/src/cascadia/TerminalApp/TerminalSettings.h @@ -54,6 +54,8 @@ namespace winrt::TerminalApp::implementation GETSET_PROPERTY(hstring, WordDelimiters, DEFAULT_WORD_DELIMITERS); GETSET_PROPERTY(bool, CopyOnSelect, false); + GETSET_PROPERTY(Windows::Foundation::IReference, TabColor, nullptr); + // ------------------------ End of Core Settings ----------------------- GETSET_PROPERTY(hstring, ProfileName); diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index e99e0d2153d..4b7b64a7b15 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -82,6 +82,9 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation auto pfnTitleChanged = std::bind(&TermControl::_TerminalTitleChanged, this, std::placeholders::_1); _terminal->SetTitleChangedCallback(pfnTitleChanged); + auto pfnTabColorChanged = std::bind(&TermControl::_TerminalTabColorChanged, this, std::placeholders::_1); + _terminal->SetTabColorChangedCallback(pfnTabColorChanged); + auto pfnBackgroundColorChanged = std::bind(&TermControl::_BackgroundColorChanged, this, std::placeholders::_1); _terminal->SetBackgroundCallback(pfnBackgroundColorChanged); @@ -2051,6 +2054,10 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation { _titleChangedHandlers(winrt::hstring{ wstr }); } + void TermControl::_TerminalTabColorChanged(const std::optional /*color*/) + { + _TabColorChangedHandlers(*this, nullptr); + } void TermControl::_CopyToClipboard(const std::wstring_view& wstr) { @@ -2821,6 +2828,12 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation _renderer->ResetErrorStateAndResume(); } + Windows::Foundation::IReference TermControl::TabColor() noexcept + { + auto coreColor = _terminal->GetTabColor(); + return coreColor.has_value() ? Windows::Foundation::IReference(coreColor.value()) : nullptr; + } + // -------------------------------- WinRT Events --------------------------------- // Winrt events need a method for adding a callback to the event and removing the callback. // These macros will define them both for you. diff --git a/src/cascadia/TerminalControl/TermControl.h b/src/cascadia/TerminalControl/TermControl.h index ce9a8a49d2d..5b159fea38e 100644 --- a/src/cascadia/TerminalControl/TermControl.h +++ b/src/cascadia/TerminalControl/TermControl.h @@ -107,6 +107,8 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation const winrt::hstring& padding, const uint32_t dpi); + Windows::Foundation::IReference TabColor() noexcept; + // clang-format off // -------------------------------- WinRT Events --------------------------------- DECLARE_EVENT(TitleChanged, _titleChangedHandlers, TerminalControl::TitleChangedEventArgs); @@ -118,6 +120,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation TYPED_EVENT(ConnectionStateChanged, TerminalControl::TermControl, IInspectable); TYPED_EVENT(Initialized, TerminalControl::TermControl, Windows::UI::Xaml::RoutedEventArgs); + TYPED_EVENT(TabColorChanged, IInspectable, IInspectable); // clang-format on private: @@ -219,6 +222,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation void _DoResizeUnderLock(const double newWidth, const double newHeight); void _RefreshSizeUnderLock(); void _TerminalTitleChanged(const std::wstring_view& wstr); + void _TerminalTabColorChanged(const std::optional color); void _CopyToClipboard(const std::wstring_view& wstr); void _TerminalScrollPositionChanged(const int viewTop, const int viewHeight, const int bufferSize); void _TerminalCursorPositionChanged(); diff --git a/src/cascadia/TerminalControl/TermControl.idl b/src/cascadia/TerminalControl/TermControl.idl index e729c38659c..89e4634e968 100644 --- a/src/cascadia/TerminalControl/TermControl.idl +++ b/src/cascadia/TerminalControl/TermControl.idl @@ -70,5 +70,8 @@ namespace Microsoft.Terminal.TerminalControl void ResetFontSize(); void ToggleRetroEffect(); + + Windows.Foundation.IReference TabColor { get; }; + event Windows.Foundation.TypedEventHandler TabColorChanged; } } diff --git a/src/cascadia/TerminalCore/ICoreSettings.idl b/src/cascadia/TerminalCore/ICoreSettings.idl index 99fe24e7930..de11ec04b05 100644 --- a/src/cascadia/TerminalCore/ICoreSettings.idl +++ b/src/cascadia/TerminalCore/ICoreSettings.idl @@ -34,6 +34,8 @@ namespace Microsoft.Terminal.TerminalControl String WordDelimiters; Boolean ForceVTInput; + + Windows.Foundation.IReference TabColor; }; } diff --git a/src/cascadia/TerminalCore/Terminal.cpp b/src/cascadia/TerminalCore/Terminal.cpp index 6d4a4208567..f4a847cc884 100644 --- a/src/cascadia/TerminalCore/Terminal.cpp +++ b/src/cascadia/TerminalCore/Terminal.cpp @@ -147,6 +147,19 @@ void Terminal::UpdateSettings(ICoreSettings settings) _terminalInput->ForceDisableWin32InputMode(settings.ForceVTInput()); + if (settings.TabColor() == nullptr) + { + _tabColor = std::nullopt; + } + else + { + _tabColor = til::color(settings.TabColor().Value() | 0xff000000); + } + if (_pfnTabColorChanged) + { + _pfnTabColorChanged(_tabColor); + } + // TODO:MSFT:21327402 - if HistorySize has changed, resize the buffer so we // have a smaller scrollback. We should do this carefully - if the new buffer // size is smaller than where the mutable viewport currently is, we'll want @@ -913,6 +926,11 @@ void Terminal::SetTitleChangedCallback(std::function)> pfn) noexcept +{ + _pfnTabColorChanged.swap(pfn); +} + void Terminal::SetCopyToClipboardCallback(std::function pfn) noexcept { _pfnCopyToClipboard.swap(pfn); @@ -969,3 +987,8 @@ bool Terminal::IsCursorBlinkingAllowed() const noexcept const auto& cursor = _buffer->GetCursor(); return cursor.IsBlinkingAllowed(); } + +const std::optional Terminal::GetTabColor() const noexcept +{ + return _tabColor; +} diff --git a/src/cascadia/TerminalCore/Terminal.hpp b/src/cascadia/TerminalCore/Terminal.hpp index 351b7c7f8a5..78e0ead8952 100644 --- a/src/cascadia/TerminalCore/Terminal.hpp +++ b/src/cascadia/TerminalCore/Terminal.hpp @@ -168,6 +168,7 @@ class Microsoft::Terminal::Core::Terminal final : void SetWriteInputCallback(std::function pfn) noexcept; void SetTitleChangedCallback(std::function pfn) noexcept; + void SetTabColorChangedCallback(std::function)> pfn) noexcept; void SetCopyToClipboardCallback(std::function pfn) noexcept; void SetScrollPositionChangedCallback(std::function pfn) noexcept; void SetCursorPositionChangedCallback(std::function pfn) noexcept; @@ -176,6 +177,8 @@ class Microsoft::Terminal::Core::Terminal final : void SetCursorOn(const bool isOn); bool IsCursorBlinkingAllowed() const noexcept; + const std::optional GetTabColor() const noexcept; + #pragma region TextSelection // These methods are defined in TerminalSelection.cpp enum class SelectionExpansionMode @@ -199,12 +202,14 @@ class Microsoft::Terminal::Core::Terminal final : std::function _pfnScrollPositionChanged; std::function _pfnBackgroundColorChanged; std::function _pfnCursorPositionChanged; + std::function)> _pfnTabColorChanged; std::unique_ptr<::Microsoft::Console::VirtualTerminal::StateMachine> _stateMachine; std::unique_ptr<::Microsoft::Console::VirtualTerminal::TerminalInput> _terminalInput; std::optional _title; std::wstring _startingTitle; + std::optional _tabColor; std::array _colorTable; COLORREF _defaultFg; diff --git a/src/cascadia/TerminalCore/pch.h b/src/cascadia/TerminalCore/pch.h index e03399daf91..58fe68df1da 100644 --- a/src/cascadia/TerminalCore/pch.h +++ b/src/cascadia/TerminalCore/pch.h @@ -4,3 +4,4 @@ #pragma once #include +#include "winrt/Windows.Foundation.h" diff --git a/src/cascadia/UnitTests_TerminalCore/ConptyRoundtripTests.cpp b/src/cascadia/UnitTests_TerminalCore/ConptyRoundtripTests.cpp index 95812c957a8..a68aa213db1 100644 --- a/src/cascadia/UnitTests_TerminalCore/ConptyRoundtripTests.cpp +++ b/src/cascadia/UnitTests_TerminalCore/ConptyRoundtripTests.cpp @@ -9,8 +9,6 @@ // output, and then flush the output of the VtEngine straight to the Terminal. #include "pch.h" -#include -#include "../../inc/consoletaeftemplates.hpp" #include "../../types/inc/Viewport.hpp" #include "../../types/inc/convert.hpp" diff --git a/src/cascadia/UnitTests_TerminalCore/MockTermSettings.h b/src/cascadia/UnitTests_TerminalCore/MockTermSettings.h index 8ddc223ee36..1a328c9d015 100644 --- a/src/cascadia/UnitTests_TerminalCore/MockTermSettings.h +++ b/src/cascadia/UnitTests_TerminalCore/MockTermSettings.h @@ -6,6 +6,7 @@ #include "DefaultSettings.h" #include +#include "../inc/cppwinrt_utils.h" using namespace winrt::Microsoft::Terminal::TerminalControl; @@ -63,6 +64,8 @@ namespace TerminalCoreUnitTests // other unimplemented methods void SetColorTableEntry(int32_t /* index */, uint32_t /* value */) {} + GETSET_PROPERTY(winrt::Windows::Foundation::IReference, TabColor, nullptr); + private: int32_t _historySize; int32_t _initialRows; diff --git a/src/cascadia/UnitTests_TerminalCore/pch.h b/src/cascadia/UnitTests_TerminalCore/pch.h index b63aeadb8a0..c33ba50c236 100644 --- a/src/cascadia/UnitTests_TerminalCore/pch.h +++ b/src/cascadia/UnitTests_TerminalCore/pch.h @@ -17,31 +17,40 @@ Author(s): #pragma once -// -// This header and define are needed so that the console host code can build in -// this test binary. - -// Block minwindef.h min/max macros to prevent conflict -#define NOMINMAX - -// This includes a lot of common headers needed by both the host and the propsheet -// including: windows.h, winuser, ntstatus, assert, and the DDK -#include "HostAndPropsheetIncludes.h" -// - +#define BLOCK_TIL // This includes support libraries from the CRT, STL, WIL, and GSL #include "LibraryIncludes.h" - -#ifdef BUILDING_INSIDE_WINIDE -#define DbgRaiseAssertionFailure() __int2c() +// This is inexplicable, but for whatever reason, cppwinrt conflicts with the +// SDK definition of this function, so the only fix is to undef it. +// from WinBase.h +// Windows::UI::Xaml::Media::Animation::IStoryboard::GetCurrentTime +#ifdef GetCurrentTime +#undef GetCurrentTime #endif -#include +#include +#include +#include -// Comment to build against the private SDK. -#define CON_BUILD_PUBLIC +#include +#include "consoletaeftemplates.hpp" -#ifdef CON_BUILD_PUBLIC -#define CON_USERPRIVAPI_INDIRECT -#define CON_DPIAPI_INDIRECT -#endif +#include +#include +#include + +// Manually include til after we include Windows.Foundation to give it winrt superpowers +#include "til.h" + +// +// These are needed because the roundtrip tests included in this library also +// re-use some conhost code that depends on these. + +#include "conddkrefs.h" +// From ntdef.h, but that can't be included or it'll fight over PROBE_ALIGNMENT and other such arch specific defs +typedef _Return_type_success_(return >= 0) LONG NTSTATUS; +/*lint -save -e624 */ // Don't complain about different typedefs. +typedef NTSTATUS* PNTSTATUS; +/*lint -restore */ // Resume checking for different typedefs. +#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0) +// diff --git a/src/inc/test/CommonState.hpp b/src/inc/test/CommonState.hpp index 2a4ddeab47e..03abae9a221 100644 --- a/src/inc/test/CommonState.hpp +++ b/src/inc/test/CommonState.hpp @@ -22,7 +22,6 @@ unit testing projects in the codebase without a bunch of overhead. #define VERIFY_SUCCESS_NTSTATUS(x) VERIFY_IS_TRUE(NT_SUCCESS(x)) -#include "precomp.h" #include "../host/globals.h" #include "../host/inputReadHandleData.h" #include "../buffer/out/CharRow.hpp" diff --git a/src/inc/til.h b/src/inc/til.h index e9504535708..36e10ad0e6f 100644 --- a/src/inc/til.h +++ b/src/inc/til.h @@ -16,6 +16,7 @@ #include "til/bitmap.h" #include "til/u8u16convert.h" #include "til/spsc.h" +#include "til/coalesce.h" namespace til // Terminal Implementation Library. Also: "Today I Learned" { diff --git a/src/inc/til/coalesce.h b/src/inc/til/coalesce.h new file mode 100644 index 00000000000..24153869a67 --- /dev/null +++ b/src/inc/til/coalesce.h @@ -0,0 +1,61 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +#pragma once + +namespace til +{ + // Method Description: + // - Base case provided to handle the last argument to coalesce_value() + template + T coalesce_value(const T& base) + { + return base; + } + + // Method Description: + // - Base case provided to throw an assertion if you call coalesce_value(opt, opt, opt) + template + T coalesce_value(const std::optional& base) + { + static_assert(false, "coalesce_value must be passed a base non-optional value to be used if all optionals are empty"); + return T{}; + } + + // Method Description: + // - Returns the value from the first populated optional, or a base value if none were populated. + template + T coalesce_value(const std::optional& t1, Ts&&... t2) + { + // Initially, I wanted to check "has_value" and short-circuit out so that we didn't + // evaluate value_or for every single optional, but has_value/value emits exception handling + // code that value_or doesn't. Less exception handling is cheaper than calling value_or a + // few more times. + return t1.value_or(coalesce_value(std::forward(t2)...)); + } + + // Method Description: + // - Base case provided to handle the last argument to coalesce_value() + template + std::optional coalesce(const std::optional& base) + { + return base; + } + + // Method Description: + // - Base case provided to handle the last argument to coalesce_value(..., nullopt) + template + std::optional coalesce(const std::nullopt_t& base) + { + return base; + } + + // Method Description: + // - Returns the value from the first populated optional, or the last one (if none of the previous had a value) + template + std::optional coalesce(const std::optional& t1, Ts&&... t2) + { + return t1.has_value() ? t1 : coalesce(std::forward(t2)...); + } + +} diff --git a/src/til/ut_til/CoalesceTests.cpp b/src/til/ut_til/CoalesceTests.cpp new file mode 100644 index 00000000000..76c2e9c31ab --- /dev/null +++ b/src/til/ut_til/CoalesceTests.cpp @@ -0,0 +1,84 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +#include "precomp.h" +#include "WexTestClass.h" + +using namespace WEX::Common; +using namespace WEX::Logging; +using namespace WEX::TestExecution; + +class CoalesceTests +{ + TEST_CLASS(CoalesceTests); + + TEST_METHOD(CoalesceFirstValue); + TEST_METHOD(CoalesceMiddleValue); + TEST_METHOD(CoalesceDefaultValue); + + TEST_METHOD(CoalesceOrNotFirstValue); + TEST_METHOD(CoalesceOrNotMiddleValue); + TEST_METHOD(CoalesceOrNotDefaultValue); + TEST_METHOD(CoalesceOrNotDefaultIsNullopt); +}; + +void CoalesceTests::CoalesceFirstValue() +{ + int result = til::coalesce_value(std::optional(1), + std::optional(2), + std::optional(3), + 4); + VERIFY_ARE_EQUAL(1, result); +} +void CoalesceTests::CoalesceMiddleValue() +{ + int result = til::coalesce_value(std::optional(std::nullopt), + std::optional(2), + std::optional(3), + 4); + VERIFY_ARE_EQUAL(2, result); +} +void CoalesceTests::CoalesceDefaultValue() +{ + int result = til::coalesce_value(std::optional(std::nullopt), + std::optional(std::nullopt), + std::optional(std::nullopt), + 4); + VERIFY_ARE_EQUAL(4, result); +} + +void CoalesceTests::CoalesceOrNotFirstValue() +{ + std::optional result = til::coalesce(std::optional(1), + std::optional(2), + std::optional(3), + std::optional(4)); + VERIFY_IS_TRUE(result.has_value()); + VERIFY_ARE_EQUAL(1, result.value()); +} +void CoalesceTests::CoalesceOrNotMiddleValue() +{ + std::optional result = til::coalesce(std::optional(std::nullopt), + std::optional(2), + std::optional(3), + std::optional(4)); + VERIFY_IS_TRUE(result.has_value()); + VERIFY_ARE_EQUAL(2, result.value()); +} +void CoalesceTests::CoalesceOrNotDefaultValue() +{ + std::optional result = til::coalesce(std::optional(std::nullopt), + std::optional(std::nullopt), + std::optional(std::nullopt), + std::optional(4)); + VERIFY_IS_TRUE(result.has_value()); + VERIFY_ARE_EQUAL(4, result.value()); +} +void CoalesceTests::CoalesceOrNotDefaultIsNullopt() +{ + std::optional result = til::coalesce(std::optional(std::nullopt), + std::optional(std::nullopt), + std::optional(std::nullopt), + std::optional(std::nullopt)); + VERIFY_IS_FALSE(result.has_value()); +} diff --git a/src/til/ut_til/til.unit.tests.vcxproj b/src/til/ut_til/til.unit.tests.vcxproj index 82b7908bb7c..52a07246b81 100644 --- a/src/til/ut_til/til.unit.tests.vcxproj +++ b/src/til/ut_til/til.unit.tests.vcxproj @@ -18,6 +18,7 @@ + Create @@ -36,4 +37,4 @@ - \ No newline at end of file + diff --git a/src/types/inc/utils.hpp b/src/types/inc/utils.hpp index 5e22a25127e..05ba610e9d5 100644 --- a/src/types/inc/utils.hpp +++ b/src/types/inc/utils.hpp @@ -96,32 +96,4 @@ namespace Microsoft::Console::Utils GUID CreateV5Uuid(const GUID& namespaceGuid, const gsl::span name); - // Method Description: - // - Base case provided to handle the last argument to CoalesceOptionals() - template - T CoalesceOptionals(const T& base) - { - return base; - } - - // Method Description: - // - Base case provided to throw an assertion if you call CoalesceOptionals(opt, opt, opt) - template - T CoalesceOptionals(const std::optional& base) - { - static_assert(false, "CoalesceOptionals must be passed a base non-optional value to be used if all optionals are empty"); - return T{}; - } - - // Method Description: - // - Returns the value from the first populated optional, or a base value if none were populated. - template - T CoalesceOptionals(const std::optional& t1, Ts&&... t2) - { - // Initially, I wanted to check "has_value" and short-circuit out so that we didn't - // evaluate value_or for every single optional, but has_value/value emits exception handling - // code that value_or doesn't. Less exception handling is cheaper than calling value_or a - // few more times. - return t1.value_or(CoalesceOptionals(std::forward(t2)...)); - } } From 70fd03f247f03b6cc38502ab024c78e11a279c4e Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Fri, 7 Aug 2020 18:11:44 -0500 Subject: [PATCH 030/266] Add a `togglePaneZoom` action for zooming a pane (#6989) This PR adds the `togglePaneZoom` action, which can be used to make a pane expand to fill the entire contents of the window. A tab that contains a zoomed pane will have a magnifying glass icon prepended to its title. Any attempts to manage panes with one zoomed will force the zoomed pane back to normal size. VALIDATION Zoomed in and out a bunch. Tried closing panes while zoomed. Tried splitting panes while zoomed. Etc. Closes #996 --- src/cascadia/TerminalApp/ActionAndArgs.cpp | 3 + .../TerminalApp/AppActionHandlers.cpp | 20 ++++ src/cascadia/TerminalApp/Pane.cpp | 102 +++++++++++++++--- src/cascadia/TerminalApp/Pane.h | 5 + .../Resources/en-US/Resources.resw | 3 + .../TerminalApp/ShortcutActionDispatch.cpp | 6 ++ .../TerminalApp/ShortcutActionDispatch.h | 1 + .../TerminalApp/ShortcutActionDispatch.idl | 2 + src/cascadia/TerminalApp/Tab.cpp | 75 ++++++++++++- src/cascadia/TerminalApp/Tab.h | 6 ++ src/cascadia/TerminalApp/TerminalPage.cpp | 33 ++++++ src/cascadia/TerminalApp/TerminalPage.h | 3 + 12 files changed, 244 insertions(+), 15 deletions(-) diff --git a/src/cascadia/TerminalApp/ActionAndArgs.cpp b/src/cascadia/TerminalApp/ActionAndArgs.cpp index 2f8966810fe..f784345ba5a 100644 --- a/src/cascadia/TerminalApp/ActionAndArgs.cpp +++ b/src/cascadia/TerminalApp/ActionAndArgs.cpp @@ -28,6 +28,7 @@ static constexpr std::string_view ScrolldownpageKey{ "scrollDownPage" }; static constexpr std::string_view SwitchToTabKey{ "switchToTab" }; static constexpr std::string_view OpenSettingsKey{ "openSettings" }; // TODO GH#2557: Add args for OpenSettings static constexpr std::string_view SplitPaneKey{ "splitPane" }; +static constexpr std::string_view TogglePaneZoomKey{ "togglePaneZoom" }; static constexpr std::string_view ResizePaneKey{ "resizePane" }; static constexpr std::string_view MoveFocusKey{ "moveFocus" }; static constexpr std::string_view FindKey{ "find" }; @@ -87,6 +88,7 @@ namespace winrt::TerminalApp::implementation { ToggleFullscreenKey, ShortcutAction::ToggleFullscreen }, { ToggleAlwaysOnTopKey, ShortcutAction::ToggleAlwaysOnTop }, { SplitPaneKey, ShortcutAction::SplitPane }, + { TogglePaneZoomKey, ShortcutAction::TogglePaneZoom }, { SetTabColorKey, ShortcutAction::SetTabColor }, { OpenTabColorPickerKey, ShortcutAction::OpenTabColorPicker }, { UnboundKey, ShortcutAction::Invalid }, @@ -275,6 +277,7 @@ namespace winrt::TerminalApp::implementation { ShortcutAction::ToggleFullscreen, RS_(L"ToggleFullscreenCommandKey") }, { ShortcutAction::ToggleAlwaysOnTop, RS_(L"ToggleAlwaysOnTopCommandKey") }, { ShortcutAction::SplitPane, RS_(L"SplitPaneCommandKey") }, + { ShortcutAction::TogglePaneZoom, RS_(L"TogglePaneZoomCommandKey") }, { ShortcutAction::Invalid, L"" }, { ShortcutAction::Find, RS_(L"FindCommandKey") }, { ShortcutAction::SetTabColor, RS_(L"ResetTabColorCommandKey") }, diff --git a/src/cascadia/TerminalApp/AppActionHandlers.cpp b/src/cascadia/TerminalApp/AppActionHandlers.cpp index 71bea71051f..c58a95b248c 100644 --- a/src/cascadia/TerminalApp/AppActionHandlers.cpp +++ b/src/cascadia/TerminalApp/AppActionHandlers.cpp @@ -103,6 +103,26 @@ namespace winrt::TerminalApp::implementation } } + void TerminalPage::_HandleTogglePaneZoom(const IInspectable& /*sender*/, + const TerminalApp::ActionEventArgs& args) + { + auto activeTab = _GetFocusedTab(); + if (activeTab) + { + // First thing's first, remove the current content from the UI + // tree. This is important, because we might be leaving zoom, and if + // a pane is zoomed, then it's currently in the UI tree, and should + // be removed before it's re-added in Pane::Restore + _tabContent.Children().Clear(); + + activeTab->ToggleZoom(); + + // Update the selected tab, to trigger us to re-add the tab's GetRootElement to the UI tree + _UpdatedSelectedTab(_tabView.SelectedIndex()); + } + args.Handled(true); + } + void TerminalPage::_HandleScrollUpPage(const IInspectable& /*sender*/, const TerminalApp::ActionEventArgs& args) { diff --git a/src/cascadia/TerminalApp/Pane.cpp b/src/cascadia/TerminalApp/Pane.cpp index 40438f81f51..180100f4a97 100644 --- a/src/cascadia/TerminalApp/Pane.cpp +++ b/src/cascadia/TerminalApp/Pane.cpp @@ -840,21 +840,29 @@ void Pane::_UpdateBorders() double top = 0, bottom = 0, left = 0, right = 0; Thickness newBorders{ 0 }; - if (WI_IsFlagSet(_borders, Borders::Top)) + if (_zoomed) { - top = PaneBorderSize; + // When the pane is zoomed, manually show all the borders around the window. + top = bottom = right = left = PaneBorderSize; } - if (WI_IsFlagSet(_borders, Borders::Bottom)) - { - bottom = PaneBorderSize; - } - if (WI_IsFlagSet(_borders, Borders::Left)) - { - left = PaneBorderSize; - } - if (WI_IsFlagSet(_borders, Borders::Right)) + else { - right = PaneBorderSize; + if (WI_IsFlagSet(_borders, Borders::Top)) + { + top = PaneBorderSize; + } + if (WI_IsFlagSet(_borders, Borders::Bottom)) + { + bottom = PaneBorderSize; + } + if (WI_IsFlagSet(_borders, Borders::Left)) + { + left = PaneBorderSize; + } + if (WI_IsFlagSet(_borders, Borders::Right)) + { + right = PaneBorderSize; + } } _border.BorderThickness(ThicknessHelper::FromLengths(left, top, right, bottom)); } @@ -1172,6 +1180,76 @@ std::pair, std::shared_ptr> Pane::_Split(SplitState return { _firstChild, _secondChild }; } +// Method Description: +// - Recursively attempt to "zoom" the given pane. When the pane is zoomed, it +// won't be displayed as part of the tab tree, instead it'll take up the full +// content of the tab. When we find the given pane, we'll need to remove it +// from the UI tree, so that the caller can re-add it. We'll also set some +// internal state, so the pane can display all of its borders. +// Arguments: +// - zoomedPane: This is the pane which we're attempting to zoom on. +// Return Value: +// - +void Pane::Maximize(std::shared_ptr zoomedPane) +{ + if (_IsLeaf()) + { + _zoomed = (zoomedPane == shared_from_this()); + _UpdateBorders(); + } + else + { + if (zoomedPane == _firstChild || zoomedPane == _secondChild) + { + // When we're zooming the pane, we'll need to remove it from our UI + // tree. Easy way: just remove both children. We'll re-attach both + // when we un-zoom. + _root.Children().Clear(); + } + + // Always recurse into both children. If the (un)zoomed pane was one of + // our direct children, we'll still want to update it's borders. + _firstChild->Maximize(zoomedPane); + _secondChild->Maximize(zoomedPane); + } +} + +// Method Description: +// - Recursively attempt to "un-zoom" the given pane. This does the opposite of +// Pane::Maximize. When we find the given pane, we should return the pane to our +// UI tree. We'll also clear the internal state, so the pane can display its +// borders correctly. +// - The caller should make sure to have removed the zoomed pane from the UI +// tree _before_ calling this. +// Arguments: +// - zoomedPane: This is the pane which we're attempting to un-zoom. +// Return Value: +// - +void Pane::Restore(std::shared_ptr zoomedPane) +{ + if (_IsLeaf()) + { + _zoomed = false; + _UpdateBorders(); + } + else + { + if (zoomedPane == _firstChild || zoomedPane == _secondChild) + { + // When we're un-zooming the pane, we'll need to re-add it to our UI + // tree where it originally belonged. easy way: just re-add both. + _root.Children().Clear(); + _root.Children().Append(_firstChild->GetRootElement()); + _root.Children().Append(_secondChild->GetRootElement()); + } + + // Always recurse into both children. If the (un)zoomed pane was one of + // our direct children, we'll still want to update it's borders. + _firstChild->Restore(zoomedPane); + _secondChild->Restore(zoomedPane); + } +} + // Method Description: // - Gets the size in pixels of each of our children, given the full size they // should fill. Since these children own their own separators (borders), this diff --git a/src/cascadia/TerminalApp/Pane.h b/src/cascadia/TerminalApp/Pane.h index dfbcf1e7bc2..6d1ffa133f1 100644 --- a/src/cascadia/TerminalApp/Pane.h +++ b/src/cascadia/TerminalApp/Pane.h @@ -72,6 +72,9 @@ class Pane : public std::enable_shared_from_this int GetLeafPaneCount() const noexcept; + void Maximize(std::shared_ptr zoomedPane); + void Restore(std::shared_ptr zoomedPane); + WINRT_CALLBACK(Closed, winrt::Windows::Foundation::EventHandler); DECLARE_EVENT(GotFocus, _GotFocusHandlers, winrt::delegate>); @@ -103,6 +106,8 @@ class Pane : public std::enable_shared_from_this Borders _borders{ Borders::None }; + bool _zoomed{ false }; + bool _IsLeaf() const noexcept; bool _HasFocusedChild() const noexcept; void _SetupChildCloseHandlers(); diff --git a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw index d1cb5606c07..25fc712d10f 100644 --- a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw +++ b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw @@ -452,6 +452,9 @@ Split pane + + Toggle pane zoom + New window diff --git a/src/cascadia/TerminalApp/ShortcutActionDispatch.cpp b/src/cascadia/TerminalApp/ShortcutActionDispatch.cpp index 1ea1bb7fae2..2f6a1a280c6 100644 --- a/src/cascadia/TerminalApp/ShortcutActionDispatch.cpp +++ b/src/cascadia/TerminalApp/ShortcutActionDispatch.cpp @@ -121,6 +121,12 @@ namespace winrt::TerminalApp::implementation break; } + case ShortcutAction::TogglePaneZoom: + { + _TogglePaneZoomHandlers(*this, *eventArgs); + break; + } + case ShortcutAction::SwitchToTab: { _SwitchToTabHandlers(*this, *eventArgs); diff --git a/src/cascadia/TerminalApp/ShortcutActionDispatch.h b/src/cascadia/TerminalApp/ShortcutActionDispatch.h index 7ed978d9b80..963bfbea447 100644 --- a/src/cascadia/TerminalApp/ShortcutActionDispatch.h +++ b/src/cascadia/TerminalApp/ShortcutActionDispatch.h @@ -36,6 +36,7 @@ namespace winrt::TerminalApp::implementation TYPED_EVENT(NextTab, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs); TYPED_EVENT(PrevTab, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs); TYPED_EVENT(SplitPane, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs); + TYPED_EVENT(TogglePaneZoom, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs); TYPED_EVENT(AdjustFontSize, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs); TYPED_EVENT(ResetFontSize, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs); TYPED_EVENT(ScrollUp, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs); diff --git a/src/cascadia/TerminalApp/ShortcutActionDispatch.idl b/src/cascadia/TerminalApp/ShortcutActionDispatch.idl index 026fa4aa2ba..4136e44a97e 100644 --- a/src/cascadia/TerminalApp/ShortcutActionDispatch.idl +++ b/src/cascadia/TerminalApp/ShortcutActionDispatch.idl @@ -21,6 +21,7 @@ namespace TerminalApp SplitVertical, SplitHorizontal, SplitPane, + TogglePaneZoom, SwitchToTab, AdjustFontSize, ResetFontSize, @@ -69,6 +70,7 @@ namespace TerminalApp event Windows.Foundation.TypedEventHandler NextTab; event Windows.Foundation.TypedEventHandler PrevTab; event Windows.Foundation.TypedEventHandler SplitPane; + event Windows.Foundation.TypedEventHandler TogglePaneZoom; event Windows.Foundation.TypedEventHandler AdjustFontSize; event Windows.Foundation.TypedEventHandler ResetFontSize; event Windows.Foundation.TypedEventHandler ScrollUp; diff --git a/src/cascadia/TerminalApp/Tab.cpp b/src/cascadia/TerminalApp/Tab.cpp index 77e3371104f..eb396275303 100644 --- a/src/cascadia/TerminalApp/Tab.cpp +++ b/src/cascadia/TerminalApp/Tab.cpp @@ -65,7 +65,14 @@ namespace winrt::TerminalApp::implementation // - The UIElement acting as root of the Tab's root pane. UIElement Tab::GetRootElement() { - return _rootPane->GetRootElement(); + if (_zoomedPane) + { + return _zoomedPane->GetRootElement(); + } + else + { + return _rootPane->GetRootElement(); + } } // Method Description: @@ -598,8 +605,28 @@ namespace winrt::TerminalApp::implementation if (!_inRename) { - // If we're not currently in the process of renaming the tab, then just set the tab's text to whatever our active title is. - _tabViewItem.Header(winrt::box_value(tabText)); + if (_zoomedPane) + { + Controls::StackPanel sp; + sp.Orientation(Controls::Orientation::Horizontal); + Controls::FontIcon ico; + ico.FontFamily(Media::FontFamily{ L"Segoe MDL2 Assets" }); + ico.Glyph(L"\xE8A3"); // "ZoomIn", a magnifying glass with a '+' in it. + ico.FontSize(12); + ico.Margin(ThicknessHelper::FromLengths(0, 0, 8, 0)); + sp.Children().Append(ico); + Controls::TextBlock tb; + tb.Text(tabText); + sp.Children().Append(tb); + + _tabViewItem.Header(sp); + } + else + { + // If we're not currently in the process of renaming the tab, + // then just set the tab's text to whatever our active title is. + _tabViewItem.Header(winrt::box_value(tabText)); + } } else { @@ -955,6 +982,48 @@ namespace winrt::TerminalApp::implementation { return _rootPane->PreCalculateCanSplit(_activePane, splitType, availableSpace).value_or(false); } + + // Method Description: + // - Toggle our zoom state. + // * If we're not zoomed, then zoom the active pane, making it take the + // full size of the tab. We'll achieve this by changing our response to + // Tab::GetRootElement, so that it'll return the zoomed pane only. + // * If we're currently zoomed on a pane, un-zoom that pane. + // Arguments: + // - + // Return Value: + // - + void Tab::ToggleZoom() + { + if (_zoomedPane) + { + ExitZoom(); + } + else + { + EnterZoom(); + } + } + void Tab::EnterZoom() + { + _zoomedPane = _activePane; + _rootPane->Maximize(_zoomedPane); + // Update the tab header to show the magnifying glass + _UpdateTabHeader(); + } + void Tab::ExitZoom() + { + _rootPane->Restore(_zoomedPane); + _zoomedPane = nullptr; + // Update the tab header to hide the magnifying glass + _UpdateTabHeader(); + } + + bool Tab::IsZoomed() + { + return _zoomedPane != nullptr; + } + DEFINE_EVENT(Tab, ActivePaneChanged, _ActivePaneChangedHandlers, winrt::delegate<>); DEFINE_EVENT(Tab, ColorSelected, _colorSelected, winrt::delegate); DEFINE_EVENT(Tab, ColorCleared, _colorCleared, winrt::delegate<>); diff --git a/src/cascadia/TerminalApp/Tab.h b/src/cascadia/TerminalApp/Tab.h index a53326b04f6..6e3e5cc5b95 100644 --- a/src/cascadia/TerminalApp/Tab.h +++ b/src/cascadia/TerminalApp/Tab.h @@ -61,6 +61,11 @@ namespace winrt::TerminalApp::implementation void ResetRuntimeTabColor(); void ActivateColorPicker(); + void ToggleZoom(); + bool IsZoomed(); + void EnterZoom(); + void ExitZoom(); + WINRT_CALLBACK(Closed, winrt::Windows::Foundation::EventHandler); WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler); DECLARE_EVENT(ActivePaneChanged, _ActivePaneChangedHandlers, winrt::delegate<>); @@ -73,6 +78,7 @@ namespace winrt::TerminalApp::implementation private: std::shared_ptr _rootPane{ nullptr }; std::shared_ptr _activePane{ nullptr }; + std::shared_ptr _zoomedPane{ nullptr }; winrt::hstring _lastIconPath{}; winrt::TerminalApp::ColorPickupFlyout _tabColorPickup{}; std::optional _themeTabColor{}; diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index b19710a8194..309fb12fe09 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -872,6 +872,7 @@ namespace winrt::TerminalApp::implementation _actionDispatch->NextTab({ this, &TerminalPage::_HandleNextTab }); _actionDispatch->PrevTab({ this, &TerminalPage::_HandlePrevTab }); _actionDispatch->SplitPane({ this, &TerminalPage::_HandleSplitPane }); + _actionDispatch->TogglePaneZoom({ this, &TerminalPage::_HandleTogglePaneZoom }); _actionDispatch->ScrollUpPage({ this, &TerminalPage::_HandleScrollUpPage }); _actionDispatch->ScrollDownPage({ this, &TerminalPage::_HandleScrollDownPage }); _actionDispatch->OpenSettings({ this, &TerminalPage::_HandleOpenSettings }); @@ -1189,6 +1190,33 @@ namespace winrt::TerminalApp::implementation return false; } + // Method Description: + // - Helper to manually exit "zoom" when certain actions take place. + // Anything that modifies the state of the pane tree should probably + // un-zoom the focused pane first, so that the user can see the full pane + // tree again. These actions include: + // * Splitting a new pane + // * Closing a pane + // * Moving focus between panes + // * Resizing a pane + // Arguments: + // - + // Return Value: + // - + void TerminalPage::_UnZoomIfNeeded() + { + auto activeTab = _GetFocusedTab(); + if (activeTab && activeTab->IsZoomed()) + { + // Remove the content from the tab first, so Pane::UnZoom can + // re-attach the content to the tree w/in the pane + _tabContent.Children().Clear(); + activeTab->ExitZoom(); + // Re-attach the tab's content to the UI tree. + _tabContent.Children().Append(activeTab->GetRootElement()); + } + } + // Method Description: // - Attempt to move focus between panes, as to focus the child on // the other side of the separator. See Pane::NavigateFocus for details. @@ -1202,6 +1230,7 @@ namespace winrt::TerminalApp::implementation if (auto index{ _GetFocusedTabIndex() }) { auto focusedTab{ _GetStrongTabImpl(*index) }; + _UnZoomIfNeeded(); focusedTab->NavigateFocus(direction); } } @@ -1292,6 +1321,7 @@ namespace winrt::TerminalApp::implementation if (auto index{ _GetFocusedTabIndex() }) { auto focusedTab{ _GetStrongTabImpl(*index) }; + _UnZoomIfNeeded(); focusedTab->ClosePane(); } } @@ -1423,6 +1453,8 @@ namespace winrt::TerminalApp::implementation // Hookup our event handlers to the new terminal _RegisterTerminalEvents(newControl, *focusedTab); + _UnZoomIfNeeded(); + focusedTab->SplitPane(realSplitType, realGuid, newControl); } CATCH_LOG(); @@ -1441,6 +1473,7 @@ namespace winrt::TerminalApp::implementation if (auto index{ _GetFocusedTabIndex() }) { auto focusedTab{ _GetStrongTabImpl(*index) }; + _UnZoomIfNeeded(); focusedTab->ResizePane(direction); } } diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h index 8eb8e5752a3..1228226f6c1 100644 --- a/src/cascadia/TerminalApp/TerminalPage.h +++ b/src/cascadia/TerminalApp/TerminalPage.h @@ -191,6 +191,8 @@ namespace winrt::TerminalApp::implementation void _CommandPaletteClosed(const IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& eventArgs); + void _UnZoomIfNeeded(); + #pragma region ActionHandlers // These are all defined in AppActionHandlers.cpp void _HandleOpenNewTabDropdown(const IInspectable& sender, const TerminalApp::ActionEventArgs& args); @@ -202,6 +204,7 @@ namespace winrt::TerminalApp::implementation void _HandleNextTab(const IInspectable& sender, const TerminalApp::ActionEventArgs& args); void _HandlePrevTab(const IInspectable& sender, const TerminalApp::ActionEventArgs& args); void _HandleSplitPane(const IInspectable& sender, const TerminalApp::ActionEventArgs& args); + void _HandleTogglePaneZoom(const IInspectable& sender, const TerminalApp::ActionEventArgs& args); void _HandleScrollUpPage(const IInspectable& sender, const TerminalApp::ActionEventArgs& args); void _HandleScrollDownPage(const IInspectable& sender, const TerminalApp::ActionEventArgs& args); void _HandleOpenSettings(const IInspectable& sender, const TerminalApp::ActionEventArgs& args); From 20a288020e26d48efab309b843e41498e7bc8684 Mon Sep 17 00:00:00 2001 From: Carlos Zamora Date: Fri, 7 Aug 2020 16:21:09 -0700 Subject: [PATCH 031/266] Pass mouse button state into HandleMouse instead of asking win32 (#6765) MouseInput was directly asking user32 about the state of the mouse buttons, which was somewhat of a layering violation. This commit makes all callers have to pass the mouse state in themselves. Closes #4869 --- .../PublicTerminalCore/HwndTerminal.cpp | 12 +++- .../TerminalControl/IMouseWheelListener.idl | 2 +- src/cascadia/TerminalControl/TermControl.cpp | 24 +++++--- src/cascadia/TerminalControl/TermControl.h | 9 ++- src/cascadia/TerminalCore/ITerminalInput.hpp | 2 +- src/cascadia/TerminalCore/Terminal.cpp | 4 +- src/cascadia/TerminalCore/Terminal.hpp | 2 +- src/cascadia/WindowsTerminal/AppHost.cpp | 10 +++- src/interactivity/win32/windowio.cpp | 13 ++++- .../adapter/ut_adapter/MouseInputTest.cpp | 55 +++++++++++-------- src/terminal/input/mouseInput.cpp | 24 ++++---- src/terminal/input/terminalInput.hpp | 13 ++++- 12 files changed, 116 insertions(+), 54 deletions(-) diff --git a/src/cascadia/PublicTerminalCore/HwndTerminal.cpp b/src/cascadia/PublicTerminalCore/HwndTerminal.cpp index bb7112efb1b..c194e5d77a8 100644 --- a/src/cascadia/PublicTerminalCore/HwndTerminal.cpp +++ b/src/cascadia/PublicTerminalCore/HwndTerminal.cpp @@ -16,6 +16,10 @@ using namespace ::Microsoft::Terminal::Core; static LPCWSTR term_window_class = L"HwndTerminalClass"; +// This magic flag is "documented" at https://msdn.microsoft.com/en-us/library/windows/desktop/ms646301(v=vs.85).aspx +// "If the high-order bit is 1, the key is down; otherwise, it is up." +static constexpr short KeyPressed{ gsl::narrow_cast(0x8000) }; + static constexpr bool _IsMouseMessage(UINT uMsg) { return uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONUP || uMsg == WM_LBUTTONDBLCLK || @@ -645,7 +649,13 @@ try cursorPosition = coordsToTransform; } - return _terminal->SendMouseEvent(cursorPosition / fontSize, uMsg, getControlKeyState(), wheelDelta); + const TerminalInput::MouseButtonState state{ + WI_IsFlagSet(GetKeyState(VK_LBUTTON), KeyPressed), + WI_IsFlagSet(GetKeyState(VK_MBUTTON), KeyPressed), + WI_IsFlagSet(GetKeyState(VK_RBUTTON), KeyPressed) + }; + + return _terminal->SendMouseEvent(cursorPosition / fontSize, uMsg, getControlKeyState(), wheelDelta, state); } catch (...) { diff --git a/src/cascadia/TerminalControl/IMouseWheelListener.idl b/src/cascadia/TerminalControl/IMouseWheelListener.idl index 63089552683..8ba8284b5d4 100644 --- a/src/cascadia/TerminalControl/IMouseWheelListener.idl +++ b/src/cascadia/TerminalControl/IMouseWheelListener.idl @@ -11,6 +11,6 @@ namespace Microsoft.Terminal.TerminalControl [uuid("65b8b8c5-988f-43ff-aba9-e89368da1598")] interface IMouseWheelListener { - Boolean OnMouseWheel(Windows.Foundation.Point coord, Int32 delta); + Boolean OnMouseWheel(Windows.Foundation.Point coord, Int32 delta, Boolean leftButtonDown, Boolean midButtonDown, Boolean rightButtonDown); } } diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index 4b7b64a7b15..d14fb9c9061 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -16,6 +16,7 @@ #include "TermControlAutomationPeer.h" using namespace ::Microsoft::Console::Types; +using namespace ::Microsoft::Console::VirtualTerminal; using namespace ::Microsoft::Terminal::Core; using namespace winrt::Windows::Graphics::Display; using namespace winrt::Windows::UI::Xaml; @@ -1007,7 +1008,8 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation } const auto modifiers = _GetPressedModifierKeys(); - return _terminal->SendMouseEvent(terminalPosition, uiButton, modifiers, sWheelDelta); + const TerminalInput::MouseButtonState state{ props.IsLeftButtonPressed(), props.IsMiddleButtonPressed(), props.IsRightButtonPressed() }; + return _terminal->SendMouseEvent(terminalPosition, uiButton, modifiers, sWheelDelta, state); } // Method Description: @@ -1331,10 +1333,12 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation } const auto point = args.GetCurrentPoint(*this); + const auto props = point.Properties(); + const TerminalInput::MouseButtonState state{ props.IsLeftButtonPressed(), props.IsMiddleButtonPressed(), props.IsRightButtonPressed() }; auto result = _DoMouseWheel(point.Position(), ControlKeyStates{ args.KeyModifiers() }, point.Properties().MouseWheelDelta(), - point.Properties().IsLeftButtonPressed()); + state); if (result) { args.Handled(true); @@ -1357,7 +1361,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation bool TermControl::_DoMouseWheel(const Windows::Foundation::Point point, const ControlKeyStates modifiers, const int32_t delta, - const bool isLeftButtonPressed) + const TerminalInput::MouseButtonState state) { if (_CanSendVTMouseInput()) { @@ -1369,7 +1373,8 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation return _terminal->SendMouseEvent(_GetTerminalPosition(point), WM_MOUSEWHEEL, _GetPressedModifierKeys(), - ::base::saturated_cast(delta)); + ::base::saturated_cast(delta), + state); } const auto ctrlPressed = modifiers.IsCtrlPressed(); @@ -1385,7 +1390,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation } else { - _MouseScrollHandler(delta, point, isLeftButtonPressed); + _MouseScrollHandler(delta, point, state.isLeftButtonDown); } return false; } @@ -1399,11 +1404,16 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation // - location: the location of the mouse during this event. This location is // relative to the origin of the control // - delta: the mouse wheel delta that triggered this event. + // - state: the state for each of the mouse buttons individually (pressed/unpressed) bool TermControl::OnMouseWheel(const Windows::Foundation::Point location, - const int32_t delta) + const int32_t delta, + const bool leftButtonDown, + const bool midButtonDown, + const bool rightButtonDown) { const auto modifiers = _GetPressedModifierKeys(); - return _DoMouseWheel(location, modifiers, delta, false); + TerminalInput::MouseButtonState state{ leftButtonDown, midButtonDown, rightButtonDown }; + return _DoMouseWheel(location, modifiers, delta, state); } // Method Description: diff --git a/src/cascadia/TerminalControl/TermControl.h b/src/cascadia/TerminalControl/TermControl.h index 5b159fea38e..f3d91c5c0b3 100644 --- a/src/cascadia/TerminalControl/TermControl.h +++ b/src/cascadia/TerminalControl/TermControl.h @@ -16,6 +16,11 @@ #include "SearchBoxControl.h" #include "ThrottledFunc.h" +namespace Microsoft::Console::VirtualTerminal +{ + struct MouseButtonState; +} + namespace winrt::Microsoft::Terminal::TerminalControl::implementation { struct CopyToClipboardEventArgs : @@ -87,7 +92,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation bool OnDirectKeyEvent(const uint32_t vkey, const bool down); - bool OnMouseWheel(const Windows::Foundation::Point location, const int32_t delta); + bool OnMouseWheel(const Windows::Foundation::Point location, const int32_t delta, const bool leftButtonDown, const bool midButtonDown, const bool rightButtonDown); ~TermControl(); @@ -230,7 +235,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation void _MouseScrollHandler(const double mouseDelta, const Windows::Foundation::Point point, const bool isLeftButtonPressed); void _MouseZoomHandler(const double delta); void _MouseTransparencyHandler(const double delta); - bool _DoMouseWheel(const Windows::Foundation::Point point, const ::Microsoft::Terminal::Core::ControlKeyStates modifiers, const int32_t delta, const bool isLeftButtonPressed); + bool _DoMouseWheel(const Windows::Foundation::Point point, const ::Microsoft::Terminal::Core::ControlKeyStates modifiers, const int32_t delta, const ::Microsoft::Console::VirtualTerminal::TerminalInput::MouseButtonState state); bool _CapturePointer(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs const& e); bool _ReleasePointerCapture(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs const& e); diff --git a/src/cascadia/TerminalCore/ITerminalInput.hpp b/src/cascadia/TerminalCore/ITerminalInput.hpp index 1d9785e4ee6..307f03b1165 100644 --- a/src/cascadia/TerminalCore/ITerminalInput.hpp +++ b/src/cascadia/TerminalCore/ITerminalInput.hpp @@ -17,7 +17,7 @@ namespace Microsoft::Terminal::Core ITerminalInput& operator=(ITerminalInput&&) = default; virtual bool SendKeyEvent(const WORD vkey, const WORD scanCode, const ControlKeyStates states, const bool keyDown) = 0; - virtual bool SendMouseEvent(const COORD viewportPos, const unsigned int uiButton, const ControlKeyStates states, const short wheelDelta) = 0; + virtual bool SendMouseEvent(const COORD viewportPos, const unsigned int uiButton, const ControlKeyStates states, const short wheelDelta, const Microsoft::Console::VirtualTerminal::TerminalInput::MouseButtonState state) = 0; virtual bool SendCharEvent(const wchar_t ch, const WORD scanCode, const ControlKeyStates states) = 0; // void SendMouseEvent(uint row, uint col, KeyModifiers modifiers); diff --git a/src/cascadia/TerminalCore/Terminal.cpp b/src/cascadia/TerminalCore/Terminal.cpp index f4a847cc884..4709eeaf0e8 100644 --- a/src/cascadia/TerminalCore/Terminal.cpp +++ b/src/cascadia/TerminalCore/Terminal.cpp @@ -510,7 +510,7 @@ bool Terminal::SendKeyEvent(const WORD vkey, // Return Value: // - true if we translated the key event, and it should not be processed any further. // - false if we did not translate the key, and it should be processed into a character. -bool Terminal::SendMouseEvent(const COORD viewportPos, const unsigned int uiButton, const ControlKeyStates states, const short wheelDelta) +bool Terminal::SendMouseEvent(const COORD viewportPos, const unsigned int uiButton, const ControlKeyStates states, const short wheelDelta, const TerminalInput::MouseButtonState state) { // GH#6401: VT applications should be able to receive mouse events from outside the // terminal buffer. This is likely to happen when the user drags the cursor offscreen. @@ -519,7 +519,7 @@ bool Terminal::SendMouseEvent(const COORD viewportPos, const unsigned int uiButt #pragma warning(suppress : 26496) // analysis can't tell we're assigning through a reference below auto clampedPos{ viewportPos }; _mutableViewport.ToOrigin().Clamp(clampedPos); - return _terminalInput->HandleMouse(clampedPos, uiButton, GET_KEYSTATE_WPARAM(states.Value()), wheelDelta); + return _terminalInput->HandleMouse(clampedPos, uiButton, GET_KEYSTATE_WPARAM(states.Value()), wheelDelta, state); } // Method Description: diff --git a/src/cascadia/TerminalCore/Terminal.hpp b/src/cascadia/TerminalCore/Terminal.hpp index 78e0ead8952..df70bc0184c 100644 --- a/src/cascadia/TerminalCore/Terminal.hpp +++ b/src/cascadia/TerminalCore/Terminal.hpp @@ -116,7 +116,7 @@ class Microsoft::Terminal::Core::Terminal final : #pragma region ITerminalInput // These methods are defined in Terminal.cpp bool SendKeyEvent(const WORD vkey, const WORD scanCode, const Microsoft::Terminal::Core::ControlKeyStates states, const bool keyDown) override; - bool SendMouseEvent(const COORD viewportPos, const unsigned int uiButton, const ControlKeyStates states, const short wheelDelta) override; + bool SendMouseEvent(const COORD viewportPos, const unsigned int uiButton, const ControlKeyStates states, const short wheelDelta, const Microsoft::Console::VirtualTerminal::TerminalInput::MouseButtonState state) override; bool SendCharEvent(const wchar_t ch, const WORD scanCode, const ControlKeyStates states) override; [[nodiscard]] HRESULT UserResize(const COORD viewportSize) noexcept override; diff --git a/src/cascadia/WindowsTerminal/AppHost.cpp b/src/cascadia/WindowsTerminal/AppHost.cpp index 36ec74db1a7..1f0fb413e26 100644 --- a/src/cascadia/WindowsTerminal/AppHost.cpp +++ b/src/cascadia/WindowsTerminal/AppHost.cpp @@ -17,6 +17,10 @@ using namespace winrt::Windows::Foundation::Numerics; using namespace ::Microsoft::Console; using namespace ::Microsoft::Console::Types; +// This magic flag is "documented" at https://msdn.microsoft.com/en-us/library/windows/desktop/ms646301(v=vs.85).aspx +// "If the high-order bit is 1, the key is down; otherwise, it is up." +static constexpr short KeyPressed{ gsl::narrow_cast(0x8000) }; + AppHost::AppHost() noexcept : _app{}, _logic{ nullptr }, // don't make one, we're going to take a ref on app's @@ -405,7 +409,11 @@ void AppHost::_WindowMouseWheeled(const til::point coord, const int32_t delta) const til::point offsetPoint = coord - controlOrigin; - if (control.OnMouseWheel(offsetPoint, delta)) + const auto lButtonDown = WI_IsFlagSet(GetKeyState(VK_LBUTTON), KeyPressed); + const auto mButtonDown = WI_IsFlagSet(GetKeyState(VK_MBUTTON), KeyPressed); + const auto rButtonDown = WI_IsFlagSet(GetKeyState(VK_RBUTTON), KeyPressed); + + if (control.OnMouseWheel(offsetPoint, delta, lButtonDown, mButtonDown, rButtonDown)) { // If the element handled the mouse wheel event, don't // continue to iterate over the remaining controls. diff --git a/src/interactivity/win32/windowio.cpp b/src/interactivity/win32/windowio.cpp index 2b65f515047..19542281c7d 100644 --- a/src/interactivity/win32/windowio.cpp +++ b/src/interactivity/win32/windowio.cpp @@ -23,12 +23,17 @@ #pragma hdrstop using namespace Microsoft::Console::Interactivity::Win32; +using namespace Microsoft::Console::VirtualTerminal; using Microsoft::Console::Interactivity::ServiceLocator; // For usage with WM_SYSKEYDOWN message processing. // See https://msdn.microsoft.com/en-us/library/windows/desktop/ms646286(v=vs.85).aspx // Bit 29 is whether ALT was held when the message was posted. #define WM_SYSKEYDOWN_ALT_PRESSED (0x20000000) +// This magic flag is "documented" at https://msdn.microsoft.com/en-us/library/windows/desktop/ms646301(v=vs.85).aspx +// "If the high-order bit is 1, the key is down; otherwise, it is up." +static constexpr short KeyPressed{ gsl::narrow_cast(0x8000) }; + // ---------------------------- // Helpers // ---------------------------- @@ -123,6 +128,12 @@ bool HandleTerminalMouseEvent(const COORD cMousePosition, // Virtual terminal input mode if (IsInVirtualTerminalInputMode()) { + const TerminalInput::MouseButtonState state{ + WI_IsFlagSet(GetKeyState(VK_LBUTTON), KeyPressed), + WI_IsFlagSet(GetKeyState(VK_MBUTTON), KeyPressed), + WI_IsFlagSet(GetKeyState(VK_RBUTTON), KeyPressed) + }; + // GH#6401: VT applications should be able to receive mouse events from outside the // terminal buffer. This is likely to happen when the user drags the cursor offscreen. // We shouldn't throw away perfectly good events when they're offscreen, so we just @@ -130,7 +141,7 @@ bool HandleTerminalMouseEvent(const COORD cMousePosition, auto clampedPosition{ cMousePosition }; const auto clampViewport{ gci.GetActiveOutputBuffer().GetViewport().ToOrigin() }; clampViewport.Clamp(clampedPosition); - fWasHandled = gci.GetActiveInputBuffer()->GetTerminalInput().HandleMouse(clampedPosition, uiButton, sModifierKeystate, sWheelDelta); + fWasHandled = gci.GetActiveInputBuffer()->GetTerminalInput().HandleMouse(clampedPosition, uiButton, sModifierKeystate, sWheelDelta, state); } return fWasHandled; diff --git a/src/terminal/adapter/ut_adapter/MouseInputTest.cpp b/src/terminal/adapter/ut_adapter/MouseInputTest.cpp index c064c330dd0..a5e28356ae3 100644 --- a/src/terminal/adapter/ut_adapter/MouseInputTest.cpp +++ b/src/terminal/adapter/ut_adapter/MouseInputTest.cpp @@ -292,7 +292,7 @@ class MouseInputTest bool fExpectedKeyHandled = false; s_pwszInputExpected = L"\x0"; - VERIFY_ARE_EQUAL(fExpectedKeyHandled, mouseInput->HandleMouse({ 0, 0 }, uiButton, sModifierKeystate, sScrollDelta)); + VERIFY_ARE_EQUAL(fExpectedKeyHandled, mouseInput->HandleMouse({ 0, 0 }, uiButton, sModifierKeystate, sScrollDelta, {})); mouseInput->EnableDefaultTracking(true); @@ -309,7 +309,8 @@ class MouseInputTest mouseInput->HandleMouse(Coord, uiButton, sModifierKeystate, - sScrollDelta), + sScrollDelta, + {}), NoThrowString().Format(L"(x,y)=(%d,%d)", Coord.X, Coord.Y)); } @@ -327,7 +328,8 @@ class MouseInputTest mouseInput->HandleMouse(Coord, uiButton, sModifierKeystate, - sScrollDelta), + sScrollDelta, + {}), NoThrowString().Format(L"(x,y)=(%d,%d)", Coord.X, Coord.Y)); } @@ -345,7 +347,8 @@ class MouseInputTest mouseInput->HandleMouse(Coord, uiButton, sModifierKeystate, - sScrollDelta), + sScrollDelta, + {}), NoThrowString().Format(L"(x,y)=(%d,%d)", Coord.X, Coord.Y)); } } @@ -371,7 +374,7 @@ class MouseInputTest bool fExpectedKeyHandled = false; s_pwszInputExpected = L"\x0"; - VERIFY_ARE_EQUAL(fExpectedKeyHandled, mouseInput->HandleMouse({ 0, 0 }, uiButton, sModifierKeystate, sScrollDelta)); + VERIFY_ARE_EQUAL(fExpectedKeyHandled, mouseInput->HandleMouse({ 0, 0 }, uiButton, sModifierKeystate, sScrollDelta, {})); mouseInput->SetUtf8ExtendedMode(true); @@ -391,7 +394,8 @@ class MouseInputTest mouseInput->HandleMouse(Coord, uiButton, sModifierKeystate, - sScrollDelta), + sScrollDelta, + {}), NoThrowString().Format(L"(x,y)=(%d,%d)", Coord.X, Coord.Y)); } @@ -409,7 +413,8 @@ class MouseInputTest mouseInput->HandleMouse(Coord, uiButton, sModifierKeystate, - sScrollDelta), + sScrollDelta, + {}), NoThrowString().Format(L"(x,y)=(%d,%d)", Coord.X, Coord.Y)); } @@ -427,7 +432,8 @@ class MouseInputTest mouseInput->HandleMouse(Coord, uiButton, sModifierKeystate, - sScrollDelta), + sScrollDelta, + {}), NoThrowString().Format(L"(x,y)=(%d,%d)", Coord.X, Coord.Y)); } } @@ -453,7 +459,7 @@ class MouseInputTest bool fExpectedKeyHandled = false; s_pwszInputExpected = L"\x0"; - VERIFY_ARE_EQUAL(fExpectedKeyHandled, mouseInput->HandleMouse({ 0, 0 }, uiButton, sModifierKeystate, sScrollDelta)); + VERIFY_ARE_EQUAL(fExpectedKeyHandled, mouseInput->HandleMouse({ 0, 0 }, uiButton, sModifierKeystate, sScrollDelta, {})); mouseInput->SetSGRExtendedMode(true); @@ -471,7 +477,7 @@ class MouseInputTest // validate translation VERIFY_ARE_EQUAL(fExpectedKeyHandled, - mouseInput->HandleMouse(Coord, uiButton, sModifierKeystate, sScrollDelta), + mouseInput->HandleMouse(Coord, uiButton, sModifierKeystate, sScrollDelta, {}), NoThrowString().Format(L"(x,y)=(%d,%d)", Coord.X, Coord.Y)); } @@ -488,7 +494,8 @@ class MouseInputTest mouseInput->HandleMouse(Coord, uiButton, sModifierKeystate, - sScrollDelta), + sScrollDelta, + {}), NoThrowString().Format(L"(x,y)=(%d,%d)", Coord.X, Coord.Y)); } @@ -506,7 +513,8 @@ class MouseInputTest mouseInput->HandleMouse(Coord, uiButton, sModifierKeystate, - sScrollDelta), + sScrollDelta, + {}), NoThrowString().Format(L"(x,y)=(%d,%d)", Coord.X, Coord.Y)); } } @@ -532,7 +540,7 @@ class MouseInputTest bool fExpectedKeyHandled = false; s_pwszInputExpected = L"\x0"; - VERIFY_ARE_EQUAL(fExpectedKeyHandled, mouseInput->HandleMouse({ 0, 0 }, uiButton, sModifierKeystate, sScrollDelta)); + VERIFY_ARE_EQUAL(fExpectedKeyHandled, mouseInput->HandleMouse({ 0, 0 }, uiButton, sModifierKeystate, sScrollDelta, {})); // Default Tracking, Default Encoding mouseInput->EnableDefaultTracking(true); @@ -550,7 +558,8 @@ class MouseInputTest mouseInput->HandleMouse(Coord, uiButton, sModifierKeystate, - sScrollDelta), + sScrollDelta, + {}), NoThrowString().Format(L"(x,y)=(%d,%d)", Coord.X, Coord.Y)); } @@ -570,7 +579,8 @@ class MouseInputTest mouseInput->HandleMouse(Coord, uiButton, sModifierKeystate, - sScrollDelta), + sScrollDelta, + {}), NoThrowString().Format(L"(x,y)=(%d,%d)", Coord.X, Coord.Y)); } @@ -589,7 +599,8 @@ class MouseInputTest mouseInput->HandleMouse(Coord, uiButton, sModifierKeystate, - sScrollDelta), + sScrollDelta, + {}), NoThrowString().Format(L"(x,y)=(%d,%d)", Coord.X, Coord.Y)); } } @@ -606,31 +617,31 @@ class MouseInputTest Log::Comment(L"Test mouse wheel scrolling up"); s_pwszInputExpected = L"\x1B[A"; - VERIFY_IS_TRUE(mouseInput->HandleMouse({ 0, 0 }, WM_MOUSEWHEEL, noModifierKeys, WHEEL_DELTA)); + VERIFY_IS_TRUE(mouseInput->HandleMouse({ 0, 0 }, WM_MOUSEWHEEL, noModifierKeys, WHEEL_DELTA, {})); Log::Comment(L"Test mouse wheel scrolling down"); s_pwszInputExpected = L"\x1B[B"; - VERIFY_IS_TRUE(mouseInput->HandleMouse({ 0, 0 }, WM_MOUSEWHEEL, noModifierKeys, -WHEEL_DELTA)); + VERIFY_IS_TRUE(mouseInput->HandleMouse({ 0, 0 }, WM_MOUSEWHEEL, noModifierKeys, -WHEEL_DELTA, {})); Log::Comment(L"Enable cursor keys mode"); mouseInput->ChangeCursorKeysMode(true); Log::Comment(L"Test mouse wheel scrolling up"); s_pwszInputExpected = L"\x1BOA"; - VERIFY_IS_TRUE(mouseInput->HandleMouse({ 0, 0 }, WM_MOUSEWHEEL, noModifierKeys, WHEEL_DELTA)); + VERIFY_IS_TRUE(mouseInput->HandleMouse({ 0, 0 }, WM_MOUSEWHEEL, noModifierKeys, WHEEL_DELTA, {})); Log::Comment(L"Test mouse wheel scrolling down"); s_pwszInputExpected = L"\x1BOB"; - VERIFY_IS_TRUE(mouseInput->HandleMouse({ 0, 0 }, WM_MOUSEWHEEL, noModifierKeys, -WHEEL_DELTA)); + VERIFY_IS_TRUE(mouseInput->HandleMouse({ 0, 0 }, WM_MOUSEWHEEL, noModifierKeys, -WHEEL_DELTA, {})); Log::Comment(L"Confirm no effect when scroll mode is disabled"); mouseInput->UseAlternateScreenBuffer(); mouseInput->EnableAlternateScroll(false); - VERIFY_IS_FALSE(mouseInput->HandleMouse({ 0, 0 }, WM_MOUSEWHEEL, noModifierKeys, WHEEL_DELTA)); + VERIFY_IS_FALSE(mouseInput->HandleMouse({ 0, 0 }, WM_MOUSEWHEEL, noModifierKeys, WHEEL_DELTA, {})); Log::Comment(L"Confirm no effect when using the main buffer"); mouseInput->UseMainScreenBuffer(); mouseInput->EnableAlternateScroll(true); - VERIFY_IS_FALSE(mouseInput->HandleMouse({ 0, 0 }, WM_MOUSEWHEEL, noModifierKeys, WHEEL_DELTA)); + VERIFY_IS_FALSE(mouseInput->HandleMouse({ 0, 0 }, WM_MOUSEWHEEL, noModifierKeys, WHEEL_DELTA, {})); } }; diff --git a/src/terminal/input/mouseInput.cpp b/src/terminal/input/mouseInput.cpp index 70694d26dff..152ab4f4958 100644 --- a/src/terminal/input/mouseInput.cpp +++ b/src/terminal/input/mouseInput.cpp @@ -13,10 +13,6 @@ using namespace Microsoft::Console::VirtualTerminal; #endif static const int s_MaxDefaultCoordinate = 94; -// This magic flag is "documented" at https://msdn.microsoft.com/en-us/library/windows/desktop/ms646301(v=vs.85).aspx -// "If the high-order bit is 1, the key is down; otherwise, it is up." -static constexpr short KeyPressed{ gsl::narrow_cast(0x8000) }; - // Alternate scroll sequences static constexpr std::wstring_view CursorUpSequence{ L"\x1b[A" }; static constexpr std::wstring_view CursorDownSequence{ L"\x1b[B" }; @@ -105,22 +101,22 @@ static constexpr bool _isButtonDown(const unsigned int button) noexcept // - Retrieves which mouse button is currently pressed. This is needed because // MOUSEMOVE events do not also tell us if any mouse buttons are pressed during the move. // Parameters: -// +// - state - the current state of which mouse buttons are pressed // Return value: // - a button corresponding to any pressed mouse buttons, else WM_LBUTTONUP if none are pressed. -unsigned int TerminalInput::s_GetPressedButton() noexcept +constexpr unsigned int TerminalInput::s_GetPressedButton(const MouseButtonState state) noexcept { - // TODO GH#4869: Have the caller pass the mouse button state into HandleMouse - unsigned int button = WM_LBUTTONUP; // Will be treated as a release, or no button pressed. - if (WI_IsFlagSet(GetKeyState(VK_LBUTTON), KeyPressed)) + // Will be treated as a release, or no button pressed. + unsigned int button = WM_LBUTTONUP; + if (state.isLeftButtonDown) { button = WM_LBUTTONDOWN; } - else if (WI_IsFlagSet(GetKeyState(VK_MBUTTON), KeyPressed)) + else if (state.isMiddleButtonDown) { button = WM_MBUTTONDOWN; } - else if (WI_IsFlagSet(GetKeyState(VK_RBUTTON), KeyPressed)) + else if (state.isRightButtonDown) { button = WM_RBUTTONDOWN; } @@ -298,12 +294,14 @@ bool TerminalInput::IsTrackingMouseInput() const noexcept // - button - the message to decode. // - modifierKeyState - the modifier keys pressed with this button // - delta - the amount that the scroll wheel changed (should be 0 unless button is a WM_MOUSE*WHEEL) +// - state - the state of the mouse buttons at this moment // Return value: // - true if the event was handled and we should stop event propagation to the default window handler. bool TerminalInput::HandleMouse(const COORD position, const unsigned int button, const short modifierKeyState, - const short delta) + const short delta, + const MouseButtonState state) { if (Utils::Sign(delta) != Utils::Sign(_mouseInputState.accumulatedDelta)) { @@ -354,7 +352,7 @@ bool TerminalInput::HandleMouse(const COORD position, // _GetPressedButton will return the first pressed mouse button. // If it returns WM_LBUTTONUP, then we can assume that the mouse // moved without a button being pressed. - const unsigned int realButton = isHover ? s_GetPressedButton() : button; + const unsigned int realButton = isHover ? s_GetPressedButton(state) : button; // In default mode, only button presses/releases are sent // In ButtonEvent mode, changing coord hovers WITH A BUTTON PRESSED diff --git a/src/terminal/input/terminalInput.hpp b/src/terminal/input/terminalInput.hpp index 167e0f68370..0405ecca36b 100644 --- a/src/terminal/input/terminalInput.hpp +++ b/src/terminal/input/terminalInput.hpp @@ -43,10 +43,19 @@ namespace Microsoft::Console::VirtualTerminal #pragma region MouseInput // These methods are defined in mouseInput.cpp + + struct MouseButtonState + { + bool isLeftButtonDown; + bool isMiddleButtonDown; + bool isRightButtonDown; + }; + bool HandleMouse(const COORD position, const unsigned int button, const short modifierKeyState, - const short delta); + const short delta, + const MouseButtonState state); bool IsTrackingMouseInput() const noexcept; #pragma endregion @@ -136,7 +145,7 @@ namespace Microsoft::Console::VirtualTerminal bool _ShouldSendAlternateScroll(const unsigned int button, const short delta) const noexcept; bool _SendAlternateScroll(const short delta) const noexcept; - static unsigned int s_GetPressedButton() noexcept; + static constexpr unsigned int s_GetPressedButton(const MouseButtonState state) noexcept; #pragma endregion }; } From aee803e694a876ff89fef786dad4ae0198dc461f Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Mon, 10 Aug 2020 11:21:56 -0500 Subject: [PATCH 032/266] Add support for changing the active color scheme with an action (#6993) ## Summary of the Pull Request Adds the `setColorScheme` action, to change the color scheme of the active control to one given by the `name` parameter. `name` is required. If `name` is not the name of a color scheme, the action does nothing. ## References * Being done as a stepping stone to #6689 ## PR Checklist * [x] Closes #5401 * [x] I work here * [ ] Tests added/passed * [n/a] Requires documentation to be updated ## Detailed Description of the Pull Request / Additional comments Technically, the action is being done by changing the settings of the current `TerminalSettings` of the `TermControl`. Frankly, it should be operating on a copy of the `TermControl`'s `IControlSettings`, then updating the control's settings, or the Control should just listen for changes to it's setting's properties, and update in real time (without a manual call to `UpdateSettings`. However, both those paths are somewhere unknowable beyond #6904, so we'll just do this for now. ## Validation Steps Performed * tested manually with a scheme that exists * tested manually with a scheme that doesn't exist --- doc/cascadia/profiles.schema.json | 19 +++++++++++ src/cascadia/TerminalApp/ActionAndArgs.cpp | 5 +++ src/cascadia/TerminalApp/ActionArgs.cpp | 14 ++++++++ src/cascadia/TerminalApp/ActionArgs.h | 33 +++++++++++++++++++ src/cascadia/TerminalApp/ActionArgs.idl | 5 +++ .../TerminalApp/AppActionHandlers.cpp | 21 ++++++++++++ src/cascadia/TerminalApp/CascadiaSettings.cpp | 23 +++++++++++++ src/cascadia/TerminalApp/CascadiaSettings.h | 2 ++ src/cascadia/TerminalApp/ColorScheme.cpp | 2 +- src/cascadia/TerminalApp/ColorScheme.h | 2 +- .../Resources/en-US/Resources.resw | 4 +++ .../TerminalApp/ShortcutActionDispatch.cpp | 5 +++ .../TerminalApp/ShortcutActionDispatch.h | 1 + .../TerminalApp/ShortcutActionDispatch.idl | 2 ++ src/cascadia/TerminalApp/TerminalPage.cpp | 1 + src/cascadia/TerminalApp/TerminalPage.h | 1 + src/cascadia/TerminalControl/TermControl.cpp | 5 +++ src/cascadia/TerminalControl/TermControl.h | 1 + src/cascadia/TerminalControl/TermControl.idl | 2 ++ 19 files changed, 146 insertions(+), 2 deletions(-) diff --git a/doc/cascadia/profiles.schema.json b/doc/cascadia/profiles.schema.json index a4dbd3d806d..38bdd5352ab 100644 --- a/doc/cascadia/profiles.schema.json +++ b/doc/cascadia/profiles.schema.json @@ -59,6 +59,7 @@ "toggleAlwaysOnTop", "toggleRetroEffect", "find", + "setColorScheme", "setTabColor", "openTabColorPicker", "renameTab", @@ -283,6 +284,23 @@ } ] }, + "SetColorSchemeAction": { + "description": "Arguments corresponding to a Set Color Scheme Action", + "allOf": [ + { "$ref": "#/definitions/ShortcutAction" }, + { + "properties": { + "action": { "type": "string", "pattern": "setColorScheme" }, + "colorScheme": { + "type": "string", + "default": "", + "description": "the name of the scheme to apply to the active pane" + } + } + } + ], + "required": [ "name" ] + }, "WtAction": { "description": "Arguments corresponding to a wt Action", "allOf": [ @@ -350,6 +368,7 @@ { "$ref": "#/definitions/SplitPaneAction" }, { "$ref": "#/definitions/OpenSettingsAction" }, { "$ref": "#/definitions/SetTabColorAction" }, + { "$ref": "#/definitions/SetColorSchemeAction" }, { "$ref": "#/definitions/WtAction" }, { "$ref": "#/definitions/CloseOtherTabsAction" }, { "$ref": "#/definitions/CloseTabsAfterAction" }, diff --git a/src/cascadia/TerminalApp/ActionAndArgs.cpp b/src/cascadia/TerminalApp/ActionAndArgs.cpp index f784345ba5a..f4511a00d26 100644 --- a/src/cascadia/TerminalApp/ActionAndArgs.cpp +++ b/src/cascadia/TerminalApp/ActionAndArgs.cpp @@ -36,6 +36,7 @@ static constexpr std::string_view ToggleRetroEffectKey{ "toggleRetroEffect" }; static constexpr std::string_view ToggleFocusModeKey{ "toggleFocusMode" }; static constexpr std::string_view ToggleFullscreenKey{ "toggleFullscreen" }; static constexpr std::string_view ToggleAlwaysOnTopKey{ "toggleAlwaysOnTop" }; +static constexpr std::string_view SetColorSchemeKey{ "setColorScheme" }; static constexpr std::string_view SetTabColorKey{ "setTabColor" }; static constexpr std::string_view OpenTabColorPickerKey{ "openTabColorPicker" }; static constexpr std::string_view RenameTabKey{ "renameTab" }; @@ -83,6 +84,7 @@ namespace winrt::TerminalApp::implementation { ResizePaneKey, ShortcutAction::ResizePane }, { MoveFocusKey, ShortcutAction::MoveFocus }, { OpenSettingsKey, ShortcutAction::OpenSettings }, + { SetColorSchemeKey, ShortcutAction::SetColorScheme }, { ToggleRetroEffectKey, ShortcutAction::ToggleRetroEffect }, { ToggleFocusModeKey, ShortcutAction::ToggleFocusMode }, { ToggleFullscreenKey, ShortcutAction::ToggleFullscreen }, @@ -125,6 +127,8 @@ namespace winrt::TerminalApp::implementation { ShortcutAction::OpenSettings, winrt::TerminalApp::implementation::OpenSettingsArgs::FromJson }, + { ShortcutAction::SetColorScheme, winrt::TerminalApp::implementation::SetColorSchemeArgs::FromJson }, + { ShortcutAction::SetTabColor, winrt::TerminalApp::implementation::SetTabColorArgs::FromJson }, { ShortcutAction::RenameTab, winrt::TerminalApp::implementation::RenameTabArgs::FromJson }, @@ -280,6 +284,7 @@ namespace winrt::TerminalApp::implementation { ShortcutAction::TogglePaneZoom, RS_(L"TogglePaneZoomCommandKey") }, { ShortcutAction::Invalid, L"" }, { ShortcutAction::Find, RS_(L"FindCommandKey") }, + { ShortcutAction::SetColorScheme, L"" }, { ShortcutAction::SetTabColor, RS_(L"ResetTabColorCommandKey") }, { ShortcutAction::OpenTabColorPicker, RS_(L"OpenTabColorPickerCommandKey") }, { ShortcutAction::RenameTab, RS_(L"ResetTabNameCommandKey") }, diff --git a/src/cascadia/TerminalApp/ActionArgs.cpp b/src/cascadia/TerminalApp/ActionArgs.cpp index 27425c58fc7..eedf3338d9a 100644 --- a/src/cascadia/TerminalApp/ActionArgs.cpp +++ b/src/cascadia/TerminalApp/ActionArgs.cpp @@ -15,6 +15,7 @@ #include "AdjustFontSizeArgs.g.cpp" #include "SplitPaneArgs.g.cpp" #include "OpenSettingsArgs.g.cpp" +#include "SetColorSchemeArgs.g.cpp" #include "SetTabColorArgs.g.cpp" #include "RenameTabArgs.g.cpp" #include "ExecuteCommandlineArgs.g.cpp" @@ -229,6 +230,19 @@ namespace winrt::TerminalApp::implementation } } + winrt::hstring SetColorSchemeArgs::GenerateName() const + { + // "Set color scheme to "{_SchemeName}"" + if (!_SchemeName.empty()) + { + return winrt::hstring{ + fmt::format(std::wstring_view(RS_(L"SetColorSchemeCommandKey")), + _SchemeName.c_str()) + }; + } + return L""; + } + winrt::hstring SetTabColorArgs::GenerateName() const { // "Set tab color to #RRGGBB" diff --git a/src/cascadia/TerminalApp/ActionArgs.h b/src/cascadia/TerminalApp/ActionArgs.h index 941b4716a8f..ac84dde5a5c 100644 --- a/src/cascadia/TerminalApp/ActionArgs.h +++ b/src/cascadia/TerminalApp/ActionArgs.h @@ -15,6 +15,7 @@ #include "AdjustFontSizeArgs.g.h" #include "SplitPaneArgs.g.h" #include "OpenSettingsArgs.g.h" +#include "SetColorSchemeArgs.g.h" #include "SetTabColorArgs.g.h" #include "RenameTabArgs.g.h" #include "ExecuteCommandlineArgs.g.h" @@ -332,6 +333,38 @@ namespace winrt::TerminalApp::implementation } }; + struct SetColorSchemeArgs : public SetColorSchemeArgsT + { + SetColorSchemeArgs() = default; + GETSET_PROPERTY(winrt::hstring, SchemeName, L""); + + static constexpr std::string_view NameKey{ "colorScheme" }; + + public: + hstring GenerateName() const; + + bool Equals(const IActionArgs& other) + { + auto otherAsUs = other.try_as(); + if (otherAsUs) + { + return otherAsUs->_SchemeName == _SchemeName; + } + return false; + }; + static FromJsonResult FromJson(const Json::Value& json) + { + // LOAD BEARING: Not using make_self here _will_ break you in the future! + auto args = winrt::make_self(); + JsonUtils::GetValueForKey(json, NameKey, args->_SchemeName); + if (args->_SchemeName.empty()) + { + return { nullptr, { ::TerminalApp::SettingsLoadWarnings::MissingRequiredParameter } }; + } + return { *args, {} }; + } + }; + struct SetTabColorArgs : public SetTabColorArgsT { SetTabColorArgs() = default; diff --git a/src/cascadia/TerminalApp/ActionArgs.idl b/src/cascadia/TerminalApp/ActionArgs.idl index bfeee27d3f6..e57c5243903 100644 --- a/src/cascadia/TerminalApp/ActionArgs.idl +++ b/src/cascadia/TerminalApp/ActionArgs.idl @@ -106,6 +106,11 @@ namespace TerminalApp SettingsTarget Target { get; }; }; + [default_interface] runtimeclass SetColorSchemeArgs : IActionArgs + { + String SchemeName { get; }; + }; + [default_interface] runtimeclass SetTabColorArgs : IActionArgs { Windows.Foundation.IReference TabColor { get; }; diff --git a/src/cascadia/TerminalApp/AppActionHandlers.cpp b/src/cascadia/TerminalApp/AppActionHandlers.cpp index c58a95b248c..1f062241e04 100644 --- a/src/cascadia/TerminalApp/AppActionHandlers.cpp +++ b/src/cascadia/TerminalApp/AppActionHandlers.cpp @@ -291,6 +291,27 @@ namespace winrt::TerminalApp::implementation args.Handled(true); } + void TerminalPage::_HandleSetColorScheme(const IInspectable& /*sender*/, + const TerminalApp::ActionEventArgs& args) + { + args.Handled(false); + if (const auto& realArgs = args.ActionArgs().try_as()) + { + if (auto activeTab = _GetFocusedTab()) + { + if (auto activeControl = activeTab->GetActiveTerminalControl()) + { + auto controlSettings = activeControl.Settings(); + if (_settings->ApplyColorScheme(controlSettings, realArgs.SchemeName())) + { + activeControl.UpdateSettings(controlSettings); + args.Handled(true); + } + } + } + } + } + void TerminalPage::_HandleSetTabColor(const IInspectable& /*sender*/, const TerminalApp::ActionEventArgs& args) { diff --git a/src/cascadia/TerminalApp/CascadiaSettings.cpp b/src/cascadia/TerminalApp/CascadiaSettings.cpp index 1206437256f..bca917d8480 100644 --- a/src/cascadia/TerminalApp/CascadiaSettings.cpp +++ b/src/cascadia/TerminalApp/CascadiaSettings.cpp @@ -744,3 +744,26 @@ const ColorScheme* CascadiaSettings::GetColorSchemeForProfile(const GUID profile return nullptr; } } + +// Method Description: +// - Apply the color scheme (provided by name) to the given IControlSettings. +// The settings are modified in-place. +// - If the name doesn't correspond to any of our schemes, this does nothing. +// Arguments: +// - settings: the IControlSettings object to modify +// - name: the name of the scheme to apply +// Return Value: +// - true iff we found a matching scheme for the name schemeName +bool CascadiaSettings::ApplyColorScheme(winrt::Microsoft::Terminal::TerminalControl::IControlSettings& settings, + std::wstring_view schemeName) +{ + std::wstring name{ schemeName }; + auto schemeAndName = _globals.GetColorSchemes().find(name); + if (schemeAndName != _globals.GetColorSchemes().end()) + { + const auto& scheme = schemeAndName->second; + scheme.ApplyScheme(settings); + return true; + } + return false; +} diff --git a/src/cascadia/TerminalApp/CascadiaSettings.h b/src/cascadia/TerminalApp/CascadiaSettings.h index 08a65fba5d7..981264e10f2 100644 --- a/src/cascadia/TerminalApp/CascadiaSettings.h +++ b/src/cascadia/TerminalApp/CascadiaSettings.h @@ -74,6 +74,8 @@ class TerminalApp::CascadiaSettings final std::vector& GetWarnings(); + bool ApplyColorScheme(winrt::Microsoft::Terminal::TerminalControl::IControlSettings& settings, std::wstring_view schemeName); + private: GlobalAppSettings _globals; std::vector _profiles; diff --git a/src/cascadia/TerminalApp/ColorScheme.cpp b/src/cascadia/TerminalApp/ColorScheme.cpp index b04090b6e03..af70c3595e4 100644 --- a/src/cascadia/TerminalApp/ColorScheme.cpp +++ b/src/cascadia/TerminalApp/ColorScheme.cpp @@ -67,7 +67,7 @@ ColorScheme::~ColorScheme() // - terminalSettings: the object to apply our settings to. // Return Value: // - -void ColorScheme::ApplyScheme(TerminalSettings terminalSettings) const +void ColorScheme::ApplyScheme(const winrt::Microsoft::Terminal::TerminalControl::IControlSettings& terminalSettings) const { terminalSettings.DefaultForeground(static_cast(_defaultForeground)); terminalSettings.DefaultBackground(static_cast(_defaultBackground)); diff --git a/src/cascadia/TerminalApp/ColorScheme.h b/src/cascadia/TerminalApp/ColorScheme.h index 4eafdc75b7c..2267eb8f006 100644 --- a/src/cascadia/TerminalApp/ColorScheme.h +++ b/src/cascadia/TerminalApp/ColorScheme.h @@ -37,7 +37,7 @@ class TerminalApp::ColorScheme ColorScheme(std::wstring name, til::color defaultFg, til::color defaultBg, til::color cursorColor); ~ColorScheme(); - void ApplyScheme(winrt::TerminalApp::TerminalSettings terminalSettings) const; + void ApplyScheme(const winrt::Microsoft::Terminal::TerminalControl::IControlSettings& terminalSettings) const; static ColorScheme FromJson(const Json::Value& json); bool ShouldBeLayered(const Json::Value& json) const; diff --git a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw index 25fc712d10f..aaded2a06b4 100644 --- a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw +++ b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw @@ -529,6 +529,10 @@ Toggle command palette + + Set color scheme to {0} + {0} will be replaced with the name of a color scheme as defined by the user. + Set tab color to {0} {0} will be replaced with a color, displayed in hexadecimal (#RRGGBB) notation. diff --git a/src/cascadia/TerminalApp/ShortcutActionDispatch.cpp b/src/cascadia/TerminalApp/ShortcutActionDispatch.cpp index 2f6a1a280c6..862eb1a9de6 100644 --- a/src/cascadia/TerminalApp/ShortcutActionDispatch.cpp +++ b/src/cascadia/TerminalApp/ShortcutActionDispatch.cpp @@ -185,6 +185,11 @@ namespace winrt::TerminalApp::implementation _ToggleCommandPaletteHandlers(*this, *eventArgs); break; } + case ShortcutAction::SetColorScheme: + { + _SetColorSchemeHandlers(*this, *eventArgs); + break; + } case ShortcutAction::SetTabColor: { _SetTabColorHandlers(*this, *eventArgs); diff --git a/src/cascadia/TerminalApp/ShortcutActionDispatch.h b/src/cascadia/TerminalApp/ShortcutActionDispatch.h index 963bfbea447..1005129b531 100644 --- a/src/cascadia/TerminalApp/ShortcutActionDispatch.h +++ b/src/cascadia/TerminalApp/ShortcutActionDispatch.h @@ -52,6 +52,7 @@ namespace winrt::TerminalApp::implementation TYPED_EVENT(ToggleFullscreen, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs); TYPED_EVENT(ToggleAlwaysOnTop, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs); TYPED_EVENT(ToggleCommandPalette, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs); + TYPED_EVENT(SetColorScheme, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs); TYPED_EVENT(SetTabColor, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs); TYPED_EVENT(OpenTabColorPicker, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs); TYPED_EVENT(RenameTab, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs); diff --git a/src/cascadia/TerminalApp/ShortcutActionDispatch.idl b/src/cascadia/TerminalApp/ShortcutActionDispatch.idl index 4136e44a97e..83681760755 100644 --- a/src/cascadia/TerminalApp/ShortcutActionDispatch.idl +++ b/src/cascadia/TerminalApp/ShortcutActionDispatch.idl @@ -37,6 +37,7 @@ namespace TerminalApp ToggleFullscreen, ToggleAlwaysOnTop, OpenSettings, + SetColorScheme, SetTabColor, OpenTabColorPicker, RenameTab, @@ -86,6 +87,7 @@ namespace TerminalApp event Windows.Foundation.TypedEventHandler ToggleFullscreen; event Windows.Foundation.TypedEventHandler ToggleAlwaysOnTop; event Windows.Foundation.TypedEventHandler ToggleCommandPalette; + event Windows.Foundation.TypedEventHandler SetColorScheme; event Windows.Foundation.TypedEventHandler SetTabColor; event Windows.Foundation.TypedEventHandler OpenTabColorPicker; event Windows.Foundation.TypedEventHandler RenameTab; diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index 309fb12fe09..3b245440c03 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -890,6 +890,7 @@ namespace winrt::TerminalApp::implementation _actionDispatch->ToggleFullscreen({ this, &TerminalPage::_HandleToggleFullscreen }); _actionDispatch->ToggleAlwaysOnTop({ this, &TerminalPage::_HandleToggleAlwaysOnTop }); _actionDispatch->ToggleCommandPalette({ this, &TerminalPage::_HandleToggleCommandPalette }); + _actionDispatch->SetColorScheme({ this, &TerminalPage::_HandleSetColorScheme }); _actionDispatch->SetTabColor({ this, &TerminalPage::_HandleSetTabColor }); _actionDispatch->OpenTabColorPicker({ this, &TerminalPage::_HandleOpenTabColorPicker }); _actionDispatch->RenameTab({ this, &TerminalPage::_HandleRenameTab }); diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h index 1228226f6c1..30ca3bced58 100644 --- a/src/cascadia/TerminalApp/TerminalPage.h +++ b/src/cascadia/TerminalApp/TerminalPage.h @@ -222,6 +222,7 @@ namespace winrt::TerminalApp::implementation void _HandleToggleFocusMode(const IInspectable& sender, const TerminalApp::ActionEventArgs& args); void _HandleToggleFullscreen(const IInspectable& sender, const TerminalApp::ActionEventArgs& args); void _HandleToggleAlwaysOnTop(const IInspectable& sender, const TerminalApp::ActionEventArgs& args); + void _HandleSetColorScheme(const IInspectable& sender, const TerminalApp::ActionEventArgs& args); void _HandleSetTabColor(const IInspectable& sender, const TerminalApp::ActionEventArgs& args); void _HandleOpenTabColorPicker(const IInspectable& sender, const TerminalApp::ActionEventArgs& args); void _HandleRenameTab(const IInspectable& sender, const TerminalApp::ActionEventArgs& args); diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index d14fb9c9061..245413fe75c 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -2838,6 +2838,11 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation _renderer->ResetErrorStateAndResume(); } + IControlSettings TermControl::Settings() const + { + return _settings; + } + Windows::Foundation::IReference TermControl::TabColor() noexcept { auto coreColor = _terminal->GetTabColor(); diff --git a/src/cascadia/TerminalControl/TermControl.h b/src/cascadia/TerminalControl/TermControl.h index f3d91c5c0b3..a3f26712962 100644 --- a/src/cascadia/TerminalControl/TermControl.h +++ b/src/cascadia/TerminalControl/TermControl.h @@ -102,6 +102,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation const Windows::UI::Xaml::Thickness GetPadding(); TerminalConnection::ConnectionState ConnectionState() const; + IControlSettings Settings() const; static Windows::Foundation::Size GetProposedDimensions(IControlSettings const& settings, const uint32_t dpi); static Windows::Foundation::Size GetProposedDimensions(const winrt::Windows::Foundation::Size& initialSizeInChars, diff --git a/src/cascadia/TerminalControl/TermControl.idl b/src/cascadia/TerminalControl/TermControl.idl index 89e4634e968..85b6e602cfd 100644 --- a/src/cascadia/TerminalControl/TermControl.idl +++ b/src/cascadia/TerminalControl/TermControl.idl @@ -39,6 +39,8 @@ namespace Microsoft.Terminal.TerminalControl void UpdateSettings(Microsoft.Terminal.TerminalControl.IControlSettings newSettings); + Microsoft.Terminal.TerminalControl.IControlSettings Settings { get; }; + event TitleChangedEventArgs TitleChanged; event FontSizeChangedEventArgs FontSizeChanged; event Windows.Foundation.TypedEventHandler CopyToClipboard; From e7a1a675af7d3aaa0444fd8d15e3652ffccd70c3 Mon Sep 17 00:00:00 2001 From: James Holderness Date: Mon, 10 Aug 2020 18:06:16 +0100 Subject: [PATCH 033/266] Add support for the "doubly underlined" graphic rendition attribute (#7223) This PR adds support for the ANSI _doubly underlined_ graphic rendition attribute, which is enabled by the `SGR 21` escape sequence. There was already an `ExtendedAttributes::DoublyUnderlined` flag in the `TextAttribute` class, but I needed to add `SetDoublyUnderlined` and `IsDoublyUnderlined` methods to access that flag, and update the `SetGraphicsRendition` methods of the two dispatchers to set the attribute on receipt of the `SGR 21` sequence. I also had to update the existing `SGR 24` handler to reset _DoublyUnderlined_ in addition to _Underlined_, since they share the same reset sequence. For the rendering, I've added a new grid line type, which essentially just draws an additional line with the same thickness as the regular underline, but slightly below it - I found a gap of around 0.05 "em" between the lines looked best. If there isn't enough space in the cell for that gap, the second line will be clamped to overlap the first, so you then just get a thicker line. If there isn't even enough space below for a thicker line, we move the offset _above_ the first line, but just enough to make it thicker. The only other complication was the update of the `Xterm256Engine` in the VT renderer. As mentioned above, the two underline attributes share the same reset sequence, so to forward that state over conpty we require a slightly more complicated process than with most other attributes (similar to _Bold_ and _Faint_). We first check whether either underline attribute needs to be turned off to send the reset sequence, and then check individually if each of them needs to be turned back on again. ## Validation Steps Performed For testing, I've extended the existing attribute tests in `AdapterTest`, `VTRendererTest`, and `ScreenBufferTests`, to make sure we're covering both the _Underlined_ and _DoublyUnderlined_ attributes. I've also manually tested the `SGR 21` sequence in conhost and Windows Terminal, with a variety of fonts and font sizes, to make sure the rendering was reasonably distinguishable from a single underline. Closes #2916 --- src/buffer/out/TextAttribute.cpp | 10 ++++ src/buffer/out/TextAttribute.hpp | 2 + .../TerminalCore/TerminalDispatchGraphics.cpp | 4 ++ src/host/ut_host/ScreenBufferTests.cpp | 47 ++++++++++++++++++- src/host/ut_host/VtRendererTests.cpp | 29 +++++++++++- src/inc/conattrs.hpp | 3 +- src/renderer/base/renderer.cpp | 5 ++ src/renderer/dx/DxRenderer.cpp | 29 +++++++++++- src/renderer/dx/DxRenderer.hpp | 1 + src/renderer/gdi/gdirenderer.hpp | 1 + src/renderer/gdi/paint.cpp | 8 +++- src/renderer/gdi/state.cpp | 18 +++++++ src/renderer/inc/IRenderEngine.hpp | 3 +- src/renderer/vt/VtSequences.cpp | 11 +++++ src/renderer/vt/Xterm256Engine.cpp | 24 ++++++++-- src/renderer/vt/vtrenderer.hpp | 1 + src/terminal/adapter/DispatchTypes.hpp | 1 - .../adapter/adaptDispatchGraphics.cpp | 4 ++ .../adapter/ut_adapter/adapterTest.cpp | 9 +++- 19 files changed, 195 insertions(+), 15 deletions(-) diff --git a/src/buffer/out/TextAttribute.cpp b/src/buffer/out/TextAttribute.cpp index ad7ee0546e7..06c94184432 100644 --- a/src/buffer/out/TextAttribute.cpp +++ b/src/buffer/out/TextAttribute.cpp @@ -249,6 +249,11 @@ bool TextAttribute::IsUnderlined() const noexcept return WI_IsFlagSet(_extendedAttrs, ExtendedAttributes::Underlined); } +bool TextAttribute::IsDoublyUnderlined() const noexcept +{ + return WI_IsFlagSet(_extendedAttrs, ExtendedAttributes::DoublyUnderlined); +} + bool TextAttribute::IsOverlined() const noexcept { return WI_IsFlagSet(_wAttrLegacy, COMMON_LVB_GRID_HORIZONTAL); @@ -294,6 +299,11 @@ void TextAttribute::SetUnderlined(bool isUnderlined) noexcept WI_UpdateFlag(_extendedAttrs, ExtendedAttributes::Underlined, isUnderlined); } +void TextAttribute::SetDoublyUnderlined(bool isDoublyUnderlined) noexcept +{ + WI_UpdateFlag(_extendedAttrs, ExtendedAttributes::DoublyUnderlined, isDoublyUnderlined); +} + void TextAttribute::SetOverlined(bool isOverlined) noexcept { WI_UpdateFlag(_wAttrLegacy, COMMON_LVB_GRID_HORIZONTAL, isOverlined); diff --git a/src/buffer/out/TextAttribute.hpp b/src/buffer/out/TextAttribute.hpp index 7cec03f75e6..22c61a6aa91 100644 --- a/src/buffer/out/TextAttribute.hpp +++ b/src/buffer/out/TextAttribute.hpp @@ -95,6 +95,7 @@ class TextAttribute final bool IsInvisible() const noexcept; bool IsCrossedOut() const noexcept; bool IsUnderlined() const noexcept; + bool IsDoublyUnderlined() const noexcept; bool IsOverlined() const noexcept; bool IsReverseVideo() const noexcept; @@ -105,6 +106,7 @@ class TextAttribute final void SetInvisible(bool isInvisible) noexcept; void SetCrossedOut(bool isCrossedOut) noexcept; void SetUnderlined(bool isUnderlined) noexcept; + void SetDoublyUnderlined(bool isDoublyUnderlined) noexcept; void SetOverlined(bool isOverlined) noexcept; void SetReverseVideo(bool isReversed) noexcept; diff --git a/src/cascadia/TerminalCore/TerminalDispatchGraphics.cpp b/src/cascadia/TerminalCore/TerminalDispatchGraphics.cpp index f8ff0d129da..635d9bded26 100644 --- a/src/cascadia/TerminalCore/TerminalDispatchGraphics.cpp +++ b/src/cascadia/TerminalCore/TerminalDispatchGraphics.cpp @@ -158,8 +158,12 @@ bool TerminalDispatch::SetGraphicsRendition(const gsl::span_expectedAttribute = TextAttribute{ 0 }; _testGetSet->_expectedAttribute.SetUnderlined(true); break; + case DispatchTypes::GraphicsOptions::DoublyUnderlined: + Log::Comment(L"Testing graphics 'Doubly Underlined'"); + _testGetSet->_attribute = TextAttribute{ 0 }; + _testGetSet->_expectedAttribute = TextAttribute{ 0 }; + _testGetSet->_expectedAttribute.SetDoublyUnderlined(true); + break; case DispatchTypes::GraphicsOptions::Overline: Log::Comment(L"Testing graphics 'Overline'"); _testGetSet->_attribute = TextAttribute{ 0 }; @@ -1334,6 +1340,7 @@ class AdapterTest Log::Comment(L"Testing graphics 'No Underline'"); _testGetSet->_attribute = TextAttribute{ 0 }; _testGetSet->_attribute.SetUnderlined(true); + _testGetSet->_attribute.SetDoublyUnderlined(true); _testGetSet->_expectedAttribute = TextAttribute{ 0 }; break; case DispatchTypes::GraphicsOptions::NoOverline: From e6c71cb62a8389d7e7868a9bbacff4f5975bb514 Mon Sep 17 00:00:00 2001 From: "Dustin L. Howett" Date: Mon, 10 Aug 2020 12:48:33 -0700 Subject: [PATCH 034/266] Allow profile.padding to be an int (or any other type :|) (#7235) ## Summary of the Pull Request We're expecting that people have treated `padding` as an integer, and the type-based converter is too strict for that. This PR widens its scope and explicitly allows for it in the schema. ## PR Checklist * [x] Closes #7234 --- doc/cascadia/profiles.schema.json | 11 +++++++++-- src/cascadia/TerminalApp/JsonUtils.h | 19 +++++++++++++++++++ src/cascadia/TerminalApp/Profile.cpp | 6 +++++- 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/doc/cascadia/profiles.schema.json b/doc/cascadia/profiles.schema.json index 38bdd5352ab..fbdba1eb742 100644 --- a/doc/cascadia/profiles.schema.json +++ b/doc/cascadia/profiles.schema.json @@ -735,8 +735,15 @@ "padding": { "default": "8, 8, 8, 8", "description": "Sets the padding around the text within the window. Can have three different formats:\n -\"#\" sets the same padding for all sides \n -\"#, #\" sets the same padding for left-right and top-bottom\n -\"#, #, #, #\" sets the padding individually for left, top, right, and bottom.", - "pattern": "^-?[0-9]+(\\.[0-9]+)?( *, *-?[0-9]+(\\.[0-9]+)?|( *, *-?[0-9]+(\\.[0-9]+)?){3})?$", - "type": "string" + "oneOf": [ + { + "pattern": "^-?[0-9]+(\\.[0-9]+)?( *, *-?[0-9]+(\\.[0-9]+)?|( *, *-?[0-9]+(\\.[0-9]+)?){3})?$", + "type": "string" + }, + { + "type": "integer" + } + ] }, "scrollbarState": { "default": "visible", diff --git a/src/cascadia/TerminalApp/JsonUtils.h b/src/cascadia/TerminalApp/JsonUtils.h index b98ade1da9d..9a9c9c676e5 100644 --- a/src/cascadia/TerminalApp/JsonUtils.h +++ b/src/cascadia/TerminalApp/JsonUtils.h @@ -360,6 +360,25 @@ namespace TerminalApp::JsonUtils } }; + template + struct PermissiveStringConverter + { + }; + + template<> + struct PermissiveStringConverter + { + std::wstring FromJson(const Json::Value& json) + { + return til::u8u16(json.asString()); + } + + bool CanConvert(const Json::Value& /*unused*/) + { + return true; + } + }; + // Method Description: // - Helper that will populate a reference with a value converted from a json object. // Arguments: diff --git a/src/cascadia/TerminalApp/Profile.cpp b/src/cascadia/TerminalApp/Profile.cpp index 22e627ad896..b1ad96ae3f2 100644 --- a/src/cascadia/TerminalApp/Profile.cpp +++ b/src/cascadia/TerminalApp/Profile.cpp @@ -402,7 +402,11 @@ void Profile::LayerJson(const Json::Value& json) JsonUtils::GetValueForKey(json, UseAcrylicKey, _useAcrylic); JsonUtils::GetValueForKey(json, SuppressApplicationTitleKey, _suppressApplicationTitle); JsonUtils::GetValueForKey(json, CloseOnExitKey, _closeOnExitMode); - JsonUtils::GetValueForKey(json, PaddingKey, _padding); + + // Padding was never specified as an integer, but it was a common working mistake. + // Allow it to be permissive. + JsonUtils::GetValueForKey(json, PaddingKey, _padding, JsonUtils::PermissiveStringConverter{}); + JsonUtils::GetValueForKey(json, ScrollbarStateKey, _scrollbarState); JsonUtils::GetValueForKey(json, StartingDirectoryKey, _startingDirectory); JsonUtils::GetValueForKey(json, IconKey, _icon); From c03677b0c9f5b9a0a56c9767c7e65e0a0e723dd7 Mon Sep 17 00:00:00 2001 From: "Dustin L. Howett" Date: Mon, 10 Aug 2020 14:48:27 -0700 Subject: [PATCH 035/266] Resolve the default profile during defaults load, don't crash on launch (#7237) The "default profile as name" feature in 1.1 broke the loading of default settings, as we would never get to the validation phase where the default profile string was transformed into a guid. I moved knowledge of the "unparsed default profile" optional to the consumer so that we could make sure we only attempted to deserialize it once (and only if it was present.) Fixes #7236. ## PR Checklist * [x] Closes #7236 --- src/cascadia/TerminalApp/CascadiaSettings.cpp | 9 ++++++--- .../TerminalApp/CascadiaSettingsSerialization.cpp | 6 +++--- src/cascadia/TerminalApp/GlobalAppSettings.cpp | 4 ++-- src/cascadia/TerminalApp/GlobalAppSettings.h | 2 +- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/cascadia/TerminalApp/CascadiaSettings.cpp b/src/cascadia/TerminalApp/CascadiaSettings.cpp index bca917d8480..182ae429b2d 100644 --- a/src/cascadia/TerminalApp/CascadiaSettings.cpp +++ b/src/cascadia/TerminalApp/CascadiaSettings.cpp @@ -225,9 +225,12 @@ void CascadiaSettings::_ValidateProfilesHaveGuid() void CascadiaSettings::_ResolveDefaultProfile() { const auto unparsedDefaultProfile{ GlobalSettings().UnparsedDefaultProfile() }; - auto maybeParsedDefaultProfile{ _GetProfileGuidByName(unparsedDefaultProfile) }; - auto defaultProfileGuid{ til::coalesce_value(maybeParsedDefaultProfile, GUID{}) }; - GlobalSettings().DefaultProfile(defaultProfileGuid); + if (unparsedDefaultProfile) + { + auto maybeParsedDefaultProfile{ _GetProfileGuidByName(*unparsedDefaultProfile) }; + auto defaultProfileGuid{ til::coalesce_value(maybeParsedDefaultProfile, GUID{}) }; + GlobalSettings().DefaultProfile(defaultProfileGuid); + } } // Method Description: diff --git a/src/cascadia/TerminalApp/CascadiaSettingsSerialization.cpp b/src/cascadia/TerminalApp/CascadiaSettingsSerialization.cpp index 1a8f2b6e71f..85b51bf549a 100644 --- a/src/cascadia/TerminalApp/CascadiaSettingsSerialization.cpp +++ b/src/cascadia/TerminalApp/CascadiaSettingsSerialization.cpp @@ -61,7 +61,7 @@ std::unique_ptr CascadiaSettings::LoadAll() // GH 3588, we need this below to know if the user chose something that wasn't our default. // Collect it up here in case it gets modified by any of the other layers between now and when // the user's preferences are loaded and layered. - const auto hardcodedDefaultGuid = resultPtr->GlobalSettings().UnparsedDefaultProfile(); + const auto hardcodedDefaultGuid = resultPtr->GlobalSettings().DefaultProfile(); std::optional fileData = _ReadUserSettings(); const bool foundFile = fileData.has_value(); @@ -141,12 +141,11 @@ std::unique_ptr CascadiaSettings::LoadAll() // is a lot of computation we can skip if no one cares. if (TraceLoggingProviderEnabled(g_hTerminalAppProvider, 0, MICROSOFT_KEYWORD_MEASURES)) { - const auto hardcodedDefaultGuidAsGuid = Utils::GuidFromString(hardcodedDefaultGuid); const auto guid = resultPtr->GlobalSettings().DefaultProfile(); // Compare to the defaults.json one that we set on install. // If it's different, log what the user chose. - if (hardcodedDefaultGuidAsGuid != guid) + if (hardcodedDefaultGuid != guid) { TraceLoggingWrite( g_hTerminalAppProvider, // handle to TerminalApp tracelogging provider @@ -229,6 +228,7 @@ std::unique_ptr CascadiaSettings::LoadDefaults() // them from a file (and the potential that could fail) resultPtr->_ParseJsonString(DefaultJson, true); resultPtr->LayerJson(resultPtr->_defaultSettings); + resultPtr->_ResolveDefaultProfile(); return resultPtr; } diff --git a/src/cascadia/TerminalApp/GlobalAppSettings.cpp b/src/cascadia/TerminalApp/GlobalAppSettings.cpp index 00ce2cc3310..afeca688c6d 100644 --- a/src/cascadia/TerminalApp/GlobalAppSettings.cpp +++ b/src/cascadia/TerminalApp/GlobalAppSettings.cpp @@ -89,9 +89,9 @@ GUID GlobalAppSettings::DefaultProfile() const return _defaultProfile; } -std::wstring GlobalAppSettings::UnparsedDefaultProfile() const +std::optional GlobalAppSettings::UnparsedDefaultProfile() const { - return _unparsedDefaultProfile.value(); + return _unparsedDefaultProfile; } AppKeyBindings GlobalAppSettings::GetKeybindings() const noexcept diff --git a/src/cascadia/TerminalApp/GlobalAppSettings.h b/src/cascadia/TerminalApp/GlobalAppSettings.h index 78222106716..ba51109fa0b 100644 --- a/src/cascadia/TerminalApp/GlobalAppSettings.h +++ b/src/cascadia/TerminalApp/GlobalAppSettings.h @@ -56,7 +56,7 @@ class TerminalApp::GlobalAppSettings final // by higher layers in the app. void DefaultProfile(const GUID defaultProfile) noexcept; GUID DefaultProfile() const; - std::wstring UnparsedDefaultProfile() const; + std::optional UnparsedDefaultProfile() const; GETSET_PROPERTY(int32_t, InitialRows); // default value set in constructor GETSET_PROPERTY(int32_t, InitialCols); // default value set in constructor From b07c1e49da801dca853b97a0faeb0963a5fb494c Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Tue, 11 Aug 2020 07:03:12 -0700 Subject: [PATCH 036/266] Advanced Tab Switcher (#6732) ![TabSwitchingv2](https://user-images.githubusercontent.com/57155886/88237962-5505d500-cc35-11ea-8384-d91699155067.gif) ## Summary of the Pull Request This PR adds the Advanced Tab Switcher (ATS) to Terminal. It'll work similarly to VSCode's tab switcher. Because this implementation rides off a lot of the Command Palette's XAML code, it'll look just like the Command Palette, and also have support for tab title search. ## References #3753 - ATS Spec Closes #1502 --- doc/cascadia/profiles.schema.json | 26 ++ src/cascadia/TerminalApp/ActionAndArgs.cpp | 4 + src/cascadia/TerminalApp/ActionArgs.cpp | 19 + src/cascadia/TerminalApp/ActionArgs.h | 28 ++ src/cascadia/TerminalApp/ActionArgs.idl | 5 + .../TerminalApp/AppActionHandlers.cpp | 26 ++ src/cascadia/TerminalApp/Command.h | 3 + src/cascadia/TerminalApp/Command.idl | 2 + src/cascadia/TerminalApp/CommandPalette.cpp | 366 +++++++++++++++++- src/cascadia/TerminalApp/CommandPalette.h | 40 +- src/cascadia/TerminalApp/CommandPalette.idl | 12 +- src/cascadia/TerminalApp/CommandPalette.xaml | 131 ++++--- .../Resources/en-US/Resources.resw | 15 + .../TerminalApp/ShortcutActionDispatch.cpp | 5 + .../TerminalApp/ShortcutActionDispatch.h | 1 + .../TerminalApp/ShortcutActionDispatch.idl | 4 +- src/cascadia/TerminalApp/Tab.cpp | 4 +- src/cascadia/TerminalApp/Tab.h | 2 +- src/cascadia/TerminalApp/Tab.idl | 2 +- src/cascadia/TerminalApp/TerminalPage.cpp | 21 +- src/cascadia/TerminalApp/TerminalPage.h | 1 + .../TerminalSettingsSerializationHelpers.h | 9 + src/cascadia/inc/cppwinrt_utils.h | 4 +- 23 files changed, 644 insertions(+), 86 deletions(-) diff --git a/doc/cascadia/profiles.schema.json b/doc/cascadia/profiles.schema.json index fbdba1eb742..f1e1843bf96 100644 --- a/doc/cascadia/profiles.schema.json +++ b/doc/cascadia/profiles.schema.json @@ -67,6 +67,7 @@ "wt", "closeOtherTabs", "closeTabsAfter", + "tabSwitcher", "unbound" ], "type": "string" @@ -88,6 +89,14 @@ ], "type": "string" }, + "AnchorKey": { + "enum": [ + "ctrl", + "alt", + "shift" + ], + "type": "string" + }, "NewTerminalArgs": { "properties": { "commandline": { @@ -352,6 +361,22 @@ ], "required": [ "index" ] }, + "TabSwitcherAction": { + "description": "Arguments corresponding to a Tab Switcher Action", + "allOf": [ + { "$ref": "#/definitions/ShortcutAction" }, + { + "properties": { + "action": { "type": "string", "pattern": "tabSwitcher" }, + "anchorKey": { + "$ref": "#/definitions/AnchorKey", + "default": null, + "description": "If provided, the tab switcher will stay open as long as the anchor key is held down. The anchor key should be part of the keybinding that opens the switcher." + } + } + } + ] + }, "Keybinding": { "additionalProperties": false, "properties": { @@ -372,6 +397,7 @@ { "$ref": "#/definitions/WtAction" }, { "$ref": "#/definitions/CloseOtherTabsAction" }, { "$ref": "#/definitions/CloseTabsAfterAction" }, + { "$ref": "#/definitions/TabSwitcherAction" }, { "type": "null" } ] }, diff --git a/src/cascadia/TerminalApp/ActionAndArgs.cpp b/src/cascadia/TerminalApp/ActionAndArgs.cpp index f4511a00d26..fadadac3b24 100644 --- a/src/cascadia/TerminalApp/ActionAndArgs.cpp +++ b/src/cascadia/TerminalApp/ActionAndArgs.cpp @@ -44,6 +44,7 @@ static constexpr std::string_view ExecuteCommandlineKey{ "wt" }; static constexpr std::string_view ToggleCommandPaletteKey{ "commandPalette" }; static constexpr std::string_view CloseOtherTabsKey{ "closeOtherTabs" }; static constexpr std::string_view CloseTabsAfterKey{ "closeTabsAfter" }; +static constexpr std::string_view ToggleTabSwitcherKey{ "tabSwitcher" }; static constexpr std::string_view ActionKey{ "action" }; @@ -100,6 +101,7 @@ namespace winrt::TerminalApp::implementation { ToggleCommandPaletteKey, ShortcutAction::ToggleCommandPalette }, { CloseOtherTabsKey, ShortcutAction::CloseOtherTabs }, { CloseTabsAfterKey, ShortcutAction::CloseTabsAfter }, + { ToggleTabSwitcherKey, ShortcutAction::ToggleTabSwitcher }, }; using ParseResult = std::tuple>; @@ -139,6 +141,8 @@ namespace winrt::TerminalApp::implementation { ShortcutAction::CloseTabsAfter, winrt::TerminalApp::implementation::CloseTabsAfterArgs::FromJson }, + { ShortcutAction::ToggleTabSwitcher, winrt::TerminalApp::implementation::ToggleTabSwitcherArgs::FromJson }, + { ShortcutAction::Invalid, nullptr }, }; diff --git a/src/cascadia/TerminalApp/ActionArgs.cpp b/src/cascadia/TerminalApp/ActionArgs.cpp index eedf3338d9a..d6e7219fd13 100644 --- a/src/cascadia/TerminalApp/ActionArgs.cpp +++ b/src/cascadia/TerminalApp/ActionArgs.cpp @@ -19,6 +19,7 @@ #include "SetTabColorArgs.g.cpp" #include "RenameTabArgs.g.cpp" #include "ExecuteCommandlineArgs.g.cpp" +#include "ToggleTabSwitcherArgs.g.h" #include @@ -303,4 +304,22 @@ namespace winrt::TerminalApp::implementation _Index) }; } + + winrt::hstring ToggleTabSwitcherArgs::GenerateName() const + { + // If there's an anchor key set, don't generate a name so that + // it won't show up in the command palette. Only an unanchored + // tab switcher should be able to be toggled from the palette. + // TODO: GH#7179 - once this goes in, make sure to hide the + // anchor mode command that was given a name in settings. + if (_AnchorKey != Windows::System::VirtualKey::None) + { + return L""; + } + else + { + return RS_(L"ToggleTabSwitcherCommandKey"); + } + } + } diff --git a/src/cascadia/TerminalApp/ActionArgs.h b/src/cascadia/TerminalApp/ActionArgs.h index ac84dde5a5c..7c768d58054 100644 --- a/src/cascadia/TerminalApp/ActionArgs.h +++ b/src/cascadia/TerminalApp/ActionArgs.h @@ -21,6 +21,7 @@ #include "ExecuteCommandlineArgs.g.h" #include "CloseOtherTabsArgs.g.h" #include "CloseTabsAfterArgs.g.h" +#include "ToggleTabSwitcherArgs.g.h" #include "../../cascadia/inc/cppwinrt_utils.h" #include "Utils.h" @@ -512,6 +513,33 @@ namespace winrt::TerminalApp::implementation } }; + struct ToggleTabSwitcherArgs : public ToggleTabSwitcherArgsT + { + ToggleTabSwitcherArgs() = default; + GETSET_PROPERTY(Windows::System::VirtualKey, AnchorKey, Windows::System::VirtualKey::None); + + static constexpr std::string_view AnchorJsonKey{ "anchorKey" }; + + public: + hstring GenerateName() const; + + bool Equals(const IActionArgs& other) + { + auto otherAsUs = other.try_as(); + if (otherAsUs) + { + return otherAsUs->_AnchorKey == _AnchorKey; + } + return false; + }; + static FromJsonResult FromJson(const Json::Value& json) + { + // LOAD BEARING: Not using make_self here _will_ break you in the future! + auto args = winrt::make_self(); + JsonUtils::GetValueForKey(json, AnchorJsonKey, args->_AnchorKey); + return { *args, {} }; + } + }; } namespace winrt::TerminalApp::factory_implementation diff --git a/src/cascadia/TerminalApp/ActionArgs.idl b/src/cascadia/TerminalApp/ActionArgs.idl index e57c5243903..a460d712a92 100644 --- a/src/cascadia/TerminalApp/ActionArgs.idl +++ b/src/cascadia/TerminalApp/ActionArgs.idl @@ -135,4 +135,9 @@ namespace TerminalApp { UInt32 Index { get; }; }; + + [default_interface] runtimeclass ToggleTabSwitcherArgs : IActionArgs + { + Windows.System.VirtualKey AnchorKey { get; }; + }; } diff --git a/src/cascadia/TerminalApp/AppActionHandlers.cpp b/src/cascadia/TerminalApp/AppActionHandlers.cpp index 1f062241e04..19a8c44f2ad 100644 --- a/src/cascadia/TerminalApp/AppActionHandlers.cpp +++ b/src/cascadia/TerminalApp/AppActionHandlers.cpp @@ -285,6 +285,7 @@ namespace winrt::TerminalApp::implementation { // TODO GH#6677: When we add support for commandline mode, first set the // mode that the command palette should be in, before making it visible. + CommandPalette().EnableCommandPaletteMode(); CommandPalette().Visibility(CommandPalette().Visibility() == Visibility::Visible ? Visibility::Collapsed : Visibility::Visible); @@ -414,6 +415,7 @@ namespace winrt::TerminalApp::implementation actionArgs.Handled(true); } } + void TerminalPage::_HandleCloseTabsAfter(const IInspectable& /*sender*/, const TerminalApp::ActionEventArgs& actionArgs) { @@ -436,4 +438,28 @@ namespace winrt::TerminalApp::implementation actionArgs.Handled(true); } } + + void TerminalPage::_HandleToggleTabSwitcher(const IInspectable& /*sender*/, + const TerminalApp::ActionEventArgs& args) + { + if (const auto& realArgs = args.ActionArgs().try_as()) + { + auto anchorKey = realArgs.AnchorKey(); + + auto opt = _GetFocusedTabIndex(); + uint32_t startIdx = opt ? *opt : 0; + + if (anchorKey != VirtualKey::None) + { + // TODO: GH#7178 - delta should also have the option of being -1, in the case when + // a user decides to open the tab switcher going to the prev tab. + int delta = 1; + startIdx = (startIdx + _tabs.Size() + delta) % _tabs.Size(); + } + + CommandPalette().EnableTabSwitcherMode(anchorKey, startIdx); + CommandPalette().Visibility(Visibility::Visible); + } + args.Handled(true); + } } diff --git a/src/cascadia/TerminalApp/Command.h b/src/cascadia/TerminalApp/Command.h index 2882fc8244a..b037df3beb7 100644 --- a/src/cascadia/TerminalApp/Command.h +++ b/src/cascadia/TerminalApp/Command.h @@ -32,10 +32,13 @@ namespace winrt::TerminalApp::implementation static std::vector<::TerminalApp::SettingsLoadWarnings> LayerJson(std::unordered_map& commands, const Json::Value& json); + winrt::Windows::UI::Xaml::Data::INotifyPropertyChanged::PropertyChanged_revoker propertyChangedRevoker; + WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler); OBSERVABLE_GETSET_PROPERTY(winrt::hstring, Name, _PropertyChangedHandlers); OBSERVABLE_GETSET_PROPERTY(winrt::TerminalApp::ActionAndArgs, Action, _PropertyChangedHandlers); OBSERVABLE_GETSET_PROPERTY(winrt::hstring, KeyChordText, _PropertyChangedHandlers); + OBSERVABLE_GETSET_PROPERTY(winrt::Windows::UI::Xaml::Controls::IconSource, IconSource, _PropertyChangedHandlers, nullptr); }; } diff --git a/src/cascadia/TerminalApp/Command.idl b/src/cascadia/TerminalApp/Command.idl index 80e1a2b476b..f54de393f9e 100644 --- a/src/cascadia/TerminalApp/Command.idl +++ b/src/cascadia/TerminalApp/Command.idl @@ -12,5 +12,7 @@ namespace TerminalApp String Name; ActionAndArgs Action; String KeyChordText; + + Windows.UI.Xaml.Controls.IconSource IconSource; } } diff --git a/src/cascadia/TerminalApp/CommandPalette.cpp b/src/cascadia/TerminalApp/CommandPalette.cpp index f6fdfa9567b..b743d8c1e29 100644 --- a/src/cascadia/TerminalApp/CommandPalette.cpp +++ b/src/cascadia/TerminalApp/CommandPalette.cpp @@ -3,6 +3,11 @@ #include "pch.h" #include "CommandPalette.h" +#include "ActionAndArgs.h" +#include "ActionArgs.h" +#include "Command.h" + +#include #include "CommandPalette.g.cpp" @@ -12,15 +17,18 @@ using namespace winrt::Windows::UI::Core; using namespace winrt::Windows::UI::Xaml; using namespace winrt::Windows::System; using namespace winrt::Windows::Foundation; +using namespace winrt::Windows::Foundation::Collections; namespace winrt::TerminalApp::implementation { - CommandPalette::CommandPalette() + CommandPalette::CommandPalette() : + _switcherStartIdx{ 0 } { InitializeComponent(); _filteredActions = winrt::single_threaded_observable_vector(); - _allActions = winrt::single_threaded_vector(); + _allCommands = winrt::single_threaded_vector(); + _allTabActions = winrt::single_threaded_vector(); if (CommandPaletteShadow()) { @@ -38,8 +46,26 @@ namespace winrt::TerminalApp::implementation RegisterPropertyChangedCallback(UIElement::VisibilityProperty(), [this](auto&&, auto&&) { if (Visibility() == Visibility::Visible) { - _searchBox().Focus(FocusState::Programmatic); - _filteredActionsView().SelectedIndex(0); + if (_currentMode == CommandPaletteMode::TabSwitcherMode) + { + if (_anchorKey != VirtualKey::None) + { + _searchBox().Visibility(Visibility::Collapsed); + _filteredActionsView().Focus(FocusState::Keyboard); + } + else + { + _searchBox().Focus(FocusState::Programmatic); + } + + _filteredActionsView().SelectedIndex(_switcherStartIdx); + _filteredActionsView().ScrollIntoView(_filteredActionsView().SelectedItem()); + } + else + { + _searchBox().Focus(FocusState::Programmatic); + _filteredActionsView().SelectedIndex(0); + } TraceLoggingWrite( g_hTerminalAppProvider, // handle to TerminalApp tracelogging provider @@ -55,6 +81,19 @@ namespace winrt::TerminalApp::implementation _dismissPalette(); } }); + + // Focusing the ListView when the Command Palette control is set to Visible + // for the first time fails because the ListView hasn't finished loading by + // the time Focus is called. Luckily, We can listen to SizeChanged to know + // when the ListView has been measured out and is ready, and we'll immediately + // revoke the handler because we only needed to handle it once on initialization. + _sizeChangedRevoker = _filteredActionsView().SizeChanged(winrt::auto_revoke, [this](auto /*s*/, auto /*e*/) { + if (_currentMode == CommandPaletteMode::TabSwitcherMode && _anchorKey != VirtualKey::None) + { + _filteredActionsView().Focus(FocusState::Keyboard); + } + _sizeChangedRevoker.revoke(); + }); } // Method Description: @@ -77,6 +116,36 @@ namespace winrt::TerminalApp::implementation _filteredActionsView().ScrollIntoView(_filteredActionsView().SelectedItem()); } + void CommandPalette::_previewKeyDownHandler(IInspectable const& /*sender*/, + Windows::UI::Xaml::Input::KeyRoutedEventArgs const& e) + { + auto key = e.OriginalKey(); + + // Some keypresses such as Tab, Return, Esc, and Arrow Keys are ignored by controls because + // they're not considered input key presses. While they don't raise KeyDown events, + // they do raise PreviewKeyDown events. + // + // Only give anchored tab switcher the ability to cycle through tabs with the tab button. + // For unanchored mode, accessibility becomes an issue when we try to hijack tab since it's + // a really widely used keyboard navigation key. + if (_currentMode == CommandPaletteMode::TabSwitcherMode && + key == VirtualKey::Tab && + _anchorKey != VirtualKey::None) + { + auto const state = CoreWindow::GetForCurrentThread().GetKeyState(winrt::Windows::System::VirtualKey::Shift); + if (WI_IsFlagSet(state, CoreVirtualKeyStates::Down)) + { + _selectNextItem(false); + e.Handled(true); + } + else + { + _selectNextItem(true); + e.Handled(true); + } + } + } + // Method Description: // - Process keystrokes in the input box. This is used for moving focus up // and down the list of commands in Action mode, and for executing @@ -108,7 +177,7 @@ namespace winrt::TerminalApp::implementation if (const auto selectedItem = _filteredActionsView().SelectedItem()) { - _dispatchCommand(selectedItem.try_as()); + _dispatchCommand(selectedItem.try_as()); } e.Handled(true); @@ -129,6 +198,34 @@ namespace winrt::TerminalApp::implementation } } + void CommandPalette::_keyUpHandler(IInspectable const& /*sender*/, + Windows::UI::Xaml::Input::KeyRoutedEventArgs const& e) + { + auto key = e.OriginalKey(); + + if (_currentMode == CommandPaletteMode::TabSwitcherMode) + { + if (_anchorKey && key == _anchorKey.value()) + { + // Once the user lifts the anchor key, we'll switch to the currently selected tab + // then close the tab switcher. + + if (const auto selectedItem = _filteredActionsView().SelectedItem()) + { + if (const auto data = selectedItem.try_as()) + { + const auto actionAndArgs = data.Action(); + _dispatch.DoAction(actionAndArgs); + _updateFilteredActions(); + _dismissPalette(); + } + } + + e.Handled(true); + } + } + } + // Method Description: // - This event is triggered when someone clicks anywhere in the bounds of // the window that's _not_ the command palette UI. When that happens, @@ -171,6 +268,28 @@ namespace winrt::TerminalApp::implementation _dispatchCommand(e.ClickedItem().try_as()); } + // Method Description: + // - Retrieve the list of commands that we should currently be filtering. + // * If the user has command with subcommands, this will return that command's subcommands. + // * If we're in Tab Switcher mode, return the tab actions. + // * Otherwise, just return the list of all the top-level commands. + // Arguments: + // - + // Return Value: + // - A list of Commands to filter. + Collections::IVector CommandPalette::_commandsToFilter() + { + switch (_currentMode) + { + case CommandPaletteMode::ActionMode: + return _allCommands; + case CommandPaletteMode::TabSwitcherMode: + return _allTabActions; + default: + return _allCommands; + } + } + // Method Description: // - Helper method for retrieving the action from a command the user // selected, and dispatching that command. Also fires a tracelogging event @@ -184,6 +303,10 @@ namespace winrt::TerminalApp::implementation { if (command) { + // Close before we dispatch so that actions that open the command + // palette like the Tab Switcher will be able to have the last laugh. + _close(); + const auto actionAndArgs = command.Action(); _dispatch.DoAction(actionAndArgs); @@ -194,8 +317,6 @@ namespace winrt::TerminalApp::implementation TraceLoggingUInt32(_searchBox().Text().size(), "SearchTextLength", "Number of characters in the search string"), TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance)); - - _close(); } } @@ -235,17 +356,59 @@ namespace winrt::TerminalApp::implementation _noMatchesText().Visibility(_filteredActions.Size() > 0 ? Visibility::Collapsed : Visibility::Visible); } - Collections::IObservableVector CommandPalette::FilteredActions() + Collections::IObservableVector CommandPalette::FilteredActions() { return _filteredActions; } - void CommandPalette::SetActions(Collections::IVector const& actions) + void CommandPalette::SetCommands(Collections::IVector const& actions) { - _allActions = actions; + _allCommands = actions; _updateFilteredActions(); } + void CommandPalette::EnableCommandPaletteMode() + { + _switchToMode(CommandPaletteMode::ActionMode); + _updateFilteredActions(); + } + + void CommandPalette::_switchToMode(CommandPaletteMode mode) + { + // The smooth remove/add animations that happen during + // UpdateFilteredActions don't work very well when switching between + // modes because of the sheer amount of remove/adds. So, let's just + // clear + append when switching between modes. + if (mode != _currentMode) + { + _currentMode = mode; + _filteredActions.Clear(); + auto commandsToFilter = _commandsToFilter(); + + for (auto action : commandsToFilter) + { + _filteredActions.Append(action); + } + + switch (_currentMode) + { + case CommandPaletteMode::TabSwitcherMode: + { + SearchBoxText(RS_(L"TabSwitcher_SearchBoxText")); + NoMatchesText(RS_(L"TabSwitcher_NoMatchesText")); + ControlName(RS_(L"TabSwitcherControlName")); + break; + } + case CommandPaletteMode::ActionMode: + default: + SearchBoxText(RS_(L"CommandPalette_SearchBox/PlaceholderText")); + NoMatchesText(RS_(L"CommandPalette_NoMatchesText/Text")); + ControlName(RS_(L"CommandPaletteControlName")); + break; + } + } + } + // This is a helper to aid in sorting commands by their `Name`s, alphabetically. static bool _compareCommandNames(const TerminalApp::Command& lhs, const TerminalApp::Command& rhs) { @@ -259,13 +422,23 @@ namespace winrt::TerminalApp::implementation { TerminalApp::Command command; int weight; + int inOrderCounter; bool operator<(const WeightedCommand& other) const { - // If two commands have the same weight, then we'll sort them alphabetically. if (weight == other.weight) { - return !_compareCommandNames(command, other.command); + // If two commands have the same weight, then we'll sort them alphabetically. + // If they both have the same name, fall back to the order in which they were + // pushed into the heap. + if (command.Name() == other.command.Name()) + { + return inOrderCounter > other.inOrderCounter; + } + else + { + return !_compareCommandNames(command, other.command); + } } return weight < other.weight; } @@ -286,16 +459,30 @@ namespace winrt::TerminalApp::implementation auto searchText = _searchBox().Text(); const bool addAll = searchText.empty(); + auto commandsToFilter = _commandsToFilter(); + // If there's no filter text, then just add all the commands in order to the list. // - TODO GH#6647:Possibly add the MRU commands first in order, followed // by the rest of the commands. if (addAll) { + // If TabSwitcherMode, just add all as is. We don't want + // them to be sorted alphabetically. + if (_currentMode == CommandPaletteMode::TabSwitcherMode) + { + for (auto action : commandsToFilter) + { + actions.push_back(action); + } + + return actions; + } + // Add all the commands, but make sure they're sorted alphabetically. std::vector sortedCommands; - sortedCommands.reserve(_allActions.Size()); + sortedCommands.reserve(commandsToFilter.Size()); - for (auto action : _allActions) + for (auto action : commandsToFilter) { sortedCommands.push_back(action); } @@ -325,7 +512,12 @@ namespace winrt::TerminalApp::implementation // appear first in the list. The ordering will be determined by the // match weight produced by _getWeight. std::priority_queue heap; - for (auto action : _allActions) + + // TODO GH#7205: Find a better way to ensure that WCs of the same + // weight and name stay in the order in which they were pushed onto + // the PQ. + uint32_t counter = 0; + for (auto action : commandsToFilter) { const auto weight = CommandPalette::_getWeight(searchText, action.Name()); if (weight > 0) @@ -333,6 +525,8 @@ namespace winrt::TerminalApp::implementation WeightedCommand wc; wc.command = action; wc.weight = weight; + wc.inOrderCounter = counter++; + heap.push(wc); } } @@ -502,8 +696,150 @@ namespace winrt::TerminalApp::implementation { Visibility(Visibility::Collapsed); + // Reset visibility in case anchor mode tab switcher just finished. + _searchBox().Visibility(Visibility::Visible); + // Clear the text box each time we close the dialog. This is consistent with VsCode. _searchBox().Text(L""); } + // Method Description: + // - Listens for changes to TerminalPage's _tabs vector. Updates our vector of + // tab switching commands accordingly. + // Arguments: + // - s: The vector being listened to. + // - e: The vector changed args that tells us whether a change, insert, or removal was performed + // on the listened-to vector. + // Return Value: + // - + void CommandPalette::OnTabsChanged(const IInspectable& s, const IVectorChangedEventArgs& e) + { + if (auto tabList = s.try_as>()) + { + auto idx = e.Index(); + auto changedEvent = e.CollectionChange(); + + switch (changedEvent) + { + case CollectionChange::ItemChanged: + { + winrt::com_ptr item; + item.copy_from(winrt::get_self(_allTabActions.GetAt(idx))); + item->propertyChangedRevoker.revoke(); + + auto tab = tabList.GetAt(idx); + GenerateCommandForTab(idx, false, tab); + UpdateTabIndices(idx); + break; + } + case CollectionChange::ItemInserted: + { + auto tab = tabList.GetAt(idx); + GenerateCommandForTab(idx, true, tab); + UpdateTabIndices(idx); + break; + } + case CollectionChange::ItemRemoved: + { + winrt::com_ptr item; + item.copy_from(winrt::get_self(_allTabActions.GetAt(idx))); + item->propertyChangedRevoker.revoke(); + + _allTabActions.RemoveAt(idx); + UpdateTabIndices(idx); + break; + } + } + + _updateFilteredActions(); + } + } + + // Method Description: + // - In the case where a tab is removed or reordered, the given indices of + // the tab switch commands following the removed/reordered tab will get out of sync by 1 + // (e.g. if tab 1 is removed, tabs 2,3,4,... need to become tabs 1,2,3,...) + // This function just loops through the tabs following startIdx and adjusts their given indices. + // Arguments: + // - startIdx: The index to start the update loop at. + // Return Value: + // - + void CommandPalette::UpdateTabIndices(const uint32_t startIdx) + { + if (startIdx != _allTabActions.Size() - 1) + { + for (auto i = startIdx; i < _allTabActions.Size(); ++i) + { + auto command = _allTabActions.GetAt(i); + + command.Action().Args().as()->TabIndex(i); + } + } + } + + // Method Description: + // - Create a tab switching command based on the given tab object and insert/update the command + // at the given index. The command will call a SwitchToTab action on the given idx. + // Arguments: + // - idx: The index to insert or update the tab switch command. + // - tab: The tab object to refer to when creating the tab switch command. + // Return Value: + // - + void CommandPalette::GenerateCommandForTab(const uint32_t idx, bool inserted, TerminalApp::Tab& tab) + { + auto focusTabAction = winrt::make_self(); + auto args = winrt::make_self(); + args->TabIndex(idx); + + focusTabAction->Action(ShortcutAction::SwitchToTab); + focusTabAction->Args(*args); + + auto command = winrt::make_self(); + command->Action(*focusTabAction); + command->Name(tab.Title()); + command->IconSource(tab.IconSource()); + + // Listen for changes to the Tab so we can update this Command's attributes accordingly. + auto weakThis{ get_weak() }; + auto weakCommand{ command->get_weak() }; + command->propertyChangedRevoker = tab.PropertyChanged(winrt::auto_revoke, [weakThis, weakCommand, tab](auto&&, const Windows::UI::Xaml::Data::PropertyChangedEventArgs& args) { + auto palette{ weakThis.get() }; + auto command{ weakCommand.get() }; + + if (palette && command) + { + if (args.PropertyName() == L"Title") + { + if (command->Name() != tab.Title()) + { + command->Name(tab.Title()); + } + } + if (args.PropertyName() == L"IconSource") + { + if (command->IconSource() != tab.IconSource()) + { + command->IconSource(tab.IconSource()); + } + } + } + }); + + if (inserted) + { + _allTabActions.InsertAt(idx, *command); + } + else + { + _allTabActions.SetAt(idx, *command); + } + } + + void CommandPalette::EnableTabSwitcherMode(const VirtualKey& anchorKey, const uint32_t startIdx) + { + _switcherStartIdx = startIdx; + _anchorKey = anchorKey; + _switchToMode(CommandPaletteMode::TabSwitcherMode); + _updateFilteredActions(); + } } diff --git a/src/cascadia/TerminalApp/CommandPalette.h b/src/cascadia/TerminalApp/CommandPalette.h index a14466f4f36..b062b42003c 100644 --- a/src/cascadia/TerminalApp/CommandPalette.h +++ b/src/cascadia/TerminalApp/CommandPalette.h @@ -8,26 +8,50 @@ namespace winrt::TerminalApp::implementation { + enum class CommandPaletteMode + { + ActionMode = 0, + TabSwitcherMode + }; + struct CommandPalette : CommandPaletteT { CommandPalette(); Windows::Foundation::Collections::IObservableVector FilteredActions(); - void SetActions(Windows::Foundation::Collections::IVector const& actions); + + void SetCommands(Windows::Foundation::Collections::IVector const& actions); + void EnableCommandPaletteMode(); void SetDispatch(const winrt::TerminalApp::ShortcutActionDispatch& dispatch); + // Tab Switcher + void EnableTabSwitcherMode(const Windows::System::VirtualKey& anchorKey, const uint32_t startIdx); + void OnTabsChanged(const Windows::Foundation::IInspectable& s, const Windows::Foundation::Collections::IVectorChangedEventArgs& e); + + WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler); + OBSERVABLE_GETSET_PROPERTY(winrt::hstring, NoMatchesText, _PropertyChangedHandlers); + OBSERVABLE_GETSET_PROPERTY(winrt::hstring, SearchBoxText, _PropertyChangedHandlers); + OBSERVABLE_GETSET_PROPERTY(winrt::hstring, ControlName, _PropertyChangedHandlers); + private: friend struct CommandPaletteT; // for Xaml to bind events Windows::Foundation::Collections::IObservableVector _filteredActions{ nullptr }; - Windows::Foundation::Collections::IVector _allActions{ nullptr }; + + Windows::Foundation::Collections::IVector _allCommands{ nullptr }; winrt::TerminalApp::ShortcutActionDispatch _dispatch; + Windows::Foundation::Collections::IVector _commandsToFilter(); + void _filterTextChanged(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& args); + void _previewKeyDownHandler(Windows::Foundation::IInspectable const& sender, + Windows::UI::Xaml::Input::KeyRoutedEventArgs const& e); void _keyDownHandler(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::Input::KeyRoutedEventArgs const& e); + void _keyUpHandler(Windows::Foundation::IInspectable const& sender, + Windows::UI::Xaml::Input::KeyRoutedEventArgs const& e); void _rootPointerPressed(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs const& e); void _backdropPointerPressed(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs const& e); @@ -41,6 +65,18 @@ namespace winrt::TerminalApp::implementation static int _getWeight(const winrt::hstring& searchText, const winrt::hstring& name); void _close(); + CommandPaletteMode _currentMode; + void _switchToMode(CommandPaletteMode mode); + + // Tab Switcher + std::optional _anchorKey; + void GenerateCommandForTab(const uint32_t idx, bool inserted, winrt::TerminalApp::Tab& tab); + void UpdateTabIndices(const uint32_t startIdx); + Windows::Foundation::Collections::IVector _allTabActions{ nullptr }; + uint32_t _switcherStartIdx; + + winrt::Windows::UI::Xaml::Controls::ListView::SizeChanged_revoker _sizeChangedRevoker; + void _dispatchCommand(const TerminalApp::Command& command); void _dismissPalette(); diff --git a/src/cascadia/TerminalApp/CommandPalette.idl b/src/cascadia/TerminalApp/CommandPalette.idl index f0e7c9bb539..8286077a4e4 100644 --- a/src/cascadia/TerminalApp/CommandPalette.idl +++ b/src/cascadia/TerminalApp/CommandPalette.idl @@ -5,14 +5,22 @@ import "../Command.idl"; namespace TerminalApp { - [default_interface] runtimeclass CommandPalette : Windows.UI.Xaml.Controls.Grid + [default_interface] runtimeclass CommandPalette : Windows.UI.Xaml.Controls.UserControl, Windows.UI.Xaml.Data.INotifyPropertyChanged { CommandPalette(); + String NoMatchesText { get; }; + String SearchBoxText { get; }; + String ControlName { get; }; + Windows.Foundation.Collections.IObservableVector FilteredActions { get; }; - void SetActions(Windows.Foundation.Collections.IVector actions); + void SetCommands(Windows.Foundation.Collections.IVector actions); + void EnableCommandPaletteMode(); void SetDispatch(ShortcutActionDispatch dispatch); + + void EnableTabSwitcherMode(Windows.System.VirtualKey anchorKey, UInt32 startIdx); + void OnTabsChanged(IInspectable s, Windows.Foundation.Collections.IVectorChangedEventArgs e); } } diff --git a/src/cascadia/TerminalApp/CommandPalette.xaml b/src/cascadia/TerminalApp/CommandPalette.xaml index 39b0e1a25be..50b35e8bbb6 100644 --- a/src/cascadia/TerminalApp/CommandPalette.xaml +++ b/src/cascadia/TerminalApp/CommandPalette.xaml @@ -1,6 +1,6 @@ - xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:Windows10version1903="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractPresent(Windows.Foundation.UniversalApiContract, 8)" + TabNavigation="Cycle" + IsTabStop="True" + AllowFocusOnInteraction="True" PointerPressed="_rootPointerPressed" - mc:Ignorable="d"> + PreviewKeyDown="_previewKeyDownHandler" + KeyDown="_keyDownHandler" + PreviewKeyUp="_keyUpHandler" + mc:Ignorable="d" + AutomationProperties.Name="{x:Bind ControlName, Mode=OneWay}"> - + + - + - - - - - + + + + + - - - - + + + + - + - VerticalAlignment="Stretch"> - HorizontalAlignment="Stretch" VerticalAlignment="Top"> - - - - - + + + + + - - + - - + Grid.Row="1" + Text="{x:Bind NoMatchesText, Mode=OneWay}"> + - AllowDrop="False" IsItemClickEnabled="True" ItemClick="_listItemClicked" + PreviewKeyDown="_keyDownHandler" ItemsSource="{x:Bind FilteredActions}"> - - + + - - - + - - - - - - + + + + + + - + - - - - - + - - - - - + + + + + - + - + + diff --git a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw index aaded2a06b4..c891d53df6a 100644 --- a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw +++ b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw @@ -529,6 +529,9 @@ Toggle command palette + + Command Palette + Set color scheme to {0} {0} will be replaced with the name of a color scheme as defined by the user. @@ -562,6 +565,18 @@ Close tabs after index {0} {0} will be replaced with a number + + Tab Switcher + + + Toggle tab switcher + + + Type a tab name... + + + No matching tab name + Crimson diff --git a/src/cascadia/TerminalApp/ShortcutActionDispatch.cpp b/src/cascadia/TerminalApp/ShortcutActionDispatch.cpp index 862eb1a9de6..e8b9eb778c4 100644 --- a/src/cascadia/TerminalApp/ShortcutActionDispatch.cpp +++ b/src/cascadia/TerminalApp/ShortcutActionDispatch.cpp @@ -220,6 +220,11 @@ namespace winrt::TerminalApp::implementation _CloseTabsAfterHandlers(*this, *eventArgs); break; } + case ShortcutAction::ToggleTabSwitcher: + { + _ToggleTabSwitcherHandlers(*this, *eventArgs); + break; + } default: return false; } diff --git a/src/cascadia/TerminalApp/ShortcutActionDispatch.h b/src/cascadia/TerminalApp/ShortcutActionDispatch.h index 1005129b531..fa139848e63 100644 --- a/src/cascadia/TerminalApp/ShortcutActionDispatch.h +++ b/src/cascadia/TerminalApp/ShortcutActionDispatch.h @@ -59,6 +59,7 @@ namespace winrt::TerminalApp::implementation TYPED_EVENT(ExecuteCommandline, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs); TYPED_EVENT(CloseOtherTabs, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs); TYPED_EVENT(CloseTabsAfter, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs); + TYPED_EVENT(ToggleTabSwitcher, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs); // clang-format on private: diff --git a/src/cascadia/TerminalApp/ShortcutActionDispatch.idl b/src/cascadia/TerminalApp/ShortcutActionDispatch.idl index 83681760755..b0341d4bf81 100644 --- a/src/cascadia/TerminalApp/ShortcutActionDispatch.idl +++ b/src/cascadia/TerminalApp/ShortcutActionDispatch.idl @@ -44,7 +44,8 @@ namespace TerminalApp ExecuteCommandline, ToggleCommandPalette, CloseOtherTabs, - CloseTabsAfter + CloseTabsAfter, + ToggleTabSwitcher }; [default_interface] runtimeclass ActionAndArgs { @@ -94,5 +95,6 @@ namespace TerminalApp event Windows.Foundation.TypedEventHandler ExecuteCommandline; event Windows.Foundation.TypedEventHandler CloseOtherTabs; event Windows.Foundation.TypedEventHandler CloseTabsAfter; + event Windows.Foundation.TypedEventHandler ToggleTabSwitcher; } } diff --git a/src/cascadia/TerminalApp/Tab.cpp b/src/cascadia/TerminalApp/Tab.cpp index eb396275303..ead28ce1f02 100644 --- a/src/cascadia/TerminalApp/Tab.cpp +++ b/src/cascadia/TerminalApp/Tab.cpp @@ -18,6 +18,7 @@ using namespace winrt::Windows::System; namespace winrt { namespace MUX = Microsoft::UI::Xaml; + namespace WUX = Windows::UI::Xaml; } namespace winrt::TerminalApp::implementation @@ -225,7 +226,8 @@ namespace winrt::TerminalApp::implementation if (auto tab{ weakThis.get() }) { - IconPath(_lastIconPath); + // The TabViewItem Icon needs MUX while the IconSourceElement in the CommandPalette needs WUX... + IconSource(GetColoredIcon(_lastIconPath)); _tabViewItem.IconSource(GetColoredIcon(_lastIconPath)); } } diff --git a/src/cascadia/TerminalApp/Tab.h b/src/cascadia/TerminalApp/Tab.h index 6e3e5cc5b95..02055b05767 100644 --- a/src/cascadia/TerminalApp/Tab.h +++ b/src/cascadia/TerminalApp/Tab.h @@ -73,7 +73,7 @@ namespace winrt::TerminalApp::implementation DECLARE_EVENT(ColorCleared, _colorCleared, winrt::delegate<>); OBSERVABLE_GETSET_PROPERTY(winrt::hstring, Title, _PropertyChangedHandlers); - OBSERVABLE_GETSET_PROPERTY(winrt::hstring, IconPath, _PropertyChangedHandlers); + OBSERVABLE_GETSET_PROPERTY(winrt::Windows::UI::Xaml::Controls::IconSource, IconSource, _PropertyChangedHandlers, nullptr); private: std::shared_ptr _rootPane{ nullptr }; diff --git a/src/cascadia/TerminalApp/Tab.idl b/src/cascadia/TerminalApp/Tab.idl index 955c243845a..5aba64605fc 100644 --- a/src/cascadia/TerminalApp/Tab.idl +++ b/src/cascadia/TerminalApp/Tab.idl @@ -6,6 +6,6 @@ namespace TerminalApp [default_interface] runtimeclass Tab : Windows.UI.Xaml.Data.INotifyPropertyChanged { String Title { get; }; - String IconPath { get; }; + Windows.UI.Xaml.Controls.IconSource IconSource { get; }; } } diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index 3b245440c03..3838e4ccf50 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -80,9 +80,20 @@ namespace winrt::TerminalApp::implementation { command.KeyChordText(KeyChordSerialization::ToString(keyChord)); } + + // Set the default IconSource to a BitmapIconSource with a null source + // (instead of just nullptr) because there's a really weird crash when swapping + // data bound IconSourceElements in a ListViewTemplate (i.e. CommandPalette). + // Swapping between nullptr IconSources and non-null IconSources causes a crash + // to occur, but swapping between IconSources with a null source and non-null IconSources + // work perfectly fine :shrug:. + winrt::Windows::UI::Xaml::Controls::BitmapIconSource icon; + icon.UriSource(nullptr); + command.IconSource(icon); + commandsCollection.Append(command); } - CommandPalette().SetActions(commandsCollection); + CommandPalette().SetCommands(commandsCollection); } } @@ -211,6 +222,13 @@ namespace winrt::TerminalApp::implementation } }); + _tabs.VectorChanged([weakThis{ get_weak() }](auto&& s, auto&& e) { + if (auto page{ weakThis.get() }) + { + page->CommandPalette().OnTabsChanged(s, e); + } + }); + // Once the page is actually laid out on the screen, trigger all our // startup actions. Things like Panes need to know at least how big the // window will be, so they can subdivide that space. @@ -897,6 +915,7 @@ namespace winrt::TerminalApp::implementation _actionDispatch->ExecuteCommandline({ this, &TerminalPage::_HandleExecuteCommandline }); _actionDispatch->CloseOtherTabs({ this, &TerminalPage::_HandleCloseOtherTabs }); _actionDispatch->CloseTabsAfter({ this, &TerminalPage::_HandleCloseTabsAfter }); + _actionDispatch->ToggleTabSwitcher({ this, &TerminalPage::_HandleToggleTabSwitcher }); } // Method Description: diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h index 30ca3bced58..984f1064245 100644 --- a/src/cascadia/TerminalApp/TerminalPage.h +++ b/src/cascadia/TerminalApp/TerminalPage.h @@ -230,6 +230,7 @@ namespace winrt::TerminalApp::implementation void _HandleToggleCommandPalette(const IInspectable& sender, const TerminalApp::ActionEventArgs& args); void _HandleCloseOtherTabs(const IInspectable& sender, const TerminalApp::ActionEventArgs& args); void _HandleCloseTabsAfter(const IInspectable& sender, const TerminalApp::ActionEventArgs& args); + void _HandleToggleTabSwitcher(const IInspectable& sender, const TerminalApp::ActionEventArgs& args); // Make sure to hook new actions up in _RegisterActionCallbacks! #pragma endregion diff --git a/src/cascadia/TerminalApp/TerminalSettingsSerializationHelpers.h b/src/cascadia/TerminalApp/TerminalSettingsSerializationHelpers.h index f7058a49a74..80459845a09 100644 --- a/src/cascadia/TerminalApp/TerminalSettingsSerializationHelpers.h +++ b/src/cascadia/TerminalApp/TerminalSettingsSerializationHelpers.h @@ -270,3 +270,12 @@ JSON_ENUM_MAPPER(::winrt::TerminalApp::SettingsTarget) pair_type{ "allFiles", ValueType::AllFiles }, }; }; + +JSON_ENUM_MAPPER(::winrt::Windows::System::VirtualKey) +{ + JSON_MAPPINGS(3) = { + pair_type{ "ctrl", ValueType::Control }, + pair_type{ "alt", ValueType::Menu }, + pair_type{ "shift", ValueType::Shift }, + }; +}; diff --git a/src/cascadia/inc/cppwinrt_utils.h b/src/cascadia/inc/cppwinrt_utils.h index 3d9599bbeef..dcc53ef23ce 100644 --- a/src/cascadia/inc/cppwinrt_utils.h +++ b/src/cascadia/inc/cppwinrt_utils.h @@ -114,7 +114,7 @@ private: \ // private _setName() method, that the class can internally use to change the // value when it _knows_ it doesn't need to raise the PropertyChanged event // (like when the class is being initialized). -#define OBSERVABLE_GETSET_PROPERTY(type, name, event) \ +#define OBSERVABLE_GETSET_PROPERTY(type, name, event, ...) \ public: \ type name() { return _##name; }; \ void name(const type& value) \ @@ -127,7 +127,7 @@ public: }; \ \ private: \ - const type _##name; \ + const type _##name{ __VA_ARGS__ }; \ void _set##name(const type& value) \ { \ const_cast(_##name) = value; \ From 7ccd1f6f1a3315484ad8728208e9487f9b7a0928 Mon Sep 17 00:00:00 2001 From: "Dustin L. Howett" Date: Tue, 11 Aug 2020 12:50:13 -0700 Subject: [PATCH 037/266] Display meaningful errors when JSON types don't match (#7241) This pull request completes (and somewhat rewrites) the JsonUtils error handling arc. Deserialization errors, no longer represented by trees of exceptions that must be rethrown and caught, are now transformed at catch time into a message explaining what we expected and where we expected it. Instead of exception trees, a deserialization failure will result in a single type of exception with the originating JSON object from which we can determine the contents and location of the failure. Because most of the error message actually comes from the JSON schema or the actual supported types, and the other jsoncpp errors are not localized I've made the decision to **not** localize these messages. --- src/cascadia/TerminalApp/AppLogic.cpp | 6 + src/cascadia/TerminalApp/CascadiaSettings.h | 8 ++ .../CascadiaSettingsSerialization.cpp | 75 ++++++++-- src/cascadia/TerminalApp/JsonUtils.h | 129 +++++++++++------- .../TerminalSettingsSerializationHelpers.h | 9 ++ src/cascadia/ut_app/JsonUtilsTests.cpp | 52 ++++--- 6 files changed, 194 insertions(+), 85 deletions(-) diff --git a/src/cascadia/TerminalApp/AppLogic.cpp b/src/cascadia/TerminalApp/AppLogic.cpp index b0257b431a6..9b6c3eddc77 100644 --- a/src/cascadia/TerminalApp/AppLogic.cpp +++ b/src/cascadia/TerminalApp/AppLogic.cpp @@ -632,6 +632,12 @@ namespace winrt::TerminalApp::implementation hr = E_INVALIDARG; _settingsLoadExceptionText = _GetErrorText(ex.Error()); } + catch (const ::TerminalApp::SettingsTypedDeserializationException& e) + { + hr = E_INVALIDARG; + std::string_view what{ e.what() }; + _settingsLoadExceptionText = til::u8u16(what); + } catch (...) { hr = wil::ResultFromCaughtException(); diff --git a/src/cascadia/TerminalApp/CascadiaSettings.h b/src/cascadia/TerminalApp/CascadiaSettings.h index 981264e10f2..a4b61893112 100644 --- a/src/cascadia/TerminalApp/CascadiaSettings.h +++ b/src/cascadia/TerminalApp/CascadiaSettings.h @@ -39,9 +39,17 @@ namespace TerminalAppUnitTests namespace TerminalApp { + class SettingsTypedDeserializationException; class CascadiaSettings; }; +class TerminalApp::SettingsTypedDeserializationException final : public std::runtime_error +{ +public: + SettingsTypedDeserializationException(const std::string_view description) : + runtime_error(description.data()) {} +}; + class TerminalApp::CascadiaSettings final { public: diff --git a/src/cascadia/TerminalApp/CascadiaSettingsSerialization.cpp b/src/cascadia/TerminalApp/CascadiaSettingsSerialization.cpp index 85b51bf549a..bba84551f4d 100644 --- a/src/cascadia/TerminalApp/CascadiaSettingsSerialization.cpp +++ b/src/cascadia/TerminalApp/CascadiaSettingsSerialization.cpp @@ -42,6 +42,54 @@ static constexpr std::string_view Utf8Bom{ u8"\uFEFF" }; static constexpr std::string_view SettingsSchemaFragment{ "\n" R"( "$schema": "https://aka.ms/terminal-profiles-schema")" }; +static std::tuple _LineAndColumnFromPosition(const std::string_view string, ptrdiff_t position) +{ + size_t line = 1, column = position + 1; + auto lastNL = string.find_last_of('\n', position); + if (lastNL != std::string::npos) + { + column = (position - lastNL); + line = std::count(string.cbegin(), string.cbegin() + lastNL + 1, '\n') + 1; + } + + return { line, column }; +} + +static void _CatchRethrowSerializationExceptionWithLocationInfo(std::string_view settingsString) +{ + std::string msg; + + try + { + throw; + } + catch (const JsonUtils::DeserializationError& e) + { + static constexpr std::string_view basicHeader{ "* Line {line}, Column {column}\n{message}" }; + static constexpr std::string_view keyedHeader{ "* Line {line}, Column {column} ({key})\n{message}" }; + + std::string jsonValueAsString{ "array or object" }; + try + { + jsonValueAsString = e.jsonValue.asString(); + } + catch (...) + { + // discard: we're in the middle of error handling + } + + msg = fmt::format(" Have: \"{}\"\n Expected: {}", jsonValueAsString, e.expectedType); + + auto [l, c] = _LineAndColumnFromPosition(settingsString, e.jsonValue.getOffsetStart()); + msg = fmt::format((e.key ? keyedHeader : basicHeader), + fmt::arg("line", l), + fmt::arg("column", c), + fmt::arg("key", e.key.value_or("")), + fmt::arg("message", msg)); + throw SettingsTypedDeserializationException{ msg }; + } +} + // Method Description: // - Creates a CascadiaSettings from whatever's saved on disk, or instantiates // a new one with the default values. If we're running as a packaged app, @@ -90,16 +138,23 @@ std::unique_ptr CascadiaSettings::LoadAll() needToWriteFile = true; } - // See microsoft/terminal#2325: find the defaultSettings from the user's - // settings. Layer those settings upon all the existing profiles we have - // (defaults and dynamic profiles). We'll also set - // _userDefaultProfileSettings here. When we LayerJson below to apply the - // user settings, we'll make sure to use these defaultSettings _before_ any - // profiles the user might have. - resultPtr->_ApplyDefaultsFromUserSettings(); - - // Apply the user's settings - resultPtr->LayerJson(resultPtr->_userSettings); + try + { + // See microsoft/terminal#2325: find the defaultSettings from the user's + // settings. Layer those settings upon all the existing profiles we have + // (defaults and dynamic profiles). We'll also set + // _userDefaultProfileSettings here. When we LayerJson below to apply the + // user settings, we'll make sure to use these defaultSettings _before_ any + // profiles the user might have. + resultPtr->_ApplyDefaultsFromUserSettings(); + + // Apply the user's settings + resultPtr->LayerJson(resultPtr->_userSettings); + } + catch (...) + { + _CatchRethrowSerializationExceptionWithLocationInfo(resultPtr->_userSettingsString); + } // After layering the user settings, check if there are any new profiles // that need to be inserted into their user settings file. diff --git a/src/cascadia/TerminalApp/JsonUtils.h b/src/cascadia/TerminalApp/JsonUtils.h index 9a9c9c676e5..b15eb1478a2 100644 --- a/src/cascadia/TerminalApp/JsonUtils.h +++ b/src/cascadia/TerminalApp/JsonUtils.h @@ -69,52 +69,24 @@ namespace TerminalApp::JsonUtils }; } - // These exceptions cannot use localized messages, as we do not have - // guaranteed access to the resource loader. - class TypeMismatchException : public std::runtime_error + class DeserializationError : public std::runtime_error { public: - TypeMismatchException() : - runtime_error("unexpected data type") {} - }; - - class KeyedException : public std::runtime_error - { - public: - KeyedException(const std::string_view key, std::exception_ptr exception) : - runtime_error(fmt::format("error parsing \"{0}\"", key).c_str()), - _key{ key }, - _innerException{ std::move(exception) } {} - - std::string GetKey() const - { - return _key; - } + DeserializationError(const Json::Value& value) : + runtime_error("failed to deserialize"), + jsonValue{ value } {} - [[noreturn]] void RethrowInner() const + void SetKey(std::string_view newKey) { - std::rethrow_exception(_innerException); - } - - private: - std::string _key; - std::exception_ptr _innerException; - }; - - class UnexpectedValueException : public std::runtime_error - { - public: - UnexpectedValueException(const std::string_view value) : - runtime_error(fmt::format("unexpected value \"{0}\"", value).c_str()), - _value{ value } {} - - std::string GetValue() const - { - return _value; + if (!key) + { + key = newKey; + } } - private: - std::string _value; + std::optional key; + Json::Value jsonValue; + std::string expectedType; }; template @@ -123,6 +95,8 @@ namespace TerminalApp::JsonUtils // Forward-declare these so the linker can pick up specializations from elsewhere! T FromJson(const Json::Value&); bool CanConvert(const Json::Value& json); + + std::string TypeDescription() const { return ""; } }; template<> @@ -137,6 +111,11 @@ namespace TerminalApp::JsonUtils { return json.isString(); } + + std::string TypeDescription() const + { + return "string"; + } }; template<> @@ -151,6 +130,11 @@ namespace TerminalApp::JsonUtils { return json.isString(); } + + std::string TypeDescription() const + { + return "string"; + } }; #ifdef WINRT_BASE_H @@ -177,6 +161,11 @@ namespace TerminalApp::JsonUtils { return json.isBool(); } + + std::string TypeDescription() const + { + return "true | false"; + } }; template<> @@ -191,6 +180,11 @@ namespace TerminalApp::JsonUtils { return json.isInt(); } + + std::string TypeDescription() const + { + return "number"; + } }; template<> @@ -205,6 +199,11 @@ namespace TerminalApp::JsonUtils { return json.isUInt(); } + + std::string TypeDescription() const + { + return "number (>= 0)"; + } }; template<> @@ -219,6 +218,11 @@ namespace TerminalApp::JsonUtils { return json.isNumeric(); } + + std::string TypeDescription() const + { + return "number"; + } }; template<> @@ -233,6 +237,11 @@ namespace TerminalApp::JsonUtils { return json.isNumeric(); } + + std::string TypeDescription() const + { + return "number"; + } }; template<> @@ -253,6 +262,11 @@ namespace TerminalApp::JsonUtils const auto string{ Detail::GetStringView(json) }; return string.length() == 38 && string.front() == '{' && string.back() == '}'; } + + std::string TypeDescription() const + { + return "guid"; + } }; // (GUID and winrt::guid are mutually convertible!) @@ -279,6 +293,11 @@ namespace TerminalApp::JsonUtils const auto string{ Detail::GetStringView(json) }; return (string.length() == 7 || string.length() == 4) && string.front() == '#'; } + + std::string TypeDescription() const + { + return "color (#rrggbb, #rgb)"; + } }; template @@ -298,13 +317,22 @@ namespace TerminalApp::JsonUtils } } - throw UnexpectedValueException{ name }; + DeserializationError e{ json }; + e.expectedType = TypeDescription(); + throw e; } bool CanConvert(const Json::Value& json) { return json.isString(); } + + std::string TypeDescription() const + { + std::vector names; + std::transform(TBase::mappings.cbegin(), TBase::mappings.cend(), std::back_inserter(names), [](auto&& p) { return p.first; }); + return fmt::format("{}", fmt::join(names, " | ")); + } }; // FlagMapper is EnumMapper, but it works for bitfields. @@ -343,7 +371,9 @@ namespace TerminalApp::JsonUtils (value == AllClear && newFlag != AllClear))) { // attempt to combine AllClear (explicitly) with anything else - throw UnexpectedValueException{ element.asString() }; + DeserializationError e{ element }; + e.expectedType = TypeDescription(); + throw e; } value |= newFlag; } @@ -377,6 +407,11 @@ namespace TerminalApp::JsonUtils { return true; } + + std::string TypeDescription() const + { + return "any"; + } }; // Method Description: @@ -407,7 +442,9 @@ namespace TerminalApp::JsonUtils { if (!conv.CanConvert(json)) { - throw TypeMismatchException{}; + DeserializationError e{ json }; + e.expectedType = conv.TypeDescription(); + throw e; } target = conv.FromJson(json); @@ -435,10 +472,10 @@ namespace TerminalApp::JsonUtils { return GetValue(*found, target, std::forward(conv)); } - catch (...) + catch (DeserializationError& e) { - // Wrap any caught exceptions in one that preserves context. - throw KeyedException(key, std::current_exception()); + e.SetKey(key); + throw; // rethrow now that it has a key } } return false; diff --git a/src/cascadia/TerminalApp/TerminalSettingsSerializationHelpers.h b/src/cascadia/TerminalApp/TerminalSettingsSerializationHelpers.h index 80459845a09..c1e60b6a705 100644 --- a/src/cascadia/TerminalApp/TerminalSettingsSerializationHelpers.h +++ b/src/cascadia/TerminalApp/TerminalSettingsSerializationHelpers.h @@ -101,6 +101,8 @@ JSON_ENUM_MAPPER(::TerminalApp::CloseOnExitMode) { return EnumMapper::CanConvert(json) || json.isBool(); } + + using EnumMapper::TypeDescription; }; // This specialization isn't using JSON_ENUM_MAPPER because we need to have a different @@ -151,6 +153,8 @@ struct ::TerminalApp::JsonUtils::ConversionTrait<::winrt::Windows::UI::Text::Fon { return BaseEnumMapper::CanConvert(json) || json.isUInt(); } + + using EnumMapper::TypeDescription; }; JSON_ENUM_MAPPER(::winrt::Windows::UI::Xaml::ElementTheme) @@ -231,6 +235,11 @@ struct ::TerminalApp::JsonUtils::ConversionTrait<::TerminalApp::LaunchPosition> { return json.isString(); } + + std::string TypeDescription() const + { + return "x, y"; + } }; // Possible Direction values diff --git a/src/cascadia/ut_app/JsonUtilsTests.cpp b/src/cascadia/ut_app/JsonUtilsTests.cpp index f3f3c7c5b2c..44d2c02fe44 100644 --- a/src/cascadia/ut_app/JsonUtilsTests.cpp +++ b/src/cascadia/ut_app/JsonUtilsTests.cpp @@ -33,6 +33,8 @@ struct ConversionTrait { return value.isInt(); } + + std::string TypeDescription() const { return ""; } }; // Converts a JSON string value to an int and multiplies it by a specified factor @@ -49,6 +51,8 @@ struct CustomConverter { return true; } + + std::string TypeDescription() const { return ""; } }; enum class JsonTestEnum : int @@ -130,7 +134,7 @@ namespace TerminalAppUnitTests //// 1. Bare Value //// //// 1.a. Type Invalid - Exception //// - VERIFY_THROWS_SPECIFIC(GetValue(object), TypeMismatchException, _ReturnTrueForException); + VERIFY_THROWS_SPECIFIC(GetValue(object), DeserializationError, _ReturnTrueForException); //// 1.b. JSON NULL - Zero Value //// std::string zeroValueString{}; @@ -141,7 +145,7 @@ namespace TerminalAppUnitTests //// 2. Optional //// //// 2.a. Type Invalid - Exception //// - VERIFY_THROWS_SPECIFIC(GetValue>(object), TypeMismatchException, _ReturnTrueForException); + VERIFY_THROWS_SPECIFIC(GetValue>(object), DeserializationError, _ReturnTrueForException); //// 2.b. JSON NULL - nullopt //// VERIFY_ARE_EQUAL(std::nullopt, GetValue>(Json::Value::nullSingleton())); @@ -160,7 +164,7 @@ namespace TerminalAppUnitTests std::string output{ "sentinel" }; // explicitly not the zero value //// 1.a. Type Invalid - Exception //// - VERIFY_THROWS_SPECIFIC(GetValue(object, outputRedHerring), TypeMismatchException, _ReturnTrueForException); + VERIFY_THROWS_SPECIFIC(GetValue(object, outputRedHerring), DeserializationError, _ReturnTrueForException); VERIFY_ARE_EQUAL(5, outputRedHerring); // unchanged //// 1.b. JSON NULL - Unchanged //// @@ -176,7 +180,7 @@ namespace TerminalAppUnitTests std::optional optionalOutput{ "sentinel2" }; // explicitly not nullopt //// 2.a. Type Invalid - Exception //// - VERIFY_THROWS_SPECIFIC(GetValue(object, optionalOutputRedHerring), TypeMismatchException, _ReturnTrueForException); + VERIFY_THROWS_SPECIFIC(GetValue(object, optionalOutputRedHerring), DeserializationError, _ReturnTrueForException); VERIFY_ARE_EQUAL(6, optionalOutputRedHerring); // unchanged //// 2.b. JSON NULL - nullopt //// @@ -202,7 +206,7 @@ namespace TerminalAppUnitTests //// 1. Bare Value //// //// 1.a. Type Invalid - Exception //// - VERIFY_THROWS_SPECIFIC(GetValueForKey(object, key), KeyedException, _ReturnTrueForException); + VERIFY_THROWS_SPECIFIC(GetValueForKey(object, key), DeserializationError, _ReturnTrueForException); //// 1.b. JSON NULL - Zero Value //// std::string zeroValueString{}; @@ -216,7 +220,7 @@ namespace TerminalAppUnitTests //// 2. Optional //// //// 2.a. Type Invalid - Exception //// - VERIFY_THROWS_SPECIFIC(GetValueForKey>(object, key), KeyedException, _ReturnTrueForException); + VERIFY_THROWS_SPECIFIC(GetValueForKey>(object, key), DeserializationError, _ReturnTrueForException); //// 2.b. JSON NULL - nullopt //// VERIFY_ARE_EQUAL(std::nullopt, GetValueForKey>(object, nullKey)); @@ -245,7 +249,7 @@ namespace TerminalAppUnitTests std::string output{ "sentinel" }; // explicitly not the zero value //// 1.a. Type Invalid - Exception //// - VERIFY_THROWS_SPECIFIC(GetValueForKey(object, key, outputRedHerring), KeyedException, _ReturnTrueForException); + VERIFY_THROWS_SPECIFIC(GetValueForKey(object, key, outputRedHerring), DeserializationError, _ReturnTrueForException); VERIFY_ARE_EQUAL(5, outputRedHerring); // unchanged //// 1.b. JSON NULL - Unchanged //// @@ -267,7 +271,7 @@ namespace TerminalAppUnitTests std::optional optionalOutput{ "sentinel2" }; // explicitly not nullopt //// 2.a. Type Invalid - Exception //// - VERIFY_THROWS_SPECIFIC(GetValueForKey(object, key, optionalOutputRedHerring), KeyedException, _ReturnTrueForException); + VERIFY_THROWS_SPECIFIC(GetValueForKey(object, key, optionalOutputRedHerring), DeserializationError, _ReturnTrueForException); VERIFY_ARE_EQUAL(6, optionalOutputRedHerring); // unchanged //// 2.b. JSON NULL - nullopt //// @@ -321,12 +325,12 @@ namespace TerminalAppUnitTests TryBasicType(testGuid, testGuidString); - VERIFY_THROWS_SPECIFIC(GetValue({ "NOT_A_GUID" }), TypeMismatchException, _ReturnTrueForException); - VERIFY_THROWS_SPECIFIC(GetValue({ "{too short for a guid but just a bit}" }), TypeMismatchException, _ReturnTrueForException); + VERIFY_THROWS_SPECIFIC(GetValue({ "NOT_A_GUID" }), DeserializationError, _ReturnTrueForException); + VERIFY_THROWS_SPECIFIC(GetValue({ "{too short for a guid but just a bit}" }), DeserializationError, _ReturnTrueForException); VERIFY_THROWS_SPECIFIC(GetValue({ "{proper length string not a guid tho?}" }), std::exception, _ReturnTrueForException); - VERIFY_THROWS_SPECIFIC(GetValue({ "#" }), TypeMismatchException, _ReturnTrueForException); - VERIFY_THROWS_SPECIFIC(GetValue({ "#1234567890" }), TypeMismatchException, _ReturnTrueForException); + VERIFY_THROWS_SPECIFIC(GetValue({ "#" }), DeserializationError, _ReturnTrueForException); + VERIFY_THROWS_SPECIFIC(GetValue({ "#1234567890" }), DeserializationError, _ReturnTrueForException); } void JsonUtilsTests::BasicTypeWithCustomConverter() @@ -366,7 +370,7 @@ namespace TerminalAppUnitTests // Unknown value should produce something? Json::Value stringUnknown{ "unknown" }; - VERIFY_THROWS_SPECIFIC(GetValue(stringUnknown), UnexpectedValueException, _ReturnTrueForException); + VERIFY_THROWS_SPECIFIC(GetValue(stringUnknown), DeserializationError, _ReturnTrueForException); } void JsonUtilsTests::FlagMapper() @@ -401,17 +405,17 @@ namespace TerminalAppUnitTests Json::Value arrayNoneFirst{ Json::arrayValue }; arrayNoneFirst.append({ "none" }); arrayNoneFirst.append({ "first" }); - VERIFY_THROWS_SPECIFIC(GetValue(arrayNoneFirst), UnexpectedValueException, _ReturnTrueForException); + VERIFY_THROWS_SPECIFIC(GetValue(arrayNoneFirst), DeserializationError, _ReturnTrueForException); // Stacking Any + None (Exception; same as above, different order) Json::Value arrayFirstNone{ Json::arrayValue }; arrayFirstNone.append({ "first" }); arrayFirstNone.append({ "none" }); - VERIFY_THROWS_SPECIFIC(GetValue(arrayFirstNone), UnexpectedValueException, _ReturnTrueForException); + VERIFY_THROWS_SPECIFIC(GetValue(arrayFirstNone), DeserializationError, _ReturnTrueForException); // Unknown flag value? Json::Value stringUnknown{ "unknown" }; - VERIFY_THROWS_SPECIFIC(GetValue(stringUnknown), UnexpectedValueException, _ReturnTrueForException); + VERIFY_THROWS_SPECIFIC(GetValue(stringUnknown), DeserializationError, _ReturnTrueForException); } void JsonUtilsTests::NestedExceptionDuringKeyParse() @@ -420,20 +424,10 @@ namespace TerminalAppUnitTests Json::Value object{ Json::objectValue }; object[key] = Json::Value{ "string" }; - auto CheckKeyedException = [](const KeyedException& k) { - try - { - k.RethrowInner(); - } - catch (TypeMismatchException&) - { - // This Keyed exception contained the correct inner. - return true; - } - // This Keyed exception did not contain the correct inner. - return false; + auto CheckKeyInException = [](const DeserializationError& k) { + return k.key.has_value(); }; - VERIFY_THROWS_SPECIFIC(GetValueForKey(object, key), KeyedException, CheckKeyedException); + VERIFY_THROWS_SPECIFIC(GetValueForKey(object, key), DeserializationError, CheckKeyInException); } } From bc642bbf2a51e792b1eddb219d8ae3117bed9d3c Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Tue, 11 Aug 2020 14:57:45 -0500 Subject: [PATCH 038/266] Fix viewport moving when we've scrolled up and circled the buffer (#7247) If you scroll up to view the scrollback, then we want the viewport to "stay in place", as new output comes in (see #6062). This works fine up until the buffer circles. In this case, the mutable viewport isn't actually moving, so we never set `updatedViewport` to true. This regressed in #6062 Closes #7222 --- src/cascadia/TerminalCore/Terminal.cpp | 18 +++- .../TerminalBufferTests.cpp | 84 +++++++++++++++++++ 2 files changed, 101 insertions(+), 1 deletion(-) diff --git a/src/cascadia/TerminalCore/Terminal.cpp b/src/cascadia/TerminalCore/Terminal.cpp index 4709eeaf0e8..f6b3950a262 100644 --- a/src/cascadia/TerminalCore/Terminal.cpp +++ b/src/cascadia/TerminalCore/Terminal.cpp @@ -843,8 +843,12 @@ void Terminal::_AdjustCursorPosition(const COORD proposedPosition) } } - if (updatedViewport) + // If the viewport moved, or we circled the buffer, we might need to update + // our _scrollOffset + if (updatedViewport || newRows != 0) { + const auto oldScrollOffset = _scrollOffset; + // scroll if... // - no selection is active // - viewport is already at the bottom @@ -852,6 +856,18 @@ void Terminal::_AdjustCursorPosition(const COORD proposedPosition) _scrollOffset = scrollToOutput ? 0 : _scrollOffset + scrollAmount + newRows; + // Clamp the range to make sure that we don't scroll way off the top of the buffer + _scrollOffset = std::clamp(_scrollOffset, + 0, + _buffer->GetSize().Height() - _mutableViewport.Height()); + + // If the new scroll offset is different, then we'll still want to raise a scroll event + updatedViewport = updatedViewport || (oldScrollOffset != _scrollOffset); + } + + // If the viewport moved, then send a scrolling notification. + if (updatedViewport) + { _NotifyScrollEvent(); } diff --git a/src/cascadia/UnitTests_TerminalCore/TerminalBufferTests.cpp b/src/cascadia/UnitTests_TerminalCore/TerminalBufferTests.cpp index 5fbc2d7403d..e4636081803 100644 --- a/src/cascadia/UnitTests_TerminalCore/TerminalBufferTests.cpp +++ b/src/cascadia/UnitTests_TerminalCore/TerminalBufferTests.cpp @@ -39,6 +39,8 @@ class TerminalCoreUnitTests::TerminalBufferTests final TEST_METHOD(TestWrappingCharByChar); TEST_METHOD(TestWrappingALongString); + TEST_METHOD(DontSnapToOutputTest); + TEST_METHOD_SETUP(MethodSetup) { // STEP 1: Set up the Terminal @@ -149,3 +151,85 @@ void TerminalBufferTests::TestWrappingALongString() TestUtils::VerifyExpectedString(termTb, TestUtils::Test100CharsString, { 0, 0 }); } + +void TerminalBufferTests::DontSnapToOutputTest() +{ + auto& termTb = *term->_buffer; + auto& termSm = *term->_stateMachine; + const auto initialView = term->GetViewport(); + + VERIFY_ARE_EQUAL(0, initialView.Top()); + VERIFY_ARE_EQUAL(TerminalViewHeight, initialView.BottomExclusive()); + VERIFY_ARE_EQUAL(0, term->_scrollOffset); + + // -1 so that we don't print the last \n + for (int i = 0; i < TerminalViewHeight + 8 - 1; i++) + { + termSm.ProcessString(L"x\n"); + } + + const auto secondView = term->GetViewport(); + + VERIFY_ARE_EQUAL(8, secondView.Top()); + VERIFY_ARE_EQUAL(TerminalViewHeight + 8, secondView.BottomExclusive()); + VERIFY_ARE_EQUAL(0, term->_scrollOffset); + + Log::Comment(L"Scroll up one line"); + term->_scrollOffset = 1; + + const auto thirdView = term->GetViewport(); + VERIFY_ARE_EQUAL(7, thirdView.Top()); + VERIFY_ARE_EQUAL(TerminalViewHeight + 7, thirdView.BottomExclusive()); + VERIFY_ARE_EQUAL(1, term->_scrollOffset); + + Log::Comment(L"Print a few lines, to see that the viewport stays where it was"); + for (int i = 0; i < 8; i++) + { + termSm.ProcessString(L"x\n"); + } + + const auto fourthView = term->GetViewport(); + VERIFY_ARE_EQUAL(7, fourthView.Top()); + VERIFY_ARE_EQUAL(TerminalViewHeight + 7, fourthView.BottomExclusive()); + VERIFY_ARE_EQUAL(1 + 8, term->_scrollOffset); + + Log::Comment(L"Print enough lines to get the buffer just about ready to " + L"circle (on the next newline)"); + auto viewBottom = term->_mutableViewport.BottomInclusive(); + do + { + termSm.ProcessString(L"x\n"); + viewBottom = term->_mutableViewport.BottomInclusive(); + } while (viewBottom < termTb.GetSize().BottomInclusive()); + + const auto fifthView = term->GetViewport(); + VERIFY_ARE_EQUAL(7, fifthView.Top()); + VERIFY_ARE_EQUAL(TerminalViewHeight + 7, fifthView.BottomExclusive()); + VERIFY_ARE_EQUAL(TerminalHistoryLength - 7, term->_scrollOffset); + + Log::Comment(L"Print 3 more lines, and see that we stick to where the old " + L"rows now are in the buffer (after circling)"); + for (int i = 0; i < 3; i++) + { + termSm.ProcessString(L"x\n"); + Log::Comment(NoThrowString().Format( + L"_scrollOffset: %d", term->_scrollOffset)); + } + const auto sixthView = term->GetViewport(); + VERIFY_ARE_EQUAL(4, sixthView.Top()); + VERIFY_ARE_EQUAL(TerminalViewHeight + 4, sixthView.BottomExclusive()); + VERIFY_ARE_EQUAL(TerminalHistoryLength - 4, term->_scrollOffset); + + Log::Comment(L"Print 8 more lines, and see that we're now just stuck at the" + L"top of the buffer"); + for (int i = 0; i < 8; i++) + { + termSm.ProcessString(L"x\n"); + Log::Comment(NoThrowString().Format( + L"_scrollOffset: %d", term->_scrollOffset)); + } + const auto seventhView = term->GetViewport(); + VERIFY_ARE_EQUAL(0, seventhView.Top()); + VERIFY_ARE_EQUAL(TerminalViewHeight, seventhView.BottomExclusive()); + VERIFY_ARE_EQUAL(TerminalHistoryLength, term->_scrollOffset); +} From c5d5500758c011f7378552a78589ae38fd807ee5 Mon Sep 17 00:00:00 2001 From: "Dustin L. Howett" Date: Tue, 11 Aug 2020 13:08:03 -0700 Subject: [PATCH 039/266] tools: add Get-OSSConhostLog (#7250) This script takes a range of commits and generates a commit log with the git2git-excluded file changes filtered out. It also replaces GitHub issue numbers with GH-XXX so as to not confuse Git2Git or Azure DevOps. Community contributions are tagged with CC- so they can be detected later. The output looks like this: ``` Carlos Zamora (2) * Pass mouse button state into HandleMouse instead of asking win32 (GH-6765) Dustin L. Howett (6) * Disable MinimalCoreWin when OpenConsoleUniversalApp is false (GH-7203) James Holderness (1) * Add support for the "doubly underlined" graphic rendition attribute (CC-7223) ``` Yes, the numbers are wrong. No, it doesn't really matter. --- .github/actions/spell-check/expect/expect.txt | 11 +++- tools/Get-OSSConhostLog.ps1 | 65 +++++++++++++++++++ 2 files changed, 73 insertions(+), 3 deletions(-) create mode 100644 tools/Get-OSSConhostLog.ps1 diff --git a/.github/actions/spell-check/expect/expect.txt b/.github/actions/spell-check/expect/expect.txt index 5a74915444a..9379acedf80 100644 --- a/.github/actions/spell-check/expect/expect.txt +++ b/.github/actions/spell-check/expect/expect.txt @@ -352,6 +352,7 @@ conserv consoleapi CONSOLECONTROL CONSOLEENDTASK +consolegit CONSOLEIME consoleinternal Consoleroot @@ -422,6 +423,7 @@ cstdlib cstr cstring cstyle +CSV CSwitch CText ctime @@ -886,6 +888,7 @@ getwriter Gfun gfx gh +gitfilters github gitlab gle @@ -1056,6 +1059,8 @@ IInteract IInteractivity IIo IList +imagemagick +Imatch ime Imm IMouse @@ -1072,7 +1077,6 @@ INITCOMMONCONTROLSEX INITDIALOG initguid INITMENU -imagemagick inkscape inl INLINEPREFIX @@ -1520,8 +1524,8 @@ nothrow NOTICKS NOTIMPL notin -NOTOPMOST NOTNULL +NOTOPMOST NOTRACK NOTSUPPORTED notypeopt @@ -1610,8 +1614,8 @@ OSCBG OSCCT OSCFG OSCRCC -OSCSCC OSCSCB +OSCSCC OSCWT OSDEPENDSROOT osfhandle @@ -2337,6 +2341,7 @@ Toolset tooltip TOPDOWNDIB TOPLEFT +toplevel TOPRIGHT TOpt tosign diff --git a/tools/Get-OSSConhostLog.ps1 b/tools/Get-OSSConhostLog.ps1 new file mode 100644 index 00000000000..4c206effa8e --- /dev/null +++ b/tools/Get-OSSConhostLog.ps1 @@ -0,0 +1,65 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT license. + +################################ +# This script takes a range of commits and generates +# a commit log with the git2git-excluded file changes +# filtered out. +# +# It also replaces GitHub issue numbers with GH-XXX so +# as to not confuse Git2Git or Azure DevOps. +# Community contributions are tagged with CC- so they +# can be detected later. + +[CmdletBinding()] +Param( + [string]$RevisionRange +) + +Function Test-MicrosoftPerson($email) { + Return $email -like "*@microsoft.com" +} + +# Replaces github PR numbers with GH-XXX or CC-XXX (community contribution) +# and issue numbers with GH-XXX +Function Mangle-CommitMessage($object) { + $Prefix = "GH-" + If (-Not (Test-MicrosoftPerson $object.Email)) { + $Prefix = "CC-" + } + + $s = $object.Subject -Replace "\(#(\d+)\)", "(${Prefix}`$1)" + $s = $s -Replace "#(\d+)","GH-`$1" + $s +} + +Function Get-Git2GitIgnoresAsExcludes() { + $filters = (Get-Content (Join-Path (& git rev-parse --show-toplevel) consolegit2gitfilters.json) | ConvertFrom-Json) + $excludes = $filters.ContainsFilters | ? { $_ -Ne "/." } | % { $_ -Replace "^/","" } + $excludes += $filters.SuffixFilters | % { "**/*$_"; "*$_" } + $excludes += $filters.PrefixFilters | % { "**/$_*"; "$_*" } + $excludes | % { ":(top,exclude)$_" } +} + +$Excludes = Get-Git2GitIgnoresAsExcludes +Write-Verbose "IGNORING: $Excludes" +$Entries = & git log $RevisionRange "--pretty=format:%an%x1C%ae%x1C%s" -- $Excludes | + ConvertFrom-CSV -Delimiter "`u{001C}" -Header Author,Email,Subject + +Write-Verbose ("{0} unfiltered log entries" -f $Entries.Count) + +$Grouped = $Entries | Group Email +$Grouped | % { + $e = $_.Group[0].Email + $p = $_.Group[0].Author + "$p ($($_.Group.Count))" + $_.Group | % { + If ($_.Subject -Imatch "^Merge") { + # Skip merge commits + Return + } + $cm = Mangle-CommitMessage $_ + "* $cm" + } + "" +} From fe82e97ff6e532e2bf367344657c7b510bb56dc6 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Tue, 11 Aug 2020 18:56:58 -0500 Subject: [PATCH 040/266] Enable partial rebuilds of the TerminalControl project again (#7248) This regressed around the #7163 timeframe. We're discussing this on chat currently. It might break the intellisense on the `#include ` line in VS 16.7, but we're not _really_ sure? Intellisense has been notoriously flaky for us. I'm running 16.6.5, and it works for me. @lhecker is running 16.7 and confirmed it worked there. If the CI build passes, then this definitely will work for 16.7. --- src/cascadia/TerminalCore/lib/terminalcore-lib.vcxproj | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/cascadia/TerminalCore/lib/terminalcore-lib.vcxproj b/src/cascadia/TerminalCore/lib/terminalcore-lib.vcxproj index 42006cbda86..29c99c3eeae 100644 --- a/src/cascadia/TerminalCore/lib/terminalcore-lib.vcxproj +++ b/src/cascadia/TerminalCore/lib/terminalcore-lib.vcxproj @@ -8,6 +8,10 @@ StaticLibrary 10.0.17763.0 Microsoft.Terminal.TerminalControl + + + true + +[Command Palette Spec]: https://github.com/microsoft/terminal/blob/master/doc/specs/%232046%20-%20Command%20Palette.md +[New Tab Menu Customization Spec]: https://github.com/microsoft/terminal/blob/master/doc/specs/%231571%20-%20New%20Tab%20Menu%20Customization.md + +[#1571]: https://github.com/microsoft/terminal/issues/1571 +[#1912]: https://github.com/microsoft/terminal/issues/1912 +[#3337]: https://github.com/microsoft/terminal/issues/3337 +[#5025]: https://github.com/microsoft/terminal/issues/5025 +[#5524]: https://github.com/microsoft/terminal/issues/5524 +[#5633]: https://github.com/microsoft/terminal/issues/5633 +[#6532]: https://github.com/microsoft/terminal/issues/6532 +[#6899]: https://github.com/microsoft/terminal/issues/6899 diff --git a/doc/specs/#6899 - Action IDs/data-mockup-002.png b/doc/specs/#6899 - Action IDs/data-mockup-002.png new file mode 100644 index 0000000000000000000000000000000000000000..1a165d59fd5b5d0a7ffdaeaafe77f15be540329c GIT binary patch literal 106114 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