From 03d33234d06b9968accc09c6d6ee4d8060522247 Mon Sep 17 00:00:00 2001 From: khvitaly Date: Fri, 19 Feb 2021 11:09:11 +0200 Subject: [PATCH 1/5] Introduce Pane broadcast --- src/cascadia/TerminalApp/Pane.cpp | 16 ++++++++++++ src/cascadia/TerminalApp/Pane.h | 2 ++ src/cascadia/TerminalApp/TerminalTab.cpp | 10 ++++++++ src/cascadia/TerminalControl/TermControl.cpp | 27 +++++++++++++++++--- src/cascadia/TerminalControl/TermControl.h | 26 +++++++++++++++++++ src/cascadia/TerminalControl/TermControl.idl | 10 ++++++++ 6 files changed, 88 insertions(+), 3 deletions(-) diff --git a/src/cascadia/TerminalApp/Pane.cpp b/src/cascadia/TerminalApp/Pane.cpp index f7d681564a5..a5ffe5358f5 100644 --- a/src/cascadia/TerminalApp/Pane.cpp +++ b/src/cascadia/TerminalApp/Pane.cpp @@ -2101,6 +2101,22 @@ bool Pane::ContainsReadOnly() const return _IsLeaf() ? _control.ReadOnly() : (_firstChild->ContainsReadOnly() || _secondChild->ContainsReadOnly()); } +void Pane::BroadcastKey(const winrt::Microsoft::Terminal::TerminalControl::TermControl& sourceControl, const WORD vkey, const WORD scanCode, const DWORD modifiers, const bool keyDown) +{ + if (_IsLeaf()) + { + if (_control != sourceControl) + { + _control.TrySendKeyEvent(vkey, scanCode, modifiers, keyDown); + } + } + else + { + _firstChild->BroadcastKey(sourceControl, vkey, scanCode, modifiers, keyDown); + _secondChild->BroadcastKey(sourceControl, vkey, scanCode, modifiers, keyDown); + } +} + DEFINE_EVENT(Pane, GotFocus, _GotFocusHandlers, winrt::delegate>); DEFINE_EVENT(Pane, LostFocus, _LostFocusHandlers, winrt::delegate>); DEFINE_EVENT(Pane, PaneRaiseBell, _PaneRaiseBellHandlers, winrt::Windows::Foundation::EventHandler); diff --git a/src/cascadia/TerminalApp/Pane.h b/src/cascadia/TerminalApp/Pane.h index 0aa41958e1f..b4b2a1cca95 100644 --- a/src/cascadia/TerminalApp/Pane.h +++ b/src/cascadia/TerminalApp/Pane.h @@ -83,6 +83,8 @@ class Pane : public std::enable_shared_from_this bool ContainsReadOnly() const; + void BroadcastKey(const winrt::Microsoft::Terminal::TerminalControl::TermControl& sourceControl, const WORD vkey, const WORD scanCode, const DWORD modifiers, const bool keyDown); + WINRT_CALLBACK(Closed, winrt::Windows::Foundation::EventHandler); DECLARE_EVENT(GotFocus, _GotFocusHandlers, winrt::delegate>); DECLARE_EVENT(LostFocus, _LostFocusHandlers, winrt::delegate>); diff --git a/src/cascadia/TerminalApp/TerminalTab.cpp b/src/cascadia/TerminalApp/TerminalTab.cpp index e290cee3042..a6eec4b3af8 100644 --- a/src/cascadia/TerminalApp/TerminalTab.cpp +++ b/src/cascadia/TerminalApp/TerminalTab.cpp @@ -628,6 +628,16 @@ namespace winrt::TerminalApp::implementation } } }); + + control.KeySent([weakThis](auto&& sender, auto&& e) { + if (const auto tab{ weakThis.get() }) + { + if (const auto termControl{ sender.try_as() }) + { + tab->_rootPane->BroadcastKey(termControl, e.VKey(), e.ScanCode(), e.Modifiers(), e.KeyDown()); + } + } + }); } // Method Description: diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index d929597a6c1..cfffa44e80d 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -1091,6 +1091,25 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation } } + // Method Description: + // - Invokes TrySendKeyEvent and triggers KeySent event + // Arguments: + // - vkey: The vkey of the key pressed. + // - scanCode: The scan code of the key pressed. + // - keyStates: The Microsoft::Terminal::Core::ControlKeyStates representing the modifier key states. + // - keyDown: If true, the key was pressed, otherwise the key was released. + bool TermControl::_TrySendKeyEvent(const WORD vkey, + const WORD scanCode, + const ControlKeyStates keyStates, + const bool keyDown) + { + const auto modifiers = keyStates.Value(); + const auto result = TrySendKeyEvent(vkey, scanCode, modifiers, keyDown); + auto keySentArgs = winrt::make(vkey, scanCode, modifiers, keyDown); + _keySentHandlers(*this, std::move(keySentArgs)); + return result; + } + // Method Description: // - Send this particular key event to the terminal. // See Terminal::SendKeyEvent for more information. @@ -1101,9 +1120,9 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation // - scanCode: The scan code of the key pressed. // - states: The Microsoft::Terminal::Core::ControlKeyStates representing the modifier key states. // - keyDown: If true, the key was pressed, otherwise the key was released. - bool TermControl::_TrySendKeyEvent(const WORD vkey, + bool TermControl::TrySendKeyEvent(const WORD vkey, const WORD scanCode, - const ControlKeyStates modifiers, + const DWORD modifiers, const bool keyDown) { // When there is a selection active, escape should clear it and NOT flow through @@ -1149,7 +1168,8 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation // If the terminal translated the key, mark the event as handled. // This will prevent the system from trying to get the character out // of it and sending us a CharacterReceived event. - const auto handled = vkey ? _terminal->SendKeyEvent(vkey, scanCode, modifiers, keyDown) : true; + ControlKeyStates keyStates{ modifiers }; + const auto handled = vkey ? _terminal->SendKeyEvent(vkey, scanCode, keyStates, keyDown) : true; if (_cursorTimer.has_value()) { @@ -3363,5 +3383,6 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(TermControl, OpenHyperlink, _openHyperlinkHandlers, TerminalControl::TermControl, TerminalControl::OpenHyperlinkEventArgs); DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(TermControl, SetTaskbarProgress, _setTaskbarProgressHandlers, TerminalControl::TermControl, IInspectable); DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(TermControl, RaiseNotice, _raiseNoticeHandlers, TerminalControl::TermControl, TerminalControl::NoticeEventArgs); + DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(TermControl, KeySent, _keySentHandlers, TerminalControl::TermControl, TerminalControl::KeySentEventArgs); // clang-format on } diff --git a/src/cascadia/TerminalControl/TermControl.h b/src/cascadia/TerminalControl/TermControl.h index 52b76422ec8..9b2aad3c69e 100644 --- a/src/cascadia/TerminalControl/TermControl.h +++ b/src/cascadia/TerminalControl/TermControl.h @@ -8,6 +8,7 @@ #include "PasteFromClipboardEventArgs.g.h" #include "OpenHyperlinkEventArgs.g.h" #include "NoticeEventArgs.g.h" +#include "KeySentEventArgs.g.h" #include #include "../../renderer/base/Renderer.hpp" #include "../../renderer/dx/DxRenderer.hpp" @@ -98,6 +99,28 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation const hstring _message; }; + struct KeySentEventArgs : + public KeySentEventArgsT + { + public: + KeySentEventArgs(const WORD vkey, const WORD scanCode, const DWORD modifiers, const bool keyDown) : + _vkey(vkey), + _scanCode(scanCode), + _modifiers(modifiers), + _keyDown(keyDown) {} + + WORD VKey() { return _vkey; }; + WORD ScanCode() { return _scanCode; }; + DWORD Modifiers() { return _modifiers; }; + bool KeyDown() { return _keyDown; }; + + private: + const WORD _vkey; + const WORD _scanCode; + const DWORD _modifiers; + const bool _keyDown; + }; + struct TermControl : TermControlT { TermControl(IControlSettings settings, TerminalConnection::ITerminalConnection connection); @@ -169,6 +192,8 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation bool ReadOnly() const noexcept; void ToggleReadOnly(); + bool TrySendKeyEvent(const WORD vkey, const WORD scanCode, const DWORD modifiers, const bool keyDown); + // clang-format off // -------------------------------- WinRT Events --------------------------------- DECLARE_EVENT(TitleChanged, _titleChangedHandlers, TerminalControl::TitleChangedEventArgs); @@ -180,6 +205,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(OpenHyperlink, _openHyperlinkHandlers, TerminalControl::TermControl, TerminalControl::OpenHyperlinkEventArgs); DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(SetTaskbarProgress, _setTaskbarProgressHandlers, TerminalControl::TermControl, IInspectable); DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(RaiseNotice, _raiseNoticeHandlers, TerminalControl::TermControl, TerminalControl::NoticeEventArgs); + DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(KeySent, _keySentHandlers, TerminalControl::TermControl, TerminalControl::KeySentEventArgs); TYPED_EVENT(WarningBell, IInspectable, IInspectable); TYPED_EVENT(ConnectionStateChanged, TerminalControl::TermControl, IInspectable); diff --git a/src/cascadia/TerminalControl/TermControl.idl b/src/cascadia/TerminalControl/TermControl.idl index 4470c0555d6..dc7139a838a 100644 --- a/src/cascadia/TerminalControl/TermControl.idl +++ b/src/cascadia/TerminalControl/TermControl.idl @@ -59,6 +59,14 @@ namespace Microsoft.Terminal.TerminalControl String Message { get; }; } + runtimeclass KeySentEventArgs + { + UInt16 VKey { get; }; + UInt16 ScanCode { get; }; + UInt32 Modifiers { get; }; + Boolean KeyDown { get; }; + } + [default_interface] runtimeclass TermControl : Windows.UI.Xaml.Controls.UserControl, IDirectKeyListener, IMouseWheelListener { TermControl(Microsoft.Terminal.TerminalControl.IControlSettings settings, Microsoft.Terminal.TerminalConnection.ITerminalConnection connection); @@ -79,6 +87,7 @@ namespace Microsoft.Terminal.TerminalControl event Windows.Foundation.TypedEventHandler WarningBell; event Windows.Foundation.TypedEventHandler HidePointerCursor; event Windows.Foundation.TypedEventHandler RestorePointerCursor; + event Windows.Foundation.TypedEventHandler KeySent; event Windows.Foundation.TypedEventHandler Initialized; // This is an event handler forwarder for the underlying connection. @@ -109,6 +118,7 @@ namespace Microsoft.Terminal.TerminalControl void ToggleShaderEffects(); void SendInput(String input); + Boolean TrySendKeyEvent(UInt16 vkey, UInt16 scanCode, UInt32 modifiers, Boolean keyDown); void TaskbarProgressChanged(); UInt64 TaskbarState { get; }; From f77a69d409f93495b9d01581a5291bc6cc5bf894 Mon Sep 17 00:00:00 2001 From: khvitaly Date: Fri, 19 Feb 2021 20:08:54 +0200 Subject: [PATCH 2/5] Introduce Char broadcast --- src/cascadia/TerminalApp/Pane.cpp | 16 +++++ src/cascadia/TerminalApp/Pane.h | 1 + src/cascadia/TerminalApp/TerminalTab.cpp | 11 +++- src/cascadia/TerminalControl/TermControl.cpp | 20 +++++-- src/cascadia/TerminalControl/TermControl.h | 62 +++++++++++++------- src/cascadia/TerminalControl/TermControl.idl | 9 +++ 6 files changed, 94 insertions(+), 25 deletions(-) diff --git a/src/cascadia/TerminalApp/Pane.cpp b/src/cascadia/TerminalApp/Pane.cpp index a5ffe5358f5..c67232f8883 100644 --- a/src/cascadia/TerminalApp/Pane.cpp +++ b/src/cascadia/TerminalApp/Pane.cpp @@ -2117,6 +2117,22 @@ void Pane::BroadcastKey(const winrt::Microsoft::Terminal::TerminalControl::TermC } } +void Pane::BroadcastChar(const winrt::Microsoft::Terminal::TerminalControl::TermControl& sourceControl, const wchar_t character, const WORD scanCode, const DWORD modifiers) +{ + if (_IsLeaf()) + { + if (_control != sourceControl) + { + _control.TrySendChar(character, scanCode, modifiers); + } + } + else + { + _firstChild->BroadcastChar(sourceControl, character, scanCode, modifiers); + _secondChild->BroadcastChar(sourceControl, character, scanCode, modifiers); + } +} + DEFINE_EVENT(Pane, GotFocus, _GotFocusHandlers, winrt::delegate>); DEFINE_EVENT(Pane, LostFocus, _LostFocusHandlers, winrt::delegate>); DEFINE_EVENT(Pane, PaneRaiseBell, _PaneRaiseBellHandlers, winrt::Windows::Foundation::EventHandler); diff --git a/src/cascadia/TerminalApp/Pane.h b/src/cascadia/TerminalApp/Pane.h index b4b2a1cca95..8ec1362da81 100644 --- a/src/cascadia/TerminalApp/Pane.h +++ b/src/cascadia/TerminalApp/Pane.h @@ -84,6 +84,7 @@ class Pane : public std::enable_shared_from_this bool ContainsReadOnly() const; void BroadcastKey(const winrt::Microsoft::Terminal::TerminalControl::TermControl& sourceControl, const WORD vkey, const WORD scanCode, const DWORD modifiers, const bool keyDown); + void BroadcastChar(const winrt::Microsoft::Terminal::TerminalControl::TermControl& sourceControl, const wchar_t vkey, const WORD scanCode, const DWORD modifiers); WINRT_CALLBACK(Closed, winrt::Windows::Foundation::EventHandler); DECLARE_EVENT(GotFocus, _GotFocusHandlers, winrt::delegate>); diff --git a/src/cascadia/TerminalApp/TerminalTab.cpp b/src/cascadia/TerminalApp/TerminalTab.cpp index a6eec4b3af8..9deebeafff1 100644 --- a/src/cascadia/TerminalApp/TerminalTab.cpp +++ b/src/cascadia/TerminalApp/TerminalTab.cpp @@ -412,7 +412,6 @@ namespace winrt::TerminalApp::implementation ++_nextPaneId; } _activePane = first; - _AttachEventHandlersToControl(control); // Add a event handlers to the new panes' GotFocus event. When the pane // gains focus, we'll mark it as the new active pane. @@ -638,6 +637,16 @@ namespace winrt::TerminalApp::implementation } } }); + + control.CharSent([weakThis](auto&& sender, auto&& e) { + if (const auto tab{ weakThis.get() }) + { + if (const auto termControl{ sender.try_as() }) + { + tab->_rootPane->BroadcastChar(termControl, e.Character(), e.ScanCode(), e.Modifiers()); + } + } + }); } // Method Description: diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index cfffa44e80d..697e3e9b499 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -889,10 +889,21 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation { modifiers |= ControlKeyStates::EnhancedKey; } - const bool handled = _terminal->SendCharEvent(ch, scanCode, modifiers); + + const bool handled = TrySendChar(ch, scanCode, modifiers.Value()); + auto charSentArgs = winrt::make(ch, scanCode, modifiers.Value()); + _charSentHandlers(*this, charSentArgs); e.Handled(handled); } + // Method Description: + // - Sends character to terminal + bool TermControl::TrySendChar(const wchar_t character, const WORD scanCode, const DWORD modifiers) + { + ControlKeyStates keyStates{ modifiers }; + return _terminal->SendCharEvent(character, scanCode, keyStates); + } + // Method Description: // - Manually handles key events for certain keys that can't be passed to us // normally. Namely, the keys we're concerned with are F7 down and Alt up. @@ -1121,9 +1132,9 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation // - states: The Microsoft::Terminal::Core::ControlKeyStates representing the modifier key states. // - keyDown: If true, the key was pressed, otherwise the key was released. bool TermControl::TrySendKeyEvent(const WORD vkey, - const WORD scanCode, - const DWORD modifiers, - const bool keyDown) + const WORD scanCode, + const DWORD modifiers, + const bool keyDown) { // When there is a selection active, escape should clear it and NOT flow through // to the terminal. With any other keypress, it should clear the selection AND @@ -3384,5 +3395,6 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(TermControl, SetTaskbarProgress, _setTaskbarProgressHandlers, TerminalControl::TermControl, IInspectable); DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(TermControl, RaiseNotice, _raiseNoticeHandlers, TerminalControl::TermControl, TerminalControl::NoticeEventArgs); DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(TermControl, KeySent, _keySentHandlers, TerminalControl::TermControl, TerminalControl::KeySentEventArgs); + DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(TermControl, CharSent, _charSentHandlers, TerminalControl::TermControl, TerminalControl::CharSentEventArgs); // clang-format on } diff --git a/src/cascadia/TerminalControl/TermControl.h b/src/cascadia/TerminalControl/TermControl.h index 9b2aad3c69e..09f25c171ed 100644 --- a/src/cascadia/TerminalControl/TermControl.h +++ b/src/cascadia/TerminalControl/TermControl.h @@ -9,6 +9,7 @@ #include "OpenHyperlinkEventArgs.g.h" #include "NoticeEventArgs.g.h" #include "KeySentEventArgs.g.h" +#include "CharSentEventArgs.g.h" #include #include "../../renderer/base/Renderer.hpp" #include "../../renderer/dx/DxRenderer.hpp" @@ -99,27 +100,46 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation const hstring _message; }; - struct KeySentEventArgs : + struct KeySentEventArgs : public KeySentEventArgsT - { - public: - KeySentEventArgs(const WORD vkey, const WORD scanCode, const DWORD modifiers, const bool keyDown) : - _vkey(vkey), - _scanCode(scanCode), - _modifiers(modifiers), - _keyDown(keyDown) {} - - WORD VKey() { return _vkey; }; - WORD ScanCode() { return _scanCode; }; - DWORD Modifiers() { return _modifiers; }; - bool KeyDown() { return _keyDown; }; - - private: - const WORD _vkey; - const WORD _scanCode; - const DWORD _modifiers; - const bool _keyDown; - }; + { + public: + KeySentEventArgs(const WORD vkey, const WORD scanCode, const DWORD modifiers, const bool keyDown) : + _vkey(vkey), + _scanCode(scanCode), + _modifiers(modifiers), + _keyDown(keyDown) {} + + WORD VKey() { return _vkey; }; + WORD ScanCode() { return _scanCode; }; + DWORD Modifiers() { return _modifiers; }; + bool KeyDown() { return _keyDown; }; + + private: + const WORD _vkey; + const WORD _scanCode; + const DWORD _modifiers; + const bool _keyDown; + }; + + struct CharSentEventArgs : + public CharSentEventArgsT + { + public: + CharSentEventArgs(const wchar_t character, const WORD scanCode, const DWORD modifiers) : + _character(character), + _scanCode(scanCode), + _modifiers(modifiers) {} + + wchar_t Character() { return _character; }; + WORD ScanCode() { return _scanCode; }; + DWORD Modifiers() { return _modifiers; }; + + private: + const wchar_t _character; + const WORD _scanCode; + const DWORD _modifiers; + }; struct TermControl : TermControlT { @@ -193,6 +213,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation void ToggleReadOnly(); bool TrySendKeyEvent(const WORD vkey, const WORD scanCode, const DWORD modifiers, const bool keyDown); + bool TrySendChar(const wchar_t character, const WORD scanCode, const DWORD modifiers); // clang-format off // -------------------------------- WinRT Events --------------------------------- @@ -206,6 +227,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(SetTaskbarProgress, _setTaskbarProgressHandlers, TerminalControl::TermControl, IInspectable); DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(RaiseNotice, _raiseNoticeHandlers, TerminalControl::TermControl, TerminalControl::NoticeEventArgs); DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(KeySent, _keySentHandlers, TerminalControl::TermControl, TerminalControl::KeySentEventArgs); + DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(CharSent, _charSentHandlers, TerminalControl::TermControl, TerminalControl::CharSentEventArgs); TYPED_EVENT(WarningBell, IInspectable, IInspectable); TYPED_EVENT(ConnectionStateChanged, TerminalControl::TermControl, IInspectable); diff --git a/src/cascadia/TerminalControl/TermControl.idl b/src/cascadia/TerminalControl/TermControl.idl index dc7139a838a..e6d31266486 100644 --- a/src/cascadia/TerminalControl/TermControl.idl +++ b/src/cascadia/TerminalControl/TermControl.idl @@ -67,6 +67,13 @@ namespace Microsoft.Terminal.TerminalControl Boolean KeyDown { get; }; } + runtimeclass CharSentEventArgs + { + Char Character { get; }; + UInt16 ScanCode { get; }; + UInt32 Modifiers { get; }; + } + [default_interface] runtimeclass TermControl : Windows.UI.Xaml.Controls.UserControl, IDirectKeyListener, IMouseWheelListener { TermControl(Microsoft.Terminal.TerminalControl.IControlSettings settings, Microsoft.Terminal.TerminalConnection.ITerminalConnection connection); @@ -88,6 +95,7 @@ namespace Microsoft.Terminal.TerminalControl event Windows.Foundation.TypedEventHandler HidePointerCursor; event Windows.Foundation.TypedEventHandler RestorePointerCursor; event Windows.Foundation.TypedEventHandler KeySent; + event Windows.Foundation.TypedEventHandler CharSent; event Windows.Foundation.TypedEventHandler Initialized; // This is an event handler forwarder for the underlying connection. @@ -119,6 +127,7 @@ namespace Microsoft.Terminal.TerminalControl void ToggleShaderEffects(); void SendInput(String input); Boolean TrySendKeyEvent(UInt16 vkey, UInt16 scanCode, UInt32 modifiers, Boolean keyDown); + Boolean TrySendChar(Char character, UInt16 scanCode, UInt32 modifiers); void TaskbarProgressChanged(); UInt64 TaskbarState { get; }; From 32c98f5664fea595166e17dc58f1a5dc6418c237 Mon Sep 17 00:00:00 2001 From: khvitaly Date: Fri, 19 Feb 2021 20:57:01 +0200 Subject: [PATCH 3/5] Add ToggleInputBroadcast command --- .../TerminalApp/AppActionHandlers.cpp | 11 ++++++++++ src/cascadia/TerminalApp/CommandPalette.xaml | 7 +++++++ .../TerminalApp/ShortcutActionDispatch.cpp | 5 +++++ .../TerminalApp/ShortcutActionDispatch.h | 1 + .../TerminalApp/ShortcutActionDispatch.idl | 1 + .../TerminalApp/TabHeaderControl.xaml | 6 ++++++ src/cascadia/TerminalApp/TerminalPage.cpp | 1 + src/cascadia/TerminalApp/TerminalPage.h | 1 + src/cascadia/TerminalApp/TerminalTab.cpp | 21 +++++++++++++++---- src/cascadia/TerminalApp/TerminalTab.h | 2 ++ src/cascadia/TerminalApp/TerminalTabStatus.h | 1 + .../TerminalApp/TerminalTabStatus.idl | 1 + .../TerminalSettingsModel/ActionAndArgs.cpp | 3 +++ .../TerminalSettingsModel/KeyMapping.idl | 3 ++- .../Resources/en-US/Resources.resw | 3 +++ .../TerminalSettingsModel/defaults.json | 1 + 16 files changed, 63 insertions(+), 5 deletions(-) diff --git a/src/cascadia/TerminalApp/AppActionHandlers.cpp b/src/cascadia/TerminalApp/AppActionHandlers.cpp index 227f7285f90..1afec7f8bd8 100644 --- a/src/cascadia/TerminalApp/AppActionHandlers.cpp +++ b/src/cascadia/TerminalApp/AppActionHandlers.cpp @@ -165,6 +165,17 @@ namespace winrt::TerminalApp::implementation args.Handled(true); } + void TerminalPage::_HandleToggleInputBroadcast(const IInspectable& /*sender*/, + const ActionEventArgs& args) + { + if (const auto activeTab{ _GetFocusedTabImpl() }) + { + activeTab->ToggleInputBroadcast(); + } + + args.Handled(true); + } + void TerminalPage::_HandleScrollUpPage(const IInspectable& /*sender*/, const ActionEventArgs& args) { diff --git a/src/cascadia/TerminalApp/CommandPalette.xaml b/src/cascadia/TerminalApp/CommandPalette.xaml index 43f4c0a5a88..42dffff727a 100644 --- a/src/cascadia/TerminalApp/CommandPalette.xaml +++ b/src/cascadia/TerminalApp/CommandPalette.xaml @@ -179,6 +179,13 @@ the MIT License. See LICENSE in the project root for license information. --> FontSize="12" Margin="0,0,8,0"/> + + diff --git a/src/cascadia/TerminalApp/ShortcutActionDispatch.cpp b/src/cascadia/TerminalApp/ShortcutActionDispatch.cpp index 033f1a37813..89f17df1da8 100644 --- a/src/cascadia/TerminalApp/ShortcutActionDispatch.cpp +++ b/src/cascadia/TerminalApp/ShortcutActionDispatch.cpp @@ -266,6 +266,11 @@ namespace winrt::TerminalApp::implementation _TogglePaneReadOnlyHandlers(*this, eventArgs); break; } + case ShortcutAction::ToggleInputBroadcast: + { + _ToggleInputBroadcastHandlers(*this, eventArgs); + break; + } default: return false; } diff --git a/src/cascadia/TerminalApp/ShortcutActionDispatch.h b/src/cascadia/TerminalApp/ShortcutActionDispatch.h index 0f2488e40ce..46479b9b90f 100644 --- a/src/cascadia/TerminalApp/ShortcutActionDispatch.h +++ b/src/cascadia/TerminalApp/ShortcutActionDispatch.h @@ -67,6 +67,7 @@ namespace winrt::TerminalApp::implementation TYPED_EVENT(BreakIntoDebugger, TerminalApp::ShortcutActionDispatch, Microsoft::Terminal::Settings::Model::ActionEventArgs); TYPED_EVENT(FindMatch, TerminalApp::ShortcutActionDispatch, Microsoft::Terminal::Settings::Model::ActionEventArgs); TYPED_EVENT(TogglePaneReadOnly, TerminalApp::ShortcutActionDispatch, Microsoft::Terminal::Settings::Model::ActionEventArgs); + TYPED_EVENT(ToggleInputBroadcast, TerminalApp::ShortcutActionDispatch, Microsoft::Terminal::Settings::Model::ActionEventArgs); // clang-format on private: diff --git a/src/cascadia/TerminalApp/ShortcutActionDispatch.idl b/src/cascadia/TerminalApp/ShortcutActionDispatch.idl index 906de95498d..9356564837b 100644 --- a/src/cascadia/TerminalApp/ShortcutActionDispatch.idl +++ b/src/cascadia/TerminalApp/ShortcutActionDispatch.idl @@ -53,5 +53,6 @@ namespace TerminalApp event Windows.Foundation.TypedEventHandler BreakIntoDebugger; event Windows.Foundation.TypedEventHandler FindMatch; event Windows.Foundation.TypedEventHandler TogglePaneReadOnly; + event Windows.Foundation.TypedEventHandler ToggleInputBroadcast; } } diff --git a/src/cascadia/TerminalApp/TabHeaderControl.xaml b/src/cascadia/TerminalApp/TabHeaderControl.xaml index 8b9741b07ab..ddf9f02aa7c 100644 --- a/src/cascadia/TerminalApp/TabHeaderControl.xaml +++ b/src/cascadia/TerminalApp/TabHeaderControl.xaml @@ -61,6 +61,12 @@ the MIT License. See LICENSE in the project root for license information. --> Glyph="" FontSize="12" Margin="0,0,8,0"/> + diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index b96a0e7cc09..f8e683c54cd 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -1133,6 +1133,7 @@ namespace winrt::TerminalApp::implementation _actionDispatch->BreakIntoDebugger({ this, &TerminalPage::_HandleBreakIntoDebugger }); _actionDispatch->FindMatch({ this, &TerminalPage::_HandleFindMatch }); _actionDispatch->TogglePaneReadOnly({ this, &TerminalPage::_HandleTogglePaneReadOnly }); + _actionDispatch->ToggleInputBroadcast({ this, &TerminalPage::_HandleToggleInputBroadcast }); } // Method Description: diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h index 67ca1841d60..3710cb0b0e0 100644 --- a/src/cascadia/TerminalApp/TerminalPage.h +++ b/src/cascadia/TerminalApp/TerminalPage.h @@ -317,6 +317,7 @@ namespace winrt::TerminalApp::implementation void _HandleBreakIntoDebugger(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::ActionEventArgs& args); void _HandleFindMatch(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::ActionEventArgs& args); void _HandleTogglePaneReadOnly(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::ActionEventArgs& args); + void _HandleToggleInputBroadcast(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::ActionEventArgs& args); // Make sure to hook new actions up in _RegisterActionCallbacks! #pragma endregion diff --git a/src/cascadia/TerminalApp/TerminalTab.cpp b/src/cascadia/TerminalApp/TerminalTab.cpp index 9deebeafff1..f2ad9a6b8f3 100644 --- a/src/cascadia/TerminalApp/TerminalTab.cpp +++ b/src/cascadia/TerminalApp/TerminalTab.cpp @@ -631,9 +631,12 @@ namespace winrt::TerminalApp::implementation control.KeySent([weakThis](auto&& sender, auto&& e) { if (const auto tab{ weakThis.get() }) { - if (const auto termControl{ sender.try_as() }) + if (tab->_tabStatus.IsInputBroadcastActive()) { - tab->_rootPane->BroadcastKey(termControl, e.VKey(), e.ScanCode(), e.Modifiers(), e.KeyDown()); + if (const auto termControl{ sender.try_as() }) + { + tab->_rootPane->BroadcastKey(termControl, e.VKey(), e.ScanCode(), e.Modifiers(), e.KeyDown()); + } } } }); @@ -641,9 +644,12 @@ namespace winrt::TerminalApp::implementation control.CharSent([weakThis](auto&& sender, auto&& e) { if (const auto tab{ weakThis.get() }) { - if (const auto termControl{ sender.try_as() }) + if (tab->_tabStatus.IsInputBroadcastActive()) { - tab->_rootPane->BroadcastChar(termControl, e.Character(), e.ScanCode(), e.Modifiers()); + if (const auto termControl{ sender.try_as() }) + { + tab->_rootPane->BroadcastChar(termControl, e.Character(), e.ScanCode(), e.Modifiers()); + } } } }); @@ -1173,6 +1179,13 @@ namespace winrt::TerminalApp::implementation } } + // Method Description: + // - Toggle read-only mode on the active pane + void TerminalTab::ToggleInputBroadcast() + { + _tabStatus.IsInputBroadcastActive(!_tabStatus.IsInputBroadcastActive()); + } + // Method Description: // - Calculates if the tab is read-only. // The tab is considered read-only if one of the panes is read-only. diff --git a/src/cascadia/TerminalApp/TerminalTab.h b/src/cascadia/TerminalApp/TerminalTab.h index f8fb560ee60..5e9f65d96ec 100644 --- a/src/cascadia/TerminalApp/TerminalTab.h +++ b/src/cascadia/TerminalApp/TerminalTab.h @@ -78,6 +78,8 @@ namespace winrt::TerminalApp::implementation int GetLeafPaneCount() const noexcept; void TogglePaneReadOnly(); + void ToggleInputBroadcast(); + std::shared_ptr GetActivePane() const; winrt::TerminalApp::TerminalTabStatus TabStatus() diff --git a/src/cascadia/TerminalApp/TerminalTabStatus.h b/src/cascadia/TerminalApp/TerminalTabStatus.h index 64b75cda5d5..0c5dd96e053 100644 --- a/src/cascadia/TerminalApp/TerminalTabStatus.h +++ b/src/cascadia/TerminalApp/TerminalTabStatus.h @@ -18,6 +18,7 @@ namespace winrt::TerminalApp::implementation OBSERVABLE_GETSET_PROPERTY(bool, IsProgressRingIndeterminate, _PropertyChangedHandlers); OBSERVABLE_GETSET_PROPERTY(bool, BellIndicator, _PropertyChangedHandlers); OBSERVABLE_GETSET_PROPERTY(bool, IsReadOnlyActive, _PropertyChangedHandlers); + OBSERVABLE_GETSET_PROPERTY(bool, IsInputBroadcastActive, _PropertyChangedHandlers); OBSERVABLE_GETSET_PROPERTY(uint32_t, ProgressValue, _PropertyChangedHandlers); }; } diff --git a/src/cascadia/TerminalApp/TerminalTabStatus.idl b/src/cascadia/TerminalApp/TerminalTabStatus.idl index 11d659f745f..57f4e05fa1a 100644 --- a/src/cascadia/TerminalApp/TerminalTabStatus.idl +++ b/src/cascadia/TerminalApp/TerminalTabStatus.idl @@ -13,5 +13,6 @@ namespace TerminalApp Boolean BellIndicator { get; set; }; UInt32 ProgressValue { get; set; }; Boolean IsReadOnlyActive { get; set; }; + Boolean IsInputBroadcastActive { get; set; }; } } diff --git a/src/cascadia/TerminalSettingsModel/ActionAndArgs.cpp b/src/cascadia/TerminalSettingsModel/ActionAndArgs.cpp index 501c43db175..2d19b6542b4 100644 --- a/src/cascadia/TerminalSettingsModel/ActionAndArgs.cpp +++ b/src/cascadia/TerminalSettingsModel/ActionAndArgs.cpp @@ -53,6 +53,7 @@ static constexpr std::string_view MoveTabKey{ "moveTab" }; static constexpr std::string_view BreakIntoDebuggerKey{ "breakIntoDebugger" }; static constexpr std::string_view FindMatchKey{ "findMatch" }; static constexpr std::string_view TogglePaneReadOnlyKey{ "toggleReadOnlyMode" }; +static constexpr std::string_view ToggleInputBroadcastKey{ "toggleInputBroadcast" }; static constexpr std::string_view ActionKey{ "action" }; @@ -119,6 +120,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation { UnboundKey, ShortcutAction::Invalid }, { FindMatchKey, ShortcutAction::FindMatch }, { TogglePaneReadOnlyKey, ShortcutAction::TogglePaneReadOnly }, + { ToggleInputBroadcastKey, ShortcutAction::ToggleInputBroadcast }, }; using ParseResult = std::tuple>; @@ -321,6 +323,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation { ShortcutAction::BreakIntoDebugger, RS_(L"BreakIntoDebuggerCommandKey") }, { ShortcutAction::FindMatch, L"" }, // Intentionally omitted, must be generated by GenerateName { ShortcutAction::TogglePaneReadOnly, RS_(L"TogglePaneReadOnlyCommandKey") }, + { ShortcutAction::ToggleInputBroadcast, RS_(L"ToggleInputBroadcastCommandKey") }, }; }(); diff --git a/src/cascadia/TerminalSettingsModel/KeyMapping.idl b/src/cascadia/TerminalSettingsModel/KeyMapping.idl index 7df3dbb489f..d59bc1f0e84 100644 --- a/src/cascadia/TerminalSettingsModel/KeyMapping.idl +++ b/src/cascadia/TerminalSettingsModel/KeyMapping.idl @@ -54,7 +54,8 @@ namespace Microsoft.Terminal.Settings.Model MoveTab, BreakIntoDebugger, FindMatch, - TogglePaneReadOnly + TogglePaneReadOnly, + ToggleInputBroadcast }; [default_interface] runtimeclass ActionAndArgs { diff --git a/src/cascadia/TerminalSettingsModel/Resources/en-US/Resources.resw b/src/cascadia/TerminalSettingsModel/Resources/en-US/Resources.resw index f8a588553f5..14dc4353c3d 100644 --- a/src/cascadia/TerminalSettingsModel/Resources/en-US/Resources.resw +++ b/src/cascadia/TerminalSettingsModel/Resources/en-US/Resources.resw @@ -366,6 +366,9 @@ Toggle pane read-only mode + + Toggle input broadcast + Toggle terminal visual effects diff --git a/src/cascadia/TerminalSettingsModel/defaults.json b/src/cascadia/TerminalSettingsModel/defaults.json index b3b4888ec06..89279b761d5 100644 --- a/src/cascadia/TerminalSettingsModel/defaults.json +++ b/src/cascadia/TerminalSettingsModel/defaults.json @@ -340,6 +340,7 @@ { "command": { "action": "moveFocus", "direction": "previous" }, "keys": "ctrl+alt+left" }, { "command": "togglePaneZoom" }, { "command": "toggleReadOnlyMode" }, + { "command": "toggleInputBroadcast" }, // Clipboard Integration { "command": { "action": "copy", "singleLine": false }, "keys": "ctrl+shift+c" }, From 38ca58705a6df4149b7447ba17f42919add81d10 Mon Sep 17 00:00:00 2001 From: khvitaly Date: Sun, 21 Feb 2021 09:28:10 +0200 Subject: [PATCH 4/5] Avoid broadcasting to read-only panes --- src/cascadia/TerminalApp/Pane.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cascadia/TerminalApp/Pane.cpp b/src/cascadia/TerminalApp/Pane.cpp index c67232f8883..352b730d207 100644 --- a/src/cascadia/TerminalApp/Pane.cpp +++ b/src/cascadia/TerminalApp/Pane.cpp @@ -2105,7 +2105,7 @@ void Pane::BroadcastKey(const winrt::Microsoft::Terminal::TerminalControl::TermC { if (_IsLeaf()) { - if (_control != sourceControl) + if (_control != sourceControl && !_control.ReadOnly()) { _control.TrySendKeyEvent(vkey, scanCode, modifiers, keyDown); } @@ -2121,7 +2121,7 @@ void Pane::BroadcastChar(const winrt::Microsoft::Terminal::TerminalControl::Term { if (_IsLeaf()) { - if (_control != sourceControl) + if (_control != sourceControl && !_control.ReadOnly()) { _control.TrySendChar(character, scanCode, modifiers); } From 4612901d94bda1fb8e4df116bf2ed442cf858234 Mon Sep 17 00:00:00 2001 From: khvitaly Date: Thu, 25 Feb 2021 21:50:20 +0200 Subject: [PATCH 5/5] Introduce color-coding of read-only and broad-casting panes --- src/cascadia/TerminalApp/App.xaml | 4 ++ src/cascadia/TerminalApp/Pane.cpp | 80 +++++++++++++++++++++++- src/cascadia/TerminalApp/Pane.h | 8 +++ src/cascadia/TerminalApp/TerminalTab.cpp | 1 + 4 files changed, 91 insertions(+), 2 deletions(-) diff --git a/src/cascadia/TerminalApp/App.xaml b/src/cascadia/TerminalApp/App.xaml index a12620b8db8..b6a46ce3a97 100644 --- a/src/cascadia/TerminalApp/App.xaml +++ b/src/cascadia/TerminalApp/App.xaml @@ -42,11 +42,15 @@ the MIT License. See LICENSE in the project root for license information. --> + + + + diff --git a/src/cascadia/TerminalApp/Pane.cpp b/src/cascadia/TerminalApp/Pane.cpp index 352b730d207..9340c8c3e0b 100644 --- a/src/cascadia/TerminalApp/Pane.cpp +++ b/src/cascadia/TerminalApp/Pane.cpp @@ -33,6 +33,8 @@ static const Duration AnimationDuration = DurationHelper::FromTimeSpan(winrt::Wi winrt::Windows::UI::Xaml::Media::SolidColorBrush Pane::s_focusedBorderBrush = { nullptr }; winrt::Windows::UI::Xaml::Media::SolidColorBrush Pane::s_unfocusedBorderBrush = { nullptr }; +winrt::Windows::UI::Xaml::Media::SolidColorBrush Pane::s_readOnlyBorderBrush = { nullptr }; +winrt::Windows::UI::Xaml::Media::SolidColorBrush Pane::s_broadcastBorderBrush = { nullptr }; Pane::Pane(const GUID& profile, const TermControl& control, const bool lastFocused) : _control{ control }, @@ -44,11 +46,12 @@ Pane::Pane(const GUID& profile, const TermControl& control, const bool lastFocus _connectionStateChangedToken = _control.ConnectionStateChanged({ this, &Pane::_ControlConnectionStateChangedHandler }); _warningBellToken = _control.WarningBell({ this, &Pane::_ControlWarningBellHandler }); + _readOnlyChangedToken = _control.ReadOnlyChanged({ this, &Pane::_ControlReadOnlyChangedHandler }); // On the first Pane's creation, lookup resources we'll use to theme the // Pane, including the brushed to use for the focused/unfocused border // color. - if (s_focusedBorderBrush == nullptr || s_unfocusedBorderBrush == nullptr) + if (s_focusedBorderBrush == nullptr || s_unfocusedBorderBrush == nullptr || s_readOnlyBorderBrush == nullptr || s_broadcastBorderBrush == nullptr) { _SetupResources(); } @@ -586,7 +589,7 @@ bool Pane::_HasFocusedChild() const noexcept // - void Pane::UpdateVisuals() { - _border.BorderBrush(_lastActive ? s_focusedBorderBrush : s_unfocusedBorderBrush); + _border.BorderBrush(_ComputeBorderColor()); } // Method Description: @@ -698,6 +701,7 @@ void Pane::_CloseChild(const bool closeFirst) // Add our new event handler before revoking the old one. _connectionStateChangedToken = _control.ConnectionStateChanged({ this, &Pane::_ControlConnectionStateChangedHandler }); _warningBellToken = _control.WarningBell({ this, &Pane::_ControlWarningBellHandler }); + _readOnlyChangedToken = _control.ReadOnlyChanged({ this, &Pane::_ControlReadOnlyChangedHandler }); // Revoke the old event handlers. Remove both the handlers for the panes // themselves closing, and remove their handlers for their controls @@ -709,6 +713,8 @@ void Pane::_CloseChild(const bool closeFirst) remainingChild->_control.ConnectionStateChanged(remainingChild->_connectionStateChangedToken); closedChild->_control.WarningBell(closedChild->_warningBellToken); remainingChild->_control.WarningBell(remainingChild->_warningBellToken); + closedChild->_control.ReadOnlyChanged(closedChild->_readOnlyChangedToken); + remainingChild->_control.ReadOnlyChanged(remainingChild->_readOnlyChangedToken); // If either of our children was focused, we want to take that focus from // them. @@ -1440,6 +1446,8 @@ std::pair, std::shared_ptr> Pane::_Split(SplitState _connectionStateChangedToken.value = 0; _control.WarningBell(_warningBellToken); _warningBellToken.value = 0; + _control.ReadOnlyChanged(_readOnlyChangedToken); + _readOnlyChangedToken.value = 0; // Remove our old GotFocus handler from the control. We don't what the // control telling us that it's now focused, we want it telling its new @@ -2022,6 +2030,34 @@ void Pane::_SetupResources() // will eat focus. s_unfocusedBorderBrush = SolidColorBrush{ Colors::Black() }; } + + const auto readOnlyColorKey = winrt::box_value(L"ReadOnlyPaneBorderColor"); + if (res.HasKey(readOnlyColorKey)) + { + winrt::Windows::Foundation::IInspectable obj = res.Lookup(readOnlyColorKey); + s_readOnlyBorderBrush = obj.try_as(); + } + else + { + // DON'T use Transparent here - if it's "Transparent", then it won't + // be able to hittest for clicks, and then clicking on the border + // will eat focus. + s_readOnlyBorderBrush = SolidColorBrush{ Colors::Black() }; + } + + const auto broadcastColorKey = winrt::box_value(L"BroadcastPaneBorderColor"); + if (res.HasKey(broadcastColorKey)) + { + winrt::Windows::Foundation::IInspectable obj = res.Lookup(broadcastColorKey); + s_broadcastBorderBrush = obj.try_as(); + } + else + { + // DON'T use Transparent here - if it's "Transparent", then it won't + // be able to hittest for clicks, and then clicking on the border + // will eat focus. + s_broadcastBorderBrush = SolidColorBrush{ Colors::Black() }; + } } int Pane::GetLeafPaneCount() const noexcept @@ -2101,6 +2137,21 @@ bool Pane::ContainsReadOnly() const return _IsLeaf() ? _control.ReadOnly() : (_firstChild->ContainsReadOnly() || _secondChild->ContainsReadOnly()); } +void Pane::EnableBroadcast(bool enabled) +{ + if (_IsLeaf()) + { + _broadcastEnabled = enabled; + UpdateVisuals(); + } + else + { + _firstChild->EnableBroadcast(enabled); + _secondChild->EnableBroadcast(enabled); + } +} + + void Pane::BroadcastKey(const winrt::Microsoft::Terminal::TerminalControl::TermControl& sourceControl, const WORD vkey, const WORD scanCode, const DWORD modifiers, const bool keyDown) { if (_IsLeaf()) @@ -2133,6 +2184,31 @@ void Pane::BroadcastChar(const winrt::Microsoft::Terminal::TerminalControl::Term } } +void Pane::_ControlReadOnlyChangedHandler(const winrt::Windows::Foundation::IInspectable& /*sender*/, const winrt::Windows::Foundation::IInspectable& /*e*/) +{ + UpdateVisuals(); +} + +winrt::Windows::UI::Xaml::Media::SolidColorBrush Pane::_ComputeBorderColor() +{ + if (_lastActive) + { + return s_focusedBorderBrush; + } + + if (_control && _control.ReadOnly()) + { + return s_readOnlyBorderBrush; + } + + if (_broadcastEnabled) + { + return s_broadcastBorderBrush; + } + + return s_unfocusedBorderBrush; +} + DEFINE_EVENT(Pane, GotFocus, _GotFocusHandlers, winrt::delegate>); DEFINE_EVENT(Pane, LostFocus, _LostFocusHandlers, winrt::delegate>); DEFINE_EVENT(Pane, PaneRaiseBell, _PaneRaiseBellHandlers, winrt::Windows::Foundation::EventHandler); diff --git a/src/cascadia/TerminalApp/Pane.h b/src/cascadia/TerminalApp/Pane.h index 8ec1362da81..758412cd47c 100644 --- a/src/cascadia/TerminalApp/Pane.h +++ b/src/cascadia/TerminalApp/Pane.h @@ -83,6 +83,7 @@ class Pane : public std::enable_shared_from_this bool ContainsReadOnly() const; + void EnableBroadcast(bool enabled); void BroadcastKey(const winrt::Microsoft::Terminal::TerminalControl::TermControl& sourceControl, const WORD vkey, const WORD scanCode, const DWORD modifiers, const bool keyDown); void BroadcastChar(const winrt::Microsoft::Terminal::TerminalControl::TermControl& sourceControl, const wchar_t vkey, const WORD scanCode, const DWORD modifiers); @@ -101,6 +102,8 @@ class Pane : public std::enable_shared_from_this winrt::Microsoft::Terminal::TerminalControl::TermControl _control{ nullptr }; static winrt::Windows::UI::Xaml::Media::SolidColorBrush s_focusedBorderBrush; static winrt::Windows::UI::Xaml::Media::SolidColorBrush s_unfocusedBorderBrush; + static winrt::Windows::UI::Xaml::Media::SolidColorBrush s_readOnlyBorderBrush; + static winrt::Windows::UI::Xaml::Media::SolidColorBrush s_broadcastBorderBrush; std::shared_ptr _firstChild{ nullptr }; std::shared_ptr _secondChild{ nullptr }; @@ -115,6 +118,7 @@ class Pane : public std::enable_shared_from_this winrt::event_token _firstClosedToken{ 0 }; winrt::event_token _secondClosedToken{ 0 }; winrt::event_token _warningBellToken{ 0 }; + winrt::event_token _readOnlyChangedToken{ 0 }; winrt::Windows::UI::Xaml::UIElement::GotFocus_revoker _gotFocusRevoker; winrt::Windows::UI::Xaml::UIElement::LostFocus_revoker _lostFocusRevoker; @@ -126,6 +130,7 @@ class Pane : public std::enable_shared_from_this std::atomic _isClosing{ false }; bool _zoomed{ false }; + bool _broadcastEnabled{ false }; bool _IsLeaf() const noexcept; bool _HasFocusedChild() const noexcept; @@ -140,6 +145,7 @@ class Pane : public std::enable_shared_from_this void _ApplySplitDefinitions(); void _SetupEntranceAnimation(); void _UpdateBorders(); + winrt::Windows::UI::Xaml::Media::SolidColorBrush _ComputeBorderColor(); bool _Resize(const winrt::Microsoft::Terminal::Settings::Model::ResizeDirection& direction); bool _NavigateFocus(const winrt::Microsoft::Terminal::Settings::Model::FocusDirection& direction); @@ -156,6 +162,8 @@ class Pane : public std::enable_shared_from_this void _ControlLostFocusHandler(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e); + void _ControlReadOnlyChangedHandler(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& e); + std::pair _CalcChildrenSizes(const float fullSize) const; SnapChildrenSizeResult _CalcSnappedChildrenSizes(const bool widthOrHeight, const float fullSize) const; SnapSizeResult _CalcSnappedDimension(const bool widthOrHeight, const float dimension) const; diff --git a/src/cascadia/TerminalApp/TerminalTab.cpp b/src/cascadia/TerminalApp/TerminalTab.cpp index f2ad9a6b8f3..5b9eff2dffc 100644 --- a/src/cascadia/TerminalApp/TerminalTab.cpp +++ b/src/cascadia/TerminalApp/TerminalTab.cpp @@ -1184,6 +1184,7 @@ namespace winrt::TerminalApp::implementation void TerminalTab::ToggleInputBroadcast() { _tabStatus.IsInputBroadcastActive(!_tabStatus.IsInputBroadcastActive()); + _rootPane->EnableBroadcast(_tabStatus.IsInputBroadcastActive()); } // Method Description: