diff --git a/src/cascadia/TerminalApp/IPaneContent.idl b/src/cascadia/TerminalApp/IPaneContent.idl index a9fc04145f4..b2031bac6f9 100644 --- a/src/cascadia/TerminalApp/IPaneContent.idl +++ b/src/cascadia/TerminalApp/IPaneContent.idl @@ -14,7 +14,7 @@ namespace TerminalApp Windows.UI.Xaml.FrameworkElement GetRoot(); void UpdateSettings(Microsoft.Terminal.Settings.Model.CascadiaSettings settings); - Windows.Foundation.Size MinSize { get; }; + Windows.Foundation.Size MinimumSize { get; }; String Title { get; }; UInt64 TaskbarState { get; }; @@ -30,15 +30,15 @@ namespace TerminalApp void Close(); - event Windows.Foundation.TypedEventHandler CloseRequested; + event Windows.Foundation.TypedEventHandler CloseRequested; - event Windows.Foundation.TypedEventHandler BellRequested; - event Windows.Foundation.TypedEventHandler TitleChanged; - event Windows.Foundation.TypedEventHandler TabColorChanged; - event Windows.Foundation.TypedEventHandler TaskbarProgressChanged; event Windows.Foundation.TypedEventHandler ConnectionStateChanged; - event Windows.Foundation.TypedEventHandler ReadOnlyChanged; - event Windows.Foundation.TypedEventHandler FocusRequested; + event Windows.Foundation.TypedEventHandler BellRequested; + event Windows.Foundation.TypedEventHandler TitleChanged; + event Windows.Foundation.TypedEventHandler TabColorChanged; + event Windows.Foundation.TypedEventHandler TaskbarProgressChanged; + event Windows.Foundation.TypedEventHandler ReadOnlyChanged; + event Windows.Foundation.TypedEventHandler FocusRequested; }; @@ -51,6 +51,6 @@ namespace TerminalApp interface ISnappable { Single SnapDownToGrid(PaneSnapDirection direction, Single sizeToSnap); - Windows.Foundation.Size GridSize { get; }; + Windows.Foundation.Size GridUnitSize { get; }; }; } diff --git a/src/cascadia/TerminalApp/Pane.cpp b/src/cascadia/TerminalApp/Pane.cpp index c62f81fcaa7..057d2589311 100644 --- a/src/cascadia/TerminalApp/Pane.cpp +++ b/src/cascadia/TerminalApp/Pane.cpp @@ -3,6 +3,7 @@ #include "pch.h" #include "Pane.h" + #include "AppLogic.h" #include "Utils.h" @@ -1080,14 +1081,7 @@ TermControl Pane::GetLastFocusedTerminalControl() { if (p->_IsLeaf()) { - if (const auto& terminalPane{ p->_content.try_as() }) - { - return terminalPane.GetTerminal(); - } - else - { - return nullptr; - } + return p->GetTerminalControl(); } pane = p; } @@ -1095,15 +1089,8 @@ TermControl Pane::GetLastFocusedTerminalControl() } return _firstChild->GetLastFocusedTerminalControl(); } - - if (const auto& terminalPane{ _content.try_as() }) - { - return terminalPane.GetTerminal(); - } - else - { - return nullptr; - } + // we _are_ a leaf. + return GetTerminalControl(); } IPaneContent Pane::GetLastFocusedContent() @@ -1140,7 +1127,7 @@ TermControl Pane::GetTerminalControl() const { if (const auto& terminalPane{ _getTerminalContent() }) { - return terminalPane.GetTerminal(); + return terminalPane.GetTermControl(); } else { @@ -2667,7 +2654,7 @@ Pane::SnapSizeResult Pane::_CalcSnappedDimension(const bool widthOrHeight, const } else { - const auto cellSize = snappable.GridSize(); + const auto cellSize = snappable.GridUnitSize(); const auto higher = lower + (direction == PaneSnapDirection::Width ? cellSize.Width : cellSize.Height); @@ -2728,13 +2715,11 @@ void Pane::_AdvanceSnappedDimension(const bool widthOrHeight, LayoutSizeNode& si // be, say, half a character, or fixed 10 pixels), so snap it upward. It might // however be already snapped, so add 1 to make sure it really increases // (not strictly necessary but to avoid surprises). - sizeNode.size = _CalcSnappedDimension(widthOrHeight, - sizeNode.size + 1) - .higher; + sizeNode.size = _CalcSnappedDimension(widthOrHeight, sizeNode.size + 1).higher; } else { - const auto cellSize = snappable.GridSize(); + const auto cellSize = snappable.GridUnitSize(); sizeNode.size += widthOrHeight ? cellSize.Width : cellSize.Height; } } @@ -2850,7 +2835,7 @@ Size Pane::_GetMinSize() const { if (_IsLeaf()) { - auto controlSize = _content.MinSize(); + auto controlSize = _content.MinimumSize(); auto newWidth = controlSize.Width; auto newHeight = controlSize.Height; diff --git a/src/cascadia/TerminalApp/Pane.h b/src/cascadia/TerminalApp/Pane.h index 7ae85bc95bf..f334151e513 100644 --- a/src/cascadia/TerminalApp/Pane.h +++ b/src/cascadia/TerminalApp/Pane.h @@ -222,7 +222,6 @@ class Pane : public std::enable_shared_from_this WINRT_CALLBACK(GotFocus, gotFocusArgs); WINRT_CALLBACK(LostFocus, winrt::delegate>); - WINRT_CALLBACK(PaneRaiseBell, winrt::Windows::Foundation::EventHandler); WINRT_CALLBACK(Detached, winrt::delegate>); private: diff --git a/src/cascadia/TerminalApp/PaneArgs.cpp b/src/cascadia/TerminalApp/PaneArgs.cpp deleted file mode 100644 index 2b5beddb8b5..00000000000 --- a/src/cascadia/TerminalApp/PaneArgs.cpp +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. - -#include "pch.h" -#include "PaneArgs.h" -#include "BellEventArgs.g.cpp" diff --git a/src/cascadia/TerminalApp/PaneArgs.h b/src/cascadia/TerminalApp/PaneArgs.h deleted file mode 100644 index 5627623be9e..00000000000 --- a/src/cascadia/TerminalApp/PaneArgs.h +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. - -#pragma once - -#include "BellEventArgs.g.h" - -namespace winrt::TerminalApp::implementation -{ - struct BellEventArgs : public BellEventArgsT - { - public: - BellEventArgs(bool flashTaskbar) : - FlashTaskbar(flashTaskbar) {} - - til::property FlashTaskbar; - }; -}; diff --git a/src/cascadia/TerminalApp/TerminalAppLib.vcxproj b/src/cascadia/TerminalApp/TerminalAppLib.vcxproj index 9abea465324..d0629da8036 100644 --- a/src/cascadia/TerminalApp/TerminalAppLib.vcxproj +++ b/src/cascadia/TerminalApp/TerminalAppLib.vcxproj @@ -128,9 +128,6 @@ - - IPaneContent.idl - @@ -239,9 +236,6 @@ - - IPaneContent.idl - NotUsing diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index e046d9f6c31..e41159a8062 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -1306,7 +1306,7 @@ namespace winrt::TerminalApp::implementation return nullptr; } - const auto& control{ paneContent.GetTerminal() }; + const auto& control{ paneContent.GetTermControl() }; if (control == nullptr) { return nullptr; @@ -1731,11 +1731,8 @@ namespace winrt::TerminalApp::implementation // Add an event handler for when the terminal or tab wants to set a // progress indicator on the taskbar hostingTab.TaskbarProgressChanged({ get_weak(), &TerminalPage::_SetTaskbarProgressHandler }); - } - void TerminalPage::_RegisterPaneEvents(const TerminalApp::TerminalPaneContent& paneContent) - { - paneContent.RestartTerminalRequested({ get_weak(), &TerminalPage::_restartPaneConnection }); + hostingTab.RestartTerminalRequested({ get_weak(), &TerminalPage::_restartPaneConnection }); } // Method Description: @@ -2390,16 +2387,6 @@ namespace winrt::TerminalApp::implementation _UnZoomIfNeeded(); auto [original, _] = activeTab->SplitPane(*realSplitType, splitSize, newPane); - // When we split the pane, the Pane itself will create a _new_ Pane - // instance for the original content. We need to make sure we also - // re-add our event handler to that newly created pane. - // - // _MakePane will already call this for the newly created pane. - if (const auto& paneContent{ original->GetContent().try_as() }) - { - _RegisterPaneEvents(*paneContent); - } - // After GH#6586, the control will no longer focus itself // automatically when it's finished being laid out. Manually focus // the control here instead. @@ -3131,8 +3118,8 @@ namespace winrt::TerminalApp::implementation // serialize the actual profile's GUID along with the content guid. const auto& profile = _settings.GetProfileForArgs(newTerminalArgs); const auto control = _AttachControlToContent(newTerminalArgs.ContentId()); - auto terminalPane{ winrt::make(profile, control) }; - return std::make_shared(terminalPane); + auto paneContent{ winrt::make(profile, control) }; + return std::make_shared(paneContent); } TerminalSettingsCreateResult controlSettings{ nullptr }; @@ -3188,15 +3175,15 @@ namespace winrt::TerminalApp::implementation const auto control = _CreateNewControlAndContent(controlSettings, connection); - auto terminalPane{ winrt::make(profile, control) }; - auto resultPane = std::make_shared(terminalPane); + auto paneContent{ winrt::make(profile, control) }; + auto resultPane = std::make_shared(paneContent); if (debugConnection) // this will only be set if global debugging is on and tap is active { auto newControl = _CreateNewControlAndContent(controlSettings, debugConnection); // Split (auto) with the debug tap. - auto debugTerminalPane{ winrt::make(profile, newControl) }; - auto debugPane = std::make_shared(debugTerminalPane); + auto debugContent{ winrt::make(profile, newControl) }; + auto debugPane = std::make_shared(debugContent); // Since we're doing this split directly on the pane (instead of going through TerminalTab, // we need to handle the panes 'active' states @@ -3210,8 +3197,6 @@ namespace winrt::TerminalApp::implementation original->SetActive(); } - _RegisterPaneEvents(terminalPane); - return resultPane; } @@ -3225,7 +3210,7 @@ namespace winrt::TerminalApp::implementation // for nulls if (const auto& connection{ _duplicateConnectionForRestart(paneContent) }) { - paneContent.GetTerminal().Connection(connection); + paneContent.GetTermControl().Connection(connection); connection.Start(); } } diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h index 00215eb749b..82c8482aace 100644 --- a/src/cascadia/TerminalApp/TerminalPage.h +++ b/src/cascadia/TerminalApp/TerminalPage.h @@ -347,7 +347,6 @@ namespace winrt::TerminalApp::implementation void _InitializeTab(winrt::com_ptr newTabImpl, uint32_t insertPosition = -1); void _RegisterTerminalEvents(Microsoft::Terminal::Control::TermControl term); void _RegisterTabEvents(TerminalTab& hostingTab); - void _RegisterPaneEvents(const TerminalApp::TerminalPaneContent& paneContent); void _DismissTabContextMenus(); void _FocusCurrentTab(const bool focusAlways); diff --git a/src/cascadia/TerminalApp/TerminalPaneContent.cpp b/src/cascadia/TerminalApp/TerminalPaneContent.cpp index 4813c08443a..e8de73ab7ad 100644 --- a/src/cascadia/TerminalApp/TerminalPaneContent.cpp +++ b/src/cascadia/TerminalApp/TerminalPaneContent.cpp @@ -3,9 +3,10 @@ #include "pch.h" #include "TerminalPaneContent.h" -#include "PaneArgs.h" #include "TerminalPaneContent.g.cpp" +#include "BellEventArgs.g.cpp" + #include using namespace winrt::Windows::Foundation; using namespace winrt::Windows::UI::Xaml; @@ -45,11 +46,11 @@ namespace winrt::TerminalApp::implementation { return _control; } - winrt::Microsoft::Terminal::Control::TermControl TerminalPaneContent::GetTerminal() + winrt::Microsoft::Terminal::Control::TermControl TerminalPaneContent::GetTermControl() { return _control; } - winrt::Windows::Foundation::Size TerminalPaneContent::MinSize() + winrt::Windows::Foundation::Size TerminalPaneContent::MinimumSize() { return _control.MinimumSize(); } @@ -348,7 +349,7 @@ namespace winrt::TerminalApp::implementation { return _control.SnapDimensionToGrid(direction == PaneSnapDirection::Width, sizeToSnap); } - Windows::Foundation::Size TerminalPaneContent::GridSize() + Windows::Foundation::Size TerminalPaneContent::GridUnitSize() { return _control.CharacterDimensions(); } diff --git a/src/cascadia/TerminalApp/TerminalPaneContent.h b/src/cascadia/TerminalApp/TerminalPaneContent.h index 91da5b31c07..7d3a9f5c0da 100644 --- a/src/cascadia/TerminalApp/TerminalPaneContent.h +++ b/src/cascadia/TerminalApp/TerminalPaneContent.h @@ -3,19 +3,27 @@ #pragma once #include "TerminalPaneContent.g.h" -#include "../../cascadia/inc/cppwinrt_utils.h" -#include +#include "BellEventArgs.g.h" namespace winrt::TerminalApp::implementation { + struct BellEventArgs : public BellEventArgsT + { + public: + BellEventArgs(bool flashTaskbar) : + FlashTaskbar(flashTaskbar) {} + + til::property FlashTaskbar; + }; + struct TerminalPaneContent : TerminalPaneContentT { TerminalPaneContent(const winrt::Microsoft::Terminal::Settings::Model::Profile& profile, const winrt::Microsoft::Terminal::Control::TermControl& control); winrt::Windows::UI::Xaml::FrameworkElement GetRoot(); - winrt::Microsoft::Terminal::Control::TermControl GetTerminal(); - winrt::Windows::Foundation::Size MinSize(); + winrt::Microsoft::Terminal::Control::TermControl GetTermControl(); + winrt::Windows::Foundation::Size MinimumSize(); void Focus(winrt::Windows::UI::Xaml::FocusState reason = winrt::Windows::UI::Xaml::FocusState::Programmatic); void Close(); @@ -29,7 +37,7 @@ namespace winrt::TerminalApp::implementation winrt::Microsoft::Terminal::Settings::Model::Profile GetProfile() const { return _profile; - }; + } winrt::hstring Title() { return _control.Title(); } uint64_t TaskbarState() { return _control.TaskbarState(); } @@ -40,17 +48,17 @@ namespace winrt::TerminalApp::implementation winrt::Windows::UI::Xaml::Media::Brush BackgroundBrush(); float SnapDownToGrid(const TerminalApp::PaneSnapDirection direction, const float sizeToSnap); - Windows::Foundation::Size GridSize(); + Windows::Foundation::Size GridUnitSize(); til::typed_event RestartTerminalRequested; - til::typed_event<> CloseRequested; - til::typed_event BellRequested; - til::typed_event<> TitleChanged; - til::typed_event<> TabColorChanged; - til::typed_event<> TaskbarProgressChanged; til::typed_event<> ConnectionStateChanged; - til::typed_event<> ReadOnlyChanged; - til::typed_event<> FocusRequested; + til::typed_event CloseRequested; + til::typed_event BellRequested; + til::typed_event TitleChanged; + til::typed_event TabColorChanged; + til::typed_event TaskbarProgressChanged; + til::typed_event ReadOnlyChanged; + til::typed_event FocusRequested; private: winrt::Microsoft::Terminal::Control::TermControl _control{ nullptr }; diff --git a/src/cascadia/TerminalApp/TerminalPaneContent.idl b/src/cascadia/TerminalApp/TerminalPaneContent.idl index adb24d8eb35..9f8a697d4a6 100644 --- a/src/cascadia/TerminalApp/TerminalPaneContent.idl +++ b/src/cascadia/TerminalApp/TerminalPaneContent.idl @@ -8,7 +8,7 @@ namespace TerminalApp { [default_interface] runtimeclass TerminalPaneContent : IPaneContent, ISnappable { - Microsoft.Terminal.Control.TermControl GetTerminal(); + Microsoft.Terminal.Control.TermControl GetTermControl(); void UpdateTerminalSettings(TerminalSettingsCache cache); diff --git a/src/cascadia/TerminalApp/TerminalTab.cpp b/src/cascadia/TerminalApp/TerminalTab.cpp index 4b4177ff4ca..56b3cec7554 100644 --- a/src/cascadia/TerminalApp/TerminalTab.cpp +++ b/src/cascadia/TerminalApp/TerminalTab.cpp @@ -933,7 +933,6 @@ namespace winrt::TerminalApp::implementation if (it != _contentEvents.end()) { // revoke the event handlers by resetting the event struct - it->second = {}; // and remove it from the map _contentEvents.erase(paneId); } @@ -959,7 +958,7 @@ namespace winrt::TerminalApp::implementation events.CloseRequested = content.CloseRequested( winrt::auto_revoke, [dispatcher, weakThis](auto sender, auto&&) -> winrt::fire_and_forget { - // Don't forget! this ^^^^^^^^ sender can't be a reference, this is a async callback. + // Don't forget! this ^^^^^^^^ sender can't be a reference, this is a async callback. // The lambda lives in the `std::function`-style container owned by `control`. That is, when the // `control` gets destroyed the lambda struct also gets destroyed. In other words, we need to @@ -1050,26 +1049,55 @@ namespace winrt::TerminalApp::implementation events.FocusRequested = content.FocusRequested( winrt::auto_revoke, - [dispatcher, weakThis](auto sender, auto) -> winrt::fire_and_forget { + [dispatcher, weakThis](TerminalApp::IPaneContent sender, auto) -> winrt::fire_and_forget { const auto weakThisCopy = weakThis; co_await wil::resume_foreground(dispatcher); if (const auto tab{ weakThisCopy.get() }) { if (tab->_focused()) { - if (const auto content{ sender.try_as() }) - { - content.Focus(FocusState::Pointer); - } + sender.Focus(FocusState::Pointer); } } }); + events.BellRequested = content.BellRequested( + winrt::auto_revoke, + [dispatcher, weakThis](TerminalApp::IPaneContent sender, auto bellArgs) -> winrt::fire_and_forget { + const auto weakThisCopy = weakThis; + co_await wil::resume_foreground(dispatcher); + if (const auto tab{ weakThisCopy.get() }) + { + if (bellArgs.FlashTaskbar()) + { + // If visual is set, we need to bubble this event all the way to app host to flash the taskbar + // In this part of the chain we bubble it from the hosting tab to the page + tab->_TabRaiseVisualBellHandlers(); + } + + // Show the bell indicator in the tab header + tab->ShowBellIndicator(true); + + // If this tab is focused, activate the bell indicator timer, which will + // remove the bell indicator once it fires + // (otherwise, the indicator is removed when the tab gets focus) + if (tab->_focusState != WUX::FocusState::Unfocused) + { + tab->ActivateBellIndicatorTimer(); + } + } + }); + + if (const auto& terminal{ content.try_as() }) + { + events.RestartTerminalRequested = terminal.RestartTerminalRequested(winrt::auto_revoke, { get_weak(), &TerminalTab::_bubbleRestartTerminalRequested }); + } + if (_tabStatus.IsInputBroadcastActive()) { if (const auto& termContent{ content.try_as() }) { - _addBroadcastHandlers(termContent.GetTerminal(), events); + _addBroadcastHandlers(termContent.GetTermControl(), events); } } @@ -1751,7 +1779,7 @@ namespace winrt::TerminalApp::implementation { if (const auto termContent{ content.try_as() }) { - return termContent.GetTerminal(); + return termContent.GetTermControl(); } } return nullptr; @@ -2003,4 +2031,9 @@ namespace winrt::TerminalApp::implementation ActionAndArgs actionAndArgs{ ShortcutAction::Find, nullptr }; _dispatch.DoAction(*this, actionAndArgs); } + void TerminalTab::_bubbleRestartTerminalRequested(TerminalApp::TerminalPaneContent sender, + const winrt::Windows::Foundation::IInspectable& args) + { + RestartTerminalRequested.raise(sender, args); + } } diff --git a/src/cascadia/TerminalApp/TerminalTab.h b/src/cascadia/TerminalApp/TerminalTab.h index a27375926c3..9d116d8ff49 100644 --- a/src/cascadia/TerminalApp/TerminalTab.h +++ b/src/cascadia/TerminalApp/TerminalTab.h @@ -97,6 +97,8 @@ namespace winrt::TerminalApp::implementation return _tabStatus; } + til::typed_event RestartTerminalRequested; + WINRT_CALLBACK(ActivePaneChanged, winrt::delegate<>); WINRT_CALLBACK(TabRaiseVisualBell, winrt::delegate<>); TYPED_EVENT(TaskbarProgressChanged, IInspectable, IInspectable); @@ -138,6 +140,8 @@ namespace winrt::TerminalApp::implementation winrt::Microsoft::Terminal::Control::TermControl::KeySent_revoker KeySent; winrt::Microsoft::Terminal::Control::TermControl::CharSent_revoker CharSent; winrt::Microsoft::Terminal::Control::TermControl::StringSent_revoker StringSent; + + winrt::TerminalApp::TerminalPaneContent::RestartTerminalRequested_revoker RestartTerminalRequested; }; std::unordered_map _contentEvents; @@ -196,6 +200,8 @@ namespace winrt::TerminalApp::implementation void _moveTabToNewWindowClicked(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::UI::Xaml::RoutedEventArgs& e); void _findClicked(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::UI::Xaml::RoutedEventArgs& e); + void _bubbleRestartTerminalRequested(TerminalApp::TerminalPaneContent sender, const winrt::Windows::Foundation::IInspectable& args); + friend class ::TerminalAppLocalTests::TabTests; }; } diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index d1526faf534..de7b6fc88a9 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -333,7 +333,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation // (The window has a min. size that ensures that there's always a scrollbar thumb.) if (drawableRange < 0) { - // assert(false); return; }