mirror of
https://github.com/microsoft/terminal.git
synced 2026-10-02 11:29:58 +00:00
Merge remote-tracking branch 'origin/dev/duhowett/stop-using-projection-for-control-innards' into HEAD
# Conflicts: # src/cascadia/TerminalControl/TermControl.cpp
This commit is contained in:
@@ -2034,7 +2034,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
_lastSwapChainHandle = std::move(duplicatedHandle);
|
||||
// Now bubble the event up to the control.
|
||||
SwapChainChanged.raise(*this, winrt::box_value<uint64_t>(reinterpret_cast<uint64_t>(_lastSwapChainHandle.get())));
|
||||
SwapChainChanged.raise(*this, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2331,13 +2331,13 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
return _renderer.get();
|
||||
}
|
||||
|
||||
uint64_t ControlCore::SwapChainHandle() const
|
||||
HANDLE ControlCore::SwapChainHandle() const
|
||||
{
|
||||
// This is only ever called by TermControl::AttachContent, which occurs
|
||||
// when we're taking an existing core and moving it to a new control.
|
||||
// Otherwise, we only ever use the value from the SwapChainChanged
|
||||
// event.
|
||||
return reinterpret_cast<uint64_t>(_lastSwapChainHandle.get());
|
||||
return _lastSwapChainHandle.get();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
|
||||
@@ -107,7 +107,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
void SetOverrideColorScheme(const Core::ICoreScheme&);
|
||||
|
||||
::Microsoft::Console::Render::Renderer* GetRenderer() const noexcept;
|
||||
uint64_t SwapChainHandle() const;
|
||||
HANDLE SwapChainHandle() const;
|
||||
void AttachToNewControl();
|
||||
|
||||
void SizeChanged(const float width, const float height);
|
||||
|
||||
@@ -111,8 +111,6 @@ namespace Microsoft.Terminal.Control
|
||||
|
||||
void SetOverrideColorScheme(Microsoft.Terminal.Core.ICoreScheme scheme);
|
||||
|
||||
UInt64 SwapChainHandle { get; };
|
||||
|
||||
Windows.Foundation.Size FontSize { get; };
|
||||
Windows.Foundation.Size FontSizeInDips { get; };
|
||||
UInt16 FontWeight { get; };
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
#include "../../types/inc/Utils.hpp"
|
||||
#include "../../buffer/out/search.h"
|
||||
|
||||
#include "InteractivityAutomationPeer.h"
|
||||
|
||||
#include "ControlInteractivity.g.cpp"
|
||||
|
||||
using namespace ::Microsoft::Console::Types;
|
||||
@@ -831,23 +829,17 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// - None
|
||||
// Return Value:
|
||||
// - The automation peer for our control
|
||||
Control::InteractivityAutomationPeer ControlInteractivity::OnCreateAutomationPeer()
|
||||
void ControlInteractivity::SetUiaEventDispatcher(IUiaEventDispatcher* uiaEventDispatcher)
|
||||
try
|
||||
{
|
||||
const auto autoPeer = winrt::make_self<implementation::InteractivityAutomationPeer>(this);
|
||||
if (_uiaEngine)
|
||||
{
|
||||
_core->DetachUiaEngine(_uiaEngine.get());
|
||||
}
|
||||
_uiaEngine = std::make_unique<::Microsoft::Console::Render::UiaEngine>(autoPeer.get());
|
||||
_uiaEngine = std::make_unique<::Microsoft::Console::Render::UiaEngine>(uiaEventDispatcher);
|
||||
_core->AttachUiaEngine(_uiaEngine.get());
|
||||
return *autoPeer;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
LOG_CAUGHT_EXCEPTION();
|
||||
return nullptr;
|
||||
}
|
||||
CATCH_LOG()
|
||||
|
||||
::Microsoft::Console::Render::IRenderData* ControlInteractivity::GetRenderData() const
|
||||
{
|
||||
|
||||
@@ -48,7 +48,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
void Close();
|
||||
void Detach();
|
||||
|
||||
Control::InteractivityAutomationPeer OnCreateAutomationPeer();
|
||||
void SetUiaEventDispatcher(::Microsoft::Console::Types::IUiaEventDispatcher* uiaEventDispatcher);
|
||||
::Microsoft::Console::Render::IRenderData* GetRenderData() const;
|
||||
|
||||
#pragma region Input Methods
|
||||
|
||||
@@ -5,8 +5,6 @@ import "ICoreState.idl";
|
||||
import "IControlSettings.idl";
|
||||
import "ControlCore.idl";
|
||||
import "EventArgs.idl";
|
||||
import "InteractivityAutomationPeer.idl";
|
||||
|
||||
|
||||
namespace Microsoft.Terminal.Control
|
||||
{
|
||||
@@ -30,8 +28,6 @@ namespace Microsoft.Terminal.Control
|
||||
|
||||
void Close();
|
||||
|
||||
InteractivityAutomationPeer OnCreateAutomationPeer();
|
||||
|
||||
Boolean CopySelectionToClipboard(Boolean singleLine, Boolean withControlSequences, CopyFormat formats);
|
||||
void RequestPasteTextFromClipboard();
|
||||
void SetEndSelectionPoint(Microsoft.Terminal.Core.Point point);
|
||||
|
||||
@@ -1,223 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "pch.h"
|
||||
#include <UIAutomationCore.h>
|
||||
#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(Control::implementation::ControlInteractivity* owner) :
|
||||
_interactivity{ owner }
|
||||
{
|
||||
THROW_IF_FAILED(::Microsoft::WRL::MakeAndInitialize<::Microsoft::Terminal::TermControlUiaProvider>(&_uiaProvider, _interactivity->GetRenderData(), this));
|
||||
};
|
||||
|
||||
// Bounds is expected to be in pixels.
|
||||
void InteractivityAutomationPeer::SetControlBounds(const Windows::Foundation::Rect bounds)
|
||||
{
|
||||
_controlBounds = { til::math::rounding, bounds };
|
||||
}
|
||||
|
||||
// Padding is expected to be in DIPs.
|
||||
void InteractivityAutomationPeer::SetControlPadding(const Core::Padding padding)
|
||||
{
|
||||
const auto scale = static_cast<float>(DisplayInformation::GetForCurrentView().RawPixelsPerViewPixel());
|
||||
_controlPadding = { til::math::rounding, padding.Left * scale, padding.Top * scale, padding.Right * scale, padding.Bottom * scale };
|
||||
}
|
||||
|
||||
void InteractivityAutomationPeer::ParentProvider(AutomationPeer parentProvider)
|
||||
{
|
||||
// LOAD-BEARING: use _parentProvider->ProviderFromPeer(_parentProvider) instead of this->ProviderFromPeer(*this).
|
||||
// Since we split the automation peer into TermControlAutomationPeer and InteractivityAutomationPeer,
|
||||
// using "this" returns null. This can cause issues with some UIA Client scenarios like any navigation in Narrator.
|
||||
_parentProvider = parentProvider ? parentProvider.as<IAutomationPeerProtected>().ProviderFromPeer(parentProvider) : nullptr;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - 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:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void InteractivityAutomationPeer::SignalSelectionChanged()
|
||||
{
|
||||
SelectionChanged.raise(*this, nullptr);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - 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:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void InteractivityAutomationPeer::SignalTextChanged()
|
||||
{
|
||||
TextChanged.raise(*this, nullptr);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - 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:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void InteractivityAutomationPeer::SignalCursorChanged()
|
||||
{
|
||||
CursorChanged.raise(*this, nullptr);
|
||||
}
|
||||
|
||||
void InteractivityAutomationPeer::NotifyNewOutput(std::wstring_view newOutput)
|
||||
{
|
||||
NewOutput.raise(*this, hstring{ newOutput });
|
||||
}
|
||||
|
||||
#pragma region ITextProvider
|
||||
com_array<XamlAutomation::ITextRangeProvider> InteractivityAutomationPeer::GetSelection()
|
||||
{
|
||||
SAFEARRAY* pReturnVal;
|
||||
THROW_IF_FAILED(_uiaProvider->GetSelection(&pReturnVal));
|
||||
return WrapArrayOfTextRangeProviders(pReturnVal);
|
||||
}
|
||||
|
||||
com_array<XamlAutomation::ITextRangeProvider> 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));
|
||||
return _CreateXamlUiaTextRange(returnVal);
|
||||
}
|
||||
|
||||
XamlAutomation::ITextRangeProvider InteractivityAutomationPeer::RangeFromPoint(Windows::Foundation::Point screenLocation)
|
||||
{
|
||||
UIA::ITextRangeProvider* returnVal;
|
||||
THROW_IF_FAILED(_uiaProvider->RangeFromPoint({ screenLocation.X, screenLocation.Y }, &returnVal));
|
||||
return _CreateXamlUiaTextRange(returnVal);
|
||||
}
|
||||
|
||||
XamlAutomation::ITextRangeProvider InteractivityAutomationPeer::DocumentRange()
|
||||
{
|
||||
UIA::ITextRangeProvider* returnVal;
|
||||
THROW_IF_FAILED(_uiaProvider->get_DocumentRange(&returnVal));
|
||||
return _CreateXamlUiaTextRange(returnVal);
|
||||
}
|
||||
|
||||
XamlAutomation::SupportedTextSelection InteractivityAutomationPeer::SupportedTextSelection()
|
||||
{
|
||||
UIA::SupportedTextSelection returnVal;
|
||||
THROW_IF_FAILED(_uiaProvider->get_SupportedTextSelection(&returnVal));
|
||||
return static_cast<XamlAutomation::SupportedTextSelection>(returnVal);
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region IControlAccessibilityInfo
|
||||
til::size InteractivityAutomationPeer::GetFontSize() const noexcept
|
||||
{
|
||||
return { til::math::rounding, _interactivity->Core().FontSize() };
|
||||
}
|
||||
|
||||
til::rect InteractivityAutomationPeer::GetBounds() const noexcept
|
||||
{
|
||||
return _controlBounds;
|
||||
}
|
||||
|
||||
HRESULT InteractivityAutomationPeer::GetHostUiaProvider(IRawElementProviderSimple** provider)
|
||||
{
|
||||
RETURN_HR_IF(E_INVALIDARG, provider == nullptr);
|
||||
*provider = nullptr;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
til::rect InteractivityAutomationPeer::GetPadding() const noexcept
|
||||
{
|
||||
return _controlPadding;
|
||||
}
|
||||
|
||||
void InteractivityAutomationPeer::ChangeViewport(const til::inclusive_rect& NewWindow)
|
||||
{
|
||||
_interactivity->UpdateScrollbar(static_cast<float>(NewWindow.top));
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
XamlAutomation::ITextRangeProvider InteractivityAutomationPeer::_CreateXamlUiaTextRange(UIA::ITextRangeProvider* returnVal) const
|
||||
{
|
||||
if (!_parentProvider)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
const auto xutr = winrt::make_self<XamlUiaTextRange>(returnVal, _parentProvider);
|
||||
return xutr.as<XamlAutomation::ITextRangeProvider>();
|
||||
};
|
||||
|
||||
// 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<XamlAutomation::ITextRangeProvider> InteractivityAutomationPeer::WrapArrayOfTextRangeProviders(SAFEARRAY* textRanges)
|
||||
{
|
||||
if (!_parentProvider)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
// transfer ownership of UiaTextRanges to this new vector
|
||||
auto providers = SafeArrayToOwningVector<::Microsoft::Terminal::TermControlUiaTextRange>(textRanges);
|
||||
const auto len = gsl::narrow<uint32_t>(providers.size());
|
||||
com_array<XamlAutomation::ITextRangeProvider> result{ len };
|
||||
|
||||
for (uint32_t i = 0; i < len; ++i)
|
||||
{
|
||||
if (auto xutr = _CreateXamlUiaTextRange(providers[i].detach()))
|
||||
{
|
||||
result[i] = std::move(xutr);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
/*++
|
||||
Copyright (c) Microsoft Corporation
|
||||
Licensed under the MIT license.
|
||||
|
||||
Module Name:
|
||||
- InteractivityAutomationPeer.h
|
||||
|
||||
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 implementation in the actual UI tree.
|
||||
|
||||
Author(s):
|
||||
- Mike Griese (migrie), May 2021
|
||||
|
||||
--*/
|
||||
|
||||
#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<InteractivityAutomationPeer>,
|
||||
::Microsoft::Console::Types::IUiaEventDispatcher,
|
||||
::Microsoft::Console::Types::IControlAccessibilityInfo
|
||||
{
|
||||
public:
|
||||
InteractivityAutomationPeer(Microsoft::Terminal::Control::implementation::ControlInteractivity* owner);
|
||||
|
||||
void SetControlBounds(const Windows::Foundation::Rect bounds);
|
||||
void SetControlPadding(const Core::Padding padding);
|
||||
void ParentProvider(Windows::UI::Xaml::Automation::Peers::AutomationPeer parentProvider);
|
||||
|
||||
#pragma region IUiaEventDispatcher
|
||||
void SignalSelectionChanged() override;
|
||||
void SignalTextChanged() override;
|
||||
void SignalCursorChanged() override;
|
||||
void NotifyNewOutput(std::wstring_view newOutput) 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<Windows::UI::Xaml::Automation::Provider::ITextRangeProvider> GetVisibleRanges();
|
||||
com_array<Windows::UI::Xaml::Automation::Provider::ITextRangeProvider> GetSelection();
|
||||
Windows::UI::Xaml::Automation::SupportedTextSelection SupportedTextSelection();
|
||||
Windows::UI::Xaml::Automation::Provider::ITextRangeProvider DocumentRange();
|
||||
#pragma endregion
|
||||
|
||||
#pragma region IControlAccessibilityInfo Pattern
|
||||
// Inherited via IControlAccessibilityInfo
|
||||
virtual til::size GetFontSize() const noexcept override;
|
||||
virtual til::rect GetBounds() const noexcept override;
|
||||
virtual til::rect GetPadding() const noexcept override;
|
||||
virtual void ChangeViewport(const til::inclusive_rect& NewWindow) override;
|
||||
virtual HRESULT GetHostUiaProvider(IRawElementProviderSimple** provider) override;
|
||||
#pragma endregion
|
||||
|
||||
til::typed_event<IInspectable, IInspectable> SelectionChanged;
|
||||
til::typed_event<IInspectable, IInspectable> TextChanged;
|
||||
til::typed_event<IInspectable, IInspectable> CursorChanged;
|
||||
til::typed_event<IInspectable, hstring> NewOutput;
|
||||
|
||||
private:
|
||||
Windows::UI::Xaml::Automation::Provider::ITextRangeProvider _CreateXamlUiaTextRange(::ITextRangeProvider* returnVal) const;
|
||||
|
||||
::Microsoft::WRL::ComPtr<::Microsoft::Terminal::TermControlUiaProvider> _uiaProvider;
|
||||
winrt::Microsoft::Terminal::Control::implementation::ControlInteractivity* _interactivity;
|
||||
winrt::Windows::UI::Xaml::Automation::Provider::IRawElementProviderSimple _parentProvider{ nullptr };
|
||||
|
||||
til::rect _controlBounds{};
|
||||
til::rect _controlPadding{};
|
||||
|
||||
winrt::com_array<Windows::UI::Xaml::Automation::Provider::ITextRangeProvider> WrapArrayOfTextRangeProviders(SAFEARRAY* textRanges);
|
||||
};
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
namespace Microsoft.Terminal.Control
|
||||
{
|
||||
[default_interface] runtimeclass InteractivityAutomationPeer :
|
||||
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);
|
||||
void ParentProvider(Windows.UI.Xaml.Automation.Peers.AutomationPeer parentProvider);
|
||||
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> SelectionChanged;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> TextChanged;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> CursorChanged;
|
||||
event Windows.Foundation.TypedEventHandler<Object, String> NewOutput;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -10,8 +10,6 @@
|
||||
#include "../../renderer/uia/UiaRenderer.hpp"
|
||||
#include "../../tsf/Handle.h"
|
||||
|
||||
#include "ControlInteractivity.h"
|
||||
|
||||
namespace Microsoft::Console::VirtualTerminal
|
||||
{
|
||||
struct MouseButtonState;
|
||||
@@ -19,7 +17,10 @@ namespace Microsoft::Console::VirtualTerminal
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
{
|
||||
struct ControlCore;
|
||||
struct ControlInteractivity;
|
||||
struct TermControl;
|
||||
struct TermControlAutomationPeer;
|
||||
|
||||
struct TsfDataProvider : ::Microsoft::Console::TSF::IDataProvider
|
||||
{
|
||||
@@ -195,9 +196,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
Control::CursorDisplayState CursorVisibility() const noexcept;
|
||||
void CursorVisibility(Control::CursorDisplayState cursorVisibility);
|
||||
|
||||
void ApplyPreviewColorScheme(const Core::ICoreScheme& scheme) { _core.ApplyPreviewColorScheme(scheme); }
|
||||
void ResetPreviewColorScheme() { _core.ResetPreviewColorScheme(); }
|
||||
void SetOverrideColorScheme(const Core::ICoreScheme& scheme) { _core.SetOverrideColorScheme(scheme); }
|
||||
void ApplyPreviewColorScheme(const Core::ICoreScheme& scheme);
|
||||
void ResetPreviewColorScheme();
|
||||
void SetOverrideColorScheme(const Core::ICoreScheme& scheme);
|
||||
|
||||
// -------------------------------- WinRT Events ---------------------------------
|
||||
// clang-format off
|
||||
@@ -238,6 +239,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
private:
|
||||
friend struct TermControlT<TermControl>; // friend our parent so it can bind private event handlers
|
||||
friend struct TermControlAutomationPeer;
|
||||
friend struct TsfDataProvider;
|
||||
|
||||
// NOTE: _uiaEngine must be ordered before _core.
|
||||
@@ -248,9 +250,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// IRenderEngine is accessed when ControlCore calls Renderer::TriggerTeardown.
|
||||
// (C++ class members are destroyed in reverse order.)
|
||||
// Further, the TermControlAutomationPeer must be destructed after _uiaEngine!
|
||||
Control::TermControlAutomationPeer _automationPeer{ nullptr };
|
||||
Control::ControlInteractivity _interactivity{ nullptr };
|
||||
Control::ControlCore _core{ nullptr };
|
||||
winrt::com_ptr<Control::implementation::TermControlAutomationPeer> _automationPeer{ nullptr };
|
||||
winrt::com_ptr<Control::implementation::ControlInteractivity> _interactivity{ nullptr };
|
||||
winrt::com_ptr<Control::implementation::ControlCore> _core{ nullptr };
|
||||
Control::IKeyBindings _keyBindings{ nullptr };
|
||||
TsfDataProvider _tsfDataProvider{ this };
|
||||
winrt::com_ptr<SearchBoxControl> _searchBox;
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include <UIAutomationCore.h>
|
||||
#include "TermControlAutomationPeer.h"
|
||||
#include "TermControl.h"
|
||||
#include "TermControlAutomationPeer.g.cpp"
|
||||
|
||||
#include "XamlUiaTextRange.h"
|
||||
#include "../types/UiaTracing.h"
|
||||
@@ -66,45 +65,13 @@ static constexpr bool IsReadable(std::wstring_view text)
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
{
|
||||
TermControlAutomationPeer::TermControlAutomationPeer(winrt::com_ptr<TermControl> owner,
|
||||
const Core::Padding padding,
|
||||
Control::InteractivityAutomationPeer impl) :
|
||||
TermControlAutomationPeerT<TermControlAutomationPeer>(*owner.get()), // pass owner to FrameworkElementAutomationPeer
|
||||
_termControl{ owner },
|
||||
_contentAutomationPeer{ impl }
|
||||
TermControlAutomationPeer::TermControlAutomationPeer(winrt::com_ptr<TermControl> owner) :
|
||||
FrameworkElementAutomationPeerT(*owner.get()), // pass owner to FrameworkElementAutomationPeer
|
||||
_termControl{ owner }
|
||||
{
|
||||
UpdateControlBounds();
|
||||
SetControlPadding(padding);
|
||||
// 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(); });
|
||||
_contentAutomationPeer.NewOutput([this](auto&&, hstring newOutput) { NotifyNewOutput(newOutput); });
|
||||
_contentAutomationPeer.ParentProvider(*this);
|
||||
THROW_IF_FAILED(::Microsoft::WRL::MakeAndInitialize<::Microsoft::Terminal::TermControlUiaProvider>(&_uiaProvider, owner->_core->GetRenderData(), this));
|
||||
};
|
||||
|
||||
// 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:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void TermControlAutomationPeer::UpdateControlBounds()
|
||||
{
|
||||
// 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!
|
||||
_contentAutomationPeer.SetControlBounds(GetBoundingRectangle());
|
||||
}
|
||||
void TermControlAutomationPeer::SetControlPadding(const Core::Padding padding)
|
||||
{
|
||||
_contentAutomationPeer.SetControlPadding(padding);
|
||||
}
|
||||
|
||||
void TermControlAutomationPeer::RecordKeyEvent(const WORD vkey)
|
||||
{
|
||||
if (const auto charCode{ MapVirtualKey(vkey, MAPVK_VK_TO_CHAR) })
|
||||
@@ -121,9 +88,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// GH#13978: If the TermControl has already been removed from the UI tree, XAML might run into weird bugs.
|
||||
// This will prevent the `dispatcher.RunAsync` calls below from raising UIA events on the main thread.
|
||||
_termControl = {};
|
||||
|
||||
// Solve the circular reference between us and the content automation peer.
|
||||
_contentAutomationPeer.ParentProvider(nullptr);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -341,33 +305,126 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
#pragma region ITextProvider
|
||||
com_array<XamlAutomation::ITextRangeProvider> TermControlAutomationPeer::GetSelection()
|
||||
{
|
||||
return _contentAutomationPeer.GetSelection();
|
||||
SAFEARRAY* pReturnVal;
|
||||
THROW_IF_FAILED(_uiaProvider->GetSelection(&pReturnVal));
|
||||
return WrapArrayOfTextRangeProviders(pReturnVal);
|
||||
}
|
||||
|
||||
com_array<XamlAutomation::ITextRangeProvider> TermControlAutomationPeer::GetVisibleRanges()
|
||||
{
|
||||
return _contentAutomationPeer.GetVisibleRanges();
|
||||
SAFEARRAY* pReturnVal;
|
||||
THROW_IF_FAILED(_uiaProvider->GetVisibleRanges(&pReturnVal));
|
||||
return WrapArrayOfTextRangeProviders(pReturnVal);
|
||||
}
|
||||
|
||||
XamlAutomation::ITextRangeProvider TermControlAutomationPeer::RangeFromChild(XamlAutomation::IRawElementProviderSimple childElement)
|
||||
XamlAutomation::ITextRangeProvider TermControlAutomationPeer::RangeFromChild(XamlAutomation::IRawElementProviderSimple /*childElement*/)
|
||||
{
|
||||
return _contentAutomationPeer.RangeFromChild(childElement);
|
||||
UIA::ITextRangeProvider* returnVal;
|
||||
// ScreenInfoUiaProvider doesn't actually use parameter, so just pass in nullptr
|
||||
THROW_IF_FAILED(_uiaProvider->RangeFromChild(/* IRawElementProviderSimple */ nullptr,
|
||||
&returnVal));
|
||||
return _CreateXamlUiaTextRange(returnVal);
|
||||
}
|
||||
|
||||
XamlAutomation::ITextRangeProvider TermControlAutomationPeer::RangeFromPoint(Windows::Foundation::Point screenLocation)
|
||||
{
|
||||
return _contentAutomationPeer.RangeFromPoint(screenLocation);
|
||||
UIA::ITextRangeProvider* returnVal;
|
||||
THROW_IF_FAILED(_uiaProvider->RangeFromPoint({ screenLocation.X, screenLocation.Y }, &returnVal));
|
||||
return _CreateXamlUiaTextRange(returnVal);
|
||||
}
|
||||
|
||||
XamlAutomation::ITextRangeProvider TermControlAutomationPeer::DocumentRange()
|
||||
{
|
||||
return _contentAutomationPeer.DocumentRange();
|
||||
UIA::ITextRangeProvider* returnVal;
|
||||
THROW_IF_FAILED(_uiaProvider->get_DocumentRange(&returnVal));
|
||||
return _CreateXamlUiaTextRange(returnVal);
|
||||
}
|
||||
|
||||
XamlAutomation::SupportedTextSelection TermControlAutomationPeer::SupportedTextSelection()
|
||||
{
|
||||
return _contentAutomationPeer.SupportedTextSelection();
|
||||
UIA::SupportedTextSelection returnVal;
|
||||
THROW_IF_FAILED(_uiaProvider->get_SupportedTextSelection(&returnVal));
|
||||
return static_cast<XamlAutomation::SupportedTextSelection>(returnVal);
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region IControlAccessibilityInfo
|
||||
til::size TermControlAutomationPeer::GetFontSize() const noexcept
|
||||
{
|
||||
if (const auto control{ _termControl.get() })
|
||||
{
|
||||
return { til::math::rounding, control->_core->FontSize() };
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
til::rect TermControlAutomationPeer::GetBounds() const noexcept
|
||||
{
|
||||
return { til::math::rounding, GetBoundingRectangle() };
|
||||
}
|
||||
|
||||
HRESULT TermControlAutomationPeer::GetHostUiaProvider(IRawElementProviderSimple** provider)
|
||||
{
|
||||
RETURN_HR_IF(E_INVALIDARG, provider == nullptr);
|
||||
*provider = nullptr;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
til::rect TermControlAutomationPeer::GetPadding() const noexcept
|
||||
{
|
||||
if (const auto control{ _termControl.get() })
|
||||
{
|
||||
const auto padding{ control->GetPadding() };
|
||||
return {
|
||||
til::math::rounding,
|
||||
padding.Left,
|
||||
padding.Top,
|
||||
padding.Right,
|
||||
padding.Bottom,
|
||||
};
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
void TermControlAutomationPeer::ChangeViewport(const til::inclusive_rect& NewWindow)
|
||||
{
|
||||
if (const auto control{ _termControl.get() })
|
||||
{
|
||||
control->_interactivity->UpdateScrollbar(static_cast<float>(NewWindow.top));
|
||||
}
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
XamlAutomation::ITextRangeProvider TermControlAutomationPeer::_CreateXamlUiaTextRange(UIA::ITextRangeProvider* returnVal) const
|
||||
{
|
||||
const auto provider = ProviderFromPeer(*this);
|
||||
const auto xutr = winrt::make_self<XamlUiaTextRange>(returnVal, provider);
|
||||
return xutr.as<XamlAutomation::ITextRangeProvider>();
|
||||
};
|
||||
|
||||
// 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<XamlAutomation::ITextRangeProvider> TermControlAutomationPeer::WrapArrayOfTextRangeProviders(SAFEARRAY* textRanges)
|
||||
{
|
||||
// transfer ownership of UiaTextRanges to this new vector
|
||||
auto providers = SafeArrayToOwningVector<::Microsoft::Terminal::TermControlUiaTextRange>(textRanges);
|
||||
const auto len = gsl::narrow<uint32_t>(providers.size());
|
||||
com_array<XamlAutomation::ITextRangeProvider> result{ len };
|
||||
|
||||
for (uint32_t i = 0; i < len; ++i)
|
||||
{
|
||||
if (auto xutr = _CreateXamlUiaTextRange(providers[i].detach()))
|
||||
{
|
||||
result[i] = std::move(xutr);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,16 +20,11 @@ Abstract:
|
||||
|
||||
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
|
||||
|
||||
#include "ControlInteractivity.h"
|
||||
#include "TermControlAutomationPeer.g.h"
|
||||
#include "../types/TermControlUiaProvider.hpp"
|
||||
#include "../types/IUiaEventDispatcher.h"
|
||||
#include "../types/IControlAccessibilityInfo.h"
|
||||
@@ -39,16 +34,14 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
struct TermControl;
|
||||
|
||||
struct TermControlAutomationPeer :
|
||||
public TermControlAutomationPeerT<TermControlAutomationPeer>,
|
||||
::Microsoft::Console::Types::IUiaEventDispatcher
|
||||
public winrt::Windows::UI::Xaml::Automation::Peers::FrameworkElementAutomationPeerT<TermControlAutomationPeer,
|
||||
winrt::Windows::UI::Xaml::Automation::Provider::ITextProvider>,
|
||||
::Microsoft::Console::Types::IUiaEventDispatcher,
|
||||
::Microsoft::Console::Types::IControlAccessibilityInfo
|
||||
{
|
||||
public:
|
||||
TermControlAutomationPeer(winrt::com_ptr<Microsoft::Terminal::Control::implementation::TermControl> owner,
|
||||
const Core::Padding padding,
|
||||
Control::InteractivityAutomationPeer implementation);
|
||||
TermControlAutomationPeer(winrt::com_ptr<Microsoft::Terminal::Control::implementation::TermControl> owner);
|
||||
|
||||
void UpdateControlBounds();
|
||||
void SetControlPadding(const Core::Padding padding);
|
||||
void RecordKeyEvent(const WORD vkey);
|
||||
void Close();
|
||||
|
||||
@@ -79,9 +72,23 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
Windows::UI::Xaml::Automation::Provider::ITextRangeProvider DocumentRange();
|
||||
#pragma endregion
|
||||
|
||||
#pragma region IControlAccessibilityInfo Pattern
|
||||
// Inherited via IControlAccessibilityInfo
|
||||
virtual til::size GetFontSize() const noexcept override;
|
||||
virtual til::rect GetBounds() const noexcept override;
|
||||
virtual til::rect GetPadding() const noexcept override;
|
||||
virtual void ChangeViewport(const til::inclusive_rect& NewWindow) override;
|
||||
virtual HRESULT GetHostUiaProvider(IRawElementProviderSimple** provider) override;
|
||||
#pragma endregion
|
||||
|
||||
private:
|
||||
Windows::UI::Xaml::Automation::Provider::ITextRangeProvider _CreateXamlUiaTextRange(::ITextRangeProvider* returnVal) const;
|
||||
winrt::com_array<Windows::UI::Xaml::Automation::Provider::ITextRangeProvider> WrapArrayOfTextRangeProviders(SAFEARRAY* textRanges);
|
||||
|
||||
winrt::weak_ref<Microsoft::Terminal::Control::implementation::TermControl> _termControl;
|
||||
Control::InteractivityAutomationPeer _contentAutomationPeer;
|
||||
::Microsoft::WRL::ComPtr<::Microsoft::Terminal::TermControlUiaProvider> _uiaProvider;
|
||||
|
||||
til::rect _controlPadding{};
|
||||
til::shared_mutex<std::deque<wchar_t>> _keyEvents;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import "TermControl.idl";
|
||||
|
||||
namespace Microsoft.Terminal.Control
|
||||
{
|
||||
[default_interface] runtimeclass TermControlAutomationPeer :
|
||||
Windows.UI.Xaml.Automation.Peers.FrameworkElementAutomationPeer,
|
||||
Windows.UI.Xaml.Automation.Provider.ITextProvider
|
||||
{
|
||||
|
||||
void UpdateControlBounds();
|
||||
void SetControlPadding(Microsoft.Terminal.Core.Padding padding);
|
||||
}
|
||||
}
|
||||
@@ -54,12 +54,7 @@
|
||||
<ClInclude Include="TermControl.h">
|
||||
<DependentUpon>TermControl.xaml</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TermControlAutomationPeer.h">
|
||||
<DependentUpon>TermControlAutomationPeer.idl</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="InteractivityAutomationPeer.h">
|
||||
<DependentUpon>InteractivityAutomationPeer.idl</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TermControlAutomationPeer.h" />
|
||||
<ClInclude Include="XamlUiaTextRange.h" />
|
||||
<ClInclude Include="HwndTerminal.hpp" />
|
||||
<ClInclude Include="HwndTerminalAutomationPeer.hpp" />
|
||||
@@ -95,12 +90,7 @@
|
||||
<DependentUpon>TermControl.xaml</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
|
||||
<ClCompile Include="TermControlAutomationPeer.cpp">
|
||||
<DependentUpon>TermControlAutomationPeer.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="InteractivityAutomationPeer.cpp">
|
||||
<DependentUpon>InteractivityAutomationPeer.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TermControlAutomationPeer.cpp" />
|
||||
<ClCompile Include="XamlUiaTextRange.cpp" />
|
||||
<ClCompile Include="HwndTerminal.cpp" />
|
||||
<ClCompile Include="HwndTerminalAutomationPeer.cpp" />
|
||||
@@ -123,8 +113,6 @@
|
||||
<Midl Include="TermControl.idl">
|
||||
<DependentUpon>TermControl.xaml</DependentUpon>
|
||||
</Midl>
|
||||
<Midl Include="TermControlAutomationPeer.idl" />
|
||||
<Midl Include="InteractivityAutomationPeer.idl" />
|
||||
<Midl Include="IMouseWheelListener.idl" />
|
||||
</ItemGroup>
|
||||
<!-- ========================= XAML Files ======================== -->
|
||||
@@ -183,4 +171,4 @@
|
||||
<!-- This -must- go after cppwinrt.build.post.props because that includes many VS-provided props including appcontainer.common.props, which stomps on what cppwinrt.targets did. -->
|
||||
<Import Project="$(OpenConsoleDir)src\common.nugetversions.targets" />
|
||||
<Import Project="$(SolutionDir)build\rules\CollectWildcardResources.targets" />
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include <winrt/Windows.UI.ViewManagement.h>
|
||||
#include <winrt/Windows.UI.Xaml.h>
|
||||
#include <winrt/Windows.UI.Xaml.Automation.Peers.h>
|
||||
#include <winrt/Windows.UI.Xaml.Automation.Provider.h>
|
||||
#include <winrt/Windows.UI.Text.Core.h>
|
||||
#include <winrt/Windows.UI.Xaml.Controls.h>
|
||||
#include <winrt/Windows.UI.Xaml.Controls.Primitives.h>
|
||||
|
||||
Reference in New Issue
Block a user