From e4478eec6afa26b0f9d401e80195b527471a1005 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Thu, 29 Apr 2021 12:03:30 -0500 Subject: [PATCH 01/30] Only access ControlInteractivity through the projection --- .../TerminalControl/ControlInteractivity.cpp | 110 ++++++--- .../TerminalControl/ControlInteractivity.h | 30 ++- .../TerminalControl/ControlInteractivity.idl | 55 +++++ src/cascadia/TerminalControl/TermControl.cpp | 82 +++---- src/cascadia/TerminalControl/TermControl.h | 9 +- .../TerminalCore/ControlKeyStates.hpp | 14 ++ src/cascadia/TerminalCore/ICoreAppearance.idl | 14 ++ .../ControlInteractivityTests.cpp | 227 ++++++++++++++++++ src/cascadia/inc/cppwinrt_utils.h | 6 + src/inc/til/point.h | 15 ++ 10 files changed, 465 insertions(+), 97 deletions(-) diff --git a/src/cascadia/TerminalControl/ControlInteractivity.cpp b/src/cascadia/TerminalControl/ControlInteractivity.cpp index ecee7cc0e56..76994f96935 100644 --- a/src/cascadia/TerminalControl/ControlInteractivity.cpp +++ b/src/cascadia/TerminalControl/ControlInteractivity.cpp @@ -27,6 +27,13 @@ static constexpr unsigned int MAX_CLICK_COUNT = 3; namespace winrt::Microsoft::Terminal::Control::implementation { + TerminalInput::MouseButtonState toInternalMouseState(const Control::MouseButtonState& state) + { + return TerminalInput::MouseButtonState{ + state.IsLeftButtonDown, state.IsMiddleButtonDown, state.IsRightButtonDown + }; + } + ControlInteractivity::ControlInteractivity(IControlSettings settings, TerminalConnection::ITerminalConnection connection) : _touchAnchor{ std::nullopt }, @@ -35,6 +42,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation _selectionNeedsToBeCopied{ false } { _core = winrt::make_self(settings, connection); + + // _core->ScrollPositionChanged({ this, &ControlInteractivity::_coreScrollPositionChanged }); } void ControlInteractivity::UpdateSettings() @@ -50,9 +59,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation _multiClickTimer = GetDoubleClickTime() * 1000; } - winrt::com_ptr ControlInteractivity::GetCore() + Control::ControlCore ControlInteractivity::GetCore() { - return _core; + return *_core; } // Method Description: @@ -156,7 +165,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation _core->PasteText(winrt::hstring{ wstr }); } - void ControlInteractivity::PointerPressed(TerminalInput::MouseButtonState buttonState, + void ControlInteractivity::PointerPressed(Control::MouseButtonState buttonState, const unsigned int pointerUpdateKind, const uint64_t timestamp, const ::Microsoft::Terminal::Core::ControlKeyStates modifiers, @@ -170,7 +179,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation // GH#9396: we prioritize hyper-link over VT mouse events auto hyperlink = _core->GetHyperlink(terminalPosition); - if (buttonState.isLeftButtonDown && + if (buttonState.IsLeftButtonDown && ctrlEnabled && !hyperlink.empty()) { const auto clickCount = _numberOfClicks(pixelPosition, timestamp); @@ -182,9 +191,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation } else if (_canSendVTMouseInput(modifiers)) { - _core->SendMouseEvent(terminalPosition, pointerUpdateKind, modifiers, 0, buttonState); + _core->SendMouseEvent(terminalPosition, pointerUpdateKind, modifiers, 0, toInternalMouseState(buttonState)); } - else if (buttonState.isLeftButtonDown) + else if (buttonState.IsLeftButtonDown) { const auto clickCount = _numberOfClicks(pixelPosition, timestamp); // This formula enables the number of clicks to cycle properly @@ -197,7 +206,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation if (multiClickMapper == 1) { _singleClickTouchdownPos = pixelPosition; - _singleClickTouchdownTerminalPos = terminalPosition; if (!_core->HasSelection()) { @@ -220,7 +228,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation _singleClickTouchdownPos = std::nullopt; } } - else if (buttonState.isRightButtonDown) + else if (buttonState.IsRightButtonDown) { // CopyOnSelect right click always pastes if (_core->CopyOnSelect() || !_core->HasSelection()) @@ -239,7 +247,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation _touchAnchor = contactPoint; } - void ControlInteractivity::PointerMoved(TerminalInput::MouseButtonState buttonState, + void ControlInteractivity::PointerMoved(Control::MouseButtonState buttonState, const unsigned int pointerUpdateKind, const ::Microsoft::Terminal::Core::ControlKeyStates modifiers, const bool focused, @@ -250,9 +258,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation // Short-circuit isReadOnly check to avoid warning dialog if (focused && !_core->IsInReadOnlyMode() && _canSendVTMouseInput(modifiers)) { - _core->SendMouseEvent(terminalPosition, pointerUpdateKind, modifiers, 0, buttonState); + _core->SendMouseEvent(terminalPosition, pointerUpdateKind, modifiers, 0, toInternalMouseState(buttonState)); } - else if (focused && buttonState.isLeftButtonDown) + else if (focused && buttonState.IsLeftButtonDown) { if (_singleClickTouchdownPos) { @@ -266,10 +274,14 @@ namespace winrt::Microsoft::Terminal::Control::implementation const auto fontSizeInDips{ _core->FontSizeInDips() }; if (distance >= (std::min(fontSizeInDips.width(), fontSizeInDips.height()) / 4.f)) { - _core->SetSelectionAnchor(terminalPosition); + // GH#9955.c: Make sure to use the terminal location of the + // _touchdown_ point here. We want to start the selection + // from where the user initially clicked, not where they are + // now. + _core->SetSelectionAnchor(_getTerminalPosition(touchdownPoint)); + // stop tracking the touchdown point _singleClickTouchdownPos = std::nullopt; - _singleClickTouchdownTerminalPos = std::nullopt; } } @@ -303,12 +315,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation // panning down) const float numRows = -1.0f * (dy / fontSizeInDips.height()); - const auto currentOffset = ::base::ClampedNumeric(_core->ScrollOffset()); - const auto newValue = numRows + currentOffset; + const double currentOffset = ::base::ClampedNumeric(_core->ScrollOffset()); + const double newValue = numRows + currentOffset; // Update the Core's viewport position, and raise a // ScrollPositionChanged event to update the scrollbar - _updateScrollbar(newValue); + UpdateScrollbar(newValue); // Use this point as our new scroll anchor. _touchAnchor = newTouchPoint; @@ -316,7 +328,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation } } - void ControlInteractivity::PointerReleased(TerminalInput::MouseButtonState buttonState, + void ControlInteractivity::PointerReleased(Control::MouseButtonState buttonState, const unsigned int pointerUpdateKind, const ::Microsoft::Terminal::Core::ControlKeyStates modifiers, const til::point pixelPosition) @@ -325,7 +337,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation // Short-circuit isReadOnly check to avoid warning dialog if (!_core->IsInReadOnlyMode() && _canSendVTMouseInput(modifiers)) { - _core->SendMouseEvent(terminalPosition, pointerUpdateKind, modifiers, 0, buttonState); + _core->SendMouseEvent(terminalPosition, pointerUpdateKind, modifiers, 0, toInternalMouseState(buttonState)); return; } @@ -341,7 +353,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation } _singleClickTouchdownPos = std::nullopt; - _singleClickTouchdownTerminalPos = std::nullopt; } void ControlInteractivity::TouchReleased() @@ -364,7 +375,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation bool ControlInteractivity::MouseWheel(const ::Microsoft::Terminal::Core::ControlKeyStates modifiers, const int32_t delta, const til::point pixelPosition, - const TerminalInput::MouseButtonState state) + const Control::MouseButtonState buttonState) { const til::point terminalPosition = _getTerminalPosition(pixelPosition); @@ -380,7 +391,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation WM_MOUSEWHEEL, modifiers, ::base::saturated_cast(delta), - state); + toInternalMouseState(buttonState)); } const auto ctrlPressed = modifiers.IsCtrlPressed(); @@ -396,7 +407,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation } else { - _mouseScrollHandler(delta, terminalPosition, state.isLeftButtonDown); + _mouseScrollHandler(delta, pixelPosition, buttonState.IsLeftButtonDown); } return false; } @@ -428,35 +439,50 @@ namespace winrt::Microsoft::Terminal::Control::implementation // - Scroll the visible viewport in response to a mouse wheel event. // Arguments: // - mouseDelta: the mouse wheel delta that triggered this event. - // - point: the location of the mouse during this event + // - pixelPosition: the location of the mouse during this event // - isLeftButtonPressed: true iff the left mouse button was pressed during this event. void ControlInteractivity::_mouseScrollHandler(const double mouseDelta, - const til::point terminalPosition, + const til::point pixelPosition, const bool isLeftButtonPressed) { - const auto currentOffset = _core->ScrollOffset(); + // GH#9955.b: Start scrolling from our internal scrollbar position. This + // lets us accumulate fractional numbers of rows to scroll with each + // event. Especially for precision trackpads, we might be getting scroll + // deltas smaller than a single row, but we still want lots of those to + // accumulate. + // + // At the start, let's compare what we _think_ the scrollbar is, with + // what it should be. It's possible the core scrolled out from + // underneath us. We wouldn't know - we don't want the overhead of + // another ScrollPositionChanged handler. If the scrollbar should be + // somewhere other than where it is currently, then start from that row. + const int currentInternalRow = ::base::saturated_cast(::std::round(_internalScrollbarPosition)); + const int currentCoreRow = _core->ScrollOffset(); + const double currentOffset = currentInternalRow == currentCoreRow ? + _internalScrollbarPosition : + currentCoreRow; // negative = down, positive = up // However, for us, the signs are flipped. // With one of the precision mice, one click is always a multiple of 120 (WHEEL_DELTA), // but the "smooth scrolling" mode results in non-int values - const auto rowDelta = mouseDelta / (-1.0 * WHEEL_DELTA); + const double rowDelta = mouseDelta / (-1.0 * WHEEL_DELTA); // WHEEL_PAGESCROLL is a Win32 constant that represents the "scroll one page // at a time" setting. If we ignore it, we will scroll a truly absurd number // of rows. - const auto rowsToScroll{ _rowsToScroll == WHEEL_PAGESCROLL ? _core->ViewHeight() : _rowsToScroll }; + const double rowsToScroll{ _rowsToScroll == WHEEL_PAGESCROLL ? ::base::saturated_cast(_core->ViewHeight()) : _rowsToScroll }; double newValue = (rowsToScroll * rowDelta) + (currentOffset); // Update the Core's viewport position, and raise a // ScrollPositionChanged event to update the scrollbar - _updateScrollbar(::base::saturated_cast(newValue)); + UpdateScrollbar(newValue); if (isLeftButtonPressed) { // If user is mouse selecting and scrolls, they then point at new // character. Make sure selection reflects that immediately. - SetEndSelectionPoint(terminalPosition); + SetEndSelectionPoint(pixelPosition); } } @@ -476,15 +502,27 @@ namespace winrt::Microsoft::Terminal::Control::implementation // - newValue: The new top of the viewport // Return Value: // - - void ControlInteractivity::_updateScrollbar(const int newValue) + void ControlInteractivity::UpdateScrollbar(const double newValue) { - _core->UserScrollViewport(newValue); + // Set this as the new value of our internal scrollbar representation. + // We're doing this so we can accumulate fractional amounts of a row to + // scroll each time the mouse scrolls. + _internalScrollbarPosition = std::clamp(newValue, 0.0, _core->BufferHeight()); + + // If the new scrollbar position, rounded to an int, is at a different + // row, then actually update the scroll position in the core, and raise + // a ScrollPositionChanged to inform the control. + int viewTop = ::base::saturated_cast(::std::round(_internalScrollbarPosition)); + if (viewTop != _core->ScrollOffset()) + { + _core->UserScrollViewport(viewTop); - // _core->ScrollOffset() is now set to newValue - _ScrollPositionChangedHandlers(*this, - winrt::make(_core->ScrollOffset(), - _core->ViewHeight(), - _core->BufferHeight())); + // _core->ScrollOffset() is now set to newValue + _ScrollPositionChangedHandlers(*this, + winrt::make(_core->ScrollOffset(), + _core->ViewHeight(), + _core->BufferHeight())); + } } void ControlInteractivity::_hyperlinkHandler(const std::wstring_view uri) diff --git a/src/cascadia/TerminalControl/ControlInteractivity.h b/src/cascadia/TerminalControl/ControlInteractivity.h index cd099dff3a4..6c6693385d3 100644 --- a/src/cascadia/TerminalControl/ControlInteractivity.h +++ b/src/cascadia/TerminalControl/ControlInteractivity.h @@ -23,11 +23,6 @@ #include "ControlCore.h" -namespace Microsoft::Console::VirtualTerminal -{ - struct MouseButtonState; -} - namespace ControlUnitTests { class ControlCoreTests; @@ -45,17 +40,17 @@ namespace winrt::Microsoft::Terminal::Control::implementation void GainFocus(); void UpdateSettings(); void Initialize(); - winrt::com_ptr GetCore(); + Control::ControlCore GetCore(); #pragma region Input Methods - void PointerPressed(::Microsoft::Console::VirtualTerminal::TerminalInput::MouseButtonState buttonState, + void PointerPressed(Control::MouseButtonState buttonState, const unsigned int pointerUpdateKind, const uint64_t timestamp, const ::Microsoft::Terminal::Core::ControlKeyStates modifiers, const til::point pixelPosition); void TouchPressed(const til::point contactPoint); - void PointerMoved(::Microsoft::Console::VirtualTerminal::TerminalInput::MouseButtonState buttonState, + void PointerMoved(Control::MouseButtonState buttonState, const unsigned int pointerUpdateKind, const ::Microsoft::Terminal::Core::ControlKeyStates modifiers, const bool focused, @@ -63,7 +58,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation void TouchMoved(const til::point newTouchPoint, const bool focused); - void PointerReleased(::Microsoft::Console::VirtualTerminal::TerminalInput::MouseButtonState buttonState, + void PointerReleased(Control::MouseButtonState buttonState, const unsigned int pointerUpdateKind, const ::Microsoft::Terminal::Core::ControlKeyStates modifiers, const til::point pixelPosition); @@ -72,17 +67,26 @@ namespace winrt::Microsoft::Terminal::Control::implementation bool MouseWheel(const ::Microsoft::Terminal::Core::ControlKeyStates modifiers, const int32_t delta, const til::point pixelPosition, - const ::Microsoft::Console::VirtualTerminal::TerminalInput::MouseButtonState state); + const Control::MouseButtonState state); + + void UpdateScrollbar(const double newValue); + #pragma endregion bool CopySelectionToClipboard(bool singleLine, const Windows::Foundation::IReference& formats); void RequestPasteTextFromClipboard(); void SetEndSelectionPoint(const til::point pixelPosition); + // void SetEndSelectionPoint(const Core::Point pixelPosition); + + TYPED_EVENT(OpenHyperlink, IInspectable, Control::OpenHyperlinkEventArgs); + TYPED_EVENT(PasteFromClipboard, IInspectable, Control::PasteFromClipboardEventArgs); + TYPED_EVENT(ScrollPositionChanged, IInspectable, Control::ScrollPositionChangedArgs); private: winrt::com_ptr _core{ nullptr }; unsigned int _rowsToScroll; + double _internalScrollbarPosition{ 0.0 }; // If this is set, then we assume we are in the middle of panning the // viewport via touch input. @@ -97,7 +101,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation Timestamp _lastMouseClickTimestamp; std::optional _lastMouseClickPos; std::optional _singleClickTouchdownPos; - std::optional _singleClickTouchdownTerminalPos; std::optional _lastMouseClickPosNoSelection; // This field tracks whether the selection has changed meaningfully // since it was last copied. It's generally used to prevent copyOnSelect @@ -124,13 +127,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation bool _canSendVTMouseInput(const ::Microsoft::Terminal::Core::ControlKeyStates modifiers); void _sendPastedTextToConnection(std::wstring_view wstr); - void _updateScrollbar(const int newValue); til::point _getTerminalPosition(const til::point& pixelPosition); - TYPED_EVENT(OpenHyperlink, IInspectable, Control::OpenHyperlinkEventArgs); - TYPED_EVENT(PasteFromClipboard, IInspectable, Control::PasteFromClipboardEventArgs); - TYPED_EVENT(ScrollPositionChanged, IInspectable, Control::ScrollPositionChangedArgs); - friend class ControlUnitTests::ControlCoreTests; friend class ControlUnitTests::ControlInteractivityTests; }; diff --git a/src/cascadia/TerminalControl/ControlInteractivity.idl b/src/cascadia/TerminalControl/ControlInteractivity.idl index 3a9afaa1409..aedf612e4df 100644 --- a/src/cascadia/TerminalControl/ControlInteractivity.idl +++ b/src/cascadia/TerminalControl/ControlInteractivity.idl @@ -9,9 +9,64 @@ import "EventArgs.idl"; namespace Microsoft.Terminal.Control { + // This is a mirror of + // ::Microsoft::Console::VirtualTerminal::TerminalInput::MouseButtonState, + // but projectable. + struct MouseButtonState + { + Boolean IsLeftButtonDown; + Boolean IsMiddleButtonDown; + Boolean IsRightButtonDown; + }; + [default_interface] runtimeclass ControlInteractivity { ControlInteractivity(IControlSettings settings, Microsoft.Terminal.TerminalConnection.ITerminalConnection connection); + + ControlCore GetCore(); + void UpdateSettings(); + void Initialize(); + void GainFocus(); + + Boolean CopySelectionToClipboard(Boolean singleLine, Windows.Foundation.IReference formats); + void RequestPasteTextFromClipboard(); + void SetEndSelectionPoint(Microsoft.Terminal.Core.Point point); + + + void PointerPressed(MouseButtonState buttonState, + UInt32 pointerUpdateKind, + UInt64 timestamp, + Microsoft.Terminal.Core.ControlKeyStates modifiers, + Microsoft.Terminal.Core.Point pixelPosition); + void TouchPressed(Microsoft.Terminal.Core.Point contactPoint); + + void PointerMoved(MouseButtonState buttonState, + UInt32 pointerUpdateKind, + Microsoft.Terminal.Core.ControlKeyStates modifiers, + Boolean focused, + Microsoft.Terminal.Core.Point pixelPosition); + void TouchMoved(Microsoft.Terminal.Core.Point newTouchPoint, + Boolean focused); + + void PointerReleased(MouseButtonState buttonState, + UInt32 pointerUpdateKind, + Microsoft.Terminal.Core.ControlKeyStates modifiers, + Microsoft.Terminal.Core.Point pixelPosition); + void TouchReleased(); + + Boolean MouseWheel(Microsoft.Terminal.Core.ControlKeyStates modifiers, + Int32 delta, + Microsoft.Terminal.Core.Point pixelPosition, + MouseButtonState state); + + void UpdateScrollbar(Double newValue); + + + event Windows.Foundation.TypedEventHandler OpenHyperlink; + event Windows.Foundation.TypedEventHandler ScrollPositionChanged; + event Windows.Foundation.TypedEventHandler PasteFromClipboard; + + }; } diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index 5346d0507c9..1f1920b4a61 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -62,8 +62,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation { InitializeComponent(); - _interactivity = winrt::make_self(settings, connection); - _core = _interactivity->GetCore(); + _interactivity = winrt::make(settings, connection); + _core = _interactivity.GetCore(); // Use a manual revoker on the output event, so we can immediately stop // worrying about it on destruction. @@ -87,8 +87,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation _core->TransparencyChanged({ this, &TermControl::_coreTransparencyChanged }); _core->RaiseNotice({ this, &TermControl::_coreRaisedNotice }); _core->HoveredHyperlinkChanged({ this, &TermControl::_hoveredHyperlinkChanged }); - _interactivity->OpenHyperlink({ this, &TermControl::_HyperlinkHandler }); - _interactivity->ScrollPositionChanged({ this, &TermControl::_ScrollPositionChanged }); + _interactivity.OpenHyperlink({ this, &TermControl::_HyperlinkHandler }); + _interactivity.ScrollPositionChanged({ this, &TermControl::_ScrollPositionChanged }); // Initialize the terminal only once the swapchainpanel is loaded - that // way, we'll be able to query the real pixel size it got on layout @@ -420,7 +420,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation ScrollBar().Visibility(Visibility::Visible); } - _interactivity->UpdateSettings(); + _interactivity.UpdateSettings(); } // Method Description: @@ -664,7 +664,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation { return false; } - _interactivity->Initialize(); + _interactivity.Initialize(); _AttachDxgiSwapChainToXaml(_core->GetSwapChain()); @@ -1054,16 +1054,16 @@ namespace winrt::Microsoft::Terminal::Control::implementation { const auto contactRect = point.Properties().ContactRect(); auto anchor = til::point{ til::math::rounding, contactRect.X, contactRect.Y }; - _interactivity->TouchPressed(anchor); + _interactivity.TouchPressed(anchor); } else { const auto cursorPosition = point.Position(); - _interactivity->PointerPressed(TermControl::GetPressedMouseButtons(point), - TermControl::GetPointerUpdateKind(point), - point.Timestamp(), - ControlKeyStates{ args.KeyModifiers() }, - _toTerminalOrigin(cursorPosition)); + _interactivity.PointerPressed(TermControl::GetPressedMouseButtons(point), + TermControl::GetPointerUpdateKind(point), + point.Timestamp(), + ControlKeyStates{ args.KeyModifiers() }, + _toTerminalOrigin(cursorPosition)); } args.Handled(true); @@ -1098,11 +1098,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation if (type == Windows::Devices::Input::PointerDeviceType::Mouse || type == Windows::Devices::Input::PointerDeviceType::Pen) { - _interactivity->PointerMoved(TermControl::GetPressedMouseButtons(point), - TermControl::GetPointerUpdateKind(point), - ControlKeyStates(args.KeyModifiers()), - _focused, - pixelPosition); + _interactivity.PointerMoved(TermControl::GetPressedMouseButtons(point), + TermControl::GetPointerUpdateKind(point), + ControlKeyStates(args.KeyModifiers()), + _focused, + pixelPosition); if (_focused && point.Properties().IsLeftButtonPressed()) { @@ -1135,7 +1135,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation const auto contactRect = point.Properties().ContactRect(); til::point newTouchPoint{ til::math::rounding, contactRect.X, contactRect.Y }; - _interactivity->TouchMoved(newTouchPoint, _focused); + _interactivity.TouchMoved(newTouchPoint, _focused); } args.Handled(true); @@ -1166,14 +1166,14 @@ namespace winrt::Microsoft::Terminal::Control::implementation if (type == Windows::Devices::Input::PointerDeviceType::Mouse || type == Windows::Devices::Input::PointerDeviceType::Pen) { - _interactivity->PointerReleased(TermControl::GetPressedMouseButtons(point), - TermControl::GetPointerUpdateKind(point), - ControlKeyStates(args.KeyModifiers()), - pixelPosition); + _interactivity.PointerReleased(TermControl::GetPressedMouseButtons(point), + TermControl::GetPointerUpdateKind(point), + ControlKeyStates(args.KeyModifiers()), + pixelPosition); } else if (type == Windows::Devices::Input::PointerDeviceType::Touch) { - _interactivity->TouchReleased(); + _interactivity.TouchReleased(); } _TryStopAutoScroll(ptr.PointerId()); @@ -1201,10 +1201,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation const auto point = args.GetCurrentPoint(*this); - auto result = _interactivity->MouseWheel(ControlKeyStates{ args.KeyModifiers() }, - point.Properties().MouseWheelDelta(), - _toTerminalOrigin(point.Position()), - TermControl::GetPressedMouseButtons(point)); + auto result = _interactivity.MouseWheel(ControlKeyStates{ args.KeyModifiers() }, + point.Properties().MouseWheelDelta(), + _toTerminalOrigin(point.Position()), + TermControl::GetPressedMouseButtons(point)); if (result) { args.Handled(true); @@ -1228,10 +1228,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation const bool rightButtonDown) { const auto modifiers = _GetPressedModifierKeys(); - TerminalInput::MouseButtonState state{ leftButtonDown, - midButtonDown, - rightButtonDown }; - return _interactivity->MouseWheel(modifiers, delta, _toTerminalOrigin(location), state); + Control::MouseButtonState state{ leftButtonDown, + midButtonDown, + rightButtonDown }; + return _interactivity.MouseWheel(modifiers, delta, _toTerminalOrigin(location), state); } // Method Description: @@ -1302,8 +1302,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation return; } - const auto newValue = static_cast(args.NewValue()); - _core->UserScrollViewport(newValue); + const auto newValue = args.NewValue(); + _interactivity.UpdateScrollbar(newValue); // User input takes priority over terminal events so cancel // any pending scroll bar update if the user scrolls. @@ -1479,7 +1479,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation _blinkTimer.value().Start(); } - _interactivity->GainFocus(); + _interactivity.GainFocus(); // Only update the appearance here if an unfocused config exists - // if an unfocused config does not exist then we never would have switched @@ -1621,7 +1621,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation // - cursorPosition: in pixels, relative to the origin of the control void TermControl::_SetEndSelectionPointAtCursor(Windows::Foundation::Point const& cursorPosition) { - _interactivity->SetEndSelectionPoint(_toTerminalOrigin(cursorPosition)); + _interactivity.SetEndSelectionPoint(_toTerminalOrigin(cursorPosition)); } // Method Description: @@ -1701,14 +1701,14 @@ namespace winrt::Microsoft::Terminal::Control::implementation return false; } - return _interactivity->CopySelectionToClipboard(singleLine, formats); + return _interactivity.CopySelectionToClipboard(singleLine, formats); } // Method Description: // - Initiate a paste operation. void TermControl::PasteTextFromClipboard() { - _interactivity->RequestPasteTextFromClipboard(); + _interactivity.RequestPasteTextFromClipboard(); } void TermControl::Close() @@ -2448,11 +2448,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation _RaiseNoticeHandlers(*this, eventArgs); } - TerminalInput::MouseButtonState TermControl::GetPressedMouseButtons(const winrt::Windows::UI::Input::PointerPoint point) + Control::MouseButtonState TermControl::GetPressedMouseButtons(const winrt::Windows::UI::Input::PointerPoint point) { - return TerminalInput::MouseButtonState{ point.Properties().IsLeftButtonPressed(), - point.Properties().IsMiddleButtonPressed(), - point.Properties().IsRightButtonPressed() }; + return Control::MouseButtonState{ point.Properties().IsLeftButtonPressed(), + point.Properties().IsMiddleButtonPressed(), + point.Properties().IsRightButtonPressed() }; } unsigned int TermControl::GetPointerUpdateKind(const winrt::Windows::UI::Input::PointerPoint point) diff --git a/src/cascadia/TerminalControl/TermControl.h b/src/cascadia/TerminalControl/TermControl.h index 54fd49c37f2..8f1b3ee2fef 100644 --- a/src/cascadia/TerminalControl/TermControl.h +++ b/src/cascadia/TerminalControl/TermControl.h @@ -101,7 +101,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation bool ReadOnly() const noexcept; void ToggleReadOnly(); - static ::Microsoft::Console::VirtualTerminal::TerminalInput::MouseButtonState GetPressedMouseButtons(const winrt::Windows::UI::Input::PointerPoint point); + static Control::MouseButtonState GetPressedMouseButtons(const winrt::Windows::UI::Input::PointerPoint point); static unsigned int GetPointerUpdateKind(const winrt::Windows::UI::Input::PointerPoint point); // -------------------------------- WinRT Events --------------------------------- @@ -113,7 +113,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation FORWARDED_TYPED_EVENT(TabColorChanged, IInspectable, IInspectable, _core, TabColorChanged); FORWARDED_TYPED_EVENT(SetTaskbarProgress, IInspectable, IInspectable, _core, TaskbarProgressChanged); FORWARDED_TYPED_EVENT(ConnectionStateChanged, IInspectable, IInspectable, _core, ConnectionStateChanged); - FORWARDED_TYPED_EVENT(PasteFromClipboard, IInspectable, Control::PasteFromClipboardEventArgs, _interactivity, PasteFromClipboard); + + PROJECTED_FORWARDED_TYPED_EVENT(PasteFromClipboard, IInspectable, Control::PasteFromClipboardEventArgs, _interactivity, PasteFromClipboard); TYPED_EVENT(OpenHyperlink, IInspectable, Control::OpenHyperlinkEventArgs); TYPED_EVENT(RaiseNotice, IInspectable, Control::NoticeEventArgs); @@ -130,8 +131,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation private: friend struct TermControlT; // friend our parent so it can bind private event handlers - winrt::com_ptr _core; - winrt::com_ptr _interactivity; + winrt::com_ptr _core{ nullptr }; + Control::ControlInteractivity _interactivity{ nullptr }; bool _initializedTerminal; diff --git a/src/cascadia/TerminalCore/ControlKeyStates.hpp b/src/cascadia/TerminalCore/ControlKeyStates.hpp index 9b88c71a3eb..9d09bb6e567 100644 --- a/src/cascadia/TerminalCore/ControlKeyStates.hpp +++ b/src/cascadia/TerminalCore/ControlKeyStates.hpp @@ -82,6 +82,20 @@ class Microsoft::Terminal::Core::ControlKeyStates } #endif +#ifdef WINRT_Microsoft_Terminal_Core_H + constexpr ControlKeyStates(const winrt::Microsoft::Terminal::Core::ControlKeyStates& projKeyStates) : + ControlKeyStates(projKeyStates.Value) + { + } + + operator winrt::Microsoft::Terminal::Core::ControlKeyStates() const noexcept + { + winrt::Microsoft::Terminal::Core::ControlKeyStates ret; + ret.Value = _value; + return ret; + } +#endif + constexpr DWORD Value() const noexcept { return _value; diff --git a/src/cascadia/TerminalCore/ICoreAppearance.idl b/src/cascadia/TerminalCore/ICoreAppearance.idl index 30c91833ceb..ff6b16f4576 100644 --- a/src/cascadia/TerminalCore/ICoreAppearance.idl +++ b/src/cascadia/TerminalCore/ICoreAppearance.idl @@ -24,11 +24,25 @@ namespace Microsoft.Terminal.Core UInt8 A; }; + // TODO! + // It is supported by til::point for conversions in and out of WinRT land. + struct Point + { + Int32 X; + Int32 Y; + }; + // It is supported by Microsoft::Terminal::Core::ControlKeyStates for conversions in and out of WinRT land. + struct ControlKeyStates + { + Int32 Value; + }; + declare { // Forward declare this parameterized specialization so that it lives // in TerminalCore instead of being flung to the winds of all IDL dependents. interface Windows.Foundation.IReference; + interface Windows.Foundation.IReference; } interface ICoreAppearance diff --git a/src/cascadia/UnitTests_Control/ControlInteractivityTests.cpp b/src/cascadia/UnitTests_Control/ControlInteractivityTests.cpp index eeb9825475f..ca63063f6a1 100644 --- a/src/cascadia/UnitTests_Control/ControlInteractivityTests.cpp +++ b/src/cascadia/UnitTests_Control/ControlInteractivityTests.cpp @@ -29,6 +29,9 @@ namespace ControlUnitTests TEST_METHOD(TestScrollWithMouse); TEST_METHOD(CreateSubsequentSelectionWithDragging); + TEST_METHOD(ScrollWithSelection); + TEST_METHOD(TestScrollWithTrackpad); + TEST_METHOD(TestQuickDragOnSelect); TEST_CLASS_SETUP(ClassSetup) { @@ -226,11 +229,13 @@ namespace ControlUnitTests Log::Comment(L"Scroll down 21 more times, to the bottom"); for (int i = 0; i < 21; ++i) { + Log::Comment(NoThrowString().Format(L"---scroll down #%d---", i)); expectedTop++; interactivity->MouseWheel(modifiers, -WHEEL_DELTA, til::point{ 0, 0 }, { false, false, false }); + Log::Comment(NoThrowString().Format(L"internal scrollbar pos:%f", interactivity->_internalScrollbarPosition)); } Log::Comment(L"Scrolling up more should do nothing"); expectedTop = 21; @@ -330,4 +335,226 @@ namespace ControlUnitTests VERIFY_IS_TRUE(core->HasSelection()); VERIFY_ARE_EQUAL(1u, core->_terminal->GetSelectionRects().size()); } + + void ControlInteractivityTests::ScrollWithSelection() + { + // This is a test for GH#9955.a + auto [settings, conn] = _createSettingsAndConnection(); + auto [core, interactivity] = _createCoreAndInteractivity(*settings, *conn); + _standardInit(core, interactivity); + // For the sake of this test, scroll one line at a time + interactivity->_rowsToScroll = 1; + + Log::Comment(L"Add some test to the terminal so we can scroll"); + for (int i = 0; i < 40; ++i) + { + conn->WriteInput(L"Foo\r\n"); + } + // We printed that 40 times, but the final \r\n bumped the view down one MORE row. + VERIFY_ARE_EQUAL(20, core->_terminal->GetViewport().Height()); + VERIFY_ARE_EQUAL(21, core->ScrollOffset()); + VERIFY_ARE_EQUAL(20, core->ViewHeight()); + VERIFY_ARE_EQUAL(41, core->BufferHeight()); + + // For this test, don't use any modifiers + const auto modifiers = ControlKeyStates(); + const TerminalInput::MouseButtonState leftMouseDown{ true, false, false }; + const TerminalInput::MouseButtonState noMouseDown{ false, false, false }; + + const til::size fontSize{ 9, 21 }; + + Log::Comment(L"Click on the terminal"); + const til::point terminalPosition0{ 5, 5 }; + const til::point cursorPosition0{ terminalPosition0 * fontSize }; + interactivity->PointerPressed(leftMouseDown, + WM_LBUTTONDOWN, //pointerUpdateKind + 0, // timestamp + modifiers, + cursorPosition0); + + Log::Comment(L"Verify that there's not yet a selection"); + VERIFY_IS_FALSE(core->HasSelection()); + + VERIFY_IS_TRUE(interactivity->_singleClickTouchdownPos.has_value()); + VERIFY_ARE_EQUAL(cursorPosition0, interactivity->_singleClickTouchdownPos.value()); + + Log::Comment(L"Drag the mouse just a little"); + // move not quite a whole cell, but enough to start a selection + const til::point cursorPosition1{ cursorPosition0 + til::point{ 6, 0 } }; + interactivity->PointerMoved(leftMouseDown, + WM_LBUTTONDOWN, //pointerUpdateKind + modifiers, + true, // focused, + cursorPosition1); + Log::Comment(L"Verify that there's one selection"); + VERIFY_IS_TRUE(core->HasSelection()); + VERIFY_ARE_EQUAL(1u, core->_terminal->GetSelectionRects().size()); + + Log::Comment(L"Verify the location of the selection"); + // The viewport is on row 21, so the selection will be on: + // {(5, 5)+(0, 21)} to {(5, 5)+(0, 21)} + COORD expectedAnchor{ 5, 26 }; + VERIFY_ARE_EQUAL(expectedAnchor, core->_terminal->GetSelectionAnchor()); + VERIFY_ARE_EQUAL(expectedAnchor, core->_terminal->GetSelectionEnd()); + + Log::Comment(L"Scroll up a line, with the left mouse button selected"); + interactivity->MouseWheel(modifiers, + WHEEL_DELTA, + cursorPosition1, + { true, false, false }); + + Log::Comment(L"Verify the location of the selection"); + // The viewport is now on row 20, so the selection will be on: + // {(5, 5)+(0, 20)} to {(5, 5)+(0, 21)} + COORD newExpectedAnchor{ 5, 25 }; + // Remember, the anchor is always before the end in the buffer. So yes, + // se started the selection on 5,26, but now that's the end. + VERIFY_ARE_EQUAL(newExpectedAnchor, core->_terminal->GetSelectionAnchor()); + VERIFY_ARE_EQUAL(expectedAnchor, core->_terminal->GetSelectionEnd()); + } + + void ControlInteractivityTests::TestScrollWithTrackpad() + { + WEX::TestExecution::DisableVerifyExceptions disableVerifyExceptions{}; + + auto [settings, conn] = _createSettingsAndConnection(); + auto [core, interactivity] = _createCoreAndInteractivity(*settings, *conn); + _standardInit(core, interactivity); + // For the sake of this test, scroll one line at a time + interactivity->_rowsToScroll = 1; + + // auto scrollChangedHandler = [&](auto&&, const Control::ScrollPositionChangedArgs& args) mutable { + // // This mock emulates how the TermControl updates the + // // interactivity's internal scrollbar when the core changes its + // // viewport. + // // + // // In reality, the TermControl throttles scrollbar updates, and only + // // calls back to UpdateScrollbar once every 60 seconds. + // const auto newValue = args.ViewTop(); + // if (newValue != core->ScrollOffset()) + // { + // interactivity->UpdateScrollbar(newValue); + // } + // }; + // core->ScrollPositionChanged(scrollChangedHandler); + + for (int i = 0; i < 40; ++i) + { + conn->WriteInput(L"Foo\r\n"); + } + // We printed that 40 times, but the final \r\n bumped the view down one MORE row. + VERIFY_ARE_EQUAL(20, core->_terminal->GetViewport().Height()); + VERIFY_ARE_EQUAL(21, core->ScrollOffset()); + VERIFY_ARE_EQUAL(20, core->ViewHeight()); + VERIFY_ARE_EQUAL(41, core->BufferHeight()); + + Log::Comment(L"Scroll up a line"); + const auto modifiers = ControlKeyStates(); + + // Deltas that I saw while scrolling with the surface laptop trackpad + // were on the range [-22, 7], though I'm sure they could be greater in + // magnitude. + // + // WHEEL_DELTA is 120, so we'll use 24 for now as the delta, just so the tests don't take forever. + + const int delta = WHEEL_DELTA / 5; + const til::point mousePos{ 0, 0 }; + TerminalInput::MouseButtonState state{ false, false, false }; + + interactivity->MouseWheel(modifiers, delta, mousePos, state); // 1/5 + VERIFY_ARE_EQUAL(21, core->ScrollOffset()); + + Log::Comment(L"Scroll up 4 more times. Once we're at 3/5 scrolls, " + L"we'll round the internal scrollbar position to scrolling to the next row."); + interactivity->MouseWheel(modifiers, delta, mousePos, state); // 2/5 + VERIFY_ARE_EQUAL(21, core->ScrollOffset()); + interactivity->MouseWheel(modifiers, delta, mousePos, state); // 3/5 + VERIFY_ARE_EQUAL(20, core->ScrollOffset()); + interactivity->MouseWheel(modifiers, delta, mousePos, state); // 4/5 + VERIFY_ARE_EQUAL(20, core->ScrollOffset()); + interactivity->MouseWheel(modifiers, delta, mousePos, state); // 5/5 + VERIFY_ARE_EQUAL(20, core->ScrollOffset()); + + Log::Comment(L"Jump to line 5, so we can scroll down from there."); + interactivity->UpdateScrollbar(5); + VERIFY_ARE_EQUAL(5, core->ScrollOffset()); + Log::Comment(L"Scroll down 5 times, at which point we should accumulate a whole row of delta."); + interactivity->MouseWheel(modifiers, -delta, mousePos, state); // 1/5 + VERIFY_ARE_EQUAL(5, core->ScrollOffset()); + interactivity->MouseWheel(modifiers, -delta, mousePos, state); // 2/5 + VERIFY_ARE_EQUAL(5, core->ScrollOffset()); + interactivity->MouseWheel(modifiers, -delta, mousePos, state); // 3/5 + VERIFY_ARE_EQUAL(6, core->ScrollOffset()); + interactivity->MouseWheel(modifiers, -delta, mousePos, state); // 4/5 + VERIFY_ARE_EQUAL(6, core->ScrollOffset()); + interactivity->MouseWheel(modifiers, -delta, mousePos, state); // 5/5 + VERIFY_ARE_EQUAL(6, core->ScrollOffset()); + + Log::Comment(L"Jump to the bottom."); + interactivity->UpdateScrollbar(21); + VERIFY_ARE_EQUAL(21, core->ScrollOffset()); + Log::Comment(L"Scroll a bit, then emit a line of text. We should reset our internal scroll position."); + interactivity->MouseWheel(modifiers, delta, mousePos, state); // 1/5 + VERIFY_ARE_EQUAL(21, core->ScrollOffset()); + interactivity->MouseWheel(modifiers, delta, mousePos, state); // 2/5 + VERIFY_ARE_EQUAL(21, core->ScrollOffset()); + + conn->WriteInput(L"Foo\r\n"); + VERIFY_ARE_EQUAL(22, core->ScrollOffset()); + interactivity->MouseWheel(modifiers, delta, mousePos, state); // 1/5 + VERIFY_ARE_EQUAL(22, core->ScrollOffset()); + interactivity->MouseWheel(modifiers, delta, mousePos, state); // 2/5 + VERIFY_ARE_EQUAL(22, core->ScrollOffset()); + interactivity->MouseWheel(modifiers, delta, mousePos, state); // 3/5 + VERIFY_ARE_EQUAL(21, core->ScrollOffset()); + interactivity->MouseWheel(modifiers, delta, mousePos, state); // 4/5 + VERIFY_ARE_EQUAL(21, core->ScrollOffset()); + interactivity->MouseWheel(modifiers, delta, mousePos, state); // 5/5 + VERIFY_ARE_EQUAL(21, core->ScrollOffset()); + } + + void ControlInteractivityTests::TestQuickDragOnSelect() + { + // This is a test for GH#9955.c + + auto [settings, conn] = _createSettingsAndConnection(); + auto [core, interactivity] = _createCoreAndInteractivity(*settings, *conn); + _standardInit(core, interactivity); + + // For this test, don't use any modifiers + const auto modifiers = ControlKeyStates(); + const TerminalInput::MouseButtonState leftMouseDown{ true, false, false }; + const TerminalInput::MouseButtonState noMouseDown{ false, false, false }; + + const til::size fontSize{ 9, 21 }; + + Log::Comment(L"Click on the terminal"); + const til::point cursorPosition0{ 6, 0 }; + interactivity->PointerPressed(leftMouseDown, + WM_LBUTTONDOWN, //pointerUpdateKind + 0, // timestamp + modifiers, + cursorPosition0); + + Log::Comment(L"Verify that there's not yet a selection"); + VERIFY_IS_FALSE(core->HasSelection()); + + VERIFY_IS_TRUE(interactivity->_singleClickTouchdownPos.has_value()); + VERIFY_ARE_EQUAL(cursorPosition0, interactivity->_singleClickTouchdownPos.value()); + + Log::Comment(L"Drag the mouse a lot. This simulates dragging the mouse real fast."); + const til::point cursorPosition1{ 6 + fontSize.width() * 2, 0 }; + interactivity->PointerMoved(leftMouseDown, + WM_LBUTTONDOWN, //pointerUpdateKind + modifiers, + true, // focused, + cursorPosition1); + Log::Comment(L"Verify that there's one selection"); + VERIFY_IS_TRUE(core->HasSelection()); + VERIFY_ARE_EQUAL(1u, core->_terminal->GetSelectionRects().size()); + + Log::Comment(L"Verify that it started on the first cell we clicked on, not the one we dragged to"); + COORD expectedAnchor{ 0, 0 }; + VERIFY_ARE_EQUAL(expectedAnchor, core->_terminal->GetSelectionAnchor()); + } } diff --git a/src/cascadia/inc/cppwinrt_utils.h b/src/cascadia/inc/cppwinrt_utils.h index d73ad493411..9b65c6fb59a 100644 --- a/src/cascadia/inc/cppwinrt_utils.h +++ b/src/cascadia/inc/cppwinrt_utils.h @@ -96,6 +96,12 @@ public: winrt::event_token name(Windows::Foundation::TypedEventHandler const& h) { return handler->handlerName(h); } \ void name(winrt::event_token const& token) noexcept { handler->handlerName(token); } +// Same thing, but handler is a projected type, not an implementation +#define PROJECTED_FORWARDED_TYPED_EVENT(name, sender, args, handler, handlerName) \ +public: \ + winrt::event_token name(Windows::Foundation::TypedEventHandler const& h) { return handler.handlerName(h); } \ + void name(winrt::event_token const& token) noexcept { handler.handlerName(token); } + // Use this macro to quick implement both the getter and setter for a property. // This should only be used for simple types where there's no logic in the // getter/setter beyond just accessing/updating the value. diff --git a/src/inc/til/point.h b/src/inc/til/point.h index 366ba18077b..369a827d603 100644 --- a/src/inc/til/point.h +++ b/src/inc/til/point.h @@ -338,6 +338,21 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned" } #endif +#ifdef WINRT_Microsoft_Terminal_Core_H + constexpr point(const winrt::Microsoft::Terminal::Core::Point& corePoint) : + point(corePoint.X, corePoint.Y) + { + } + + operator winrt::Microsoft::Terminal::Core::Point() const noexcept + { + winrt::Microsoft::Terminal::Core::Point ret; + ret.X = x(); + ret.Y = y(); + return ret; + } +#endif + std::wstring to_string() const { return wil::str_printf(L"(X:%td, Y:%td)", x(), y()); From 400b35f8140732aa8483f6a90c09ad225a93581c Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Fri, 30 Apr 2021 06:39:29 -0500 Subject: [PATCH 02/30] Only 24 more errors to go --- src/cascadia/TerminalControl/ControlCore.cpp | 19 +- src/cascadia/TerminalControl/ControlCore.h | 6 +- src/cascadia/TerminalControl/ControlCore.idl | 80 +++++++++ .../TerminalControl/ControlInteractivity.h | 1 - .../TerminalControl/ControlInteractivity.idl | 10 -- src/cascadia/TerminalControl/ICoreState.idl | 1 + src/cascadia/TerminalControl/TermControl.cpp | 169 +++++++++--------- src/cascadia/TerminalControl/TermControl.h | 12 +- 8 files changed, 194 insertions(+), 104 deletions(-) diff --git a/src/cascadia/TerminalControl/ControlCore.cpp b/src/cascadia/TerminalControl/ControlCore.cpp index 46775a70310..e909b013846 100644 --- a/src/cascadia/TerminalControl/ControlCore.cpp +++ b/src/cascadia/TerminalControl/ControlCore.cpp @@ -887,6 +887,23 @@ namespace winrt::Microsoft::Terminal::Control::implementation return _actualFont; } + winrt::Windows::Foundation::Size ControlCore::FontSize() const noexcept + { + const auto fontSize = GetFont().GetSize(); + return { + ::base::saturated_cast(fontSize.X), + ::base::saturated_cast(fontSize.Y) + }; + } + winrt::hstring ControlCore::FontFaceName() const noexcept + { + return GetFont().GetFaceName(); + } + uint16_t ControlCore::FontWeight() const noexcept + { + return static_cast(GetFont().GetWeight()); + } + til::size ControlCore::FontSizeInDips() const { const til::size fontSize{ GetFont().GetSize() }; @@ -1116,7 +1133,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation } } - void ControlCore::SetBackgroundOpacity(const float opacity) + void ControlCore::SetBackgroundOpacity(const double opacity) { if (_renderEngine) { diff --git a/src/cascadia/TerminalControl/ControlCore.h b/src/cascadia/TerminalControl/ControlCore.h index 8ab58a2243d..0d46ebde2fd 100644 --- a/src/cascadia/TerminalControl/ControlCore.h +++ b/src/cascadia/TerminalControl/ControlCore.h @@ -56,8 +56,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation FontInfo GetFont() const; til::size FontSizeInDips() const; + winrt::Windows::Foundation::Size FontSize() const noexcept; + winrt::hstring FontFaceName() const noexcept; + uint16_t FontWeight() const noexcept; + til::color BackgroundColor() const; - void SetBackgroundOpacity(const float opacity); + void SetBackgroundOpacity(const double opacity); void SendInput(const winrt::hstring& wstr); void PasteText(const winrt::hstring& hstr); diff --git a/src/cascadia/TerminalControl/ControlCore.idl b/src/cascadia/TerminalControl/ControlCore.idl index c3074000f75..93020e114ab 100644 --- a/src/cascadia/TerminalControl/ControlCore.idl +++ b/src/cascadia/TerminalControl/ControlCore.idl @@ -8,9 +8,89 @@ import "EventArgs.idl"; namespace Microsoft.Terminal.Control { + // This is a mirror of + // ::Microsoft::Console::VirtualTerminal::TerminalInput::MouseButtonState, + // but projectable. + struct MouseButtonState + { + Boolean IsLeftButtonDown; + Boolean IsMiddleButtonDown; + Boolean IsRightButtonDown; + }; + + [default_interface] runtimeclass ControlCore : ICoreState { ControlCore(IControlSettings settings, Microsoft.Terminal.TerminalConnection.ITerminalConnection connection); + + // void AttachUiaEngine(::Microsoft::Console::Render::IRenderEngine* const pEngine); + // ::Microsoft::Console::Types::IUiaData* GetUiaData() const; + + Windows.Foundation.Size FontSize { get; }; + String FontFaceName { get; }; + UInt16 FontWeight { get; }; + + // IDXGISwapChain1* GetSwapChain() const; + // std::vector SelectedText(bool trimTrailingWhitespace) const; + // void UpdateHoveredCell(const std::optional& terminalPosition); + // std::optional GetHoveredCell() const; + + Boolean TrySendKeyEvent(Int16 vkey, + Int16 scanCode, + Microsoft.Terminal.Core.ControlKeyStates modifiers, + Boolean keyDown); + Boolean SendCharEvent(Char ch, + Int16 scanCode, + Microsoft.Terminal.Core.ControlKeyStates modifiers); + + Microsoft.Terminal.Core.Point CursorPosition(); + void ResumeRendering(); + void ToggleReadOnlyMode(); + void BlinkAttributeTick(); + String GetHoveredUriText(); + void SendInput(String text); + void PasteText(String text); + void UpdatePatternLocations(); + Boolean HasSelection(); + void Search(String text, Boolean goForward, Boolean caseSensitive); + void UpdateSettings(IControlSettings settings); + void UpdateAppearance(IControlAppearance appearance); + void ToggleShaderEffects(); + void SetBackgroundOpacity(Double opacity); + Microsoft.Terminal.Core.Color BackgroundColor(); + void Initialize(Double actualWidth, + Double actualHeight, + Double compositionScale); + void Close(); + void BlinkCursor(); + void ResetFontSize(); + void AdjustFontSize(Int32 fontSize); + void SizeChanged(Double width, Double height); + void ScaleChanged(Double scale); + Boolean IsInReadOnlyMode(); + Boolean CursorOn; + void EnablePainting(); + + + event FontSizeChangedEventArgs FontSizeChanged; + + event Windows.Foundation.TypedEventHandler CopyToClipboard; + event Windows.Foundation.TypedEventHandler TitleChanged; + event Windows.Foundation.TypedEventHandler WarningBell; + event Windows.Foundation.TypedEventHandler TabColorChanged; + event Windows.Foundation.TypedEventHandler BackgroundColorChanged; + event Windows.Foundation.TypedEventHandler ScrollPositionChanged; + event Windows.Foundation.TypedEventHandler CursorPositionChanged; + event Windows.Foundation.TypedEventHandler TaskbarProgressChanged; + event Windows.Foundation.TypedEventHandler ConnectionStateChanged; + event Windows.Foundation.TypedEventHandler HoveredHyperlinkChanged; + event Windows.Foundation.TypedEventHandler RendererEnteredErrorState; + event Windows.Foundation.TypedEventHandler SwapChainChanged; + event Windows.Foundation.TypedEventHandler RendererWarning; + event Windows.Foundation.TypedEventHandler RaiseNotice; + event Windows.Foundation.TypedEventHandler TransparencyChanged; + event Windows.Foundation.TypedEventHandler ReceivedOutput; + }; } diff --git a/src/cascadia/TerminalControl/ControlInteractivity.h b/src/cascadia/TerminalControl/ControlInteractivity.h index 6c6693385d3..83535bd7cc3 100644 --- a/src/cascadia/TerminalControl/ControlInteractivity.h +++ b/src/cascadia/TerminalControl/ControlInteractivity.h @@ -77,7 +77,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation const Windows::Foundation::IReference& formats); void RequestPasteTextFromClipboard(); void SetEndSelectionPoint(const til::point pixelPosition); - // void SetEndSelectionPoint(const Core::Point pixelPosition); TYPED_EVENT(OpenHyperlink, IInspectable, Control::OpenHyperlinkEventArgs); TYPED_EVENT(PasteFromClipboard, IInspectable, Control::PasteFromClipboardEventArgs); diff --git a/src/cascadia/TerminalControl/ControlInteractivity.idl b/src/cascadia/TerminalControl/ControlInteractivity.idl index aedf612e4df..5856d7cf153 100644 --- a/src/cascadia/TerminalControl/ControlInteractivity.idl +++ b/src/cascadia/TerminalControl/ControlInteractivity.idl @@ -9,16 +9,6 @@ import "EventArgs.idl"; namespace Microsoft.Terminal.Control { - // This is a mirror of - // ::Microsoft::Console::VirtualTerminal::TerminalInput::MouseButtonState, - // but projectable. - struct MouseButtonState - { - Boolean IsLeftButtonDown; - Boolean IsMiddleButtonDown; - Boolean IsRightButtonDown; - }; - [default_interface] runtimeclass ControlInteractivity { ControlInteractivity(IControlSettings settings, diff --git a/src/cascadia/TerminalControl/ICoreState.idl b/src/cascadia/TerminalControl/ICoreState.idl index a21c0747c3e..ad5217bf666 100644 --- a/src/cascadia/TerminalControl/ICoreState.idl +++ b/src/cascadia/TerminalControl/ICoreState.idl @@ -17,6 +17,7 @@ namespace Microsoft.Terminal.Control Int32 ScrollOffset { get; }; Int32 ViewHeight { get; }; + Int32 BufferHeight { get; }; Boolean BracketedPasteEnabled { get; }; diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index 1f1920b4a61..986d1bdb61e 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -67,26 +67,26 @@ namespace winrt::Microsoft::Terminal::Control::implementation // Use a manual revoker on the output event, so we can immediately stop // worrying about it on destruction. - _coreOutputEventToken = _core->ReceivedOutput({ this, &TermControl::_coreReceivedOutput }); + _coreOutputEventToken = _core.ReceivedOutput({ this, &TermControl::_coreReceivedOutput }); // These events might all be triggered by the connection, but that // should be drained and closed before we complete destruction. So these // are safe. - _core->ScrollPositionChanged({ this, &TermControl::_ScrollPositionChanged }); - _core->WarningBell({ this, &TermControl::_coreWarningBell }); - _core->CursorPositionChanged({ this, &TermControl::_CursorPositionChanged }); + _core.ScrollPositionChanged({ this, &TermControl::_ScrollPositionChanged }); + _core.WarningBell({ this, &TermControl::_coreWarningBell }); + _core.CursorPositionChanged({ this, &TermControl::_CursorPositionChanged }); // This event is specifically triggered by the renderer thread, a BG thread. Use a weak ref here. - _core->RendererEnteredErrorState({ get_weak(), &TermControl::_RendererEnteredErrorState }); + _core.RendererEnteredErrorState({ get_weak(), &TermControl::_RendererEnteredErrorState }); // These callbacks can only really be triggered by UI interactions. So // they don't need weak refs - they can't be triggered unless we're // alive. - _core->BackgroundColorChanged({ this, &TermControl::_BackgroundColorChangedHandler }); - _core->FontSizeChanged({ this, &TermControl::_coreFontSizeChanged }); - _core->TransparencyChanged({ this, &TermControl::_coreTransparencyChanged }); - _core->RaiseNotice({ this, &TermControl::_coreRaisedNotice }); - _core->HoveredHyperlinkChanged({ this, &TermControl::_hoveredHyperlinkChanged }); + _core.BackgroundColorChanged({ this, &TermControl::_BackgroundColorChangedHandler }); + _core.FontSizeChanged({ this, &TermControl::_coreFontSizeChanged }); + _core.TransparencyChanged({ this, &TermControl::_coreTransparencyChanged }); + _core.RaiseNotice({ this, &TermControl::_coreRaisedNotice }); + _core.HoveredHyperlinkChanged({ this, &TermControl::_hoveredHyperlinkChanged }); _interactivity.OpenHyperlink({ this, &TermControl::_HyperlinkHandler }); _interactivity.ScrollPositionChanged({ this, &TermControl::_ScrollPositionChanged }); @@ -124,7 +124,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation [weakThis = get_weak()]() { if (auto control{ weakThis.get() }) { - control->_core->UpdatePatternLocations(); + control->_core.UpdatePatternLocations(); } }, UpdatePatternLocationsInterval, @@ -185,12 +185,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation // If a text is selected inside terminal, use it to populate the search box. // If the search box already contains a value, it will be overridden. - if (_core->HasSelection()) + if (_core.HasSelection()) { // Currently we populate the search box only if a single line is selected. // Empirically, multi-line selection works as well on sample scenarios, // but since code paths differ, extra work is required to ensure correctness. - auto bufferText = _core->SelectedText(true); + auto bufferText = _core.SelectedText(true); if (bufferText.size() == 1) { const auto selectedLine{ til::at(bufferText, 0) }; @@ -215,7 +215,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation } else { - _core->Search(_searchBox->TextBox().Text(), goForward, false); + _core.Search(_searchBox->TextBox().Text(), goForward, false); } } @@ -232,7 +232,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation const bool goForward, const bool caseSensitive) { - _core->Search(text, goForward, caseSensitive); + _core.Search(text, goForward, caseSensitive); } // Method Description: @@ -301,7 +301,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation return; } - _core->UpdateSettings(_settings); + _core.UpdateSettings(_settings); // Update our control settings _ApplyUISettings(_settings); @@ -360,7 +360,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation foregroundBrush.Color(static_cast(newAppearance.DefaultForeground())); TSFInputControl().Foreground(foregroundBrush); - _core->UpdateAppearance(newAppearance); + _core.UpdateAppearance(newAppearance); } // Method Description: @@ -371,12 +371,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation // - void TermControl::SendInput(const winrt::hstring& wstr) { - _core->SendInput(wstr); + _core.SendInput(wstr); } void TermControl::ToggleShaderEffects() { - _core->ToggleShaderEffects(); + _core.ToggleShaderEffects(); } // Method Description: @@ -469,7 +469,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation } // GH#5098: Inform the engine of the new opacity of the default text background. - _core->SetBackgroundOpacity(::base::saturated_cast(_settings.TintOpacity())); + _core.SetBackgroundOpacity(::base::saturated_cast(_settings.TintOpacity())); } else { @@ -477,7 +477,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation RootGrid().Background(solidColor); // GH#5098: Inform the engine of the new opacity of the default text background. - _core->SetBackgroundOpacity(1.0f); + _core.SetBackgroundOpacity(1.0f); } } @@ -490,7 +490,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation void TermControl::_BackgroundColorChangedHandler(const IInspectable& /*sender*/, const IInspectable& /*args*/) { - til::color newBgColor{ _core->BackgroundColor() }; + til::color newBgColor{ _core.BackgroundColor() }; _changeBackgroundColor(newBgColor); } @@ -534,7 +534,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation auto autoPeer = winrt::make_self(this); _uiaEngine = std::make_unique<::Microsoft::Console::Render::UiaEngine>(autoPeer.get()); - _core->AttachUiaEngine(_uiaEngine.get()); + _core.AttachUiaEngine(_uiaEngine.get()); return *autoPeer; } return nullptr; @@ -547,14 +547,15 @@ namespace winrt::Microsoft::Terminal::Control::implementation ::Microsoft::Console::Types::IUiaData* TermControl::GetUiaData() const { - return _core->GetUiaData(); + return _core.GetUiaData(); } // This is needed for TermControlAutomationPeer. We probably could find a // clever way around asking the core for this. til::point TermControl::GetFontSize() const { - return _core->GetFont().GetSize(); + const auto size = _core.FontSize(); + return til::point{ til::math::rounding, size.Width, size.Height }; } const Windows::UI::Xaml::Thickness TermControl::GetPadding() @@ -564,7 +565,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation TerminalConnection::ConnectionState TermControl::ConnectionState() const { - return _core->ConnectionState(); + return _core.ConnectionState(); } winrt::fire_and_forget TermControl::RenderEngineSwapChainChanged(IInspectable /*sender*/, IInspectable /*args*/) @@ -578,7 +579,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation if (auto control{ weakThis.get() }) { - const auto chain = control->_core->GetSwapChain(); + const auto chain = control->_core.GetSwapChain(); _AttachDxgiSwapChainToXaml(chain); } } @@ -655,23 +656,23 @@ namespace winrt::Microsoft::Terminal::Control::implementation // after Enable, then it'll be possible to paint the frame once // _before_ the warning handler is set up, and then warnings from // the first paint will be ignored! - _core->RendererWarning({ get_weak(), &TermControl::_RendererWarning }); + _core.RendererWarning({ get_weak(), &TermControl::_RendererWarning }); - const auto coreInitialized = _core->Initialize(panelWidth, - panelHeight, - panelScaleX); + const auto coreInitialized = _core.Initialize(panelWidth, + panelHeight, + panelScaleX); if (!coreInitialized) { return false; } _interactivity.Initialize(); - _AttachDxgiSwapChainToXaml(_core->GetSwapChain()); + _AttachDxgiSwapChainToXaml(_core.GetSwapChain()); // Tell the DX Engine to notify us when the swap chain changes. We do // this after we initially set the swapchain so as to avoid unnecessary // callbacks (and locking problems) - _core->SwapChainChanged({ get_weak(), &TermControl::RenderEngineSwapChainChanged }); + _core.SwapChainChanged({ get_weak(), &TermControl::RenderEngineSwapChainChanged }); // !! LOAD BEARING !! // Make sure you enable painting _AFTER_ calling _AttachDxgiSwapChainToXaml @@ -681,9 +682,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation // issues where the Renderer starts trying to paint before we've // actually attached the swapchain to anything, and the DxEngine is not // prepared to handle that. - _core->EnablePainting(); + _core.EnablePainting(); - auto bufferHeight = _core->BufferHeight(); + auto bufferHeight = _core.BufferHeight(); ScrollBar().Maximum(bufferHeight - bufferHeight); ScrollBar().Minimum(0); @@ -760,7 +761,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation { modifiers |= ControlKeyStates::EnhancedKey; } - const bool handled = _core->SendCharEvent(ch, scanCode, modifiers); + const bool handled = _core.SendCharEvent(ch, scanCode, modifiers); e.Handled(handled); } @@ -772,7 +773,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation bool TermControl::OnDirectKeyEvent(const uint32_t vkey, const uint8_t scanCode, const bool down) { // Short-circuit isReadOnly check to avoid warning dialog - if (_core->IsInReadOnlyMode()) + if (_core.IsInReadOnlyMode()) { return false; } @@ -858,7 +859,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation const auto scanCode = gsl::narrow_cast(e.KeyStatus().ScanCode); // Short-circuit isReadOnly check to avoid warning dialog - if (_core->IsInReadOnlyMode()) + if (_core.IsInReadOnlyMode()) { e.Handled(!keyDown || _TryHandleKeyBinding(vkey, scanCode, modifiers)); return; @@ -990,17 +991,17 @@ namespace winrt::Microsoft::Terminal::Control::implementation // This will prevent the system from trying to get the character out // of it and sending us a CharacterReceived event. const auto handled = vkey ? - _core->TrySendKeyEvent(vkey, - scanCode, - modifiers, - keyDown) : + _core.TrySendKeyEvent(vkey, + scanCode, + modifiers, + keyDown) : true; if (_cursorTimer.has_value()) { // Manually show the cursor when a key is pressed. Restarting // the timer prevents flickering. - _core->CursorOn(true); + _core.CursorOn(true); _cursorTimer.value().Start(); } @@ -1279,7 +1280,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation // - none void TermControl::ResetFontSize() { - _core->ResetFontSize(); + _core.ResetFontSize(); } // Method Description: @@ -1288,7 +1289,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation // - fontSizeDelta: The amount to increase or decrease the font size by. void TermControl::AdjustFontSize(int fontSizeDelta) { - _core->AdjustFontSize(fontSizeDelta); + _core.AdjustFontSize(fontSizeDelta); } void TermControl::_ScrollbarChangeHandler(Windows::Foundation::IInspectable const& /*sender*/, @@ -1470,7 +1471,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation if (_cursorTimer.has_value()) { // When the terminal focuses, show the cursor immediately - _core->CursorOn(true); + _core.CursorOn(true); _cursorTimer.value().Start(); } @@ -1519,7 +1520,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation if (_cursorTimer.has_value()) { _cursorTimer.value().Stop(); - _core->CursorOn(false); + _core.CursorOn(false); } if (_blinkTimer.has_value()) @@ -1549,7 +1550,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation } const auto newSize = e.NewSize(); - _core->SizeChanged(newSize.Width, newSize.Height); + _core.SizeChanged(newSize.Width, newSize.Height); } // Method Description: @@ -1584,7 +1585,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation { const auto scaleX = sender.CompositionScaleX(); - _core->ScaleChanged(scaleX); + _core.ScaleChanged(scaleX); } // Method Description: @@ -1597,7 +1598,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation { if (!_closing) { - _core->BlinkCursor(); + _core.BlinkCursor(); } } @@ -1611,7 +1612,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation { if (!_closing) { - _core->BlinkAttributeTick(); + _core.BlinkAttributeTick(); } } @@ -1668,7 +1669,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation hstring TermControl::Title() { - return _core->Title(); + return _core.Title(); } hstring TermControl::GetProfileName() const @@ -1678,12 +1679,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation hstring TermControl::WorkingDirectory() const { - return _core->WorkingDirectory(); + return _core.WorkingDirectory(); } bool TermControl::BracketedPasteEnabled() const noexcept { - return _core->BracketedPasteEnabled(); + return _core.BracketedPasteEnabled(); } // Method Description: @@ -1715,7 +1716,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation { if (!_closing.exchange(true)) { - _core->ReceivedOutput(_coreOutputEventToken); + _core.ReceivedOutput(_coreOutputEventToken); _RestorePointerCursorHandlers(*this, nullptr); @@ -1723,7 +1724,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation TSFInputControl().Close(); _autoScrollTimer.Stop(); - _core->Close(); + _core.Close(); } } @@ -1738,7 +1739,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation int TermControl::ScrollOffset() { - return _core->ScrollOffset(); + return _core.ScrollOffset(); } // Function Description: @@ -1747,7 +1748,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation // - The height of the terminal in lines of text int TermControl::ViewHeight() const { - return _core->ViewHeight(); + return _core.ViewHeight(); } // Function Description: @@ -1864,8 +1865,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation // - The dimensions of a single character of this control, in DIPs winrt::Windows::Foundation::Size TermControl::CharacterDimensions() const { - const auto fontSize = _core->GetFont().GetSize(); - return { gsl::narrow_cast(fontSize.X), gsl::narrow_cast(fontSize.Y) }; + return _core.FontSize(); } // Method Description: @@ -1881,9 +1881,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation { if (_initializedTerminal) { - const auto fontSize = _core->GetFont().GetSize(); - double width = fontSize.X; - double height = fontSize.Y; + const auto fontSize = _core.FontSize(); + double width = fontSize.Width; + double height = fontSize.Height; // Reserve additional space if scrollbar is intended to be visible if (_settings.ScrollState() == ScrollbarState::Visible) { @@ -1926,8 +1926,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation // - A dimension that would be aligned to the character grid. float TermControl::SnapDimensionToGrid(const bool widthOrHeight, const float dimension) { - const auto fontSize = _core->GetFont().GetSize(); - const auto fontDimension = widthOrHeight ? fontSize.X : fontSize.Y; + const auto fontSize = _core.FontSize(); + const auto fontDimension = widthOrHeight ? fontSize.Width : fontSize.Height; const auto padding = GetPadding(); auto nonTerminalArea = gsl::narrow_cast(widthOrHeight ? @@ -2087,7 +2087,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation return; } - _core->SendInput(text); + _core.SendInput(text); } // Method Description: @@ -2107,7 +2107,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation return; } - const til::point cursorPos = _core->CursorPosition(); + const til::point cursorPos = _core.CursorPosition(); Windows::Foundation::Point p = { ::base::ClampedNumeric(cursorPos.x()), ::base::ClampedNumeric(cursorPos.y()) }; eventArgs.CurrentPosition(p); @@ -2123,11 +2123,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation void TermControl::_FontInfoHandler(const IInspectable& /*sender*/, const FontInfoEventArgs& eventArgs) { - const auto fontInfo = _core->GetFont(); eventArgs.FontSize(CharacterDimensions()); - eventArgs.FontFace(fontInfo.GetFaceName()); + eventArgs.FontFace(_core.FontFaceName()); ::winrt::Windows::UI::Text::FontWeight weight; - weight.Weight = static_cast(fontInfo.GetWeight()); + weight.Weight = _core.FontWeight(); eventArgs.FontWeight(weight); } @@ -2169,7 +2168,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation try { Windows::Foundation::Uri link{ co_await e.DataView().GetApplicationLinkAsync() }; - _core->PasteText(link.AbsoluteUri()); + _core.PasteText(link.AbsoluteUri()); } CATCH_LOG(); } @@ -2178,7 +2177,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation try { Windows::Foundation::Uri link{ co_await e.DataView().GetWebLinkAsync() }; - _core->PasteText(link.AbsoluteUri()); + _core.PasteText(link.AbsoluteUri()); } CATCH_LOG(); } @@ -2187,7 +2186,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation try { auto text{ co_await e.DataView().GetTextAsync() }; - _core->PasteText(text); + _core.PasteText(text); } CATCH_LOG(); } @@ -2228,7 +2227,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation allPaths += fullPath; } - _core->PasteText(winrt::hstring{ allPaths }); + _core.PasteText(winrt::hstring{ allPaths }); } } } @@ -2323,7 +2322,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation { // It's already loaded if we get here, so just hide it. RendererFailedNotice().Visibility(Visibility::Collapsed); - _core->ResumeRendering(); + _core.ResumeRendering(); } IControlSettings TermControl::Settings() const @@ -2337,7 +2336,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation // hypothetical future where we allow an application to set the tab // color with VT sequences like they're currently allowed to with the // title. - return _core->TabColor(); + return _core.TabColor(); } // Method Description: @@ -2346,7 +2345,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation // - The taskbar state of this control const size_t TermControl::TaskbarState() const noexcept { - return _core->TaskbarState(); + return _core.TaskbarState(); } // Method Description: @@ -2355,7 +2354,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation // - The taskbar progress of this control const size_t TermControl::TaskbarProgress() const noexcept { - return _core->TaskbarProgress(); + return _core.TaskbarProgress(); } // Method Description: @@ -2364,15 +2363,15 @@ namespace winrt::Microsoft::Terminal::Control::implementation // - True if the mode is read-only bool TermControl::ReadOnly() const noexcept { - return _core->IsInReadOnlyMode(); + return _core.IsInReadOnlyMode(); } // Method Description: // - Toggles the read-only flag, raises event describing the value change void TermControl::ToggleReadOnly() { - _core->ToggleReadOnlyMode(); - _ReadOnlyChangedHandlers(*this, winrt::box_value(_core->IsInReadOnlyMode())); + _core.ToggleReadOnlyMode(); + _ReadOnlyChangedHandlers(*this, winrt::box_value(_core.IsInReadOnlyMode())); } // Method Description: @@ -2383,7 +2382,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation // - args: event data void TermControl::_PointerExitedHandler(Windows::Foundation::IInspectable const& /*sender*/, Windows::UI::Xaml::Input::PointerRoutedEventArgs const& /*e*/) { - _core->UpdateHoveredCell(std::nullopt); + _core.UpdateHoveredCell(std::nullopt); } winrt::fire_and_forget TermControl::_hoveredHyperlinkChanged(IInspectable sender, @@ -2393,10 +2392,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation co_await resume_foreground(Dispatcher()); if (auto self{ weakThis.get() }) { - auto lastHoveredCell = _core->GetHoveredCell(); + auto lastHoveredCell = _core.GetHoveredCell(); if (lastHoveredCell.has_value()) { - const auto uriText = _core->GetHoveredUriText(); + const auto uriText = _core.GetHoveredUriText(); if (!uriText.empty()) { // Update the tooltip with the URI @@ -2412,7 +2411,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation // Compute the location of the top left corner of the cell in DIPS const til::size marginsInDips{ til::math::rounding, GetPadding().Left, GetPadding().Top }; const til::point startPos{ *lastHoveredCell }; - const til::size fontSize{ _core->GetFont().GetSize() }; + const til::size fontSize{ til::math::rounding, _core.FontSize() }; const til::point posInPixels{ startPos * fontSize }; const til::point posInDIPs{ posInPixels / SwapChainPanel().CompositionScaleX() }; const til::point locationInDIPs{ posInDIPs + marginsInDips }; diff --git a/src/cascadia/TerminalControl/TermControl.h b/src/cascadia/TerminalControl/TermControl.h index 8f1b3ee2fef..6ba380d365d 100644 --- a/src/cascadia/TerminalControl/TermControl.h +++ b/src/cascadia/TerminalControl/TermControl.h @@ -108,11 +108,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation // clang-format off WINRT_CALLBACK(FontSizeChanged, Control::FontSizeChangedEventArgs); - FORWARDED_TYPED_EVENT(CopyToClipboard, IInspectable, Control::CopyToClipboardEventArgs, _core, CopyToClipboard); - FORWARDED_TYPED_EVENT(TitleChanged, IInspectable, Control::TitleChangedEventArgs, _core, TitleChanged); - FORWARDED_TYPED_EVENT(TabColorChanged, IInspectable, IInspectable, _core, TabColorChanged); - FORWARDED_TYPED_EVENT(SetTaskbarProgress, IInspectable, IInspectable, _core, TaskbarProgressChanged); - FORWARDED_TYPED_EVENT(ConnectionStateChanged, IInspectable, IInspectable, _core, ConnectionStateChanged); + PROJECTED_FORWARDED_TYPED_EVENT(CopyToClipboard, IInspectable, Control::CopyToClipboardEventArgs, _core, CopyToClipboard); + PROJECTED_FORWARDED_TYPED_EVENT(TitleChanged, IInspectable, Control::TitleChangedEventArgs, _core, TitleChanged); + PROJECTED_FORWARDED_TYPED_EVENT(TabColorChanged, IInspectable, IInspectable, _core, TabColorChanged); + PROJECTED_FORWARDED_TYPED_EVENT(SetTaskbarProgress, IInspectable, IInspectable, _core, TaskbarProgressChanged); + PROJECTED_FORWARDED_TYPED_EVENT(ConnectionStateChanged, IInspectable, IInspectable, _core, ConnectionStateChanged); PROJECTED_FORWARDED_TYPED_EVENT(PasteFromClipboard, IInspectable, Control::PasteFromClipboardEventArgs, _interactivity, PasteFromClipboard); @@ -131,7 +131,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation private: friend struct TermControlT; // friend our parent so it can bind private event handlers - winrt::com_ptr _core{ nullptr }; + Control::ControlCore _core{ nullptr }; Control::ControlInteractivity _interactivity{ nullptr }; bool _initializedTerminal; From 42b970b7f22248bb17dd295011ce6a5ff5a064cf Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Fri, 30 Apr 2021 10:11:29 -0500 Subject: [PATCH 03/30] Totally upend the control AutomationPeer workings Now we have an InteractivityAutomationPeer, which acts like the implementation for TermControlAutomationPeer. TermControlAutomationPeer is still needed though, because it implements FrameworkElementAutomationPeer, which is needed to hook up the AP to the actual UIA tree. So we split up the work into two halves, the bit that should be done by the core (the ITextProvider, the IControlAccessibilityInfo), vs the stuff that needs to be in the control (FrameworkElementAutomationPeer). IUiaEventDispatcher should probably be in the control as well, but that's a problem for future us. --- src/cascadia/TerminalControl/ControlCore.cpp | 3 +- src/cascadia/TerminalControl/ControlCore.idl | 7 +- .../TerminalControl/ControlInteractivity.cpp | 65 ++++- .../TerminalControl/ControlInteractivity.h | 11 +- .../TerminalControl/ControlInteractivity.idl | 9 +- .../InteractivityAutomationPeer.cpp | 274 ++++++++++++++++++ .../InteractivityAutomationPeer.h | 71 +++++ .../InteractivityAutomationPeer.idl | 11 + src/cascadia/TerminalControl/TermControl.cpp | 46 +-- src/cascadia/TerminalControl/TermControl.h | 7 +- .../TermControlAutomationPeer.cpp | 159 +++++----- .../TermControlAutomationPeer.h | 35 ++- .../TerminalControlLib.vcxproj | 7 + src/cascadia/TerminalControl/pch.h | 2 + src/cascadia/TerminalCore/ICoreAppearance.idl | 6 + src/inc/til/rectangle.h | 16 + 16 files changed, 588 insertions(+), 141 deletions(-) create mode 100644 src/cascadia/TerminalControl/InteractivityAutomationPeer.cpp create mode 100644 src/cascadia/TerminalControl/InteractivityAutomationPeer.h create mode 100644 src/cascadia/TerminalControl/InteractivityAutomationPeer.idl diff --git a/src/cascadia/TerminalControl/ControlCore.cpp b/src/cascadia/TerminalControl/ControlCore.cpp index e909b013846..8490c3719db 100644 --- a/src/cascadia/TerminalControl/ControlCore.cpp +++ b/src/cascadia/TerminalControl/ControlCore.cpp @@ -897,8 +897,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation } winrt::hstring ControlCore::FontFaceName() const noexcept { - return GetFont().GetFaceName(); + return winrt::hstring{ GetFont().GetFaceName() }; } + uint16_t ControlCore::FontWeight() const noexcept { return static_cast(GetFont().GetWeight()); diff --git a/src/cascadia/TerminalControl/ControlCore.idl b/src/cascadia/TerminalControl/ControlCore.idl index 93020e114ab..c387ab9eb08 100644 --- a/src/cascadia/TerminalControl/ControlCore.idl +++ b/src/cascadia/TerminalControl/ControlCore.idl @@ -18,7 +18,6 @@ namespace Microsoft.Terminal.Control Boolean IsRightButtonDown; }; - [default_interface] runtimeclass ControlCore : ICoreState { ControlCore(IControlSettings settings, @@ -59,9 +58,9 @@ namespace Microsoft.Terminal.Control void ToggleShaderEffects(); void SetBackgroundOpacity(Double opacity); Microsoft.Terminal.Core.Color BackgroundColor(); - void Initialize(Double actualWidth, - Double actualHeight, - Double compositionScale); + Boolean Initialize(Double actualWidth, + Double actualHeight, + Double compositionScale); void Close(); void BlinkCursor(); void ResetFontSize(); diff --git a/src/cascadia/TerminalControl/ControlInteractivity.cpp b/src/cascadia/TerminalControl/ControlInteractivity.cpp index 76994f96935..e8f4c8e97ca 100644 --- a/src/cascadia/TerminalControl/ControlInteractivity.cpp +++ b/src/cascadia/TerminalControl/ControlInteractivity.cpp @@ -8,13 +8,15 @@ #include #include #include -#include #include #include "../../types/inc/GlyphWidth.hpp" #include "../../types/inc/Utils.hpp" #include "../../buffer/out/search.h" +#include "InteractivityAutomationPeer.h" + #include "ControlInteractivity.g.cpp" +#include "TermControl.h" using namespace ::Microsoft::Console::Types; using namespace ::Microsoft::Console::VirtualTerminal; @@ -46,9 +48,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation // _core->ScrollPositionChanged({ this, &ControlInteractivity::_coreScrollPositionChanged }); } - void ControlInteractivity::UpdateSettings() + void ControlInteractivity::UpdateSettings(const til::rectangle padding) { _updateSystemParameterSettings(); + + _lastPadding = padding; } void ControlInteractivity::Initialize() @@ -96,9 +100,24 @@ namespace winrt::Microsoft::Terminal::Control::implementation void ControlInteractivity::GainFocus() { + // GH#5421: Enable the UiaEngine before checking for the SearchBox + // That way, new selections are notified to automation clients. + if (_uiaEngine.get()) + { + THROW_IF_FAILED(_uiaEngine->Enable()); + } + _updateSystemParameterSettings(); } + void ControlInteractivity::LostFocus() + { + if (_uiaEngine.get()) + { + THROW_IF_FAILED(_uiaEngine->Disable()); + } + } + // Method Description // - Updates internal params based on system parameters void ControlInteractivity::_updateSystemParameterSettings() noexcept @@ -566,4 +585,46 @@ namespace winrt::Microsoft::Terminal::Control::implementation // Convert the location in pixels to characters within the current viewport. return til::point{ pixelPosition / fontSize }; } + + // Method Description: + // - Creates an automation peer for the Terminal Control, enabling accessibility on our control. + // Arguments: + // - None + // Return Value: + // - The automation peer for our control + Control::InteractivityAutomationPeer ControlInteractivity::OnCreateAutomationPeer() + try + { + // if (_initializedTerminal && !_closing) // only set up the automation peer if we're ready to go live + // { + // create a custom automation peer with this code pattern: + // (https://docs.microsoft.com/en-us/windows/uwp/design/accessibility/custom-automation-peers) + auto autoPeer = winrt::make_self(this); + + _uiaEngine = std::make_unique<::Microsoft::Console::Render::UiaEngine>(autoPeer.get()); + _core->AttachUiaEngine(_uiaEngine.get()); + return *autoPeer; + // } + // return nullptr; + } + catch (...) + { + LOG_CAUGHT_EXCEPTION(); + return nullptr; + } + + ::Microsoft::Console::Types::IUiaData* ControlInteractivity::GetUiaData() const + { + return _core->GetUiaData(); + } + + // hstring ControlInteractivity::GetProfileName() const + // { + // return _settings.ProfileName(); + // } + til::rectangle ControlInteractivity::GetPadding() const + { + return _lastPadding; + } + } diff --git a/src/cascadia/TerminalControl/ControlInteractivity.h b/src/cascadia/TerminalControl/ControlInteractivity.h index 83535bd7cc3..fcb7e1a35f8 100644 --- a/src/cascadia/TerminalControl/ControlInteractivity.h +++ b/src/cascadia/TerminalControl/ControlInteractivity.h @@ -38,10 +38,16 @@ namespace winrt::Microsoft::Terminal::Control::implementation TerminalConnection::ITerminalConnection connection); void GainFocus(); - void UpdateSettings(); + void LostFocus(); + void UpdateSettings(const til::rectangle padding); void Initialize(); Control::ControlCore GetCore(); + // hstring GetProfileName() const; + Control::InteractivityAutomationPeer OnCreateAutomationPeer(); + ::Microsoft::Console::Types::IUiaData* GetUiaData() const; + til::rectangle GetPadding() const; + #pragma region Input Methods void PointerPressed(Control::MouseButtonState buttonState, const unsigned int pointerUpdateKind, @@ -87,6 +93,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation unsigned int _rowsToScroll; double _internalScrollbarPosition{ 0.0 }; + til::rectangle _lastPadding; + std::unique_ptr<::Microsoft::Console::Render::UiaEngine> _uiaEngine; + // If this is set, then we assume we are in the middle of panning the // viewport via touch input. std::optional _touchAnchor; diff --git a/src/cascadia/TerminalControl/ControlInteractivity.idl b/src/cascadia/TerminalControl/ControlInteractivity.idl index 5856d7cf153..3300ab12900 100644 --- a/src/cascadia/TerminalControl/ControlInteractivity.idl +++ b/src/cascadia/TerminalControl/ControlInteractivity.idl @@ -5,6 +5,8 @@ import "ICoreState.idl"; import "IControlSettings.idl"; import "ControlCore.idl"; import "EventArgs.idl"; +import "InteractivityAutomationPeer.idl"; + namespace Microsoft.Terminal.Control { @@ -15,15 +17,17 @@ namespace Microsoft.Terminal.Control Microsoft.Terminal.TerminalConnection.ITerminalConnection connection); ControlCore GetCore(); - void UpdateSettings(); + void UpdateSettings(Microsoft.Terminal.Core.Padding padding); void Initialize(); void GainFocus(); + void LostFocus(); + + InteractivityAutomationPeer OnCreateAutomationPeer(); Boolean CopySelectionToClipboard(Boolean singleLine, Windows.Foundation.IReference formats); void RequestPasteTextFromClipboard(); void SetEndSelectionPoint(Microsoft.Terminal.Core.Point point); - void PointerPressed(MouseButtonState buttonState, UInt32 pointerUpdateKind, UInt64 timestamp, @@ -52,7 +56,6 @@ namespace Microsoft.Terminal.Control void UpdateScrollbar(Double newValue); - event Windows.Foundation.TypedEventHandler OpenHyperlink; event Windows.Foundation.TypedEventHandler ScrollPositionChanged; event Windows.Foundation.TypedEventHandler PasteFromClipboard; diff --git a/src/cascadia/TerminalControl/InteractivityAutomationPeer.cpp b/src/cascadia/TerminalControl/InteractivityAutomationPeer.cpp new file mode 100644 index 00000000000..4d39a01f76c --- /dev/null +++ b/src/cascadia/TerminalControl/InteractivityAutomationPeer.cpp @@ -0,0 +1,274 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +#include "pch.h" +#include +#include +#include "InteractivityAutomationPeer.h" +#include "InteractivityAutomationPeer.g.cpp" + +#include "XamlUiaTextRange.h" +#include "../types/UiaTracing.h" + +using namespace Microsoft::Console::Types; +using namespace winrt::Windows::UI::Xaml::Automation::Peers; +using namespace winrt::Windows::Graphics::Display; + +namespace UIA +{ + using ::ITextRangeProvider; + using ::SupportedTextSelection; +} + +namespace XamlAutomation +{ + using winrt::Windows::UI::Xaml::Automation::SupportedTextSelection; + using winrt::Windows::UI::Xaml::Automation::Provider::IRawElementProviderSimple; + using winrt::Windows::UI::Xaml::Automation::Provider::ITextRangeProvider; +} + +namespace winrt::Microsoft::Terminal::Control::implementation +{ + InteractivityAutomationPeer::InteractivityAutomationPeer(winrt::Microsoft::Terminal::Control::implementation::ControlInteractivity* owner) : + _interactivity{ owner } + { + THROW_IF_FAILED(::Microsoft::WRL::MakeAndInitialize<::Microsoft::Terminal::TermControlUiaProvider>(&_uiaProvider, _interactivity->GetUiaData(), this)); + }; + + // Method Description: + // - Signals the ui automation client that the terminal's selection has changed and should be updated + // Arguments: + // - + // Return Value: + // - + void InteractivityAutomationPeer::SignalSelectionChanged() + { + UiaTracing::Signal::SelectionChanged(); + Dispatcher().RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, [&]() { + // The event that is raised when the text selection is modified. + RaiseAutomationEvent(AutomationEvents::TextPatternOnTextSelectionChanged); + }); + } + + // Method Description: + // - Signals the ui automation client that the terminal's output has changed and should be updated + // Arguments: + // - + // Return Value: + // - + void InteractivityAutomationPeer::SignalTextChanged() + { + UiaTracing::Signal::TextChanged(); + Dispatcher().RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, [&]() { + // The event that is raised when textual content is modified. + RaiseAutomationEvent(AutomationEvents::TextPatternOnTextChanged); + }); + } + + // Method Description: + // - Signals the ui automation client that the cursor's state has changed and should be updated + // Arguments: + // - + // Return Value: + // - + void InteractivityAutomationPeer::SignalCursorChanged() + { + UiaTracing::Signal::CursorChanged(); + Dispatcher().RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, [&]() { + // The event that is raised when the text was changed in an edit control. + // Do NOT fire a TextEditTextChanged. Generally, an app on the other side + // will expect more information. Though you can dispatch that event + // on its own, it may result in a nullptr exception on the other side + // because no additional information was provided. Crashing the screen + // reader. + RaiseAutomationEvent(AutomationEvents::TextPatternOnTextSelectionChanged); + }); + } + + // hstring InteractivityAutomationPeer::GetClassNameCore() const + // { + // return L"TermControl"; + // } + + // AutomationControlType InteractivityAutomationPeer::GetAutomationControlTypeCore() const + // { + // return AutomationControlType::Text; + // } + + // hstring InteractivityAutomationPeer::GetLocalizedControlTypeCore() const + // { + // return RS_(L"TerminalControl_ControlType"); + // } + + // Windows::Foundation::IInspectable InteractivityAutomationPeer::GetPatternCore(PatternInterface patternInterface) const + // { + // switch (patternInterface) + // { + // case PatternInterface::Text: + // return *this; + // break; + // default: + // return nullptr; + // } + // } + + // AutomationOrientation InteractivityAutomationPeer::GetOrientationCore() const + // { + // return AutomationOrientation::Vertical; + // } + + // hstring InteractivityAutomationPeer::GetNameCore() const + // { + // // fallback to title if profile name is empty + // auto profileName = _interactivity->GetProfileName(); + // if (profileName.empty()) + // { + // return _interactivity->GetCore().Title(); + // } + // return profileName; + // } + + // hstring InteractivityAutomationPeer::GetHelpTextCore() const + // { + // return _interactivity->GetCore().Title(); + // } + + // AutomationLiveSetting InteractivityAutomationPeer::GetLiveSettingCore() const + // { + // return AutomationLiveSetting::Polite; + // } + +#pragma region ITextProvider + com_array InteractivityAutomationPeer::GetSelection() + { + SAFEARRAY* pReturnVal; + THROW_IF_FAILED(_uiaProvider->GetSelection(&pReturnVal)); + return WrapArrayOfTextRangeProviders(pReturnVal); + } + + com_array InteractivityAutomationPeer::GetVisibleRanges() + { + SAFEARRAY* pReturnVal; + THROW_IF_FAILED(_uiaProvider->GetVisibleRanges(&pReturnVal)); + return WrapArrayOfTextRangeProviders(pReturnVal); + } + + XamlAutomation::ITextRangeProvider InteractivityAutomationPeer::RangeFromChild(XamlAutomation::IRawElementProviderSimple childElement) + { + UIA::ITextRangeProvider* returnVal; + // ScreenInfoUiaProvider doesn't actually use parameter, so just pass in nullptr + THROW_IF_FAILED(_uiaProvider->RangeFromChild(/* IRawElementProviderSimple */ nullptr, + &returnVal)); + + auto parentProvider = this->ProviderFromPeer(*this); + auto xutr = winrt::make_self(returnVal, parentProvider); + return xutr.as(); + } + + XamlAutomation::ITextRangeProvider InteractivityAutomationPeer::RangeFromPoint(Windows::Foundation::Point screenLocation) + { + UIA::ITextRangeProvider* returnVal; + THROW_IF_FAILED(_uiaProvider->RangeFromPoint({ screenLocation.X, screenLocation.Y }, &returnVal)); + + auto parentProvider = this->ProviderFromPeer(*this); + auto xutr = winrt::make_self(returnVal, parentProvider); + return xutr.as(); + } + + XamlAutomation::ITextRangeProvider InteractivityAutomationPeer::DocumentRange() + { + UIA::ITextRangeProvider* returnVal; + THROW_IF_FAILED(_uiaProvider->get_DocumentRange(&returnVal)); + + auto parentProvider = this->ProviderFromPeer(*this); + auto xutr = winrt::make_self(returnVal, parentProvider); + return xutr.as(); + } + + XamlAutomation::SupportedTextSelection InteractivityAutomationPeer::SupportedTextSelection() + { + UIA::SupportedTextSelection returnVal; + THROW_IF_FAILED(_uiaProvider->get_SupportedTextSelection(&returnVal)); + return static_cast(returnVal); + } + +#pragma endregion + +#pragma region IControlAccessibilityInfo + COORD InteractivityAutomationPeer::GetFontSize() const + { + return til::size{ til::math::rounding, _interactivity->GetCore().FontSize() }; + } + + RECT InteractivityAutomationPeer::GetBounds() const + { + const auto padding = _interactivity->GetPadding(); + // TODO! Get this from the core + const til::size dimensions{ 100, 100 }; + const til::rectangle realBounds{ padding.origin(), dimensions }; + return realBounds; + // auto rect = GetBoundingRectangle(); + // return { + // gsl::narrow_cast(rect.X), + // gsl::narrow_cast(rect.Y), + // gsl::narrow_cast(rect.X + rect.Width), + // gsl::narrow_cast(rect.Y + rect.Height) + // }; + } + + HRESULT InteractivityAutomationPeer::GetHostUiaProvider(IRawElementProviderSimple** provider) + { + RETURN_HR_IF(E_INVALIDARG, provider == nullptr); + *provider = nullptr; + + return S_OK; + } + + RECT InteractivityAutomationPeer::GetPadding() const + { + return _interactivity->GetPadding(); + // return { + // gsl::narrow_cast(padding.Left), + // gsl::narrow_cast(padding.Top), + // gsl::narrow_cast(padding.Right), + // gsl::narrow_cast(padding.Bottom) + // }; + } + + double InteractivityAutomationPeer::GetScaleFactor() const + { + return DisplayInformation::GetForCurrentView().RawPixelsPerViewPixel(); + } + + void InteractivityAutomationPeer::ChangeViewport(const SMALL_RECT NewWindow) + { + _interactivity->UpdateScrollbar(NewWindow.Top); + } +#pragma endregion + + // Method Description: + // - extracts the UiaTextRanges from the SAFEARRAY and converts them to Xaml ITextRangeProviders + // Arguments: + // - SAFEARRAY of UIA::UiaTextRange (ITextRangeProviders) + // Return Value: + // - com_array of Xaml Wrapped UiaTextRange (ITextRangeProviders) + com_array InteractivityAutomationPeer::WrapArrayOfTextRangeProviders(SAFEARRAY* textRanges) + { + // transfer ownership of UiaTextRanges to this new vector + auto providers = SafeArrayToOwningVector<::Microsoft::Terminal::TermControlUiaTextRange>(textRanges); + int count = gsl::narrow(providers.size()); + + std::vector vec; + vec.reserve(count); + auto parentProvider = this->ProviderFromPeer(*this); + for (int i = 0; i < count; i++) + { + auto xutr = make_self(providers[i].detach(), parentProvider); + vec.emplace_back(xutr.as()); + } + + com_array result{ vec }; + + return result; + } +} diff --git a/src/cascadia/TerminalControl/InteractivityAutomationPeer.h b/src/cascadia/TerminalControl/InteractivityAutomationPeer.h new file mode 100644 index 00000000000..32d7796a187 --- /dev/null +++ b/src/cascadia/TerminalControl/InteractivityAutomationPeer.h @@ -0,0 +1,71 @@ +/*++ +Copyright (c) Microsoft Corporation +Licensed under the MIT license. + + +TODO! + +--*/ + +#pragma once + +#include "ControlInteractivity.h" +#include "InteractivityAutomationPeer.g.h" +#include "../types/TermControlUiaProvider.hpp" +#include "../types/IUiaEventDispatcher.h" +#include "../types/IControlAccessibilityInfo.h" + +namespace winrt::Microsoft::Terminal::Control::implementation +{ + struct InteractivityAutomationPeer : + public InteractivityAutomationPeerT, + ::Microsoft::Console::Types::IUiaEventDispatcher, + ::Microsoft::Console::Types::IControlAccessibilityInfo + { + public: + InteractivityAutomationPeer(Microsoft::Terminal::Control::implementation::ControlInteractivity* owner); + + // #pragma region FrameworkElementAutomationPeer + // hstring GetClassNameCore() const; + // Windows::UI::Xaml::Automation::Peers::AutomationControlType GetAutomationControlTypeCore() const; + // hstring GetLocalizedControlTypeCore() const; + // Windows::Foundation::IInspectable GetPatternCore(Windows::UI::Xaml::Automation::Peers::PatternInterface patternInterface) const; + // Windows::UI::Xaml::Automation::Peers::AutomationOrientation GetOrientationCore() const; + // hstring GetNameCore() const; + // hstring GetHelpTextCore() const; + // Windows::UI::Xaml::Automation::Peers::AutomationLiveSetting GetLiveSettingCore() const; + // #pragma endregion + +#pragma region IUiaEventDispatcher + void SignalSelectionChanged() override; + void SignalTextChanged() override; + void SignalCursorChanged() override; +#pragma endregion + +#pragma region ITextProvider Pattern + Windows::UI::Xaml::Automation::Provider::ITextRangeProvider RangeFromPoint(Windows::Foundation::Point screenLocation); + Windows::UI::Xaml::Automation::Provider::ITextRangeProvider RangeFromChild(Windows::UI::Xaml::Automation::Provider::IRawElementProviderSimple childElement); + com_array GetVisibleRanges(); + com_array GetSelection(); + Windows::UI::Xaml::Automation::SupportedTextSelection SupportedTextSelection(); + Windows::UI::Xaml::Automation::Provider::ITextRangeProvider DocumentRange(); +#pragma endregion + +#pragma region IControlAccessibilityInfo Pattern + // Inherited via IControlAccessibilityInfo + virtual COORD GetFontSize() const override; + virtual RECT GetBounds() const override; + virtual RECT GetPadding() const override; + virtual double GetScaleFactor() const override; + virtual void ChangeViewport(SMALL_RECT NewWindow) override; + virtual HRESULT GetHostUiaProvider(IRawElementProviderSimple** provider) override; +#pragma endregion + + // RECT GetBoundingRectWrapped(); + + private: + ::Microsoft::WRL::ComPtr<::Microsoft::Terminal::TermControlUiaProvider> _uiaProvider; + winrt::Microsoft::Terminal::Control::implementation::ControlInteractivity* _interactivity; + winrt::com_array WrapArrayOfTextRangeProviders(SAFEARRAY* textRanges); + }; +} diff --git a/src/cascadia/TerminalControl/InteractivityAutomationPeer.idl b/src/cascadia/TerminalControl/InteractivityAutomationPeer.idl new file mode 100644 index 00000000000..15b4c608e91 --- /dev/null +++ b/src/cascadia/TerminalControl/InteractivityAutomationPeer.idl @@ -0,0 +1,11 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +namespace Microsoft.Terminal.Control +{ + [default_interface] runtimeclass InteractivityAutomationPeer : + Windows.UI.Xaml.Automation.Peers.AutomationPeer, + Windows.UI.Xaml.Automation.Provider.ITextProvider + { + } +} diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index 986d1bdb61e..fa600772ac0 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -8,7 +8,6 @@ #include #include #include -#include #include #include "../../types/inc/GlyphWidth.hpp" #include "../../types/inc/Utils.hpp" @@ -399,7 +398,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation _changeBackgroundColor(bg); // Apply padding as swapChainPanel's margin - auto newMargin = _ParseThicknessFromPadding(newSettings.Padding()); + auto newMargin = ParseThicknessFromPadding(newSettings.Padding()); SwapChainPanel().Margin(newMargin); TSFInputControl().Margin(newMargin); @@ -420,7 +419,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation ScrollBar().Visibility(Visibility::Visible); } - _interactivity.UpdateSettings(); + _interactivity.UpdateSettings(winrt::Microsoft::Terminal::Core::Padding{ newMargin.Left, + newMargin.Top, + newMargin.Right, + newMargin.Bottom }); } // Method Description: @@ -525,37 +527,21 @@ namespace winrt::Microsoft::Terminal::Control::implementation // Return Value: // - The automation peer for our control Windows::UI::Xaml::Automation::Peers::AutomationPeer TermControl::OnCreateAutomationPeer() - try { if (_initializedTerminal && !_closing) // only set up the automation peer if we're ready to go live { - // create a custom automation peer with this code pattern: - // (https://docs.microsoft.com/en-us/windows/uwp/design/accessibility/custom-automation-peers) - auto autoPeer = winrt::make_self(this); - - _uiaEngine = std::make_unique<::Microsoft::Console::Render::UiaEngine>(autoPeer.get()); - _core.AttachUiaEngine(_uiaEngine.get()); + const auto& interactivityAutoPeer = _interactivity.OnCreateAutomationPeer(); + auto autoPeer = winrt::make_self(this, interactivityAutoPeer); return *autoPeer; } return nullptr; } - catch (...) - { - LOG_CAUGHT_EXCEPTION(); - return nullptr; - } - - ::Microsoft::Console::Types::IUiaData* TermControl::GetUiaData() const - { - return _core.GetUiaData(); - } // This is needed for TermControlAutomationPeer. We probably could find a // clever way around asking the core for this. til::point TermControl::GetFontSize() const { - const auto size = _core.FontSize(); - return til::point{ til::math::rounding, size.Width, size.Height }; + return til::point{ til::math::rounding, _core.FontSize() }; } const Windows::UI::Xaml::Thickness TermControl::GetPadding() @@ -1450,10 +1436,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation // GH#5421: Enable the UiaEngine before checking for the SearchBox // That way, new selections are notified to automation clients. - if (_uiaEngine.get()) - { - THROW_IF_FAILED(_uiaEngine->Enable()); - } + _interactivity.GainFocus(); // If the searchbox is focused, we don't want TSFInputControl to think // it has focus so it doesn't intercept IME input. We also don't want the @@ -1480,8 +1463,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation _blinkTimer.value().Start(); } - _interactivity.GainFocus(); - // Only update the appearance here if an unfocused config exists - // if an unfocused config does not exist then we never would have switched // appearances anyway so there's no need to switch back upon gaining focus @@ -1507,10 +1488,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation _focused = false; - if (_uiaEngine.get()) - { - THROW_IF_FAILED(_uiaEngine->Disable()); - } + _interactivity.LostFocus(); if (TSFInputControl() != nullptr) { @@ -1847,7 +1825,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation } double height = rows * fontSize.Y; - auto thickness = _ParseThicknessFromPadding(padding); + auto thickness = ParseThicknessFromPadding(padding); // GH#2061 - make sure to account for the size the padding _will be_ scaled to width += scale * (thickness.Left + thickness.Right); height += scale * (thickness.Top + thickness.Bottom); @@ -1954,7 +1932,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation // Four Double values provide independent padding for 4 sides of the bounding rectangle // Return Value: // - Windows::UI::Xaml::Thickness object - Windows::UI::Xaml::Thickness TermControl::_ParseThicknessFromPadding(const hstring padding) + Windows::UI::Xaml::Thickness TermControl::ParseThicknessFromPadding(const hstring padding) { const wchar_t singleCharDelim = L','; std::wstringstream tokenStream(padding.c_str()); diff --git a/src/cascadia/TerminalControl/TermControl.h b/src/cascadia/TerminalControl/TermControl.h index 6ba380d365d..cbb45cbcb74 100644 --- a/src/cascadia/TerminalControl/TermControl.h +++ b/src/cascadia/TerminalControl/TermControl.h @@ -84,7 +84,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation ~TermControl(); Windows::UI::Xaml::Automation::Peers::AutomationPeer OnCreateAutomationPeer(); - ::Microsoft::Console::Types::IUiaData* GetUiaData() const; + // ::Microsoft::Console::Types::IUiaData* GetUiaData() const; const Windows::UI::Xaml::Thickness GetPadding(); IControlSettings Settings() const; @@ -103,6 +103,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation static Control::MouseButtonState GetPressedMouseButtons(const winrt::Windows::UI::Input::PointerPoint point); static unsigned int GetPointerUpdateKind(const winrt::Windows::UI::Input::PointerPoint point); + static Windows::UI::Xaml::Thickness ParseThicknessFromPadding(const hstring padding); // -------------------------------- WinRT Events --------------------------------- // clang-format off @@ -138,8 +139,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation winrt::com_ptr _searchBox; - std::unique_ptr<::Microsoft::Console::Render::UiaEngine> _uiaEngine; - IControlSettings _settings; bool _focused; std::atomic _closing; @@ -221,8 +220,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation void _TryStopAutoScroll(const uint32_t pointerId); void _UpdateAutoScroll(Windows::Foundation::IInspectable const& sender, Windows::Foundation::IInspectable const& e); - static Windows::UI::Xaml::Thickness _ParseThicknessFromPadding(const hstring padding); - void _KeyHandler(Windows::UI::Xaml::Input::KeyRoutedEventArgs const& e, const bool keyDown); ::Microsoft::Terminal::Core::ControlKeyStates _GetPressedModifierKeys() const; bool _TryHandleKeyBinding(const WORD vkey, const WORD scanCode, ::Microsoft::Terminal::Core::ControlKeyStates modifiers) const; diff --git a/src/cascadia/TerminalControl/TermControlAutomationPeer.cpp b/src/cascadia/TerminalControl/TermControlAutomationPeer.cpp index 6df09f3022d..09eb7fe6d06 100644 --- a/src/cascadia/TerminalControl/TermControlAutomationPeer.cpp +++ b/src/cascadia/TerminalControl/TermControlAutomationPeer.cpp @@ -30,12 +30,13 @@ namespace XamlAutomation namespace winrt::Microsoft::Terminal::Control::implementation { - TermControlAutomationPeer::TermControlAutomationPeer(winrt::Microsoft::Terminal::Control::implementation::TermControl* owner) : + TermControlAutomationPeer::TermControlAutomationPeer(TermControl* owner, + Control::InteractivityAutomationPeer impl) : TermControlAutomationPeerT(*owner), // pass owner to FrameworkElementAutomationPeer - _termControl{ owner } - { - THROW_IF_FAILED(::Microsoft::WRL::MakeAndInitialize<::Microsoft::Terminal::TermControlUiaProvider>(&_uiaProvider, _termControl->GetUiaData(), this)); - }; + _termControl{ _termControl }, + _implementation{ impl } { + // THROW_IF_FAILED(::Microsoft::WRL::MakeAndInitialize<::Microsoft::Terminal::TermControlUiaProvider>(&_uiaProvider, _interactivity->GetUiaData(), this)); + }; // Method Description: // - Signals the ui automation client that the terminal's selection has changed and should be updated @@ -143,104 +144,110 @@ namespace winrt::Microsoft::Terminal::Control::implementation #pragma region ITextProvider com_array TermControlAutomationPeer::GetSelection() { - SAFEARRAY* pReturnVal; - THROW_IF_FAILED(_uiaProvider->GetSelection(&pReturnVal)); - return WrapArrayOfTextRangeProviders(pReturnVal); + return _implementation.GetSelection(); + // SAFEARRAY* pReturnVal; + // THROW_IF_FAILED(_uiaProvider->GetSelection(&pReturnVal)); + // return WrapArrayOfTextRangeProviders(pReturnVal); } com_array TermControlAutomationPeer::GetVisibleRanges() { - SAFEARRAY* pReturnVal; - THROW_IF_FAILED(_uiaProvider->GetVisibleRanges(&pReturnVal)); - return WrapArrayOfTextRangeProviders(pReturnVal); + return _implementation.GetVisibleRanges(); + // SAFEARRAY* pReturnVal; + // THROW_IF_FAILED(_uiaProvider->GetVisibleRanges(&pReturnVal)); + // return WrapArrayOfTextRangeProviders(pReturnVal); } XamlAutomation::ITextRangeProvider TermControlAutomationPeer::RangeFromChild(XamlAutomation::IRawElementProviderSimple childElement) { - UIA::ITextRangeProvider* returnVal; - // ScreenInfoUiaProvider doesn't actually use parameter, so just pass in nullptr - THROW_IF_FAILED(_uiaProvider->RangeFromChild(/* IRawElementProviderSimple */ nullptr, - &returnVal)); - - auto parentProvider = this->ProviderFromPeer(*this); - auto xutr = winrt::make_self(returnVal, parentProvider); - return xutr.as(); + return _implementation.RangeFromChild(childElement); + // UIA::ITextRangeProvider* returnVal; + // // ScreenInfoUiaProvider doesn't actually use parameter, so just pass in nullptr + // THROW_IF_FAILED(_uiaProvider->RangeFromChild( IRawElementProviderSimple nullptr, + // &returnVal)); + + // auto parentProvider = this->ProviderFromPeer(*this); + // auto xutr = winrt::make_self(returnVal, parentProvider); + // return xutr.as(); } XamlAutomation::ITextRangeProvider TermControlAutomationPeer::RangeFromPoint(Windows::Foundation::Point screenLocation) { - UIA::ITextRangeProvider* returnVal; - THROW_IF_FAILED(_uiaProvider->RangeFromPoint({ screenLocation.X, screenLocation.Y }, &returnVal)); + return _implementation.RangeFromPoint(screenLocation); + // UIA::ITextRangeProvider* returnVal; + // THROW_IF_FAILED(_uiaProvider->RangeFromPoint({ screenLocation.X, screenLocation.Y }, &returnVal)); - auto parentProvider = this->ProviderFromPeer(*this); - auto xutr = winrt::make_self(returnVal, parentProvider); - return xutr.as(); + // auto parentProvider = this->ProviderFromPeer(*this); + // auto xutr = winrt::make_self(returnVal, parentProvider); + // return xutr.as(); } XamlAutomation::ITextRangeProvider TermControlAutomationPeer::DocumentRange() { - UIA::ITextRangeProvider* returnVal; - THROW_IF_FAILED(_uiaProvider->get_DocumentRange(&returnVal)); + return _implementation.DocumentRange(); + // UIA::ITextRangeProvider* returnVal; + // THROW_IF_FAILED(_uiaProvider->get_DocumentRange(&returnVal)); - auto parentProvider = this->ProviderFromPeer(*this); - auto xutr = winrt::make_self(returnVal, parentProvider); - return xutr.as(); + // auto parentProvider = this->ProviderFromPeer(*this); + // auto xutr = winrt::make_self(returnVal, parentProvider); + // return xutr.as(); } XamlAutomation::SupportedTextSelection TermControlAutomationPeer::SupportedTextSelection() { - UIA::SupportedTextSelection returnVal; - THROW_IF_FAILED(_uiaProvider->get_SupportedTextSelection(&returnVal)); - return static_cast(returnVal); + return _implementation.SupportedTextSelection(); + // UIA::SupportedTextSelection returnVal; + // THROW_IF_FAILED(_uiaProvider->get_SupportedTextSelection(&returnVal)); + // return static_cast(returnVal); } #pragma endregion #pragma region IControlAccessibilityInfo - COORD TermControlAutomationPeer::GetFontSize() const - { - return _termControl->GetFontSize(); - } - - RECT TermControlAutomationPeer::GetBounds() const - { - auto rect = GetBoundingRectangle(); - return { - gsl::narrow_cast(rect.X), - gsl::narrow_cast(rect.Y), - gsl::narrow_cast(rect.X + rect.Width), - gsl::narrow_cast(rect.Y + rect.Height) - }; - } - - HRESULT TermControlAutomationPeer::GetHostUiaProvider(IRawElementProviderSimple** provider) - { - RETURN_HR_IF(E_INVALIDARG, provider == nullptr); - *provider = nullptr; - - return S_OK; - } - - RECT TermControlAutomationPeer::GetPadding() const - { - auto padding = _termControl->GetPadding(); - return { - gsl::narrow_cast(padding.Left), - gsl::narrow_cast(padding.Top), - gsl::narrow_cast(padding.Right), - gsl::narrow_cast(padding.Bottom) - }; - } - - double TermControlAutomationPeer::GetScaleFactor() const - { - return DisplayInformation::GetForCurrentView().RawPixelsPerViewPixel(); - } - - void TermControlAutomationPeer::ChangeViewport(const SMALL_RECT NewWindow) - { - _termControl->ScrollViewport(NewWindow.Top); - } + // COORD TermControlAutomationPeer::GetFontSize() const + // { + // return til::size{ til::math::rounding, _interactivity->GetCore()->FontSize() }; + // } + + // RECT TermControlAutomationPeer::GetBounds() const + // { + // auto rect = GetBoundingRectangle(); + // return { + // gsl::narrow_cast(rect.X), + // gsl::narrow_cast(rect.Y), + // gsl::narrow_cast(rect.X + rect.Width), + // gsl::narrow_cast(rect.Y + rect.Height) + // }; + // } + + // HRESULT TermControlAutomationPeer::GetHostUiaProvider(IRawElementProviderSimple** provider) + // { + // RETURN_HR_IF(E_INVALIDARG, provider == nullptr); + // *provider = nullptr; + + // return S_OK; + // } + + // RECT TermControlAutomationPeer::GetPadding() const + // { + // return RECT{ _interactivity->GetPadding() }; + // // return { + // // gsl::narrow_cast(padding.Left), + // // gsl::narrow_cast(padding.Top), + // // gsl::narrow_cast(padding.Right), + // // gsl::narrow_cast(padding.Bottom) + // // }; + // } + + // double TermControlAutomationPeer::GetScaleFactor() const + // { + // return DisplayInformation::GetForCurrentView().RawPixelsPerViewPixel(); + // } + + // void TermControlAutomationPeer::ChangeViewport(const SMALL_RECT NewWindow) + // { + // _interactivity->UpdateScrollbar(NewWindow.Top); + // } #pragma endregion // Method Description: diff --git a/src/cascadia/TerminalControl/TermControlAutomationPeer.h b/src/cascadia/TerminalControl/TermControlAutomationPeer.h index 46a90073644..91a13fdffb1 100644 --- a/src/cascadia/TerminalControl/TermControlAutomationPeer.h +++ b/src/cascadia/TerminalControl/TermControlAutomationPeer.h @@ -25,8 +25,8 @@ Author(s): #pragma once #include "TermControl.h" +#include "ControlInteractivity.h" #include "TermControlAutomationPeer.g.h" -#include #include "../types/TermControlUiaProvider.hpp" #include "../types/IUiaEventDispatcher.h" #include "../types/IControlAccessibilityInfo.h" @@ -35,11 +35,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation { struct TermControlAutomationPeer : public TermControlAutomationPeerT, - ::Microsoft::Console::Types::IUiaEventDispatcher, - ::Microsoft::Console::Types::IControlAccessibilityInfo + ::Microsoft::Console::Types::IUiaEventDispatcher /*, + ::Microsoft::Console::Types::IControlAccessibilityInfo*/ { public: - TermControlAutomationPeer(Microsoft::Terminal::Control::implementation::TermControl* owner); + TermControlAutomationPeer(Microsoft::Terminal::Control::implementation::TermControl* owner, + Control::InteractivityAutomationPeer implementation); #pragma region FrameworkElementAutomationPeer hstring GetClassNameCore() const; @@ -67,21 +68,25 @@ namespace winrt::Microsoft::Terminal::Control::implementation Windows::UI::Xaml::Automation::Provider::ITextRangeProvider DocumentRange(); #pragma endregion -#pragma region IControlAccessibilityInfo Pattern - // Inherited via IControlAccessibilityInfo - virtual COORD GetFontSize() const override; - virtual RECT GetBounds() const override; - virtual RECT GetPadding() const override; - virtual double GetScaleFactor() const override; - virtual void ChangeViewport(SMALL_RECT NewWindow) override; - virtual HRESULT GetHostUiaProvider(IRawElementProviderSimple** provider) override; -#pragma endregion + // #pragma region IControlAccessibilityInfo Pattern + // // Inherited via IControlAccessibilityInfo + // virtual COORD GetFontSize() const override; + // virtual RECT GetBounds() const override; + // virtual RECT GetPadding() const override; + // virtual double GetScaleFactor() const override; + // virtual void ChangeViewport(SMALL_RECT NewWindow) override; + // virtual HRESULT GetHostUiaProvider(IRawElementProviderSimple** provider) override; + // #pragma endregion - RECT GetBoundingRectWrapped(); + // RECT GetBoundingRectWrapped(); private: - ::Microsoft::WRL::ComPtr<::Microsoft::Terminal::TermControlUiaProvider> _uiaProvider; + // ::Microsoft::WRL::ComPtr<::Microsoft::Terminal::TermControlUiaProvider> _uiaProvider; + // winrt::Microsoft::Terminal::Control::implementation::ControlInteractivity* _interactivity; + winrt::Microsoft::Terminal::Control::implementation::TermControl* _termControl; + Control::InteractivityAutomationPeer _implementation; + winrt::com_array WrapArrayOfTextRangeProviders(SAFEARRAY* textRanges); }; } diff --git a/src/cascadia/TerminalControl/TerminalControlLib.vcxproj b/src/cascadia/TerminalControl/TerminalControlLib.vcxproj index 5220de3e4d2..dc9d7b41dee 100644 --- a/src/cascadia/TerminalControl/TerminalControlLib.vcxproj +++ b/src/cascadia/TerminalControl/TerminalControlLib.vcxproj @@ -49,6 +49,9 @@ TermControlAutomationPeer.idl + + InteractivityAutomationPeer.idl + TSFInputControl.xaml @@ -86,6 +89,9 @@ TermControlAutomationPeer.idl + + InteractivityAutomationPeer.idl + @@ -106,6 +112,7 @@ TermControl.xaml + TSFInputControl.xaml diff --git a/src/cascadia/TerminalControl/pch.h b/src/cascadia/TerminalControl/pch.h index 83df9fdd5b5..e4170e98bc5 100644 --- a/src/cascadia/TerminalControl/pch.h +++ b/src/cascadia/TerminalControl/pch.h @@ -57,4 +57,6 @@ TRACELOGGING_DECLARE_PROVIDER(g_hTerminalControlProvider); #include +#include + #include "til.h" diff --git a/src/cascadia/TerminalCore/ICoreAppearance.idl b/src/cascadia/TerminalCore/ICoreAppearance.idl index ff6b16f4576..09d85c87b1d 100644 --- a/src/cascadia/TerminalCore/ICoreAppearance.idl +++ b/src/cascadia/TerminalCore/ICoreAppearance.idl @@ -36,6 +36,12 @@ namespace Microsoft.Terminal.Core { Int32 Value; }; + struct Padding { + Double Left; + Double Top; + Double Right; + Double Bottom; + }; declare { diff --git a/src/inc/til/rectangle.h b/src/inc/til/rectangle.h index 83bb0b3f11a..2c12e5958a2 100644 --- a/src/inc/til/rectangle.h +++ b/src/inc/til/rectangle.h @@ -875,6 +875,22 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned" } #endif +#ifdef WINRT_Microsoft_Terminal_Core_H + operator winrt::Microsoft::Terminal::Core::Padding() const noexcept + { + winrt::Microsoft::Terminal::Core::Padding ret; + THROW_HR_IF(E_ABORT, !base::MakeCheckedNum(left()).AssignIfValid(&ret.Left)); + THROW_HR_IF(E_ABORT, !base::MakeCheckedNum(top()).AssignIfValid(&ret.Top)); + THROW_HR_IF(E_ABORT, !base::MakeCheckedNum(right()).AssignIfValid(&ret.Right)); + THROW_HR_IF(E_ABORT, !base::MakeCheckedNum(bottom()).AssignIfValid(&ret.Bottom)); + return ret; + } + constexpr rectangle(const winrt::Microsoft::Terminal::Core::Padding& padding) : + rectangle(til::math::rounding, padding) + { + } +#endif + std::wstring to_string() const { return wil::str_printf(L"(L:%td, T:%td, R:%td, B:%td) [W:%td, H:%td]", left(), top(), right(), bottom(), width(), height()); From 4578c136a054a1efc50e99264a555547a909fda1 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Fri, 30 Apr 2021 10:20:11 -0500 Subject: [PATCH 04/30] some comments that should have been in the previous commit. 16 errors remain. --- .../TerminalControl/InteractivityAutomationPeer.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/cascadia/TerminalControl/InteractivityAutomationPeer.cpp b/src/cascadia/TerminalControl/InteractivityAutomationPeer.cpp index 4d39a01f76c..cc609d4ad6f 100644 --- a/src/cascadia/TerminalControl/InteractivityAutomationPeer.cpp +++ b/src/cascadia/TerminalControl/InteractivityAutomationPeer.cpp @@ -44,6 +44,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation void InteractivityAutomationPeer::SignalSelectionChanged() { UiaTracing::Signal::SelectionChanged(); + // TODO! We seemingly got Dispatcher() for free when we said we extended + // Windows.UI.Automation.Peers.AutomationPeer. This is suspect to me. + // This probably won't work when OOP. + Dispatcher().RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, [&]() { // The event that is raised when the text selection is modified. RaiseAutomationEvent(AutomationEvents::TextPatternOnTextSelectionChanged); @@ -59,6 +63,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation void InteractivityAutomationPeer::SignalTextChanged() { UiaTracing::Signal::TextChanged(); + // TODO! We seemingly got Dispatcher() for free when we said we extended + // Windows.UI.Automation.Peers.AutomationPeer. This is suspect to me. + // This probably won't work when OOP. + Dispatcher().RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, [&]() { // The event that is raised when textual content is modified. RaiseAutomationEvent(AutomationEvents::TextPatternOnTextChanged); @@ -74,6 +82,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation void InteractivityAutomationPeer::SignalCursorChanged() { UiaTracing::Signal::CursorChanged(); + // TODO! We seemingly got Dispatcher() for free when we said we extended + // Windows.UI.Automation.Peers.AutomationPeer. This is suspect to me. + // This probably won't work when OOP. + Dispatcher().RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, [&]() { // The event that is raised when the text was changed in an edit control. // Do NOT fire a TextEditTextChanged. Generally, an app on the other side From d8cc047a7ef39d93430bc724e8071e3568cd4dc6 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Fri, 30 Apr 2021 10:41:31 -0500 Subject: [PATCH 05/30] GetHoveredCell/UpdateHoveredCell. 12 remain. --- src/cascadia/TerminalControl/ControlCore.cpp | 10 +++++++--- src/cascadia/TerminalControl/ControlCore.h | 4 ++-- src/cascadia/TerminalControl/ControlCore.idl | 4 ++-- src/cascadia/TerminalControl/ControlInteractivity.cpp | 2 +- src/cascadia/TerminalControl/TermControl.cpp | 9 +++++---- 5 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/cascadia/TerminalControl/ControlCore.cpp b/src/cascadia/TerminalControl/ControlCore.cpp index 8490c3719db..23888afe2ce 100644 --- a/src/cascadia/TerminalControl/ControlCore.cpp +++ b/src/cascadia/TerminalControl/ControlCore.cpp @@ -420,8 +420,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation // - Updates last hovered cell, renders / removes rendering of hyper-link if required // Arguments: // - terminalPosition: The terminal position of the pointer - void ControlCore::UpdateHoveredCell(const std::optional& terminalPosition) + void ControlCore::UpdateHoveredCell(Windows::Foundation::IReference pos) { + auto terminalPosition = pos ? + std::optional{ pos.Value() } : + std::optional{}; + if (terminalPosition == _lastHoveredCell) { return; @@ -481,9 +485,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation return {}; } - std::optional ControlCore::GetHoveredCell() const + Windows::Foundation::IReference ControlCore::GetHoveredCell() const { - return _lastHoveredCell; + return _lastHoveredCell.has_value() ? Windows::Foundation::IReference(til::point{ _lastHoveredCell.value() }) : nullptr; } // Method Description: diff --git a/src/cascadia/TerminalControl/ControlCore.h b/src/cascadia/TerminalControl/ControlCore.h index 0d46ebde2fd..3bd0fa4fd2e 100644 --- a/src/cascadia/TerminalControl/ControlCore.h +++ b/src/cascadia/TerminalControl/ControlCore.h @@ -72,10 +72,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation void ResumeRendering(); void UpdatePatternLocations(); - void UpdateHoveredCell(const std::optional& terminalPosition); + void UpdateHoveredCell(Windows::Foundation::IReference terminalPosition); winrt::hstring GetHyperlink(const til::point position) const; winrt::hstring GetHoveredUriText() const; - std::optional GetHoveredCell() const; + Windows::Foundation::IReference GetHoveredCell() const; ::Microsoft::Console::Types::IUiaData* GetUiaData() const; diff --git a/src/cascadia/TerminalControl/ControlCore.idl b/src/cascadia/TerminalControl/ControlCore.idl index c387ab9eb08..b357214c2e9 100644 --- a/src/cascadia/TerminalControl/ControlCore.idl +++ b/src/cascadia/TerminalControl/ControlCore.idl @@ -32,8 +32,8 @@ namespace Microsoft.Terminal.Control // IDXGISwapChain1* GetSwapChain() const; // std::vector SelectedText(bool trimTrailingWhitespace) const; - // void UpdateHoveredCell(const std::optional& terminalPosition); - // std::optional GetHoveredCell() const; + void UpdateHoveredCell(Windows.Foundation.IReference terminalPosition); + Windows.Foundation.IReference GetHoveredCell(); Boolean TrySendKeyEvent(Int16 vkey, Int16 scanCode, diff --git a/src/cascadia/TerminalControl/ControlInteractivity.cpp b/src/cascadia/TerminalControl/ControlInteractivity.cpp index e8f4c8e97ca..3f5ea46469e 100644 --- a/src/cascadia/TerminalControl/ControlInteractivity.cpp +++ b/src/cascadia/TerminalControl/ControlInteractivity.cpp @@ -307,7 +307,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation SetEndSelectionPoint(pixelPosition); } - _core->UpdateHoveredCell(terminalPosition); + _core->UpdateHoveredCell(Windows::Foundation::IReference{ terminalPosition }); } void ControlInteractivity::TouchMoved(const til::point newTouchPoint, diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index fa600772ac0..36c264d2882 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -2358,9 +2358,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation // Arguments: // - sender: not used // - args: event data - void TermControl::_PointerExitedHandler(Windows::Foundation::IInspectable const& /*sender*/, Windows::UI::Xaml::Input::PointerRoutedEventArgs const& /*e*/) + void TermControl::_PointerExitedHandler(Windows::Foundation::IInspectable const& /*sender*/, + Windows::UI::Xaml::Input::PointerRoutedEventArgs const& /*e*/) { - _core.UpdateHoveredCell(std::nullopt); + _core.UpdateHoveredCell(nullptr); } winrt::fire_and_forget TermControl::_hoveredHyperlinkChanged(IInspectable sender, @@ -2371,7 +2372,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation if (auto self{ weakThis.get() }) { auto lastHoveredCell = _core.GetHoveredCell(); - if (lastHoveredCell.has_value()) + if (lastHoveredCell) { const auto uriText = _core.GetHoveredUriText(); if (!uriText.empty()) @@ -2388,7 +2389,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation // Compute the location of the top left corner of the cell in DIPS const til::size marginsInDips{ til::math::rounding, GetPadding().Left, GetPadding().Top }; - const til::point startPos{ *lastHoveredCell }; + const til::point startPos{ lastHoveredCell.Value() }; const til::size fontSize{ til::math::rounding, _core.FontSize() }; const til::point posInPixels{ startPos * fontSize }; const til::point posInDIPs{ posInPixels / SwapChainPanel().CompositionScaleX() }; From 21a97b6c80dd95cf3be84d9eb2070adc5956fa75 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Mon, 3 May 2021 09:20:06 -0500 Subject: [PATCH 06/30] Revert "Revert "Use DComp surface handle for Swap Chain management."" This reverts commit c113b65d9b15028281f6383909a73dba6af55bfc. That commit reverted 30b833547928d6dcbf88d49df0dbd5b3f6a7c879 --- src/cascadia/TerminalControl/ControlCore.cpp | 4 ++-- src/cascadia/TerminalControl/ControlCore.h | 2 +- src/cascadia/TerminalControl/TermControl.cpp | 12 +++++----- src/cascadia/TerminalControl/TermControl.h | 2 +- src/common.build.post.props | 2 +- src/renderer/dx/DxRenderer.cpp | 23 ++++++++++++++------ src/renderer/dx/DxRenderer.hpp | 3 ++- src/renderer/dx/precomp.h | 2 ++ 8 files changed, 31 insertions(+), 19 deletions(-) diff --git a/src/cascadia/TerminalControl/ControlCore.cpp b/src/cascadia/TerminalControl/ControlCore.cpp index 46775a70310..8f13c67f220 100644 --- a/src/cascadia/TerminalControl/ControlCore.cpp +++ b/src/cascadia/TerminalControl/ControlCore.cpp @@ -1191,7 +1191,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation } } - IDXGISwapChain1* ControlCore::GetSwapChain() const + HANDLE ControlCore::GetSwapChainHandle() const { // This is called by: // * TermControl::RenderEngineSwapChainChanged, who is only registered @@ -1199,7 +1199,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation // * TermControl::_InitializeTerminal, after the call to Initialize, for // _AttachDxgiSwapChainToXaml. // In both cases, we'll have a _renderEngine by then. - return _renderEngine->GetSwapChain().Get(); + return _renderEngine->GetSwapChainHandle(); } void ControlCore::_rendererWarning(const HRESULT hr) diff --git a/src/cascadia/TerminalControl/ControlCore.h b/src/cascadia/TerminalControl/ControlCore.h index 8ab58a2243d..6088275a1c0 100644 --- a/src/cascadia/TerminalControl/ControlCore.h +++ b/src/cascadia/TerminalControl/ControlCore.h @@ -49,7 +49,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation void UpdateAppearance(const IControlAppearance& newAppearance); void SizeChanged(const double width, const double height); void ScaleChanged(const double scale); - IDXGISwapChain1* GetSwapChain() const; + HANDLE GetSwapChainHandle() const; void AdjustFontSize(int fontSizeDelta); void ResetFontSize(); diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index 5346d0507c9..2d3b7f31742 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -578,8 +578,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation if (auto control{ weakThis.get() }) { - const auto chain = control->_core->GetSwapChain(); - _AttachDxgiSwapChainToXaml(chain); + const auto chainHandle = _core->GetSwapChainHandle(); + _AttachDxgiSwapChainToXaml(chainHandle); } } @@ -625,10 +625,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation } } - void TermControl::_AttachDxgiSwapChainToXaml(IDXGISwapChain1* swapChain) + void TermControl::_AttachDxgiSwapChainToXaml(HANDLE swapChainHandle) { - auto nativePanel = SwapChainPanel().as(); - nativePanel->SetSwapChain(swapChain); + auto nativePanel = SwapChainPanel().as(); + nativePanel->SetSwapChainHandle(swapChainHandle); } bool TermControl::_InitializeTerminal() @@ -666,7 +666,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation } _interactivity->Initialize(); - _AttachDxgiSwapChainToXaml(_core->GetSwapChain()); + _AttachDxgiSwapChainToXaml(_core->GetSwapChainHandle()); // Tell the DX Engine to notify us when the swap chain changes. We do // this after we initially set the swapchain so as to avoid unnecessary diff --git a/src/cascadia/TerminalControl/TermControl.h b/src/cascadia/TerminalControl/TermControl.h index 54fd49c37f2..ffca11119ff 100644 --- a/src/cascadia/TerminalControl/TermControl.h +++ b/src/cascadia/TerminalControl/TermControl.h @@ -66,7 +66,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation void ToggleShaderEffects(); winrt::fire_and_forget RenderEngineSwapChainChanged(IInspectable sender, IInspectable args); - void _AttachDxgiSwapChainToXaml(IDXGISwapChain1* swapChain); + void _AttachDxgiSwapChainToXaml(HANDLE swapChainHandle); winrt::fire_and_forget _RendererEnteredErrorState(IInspectable sender, IInspectable args); void _RenderRetryButton_Click(IInspectable const& button, IInspectable const& args); diff --git a/src/common.build.post.props b/src/common.build.post.props index e3e563b900d..c3b0d521215 100644 --- a/src/common.build.post.props +++ b/src/common.build.post.props @@ -13,7 +13,7 @@ ProgramDatabase - onecoreuap_apiset.lib;d3dcompiler.lib;dwmapi.lib;uxtheme.lib;shlwapi.lib;ntdll.lib;%(AdditionalDependencies) + onecoreuap_apiset.lib;d3dcompiler.lib;dwmapi.lib;uxtheme.lib;shlwapi.lib;ntdll.lib;dcomp.lib;%(AdditionalDependencies) diff --git a/src/renderer/dx/DxRenderer.cpp b/src/renderer/dx/DxRenderer.cpp index 1763f3c5b5a..77709d932f4 100644 --- a/src/renderer/dx/DxRenderer.cpp +++ b/src/renderer/dx/DxRenderer.cpp @@ -79,6 +79,7 @@ DxEngine::DxEngine() : _backgroundColor{ 0 }, _selectionBackground{}, _haveDeviceResources{ false }, + _swapChainHandle{ INVALID_HANDLE_VALUE }, _swapChainDesc{ 0 }, _swapChainFrameLatencyWaitableObject{ INVALID_HANDLE_VALUE }, _recreateDeviceRequested{ false }, @@ -618,6 +619,13 @@ try } case SwapChainMode::ForComposition: { + if (!_swapChainHandle) + { + RETURN_IF_FAILED(DCompositionCreateSurfaceHandle(GENERIC_ALL, nullptr, &_swapChainHandle)); + } + + RETURN_IF_FAILED(_dxgiFactory2.As(&_dxgiFactoryMedia)); + // Use the given target size for compositions. _swapChainDesc.Width = _displaySizePixels.width(); _swapChainDesc.Height = _displaySizePixels.height(); @@ -627,10 +635,11 @@ try // It's 100% required to use scaling mode stretch for composition. There is no other choice. _swapChainDesc.Scaling = DXGI_SCALING_STRETCH; - RETURN_IF_FAILED(_dxgiFactory2->CreateSwapChainForComposition(_d3dDevice.Get(), - &_swapChainDesc, - nullptr, - &_dxgiSwapChain)); + RETURN_IF_FAILED(_dxgiFactoryMedia->CreateSwapChainForCompositionSurfaceHandle(_d3dDevice.Get(), + _swapChainHandle.get(), + &_swapChainDesc, + nullptr, + &_dxgiSwapChain)); break; } default: @@ -1003,14 +1012,14 @@ try } CATCH_LOG() -Microsoft::WRL::ComPtr DxEngine::GetSwapChain() +HANDLE DxEngine::GetSwapChainHandle() { - if (_dxgiSwapChain.Get() == nullptr) + if (!_swapChainHandle) { THROW_IF_FAILED(_CreateDeviceResources(true)); } - return _dxgiSwapChain; + return _swapChainHandle.get(); } void DxEngine::_InvalidateRectangle(const til::rectangle& rc) diff --git a/src/renderer/dx/DxRenderer.hpp b/src/renderer/dx/DxRenderer.hpp index 7de6832146e..f4ae176c7e8 100644 --- a/src/renderer/dx/DxRenderer.hpp +++ b/src/renderer/dx/DxRenderer.hpp @@ -70,7 +70,7 @@ namespace Microsoft::Console::Render void SetSoftwareRendering(bool enable) noexcept; - ::Microsoft::WRL::ComPtr GetSwapChain(); + HANDLE GetSwapChainHandle(); // IRenderEngine Members [[nodiscard]] HRESULT Invalidate(const SMALL_RECT* const psrRegion) noexcept override; @@ -212,6 +212,7 @@ namespace Microsoft::Console::Render ::Microsoft::WRL::ComPtr _d2dBrushBackground; ::Microsoft::WRL::ComPtr _dxgiFactory2; + ::Microsoft::WRL::ComPtr _dxgiFactoryMedia; ::Microsoft::WRL::ComPtr _dxgiDevice; ::Microsoft::WRL::ComPtr _dxgiSurface; diff --git a/src/renderer/dx/precomp.h b/src/renderer/dx/precomp.h index 5715fd8fed3..d3d51af5f51 100644 --- a/src/renderer/dx/precomp.h +++ b/src/renderer/dx/precomp.h @@ -21,6 +21,8 @@ #include #include +#include + #include #include #include From 2e861d8a37886278e638c556b71e44943d6b64b7 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Mon, 3 May 2021 09:35:49 -0500 Subject: [PATCH 07/30] some minor cleanup --- src/renderer/dx/DxRenderer.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/renderer/dx/DxRenderer.hpp b/src/renderer/dx/DxRenderer.hpp index f4ae176c7e8..35985f655e4 100644 --- a/src/renderer/dx/DxRenderer.hpp +++ b/src/renderer/dx/DxRenderer.hpp @@ -128,8 +128,6 @@ namespace Microsoft::Console::Render void SetAntialiasingMode(const D2D1_TEXT_ANTIALIAS_MODE antialiasingMode) noexcept; void SetDefaultTextBackgroundOpacity(const float opacity) noexcept; - wil::unique_handle _swapChainHandle; - void UpdateHyperlinkHoveredId(const uint16_t hoveredId) noexcept; protected: @@ -184,6 +182,8 @@ namespace Microsoft::Console::Render static std::atomic _tracelogCount; + wil::unique_handle _swapChainHandle; + // Device-Independent Resources ::Microsoft::WRL::ComPtr _d2dFactory; From d667f3b63340b6db35a30e141c75bdecb6931ad0 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Mon, 3 May 2021 12:18:07 -0500 Subject: [PATCH 08/30] Use the HANDLE for the swapchainin the core projection --- src/cascadia/TerminalControl/ControlCore.cpp | 4 ++-- src/cascadia/TerminalControl/ControlCore.h | 2 +- src/cascadia/TerminalControl/ControlCore.idl | 2 +- src/cascadia/TerminalControl/TermControl.cpp | 8 ++------ 4 files changed, 6 insertions(+), 10 deletions(-) diff --git a/src/cascadia/TerminalControl/ControlCore.cpp b/src/cascadia/TerminalControl/ControlCore.cpp index b5e2f84fd88..3332776dd03 100644 --- a/src/cascadia/TerminalControl/ControlCore.cpp +++ b/src/cascadia/TerminalControl/ControlCore.cpp @@ -1213,7 +1213,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation } } - HANDLE ControlCore::GetSwapChainHandle() const + uint64_t ControlCore::GetSwapChainHandle() const { // This is called by: // * TermControl::RenderEngineSwapChainChanged, who is only registered @@ -1221,7 +1221,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation // * TermControl::_InitializeTerminal, after the call to Initialize, for // _AttachDxgiSwapChainToXaml. // In both cases, we'll have a _renderEngine by then. - return _renderEngine->GetSwapChainHandle(); + return reinterpret_cast(_renderEngine->GetSwapChainHandle()); } void ControlCore::_rendererWarning(const HRESULT hr) diff --git a/src/cascadia/TerminalControl/ControlCore.h b/src/cascadia/TerminalControl/ControlCore.h index a8c8904f162..e3cebd50907 100644 --- a/src/cascadia/TerminalControl/ControlCore.h +++ b/src/cascadia/TerminalControl/ControlCore.h @@ -49,7 +49,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation void UpdateAppearance(const IControlAppearance& newAppearance); void SizeChanged(const double width, const double height); void ScaleChanged(const double scale); - HANDLE GetSwapChainHandle() const; + uint64_t GetSwapChainHandle() const; void AdjustFontSize(int fontSizeDelta); void ResetFontSize(); diff --git a/src/cascadia/TerminalControl/ControlCore.idl b/src/cascadia/TerminalControl/ControlCore.idl index b357214c2e9..0b348965b7e 100644 --- a/src/cascadia/TerminalControl/ControlCore.idl +++ b/src/cascadia/TerminalControl/ControlCore.idl @@ -30,7 +30,7 @@ namespace Microsoft.Terminal.Control String FontFaceName { get; }; UInt16 FontWeight { get; }; - // IDXGISwapChain1* GetSwapChain() const; + UInt64 GetSwapChainHandle(); // std::vector SelectedText(bool trimTrailingWhitespace) const; void UpdateHoveredCell(Windows.Foundation.IReference terminalPosition); Windows.Foundation.IReference GetHoveredCell(); diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index 7d0a393f672..cd54f85d5e5 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -565,7 +565,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation if (auto control{ weakThis.get() }) { - const auto chainHandle = control->_core.GetSwapChainHandle(); + const HANDLE chainHandle = reinterpret_cast(control->_core.GetSwapChainHandle()); _AttachDxgiSwapChainToXaml(chainHandle); } } @@ -653,11 +653,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation } _interactivity.Initialize(); -<<<<<<< HEAD - _AttachDxgiSwapChainToXaml(_core.GetSwapChain()); -======= - _AttachDxgiSwapChainToXaml(_core->GetSwapChainHandle()); ->>>>>>> dev/migrie/f/oop/use-dcomp-handle + _AttachDxgiSwapChainToXaml(reinterpret_cast(_core.GetSwapChainHandle())); // Tell the DX Engine to notify us when the swap chain changes. We do // this after we initially set the swapchain so as to avoid unnecessary From 62cbf30782fd8439d755226c43ed7d366748aa94 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Mon, 3 May 2021 13:24:27 -0500 Subject: [PATCH 09/30] it builds and runs so I guess it's done now --- src/cascadia/TerminalControl/ControlCore.cpp | 11 +++++++++-- src/cascadia/TerminalControl/ControlCore.h | 2 +- src/cascadia/TerminalControl/ControlCore.idl | 1 + src/cascadia/TerminalControl/TermControl.cpp | 15 ++++++++++----- src/cascadia/TerminalControl/TermControl.h | 2 +- 5 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/cascadia/TerminalControl/ControlCore.cpp b/src/cascadia/TerminalControl/ControlCore.cpp index 3332776dd03..16584c36a93 100644 --- a/src/cascadia/TerminalControl/ControlCore.cpp +++ b/src/cascadia/TerminalControl/ControlCore.cpp @@ -1091,10 +1091,17 @@ namespace winrt::Microsoft::Terminal::Control::implementation return _settings.CopyOnSelect(); } - std::vector ControlCore::SelectedText(bool trimTrailingWhitespace) const + Windows::Foundation::Collections::IVector ControlCore::SelectedText(bool trimTrailingWhitespace) const { // RetrieveSelectedTextFromBuffer will lock while it's reading - return _terminal->RetrieveSelectedTextFromBuffer(trimTrailingWhitespace).text; + std::vector internalResult{ _terminal->RetrieveSelectedTextFromBuffer(trimTrailingWhitespace).text }; + + auto result = winrt::single_threaded_vector(); + for (const auto& row : internalResult) + { + result.Append(winrt::hstring{ row }); + } + return result; } ::Microsoft::Console::Types::IUiaData* ControlCore::GetUiaData() const diff --git a/src/cascadia/TerminalControl/ControlCore.h b/src/cascadia/TerminalControl/ControlCore.h index e3cebd50907..19a4173a228 100644 --- a/src/cascadia/TerminalControl/ControlCore.h +++ b/src/cascadia/TerminalControl/ControlCore.h @@ -124,7 +124,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation bool HasSelection() const; bool CopyOnSelect() const; - std::vector SelectedText(bool trimTrailingWhitespace) const; + Windows::Foundation::Collections::IVector SelectedText(bool trimTrailingWhitespace) const; void SetSelectionAnchor(til::point const& position); void SetEndSelectionPoint(til::point const& position); diff --git a/src/cascadia/TerminalControl/ControlCore.idl b/src/cascadia/TerminalControl/ControlCore.idl index 0b348965b7e..f47f55b64d2 100644 --- a/src/cascadia/TerminalControl/ControlCore.idl +++ b/src/cascadia/TerminalControl/ControlCore.idl @@ -32,6 +32,7 @@ namespace Microsoft.Terminal.Control UInt64 GetSwapChainHandle(); // std::vector SelectedText(bool trimTrailingWhitespace) const; + IVector SelectedText(Boolean trimTrailingWhitespace); void UpdateHoveredCell(Windows.Foundation.IReference terminalPosition); Windows.Foundation.IReference GetHoveredCell(); diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index cd54f85d5e5..a660fcb031c 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -190,10 +190,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation // Empirically, multi-line selection works as well on sample scenarios, // but since code paths differ, extra work is required to ensure correctness. auto bufferText = _core.SelectedText(true); - if (bufferText.size() == 1) + if (bufferText.Size() == 1) { - const auto selectedLine{ til::at(bufferText, 0) }; - _searchBox->PopulateTextbox(selectedLine.data()); + const auto selectedLine{ bufferText.GetAt(0) }; + _searchBox->PopulateTextbox(selectedLine); } } @@ -541,7 +541,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation // clever way around asking the core for this. til::point TermControl::GetFontSize() const { - return til::point{ til::math::rounding, _core.FontSize() }; + return til::point{ til::math::rounding, _core.FontSize().Width, _core.FontSize().Height }; } const Windows::UI::Xaml::Thickness TermControl::GetPadding() @@ -1715,7 +1715,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation ScrollBar().Value(viewTop); } - int TermControl::ScrollOffset() + int TermControl::ScrollOffset() const { return _core.ScrollOffset(); } @@ -1729,6 +1729,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation return _core.ViewHeight(); } + int TermControl::BufferHeight() const + { + return _core.BufferHeight(); + } + // Function Description: // - Determines how much space (in pixels) an app would need to reserve to // create a control with the settings stored in the settings param. This diff --git a/src/cascadia/TerminalControl/TermControl.h b/src/cascadia/TerminalControl/TermControl.h index 4885dc5af8b..4feae86ad78 100644 --- a/src/cascadia/TerminalControl/TermControl.h +++ b/src/cascadia/TerminalControl/TermControl.h @@ -49,7 +49,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation TerminalConnection::ConnectionState ConnectionState() const; - int ScrollOffset(); + int ScrollOffset() const; int ViewHeight() const; int BufferHeight() const; From 445bdf6cad73f7cec15d8bd32567d7aec9a5da94 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Thu, 6 May 2021 10:00:29 -0500 Subject: [PATCH 10/30] Do the delayload dance --- src/common.build.post.props | 2 +- src/renderer/dx/DxRenderer.cpp | 25 ++++++++++++++++++++++++- src/renderer/dx/DxRenderer.hpp | 2 ++ 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/common.build.post.props b/src/common.build.post.props index c3b0d521215..e3e563b900d 100644 --- a/src/common.build.post.props +++ b/src/common.build.post.props @@ -13,7 +13,7 @@ ProgramDatabase - onecoreuap_apiset.lib;d3dcompiler.lib;dwmapi.lib;uxtheme.lib;shlwapi.lib;ntdll.lib;dcomp.lib;%(AdditionalDependencies) + onecoreuap_apiset.lib;d3dcompiler.lib;dwmapi.lib;uxtheme.lib;shlwapi.lib;ntdll.lib;%(AdditionalDependencies) diff --git a/src/renderer/dx/DxRenderer.cpp b/src/renderer/dx/DxRenderer.cpp index 77709d932f4..1033c44d49c 100644 --- a/src/renderer/dx/DxRenderer.cpp +++ b/src/renderer/dx/DxRenderer.cpp @@ -479,6 +479,29 @@ void DxEngine::_ComputePixelShaderSettings() noexcept } } +// Method Description: +// - Use DCompositionCreateSurfaceHandle to create a swapchain handle. This API +// is only present in Windows 8.1+, so we need to delay-load it to make sure +// we can still load on Windows 7. +// - We can't actually hit this on Windows 7, because only the WPF control uses +// us on Windows 7, and they're using the ForHwnd path, which doesn't hit this +// at all. +// Arguments: +// - +// Return Value: +// - An HRESULT for failing to load dcomp.dll, or failing to find the API, or an +// actual failure from the API itself. +[[nodiscard]] HRESULT DxEngine::_CreateSurfaceHandle() noexcept +{ + wil::unique_hmodule hDComp{ LoadLibraryEx(L"Dcomp.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32) }; + RETURN_LAST_ERROR_IF(hDComp.get() == nullptr); + + auto fn = GetProcAddressByFunctionDeclaration(hDComp.get(), DCompositionCreateSurfaceHandle); + RETURN_LAST_ERROR_IF(fn == nullptr); + + return fn(GENERIC_ALL, nullptr, &_swapChainHandle); +} + // Routine Description; // - Creates device-specific resources required for drawing // which generally means those that are represented on the GPU and can @@ -621,7 +644,7 @@ try { if (!_swapChainHandle) { - RETURN_IF_FAILED(DCompositionCreateSurfaceHandle(GENERIC_ALL, nullptr, &_swapChainHandle)); + RETURN_IF_FAILED(_CreateSurfaceHandle()); } RETURN_IF_FAILED(_dxgiFactory2.As(&_dxgiFactoryMedia)); diff --git a/src/renderer/dx/DxRenderer.hpp b/src/renderer/dx/DxRenderer.hpp index 35985f655e4..cbd34ea3b78 100644 --- a/src/renderer/dx/DxRenderer.hpp +++ b/src/renderer/dx/DxRenderer.hpp @@ -271,6 +271,8 @@ namespace Microsoft::Console::Render } _pixelShaderSettings; [[nodiscard]] HRESULT _CreateDeviceResources(const bool createSwapChain) noexcept; + [[nodiscard]] HRESULT _CreateSurfaceHandle() noexcept; + bool _HasTerminalEffects() const noexcept; std::string _LoadPixelShaderFile() const; HRESULT _SetupTerminalEffects(); From a1ce7cb0773f62341712151250885b27f9ac7a59 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Fri, 7 May 2021 05:41:03 -0500 Subject: [PATCH 11/30] What a ridiculous hack --- src/cascadia/TerminalControl/ControlCore.idl | 6 +++--- src/cascadia/TerminalControl/ControlInteractivity.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cascadia/TerminalControl/ControlCore.idl b/src/cascadia/TerminalControl/ControlCore.idl index f47f55b64d2..95fd3943b7c 100644 --- a/src/cascadia/TerminalControl/ControlCore.idl +++ b/src/cascadia/TerminalControl/ControlCore.idl @@ -13,9 +13,9 @@ namespace Microsoft.Terminal.Control // but projectable. struct MouseButtonState { - Boolean IsLeftButtonDown; - Boolean IsMiddleButtonDown; - Boolean IsRightButtonDown; + Int32 IsLeftButtonDown; + Int32 IsMiddleButtonDown; + Int32 IsRightButtonDown; }; [default_interface] runtimeclass ControlCore : ICoreState diff --git a/src/cascadia/TerminalControl/ControlInteractivity.cpp b/src/cascadia/TerminalControl/ControlInteractivity.cpp index 3f5ea46469e..c64da5a06aa 100644 --- a/src/cascadia/TerminalControl/ControlInteractivity.cpp +++ b/src/cascadia/TerminalControl/ControlInteractivity.cpp @@ -32,7 +32,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation TerminalInput::MouseButtonState toInternalMouseState(const Control::MouseButtonState& state) { return TerminalInput::MouseButtonState{ - state.IsLeftButtonDown, state.IsMiddleButtonDown, state.IsRightButtonDown + state.IsLeftButtonDown != 0, state.IsMiddleButtonDown != 0, state.IsRightButtonDown != 0 }; } From 03fb764d58a22065235a20cc7c4471c8b3d3a91a Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Fri, 7 May 2021 05:52:12 -0500 Subject: [PATCH 12/30] fix accessibility --- src/cascadia/TerminalControl/TermControlAutomationPeer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cascadia/TerminalControl/TermControlAutomationPeer.cpp b/src/cascadia/TerminalControl/TermControlAutomationPeer.cpp index 09eb7fe6d06..3cf1efa50ab 100644 --- a/src/cascadia/TerminalControl/TermControlAutomationPeer.cpp +++ b/src/cascadia/TerminalControl/TermControlAutomationPeer.cpp @@ -33,7 +33,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation TermControlAutomationPeer::TermControlAutomationPeer(TermControl* owner, Control::InteractivityAutomationPeer impl) : TermControlAutomationPeerT(*owner), // pass owner to FrameworkElementAutomationPeer - _termControl{ _termControl }, + _termControl{ owner }, _implementation{ impl } { // THROW_IF_FAILED(::Microsoft::WRL::MakeAndInitialize<::Microsoft::Terminal::TermControlUiaProvider>(&_uiaProvider, _interactivity->GetUiaData(), this)); }; From 6e031e52578654f7571f63216426cad4c5975cbb Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Fri, 7 May 2021 10:51:55 -0500 Subject: [PATCH 13/30] I want to get the padding out of interactivity, but the control bounds are still wrong --- .../TerminalControl/ControlInteractivity.cpp | 34 ++++--- .../TerminalControl/ControlInteractivity.h | 5 +- .../TerminalControl/ControlInteractivity.idl | 2 +- .../InteractivityAutomationPeer.cpp | 76 ++++----------- .../InteractivityAutomationPeer.h | 36 ++++--- .../InteractivityAutomationPeer.idl | 3 + src/cascadia/TerminalControl/TermControl.cpp | 19 +++- src/cascadia/TerminalControl/TermControl.h | 2 + .../TermControlAutomationPeer.cpp | 94 +++---------------- .../TermControlAutomationPeer.h | 25 ++--- .../TermControlAutomationPeer.idl | 3 + src/cascadia/TerminalCore/ICoreAppearance.idl | 19 ++-- src/inc/til/rectangle.h | 8 ++ 13 files changed, 129 insertions(+), 197 deletions(-) diff --git a/src/cascadia/TerminalControl/ControlInteractivity.cpp b/src/cascadia/TerminalControl/ControlInteractivity.cpp index c64da5a06aa..46faecfb8e5 100644 --- a/src/cascadia/TerminalControl/ControlInteractivity.cpp +++ b/src/cascadia/TerminalControl/ControlInteractivity.cpp @@ -44,15 +44,20 @@ namespace winrt::Microsoft::Terminal::Control::implementation _selectionNeedsToBeCopied{ false } { _core = winrt::make_self(settings, connection); - - // _core->ScrollPositionChanged({ this, &ControlInteractivity::_coreScrollPositionChanged }); } - void ControlInteractivity::UpdateSettings(const til::rectangle padding) + // Method Description: + // - Updates our internal settings. These settings should be + // interactivity-specific. Right now, we primarily update _rowsToScroll + // with the current value of SPI_GETWHEELSCROLLLINES. + // Arguments: + // - + // Return Value: + // - + void ControlInteractivity::UpdateSettings() { _updateSystemParameterSettings(); - _lastPadding = padding; } void ControlInteractivity::Initialize() @@ -587,7 +592,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation } // Method Description: - // - Creates an automation peer for the Terminal Control, enabling accessibility on our control. + // - Creates an automation peer for the Terminal Control, enabling + // accessibility on our control. + // - Our implementation implements the ITextProvider pattern, and the + // IControlAccessibilityInfo, to connect to the UiaEngine, which must be + // attached to the core's renderer. + // - The TermControlAutomationPeer will connect this to the UI tree. // Arguments: // - None // Return Value: @@ -595,17 +605,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation Control::InteractivityAutomationPeer ControlInteractivity::OnCreateAutomationPeer() try { - // if (_initializedTerminal && !_closing) // only set up the automation peer if we're ready to go live - // { - // create a custom automation peer with this code pattern: - // (https://docs.microsoft.com/en-us/windows/uwp/design/accessibility/custom-automation-peers) auto autoPeer = winrt::make_self(this); _uiaEngine = std::make_unique<::Microsoft::Console::Render::UiaEngine>(autoPeer.get()); _core->AttachUiaEngine(_uiaEngine.get()); return *autoPeer; - // } - // return nullptr; } catch (...) { @@ -622,9 +626,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation // { // return _settings.ProfileName(); // } - til::rectangle ControlInteractivity::GetPadding() const - { - return _lastPadding; - } + // til::rectangle ControlInteractivity::GetPadding() const + // { + // return _lastPadding; + // } } diff --git a/src/cascadia/TerminalControl/ControlInteractivity.h b/src/cascadia/TerminalControl/ControlInteractivity.h index fcb7e1a35f8..ad441b6033d 100644 --- a/src/cascadia/TerminalControl/ControlInteractivity.h +++ b/src/cascadia/TerminalControl/ControlInteractivity.h @@ -39,14 +39,14 @@ namespace winrt::Microsoft::Terminal::Control::implementation void GainFocus(); void LostFocus(); - void UpdateSettings(const til::rectangle padding); + void UpdateSettings(/*const til::rectangle padding*/); void Initialize(); Control::ControlCore GetCore(); // hstring GetProfileName() const; Control::InteractivityAutomationPeer OnCreateAutomationPeer(); ::Microsoft::Console::Types::IUiaData* GetUiaData() const; - til::rectangle GetPadding() const; + // til::rectangle GetPadding() const; #pragma region Input Methods void PointerPressed(Control::MouseButtonState buttonState, @@ -93,7 +93,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation unsigned int _rowsToScroll; double _internalScrollbarPosition{ 0.0 }; - til::rectangle _lastPadding; std::unique_ptr<::Microsoft::Console::Render::UiaEngine> _uiaEngine; // If this is set, then we assume we are in the middle of panning the diff --git a/src/cascadia/TerminalControl/ControlInteractivity.idl b/src/cascadia/TerminalControl/ControlInteractivity.idl index 3300ab12900..a0fba34c334 100644 --- a/src/cascadia/TerminalControl/ControlInteractivity.idl +++ b/src/cascadia/TerminalControl/ControlInteractivity.idl @@ -17,7 +17,7 @@ namespace Microsoft.Terminal.Control Microsoft.Terminal.TerminalConnection.ITerminalConnection connection); ControlCore GetCore(); - void UpdateSettings(Microsoft.Terminal.Core.Padding padding); + void UpdateSettings(); void Initialize(); void GainFocus(); void LostFocus(); diff --git a/src/cascadia/TerminalControl/InteractivityAutomationPeer.cpp b/src/cascadia/TerminalControl/InteractivityAutomationPeer.cpp index cc609d4ad6f..c1ed5380211 100644 --- a/src/cascadia/TerminalControl/InteractivityAutomationPeer.cpp +++ b/src/cascadia/TerminalControl/InteractivityAutomationPeer.cpp @@ -35,6 +35,15 @@ namespace winrt::Microsoft::Terminal::Control::implementation THROW_IF_FAILED(::Microsoft::WRL::MakeAndInitialize<::Microsoft::Terminal::TermControlUiaProvider>(&_uiaProvider, _interactivity->GetUiaData(), this)); }; + void InteractivityAutomationPeer::SetControlBounds(const Windows::Foundation::Rect bounds) + { + _controlBounds = til::rectangle{ til::math::rounding, bounds }; + } + void InteractivityAutomationPeer::SetControlPadding(const Core::Padding padding) + { + _controlPadding = padding; + } + // Method Description: // - Signals the ui automation client that the terminal's selection has changed and should be updated // Arguments: @@ -97,59 +106,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation }); } - // hstring InteractivityAutomationPeer::GetClassNameCore() const - // { - // return L"TermControl"; - // } - - // AutomationControlType InteractivityAutomationPeer::GetAutomationControlTypeCore() const - // { - // return AutomationControlType::Text; - // } - - // hstring InteractivityAutomationPeer::GetLocalizedControlTypeCore() const - // { - // return RS_(L"TerminalControl_ControlType"); - // } - - // Windows::Foundation::IInspectable InteractivityAutomationPeer::GetPatternCore(PatternInterface patternInterface) const - // { - // switch (patternInterface) - // { - // case PatternInterface::Text: - // return *this; - // break; - // default: - // return nullptr; - // } - // } - - // AutomationOrientation InteractivityAutomationPeer::GetOrientationCore() const - // { - // return AutomationOrientation::Vertical; - // } - - // hstring InteractivityAutomationPeer::GetNameCore() const - // { - // // fallback to title if profile name is empty - // auto profileName = _interactivity->GetProfileName(); - // if (profileName.empty()) - // { - // return _interactivity->GetCore().Title(); - // } - // return profileName; - // } - - // hstring InteractivityAutomationPeer::GetHelpTextCore() const - // { - // return _interactivity->GetCore().Title(); - // } - - // AutomationLiveSetting InteractivityAutomationPeer::GetLiveSettingCore() const - // { - // return AutomationLiveSetting::Polite; - // } - #pragma region ITextProvider com_array InteractivityAutomationPeer::GetSelection() { @@ -214,11 +170,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation RECT InteractivityAutomationPeer::GetBounds() const { - const auto padding = _interactivity->GetPadding(); - // TODO! Get this from the core - const til::size dimensions{ 100, 100 }; - const til::rectangle realBounds{ padding.origin(), dimensions }; - return realBounds; + // const auto padding = _interactivity->GetPadding(); + // // TODO! Get this from the core + // const til::size dimensions{ 100, 100 }; + // const til::rectangle realBounds{ padding.origin(), dimensions }; + // return realBounds; // auto rect = GetBoundingRectangle(); // return { // gsl::narrow_cast(rect.X), @@ -226,6 +182,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation // gsl::narrow_cast(rect.X + rect.Width), // gsl::narrow_cast(rect.Y + rect.Height) // }; + return _controlBounds; } HRESULT InteractivityAutomationPeer::GetHostUiaProvider(IRawElementProviderSimple** provider) @@ -238,7 +195,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation RECT InteractivityAutomationPeer::GetPadding() const { - return _interactivity->GetPadding(); + return _controlPadding; + // return _interactivity->GetPadding(); // return { // gsl::narrow_cast(padding.Left), // gsl::narrow_cast(padding.Top), diff --git a/src/cascadia/TerminalControl/InteractivityAutomationPeer.h b/src/cascadia/TerminalControl/InteractivityAutomationPeer.h index 32d7796a187..61fae38bd11 100644 --- a/src/cascadia/TerminalControl/InteractivityAutomationPeer.h +++ b/src/cascadia/TerminalControl/InteractivityAutomationPeer.h @@ -2,8 +2,24 @@ Copyright (c) Microsoft Corporation Licensed under the MIT license. +Module Name: +- InteractivityAutomationPeer.h -TODO! +Abstract: +- This module provides UI Automation access to the ControlInteractivity, + to support both automation tests and accessibility (screen + reading) applications. +- See TermControlAutomationPeer for more details on how UIA is implemented. +- This is the primary implementation of the ITextProvider interface, for the + TermControlAutomationPeer. The TermControlAutomationPeer will be attached to + the actual UI tree, via FrameworkElementAutomationPeer. However, the + ControlInteractivity is totally oblivious to the UI tree that might be hosting + it. So this class implements the actual text pattern for the buffer, because + it has access to the buffer. TermControlAutomationPeer can then call the + methods on this class to expose the implemeentation in the actual UI tree. + +Author(s): +- Mike Griese (migrie), May 2021 --*/ @@ -25,16 +41,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation public: InteractivityAutomationPeer(Microsoft::Terminal::Control::implementation::ControlInteractivity* owner); - // #pragma region FrameworkElementAutomationPeer - // hstring GetClassNameCore() const; - // Windows::UI::Xaml::Automation::Peers::AutomationControlType GetAutomationControlTypeCore() const; - // hstring GetLocalizedControlTypeCore() const; - // Windows::Foundation::IInspectable GetPatternCore(Windows::UI::Xaml::Automation::Peers::PatternInterface patternInterface) const; - // Windows::UI::Xaml::Automation::Peers::AutomationOrientation GetOrientationCore() const; - // hstring GetNameCore() const; - // hstring GetHelpTextCore() const; - // Windows::UI::Xaml::Automation::Peers::AutomationLiveSetting GetLiveSettingCore() const; - // #pragma endregion + void SetControlBounds(const Windows::Foundation::Rect bounds); + void SetControlPadding(const Core::Padding padding); #pragma region IUiaEventDispatcher void SignalSelectionChanged() override; @@ -61,11 +69,13 @@ namespace winrt::Microsoft::Terminal::Control::implementation virtual HRESULT GetHostUiaProvider(IRawElementProviderSimple** provider) override; #pragma endregion - // RECT GetBoundingRectWrapped(); - private: ::Microsoft::WRL::ComPtr<::Microsoft::Terminal::TermControlUiaProvider> _uiaProvider; winrt::Microsoft::Terminal::Control::implementation::ControlInteractivity* _interactivity; + + til::rectangle _controlBounds; + til::rectangle _controlPadding; + winrt::com_array WrapArrayOfTextRangeProviders(SAFEARRAY* textRanges); }; } diff --git a/src/cascadia/TerminalControl/InteractivityAutomationPeer.idl b/src/cascadia/TerminalControl/InteractivityAutomationPeer.idl index 15b4c608e91..5bc887de270 100644 --- a/src/cascadia/TerminalControl/InteractivityAutomationPeer.idl +++ b/src/cascadia/TerminalControl/InteractivityAutomationPeer.idl @@ -7,5 +7,8 @@ namespace Microsoft.Terminal.Control Windows.UI.Xaml.Automation.Peers.AutomationPeer, Windows.UI.Xaml.Automation.Provider.ITextProvider { + + void SetControlBounds(Windows.Foundation.Rect bounds); + void SetControlPadding(Microsoft.Terminal.Core.Padding padding); } } diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index a660fcb031c..6b2e0db4b21 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -419,10 +419,14 @@ namespace winrt::Microsoft::Terminal::Control::implementation ScrollBar().Visibility(Visibility::Visible); } - _interactivity.UpdateSettings(winrt::Microsoft::Terminal::Core::Padding{ newMargin.Left, - newMargin.Top, - newMargin.Right, - newMargin.Bottom }); + _interactivity.UpdateSettings(); + if (auto ap{ _automationPeer.get() }) + { + ap.SetControlPadding(Core::Padding{ newMargin.Left, + newMargin.Top, + newMargin.Right, + newMargin.Bottom }); + } } // Method Description: @@ -532,6 +536,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation { const auto& interactivityAutoPeer = _interactivity.OnCreateAutomationPeer(); auto autoPeer = winrt::make_self(this, interactivityAutoPeer); + _automationPeer = winrt::weak_ref(*autoPeer); return *autoPeer; } return nullptr; @@ -1529,6 +1534,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation const auto newSize = e.NewSize(); _core.SizeChanged(newSize.Width, newSize.Height); + + if (auto ap{ _automationPeer.get() }) + { + auto controlOrigin{ ActualOffset() }; + ap.SetControlBounds(Windows::Foundation::Rect{ controlOrigin.x, controlOrigin.y, newSize.Width, newSize.Height }); + } } // Method Description: diff --git a/src/cascadia/TerminalControl/TermControl.h b/src/cascadia/TerminalControl/TermControl.h index 4feae86ad78..3988f2461ca 100644 --- a/src/cascadia/TerminalControl/TermControl.h +++ b/src/cascadia/TerminalControl/TermControl.h @@ -171,6 +171,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation winrt::Windows::UI::Xaml::Controls::SwapChainPanel::LayoutUpdated_revoker _layoutUpdatedRevoker; + winrt::weak_ref _automationPeer{ nullptr }; + void _UpdateSettingsFromUIThread(IControlSettings newSettings); void _UpdateAppearanceFromUIThread(IControlAppearance newAppearance); void _ApplyUISettings(const IControlSettings&); diff --git a/src/cascadia/TerminalControl/TermControlAutomationPeer.cpp b/src/cascadia/TerminalControl/TermControlAutomationPeer.cpp index 3cf1efa50ab..33edf94a25a 100644 --- a/src/cascadia/TerminalControl/TermControlAutomationPeer.cpp +++ b/src/cascadia/TerminalControl/TermControlAutomationPeer.cpp @@ -34,9 +34,21 @@ namespace winrt::Microsoft::Terminal::Control::implementation Control::InteractivityAutomationPeer impl) : TermControlAutomationPeerT(*owner), // pass owner to FrameworkElementAutomationPeer _termControl{ owner }, - _implementation{ impl } { - // THROW_IF_FAILED(::Microsoft::WRL::MakeAndInitialize<::Microsoft::Terminal::TermControlUiaProvider>(&_uiaProvider, _interactivity->GetUiaData(), this)); - }; + _implementation{ impl } + { + auto controlOrigin{ owner->ActualOffset() }; + auto controlSize{ owner->ActualSize() }; + impl.SetControlBounds(Windows::Foundation::Rect{ controlOrigin.x, controlOrigin.y, controlSize.x, controlSize.y }); + }; + + void TermControlAutomationPeer::SetControlBounds(const Windows::Foundation::Rect bounds) + { + _implementation.SetControlBounds(bounds); + } + void TermControlAutomationPeer::SetControlPadding(const Core::Padding padding) + { + _implementation.SetControlPadding(padding); + } // Method Description: // - Signals the ui automation client that the terminal's selection has changed and should be updated @@ -145,111 +157,35 @@ namespace winrt::Microsoft::Terminal::Control::implementation com_array TermControlAutomationPeer::GetSelection() { return _implementation.GetSelection(); - // SAFEARRAY* pReturnVal; - // THROW_IF_FAILED(_uiaProvider->GetSelection(&pReturnVal)); - // return WrapArrayOfTextRangeProviders(pReturnVal); } com_array TermControlAutomationPeer::GetVisibleRanges() { return _implementation.GetVisibleRanges(); - // SAFEARRAY* pReturnVal; - // THROW_IF_FAILED(_uiaProvider->GetVisibleRanges(&pReturnVal)); - // return WrapArrayOfTextRangeProviders(pReturnVal); } XamlAutomation::ITextRangeProvider TermControlAutomationPeer::RangeFromChild(XamlAutomation::IRawElementProviderSimple childElement) { return _implementation.RangeFromChild(childElement); - // UIA::ITextRangeProvider* returnVal; - // // ScreenInfoUiaProvider doesn't actually use parameter, so just pass in nullptr - // THROW_IF_FAILED(_uiaProvider->RangeFromChild( IRawElementProviderSimple nullptr, - // &returnVal)); - - // auto parentProvider = this->ProviderFromPeer(*this); - // auto xutr = winrt::make_self(returnVal, parentProvider); - // return xutr.as(); } XamlAutomation::ITextRangeProvider TermControlAutomationPeer::RangeFromPoint(Windows::Foundation::Point screenLocation) { return _implementation.RangeFromPoint(screenLocation); - // UIA::ITextRangeProvider* returnVal; - // THROW_IF_FAILED(_uiaProvider->RangeFromPoint({ screenLocation.X, screenLocation.Y }, &returnVal)); - - // auto parentProvider = this->ProviderFromPeer(*this); - // auto xutr = winrt::make_self(returnVal, parentProvider); - // return xutr.as(); } XamlAutomation::ITextRangeProvider TermControlAutomationPeer::DocumentRange() { return _implementation.DocumentRange(); - // UIA::ITextRangeProvider* returnVal; - // THROW_IF_FAILED(_uiaProvider->get_DocumentRange(&returnVal)); - - // auto parentProvider = this->ProviderFromPeer(*this); - // auto xutr = winrt::make_self(returnVal, parentProvider); - // return xutr.as(); } XamlAutomation::SupportedTextSelection TermControlAutomationPeer::SupportedTextSelection() { return _implementation.SupportedTextSelection(); - // UIA::SupportedTextSelection returnVal; - // THROW_IF_FAILED(_uiaProvider->get_SupportedTextSelection(&returnVal)); - // return static_cast(returnVal); } #pragma endregion -#pragma region IControlAccessibilityInfo - // COORD TermControlAutomationPeer::GetFontSize() const - // { - // return til::size{ til::math::rounding, _interactivity->GetCore()->FontSize() }; - // } - - // RECT TermControlAutomationPeer::GetBounds() const - // { - // auto rect = GetBoundingRectangle(); - // return { - // gsl::narrow_cast(rect.X), - // gsl::narrow_cast(rect.Y), - // gsl::narrow_cast(rect.X + rect.Width), - // gsl::narrow_cast(rect.Y + rect.Height) - // }; - // } - - // HRESULT TermControlAutomationPeer::GetHostUiaProvider(IRawElementProviderSimple** provider) - // { - // RETURN_HR_IF(E_INVALIDARG, provider == nullptr); - // *provider = nullptr; - - // return S_OK; - // } - - // RECT TermControlAutomationPeer::GetPadding() const - // { - // return RECT{ _interactivity->GetPadding() }; - // // return { - // // gsl::narrow_cast(padding.Left), - // // gsl::narrow_cast(padding.Top), - // // gsl::narrow_cast(padding.Right), - // // gsl::narrow_cast(padding.Bottom) - // // }; - // } - - // double TermControlAutomationPeer::GetScaleFactor() const - // { - // return DisplayInformation::GetForCurrentView().RawPixelsPerViewPixel(); - // } - - // void TermControlAutomationPeer::ChangeViewport(const SMALL_RECT NewWindow) - // { - // _interactivity->UpdateScrollbar(NewWindow.Top); - // } -#pragma endregion - // Method Description: // - extracts the UiaTextRanges from the SAFEARRAY and converts them to Xaml ITextRangeProviders // Arguments: diff --git a/src/cascadia/TerminalControl/TermControlAutomationPeer.h b/src/cascadia/TerminalControl/TermControlAutomationPeer.h index 91a13fdffb1..f8d704e3f0a 100644 --- a/src/cascadia/TerminalControl/TermControlAutomationPeer.h +++ b/src/cascadia/TerminalControl/TermControlAutomationPeer.h @@ -20,6 +20,10 @@ Module Name: Author(s): - Carlos Zamora (CaZamor) 2019 + +Modifications: +- May 2021: Pulled the core logic of ITextProvider implementation into the + InteractivityAutomationPeer, to support tab tear out. --*/ #pragma once @@ -35,13 +39,15 @@ namespace winrt::Microsoft::Terminal::Control::implementation { struct TermControlAutomationPeer : public TermControlAutomationPeerT, - ::Microsoft::Console::Types::IUiaEventDispatcher /*, - ::Microsoft::Console::Types::IControlAccessibilityInfo*/ + ::Microsoft::Console::Types::IUiaEventDispatcher { public: TermControlAutomationPeer(Microsoft::Terminal::Control::implementation::TermControl* owner, Control::InteractivityAutomationPeer implementation); + void SetControlBounds(const Windows::Foundation::Rect bounds); + void SetControlPadding(const Core::Padding padding); + #pragma region FrameworkElementAutomationPeer hstring GetClassNameCore() const; Windows::UI::Xaml::Automation::Peers::AutomationControlType GetAutomationControlTypeCore() const; @@ -68,22 +74,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation Windows::UI::Xaml::Automation::Provider::ITextRangeProvider DocumentRange(); #pragma endregion - // #pragma region IControlAccessibilityInfo Pattern - // // Inherited via IControlAccessibilityInfo - // virtual COORD GetFontSize() const override; - // virtual RECT GetBounds() const override; - // virtual RECT GetPadding() const override; - // virtual double GetScaleFactor() const override; - // virtual void ChangeViewport(SMALL_RECT NewWindow) override; - // virtual HRESULT GetHostUiaProvider(IRawElementProviderSimple** provider) override; - // #pragma endregion - - // RECT GetBoundingRectWrapped(); - private: - // ::Microsoft::WRL::ComPtr<::Microsoft::Terminal::TermControlUiaProvider> _uiaProvider; - // winrt::Microsoft::Terminal::Control::implementation::ControlInteractivity* _interactivity; - winrt::Microsoft::Terminal::Control::implementation::TermControl* _termControl; Control::InteractivityAutomationPeer _implementation; diff --git a/src/cascadia/TerminalControl/TermControlAutomationPeer.idl b/src/cascadia/TerminalControl/TermControlAutomationPeer.idl index 0d777b09a51..c41eecb9c46 100644 --- a/src/cascadia/TerminalControl/TermControlAutomationPeer.idl +++ b/src/cascadia/TerminalControl/TermControlAutomationPeer.idl @@ -9,5 +9,8 @@ namespace Microsoft.Terminal.Control Windows.UI.Xaml.Automation.Peers.FrameworkElementAutomationPeer, Windows.UI.Xaml.Automation.Provider.ITextProvider { + + void SetControlBounds(Windows.Foundation.Rect bounds); + void SetControlPadding(Microsoft.Terminal.Core.Padding padding); } } diff --git a/src/cascadia/TerminalCore/ICoreAppearance.idl b/src/cascadia/TerminalCore/ICoreAppearance.idl index 09d85c87b1d..52d4db55190 100644 --- a/src/cascadia/TerminalCore/ICoreAppearance.idl +++ b/src/cascadia/TerminalCore/ICoreAppearance.idl @@ -24,18 +24,18 @@ namespace Microsoft.Terminal.Core UInt8 A; }; - // TODO! + // TerminalCore declares its own Color struct to avoid depending on + // Windows.UI. Windows.Foundation.POint also exists, but it's composedof + // floating-point coordinates,whenwe almost always need integer coordinates. // It is supported by til::point for conversions in and out of WinRT land. struct Point { Int32 X; Int32 Y; }; - // It is supported by Microsoft::Terminal::Core::ControlKeyStates for conversions in and out of WinRT land. - struct ControlKeyStates - { - Int32 Value; - }; + + // Same thing here, but with padding. Can't use Windows.UI.Thickness, so + // we'll declare our own. struct Padding { Double Left; Double Top; @@ -43,6 +43,13 @@ namespace Microsoft.Terminal.Core Double Bottom; }; + // This is a projection of Microsoft::Terminal::Core::ControlKeyStates, + // for conversions in and out of WinRT land. + struct ControlKeyStates + { + Int32 Value; + }; + declare { // Forward declare this parameterized specialization so that it lives diff --git a/src/inc/til/rectangle.h b/src/inc/til/rectangle.h index 2c12e5958a2..180df49d151 100644 --- a/src/inc/til/rectangle.h +++ b/src/inc/til/rectangle.h @@ -183,6 +183,14 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned" { } + // This template will convert to rectangle from anything that has a X, Y, Width, and Height field that are floating-point; + // a math type is required. + template + constexpr rectangle(TilMath, const TOther& other, std::enable_if_t().X)> && std::is_floating_point_v().Y)> && std::is_floating_point_v().Width)> && std::is_floating_point_v().Height)>, int> /*sentinel*/ = 0) : + rectangle(til::point{ TilMath::template cast(other.X), TilMath::template cast(other.Y) }, til::size{ TilMath::template cast(other.Width), TilMath::template cast(other.Height) }) + { + } + // This template will convert to rectangle from anything that has a left, top, right, and bottom field that are floating-point; // a math type is required. template From 47410c9efb2e39af8c75286f5a4f5c6876cfbbc7 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Fri, 7 May 2021 11:08:26 -0500 Subject: [PATCH 14/30] now this works! --- src/cascadia/TerminalControl/TermControl.cpp | 3 +-- .../TerminalControl/TermControlAutomationPeer.cpp | 11 ++++++----- .../TerminalControl/TermControlAutomationPeer.h | 2 +- .../TerminalControl/TermControlAutomationPeer.idl | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index 6b2e0db4b21..af20014b7bb 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -1537,8 +1537,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation if (auto ap{ _automationPeer.get() }) { - auto controlOrigin{ ActualOffset() }; - ap.SetControlBounds(Windows::Foundation::Rect{ controlOrigin.x, controlOrigin.y, newSize.Width, newSize.Height }); + ap.UpdateControlBounds(); } } diff --git a/src/cascadia/TerminalControl/TermControlAutomationPeer.cpp b/src/cascadia/TerminalControl/TermControlAutomationPeer.cpp index 33edf94a25a..5c9e6c9c943 100644 --- a/src/cascadia/TerminalControl/TermControlAutomationPeer.cpp +++ b/src/cascadia/TerminalControl/TermControlAutomationPeer.cpp @@ -36,14 +36,15 @@ namespace winrt::Microsoft::Terminal::Control::implementation _termControl{ owner }, _implementation{ impl } { - auto controlOrigin{ owner->ActualOffset() }; - auto controlSize{ owner->ActualSize() }; - impl.SetControlBounds(Windows::Foundation::Rect{ controlOrigin.x, controlOrigin.y, controlSize.x, controlSize.y }); + UpdateControlBounds(); }; - void TermControlAutomationPeer::SetControlBounds(const Windows::Foundation::Rect bounds) + void TermControlAutomationPeer::UpdateControlBounds() { - _implementation.SetControlBounds(bounds); + // FrameworkElementAutomationPeer has this great GetBoundingRectangle + // method that's seemingly impossible to recreate just from the + // UserControl itself. Weird. But we can use it handily here! + _implementation.SetControlBounds(GetBoundingRectangle()); } void TermControlAutomationPeer::SetControlPadding(const Core::Padding padding) { diff --git a/src/cascadia/TerminalControl/TermControlAutomationPeer.h b/src/cascadia/TerminalControl/TermControlAutomationPeer.h index f8d704e3f0a..f06d06a626b 100644 --- a/src/cascadia/TerminalControl/TermControlAutomationPeer.h +++ b/src/cascadia/TerminalControl/TermControlAutomationPeer.h @@ -45,7 +45,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation TermControlAutomationPeer(Microsoft::Terminal::Control::implementation::TermControl* owner, Control::InteractivityAutomationPeer implementation); - void SetControlBounds(const Windows::Foundation::Rect bounds); + void UpdateControlBounds(); void SetControlPadding(const Core::Padding padding); #pragma region FrameworkElementAutomationPeer diff --git a/src/cascadia/TerminalControl/TermControlAutomationPeer.idl b/src/cascadia/TerminalControl/TermControlAutomationPeer.idl index c41eecb9c46..4ca83f0d9c1 100644 --- a/src/cascadia/TerminalControl/TermControlAutomationPeer.idl +++ b/src/cascadia/TerminalControl/TermControlAutomationPeer.idl @@ -10,7 +10,7 @@ namespace Microsoft.Terminal.Control Windows.UI.Xaml.Automation.Provider.ITextProvider { - void SetControlBounds(Windows.Foundation.Rect bounds); + void UpdateControlBounds(); void SetControlPadding(Microsoft.Terminal.Core.Padding padding); } } From 08694567ff1ec50171f77396e9378cbbe17cf918 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Fri, 7 May 2021 11:16:16 -0500 Subject: [PATCH 15/30] Some cleanup --- src/cascadia/TerminalControl/ControlCore.idl | 54 ++++++++++--------- .../InteractivityAutomationPeer.cpp | 37 +++++-------- .../TermControlAutomationPeer.cpp | 8 +++ 3 files changed, 50 insertions(+), 49 deletions(-) diff --git a/src/cascadia/TerminalControl/ControlCore.idl b/src/cascadia/TerminalControl/ControlCore.idl index 95fd3943b7c..b101ecc3b9c 100644 --- a/src/cascadia/TerminalControl/ControlCore.idl +++ b/src/cascadia/TerminalControl/ControlCore.idl @@ -13,6 +13,9 @@ namespace Microsoft.Terminal.Control // but projectable. struct MouseButtonState { + // !! LOAD BEARING !! If you make these Booleans (like they should be), + // then the app will crash trying to toss one of these across the + // process boundary. I haven't the damndest idea why. Int32 IsLeftButtonDown; Int32 IsMiddleButtonDown; Int32 IsRightButtonDown; @@ -23,19 +26,19 @@ namespace Microsoft.Terminal.Control ControlCore(IControlSettings settings, Microsoft.Terminal.TerminalConnection.ITerminalConnection connection); - // void AttachUiaEngine(::Microsoft::Console::Render::IRenderEngine* const pEngine); - // ::Microsoft::Console::Types::IUiaData* GetUiaData() const; + Boolean Initialize(Double actualWidth, + Double actualHeight, + Double compositionScale); + + void UpdateSettings(IControlSettings settings); + void UpdateAppearance(IControlAppearance appearance); + + UInt64 GetSwapChainHandle(); Windows.Foundation.Size FontSize { get; }; String FontFaceName { get; }; UInt16 FontWeight { get; }; - UInt64 GetSwapChainHandle(); - // std::vector SelectedText(bool trimTrailingWhitespace) const; - IVector SelectedText(Boolean trimTrailingWhitespace); - void UpdateHoveredCell(Windows.Foundation.IReference terminalPosition); - Windows.Foundation.IReference GetHoveredCell(); - Boolean TrySendKeyEvent(Int16 vkey, Int16 scanCode, Microsoft.Terminal.Core.ControlKeyStates modifiers, @@ -43,36 +46,39 @@ namespace Microsoft.Terminal.Control Boolean SendCharEvent(Char ch, Int16 scanCode, Microsoft.Terminal.Core.ControlKeyStates modifiers); + void SendInput(String text); + void PasteText(String text); + + void UpdateHoveredCell(Windows.Foundation.IReference terminalPosition); + + void ResetFontSize(); + void AdjustFontSize(Int32 fontSize); + void SizeChanged(Double width, Double height); + void ScaleChanged(Double scale); + + void ToggleShaderEffects(); + void ToggleReadOnlyMode(); Microsoft.Terminal.Core.Point CursorPosition(); void ResumeRendering(); - void ToggleReadOnlyMode(); void BlinkAttributeTick(); - String GetHoveredUriText(); - void SendInput(String text); - void PasteText(String text); void UpdatePatternLocations(); - Boolean HasSelection(); void Search(String text, Boolean goForward, Boolean caseSensitive); - void UpdateSettings(IControlSettings settings); - void UpdateAppearance(IControlAppearance appearance); - void ToggleShaderEffects(); void SetBackgroundOpacity(Double opacity); Microsoft.Terminal.Core.Color BackgroundColor(); - Boolean Initialize(Double actualWidth, - Double actualHeight, - Double compositionScale); + + Boolean HasSelection(); + IVector SelectedText(Boolean trimTrailingWhitespace); + + String GetHoveredUriText(); + Windows.Foundation.IReference GetHoveredCell(); + void Close(); void BlinkCursor(); - void ResetFontSize(); - void AdjustFontSize(Int32 fontSize); - void SizeChanged(Double width, Double height); - void ScaleChanged(Double scale); Boolean IsInReadOnlyMode(); Boolean CursorOn; void EnablePainting(); - event FontSizeChangedEventArgs FontSizeChanged; event Windows.Foundation.TypedEventHandler CopyToClipboard; diff --git a/src/cascadia/TerminalControl/InteractivityAutomationPeer.cpp b/src/cascadia/TerminalControl/InteractivityAutomationPeer.cpp index c1ed5380211..c6f7591df8e 100644 --- a/src/cascadia/TerminalControl/InteractivityAutomationPeer.cpp +++ b/src/cascadia/TerminalControl/InteractivityAutomationPeer.cpp @@ -53,9 +53,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation void InteractivityAutomationPeer::SignalSelectionChanged() { UiaTracing::Signal::SelectionChanged(); - // TODO! We seemingly got Dispatcher() for free when we said we extended + + // TODO:projects/5#card-50760282 + // We seemingly got a Dispatcher() for free when we said we extended // Windows.UI.Automation.Peers.AutomationPeer. This is suspect to me. - // This probably won't work when OOP. + // This probably won't work when out-of-proc from the WinUI layer. Dispatcher().RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, [&]() { // The event that is raised when the text selection is modified. @@ -72,9 +74,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation void InteractivityAutomationPeer::SignalTextChanged() { UiaTracing::Signal::TextChanged(); - // TODO! We seemingly got Dispatcher() for free when we said we extended + + // TODO:projects/5#card-50760282 + // We seemingly got a Dispatcher() for free when we said we extended // Windows.UI.Automation.Peers.AutomationPeer. This is suspect to me. - // This probably won't work when OOP. + // This probably won't work when out-of-proc from the WinUI layer. Dispatcher().RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, [&]() { // The event that is raised when textual content is modified. @@ -91,9 +95,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation void InteractivityAutomationPeer::SignalCursorChanged() { UiaTracing::Signal::CursorChanged(); - // TODO! We seemingly got Dispatcher() for free when we said we extended + + // TODO:projects/5#card-50760282 + // We seemingly got a Dispatcher() for free when we said we extended // Windows.UI.Automation.Peers.AutomationPeer. This is suspect to me. - // This probably won't work when OOP. + // This probably won't work when out-of-proc from the WinUI layer. Dispatcher().RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, [&]() { // The event that is raised when the text was changed in an edit control. @@ -170,18 +176,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation RECT InteractivityAutomationPeer::GetBounds() const { - // const auto padding = _interactivity->GetPadding(); - // // TODO! Get this from the core - // const til::size dimensions{ 100, 100 }; - // const til::rectangle realBounds{ padding.origin(), dimensions }; - // return realBounds; - // auto rect = GetBoundingRectangle(); - // return { - // gsl::narrow_cast(rect.X), - // gsl::narrow_cast(rect.Y), - // gsl::narrow_cast(rect.X + rect.Width), - // gsl::narrow_cast(rect.Y + rect.Height) - // }; return _controlBounds; } @@ -196,13 +190,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation RECT InteractivityAutomationPeer::GetPadding() const { return _controlPadding; - // return _interactivity->GetPadding(); - // return { - // gsl::narrow_cast(padding.Left), - // gsl::narrow_cast(padding.Top), - // gsl::narrow_cast(padding.Right), - // gsl::narrow_cast(padding.Bottom) - // }; } double InteractivityAutomationPeer::GetScaleFactor() const diff --git a/src/cascadia/TerminalControl/TermControlAutomationPeer.cpp b/src/cascadia/TerminalControl/TermControlAutomationPeer.cpp index 5c9e6c9c943..343f63dbd82 100644 --- a/src/cascadia/TerminalControl/TermControlAutomationPeer.cpp +++ b/src/cascadia/TerminalControl/TermControlAutomationPeer.cpp @@ -39,6 +39,14 @@ namespace winrt::Microsoft::Terminal::Control::implementation UpdateControlBounds(); }; + // Method Description: + // - Inform the interactivity layer about the bounds of the control. + // IControlAccessibilityInfo needs to know this information, but it cannot + // ask us directly. + // Arguments: + // - + // Return Value: + // - void TermControlAutomationPeer::UpdateControlBounds() { // FrameworkElementAutomationPeer has this great GetBoundingRectangle From dace0c4cf7bced2d5fbe84498f8f97d174da14fb Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Fri, 7 May 2021 11:24:47 -0500 Subject: [PATCH 16/30] a bit more cleanup --- src/cascadia/TerminalControl/ControlInteractivity.cpp | 10 ---------- .../TerminalControl/InteractivityAutomationPeer.cpp | 2 +- src/cascadia/TerminalControl/TermControl.h | 1 - 3 files changed, 1 insertion(+), 12 deletions(-) diff --git a/src/cascadia/TerminalControl/ControlInteractivity.cpp b/src/cascadia/TerminalControl/ControlInteractivity.cpp index 46faecfb8e5..46d71216982 100644 --- a/src/cascadia/TerminalControl/ControlInteractivity.cpp +++ b/src/cascadia/TerminalControl/ControlInteractivity.cpp @@ -57,7 +57,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation void ControlInteractivity::UpdateSettings() { _updateSystemParameterSettings(); - } void ControlInteractivity::Initialize() @@ -622,13 +621,4 @@ namespace winrt::Microsoft::Terminal::Control::implementation return _core->GetUiaData(); } - // hstring ControlInteractivity::GetProfileName() const - // { - // return _settings.ProfileName(); - // } - // til::rectangle ControlInteractivity::GetPadding() const - // { - // return _lastPadding; - // } - } diff --git a/src/cascadia/TerminalControl/InteractivityAutomationPeer.cpp b/src/cascadia/TerminalControl/InteractivityAutomationPeer.cpp index c6f7591df8e..3ef05213bdf 100644 --- a/src/cascadia/TerminalControl/InteractivityAutomationPeer.cpp +++ b/src/cascadia/TerminalControl/InteractivityAutomationPeer.cpp @@ -29,7 +29,7 @@ namespace XamlAutomation namespace winrt::Microsoft::Terminal::Control::implementation { - InteractivityAutomationPeer::InteractivityAutomationPeer(winrt::Microsoft::Terminal::Control::implementation::ControlInteractivity* owner) : + InteractivityAutomationPeer::InteractivityAutomationPeer(Control::implementation::ControlInteractivity* owner) : _interactivity{ owner } { THROW_IF_FAILED(::Microsoft::WRL::MakeAndInitialize<::Microsoft::Terminal::TermControlUiaProvider>(&_uiaProvider, _interactivity->GetUiaData(), this)); diff --git a/src/cascadia/TerminalControl/TermControl.h b/src/cascadia/TerminalControl/TermControl.h index 3988f2461ca..e2ed7bd5bdc 100644 --- a/src/cascadia/TerminalControl/TermControl.h +++ b/src/cascadia/TerminalControl/TermControl.h @@ -84,7 +84,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation ~TermControl(); Windows::UI::Xaml::Automation::Peers::AutomationPeer OnCreateAutomationPeer(); - // ::Microsoft::Console::Types::IUiaData* GetUiaData() const; const Windows::UI::Xaml::Thickness GetPadding(); IControlSettings Settings() const; From b7b23a8e7dfa70df982b7360a5c3d827662b7bae Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Fri, 7 May 2021 11:29:07 -0500 Subject: [PATCH 17/30] god I knew I left these behind --- src/cascadia/TerminalControl/ControlInteractivity.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/cascadia/TerminalControl/ControlInteractivity.h b/src/cascadia/TerminalControl/ControlInteractivity.h index ad441b6033d..f42cfac8514 100644 --- a/src/cascadia/TerminalControl/ControlInteractivity.h +++ b/src/cascadia/TerminalControl/ControlInteractivity.h @@ -39,14 +39,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation void GainFocus(); void LostFocus(); - void UpdateSettings(/*const til::rectangle padding*/); + void UpdateSettings(); void Initialize(); Control::ControlCore GetCore(); - // hstring GetProfileName() const; Control::InteractivityAutomationPeer OnCreateAutomationPeer(); ::Microsoft::Console::Types::IUiaData* GetUiaData() const; - // til::rectangle GetPadding() const; #pragma region Input Methods void PointerPressed(Control::MouseButtonState buttonState, From 21a6370ec5c0f203aefbadc068ec56aa65ba0dc3 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Wed, 12 May 2021 13:52:32 -0500 Subject: [PATCH 18/30] fix the tests --- .../ControlInteractivityTests.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/cascadia/UnitTests_Control/ControlInteractivityTests.cpp b/src/cascadia/UnitTests_Control/ControlInteractivityTests.cpp index 3839d86e8bc..4dc10911190 100644 --- a/src/cascadia/UnitTests_Control/ControlInteractivityTests.cpp +++ b/src/cascadia/UnitTests_Control/ControlInteractivityTests.cpp @@ -260,8 +260,8 @@ namespace ControlUnitTests // For this test, don't use any modifiers const auto modifiers = ControlKeyStates(); - const TerminalInput::MouseButtonState leftMouseDown{ true, false, false }; - const TerminalInput::MouseButtonState noMouseDown{ false, false, false }; + const Control::MouseButtonState leftMouseDown{ true, false, false }; + const Control::MouseButtonState noMouseDown{ false, false, false }; const til::size fontSize{ 9, 21 }; @@ -358,8 +358,8 @@ namespace ControlUnitTests // For this test, don't use any modifiers const auto modifiers = ControlKeyStates(); - const TerminalInput::MouseButtonState leftMouseDown{ true, false, false }; - const TerminalInput::MouseButtonState noMouseDown{ false, false, false }; + const Control::MouseButtonState leftMouseDown{ true, false, false }; + const Control::MouseButtonState noMouseDown{ false, false, false }; const til::size fontSize{ 9, 21 }; @@ -444,7 +444,7 @@ namespace ControlUnitTests const int delta = WHEEL_DELTA / 5; const til::point mousePos{ 0, 0 }; - TerminalInput::MouseButtonState state{ false, false, false }; + Control::MouseButtonState state{ false, false, false }; interactivity->MouseWheel(modifiers, delta, mousePos, state); // 1/5 VERIFY_ARE_EQUAL(21, core->ScrollOffset()); @@ -508,8 +508,8 @@ namespace ControlUnitTests // For this test, don't use any modifiers const auto modifiers = ControlKeyStates(); - const TerminalInput::MouseButtonState leftMouseDown{ true, false, false }; - const TerminalInput::MouseButtonState noMouseDown{ false, false, false }; + const Control::MouseButtonState leftMouseDown{ true, false, false }; + const Control::MouseButtonState noMouseDown{ false, false, false }; const til::size fontSize{ 9, 21 }; From 4efdf3925490fab7dc94fdfca863e6aba1de0a4b Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Thu, 13 May 2021 05:53:20 -0500 Subject: [PATCH 19/30] This fixes nvda, so nowwe just have to polish --- .../InteractivityAutomationPeer.cpp | 43 ++++++++++--------- .../InteractivityAutomationPeer.h | 4 ++ .../InteractivityAutomationPeer.idl | 4 ++ .../TermControlAutomationPeer.cpp | 4 ++ 4 files changed, 35 insertions(+), 20 deletions(-) diff --git a/src/cascadia/TerminalControl/InteractivityAutomationPeer.cpp b/src/cascadia/TerminalControl/InteractivityAutomationPeer.cpp index 3ef05213bdf..f0c10ab2a17 100644 --- a/src/cascadia/TerminalControl/InteractivityAutomationPeer.cpp +++ b/src/cascadia/TerminalControl/InteractivityAutomationPeer.cpp @@ -52,17 +52,18 @@ namespace winrt::Microsoft::Terminal::Control::implementation // - void InteractivityAutomationPeer::SignalSelectionChanged() { - UiaTracing::Signal::SelectionChanged(); + // UiaTracing::Signal::SelectionChanged(); // TODO:projects/5#card-50760282 // We seemingly got a Dispatcher() for free when we said we extended // Windows.UI.Automation.Peers.AutomationPeer. This is suspect to me. // This probably won't work when out-of-proc from the WinUI layer. - Dispatcher().RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, [&]() { - // The event that is raised when the text selection is modified. - RaiseAutomationEvent(AutomationEvents::TextPatternOnTextSelectionChanged); - }); + _SelectionChangedHandlers(*this, nullptr); + // Dispatcher().RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, [&]() { + // // The event that is raised when the text selection is modified. + // RaiseAutomationEvent(AutomationEvents::TextPatternOnTextSelectionChanged); + // }); } // Method Description: @@ -73,17 +74,18 @@ namespace winrt::Microsoft::Terminal::Control::implementation // - void InteractivityAutomationPeer::SignalTextChanged() { - UiaTracing::Signal::TextChanged(); + // UiaTracing::Signal::TextChanged(); // TODO:projects/5#card-50760282 // We seemingly got a Dispatcher() for free when we said we extended // Windows.UI.Automation.Peers.AutomationPeer. This is suspect to me. // This probably won't work when out-of-proc from the WinUI layer. - Dispatcher().RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, [&]() { - // The event that is raised when textual content is modified. - RaiseAutomationEvent(AutomationEvents::TextPatternOnTextChanged); - }); + _TextChangedHandlers(*this, nullptr); + // Dispatcher().RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, [&]() { + // // The event that is raised when textual content is modified. + // RaiseAutomationEvent(AutomationEvents::TextPatternOnTextChanged); + // }); } // Method Description: @@ -94,22 +96,23 @@ namespace winrt::Microsoft::Terminal::Control::implementation // - void InteractivityAutomationPeer::SignalCursorChanged() { - UiaTracing::Signal::CursorChanged(); + // UiaTracing::Signal::CursorChanged(); // TODO:projects/5#card-50760282 // We seemingly got a Dispatcher() for free when we said we extended // Windows.UI.Automation.Peers.AutomationPeer. This is suspect to me. // This probably won't work when out-of-proc from the WinUI layer. - Dispatcher().RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, [&]() { - // The event that is raised when the text was changed in an edit control. - // Do NOT fire a TextEditTextChanged. Generally, an app on the other side - // will expect more information. Though you can dispatch that event - // on its own, it may result in a nullptr exception on the other side - // because no additional information was provided. Crashing the screen - // reader. - RaiseAutomationEvent(AutomationEvents::TextPatternOnTextSelectionChanged); - }); + _CursorChangedHandlers(*this, nullptr); + // Dispatcher().RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, [&]() { + // // The event that is raised when the text was changed in an edit control. + // // Do NOT fire a TextEditTextChanged. Generally, an app on the other side + // // will expect more information. Though you can dispatch that event + // // on its own, it may result in a nullptr exception on the other side + // // because no additional information was provided. Crashing the screen + // // reader. + // RaiseAutomationEvent(AutomationEvents::TextPatternOnTextSelectionChanged); + // }); } #pragma region ITextProvider diff --git a/src/cascadia/TerminalControl/InteractivityAutomationPeer.h b/src/cascadia/TerminalControl/InteractivityAutomationPeer.h index 61fae38bd11..7df17b338e0 100644 --- a/src/cascadia/TerminalControl/InteractivityAutomationPeer.h +++ b/src/cascadia/TerminalControl/InteractivityAutomationPeer.h @@ -69,6 +69,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation virtual HRESULT GetHostUiaProvider(IRawElementProviderSimple** provider) override; #pragma endregion + TYPED_EVENT(SelectionChanged, IInspectable, IInspectable); + TYPED_EVENT(TextChanged, IInspectable, IInspectable); + TYPED_EVENT(CursorChanged, IInspectable, IInspectable); + private: ::Microsoft::WRL::ComPtr<::Microsoft::Terminal::TermControlUiaProvider> _uiaProvider; winrt::Microsoft::Terminal::Control::implementation::ControlInteractivity* _interactivity; diff --git a/src/cascadia/TerminalControl/InteractivityAutomationPeer.idl b/src/cascadia/TerminalControl/InteractivityAutomationPeer.idl index 5bc887de270..4c9039c5c82 100644 --- a/src/cascadia/TerminalControl/InteractivityAutomationPeer.idl +++ b/src/cascadia/TerminalControl/InteractivityAutomationPeer.idl @@ -10,5 +10,9 @@ namespace Microsoft.Terminal.Control void SetControlBounds(Windows.Foundation.Rect bounds); void SetControlPadding(Microsoft.Terminal.Core.Padding padding); + + event Windows.Foundation.TypedEventHandler SelectionChanged; + event Windows.Foundation.TypedEventHandler TextChanged; + event Windows.Foundation.TypedEventHandler CursorChanged; } } diff --git a/src/cascadia/TerminalControl/TermControlAutomationPeer.cpp b/src/cascadia/TerminalControl/TermControlAutomationPeer.cpp index 343f63dbd82..c1432768e3b 100644 --- a/src/cascadia/TerminalControl/TermControlAutomationPeer.cpp +++ b/src/cascadia/TerminalControl/TermControlAutomationPeer.cpp @@ -37,6 +37,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation _implementation{ impl } { UpdateControlBounds(); + + _implementation.SelectionChanged([this](auto&&, auto&&) { SignalSelectionChanged(); }); + _implementation.TextChanged([this](auto&&, auto&&) { SignalTextChanged(); }); + _implementation.CursorChanged([this](auto&&, auto&&) { SignalCursorChanged(); }); }; // Method Description: From 59e911d569ca5431c0f2f62e1291b0f66b74d61d Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Thu, 13 May 2021 07:29:10 -0500 Subject: [PATCH 20/30] minor typo cleanup --- .../InteractivityAutomationPeer.cpp | 56 +++++-------------- .../InteractivityAutomationPeer.h | 2 +- .../TermControlAutomationPeer.cpp | 27 +++++---- .../TermControlAutomationPeer.h | 2 +- src/cascadia/TerminalCore/ICoreAppearance.idl | 4 +- 5 files changed, 34 insertions(+), 57 deletions(-) diff --git a/src/cascadia/TerminalControl/InteractivityAutomationPeer.cpp b/src/cascadia/TerminalControl/InteractivityAutomationPeer.cpp index f0c10ab2a17..5b0d74343d9 100644 --- a/src/cascadia/TerminalControl/InteractivityAutomationPeer.cpp +++ b/src/cascadia/TerminalControl/InteractivityAutomationPeer.cpp @@ -45,74 +45,48 @@ namespace winrt::Microsoft::Terminal::Control::implementation } // Method Description: - // - Signals the ui automation client that the terminal's selection has changed and should be updated + // - Signals the ui automation client that the terminal's selection has + // changed and should be updated + // - We will raise a new event, for out embedding control to be able to + // raise the event. AutomationPeer by itself doesn't hook up to the + // eventing mechanism, we need the FrameworkAutomationPeer to do that. // Arguments: // - // Return Value: // - void InteractivityAutomationPeer::SignalSelectionChanged() { - // UiaTracing::Signal::SelectionChanged(); - - // TODO:projects/5#card-50760282 - // We seemingly got a Dispatcher() for free when we said we extended - // Windows.UI.Automation.Peers.AutomationPeer. This is suspect to me. - // This probably won't work when out-of-proc from the WinUI layer. - _SelectionChangedHandlers(*this, nullptr); - // Dispatcher().RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, [&]() { - // // The event that is raised when the text selection is modified. - // RaiseAutomationEvent(AutomationEvents::TextPatternOnTextSelectionChanged); - // }); } // Method Description: - // - Signals the ui automation client that the terminal's output has changed and should be updated + // - Signals the ui automation client that the terminal's output has changed + // and should be updated + // - We will raise a new event, for out embedding control to be able to + // raise the event. AutomationPeer by itself doesn't hook up to the + // eventing mechanism, we need the FrameworkAutomationPeer to do that. // Arguments: // - // Return Value: // - void InteractivityAutomationPeer::SignalTextChanged() { - // UiaTracing::Signal::TextChanged(); - - // TODO:projects/5#card-50760282 - // We seemingly got a Dispatcher() for free when we said we extended - // Windows.UI.Automation.Peers.AutomationPeer. This is suspect to me. - // This probably won't work when out-of-proc from the WinUI layer. - _TextChangedHandlers(*this, nullptr); - // Dispatcher().RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, [&]() { - // // The event that is raised when textual content is modified. - // RaiseAutomationEvent(AutomationEvents::TextPatternOnTextChanged); - // }); } // Method Description: - // - Signals the ui automation client that the cursor's state has changed and should be updated + // - Signals the ui automation client that the cursor's state has changed + // and should be updated + // - We will raise a new event, for out embedding control to be able to + // raise the event. AutomationPeer by itself doesn't hook up to the + // eventing mechanism, we need the FrameworkAutomationPeer to do that. // Arguments: // - // Return Value: // - void InteractivityAutomationPeer::SignalCursorChanged() { - // UiaTracing::Signal::CursorChanged(); - - // TODO:projects/5#card-50760282 - // We seemingly got a Dispatcher() for free when we said we extended - // Windows.UI.Automation.Peers.AutomationPeer. This is suspect to me. - // This probably won't work when out-of-proc from the WinUI layer. - _CursorChangedHandlers(*this, nullptr); - // Dispatcher().RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, [&]() { - // // The event that is raised when the text was changed in an edit control. - // // Do NOT fire a TextEditTextChanged. Generally, an app on the other side - // // will expect more information. Though you can dispatch that event - // // on its own, it may result in a nullptr exception on the other side - // // because no additional information was provided. Crashing the screen - // // reader. - // RaiseAutomationEvent(AutomationEvents::TextPatternOnTextSelectionChanged); - // }); } #pragma region ITextProvider diff --git a/src/cascadia/TerminalControl/InteractivityAutomationPeer.h b/src/cascadia/TerminalControl/InteractivityAutomationPeer.h index 7df17b338e0..07b7750889b 100644 --- a/src/cascadia/TerminalControl/InteractivityAutomationPeer.h +++ b/src/cascadia/TerminalControl/InteractivityAutomationPeer.h @@ -16,7 +16,7 @@ Module Name: ControlInteractivity is totally oblivious to the UI tree that might be hosting it. So this class implements the actual text pattern for the buffer, because it has access to the buffer. TermControlAutomationPeer can then call the - methods on this class to expose the implemeentation in the actual UI tree. + methods on this class to expose the implementation in the actual UI tree. Author(s): - Mike Griese (migrie), May 2021 diff --git a/src/cascadia/TerminalControl/TermControlAutomationPeer.cpp b/src/cascadia/TerminalControl/TermControlAutomationPeer.cpp index c1432768e3b..6368b1f76a2 100644 --- a/src/cascadia/TerminalControl/TermControlAutomationPeer.cpp +++ b/src/cascadia/TerminalControl/TermControlAutomationPeer.cpp @@ -34,13 +34,16 @@ namespace winrt::Microsoft::Terminal::Control::implementation Control::InteractivityAutomationPeer impl) : TermControlAutomationPeerT(*owner), // pass owner to FrameworkElementAutomationPeer _termControl{ owner }, - _implementation{ impl } + _contentAutomationPeer{ impl } { UpdateControlBounds(); - _implementation.SelectionChanged([this](auto&&, auto&&) { SignalSelectionChanged(); }); - _implementation.TextChanged([this](auto&&, auto&&) { SignalTextChanged(); }); - _implementation.CursorChanged([this](auto&&, auto&&) { SignalCursorChanged(); }); + // Listen for UIA signalling events from the implementation. We need to + // be the one to actually raise these automation events, so they go + // through the UI tree correctly. + _contentAutomationPeer.SelectionChanged([this](auto&&, auto&&) { SignalSelectionChanged(); }); + _contentAutomationPeer.TextChanged([this](auto&&, auto&&) { SignalTextChanged(); }); + _contentAutomationPeer.CursorChanged([this](auto&&, auto&&) { SignalCursorChanged(); }); }; // Method Description: @@ -56,11 +59,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation // FrameworkElementAutomationPeer has this great GetBoundingRectangle // method that's seemingly impossible to recreate just from the // UserControl itself. Weird. But we can use it handily here! - _implementation.SetControlBounds(GetBoundingRectangle()); + _contentAutomationPeer.SetControlBounds(GetBoundingRectangle()); } void TermControlAutomationPeer::SetControlPadding(const Core::Padding padding) { - _implementation.SetControlPadding(padding); + _contentAutomationPeer.SetControlPadding(padding); } // Method Description: @@ -169,32 +172,32 @@ namespace winrt::Microsoft::Terminal::Control::implementation #pragma region ITextProvider com_array TermControlAutomationPeer::GetSelection() { - return _implementation.GetSelection(); + return _contentAutomationPeer.GetSelection(); } com_array TermControlAutomationPeer::GetVisibleRanges() { - return _implementation.GetVisibleRanges(); + return _contentAutomationPeer.GetVisibleRanges(); } XamlAutomation::ITextRangeProvider TermControlAutomationPeer::RangeFromChild(XamlAutomation::IRawElementProviderSimple childElement) { - return _implementation.RangeFromChild(childElement); + return _contentAutomationPeer.RangeFromChild(childElement); } XamlAutomation::ITextRangeProvider TermControlAutomationPeer::RangeFromPoint(Windows::Foundation::Point screenLocation) { - return _implementation.RangeFromPoint(screenLocation); + return _contentAutomationPeer.RangeFromPoint(screenLocation); } XamlAutomation::ITextRangeProvider TermControlAutomationPeer::DocumentRange() { - return _implementation.DocumentRange(); + return _contentAutomationPeer.DocumentRange(); } XamlAutomation::SupportedTextSelection TermControlAutomationPeer::SupportedTextSelection() { - return _implementation.SupportedTextSelection(); + return _contentAutomationPeer.SupportedTextSelection(); } #pragma endregion diff --git a/src/cascadia/TerminalControl/TermControlAutomationPeer.h b/src/cascadia/TerminalControl/TermControlAutomationPeer.h index f06d06a626b..0b81ebafec5 100644 --- a/src/cascadia/TerminalControl/TermControlAutomationPeer.h +++ b/src/cascadia/TerminalControl/TermControlAutomationPeer.h @@ -76,7 +76,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation private: winrt::Microsoft::Terminal::Control::implementation::TermControl* _termControl; - Control::InteractivityAutomationPeer _implementation; + Control::InteractivityAutomationPeer _contentAutomationPeer; winrt::com_array WrapArrayOfTextRangeProviders(SAFEARRAY* textRanges); }; diff --git a/src/cascadia/TerminalCore/ICoreAppearance.idl b/src/cascadia/TerminalCore/ICoreAppearance.idl index 52d4db55190..dec0eefa40f 100644 --- a/src/cascadia/TerminalCore/ICoreAppearance.idl +++ b/src/cascadia/TerminalCore/ICoreAppearance.idl @@ -25,8 +25,8 @@ namespace Microsoft.Terminal.Core }; // TerminalCore declares its own Color struct to avoid depending on - // Windows.UI. Windows.Foundation.POint also exists, but it's composedof - // floating-point coordinates,whenwe almost always need integer coordinates. + // Windows.UI. Windows.Foundation.Point also exists, but it's composed of + // floating-point coordinates,when we almost always need integer coordinates. // It is supported by til::point for conversions in and out of WinRT land. struct Point { From 6f07004f397ed0e77a8d6583cdeedd139a958e5c Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Thu, 13 May 2021 07:39:23 -0500 Subject: [PATCH 21/30] some consts --- .../TerminalControl/InteractivityAutomationPeer.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/cascadia/TerminalControl/InteractivityAutomationPeer.cpp b/src/cascadia/TerminalControl/InteractivityAutomationPeer.cpp index 5b0d74343d9..88069bac198 100644 --- a/src/cascadia/TerminalControl/InteractivityAutomationPeer.cpp +++ b/src/cascadia/TerminalControl/InteractivityAutomationPeer.cpp @@ -111,8 +111,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation THROW_IF_FAILED(_uiaProvider->RangeFromChild(/* IRawElementProviderSimple */ nullptr, &returnVal)); - auto parentProvider = this->ProviderFromPeer(*this); - auto xutr = winrt::make_self(returnVal, parentProvider); + const auto parentProvider = this->ProviderFromPeer(*this); + const auto xutr = winrt::make_self(returnVal, parentProvider); return xutr.as(); } @@ -121,8 +121,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation UIA::ITextRangeProvider* returnVal; THROW_IF_FAILED(_uiaProvider->RangeFromPoint({ screenLocation.X, screenLocation.Y }, &returnVal)); - auto parentProvider = this->ProviderFromPeer(*this); - auto xutr = winrt::make_self(returnVal, parentProvider); + const auto parentProvider = this->ProviderFromPeer(*this); + const auto xutr = winrt::make_self(returnVal, parentProvider); return xutr.as(); } @@ -131,8 +131,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation UIA::ITextRangeProvider* returnVal; THROW_IF_FAILED(_uiaProvider->get_DocumentRange(&returnVal)); - auto parentProvider = this->ProviderFromPeer(*this); - auto xutr = winrt::make_self(returnVal, parentProvider); + const auto parentProvider = this->ProviderFromPeer(*this); + const auto xutr = winrt::make_self(returnVal, parentProvider); return xutr.as(); } From ff3b808dfb6997110142c39cafd98268f4df60e5 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Thu, 13 May 2021 08:25:36 -0500 Subject: [PATCH 22/30] this is almost exclusively nits --- src/cascadia/TerminalControl/ControlCore.cpp | 11 ++++++----- src/cascadia/TerminalControl/ControlCore.h | 6 +++--- src/cascadia/TerminalControl/ControlCore.idl | 16 ++++++++-------- .../TerminalControl/ControlInteractivity.cpp | 2 +- .../TerminalControl/ControlInteractivity.h | 2 +- .../TerminalControl/ControlInteractivity.idl | 2 +- .../InteractivityAutomationPeer.cpp | 2 +- src/cascadia/TerminalControl/TermControl.cpp | 10 +++++----- 8 files changed, 26 insertions(+), 25 deletions(-) diff --git a/src/cascadia/TerminalControl/ControlCore.cpp b/src/cascadia/TerminalControl/ControlCore.cpp index 48443caa3a4..a8d81679cfc 100644 --- a/src/cascadia/TerminalControl/ControlCore.cpp +++ b/src/cascadia/TerminalControl/ControlCore.cpp @@ -480,7 +480,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation return winrt::hstring{ _terminal->GetHyperlinkAtPosition(pos) }; } - winrt::hstring ControlCore::GetHoveredUriText() const + winrt::hstring ControlCore::HoveredUriText() const { auto lock = _terminal->LockForReading(); // Lock for the duration of our reads. if (_lastHoveredCell.has_value()) @@ -490,9 +490,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation return {}; } - Windows::Foundation::IReference ControlCore::GetHoveredCell() const + Windows::Foundation::IReference ControlCore::HoveredCell() const { - return _lastHoveredCell.has_value() ? Windows::Foundation::IReference(til::point{ _lastHoveredCell.value() }) : nullptr; + return _lastHoveredCell.has_value() ? Windows::Foundation::IReference(_lastHoveredCell.value()) : nullptr; } // Method Description: @@ -1099,9 +1099,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation Windows::Foundation::Collections::IVector ControlCore::SelectedText(bool trimTrailingWhitespace) const { // RetrieveSelectedTextFromBuffer will lock while it's reading - std::vector internalResult{ _terminal->RetrieveSelectedTextFromBuffer(trimTrailingWhitespace).text }; + auto internalResult{ _terminal->RetrieveSelectedTextFromBuffer(trimTrailingWhitespace).text }; auto result = winrt::single_threaded_vector(); + for (const auto& row : internalResult) { result.Append(winrt::hstring{ row }); @@ -1201,7 +1202,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation } } - uint64_t ControlCore::GetSwapChainHandle() const + uint64_t ControlCore::SwapChainHandle() const { // This is called by: // * TermControl::RenderEngineSwapChainChanged, who is only registered diff --git a/src/cascadia/TerminalControl/ControlCore.h b/src/cascadia/TerminalControl/ControlCore.h index 2abde2e872a..94341e54516 100644 --- a/src/cascadia/TerminalControl/ControlCore.h +++ b/src/cascadia/TerminalControl/ControlCore.h @@ -49,7 +49,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation void UpdateAppearance(const IControlAppearance& newAppearance); void SizeChanged(const double width, const double height); void ScaleChanged(const double scale); - uint64_t GetSwapChainHandle() const; + uint64_t SwapChainHandle() const; void AdjustFontSize(int fontSizeDelta); void ResetFontSize(); @@ -74,8 +74,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation void UpdatePatternLocations(); void UpdateHoveredCell(Windows::Foundation::IReference terminalPosition); winrt::hstring GetHyperlink(const til::point position) const; - winrt::hstring GetHoveredUriText() const; - Windows::Foundation::IReference GetHoveredCell() const; + winrt::hstring HoveredUriText() const; + Windows::Foundation::IReference HoveredCell() const; ::Microsoft::Console::Types::IUiaData* GetUiaData() const; diff --git a/src/cascadia/TerminalControl/ControlCore.idl b/src/cascadia/TerminalControl/ControlCore.idl index b101ecc3b9c..f5197cfc2bd 100644 --- a/src/cascadia/TerminalControl/ControlCore.idl +++ b/src/cascadia/TerminalControl/ControlCore.idl @@ -33,7 +33,7 @@ namespace Microsoft.Terminal.Control void UpdateSettings(IControlSettings settings); void UpdateAppearance(IControlAppearance appearance); - UInt64 GetSwapChainHandle(); + UInt64 SwapChainHandle { get; }; Windows.Foundation.Size FontSize { get; }; String FontFaceName { get; }; @@ -52,30 +52,30 @@ namespace Microsoft.Terminal.Control void UpdateHoveredCell(Windows.Foundation.IReference terminalPosition); void ResetFontSize(); - void AdjustFontSize(Int32 fontSize); + void AdjustFontSize(Int32 fontSizeDelta); void SizeChanged(Double width, Double height); void ScaleChanged(Double scale); void ToggleShaderEffects(); void ToggleReadOnlyMode(); - Microsoft.Terminal.Core.Point CursorPosition(); + Microsoft.Terminal.Core.Point CursorPosition { get; }; void ResumeRendering(); void BlinkAttributeTick(); void UpdatePatternLocations(); void Search(String text, Boolean goForward, Boolean caseSensitive); void SetBackgroundOpacity(Double opacity); - Microsoft.Terminal.Core.Color BackgroundColor(); + Microsoft.Terminal.Core.Color BackgroundColor { get; }; - Boolean HasSelection(); + Boolean HasSelection { get; }; IVector SelectedText(Boolean trimTrailingWhitespace); - String GetHoveredUriText(); - Windows.Foundation.IReference GetHoveredCell(); + String HoveredUriText { get; }; + Windows.Foundation.IReference HoveredCell { get; }; void Close(); void BlinkCursor(); - Boolean IsInReadOnlyMode(); + Boolean IsInReadOnlyMode { get; }; Boolean CursorOn; void EnablePainting(); diff --git a/src/cascadia/TerminalControl/ControlInteractivity.cpp b/src/cascadia/TerminalControl/ControlInteractivity.cpp index 46d71216982..ad364e4db42 100644 --- a/src/cascadia/TerminalControl/ControlInteractivity.cpp +++ b/src/cascadia/TerminalControl/ControlInteractivity.cpp @@ -67,7 +67,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation _multiClickTimer = GetDoubleClickTime() * 1000; } - Control::ControlCore ControlInteractivity::GetCore() + Control::ControlCore ControlInteractivity::Core() { return *_core; } diff --git a/src/cascadia/TerminalControl/ControlInteractivity.h b/src/cascadia/TerminalControl/ControlInteractivity.h index 5b2c4085378..87dc36d66a9 100644 --- a/src/cascadia/TerminalControl/ControlInteractivity.h +++ b/src/cascadia/TerminalControl/ControlInteractivity.h @@ -41,7 +41,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation void LostFocus(); void UpdateSettings(); void Initialize(); - Control::ControlCore GetCore(); + Control::ControlCore Core(); Control::InteractivityAutomationPeer OnCreateAutomationPeer(); ::Microsoft::Console::Types::IUiaData* GetUiaData() const; diff --git a/src/cascadia/TerminalControl/ControlInteractivity.idl b/src/cascadia/TerminalControl/ControlInteractivity.idl index a0fba34c334..0ea1308018e 100644 --- a/src/cascadia/TerminalControl/ControlInteractivity.idl +++ b/src/cascadia/TerminalControl/ControlInteractivity.idl @@ -16,7 +16,7 @@ namespace Microsoft.Terminal.Control ControlInteractivity(IControlSettings settings, Microsoft.Terminal.TerminalConnection.ITerminalConnection connection); - ControlCore GetCore(); + ControlCore Core { get; }; void UpdateSettings(); void Initialize(); void GainFocus(); diff --git a/src/cascadia/TerminalControl/InteractivityAutomationPeer.cpp b/src/cascadia/TerminalControl/InteractivityAutomationPeer.cpp index 88069bac198..9d028b48444 100644 --- a/src/cascadia/TerminalControl/InteractivityAutomationPeer.cpp +++ b/src/cascadia/TerminalControl/InteractivityAutomationPeer.cpp @@ -148,7 +148,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation #pragma region IControlAccessibilityInfo COORD InteractivityAutomationPeer::GetFontSize() const { - return til::size{ til::math::rounding, _interactivity->GetCore().FontSize() }; + return til::size{ til::math::rounding, _interactivity->Core().FontSize() }; } RECT InteractivityAutomationPeer::GetBounds() const diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index af20014b7bb..1b15c917e07 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -62,7 +62,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation InitializeComponent(); _interactivity = winrt::make(settings, connection); - _core = _interactivity.GetCore(); + _core = _interactivity.Core(); // Use a manual revoker on the output event, so we can immediately stop // worrying about it on destruction. @@ -570,7 +570,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation if (auto control{ weakThis.get() }) { - const HANDLE chainHandle = reinterpret_cast(control->_core.GetSwapChainHandle()); + const HANDLE chainHandle = reinterpret_cast(control->_core.SwapChainHandle()); _AttachDxgiSwapChainToXaml(chainHandle); } } @@ -658,7 +658,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation } _interactivity.Initialize(); - _AttachDxgiSwapChainToXaml(reinterpret_cast(_core.GetSwapChainHandle())); + _AttachDxgiSwapChainToXaml(reinterpret_cast(_core.SwapChainHandle())); // Tell the DX Engine to notify us when the swap chain changes. We do // this after we initially set the swapchain so as to avoid unnecessary @@ -2386,10 +2386,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation co_await resume_foreground(Dispatcher()); if (auto self{ weakThis.get() }) { - auto lastHoveredCell = _core.GetHoveredCell(); + auto lastHoveredCell = _core.HoveredCell(); if (lastHoveredCell) { - const auto uriText = _core.GetHoveredUriText(); + const auto uriText = _core.HoveredUriText(); if (!uriText.empty()) { // Update the tooltip with the URI From 804a114fdacdbabce26c495f22274a856446fdcd Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Thu, 20 May 2021 14:45:10 -0500 Subject: [PATCH 23/30] this one's easy too --- src/cascadia/TerminalControl/InteractivityAutomationPeer.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cascadia/TerminalControl/InteractivityAutomationPeer.h b/src/cascadia/TerminalControl/InteractivityAutomationPeer.h index 07b7750889b..893478e9192 100644 --- a/src/cascadia/TerminalControl/InteractivityAutomationPeer.h +++ b/src/cascadia/TerminalControl/InteractivityAutomationPeer.h @@ -77,8 +77,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation ::Microsoft::WRL::ComPtr<::Microsoft::Terminal::TermControlUiaProvider> _uiaProvider; winrt::Microsoft::Terminal::Control::implementation::ControlInteractivity* _interactivity; - til::rectangle _controlBounds; - til::rectangle _controlPadding; + til::rectangle _controlBounds{}; + til::rectangle _controlPadding{}; winrt::com_array WrapArrayOfTextRangeProviders(SAFEARRAY* textRanges); }; From 0f0af036ec61e0e5d217d92a7f188abbbdb2fba1 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Fri, 21 May 2021 12:18:25 -0500 Subject: [PATCH 24/30] An enum does in fact work across the process boundary (cherry picked from commit 7fc72ca82012bc295dc47513762bce9e5d148053) --- src/cascadia/TerminalControl/ControlCore.idl | 15 ++++++++------- .../TerminalControl/ControlInteractivity.cpp | 14 ++++++++------ src/cascadia/TerminalControl/TermControl.cpp | 19 +++++++++++++------ 3 files changed, 29 insertions(+), 19 deletions(-) diff --git a/src/cascadia/TerminalControl/ControlCore.idl b/src/cascadia/TerminalControl/ControlCore.idl index 34e97a4be6c..fa4746ca404 100644 --- a/src/cascadia/TerminalControl/ControlCore.idl +++ b/src/cascadia/TerminalControl/ControlCore.idl @@ -11,14 +11,15 @@ namespace Microsoft.Terminal.Control // This is a mirror of // ::Microsoft::Console::VirtualTerminal::TerminalInput::MouseButtonState, // but projectable. - struct MouseButtonState + // !! LOAD BEARING !! If you make this a struct with Booleans (like they + // make the most sense as), then the app will crash trying to toss one of + // these across the process boundary. I haven't the damndest idea why. + [flags] + enum MouseButtonState { - // !! LOAD BEARING !! If you make these Booleans (like they should be), - // then the app will crash trying to toss one of these across the - // process boundary. I haven't the damndest idea why. - Int32 IsLeftButtonDown; - Int32 IsMiddleButtonDown; - Int32 IsRightButtonDown; + IsLeftButtonDown = 0x1, + IsMiddleButtonDown = 0x2, + IsRightButtonDown = 0x4 }; [default_interface] runtimeclass ControlCore : ICoreState diff --git a/src/cascadia/TerminalControl/ControlInteractivity.cpp b/src/cascadia/TerminalControl/ControlInteractivity.cpp index 342ddef2d1a..e49759bbdab 100644 --- a/src/cascadia/TerminalControl/ControlInteractivity.cpp +++ b/src/cascadia/TerminalControl/ControlInteractivity.cpp @@ -32,7 +32,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation static constexpr TerminalInput::MouseButtonState toInternalMouseState(const Control::MouseButtonState& state) { return TerminalInput::MouseButtonState{ - state.IsLeftButtonDown != 0, state.IsMiddleButtonDown != 0, state.IsRightButtonDown != 0 + WI_IsFlagSet(state, MouseButtonState::IsLeftButtonDown), + WI_IsFlagSet(state, MouseButtonState::IsMiddleButtonDown), + WI_IsFlagSet(state, MouseButtonState::IsRightButtonDown) }; } @@ -202,7 +204,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation // GH#9396: we prioritize hyper-link over VT mouse events auto hyperlink = _core->GetHyperlink(terminalPosition); - if (buttonState.IsLeftButtonDown && + if (WI_IsFlagSet(buttonState, MouseButtonState::IsLeftButtonDown) && ctrlEnabled && !hyperlink.empty()) { const auto clickCount = _numberOfClicks(pixelPosition, timestamp); @@ -216,7 +218,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation { _core->SendMouseEvent(terminalPosition, pointerUpdateKind, modifiers, 0, toInternalMouseState(buttonState)); } - else if (buttonState.IsLeftButtonDown) + else if (WI_IsFlagSet(buttonState, MouseButtonState::IsLeftButtonDown)) { const auto clickCount = _numberOfClicks(pixelPosition, timestamp); // This formula enables the number of clicks to cycle properly @@ -251,7 +253,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation _singleClickTouchdownPos = std::nullopt; } } - else if (buttonState.IsRightButtonDown) + else if (WI_IsFlagSet(buttonState, MouseButtonState::IsRightButtonDown)) { // CopyOnSelect right click always pastes if (_core->CopyOnSelect() || !_core->HasSelection()) @@ -283,7 +285,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation { _core->SendMouseEvent(terminalPosition, pointerUpdateKind, modifiers, 0, toInternalMouseState(buttonState)); } - else if (focused && buttonState.IsLeftButtonDown) + else if (focused && WI_IsFlagSet(buttonState, MouseButtonState::IsLeftButtonDown)) { if (_singleClickTouchdownPos) { @@ -430,7 +432,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation } else { - _mouseScrollHandler(delta, pixelPosition, buttonState.IsLeftButtonDown); + _mouseScrollHandler(delta, pixelPosition, WI_IsFlagSet(buttonState, MouseButtonState::IsLeftButtonDown)); } return false; } diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index 96228a1bff6..dc0f35df0a5 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -43,6 +43,8 @@ constexpr const auto TerminalWarningBellInterval = std::chrono::milliseconds(100 DEFINE_ENUM_FLAG_OPERATORS(winrt::Microsoft::Terminal::Control::CopyFormat); +DEFINE_ENUM_FLAG_OPERATORS(winrt::Microsoft::Terminal::Control::MouseButtonState); + namespace winrt::Microsoft::Terminal::Control::implementation { TermControl::TermControl(IControlSettings settings, @@ -1219,9 +1221,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation const bool rightButtonDown) { const auto modifiers = _GetPressedModifierKeys(); - Control::MouseButtonState state{ leftButtonDown, - midButtonDown, - rightButtonDown }; + + Control::MouseButtonState state{}; + WI_SetFlagIf(state, Control::MouseButtonState::IsLeftButtonDown, leftButtonDown); + WI_SetFlagIf(state, Control::MouseButtonState::IsMiddleButtonDown, midButtonDown); + WI_SetFlagIf(state, Control::MouseButtonState::IsRightButtonDown, rightButtonDown); + return _interactivity.MouseWheel(modifiers, delta, _toTerminalOrigin(location), state); } @@ -2453,9 +2458,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation Control::MouseButtonState TermControl::GetPressedMouseButtons(const winrt::Windows::UI::Input::PointerPoint point) { - return Control::MouseButtonState{ point.Properties().IsLeftButtonPressed(), - point.Properties().IsMiddleButtonPressed(), - point.Properties().IsRightButtonPressed() }; + Control::MouseButtonState state{}; + WI_SetFlagIf(state, Control::MouseButtonState::IsLeftButtonDown, point.Properties().IsLeftButtonPressed()); + WI_SetFlagIf(state, Control::MouseButtonState::IsMiddleButtonDown, point.Properties().IsMiddleButtonPressed()); + WI_SetFlagIf(state, Control::MouseButtonState::IsRightButtonDown, point.Properties().IsRightButtonPressed()); + return state; } unsigned int TermControl::GetPointerUpdateKind(const winrt::Windows::UI::Input::PointerPoint point) From 1bc27d0c322fd8d2ded12a8c6482a300276ff336 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Mon, 24 May 2021 09:47:00 -0500 Subject: [PATCH 25/30] fix the build --- Samples.sln | 221 ++++++++++++++++++ .../ControlInteractivityTests.cpp | 36 +-- src/inc/til/point.h | 2 +- src/inc/til/rectangle.h | 2 +- 4 files changed, 242 insertions(+), 19 deletions(-) create mode 100644 Samples.sln diff --git a/Samples.sln b/Samples.sln new file mode 100644 index 00000000000..9b9fce4bd19 --- /dev/null +++ b/Samples.sln @@ -0,0 +1,221 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.31205.134 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}") = "Package", "samples\ScratchIslandApp\Package\Package.wapproj", "{CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SampleAppLib", "samples\ScratchIslandApp\SampleApp\SampleAppLib.vcxproj", "{A4394404-37F7-41C1-802B-49788D3720E3}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SampleApp", "samples\ScratchIslandApp\SampleApp\dll\SampleApp.vcxproj", "{26C51792-41A3-4FE0-AB5E-8B69D557BF91}" + ProjectSection(ProjectDependencies) = postProject + {A4394404-37F7-41C1-802B-49788D3720E3} = {A4394404-37F7-41C1-802B-49788D3720E3} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WindowExe", "samples\ScratchIslandApp\WindowExe\WindowExe.vcxproj", "{B4427499-9FDE-4208-B456-5BC580637633}" + ProjectSection(ProjectDependencies) = postProject + {26C51792-41A3-4FE0-AB5E-8B69D557BF91} = {26C51792-41A3-4FE0-AB5E-8B69D557BF91} + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Common Props", "Common Props", "{53DD5520-E64C-4C06-B472-7CE62CA539C9}" + ProjectSection(SolutionItems) = preProject + src\common.build.post.props = src\common.build.post.props + src\common.build.pre.props = src\common.build.pre.props + src\common.build.tests.props = src\common.build.tests.props + common.openconsole.props = common.openconsole.props + src\cppwinrt.build.post.props = src\cppwinrt.build.post.props + src\cppwinrt.build.pre.props = src\cppwinrt.build.pre.props + src\wap-common.build.post.props = src\wap-common.build.post.props + src\wap-common.build.pre.props = src\wap-common.build.pre.props + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fmt", "src\dep\fmt\fmt.vcxproj", "{6BAE5851-50D5-4934-8D5E-30361A8A40F3}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Types", "src\types\lib\types.vcxproj", "{18D09A24-8240-42D6-8CB6-236EEE820263}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "dependencies", "dependencies", "{75AC9360-76FD-4ABC-AFEC-EF342BD2B3E9}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + AuditMode|ARM64 = AuditMode|ARM64 + AuditMode|x64 = AuditMode|x64 + AuditMode|x86 = AuditMode|x86 + Debug|ARM64 = Debug|ARM64 + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Fuzzing|ARM64 = Fuzzing|ARM64 + Fuzzing|x64 = Fuzzing|x64 + Fuzzing|x86 = Fuzzing|x86 + Release|ARM64 = Release|ARM64 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.AuditMode|ARM64.ActiveCfg = Debug|ARM64 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.AuditMode|ARM64.Build.0 = Debug|ARM64 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.AuditMode|ARM64.Deploy.0 = Debug|ARM64 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.AuditMode|x64.ActiveCfg = Debug|x64 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.AuditMode|x64.Build.0 = Debug|x64 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.AuditMode|x64.Deploy.0 = Debug|x64 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.AuditMode|x86.ActiveCfg = Debug|x86 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.AuditMode|x86.Build.0 = Debug|x86 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.AuditMode|x86.Deploy.0 = Debug|x86 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Debug|ARM64.Build.0 = Debug|ARM64 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Debug|x64.ActiveCfg = Debug|x64 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Debug|x64.Build.0 = Debug|x64 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Debug|x64.Deploy.0 = Debug|x64 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Debug|x86.ActiveCfg = Debug|x86 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Debug|x86.Build.0 = Debug|x86 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Debug|x86.Deploy.0 = Debug|x86 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Fuzzing|ARM64.ActiveCfg = Debug|ARM64 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Fuzzing|ARM64.Build.0 = Debug|ARM64 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Fuzzing|ARM64.Deploy.0 = Debug|ARM64 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Fuzzing|x64.ActiveCfg = Debug|x64 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Fuzzing|x64.Build.0 = Debug|x64 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Fuzzing|x64.Deploy.0 = Debug|x64 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Fuzzing|x86.ActiveCfg = Debug|x86 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Fuzzing|x86.Build.0 = Debug|x86 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Fuzzing|x86.Deploy.0 = Debug|x86 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Release|ARM64.ActiveCfg = Release|ARM64 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Release|ARM64.Build.0 = Release|ARM64 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Release|ARM64.Deploy.0 = Release|ARM64 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Release|x64.ActiveCfg = Release|x64 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Release|x64.Build.0 = Release|x64 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Release|x64.Deploy.0 = Release|x64 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Release|x86.ActiveCfg = Release|x86 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Release|x86.Build.0 = Release|x86 + {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Release|x86.Deploy.0 = Release|x86 + {A4394404-37F7-41C1-802B-49788D3720E3}.AuditMode|ARM64.ActiveCfg = AuditMode|ARM64 + {A4394404-37F7-41C1-802B-49788D3720E3}.AuditMode|ARM64.Build.0 = AuditMode|ARM64 + {A4394404-37F7-41C1-802B-49788D3720E3}.AuditMode|x64.ActiveCfg = AuditMode|x64 + {A4394404-37F7-41C1-802B-49788D3720E3}.AuditMode|x64.Build.0 = AuditMode|x64 + {A4394404-37F7-41C1-802B-49788D3720E3}.AuditMode|x86.ActiveCfg = AuditMode|Win32 + {A4394404-37F7-41C1-802B-49788D3720E3}.AuditMode|x86.Build.0 = AuditMode|Win32 + {A4394404-37F7-41C1-802B-49788D3720E3}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {A4394404-37F7-41C1-802B-49788D3720E3}.Debug|ARM64.Build.0 = Debug|ARM64 + {A4394404-37F7-41C1-802B-49788D3720E3}.Debug|x64.ActiveCfg = Debug|x64 + {A4394404-37F7-41C1-802B-49788D3720E3}.Debug|x64.Build.0 = Debug|x64 + {A4394404-37F7-41C1-802B-49788D3720E3}.Debug|x86.ActiveCfg = Debug|Win32 + {A4394404-37F7-41C1-802B-49788D3720E3}.Debug|x86.Build.0 = Debug|Win32 + {A4394404-37F7-41C1-802B-49788D3720E3}.Fuzzing|ARM64.ActiveCfg = Fuzzing|ARM64 + {A4394404-37F7-41C1-802B-49788D3720E3}.Fuzzing|ARM64.Build.0 = Fuzzing|ARM64 + {A4394404-37F7-41C1-802B-49788D3720E3}.Fuzzing|x64.ActiveCfg = Fuzzing|x64 + {A4394404-37F7-41C1-802B-49788D3720E3}.Fuzzing|x64.Build.0 = Fuzzing|x64 + {A4394404-37F7-41C1-802B-49788D3720E3}.Fuzzing|x86.ActiveCfg = Fuzzing|Win32 + {A4394404-37F7-41C1-802B-49788D3720E3}.Fuzzing|x86.Build.0 = Fuzzing|Win32 + {A4394404-37F7-41C1-802B-49788D3720E3}.Release|ARM64.ActiveCfg = Release|ARM64 + {A4394404-37F7-41C1-802B-49788D3720E3}.Release|ARM64.Build.0 = Release|ARM64 + {A4394404-37F7-41C1-802B-49788D3720E3}.Release|x64.ActiveCfg = Release|x64 + {A4394404-37F7-41C1-802B-49788D3720E3}.Release|x64.Build.0 = Release|x64 + {A4394404-37F7-41C1-802B-49788D3720E3}.Release|x86.ActiveCfg = Release|Win32 + {A4394404-37F7-41C1-802B-49788D3720E3}.Release|x86.Build.0 = Release|Win32 + {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.AuditMode|ARM64.ActiveCfg = AuditMode|ARM64 + {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.AuditMode|ARM64.Build.0 = AuditMode|ARM64 + {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.AuditMode|x64.ActiveCfg = AuditMode|x64 + {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.AuditMode|x64.Build.0 = AuditMode|x64 + {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.AuditMode|x86.ActiveCfg = AuditMode|Win32 + {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.AuditMode|x86.Build.0 = AuditMode|Win32 + {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Debug|ARM64.Build.0 = Debug|ARM64 + {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Debug|x64.ActiveCfg = Debug|x64 + {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Debug|x64.Build.0 = Debug|x64 + {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Debug|x86.ActiveCfg = Debug|Win32 + {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Debug|x86.Build.0 = Debug|Win32 + {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Fuzzing|ARM64.ActiveCfg = Fuzzing|ARM64 + {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Fuzzing|ARM64.Build.0 = Fuzzing|ARM64 + {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Fuzzing|x64.ActiveCfg = Fuzzing|x64 + {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Fuzzing|x64.Build.0 = Fuzzing|x64 + {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Fuzzing|x86.ActiveCfg = Fuzzing|Win32 + {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Fuzzing|x86.Build.0 = Fuzzing|Win32 + {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Release|ARM64.ActiveCfg = Release|ARM64 + {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Release|ARM64.Build.0 = Release|ARM64 + {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Release|x64.ActiveCfg = Release|x64 + {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Release|x64.Build.0 = Release|x64 + {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Release|x86.ActiveCfg = Release|Win32 + {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Release|x86.Build.0 = Release|Win32 + {B4427499-9FDE-4208-B456-5BC580637633}.AuditMode|ARM64.ActiveCfg = AuditMode|ARM64 + {B4427499-9FDE-4208-B456-5BC580637633}.AuditMode|ARM64.Build.0 = AuditMode|ARM64 + {B4427499-9FDE-4208-B456-5BC580637633}.AuditMode|x64.ActiveCfg = AuditMode|x64 + {B4427499-9FDE-4208-B456-5BC580637633}.AuditMode|x64.Build.0 = AuditMode|x64 + {B4427499-9FDE-4208-B456-5BC580637633}.AuditMode|x86.ActiveCfg = AuditMode|Win32 + {B4427499-9FDE-4208-B456-5BC580637633}.AuditMode|x86.Build.0 = AuditMode|Win32 + {B4427499-9FDE-4208-B456-5BC580637633}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {B4427499-9FDE-4208-B456-5BC580637633}.Debug|ARM64.Build.0 = Debug|ARM64 + {B4427499-9FDE-4208-B456-5BC580637633}.Debug|x64.ActiveCfg = Debug|x64 + {B4427499-9FDE-4208-B456-5BC580637633}.Debug|x64.Build.0 = Debug|x64 + {B4427499-9FDE-4208-B456-5BC580637633}.Debug|x86.ActiveCfg = Debug|Win32 + {B4427499-9FDE-4208-B456-5BC580637633}.Debug|x86.Build.0 = Debug|Win32 + {B4427499-9FDE-4208-B456-5BC580637633}.Fuzzing|ARM64.ActiveCfg = Fuzzing|ARM64 + {B4427499-9FDE-4208-B456-5BC580637633}.Fuzzing|ARM64.Build.0 = Fuzzing|ARM64 + {B4427499-9FDE-4208-B456-5BC580637633}.Fuzzing|x64.ActiveCfg = Fuzzing|x64 + {B4427499-9FDE-4208-B456-5BC580637633}.Fuzzing|x64.Build.0 = Fuzzing|x64 + {B4427499-9FDE-4208-B456-5BC580637633}.Fuzzing|x86.ActiveCfg = Fuzzing|Win32 + {B4427499-9FDE-4208-B456-5BC580637633}.Fuzzing|x86.Build.0 = Fuzzing|Win32 + {B4427499-9FDE-4208-B456-5BC580637633}.Release|ARM64.ActiveCfg = Release|ARM64 + {B4427499-9FDE-4208-B456-5BC580637633}.Release|ARM64.Build.0 = Release|ARM64 + {B4427499-9FDE-4208-B456-5BC580637633}.Release|x64.ActiveCfg = Release|x64 + {B4427499-9FDE-4208-B456-5BC580637633}.Release|x64.Build.0 = Release|x64 + {B4427499-9FDE-4208-B456-5BC580637633}.Release|x86.ActiveCfg = Release|Win32 + {B4427499-9FDE-4208-B456-5BC580637633}.Release|x86.Build.0 = Release|Win32 + {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.AuditMode|ARM64.ActiveCfg = AuditMode|ARM64 + {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.AuditMode|ARM64.Build.0 = AuditMode|ARM64 + {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.AuditMode|x64.ActiveCfg = AuditMode|x64 + {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.AuditMode|x64.Build.0 = AuditMode|x64 + {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.AuditMode|x86.ActiveCfg = AuditMode|Win32 + {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.AuditMode|x86.Build.0 = AuditMode|Win32 + {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Debug|ARM64.Build.0 = Debug|ARM64 + {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Debug|x64.ActiveCfg = Debug|x64 + {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Debug|x64.Build.0 = Debug|x64 + {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Debug|x86.ActiveCfg = Debug|Win32 + {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Debug|x86.Build.0 = Debug|Win32 + {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Fuzzing|ARM64.ActiveCfg = Fuzzing|ARM64 + {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Fuzzing|ARM64.Build.0 = Fuzzing|ARM64 + {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Fuzzing|x64.ActiveCfg = Fuzzing|x64 + {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Fuzzing|x64.Build.0 = Fuzzing|x64 + {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Fuzzing|x86.ActiveCfg = Fuzzing|Win32 + {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Fuzzing|x86.Build.0 = Fuzzing|Win32 + {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Release|ARM64.ActiveCfg = Release|ARM64 + {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Release|ARM64.Build.0 = Release|ARM64 + {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Release|x64.ActiveCfg = Release|x64 + {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Release|x64.Build.0 = Release|x64 + {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Release|x86.ActiveCfg = Release|Win32 + {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Release|x86.Build.0 = Release|Win32 + {18D09A24-8240-42D6-8CB6-236EEE820263}.AuditMode|ARM64.ActiveCfg = AuditMode|ARM64 + {18D09A24-8240-42D6-8CB6-236EEE820263}.AuditMode|ARM64.Build.0 = AuditMode|ARM64 + {18D09A24-8240-42D6-8CB6-236EEE820263}.AuditMode|x64.ActiveCfg = AuditMode|x64 + {18D09A24-8240-42D6-8CB6-236EEE820263}.AuditMode|x64.Build.0 = AuditMode|x64 + {18D09A24-8240-42D6-8CB6-236EEE820263}.AuditMode|x86.ActiveCfg = AuditMode|Win32 + {18D09A24-8240-42D6-8CB6-236EEE820263}.AuditMode|x86.Build.0 = AuditMode|Win32 + {18D09A24-8240-42D6-8CB6-236EEE820263}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {18D09A24-8240-42D6-8CB6-236EEE820263}.Debug|ARM64.Build.0 = Debug|ARM64 + {18D09A24-8240-42D6-8CB6-236EEE820263}.Debug|x64.ActiveCfg = Debug|x64 + {18D09A24-8240-42D6-8CB6-236EEE820263}.Debug|x64.Build.0 = Debug|x64 + {18D09A24-8240-42D6-8CB6-236EEE820263}.Debug|x86.ActiveCfg = Debug|Win32 + {18D09A24-8240-42D6-8CB6-236EEE820263}.Debug|x86.Build.0 = Debug|Win32 + {18D09A24-8240-42D6-8CB6-236EEE820263}.Fuzzing|ARM64.ActiveCfg = Fuzzing|ARM64 + {18D09A24-8240-42D6-8CB6-236EEE820263}.Fuzzing|ARM64.Build.0 = Fuzzing|ARM64 + {18D09A24-8240-42D6-8CB6-236EEE820263}.Fuzzing|x64.ActiveCfg = Fuzzing|x64 + {18D09A24-8240-42D6-8CB6-236EEE820263}.Fuzzing|x64.Build.0 = Fuzzing|x64 + {18D09A24-8240-42D6-8CB6-236EEE820263}.Fuzzing|x86.ActiveCfg = Fuzzing|Win32 + {18D09A24-8240-42D6-8CB6-236EEE820263}.Fuzzing|x86.Build.0 = Fuzzing|Win32 + {18D09A24-8240-42D6-8CB6-236EEE820263}.Release|ARM64.ActiveCfg = Release|ARM64 + {18D09A24-8240-42D6-8CB6-236EEE820263}.Release|ARM64.Build.0 = Release|ARM64 + {18D09A24-8240-42D6-8CB6-236EEE820263}.Release|x64.ActiveCfg = Release|x64 + {18D09A24-8240-42D6-8CB6-236EEE820263}.Release|x64.Build.0 = Release|x64 + {18D09A24-8240-42D6-8CB6-236EEE820263}.Release|x86.ActiveCfg = Release|Win32 + {18D09A24-8240-42D6-8CB6-236EEE820263}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {6BAE5851-50D5-4934-8D5E-30361A8A40F3} = {75AC9360-76FD-4ABC-AFEC-EF342BD2B3E9} + {18D09A24-8240-42D6-8CB6-236EEE820263} = {75AC9360-76FD-4ABC-AFEC-EF342BD2B3E9} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {05EAE315-9188-4D7B-B889-7D5F480A8915} + EndGlobalSection +EndGlobal diff --git a/src/cascadia/UnitTests_Control/ControlInteractivityTests.cpp b/src/cascadia/UnitTests_Control/ControlInteractivityTests.cpp index 4dc10911190..f4c89311797 100644 --- a/src/cascadia/UnitTests_Control/ControlInteractivityTests.cpp +++ b/src/cascadia/UnitTests_Control/ControlInteractivityTests.cpp @@ -118,6 +118,7 @@ namespace ControlUnitTests core->TransparencyChanged(opacityCallback); const auto modifiers = ControlKeyStates(ControlKeyStates::RightCtrlPressed | ControlKeyStates::ShiftPressed); + const Control::MouseButtonState buttonState{}; Log::Comment(L"Scroll in the positive direction, increasing opacity"); // Scroll more than enough times to get to 1.0 from .5. @@ -134,7 +135,7 @@ namespace ControlUnitTests interactivity->MouseWheel(modifiers, 30, til::point{ 0, 0 }, - { false, false, false }); + buttonState); } Log::Comment(L"Scroll in the negative direction, decreasing opacity"); @@ -152,7 +153,7 @@ namespace ControlUnitTests interactivity->MouseWheel(modifiers, 30, til::point{ 0, 0 }, - { false, false, false }); + buttonState); } } @@ -197,6 +198,7 @@ namespace ControlUnitTests VERIFY_ARE_EQUAL(41, core->BufferHeight()); Log::Comment(L"Scroll up a line"); + const Control::MouseButtonState buttonState{}; const auto modifiers = ControlKeyStates(); expectedBufferHeight = 41; expectedTop = 20; @@ -204,7 +206,7 @@ namespace ControlUnitTests interactivity->MouseWheel(modifiers, WHEEL_DELTA, til::point{ 0, 0 }, - { false, false, false }); + buttonState); Log::Comment(L"Scroll up 19 more times, to the top"); for (int i = 0; i < 20; ++i) @@ -213,18 +215,18 @@ namespace ControlUnitTests interactivity->MouseWheel(modifiers, WHEEL_DELTA, til::point{ 0, 0 }, - { false, false, false }); + buttonState); } Log::Comment(L"Scrolling up more should do nothing"); expectedTop = 0; interactivity->MouseWheel(modifiers, WHEEL_DELTA, til::point{ 0, 0 }, - { false, false, false }); + buttonState); interactivity->MouseWheel(modifiers, WHEEL_DELTA, til::point{ 0, 0 }, - { false, false, false }); + buttonState); Log::Comment(L"Scroll down 21 more times, to the bottom"); for (int i = 0; i < 21; ++i) @@ -234,7 +236,7 @@ namespace ControlUnitTests interactivity->MouseWheel(modifiers, -WHEEL_DELTA, til::point{ 0, 0 }, - { false, false, false }); + buttonState); Log::Comment(NoThrowString().Format(L"internal scrollbar pos:%f", interactivity->_internalScrollbarPosition)); } Log::Comment(L"Scrolling up more should do nothing"); @@ -242,11 +244,11 @@ namespace ControlUnitTests interactivity->MouseWheel(modifiers, -WHEEL_DELTA, til::point{ 0, 0 }, - { false, false, false }); + buttonState); interactivity->MouseWheel(modifiers, -WHEEL_DELTA, til::point{ 0, 0 }, - { false, false, false }); + buttonState); } void ControlInteractivityTests::CreateSubsequentSelectionWithDragging() @@ -260,8 +262,8 @@ namespace ControlUnitTests // For this test, don't use any modifiers const auto modifiers = ControlKeyStates(); - const Control::MouseButtonState leftMouseDown{ true, false, false }; - const Control::MouseButtonState noMouseDown{ false, false, false }; + const Control::MouseButtonState leftMouseDown{ Control::MouseButtonState::IsLeftButtonDown }; + const Control::MouseButtonState noMouseDown{}; const til::size fontSize{ 9, 21 }; @@ -358,8 +360,8 @@ namespace ControlUnitTests // For this test, don't use any modifiers const auto modifiers = ControlKeyStates(); - const Control::MouseButtonState leftMouseDown{ true, false, false }; - const Control::MouseButtonState noMouseDown{ false, false, false }; + const Control::MouseButtonState leftMouseDown{ Control::MouseButtonState::IsLeftButtonDown }; + const Control::MouseButtonState noMouseDown{}; const til::size fontSize{ 9, 21 }; @@ -401,7 +403,7 @@ namespace ControlUnitTests interactivity->MouseWheel(modifiers, WHEEL_DELTA, cursorPosition1, - { true, false, false }); + leftMouseDown); Log::Comment(L"Verify the location of the selection"); // The viewport is now on row 20, so the selection will be on: @@ -444,7 +446,7 @@ namespace ControlUnitTests const int delta = WHEEL_DELTA / 5; const til::point mousePos{ 0, 0 }; - Control::MouseButtonState state{ false, false, false }; + Control::MouseButtonState state{}; interactivity->MouseWheel(modifiers, delta, mousePos, state); // 1/5 VERIFY_ARE_EQUAL(21, core->ScrollOffset()); @@ -508,8 +510,8 @@ namespace ControlUnitTests // For this test, don't use any modifiers const auto modifiers = ControlKeyStates(); - const Control::MouseButtonState leftMouseDown{ true, false, false }; - const Control::MouseButtonState noMouseDown{ false, false, false }; + const Control::MouseButtonState leftMouseDown{ Control::MouseButtonState::IsLeftButtonDown }; + const Control::MouseButtonState noMouseDown{}; const til::size fontSize{ 9, 21 }; diff --git a/src/inc/til/point.h b/src/inc/til/point.h index 369a827d603..5d47588255e 100644 --- a/src/inc/til/point.h +++ b/src/inc/til/point.h @@ -344,7 +344,7 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned" { } - operator winrt::Microsoft::Terminal::Core::Point() const noexcept + operator winrt::Microsoft::Terminal::Core::Point() const { winrt::Microsoft::Terminal::Core::Point ret; ret.X = x(); diff --git a/src/inc/til/rectangle.h b/src/inc/til/rectangle.h index 180df49d151..43bae773f0b 100644 --- a/src/inc/til/rectangle.h +++ b/src/inc/til/rectangle.h @@ -884,7 +884,7 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned" #endif #ifdef WINRT_Microsoft_Terminal_Core_H - operator winrt::Microsoft::Terminal::Core::Padding() const noexcept + operator winrt::Microsoft::Terminal::Core::Padding() const { winrt::Microsoft::Terminal::Core::Padding ret; THROW_HR_IF(E_ABORT, !base::MakeCheckedNum(left()).AssignIfValid(&ret.Left)); From 3cace60a33ccb0ff01d03cd20682ac24670c0df7 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Mon, 24 May 2021 10:55:21 -0500 Subject: [PATCH 26/30] chances are, this will fix the x86 build --- src/cascadia/TerminalApp/AppLogic.cpp | 4 ++-- src/cascadia/TerminalApp/AppLogic.h | 4 ++-- src/cascadia/TerminalApp/TerminalPage.cpp | 8 ++++---- src/cascadia/TerminalApp/TerminalPage.h | 4 ++-- src/cascadia/TerminalControl/TermControl.cpp | 4 ++-- src/cascadia/TerminalControl/TermControl.h | 4 ++-- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/cascadia/TerminalApp/AppLogic.cpp b/src/cascadia/TerminalApp/AppLogic.cpp index 4c9e7612bb2..7a1dde9b70f 100644 --- a/src/cascadia/TerminalApp/AppLogic.cpp +++ b/src/cascadia/TerminalApp/AppLogic.cpp @@ -1151,7 +1151,7 @@ namespace winrt::TerminalApp::implementation // - Gets the taskbar state value from the last active control // Return Value: // - The taskbar state of the last active control - size_t AppLogic::GetLastActiveControlTaskbarState() + uint64_t AppLogic::GetLastActiveControlTaskbarState() { if (_root) { @@ -1164,7 +1164,7 @@ namespace winrt::TerminalApp::implementation // - Gets the taskbar progress value from the last active control // Return Value: // - The taskbar progress of the last active control - size_t AppLogic::GetLastActiveControlTaskbarProgress() + uint64_t AppLogic::GetLastActiveControlTaskbarProgress() { if (_root) { diff --git a/src/cascadia/TerminalApp/AppLogic.h b/src/cascadia/TerminalApp/AppLogic.h index c86b543005b..d2d49c4f30c 100644 --- a/src/cascadia/TerminalApp/AppLogic.h +++ b/src/cascadia/TerminalApp/AppLogic.h @@ -85,8 +85,8 @@ namespace winrt::TerminalApp::implementation void WindowCloseButtonClicked(); - size_t GetLastActiveControlTaskbarState(); - size_t GetLastActiveControlTaskbarProgress(); + uint64_t GetLastActiveControlTaskbarState(); + uint64_t GetLastActiveControlTaskbarProgress(); winrt::Windows::Foundation::IAsyncOperation ShowDialog(winrt::Windows::UI::Xaml::Controls::ContentDialog dialog); diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index 07afc42ac94..b6192ba7d87 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -2005,11 +2005,11 @@ namespace winrt::TerminalApp::implementation // - Gets the taskbar state value from the last active control // Return Value: // - The taskbar state of the last active control - size_t TerminalPage::GetLastActiveControlTaskbarState() + uint64_t TerminalPage::GetLastActiveControlTaskbarState() { if (auto control{ _GetActiveControl() }) { - return gsl::narrow_cast(control.TaskbarState()); + return control.TaskbarState(); } return {}; } @@ -2018,11 +2018,11 @@ namespace winrt::TerminalApp::implementation // - Gets the taskbar progress value from the last active control // Return Value: // - The taskbar progress of the last active control - size_t TerminalPage::GetLastActiveControlTaskbarProgress() + uint64_t TerminalPage::GetLastActiveControlTaskbarProgress() { if (auto control{ _GetActiveControl() }) { - return gsl::narrow_cast(control.TaskbarProgress()); + return control.TaskbarProgress(); } return {}; } diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h index 794fd0e1568..be449da9e2b 100644 --- a/src/cascadia/TerminalApp/TerminalPage.h +++ b/src/cascadia/TerminalApp/TerminalPage.h @@ -85,8 +85,8 @@ namespace winrt::TerminalApp::implementation winrt::TerminalApp::IDialogPresenter DialogPresenter() const; void DialogPresenter(winrt::TerminalApp::IDialogPresenter dialogPresenter); - size_t GetLastActiveControlTaskbarState(); - size_t GetLastActiveControlTaskbarProgress(); + uint64_t GetLastActiveControlTaskbarState(); + uint64_t GetLastActiveControlTaskbarProgress(); void ShowKeyboardServiceWarning(); winrt::hstring KeyboardServiceDisabledText(); diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index fd8bb31e87c..c1b4b6c1da7 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -2351,7 +2351,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation // - Gets the internal taskbar state value // Return Value: // - The taskbar state of this control - const size_t TermControl::TaskbarState() const noexcept + const uint64_t TermControl::TaskbarState() const noexcept { return _core.TaskbarState(); } @@ -2360,7 +2360,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation // - Gets the internal taskbar progress value // Return Value: // - The taskbar progress of this control - const size_t TermControl::TaskbarProgress() const noexcept + const uint64_t TermControl::TaskbarProgress() const noexcept { return _core.TaskbarProgress(); } diff --git a/src/cascadia/TerminalControl/TermControl.h b/src/cascadia/TerminalControl/TermControl.h index 83bef7728fa..48817d4825a 100644 --- a/src/cascadia/TerminalControl/TermControl.h +++ b/src/cascadia/TerminalControl/TermControl.h @@ -40,8 +40,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation float SnapDimensionToGrid(const bool widthOrHeight, const float dimension); #pragma region ICoreState - const size_t TaskbarState() const noexcept; - const size_t TaskbarProgress() const noexcept; + const uint64_t TaskbarState() const noexcept; + const uint64_t TaskbarProgress() const noexcept; hstring Title(); Windows::Foundation::IReference TabColor() noexcept; From 265bd9fbc3b3f60a5fef6ba1cdd88b29778e35ed Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Mon, 24 May 2021 11:01:43 -0500 Subject: [PATCH 27/30] I am ashamed, this should not be there --- Samples.sln | 221 ---------------------------------------------------- 1 file changed, 221 deletions(-) delete mode 100644 Samples.sln diff --git a/Samples.sln b/Samples.sln deleted file mode 100644 index 9b9fce4bd19..00000000000 --- a/Samples.sln +++ /dev/null @@ -1,221 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.31205.134 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}") = "Package", "samples\ScratchIslandApp\Package\Package.wapproj", "{CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SampleAppLib", "samples\ScratchIslandApp\SampleApp\SampleAppLib.vcxproj", "{A4394404-37F7-41C1-802B-49788D3720E3}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SampleApp", "samples\ScratchIslandApp\SampleApp\dll\SampleApp.vcxproj", "{26C51792-41A3-4FE0-AB5E-8B69D557BF91}" - ProjectSection(ProjectDependencies) = postProject - {A4394404-37F7-41C1-802B-49788D3720E3} = {A4394404-37F7-41C1-802B-49788D3720E3} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WindowExe", "samples\ScratchIslandApp\WindowExe\WindowExe.vcxproj", "{B4427499-9FDE-4208-B456-5BC580637633}" - ProjectSection(ProjectDependencies) = postProject - {26C51792-41A3-4FE0-AB5E-8B69D557BF91} = {26C51792-41A3-4FE0-AB5E-8B69D557BF91} - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Common Props", "Common Props", "{53DD5520-E64C-4C06-B472-7CE62CA539C9}" - ProjectSection(SolutionItems) = preProject - src\common.build.post.props = src\common.build.post.props - src\common.build.pre.props = src\common.build.pre.props - src\common.build.tests.props = src\common.build.tests.props - common.openconsole.props = common.openconsole.props - src\cppwinrt.build.post.props = src\cppwinrt.build.post.props - src\cppwinrt.build.pre.props = src\cppwinrt.build.pre.props - src\wap-common.build.post.props = src\wap-common.build.post.props - src\wap-common.build.pre.props = src\wap-common.build.pre.props - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fmt", "src\dep\fmt\fmt.vcxproj", "{6BAE5851-50D5-4934-8D5E-30361A8A40F3}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Types", "src\types\lib\types.vcxproj", "{18D09A24-8240-42D6-8CB6-236EEE820263}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "dependencies", "dependencies", "{75AC9360-76FD-4ABC-AFEC-EF342BD2B3E9}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - AuditMode|ARM64 = AuditMode|ARM64 - AuditMode|x64 = AuditMode|x64 - AuditMode|x86 = AuditMode|x86 - Debug|ARM64 = Debug|ARM64 - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Fuzzing|ARM64 = Fuzzing|ARM64 - Fuzzing|x64 = Fuzzing|x64 - Fuzzing|x86 = Fuzzing|x86 - Release|ARM64 = Release|ARM64 - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.AuditMode|ARM64.ActiveCfg = Debug|ARM64 - {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.AuditMode|ARM64.Build.0 = Debug|ARM64 - {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.AuditMode|ARM64.Deploy.0 = Debug|ARM64 - {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.AuditMode|x64.ActiveCfg = Debug|x64 - {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.AuditMode|x64.Build.0 = Debug|x64 - {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.AuditMode|x64.Deploy.0 = Debug|x64 - {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.AuditMode|x86.ActiveCfg = Debug|x86 - {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.AuditMode|x86.Build.0 = Debug|x86 - {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.AuditMode|x86.Deploy.0 = Debug|x86 - {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Debug|ARM64.Build.0 = Debug|ARM64 - {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Debug|ARM64.Deploy.0 = Debug|ARM64 - {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Debug|x64.ActiveCfg = Debug|x64 - {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Debug|x64.Build.0 = Debug|x64 - {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Debug|x64.Deploy.0 = Debug|x64 - {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Debug|x86.ActiveCfg = Debug|x86 - {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Debug|x86.Build.0 = Debug|x86 - {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Debug|x86.Deploy.0 = Debug|x86 - {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Fuzzing|ARM64.ActiveCfg = Debug|ARM64 - {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Fuzzing|ARM64.Build.0 = Debug|ARM64 - {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Fuzzing|ARM64.Deploy.0 = Debug|ARM64 - {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Fuzzing|x64.ActiveCfg = Debug|x64 - {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Fuzzing|x64.Build.0 = Debug|x64 - {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Fuzzing|x64.Deploy.0 = Debug|x64 - {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Fuzzing|x86.ActiveCfg = Debug|x86 - {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Fuzzing|x86.Build.0 = Debug|x86 - {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Fuzzing|x86.Deploy.0 = Debug|x86 - {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Release|ARM64.ActiveCfg = Release|ARM64 - {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Release|ARM64.Build.0 = Release|ARM64 - {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Release|ARM64.Deploy.0 = Release|ARM64 - {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Release|x64.ActiveCfg = Release|x64 - {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Release|x64.Build.0 = Release|x64 - {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Release|x64.Deploy.0 = Release|x64 - {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Release|x86.ActiveCfg = Release|x86 - {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Release|x86.Build.0 = Release|x86 - {CF31505E-3BAE-4C0A-81D7-F1EB279F40BB}.Release|x86.Deploy.0 = Release|x86 - {A4394404-37F7-41C1-802B-49788D3720E3}.AuditMode|ARM64.ActiveCfg = AuditMode|ARM64 - {A4394404-37F7-41C1-802B-49788D3720E3}.AuditMode|ARM64.Build.0 = AuditMode|ARM64 - {A4394404-37F7-41C1-802B-49788D3720E3}.AuditMode|x64.ActiveCfg = AuditMode|x64 - {A4394404-37F7-41C1-802B-49788D3720E3}.AuditMode|x64.Build.0 = AuditMode|x64 - {A4394404-37F7-41C1-802B-49788D3720E3}.AuditMode|x86.ActiveCfg = AuditMode|Win32 - {A4394404-37F7-41C1-802B-49788D3720E3}.AuditMode|x86.Build.0 = AuditMode|Win32 - {A4394404-37F7-41C1-802B-49788D3720E3}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {A4394404-37F7-41C1-802B-49788D3720E3}.Debug|ARM64.Build.0 = Debug|ARM64 - {A4394404-37F7-41C1-802B-49788D3720E3}.Debug|x64.ActiveCfg = Debug|x64 - {A4394404-37F7-41C1-802B-49788D3720E3}.Debug|x64.Build.0 = Debug|x64 - {A4394404-37F7-41C1-802B-49788D3720E3}.Debug|x86.ActiveCfg = Debug|Win32 - {A4394404-37F7-41C1-802B-49788D3720E3}.Debug|x86.Build.0 = Debug|Win32 - {A4394404-37F7-41C1-802B-49788D3720E3}.Fuzzing|ARM64.ActiveCfg = Fuzzing|ARM64 - {A4394404-37F7-41C1-802B-49788D3720E3}.Fuzzing|ARM64.Build.0 = Fuzzing|ARM64 - {A4394404-37F7-41C1-802B-49788D3720E3}.Fuzzing|x64.ActiveCfg = Fuzzing|x64 - {A4394404-37F7-41C1-802B-49788D3720E3}.Fuzzing|x64.Build.0 = Fuzzing|x64 - {A4394404-37F7-41C1-802B-49788D3720E3}.Fuzzing|x86.ActiveCfg = Fuzzing|Win32 - {A4394404-37F7-41C1-802B-49788D3720E3}.Fuzzing|x86.Build.0 = Fuzzing|Win32 - {A4394404-37F7-41C1-802B-49788D3720E3}.Release|ARM64.ActiveCfg = Release|ARM64 - {A4394404-37F7-41C1-802B-49788D3720E3}.Release|ARM64.Build.0 = Release|ARM64 - {A4394404-37F7-41C1-802B-49788D3720E3}.Release|x64.ActiveCfg = Release|x64 - {A4394404-37F7-41C1-802B-49788D3720E3}.Release|x64.Build.0 = Release|x64 - {A4394404-37F7-41C1-802B-49788D3720E3}.Release|x86.ActiveCfg = Release|Win32 - {A4394404-37F7-41C1-802B-49788D3720E3}.Release|x86.Build.0 = Release|Win32 - {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.AuditMode|ARM64.ActiveCfg = AuditMode|ARM64 - {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.AuditMode|ARM64.Build.0 = AuditMode|ARM64 - {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.AuditMode|x64.ActiveCfg = AuditMode|x64 - {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.AuditMode|x64.Build.0 = AuditMode|x64 - {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.AuditMode|x86.ActiveCfg = AuditMode|Win32 - {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.AuditMode|x86.Build.0 = AuditMode|Win32 - {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Debug|ARM64.Build.0 = Debug|ARM64 - {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Debug|x64.ActiveCfg = Debug|x64 - {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Debug|x64.Build.0 = Debug|x64 - {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Debug|x86.ActiveCfg = Debug|Win32 - {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Debug|x86.Build.0 = Debug|Win32 - {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Fuzzing|ARM64.ActiveCfg = Fuzzing|ARM64 - {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Fuzzing|ARM64.Build.0 = Fuzzing|ARM64 - {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Fuzzing|x64.ActiveCfg = Fuzzing|x64 - {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Fuzzing|x64.Build.0 = Fuzzing|x64 - {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Fuzzing|x86.ActiveCfg = Fuzzing|Win32 - {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Fuzzing|x86.Build.0 = Fuzzing|Win32 - {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Release|ARM64.ActiveCfg = Release|ARM64 - {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Release|ARM64.Build.0 = Release|ARM64 - {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Release|x64.ActiveCfg = Release|x64 - {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Release|x64.Build.0 = Release|x64 - {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Release|x86.ActiveCfg = Release|Win32 - {26C51792-41A3-4FE0-AB5E-8B69D557BF91}.Release|x86.Build.0 = Release|Win32 - {B4427499-9FDE-4208-B456-5BC580637633}.AuditMode|ARM64.ActiveCfg = AuditMode|ARM64 - {B4427499-9FDE-4208-B456-5BC580637633}.AuditMode|ARM64.Build.0 = AuditMode|ARM64 - {B4427499-9FDE-4208-B456-5BC580637633}.AuditMode|x64.ActiveCfg = AuditMode|x64 - {B4427499-9FDE-4208-B456-5BC580637633}.AuditMode|x64.Build.0 = AuditMode|x64 - {B4427499-9FDE-4208-B456-5BC580637633}.AuditMode|x86.ActiveCfg = AuditMode|Win32 - {B4427499-9FDE-4208-B456-5BC580637633}.AuditMode|x86.Build.0 = AuditMode|Win32 - {B4427499-9FDE-4208-B456-5BC580637633}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {B4427499-9FDE-4208-B456-5BC580637633}.Debug|ARM64.Build.0 = Debug|ARM64 - {B4427499-9FDE-4208-B456-5BC580637633}.Debug|x64.ActiveCfg = Debug|x64 - {B4427499-9FDE-4208-B456-5BC580637633}.Debug|x64.Build.0 = Debug|x64 - {B4427499-9FDE-4208-B456-5BC580637633}.Debug|x86.ActiveCfg = Debug|Win32 - {B4427499-9FDE-4208-B456-5BC580637633}.Debug|x86.Build.0 = Debug|Win32 - {B4427499-9FDE-4208-B456-5BC580637633}.Fuzzing|ARM64.ActiveCfg = Fuzzing|ARM64 - {B4427499-9FDE-4208-B456-5BC580637633}.Fuzzing|ARM64.Build.0 = Fuzzing|ARM64 - {B4427499-9FDE-4208-B456-5BC580637633}.Fuzzing|x64.ActiveCfg = Fuzzing|x64 - {B4427499-9FDE-4208-B456-5BC580637633}.Fuzzing|x64.Build.0 = Fuzzing|x64 - {B4427499-9FDE-4208-B456-5BC580637633}.Fuzzing|x86.ActiveCfg = Fuzzing|Win32 - {B4427499-9FDE-4208-B456-5BC580637633}.Fuzzing|x86.Build.0 = Fuzzing|Win32 - {B4427499-9FDE-4208-B456-5BC580637633}.Release|ARM64.ActiveCfg = Release|ARM64 - {B4427499-9FDE-4208-B456-5BC580637633}.Release|ARM64.Build.0 = Release|ARM64 - {B4427499-9FDE-4208-B456-5BC580637633}.Release|x64.ActiveCfg = Release|x64 - {B4427499-9FDE-4208-B456-5BC580637633}.Release|x64.Build.0 = Release|x64 - {B4427499-9FDE-4208-B456-5BC580637633}.Release|x86.ActiveCfg = Release|Win32 - {B4427499-9FDE-4208-B456-5BC580637633}.Release|x86.Build.0 = Release|Win32 - {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.AuditMode|ARM64.ActiveCfg = AuditMode|ARM64 - {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.AuditMode|ARM64.Build.0 = AuditMode|ARM64 - {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.AuditMode|x64.ActiveCfg = AuditMode|x64 - {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.AuditMode|x64.Build.0 = AuditMode|x64 - {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.AuditMode|x86.ActiveCfg = AuditMode|Win32 - {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.AuditMode|x86.Build.0 = AuditMode|Win32 - {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Debug|ARM64.Build.0 = Debug|ARM64 - {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Debug|x64.ActiveCfg = Debug|x64 - {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Debug|x64.Build.0 = Debug|x64 - {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Debug|x86.ActiveCfg = Debug|Win32 - {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Debug|x86.Build.0 = Debug|Win32 - {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Fuzzing|ARM64.ActiveCfg = Fuzzing|ARM64 - {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Fuzzing|ARM64.Build.0 = Fuzzing|ARM64 - {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Fuzzing|x64.ActiveCfg = Fuzzing|x64 - {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Fuzzing|x64.Build.0 = Fuzzing|x64 - {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Fuzzing|x86.ActiveCfg = Fuzzing|Win32 - {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Fuzzing|x86.Build.0 = Fuzzing|Win32 - {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Release|ARM64.ActiveCfg = Release|ARM64 - {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Release|ARM64.Build.0 = Release|ARM64 - {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Release|x64.ActiveCfg = Release|x64 - {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Release|x64.Build.0 = Release|x64 - {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Release|x86.ActiveCfg = Release|Win32 - {6BAE5851-50D5-4934-8D5E-30361A8A40F3}.Release|x86.Build.0 = Release|Win32 - {18D09A24-8240-42D6-8CB6-236EEE820263}.AuditMode|ARM64.ActiveCfg = AuditMode|ARM64 - {18D09A24-8240-42D6-8CB6-236EEE820263}.AuditMode|ARM64.Build.0 = AuditMode|ARM64 - {18D09A24-8240-42D6-8CB6-236EEE820263}.AuditMode|x64.ActiveCfg = AuditMode|x64 - {18D09A24-8240-42D6-8CB6-236EEE820263}.AuditMode|x64.Build.0 = AuditMode|x64 - {18D09A24-8240-42D6-8CB6-236EEE820263}.AuditMode|x86.ActiveCfg = AuditMode|Win32 - {18D09A24-8240-42D6-8CB6-236EEE820263}.AuditMode|x86.Build.0 = AuditMode|Win32 - {18D09A24-8240-42D6-8CB6-236EEE820263}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {18D09A24-8240-42D6-8CB6-236EEE820263}.Debug|ARM64.Build.0 = Debug|ARM64 - {18D09A24-8240-42D6-8CB6-236EEE820263}.Debug|x64.ActiveCfg = Debug|x64 - {18D09A24-8240-42D6-8CB6-236EEE820263}.Debug|x64.Build.0 = Debug|x64 - {18D09A24-8240-42D6-8CB6-236EEE820263}.Debug|x86.ActiveCfg = Debug|Win32 - {18D09A24-8240-42D6-8CB6-236EEE820263}.Debug|x86.Build.0 = Debug|Win32 - {18D09A24-8240-42D6-8CB6-236EEE820263}.Fuzzing|ARM64.ActiveCfg = Fuzzing|ARM64 - {18D09A24-8240-42D6-8CB6-236EEE820263}.Fuzzing|ARM64.Build.0 = Fuzzing|ARM64 - {18D09A24-8240-42D6-8CB6-236EEE820263}.Fuzzing|x64.ActiveCfg = Fuzzing|x64 - {18D09A24-8240-42D6-8CB6-236EEE820263}.Fuzzing|x64.Build.0 = Fuzzing|x64 - {18D09A24-8240-42D6-8CB6-236EEE820263}.Fuzzing|x86.ActiveCfg = Fuzzing|Win32 - {18D09A24-8240-42D6-8CB6-236EEE820263}.Fuzzing|x86.Build.0 = Fuzzing|Win32 - {18D09A24-8240-42D6-8CB6-236EEE820263}.Release|ARM64.ActiveCfg = Release|ARM64 - {18D09A24-8240-42D6-8CB6-236EEE820263}.Release|ARM64.Build.0 = Release|ARM64 - {18D09A24-8240-42D6-8CB6-236EEE820263}.Release|x64.ActiveCfg = Release|x64 - {18D09A24-8240-42D6-8CB6-236EEE820263}.Release|x64.Build.0 = Release|x64 - {18D09A24-8240-42D6-8CB6-236EEE820263}.Release|x86.ActiveCfg = Release|Win32 - {18D09A24-8240-42D6-8CB6-236EEE820263}.Release|x86.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {6BAE5851-50D5-4934-8D5E-30361A8A40F3} = {75AC9360-76FD-4ABC-AFEC-EF342BD2B3E9} - {18D09A24-8240-42D6-8CB6-236EEE820263} = {75AC9360-76FD-4ABC-AFEC-EF342BD2B3E9} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {05EAE315-9188-4D7B-B889-7D5F480A8915} - EndGlobalSection -EndGlobal From c8a29575274d513044bf294e89b3261069b36548 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Mon, 24 May 2021 15:00:17 -0500 Subject: [PATCH 28/30] Port the automation peer crash fix to this branch, @carlos-zamora --- src/cascadia/TerminalControl/TermControl.cpp | 26 +++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index c1b4b6c1da7..fd55b4dba97 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -422,10 +422,13 @@ namespace winrt::Microsoft::Terminal::Control::implementation } _interactivity.UpdateSettings(); - _automationPeer.SetControlPadding(Core::Padding{ newMargin.Left, - newMargin.Top, - newMargin.Right, - newMargin.Bottom }); + if (_automationPeer) + { + _automationPeer.SetControlPadding(Core::Padding{ newMargin.Left, + newMargin.Top, + newMargin.Right, + newMargin.Bottom }); + } } // Method Description: @@ -535,10 +538,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation { // create a custom automation peer with this code pattern: // (https://docs.microsoft.com/en-us/windows/uwp/design/accessibility/custom-automation-peers) - const auto& interactivityAutoPeer = _interactivity.OnCreateAutomationPeer(); - auto autoPeer = winrt::make_self(this, interactivityAutoPeer); - _automationPeer = *autoPeer; - return *autoPeer; + if (const auto& interactivityAutoPeer = _interactivity.OnCreateAutomationPeer()) + { + auto autoPeer = winrt::make_self(this, interactivityAutoPeer); + _automationPeer = *autoPeer; + return *autoPeer; + } } return nullptr; } @@ -1539,7 +1544,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation const auto newSize = e.NewSize(); _core.SizeChanged(newSize.Width, newSize.Height); - _automationPeer.UpdateControlBounds(); + if (_automationPeer) + { + _automationPeer.UpdateControlBounds(); + } } // Method Description: From 074f67c7a999e0f6747cabdc95a5f5ede2a861d7 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Tue, 25 May 2021 07:26:45 -0500 Subject: [PATCH 29/30] The comment literally says to put this first. Why didn't I put this first --- src/cascadia/TerminalControl/TermControl.cpp | 5 ++++- src/cascadia/TerminalControl/TermControl.h | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index fd55b4dba97..9f88e2e3545 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -1661,7 +1661,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation void TermControl::_CursorPositionChanged(const IInspectable& /*sender*/, const IInspectable& /*args*/) { - _tsfTryRedrawCanvas->Run(); + if (_tsfTryRedrawCanvas) + { + _tsfTryRedrawCanvas->Run(); + } } hstring TermControl::Title() diff --git a/src/cascadia/TerminalControl/TermControl.h b/src/cascadia/TerminalControl/TermControl.h index 48817d4825a..cd92e04cb30 100644 --- a/src/cascadia/TerminalControl/TermControl.h +++ b/src/cascadia/TerminalControl/TermControl.h @@ -141,8 +141,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation // (C++ class members are destroyed in reverse order.) // Further, the TermControlAutomationPeer must be destructed after _uiaEngine! Control::TermControlAutomationPeer _automationPeer{ nullptr }; - Control::ControlCore _core{ nullptr }; Control::ControlInteractivity _interactivity{ nullptr }; + Control::ControlCore _core{ nullptr }; winrt::com_ptr _searchBox; From e643885673c8ddb0487c4db190253b817ce1a301 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Thu, 8 Jul 2021 09:38:15 -0500 Subject: [PATCH 30/30] minor nits from carlos --- src/cascadia/TerminalControl/ControlCore.cpp | 2 +- .../TerminalControl/ControlInteractivity.cpp | 4 +--- src/cascadia/TerminalControl/ControlInteractivity.h | 2 +- .../TerminalControl/ControlInteractivity.idl | 2 +- src/cascadia/TerminalControl/TermControl.cpp | 12 +++++++----- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/cascadia/TerminalControl/ControlCore.cpp b/src/cascadia/TerminalControl/ControlCore.cpp index 68e0ff04602..4c1cc823f90 100644 --- a/src/cascadia/TerminalControl/ControlCore.cpp +++ b/src/cascadia/TerminalControl/ControlCore.cpp @@ -1100,7 +1100,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation Windows::Foundation::Collections::IVector ControlCore::SelectedText(bool trimTrailingWhitespace) const { // RetrieveSelectedTextFromBuffer will lock while it's reading - auto internalResult{ _terminal->RetrieveSelectedTextFromBuffer(trimTrailingWhitespace).text }; + const auto internalResult{ _terminal->RetrieveSelectedTextFromBuffer(trimTrailingWhitespace).text }; auto result = winrt::single_threaded_vector(); diff --git a/src/cascadia/TerminalControl/ControlInteractivity.cpp b/src/cascadia/TerminalControl/ControlInteractivity.cpp index ad364e4db42..60034c8de79 100644 --- a/src/cascadia/TerminalControl/ControlInteractivity.cpp +++ b/src/cascadia/TerminalControl/ControlInteractivity.cpp @@ -102,10 +102,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation return _multiClickCounter; } - void ControlInteractivity::GainFocus() + void ControlInteractivity::GotFocus() { - // GH#5421: Enable the UiaEngine before checking for the SearchBox - // That way, new selections are notified to automation clients. if (_uiaEngine.get()) { THROW_IF_FAILED(_uiaEngine->Enable()); diff --git a/src/cascadia/TerminalControl/ControlInteractivity.h b/src/cascadia/TerminalControl/ControlInteractivity.h index 87dc36d66a9..1c86a52d692 100644 --- a/src/cascadia/TerminalControl/ControlInteractivity.h +++ b/src/cascadia/TerminalControl/ControlInteractivity.h @@ -37,7 +37,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation ControlInteractivity(IControlSettings settings, TerminalConnection::ITerminalConnection connection); - void GainFocus(); + void GotFocus(); void LostFocus(); void UpdateSettings(); void Initialize(); diff --git a/src/cascadia/TerminalControl/ControlInteractivity.idl b/src/cascadia/TerminalControl/ControlInteractivity.idl index 0ea1308018e..385eefdbd5c 100644 --- a/src/cascadia/TerminalControl/ControlInteractivity.idl +++ b/src/cascadia/TerminalControl/ControlInteractivity.idl @@ -19,7 +19,7 @@ namespace Microsoft.Terminal.Control ControlCore Core { get; }; void UpdateSettings(); void Initialize(); - void GainFocus(); + void GotFocus(); void LostFocus(); InteractivityAutomationPeer OnCreateAutomationPeer(); diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index 0146ff6e928..220595ad51f 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -537,9 +537,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation if (_initializedTerminal && !_IsClosing()) // only set up the automation peer if we're ready to go live { const auto& interactivityAutoPeer = _interactivity.OnCreateAutomationPeer(); - auto autoPeer = winrt::make_self(this, interactivityAutoPeer); - _automationPeer = winrt::weak_ref(*autoPeer); - return *autoPeer; + _automationPeer = winrt::make(this, interactivityAutoPeer); + return _automationPeer.get(); } return nullptr; } @@ -1443,7 +1442,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation // GH#5421: Enable the UiaEngine before checking for the SearchBox // That way, new selections are notified to automation clients. - _interactivity.GainFocus(); + // The _uiaEngine lives in _interactivity, so call into there to enable it. + _interactivity.GotFocus(); // If the searchbox is focused, we don't want TSFInputControl to think // it has focus so it doesn't intercept IME input. We also don't want the @@ -1495,6 +1495,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation _focused = false; + // This will disable the accessibility notifications, because the + // UiaEngine lives in ControlInteractivity _interactivity.LostFocus(); if (TSFInputControl() != nullptr) @@ -1837,7 +1839,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation } double height = rows * fontSize.Y; - auto thickness = ParseThicknessFromPadding(padding); + const auto thickness = ParseThicknessFromPadding(padding); // GH#2061 - make sure to account for the size the padding _will be_ scaled to width += scale * (thickness.Left + thickness.Right); height += scale * (thickness.Top + thickness.Bottom);