Only access ControlInteractivity through the projection (#10051)
## Summary of the Pull Request This forces the `TermControl` to only use `ControlCore` and `ControlInteractivity` via their WinRT projections. We want this, because WinRT projections can be used across process boundaries. In the future, `ControlCore` and `ControlInteractivity` are going to be living in a different process entirely from `TermControl`. By enforcing this boundary now, we can make sure that they will work seamlessly in the future. ## References * Tear-out: #1256 * Megathread: #5000 * Project: https://github.com/microsoft/terminal/projects/5 ## PR Checklist * [x] Closes https://github.com/microsoft/terminal/projects/5#card-50760270 * [x] I work here * [x] Tests added/passed * [n/a] Requires documentation to be updated ## Detailed Description of the Pull Request / Additional comments Most all this was just converting pure c++ types to winrt types when possible. I've added a couple helper projections with `til` converters, which made most of this really easy. The "`MouseButtonState` needs to be composed of `Int32`s instead of `bool`s" is MENTAL. I have no idea why this is, but when I had the control OOP in the sample, that would crash when trying to de-marshal the bools. BODGY. The biggest changes are in the way the UIA stuff is hooked up. The UiaEngine needs to be attached directly to the `Renderer`, and it can't be easily projected, so it needs to live next to the `ControlCore`. But the `TermControlAutomationPeer` needed the `UiaEngine` to help implement some interfaces. Now, there's a new layer we've introduced. `InteractivityAutomationPeer` does the `ITextProvider`, `IControlAccessibilityInfo` and the `IUiaEventDispatcher` thing. `TermControlAutomationPeer` now has a `InteractivityAutomationPeer` stashed inside itself, so that it can ask the interactivity layer to do the real work. We still need the `TermControlAutomationPeer` though, to be able to attach to the real UI tree. ## Validation Steps Performed The terminal behaves basically the same as before. Most importantly, I whipped out Accessibility Insights, and the Terminal looks the same as before.
This commit is contained in:
parent
8947909121
commit
7f3bc3cb04
|
@ -1129,7 +1129,7 @@ namespace winrt::TerminalApp::implementation
|
||||||
// - Gets the taskbar state value from the last active control
|
// - Gets the taskbar state value from the last active control
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - The taskbar state of the last active control
|
// - The taskbar state of the last active control
|
||||||
size_t AppLogic::GetLastActiveControlTaskbarState()
|
uint64_t AppLogic::GetLastActiveControlTaskbarState()
|
||||||
{
|
{
|
||||||
if (_root)
|
if (_root)
|
||||||
{
|
{
|
||||||
|
@ -1142,7 +1142,7 @@ namespace winrt::TerminalApp::implementation
|
||||||
// - Gets the taskbar progress value from the last active control
|
// - Gets the taskbar progress value from the last active control
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - The taskbar progress of the last active control
|
// - The taskbar progress of the last active control
|
||||||
size_t AppLogic::GetLastActiveControlTaskbarProgress()
|
uint64_t AppLogic::GetLastActiveControlTaskbarProgress()
|
||||||
{
|
{
|
||||||
if (_root)
|
if (_root)
|
||||||
{
|
{
|
||||||
|
|
|
@ -89,8 +89,8 @@ namespace winrt::TerminalApp::implementation
|
||||||
|
|
||||||
void WindowCloseButtonClicked();
|
void WindowCloseButtonClicked();
|
||||||
|
|
||||||
size_t GetLastActiveControlTaskbarState();
|
uint64_t GetLastActiveControlTaskbarState();
|
||||||
size_t GetLastActiveControlTaskbarProgress();
|
uint64_t GetLastActiveControlTaskbarProgress();
|
||||||
|
|
||||||
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::UI::Xaml::Controls::ContentDialogResult> ShowDialog(winrt::Windows::UI::Xaml::Controls::ContentDialog dialog);
|
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::UI::Xaml::Controls::ContentDialogResult> ShowDialog(winrt::Windows::UI::Xaml::Controls::ContentDialog dialog);
|
||||||
|
|
||||||
|
|
|
@ -2020,11 +2020,11 @@ namespace winrt::TerminalApp::implementation
|
||||||
// - Gets the taskbar state value from the last active control
|
// - Gets the taskbar state value from the last active control
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - The taskbar state of the last active control
|
// - The taskbar state of the last active control
|
||||||
size_t TerminalPage::GetLastActiveControlTaskbarState()
|
uint64_t TerminalPage::GetLastActiveControlTaskbarState()
|
||||||
{
|
{
|
||||||
if (auto control{ _GetActiveControl() })
|
if (auto control{ _GetActiveControl() })
|
||||||
{
|
{
|
||||||
return gsl::narrow_cast<size_t>(control.TaskbarState());
|
return control.TaskbarState();
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -2033,11 +2033,11 @@ namespace winrt::TerminalApp::implementation
|
||||||
// - Gets the taskbar progress value from the last active control
|
// - Gets the taskbar progress value from the last active control
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - The taskbar progress of the last active control
|
// - The taskbar progress of the last active control
|
||||||
size_t TerminalPage::GetLastActiveControlTaskbarProgress()
|
uint64_t TerminalPage::GetLastActiveControlTaskbarProgress()
|
||||||
{
|
{
|
||||||
if (auto control{ _GetActiveControl() })
|
if (auto control{ _GetActiveControl() })
|
||||||
{
|
{
|
||||||
return gsl::narrow_cast<size_t>(control.TaskbarProgress());
|
return control.TaskbarProgress();
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,8 +83,8 @@ namespace winrt::TerminalApp::implementation
|
||||||
winrt::TerminalApp::IDialogPresenter DialogPresenter() const;
|
winrt::TerminalApp::IDialogPresenter DialogPresenter() const;
|
||||||
void DialogPresenter(winrt::TerminalApp::IDialogPresenter dialogPresenter);
|
void DialogPresenter(winrt::TerminalApp::IDialogPresenter dialogPresenter);
|
||||||
|
|
||||||
size_t GetLastActiveControlTaskbarState();
|
uint64_t GetLastActiveControlTaskbarState();
|
||||||
size_t GetLastActiveControlTaskbarProgress();
|
uint64_t GetLastActiveControlTaskbarProgress();
|
||||||
|
|
||||||
void ShowKeyboardServiceWarning();
|
void ShowKeyboardServiceWarning();
|
||||||
winrt::hstring KeyboardServiceDisabledText();
|
winrt::hstring KeyboardServiceDisabledText();
|
||||||
|
|
|
@ -426,7 +426,16 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
// - Updates last hovered cell, renders / removes rendering of hyper-link if required
|
// - Updates last hovered cell, renders / removes rendering of hyper-link if required
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// - terminalPosition: The terminal position of the pointer
|
// - terminalPosition: The terminal position of the pointer
|
||||||
void ControlCore::UpdateHoveredCell(const std::optional<til::point>& terminalPosition)
|
void ControlCore::SetHoveredCell(Core::Point pos)
|
||||||
|
{
|
||||||
|
_updateHoveredCell(std::optional<til::point>{ pos });
|
||||||
|
}
|
||||||
|
void ControlCore::ClearHoveredCell()
|
||||||
|
{
|
||||||
|
_updateHoveredCell(std::nullopt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ControlCore::_updateHoveredCell(const std::optional<til::point> terminalPosition)
|
||||||
{
|
{
|
||||||
if (terminalPosition == _lastHoveredCell)
|
if (terminalPosition == _lastHoveredCell)
|
||||||
{
|
{
|
||||||
|
@ -477,7 +486,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
return winrt::hstring{ _terminal->GetHyperlinkAtPosition(pos) };
|
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.
|
auto lock = _terminal->LockForReading(); // Lock for the duration of our reads.
|
||||||
if (_lastHoveredCell.has_value())
|
if (_lastHoveredCell.has_value())
|
||||||
|
@ -487,9 +496,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<til::point> ControlCore::GetHoveredCell() const
|
Windows::Foundation::IReference<Core::Point> ControlCore::HoveredCell() const
|
||||||
{
|
{
|
||||||
return _lastHoveredCell;
|
return _lastHoveredCell.has_value() ? Windows::Foundation::IReference<Core::Point>{ _lastHoveredCell.value() } : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
|
@ -895,6 +904,24 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
return _actualFont;
|
return _actualFont;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
winrt::Windows::Foundation::Size ControlCore::FontSize() const noexcept
|
||||||
|
{
|
||||||
|
const auto fontSize = GetFont().GetSize();
|
||||||
|
return {
|
||||||
|
::base::saturated_cast<float>(fontSize.X),
|
||||||
|
::base::saturated_cast<float>(fontSize.Y)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
winrt::hstring ControlCore::FontFaceName() const noexcept
|
||||||
|
{
|
||||||
|
return winrt::hstring{ GetFont().GetFaceName() };
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t ControlCore::FontWeight() const noexcept
|
||||||
|
{
|
||||||
|
return static_cast<uint16_t>(GetFont().GetWeight());
|
||||||
|
}
|
||||||
|
|
||||||
til::size ControlCore::FontSizeInDips() const
|
til::size ControlCore::FontSizeInDips() const
|
||||||
{
|
{
|
||||||
const til::size fontSize{ GetFont().GetSize() };
|
const til::size fontSize{ GetFont().GetSize() };
|
||||||
|
@ -1077,10 +1104,18 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
return _settings.CopyOnSelect();
|
return _settings.CopyOnSelect();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::wstring> ControlCore::SelectedText(bool trimTrailingWhitespace) const
|
Windows::Foundation::Collections::IVector<winrt::hstring> ControlCore::SelectedText(bool trimTrailingWhitespace) const
|
||||||
{
|
{
|
||||||
// RetrieveSelectedTextFromBuffer will lock while it's reading
|
// RetrieveSelectedTextFromBuffer will lock while it's reading
|
||||||
return _terminal->RetrieveSelectedTextFromBuffer(trimTrailingWhitespace).text;
|
const auto internalResult{ _terminal->RetrieveSelectedTextFromBuffer(trimTrailingWhitespace).text };
|
||||||
|
|
||||||
|
auto result = winrt::single_threaded_vector<winrt::hstring>();
|
||||||
|
|
||||||
|
for (const auto& row : internalResult)
|
||||||
|
{
|
||||||
|
result.Append(winrt::hstring{ row });
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
::Microsoft::Console::Types::IUiaData* ControlCore::GetUiaData() const
|
::Microsoft::Console::Types::IUiaData* ControlCore::GetUiaData() const
|
||||||
|
@ -1124,7 +1159,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ControlCore::SetBackgroundOpacity(const float opacity)
|
void ControlCore::SetBackgroundOpacity(const double opacity)
|
||||||
{
|
{
|
||||||
if (_renderEngine)
|
if (_renderEngine)
|
||||||
{
|
{
|
||||||
|
@ -1176,7 +1211,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HANDLE ControlCore::GetSwapChainHandle() const
|
uint64_t ControlCore::SwapChainHandle() const
|
||||||
{
|
{
|
||||||
// This is called by:
|
// This is called by:
|
||||||
// * TermControl::RenderEngineSwapChainChanged, who is only registered
|
// * TermControl::RenderEngineSwapChainChanged, who is only registered
|
||||||
|
@ -1184,7 +1219,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
// * TermControl::_InitializeTerminal, after the call to Initialize, for
|
// * TermControl::_InitializeTerminal, after the call to Initialize, for
|
||||||
// _AttachDxgiSwapChainToXaml.
|
// _AttachDxgiSwapChainToXaml.
|
||||||
// In both cases, we'll have a _renderEngine by then.
|
// In both cases, we'll have a _renderEngine by then.
|
||||||
return _renderEngine->GetSwapChainHandle();
|
return reinterpret_cast<uint64_t>(_renderEngine->GetSwapChainHandle());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ControlCore::_rendererWarning(const HRESULT hr)
|
void ControlCore::_rendererWarning(const HRESULT hr)
|
||||||
|
|
|
@ -48,15 +48,19 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
void UpdateAppearance(const IControlAppearance& newAppearance);
|
void UpdateAppearance(const IControlAppearance& newAppearance);
|
||||||
void SizeChanged(const double width, const double height);
|
void SizeChanged(const double width, const double height);
|
||||||
void ScaleChanged(const double scale);
|
void ScaleChanged(const double scale);
|
||||||
HANDLE GetSwapChainHandle() const;
|
uint64_t SwapChainHandle() const;
|
||||||
|
|
||||||
void AdjustFontSize(int fontSizeDelta);
|
void AdjustFontSize(int fontSizeDelta);
|
||||||
void ResetFontSize();
|
void ResetFontSize();
|
||||||
FontInfo GetFont() const;
|
FontInfo GetFont() const;
|
||||||
til::size FontSizeInDips() 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;
|
til::color BackgroundColor() const;
|
||||||
void SetBackgroundOpacity(const float opacity);
|
void SetBackgroundOpacity(const double opacity);
|
||||||
|
|
||||||
void SendInput(const winrt::hstring& wstr);
|
void SendInput(const winrt::hstring& wstr);
|
||||||
void PasteText(const winrt::hstring& hstr);
|
void PasteText(const winrt::hstring& hstr);
|
||||||
|
@ -67,10 +71,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
void ResumeRendering();
|
void ResumeRendering();
|
||||||
|
|
||||||
void UpdatePatternLocations();
|
void UpdatePatternLocations();
|
||||||
void UpdateHoveredCell(const std::optional<til::point>& terminalPosition);
|
void SetHoveredCell(Core::Point terminalPosition);
|
||||||
|
void ClearHoveredCell();
|
||||||
winrt::hstring GetHyperlink(const til::point position) const;
|
winrt::hstring GetHyperlink(const til::point position) const;
|
||||||
winrt::hstring GetHoveredUriText() const;
|
winrt::hstring HoveredUriText() const;
|
||||||
std::optional<til::point> GetHoveredCell() const;
|
Windows::Foundation::IReference<Core::Point> HoveredCell() const;
|
||||||
|
|
||||||
::Microsoft::Console::Types::IUiaData* GetUiaData() const;
|
::Microsoft::Console::Types::IUiaData* GetUiaData() const;
|
||||||
|
|
||||||
|
@ -119,7 +124,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
|
|
||||||
bool HasSelection() const;
|
bool HasSelection() const;
|
||||||
bool CopyOnSelect() const;
|
bool CopyOnSelect() const;
|
||||||
std::vector<std::wstring> SelectedText(bool trimTrailingWhitespace) const;
|
Windows::Foundation::Collections::IVector<winrt::hstring> SelectedText(bool trimTrailingWhitespace) const;
|
||||||
void SetSelectionAnchor(til::point const& position);
|
void SetSelectionAnchor(til::point const& position);
|
||||||
void SetEndSelectionPoint(til::point const& position);
|
void SetEndSelectionPoint(til::point const& position);
|
||||||
|
|
||||||
|
@ -232,6 +237,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
void _raiseReadOnlyWarning();
|
void _raiseReadOnlyWarning();
|
||||||
void _updateAntiAliasingMode(::Microsoft::Console::Render::DxEngine* const dxEngine);
|
void _updateAntiAliasingMode(::Microsoft::Console::Render::DxEngine* const dxEngine);
|
||||||
void _connectionOutputHandler(const hstring& hstr);
|
void _connectionOutputHandler(const hstring& hstr);
|
||||||
|
void _updateHoveredCell(const std::optional<til::point> terminalPosition);
|
||||||
|
|
||||||
friend class ControlUnitTests::ControlCoreTests;
|
friend class ControlUnitTests::ControlCoreTests;
|
||||||
friend class ControlUnitTests::ControlInteractivityTests;
|
friend class ControlUnitTests::ControlInteractivityTests;
|
||||||
|
|
|
@ -8,9 +8,97 @@ import "EventArgs.idl";
|
||||||
namespace Microsoft.Terminal.Control
|
namespace Microsoft.Terminal.Control
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// This is a mirror of
|
||||||
|
// ::Microsoft::Console::VirtualTerminal::TerminalInput::MouseButtonState,
|
||||||
|
// but projectable.
|
||||||
|
// !! 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
|
||||||
|
{
|
||||||
|
IsLeftButtonDown = 0x1,
|
||||||
|
IsMiddleButtonDown = 0x2,
|
||||||
|
IsRightButtonDown = 0x4
|
||||||
|
};
|
||||||
|
|
||||||
[default_interface] runtimeclass ControlCore : ICoreState
|
[default_interface] runtimeclass ControlCore : ICoreState
|
||||||
{
|
{
|
||||||
ControlCore(IControlSettings settings,
|
ControlCore(IControlSettings settings,
|
||||||
Microsoft.Terminal.TerminalConnection.ITerminalConnection connection);
|
Microsoft.Terminal.TerminalConnection.ITerminalConnection connection);
|
||||||
|
|
||||||
|
Boolean Initialize(Double actualWidth,
|
||||||
|
Double actualHeight,
|
||||||
|
Double compositionScale);
|
||||||
|
|
||||||
|
void UpdateSettings(IControlSettings settings);
|
||||||
|
void UpdateAppearance(IControlAppearance appearance);
|
||||||
|
|
||||||
|
UInt64 SwapChainHandle { get; };
|
||||||
|
|
||||||
|
Windows.Foundation.Size FontSize { get; };
|
||||||
|
String FontFaceName { get; };
|
||||||
|
UInt16 FontWeight { get; };
|
||||||
|
|
||||||
|
Boolean TrySendKeyEvent(Int16 vkey,
|
||||||
|
Int16 scanCode,
|
||||||
|
Microsoft.Terminal.Core.ControlKeyStates modifiers,
|
||||||
|
Boolean keyDown);
|
||||||
|
Boolean SendCharEvent(Char ch,
|
||||||
|
Int16 scanCode,
|
||||||
|
Microsoft.Terminal.Core.ControlKeyStates modifiers);
|
||||||
|
void SendInput(String text);
|
||||||
|
void PasteText(String text);
|
||||||
|
|
||||||
|
void SetHoveredCell(Microsoft.Terminal.Core.Point terminalPosition);
|
||||||
|
void ClearHoveredCell();
|
||||||
|
|
||||||
|
void ResetFontSize();
|
||||||
|
void AdjustFontSize(Int32 fontSizeDelta);
|
||||||
|
void SizeChanged(Double width, Double height);
|
||||||
|
void ScaleChanged(Double scale);
|
||||||
|
|
||||||
|
void ToggleShaderEffects();
|
||||||
|
void ToggleReadOnlyMode();
|
||||||
|
|
||||||
|
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 { get; };
|
||||||
|
|
||||||
|
Boolean HasSelection { get; };
|
||||||
|
IVector<String> SelectedText(Boolean trimTrailingWhitespace);
|
||||||
|
|
||||||
|
String HoveredUriText { get; };
|
||||||
|
Windows.Foundation.IReference<Microsoft.Terminal.Core.Point> HoveredCell { get; };
|
||||||
|
|
||||||
|
void Close();
|
||||||
|
void BlinkCursor();
|
||||||
|
Boolean IsInReadOnlyMode { get; };
|
||||||
|
Boolean CursorOn;
|
||||||
|
void EnablePainting();
|
||||||
|
|
||||||
|
event FontSizeChangedEventArgs FontSizeChanged;
|
||||||
|
|
||||||
|
event Windows.Foundation.TypedEventHandler<Object, CopyToClipboardEventArgs> CopyToClipboard;
|
||||||
|
event Windows.Foundation.TypedEventHandler<Object, TitleChangedEventArgs> TitleChanged;
|
||||||
|
event Windows.Foundation.TypedEventHandler<Object, Object> WarningBell;
|
||||||
|
event Windows.Foundation.TypedEventHandler<Object, Object> TabColorChanged;
|
||||||
|
event Windows.Foundation.TypedEventHandler<Object, Object> BackgroundColorChanged;
|
||||||
|
event Windows.Foundation.TypedEventHandler<Object, ScrollPositionChangedArgs> ScrollPositionChanged;
|
||||||
|
event Windows.Foundation.TypedEventHandler<Object, Object> CursorPositionChanged;
|
||||||
|
event Windows.Foundation.TypedEventHandler<Object, Object> TaskbarProgressChanged;
|
||||||
|
event Windows.Foundation.TypedEventHandler<Object, Object> ConnectionStateChanged;
|
||||||
|
event Windows.Foundation.TypedEventHandler<Object, Object> HoveredHyperlinkChanged;
|
||||||
|
event Windows.Foundation.TypedEventHandler<Object, Object> RendererEnteredErrorState;
|
||||||
|
event Windows.Foundation.TypedEventHandler<Object, Object> SwapChainChanged;
|
||||||
|
event Windows.Foundation.TypedEventHandler<Object, RendererWarningArgs> RendererWarning;
|
||||||
|
event Windows.Foundation.TypedEventHandler<Object, NoticeEventArgs> RaiseNotice;
|
||||||
|
event Windows.Foundation.TypedEventHandler<Object, TransparencyChangedEventArgs> TransparencyChanged;
|
||||||
|
event Windows.Foundation.TypedEventHandler<Object, Object> ReceivedOutput;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,13 +8,15 @@
|
||||||
#include <unicode.hpp>
|
#include <unicode.hpp>
|
||||||
#include <Utf16Parser.hpp>
|
#include <Utf16Parser.hpp>
|
||||||
#include <Utils.h>
|
#include <Utils.h>
|
||||||
#include <WinUser.h>
|
|
||||||
#include <LibraryResources.h>
|
#include <LibraryResources.h>
|
||||||
#include "../../types/inc/GlyphWidth.hpp"
|
#include "../../types/inc/GlyphWidth.hpp"
|
||||||
#include "../../types/inc/Utils.hpp"
|
#include "../../types/inc/Utils.hpp"
|
||||||
#include "../../buffer/out/search.h"
|
#include "../../buffer/out/search.h"
|
||||||
|
|
||||||
|
#include "InteractivityAutomationPeer.h"
|
||||||
|
|
||||||
#include "ControlInteractivity.g.cpp"
|
#include "ControlInteractivity.g.cpp"
|
||||||
|
#include "TermControl.h"
|
||||||
|
|
||||||
using namespace ::Microsoft::Console::Types;
|
using namespace ::Microsoft::Console::Types;
|
||||||
using namespace ::Microsoft::Console::VirtualTerminal;
|
using namespace ::Microsoft::Console::VirtualTerminal;
|
||||||
|
@ -27,6 +29,15 @@ static constexpr unsigned int MAX_CLICK_COUNT = 3;
|
||||||
|
|
||||||
namespace winrt::Microsoft::Terminal::Control::implementation
|
namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
{
|
{
|
||||||
|
static constexpr TerminalInput::MouseButtonState toInternalMouseState(const Control::MouseButtonState& state)
|
||||||
|
{
|
||||||
|
return TerminalInput::MouseButtonState{
|
||||||
|
WI_IsFlagSet(state, MouseButtonState::IsLeftButtonDown),
|
||||||
|
WI_IsFlagSet(state, MouseButtonState::IsMiddleButtonDown),
|
||||||
|
WI_IsFlagSet(state, MouseButtonState::IsRightButtonDown)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
ControlInteractivity::ControlInteractivity(IControlSettings settings,
|
ControlInteractivity::ControlInteractivity(IControlSettings settings,
|
||||||
TerminalConnection::ITerminalConnection connection) :
|
TerminalConnection::ITerminalConnection connection) :
|
||||||
_touchAnchor{ std::nullopt },
|
_touchAnchor{ std::nullopt },
|
||||||
|
@ -37,6 +48,14 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
_core = winrt::make_self<ControlCore>(settings, connection);
|
_core = winrt::make_self<ControlCore>(settings, connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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:
|
||||||
|
// - <none>
|
||||||
|
// Return Value:
|
||||||
|
// - <none>
|
||||||
void ControlInteractivity::UpdateSettings()
|
void ControlInteractivity::UpdateSettings()
|
||||||
{
|
{
|
||||||
_updateSystemParameterSettings();
|
_updateSystemParameterSettings();
|
||||||
|
@ -50,9 +69,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
_multiClickTimer = GetDoubleClickTime() * 1000;
|
_multiClickTimer = GetDoubleClickTime() * 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
winrt::com_ptr<ControlCore> ControlInteractivity::GetCore()
|
Control::ControlCore ControlInteractivity::Core()
|
||||||
{
|
{
|
||||||
return _core;
|
return *_core;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
|
@ -85,11 +104,24 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
return _multiClickCounter;
|
return _multiClickCounter;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ControlInteractivity::GainFocus()
|
void ControlInteractivity::GotFocus()
|
||||||
{
|
{
|
||||||
|
if (_uiaEngine.get())
|
||||||
|
{
|
||||||
|
THROW_IF_FAILED(_uiaEngine->Enable());
|
||||||
|
}
|
||||||
|
|
||||||
_updateSystemParameterSettings();
|
_updateSystemParameterSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ControlInteractivity::LostFocus()
|
||||||
|
{
|
||||||
|
if (_uiaEngine.get())
|
||||||
|
{
|
||||||
|
THROW_IF_FAILED(_uiaEngine->Disable());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Method Description
|
// Method Description
|
||||||
// - Updates internal params based on system parameters
|
// - Updates internal params based on system parameters
|
||||||
void ControlInteractivity::_updateSystemParameterSettings() noexcept
|
void ControlInteractivity::_updateSystemParameterSettings() noexcept
|
||||||
|
@ -156,7 +188,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
_core->PasteText(winrt::hstring{ wstr });
|
_core->PasteText(winrt::hstring{ wstr });
|
||||||
}
|
}
|
||||||
|
|
||||||
void ControlInteractivity::PointerPressed(TerminalInput::MouseButtonState buttonState,
|
void ControlInteractivity::PointerPressed(Control::MouseButtonState buttonState,
|
||||||
const unsigned int pointerUpdateKind,
|
const unsigned int pointerUpdateKind,
|
||||||
const uint64_t timestamp,
|
const uint64_t timestamp,
|
||||||
const ::Microsoft::Terminal::Core::ControlKeyStates modifiers,
|
const ::Microsoft::Terminal::Core::ControlKeyStates modifiers,
|
||||||
|
@ -170,7 +202,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
|
|
||||||
// GH#9396: we prioritize hyper-link over VT mouse events
|
// GH#9396: we prioritize hyper-link over VT mouse events
|
||||||
auto hyperlink = _core->GetHyperlink(terminalPosition);
|
auto hyperlink = _core->GetHyperlink(terminalPosition);
|
||||||
if (buttonState.isLeftButtonDown &&
|
if (WI_IsFlagSet(buttonState, MouseButtonState::IsLeftButtonDown) &&
|
||||||
ctrlEnabled && !hyperlink.empty())
|
ctrlEnabled && !hyperlink.empty())
|
||||||
{
|
{
|
||||||
const auto clickCount = _numberOfClicks(pixelPosition, timestamp);
|
const auto clickCount = _numberOfClicks(pixelPosition, timestamp);
|
||||||
|
@ -182,9 +214,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
}
|
}
|
||||||
else if (_canSendVTMouseInput(modifiers))
|
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 (WI_IsFlagSet(buttonState, MouseButtonState::IsLeftButtonDown))
|
||||||
{
|
{
|
||||||
const auto clickCount = _numberOfClicks(pixelPosition, timestamp);
|
const auto clickCount = _numberOfClicks(pixelPosition, timestamp);
|
||||||
// This formula enables the number of clicks to cycle properly
|
// This formula enables the number of clicks to cycle properly
|
||||||
|
@ -219,7 +251,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
_singleClickTouchdownPos = std::nullopt;
|
_singleClickTouchdownPos = std::nullopt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (buttonState.isRightButtonDown)
|
else if (WI_IsFlagSet(buttonState, MouseButtonState::IsRightButtonDown))
|
||||||
{
|
{
|
||||||
// CopyOnSelect right click always pastes
|
// CopyOnSelect right click always pastes
|
||||||
if (_core->CopyOnSelect() || !_core->HasSelection())
|
if (_core->CopyOnSelect() || !_core->HasSelection())
|
||||||
|
@ -238,7 +270,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
_touchAnchor = contactPoint;
|
_touchAnchor = contactPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ControlInteractivity::PointerMoved(TerminalInput::MouseButtonState buttonState,
|
void ControlInteractivity::PointerMoved(Control::MouseButtonState buttonState,
|
||||||
const unsigned int pointerUpdateKind,
|
const unsigned int pointerUpdateKind,
|
||||||
const ::Microsoft::Terminal::Core::ControlKeyStates modifiers,
|
const ::Microsoft::Terminal::Core::ControlKeyStates modifiers,
|
||||||
const bool focused,
|
const bool focused,
|
||||||
|
@ -249,9 +281,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
// Short-circuit isReadOnly check to avoid warning dialog
|
// Short-circuit isReadOnly check to avoid warning dialog
|
||||||
if (focused && !_core->IsInReadOnlyMode() && _canSendVTMouseInput(modifiers))
|
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 && WI_IsFlagSet(buttonState, MouseButtonState::IsLeftButtonDown))
|
||||||
{
|
{
|
||||||
if (_singleClickTouchdownPos)
|
if (_singleClickTouchdownPos)
|
||||||
{
|
{
|
||||||
|
@ -279,7 +311,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
SetEndSelectionPoint(pixelPosition);
|
SetEndSelectionPoint(pixelPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
_core->UpdateHoveredCell(terminalPosition);
|
_core->SetHoveredCell(terminalPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ControlInteractivity::TouchMoved(const til::point newTouchPoint,
|
void ControlInteractivity::TouchMoved(const til::point newTouchPoint,
|
||||||
|
@ -319,7 +351,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ControlInteractivity::PointerReleased(TerminalInput::MouseButtonState buttonState,
|
void ControlInteractivity::PointerReleased(Control::MouseButtonState buttonState,
|
||||||
const unsigned int pointerUpdateKind,
|
const unsigned int pointerUpdateKind,
|
||||||
const ::Microsoft::Terminal::Core::ControlKeyStates modifiers,
|
const ::Microsoft::Terminal::Core::ControlKeyStates modifiers,
|
||||||
const til::point pixelPosition)
|
const til::point pixelPosition)
|
||||||
|
@ -328,7 +360,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
// Short-circuit isReadOnly check to avoid warning dialog
|
// Short-circuit isReadOnly check to avoid warning dialog
|
||||||
if (!_core->IsInReadOnlyMode() && _canSendVTMouseInput(modifiers))
|
if (!_core->IsInReadOnlyMode() && _canSendVTMouseInput(modifiers))
|
||||||
{
|
{
|
||||||
_core->SendMouseEvent(terminalPosition, pointerUpdateKind, modifiers, 0, buttonState);
|
_core->SendMouseEvent(terminalPosition, pointerUpdateKind, modifiers, 0, toInternalMouseState(buttonState));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -366,7 +398,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
bool ControlInteractivity::MouseWheel(const ::Microsoft::Terminal::Core::ControlKeyStates modifiers,
|
bool ControlInteractivity::MouseWheel(const ::Microsoft::Terminal::Core::ControlKeyStates modifiers,
|
||||||
const int32_t delta,
|
const int32_t delta,
|
||||||
const til::point pixelPosition,
|
const til::point pixelPosition,
|
||||||
const TerminalInput::MouseButtonState state)
|
const Control::MouseButtonState buttonState)
|
||||||
{
|
{
|
||||||
const til::point terminalPosition = _getTerminalPosition(pixelPosition);
|
const til::point terminalPosition = _getTerminalPosition(pixelPosition);
|
||||||
|
|
||||||
|
@ -382,7 +414,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
WM_MOUSEWHEEL,
|
WM_MOUSEWHEEL,
|
||||||
modifiers,
|
modifiers,
|
||||||
::base::saturated_cast<short>(delta),
|
::base::saturated_cast<short>(delta),
|
||||||
state);
|
toInternalMouseState(buttonState));
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto ctrlPressed = modifiers.IsCtrlPressed();
|
const auto ctrlPressed = modifiers.IsCtrlPressed();
|
||||||
|
@ -398,7 +430,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_mouseScrollHandler(delta, pixelPosition, state.isLeftButtonDown);
|
_mouseScrollHandler(delta, pixelPosition, WI_IsFlagSet(buttonState, MouseButtonState::IsLeftButtonDown));
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -557,4 +589,36 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
// Convert the location in pixels to characters within the current viewport.
|
// Convert the location in pixels to characters within the current viewport.
|
||||||
return til::point{ pixelPosition / fontSize };
|
return til::point{ pixelPosition / fontSize };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Method Description:
|
||||||
|
// - 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:
|
||||||
|
// - The automation peer for our control
|
||||||
|
Control::InteractivityAutomationPeer ControlInteractivity::OnCreateAutomationPeer()
|
||||||
|
try
|
||||||
|
{
|
||||||
|
auto autoPeer = winrt::make_self<implementation::InteractivityAutomationPeer>(this);
|
||||||
|
|
||||||
|
_uiaEngine = std::make_unique<::Microsoft::Console::Render::UiaEngine>(autoPeer.get());
|
||||||
|
_core->AttachUiaEngine(_uiaEngine.get());
|
||||||
|
return *autoPeer;
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
LOG_CAUGHT_EXCEPTION();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
::Microsoft::Console::Types::IUiaData* ControlInteractivity::GetUiaData() const
|
||||||
|
{
|
||||||
|
return _core->GetUiaData();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,11 +23,6 @@
|
||||||
|
|
||||||
#include "ControlCore.h"
|
#include "ControlCore.h"
|
||||||
|
|
||||||
namespace Microsoft::Console::VirtualTerminal
|
|
||||||
{
|
|
||||||
struct MouseButtonState;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace ControlUnitTests
|
namespace ControlUnitTests
|
||||||
{
|
{
|
||||||
class ControlCoreTests;
|
class ControlCoreTests;
|
||||||
|
@ -42,20 +37,24 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
ControlInteractivity(IControlSettings settings,
|
ControlInteractivity(IControlSettings settings,
|
||||||
TerminalConnection::ITerminalConnection connection);
|
TerminalConnection::ITerminalConnection connection);
|
||||||
|
|
||||||
void GainFocus();
|
void GotFocus();
|
||||||
|
void LostFocus();
|
||||||
void UpdateSettings();
|
void UpdateSettings();
|
||||||
void Initialize();
|
void Initialize();
|
||||||
winrt::com_ptr<ControlCore> GetCore();
|
Control::ControlCore Core();
|
||||||
|
|
||||||
|
Control::InteractivityAutomationPeer OnCreateAutomationPeer();
|
||||||
|
::Microsoft::Console::Types::IUiaData* GetUiaData() const;
|
||||||
|
|
||||||
#pragma region Input Methods
|
#pragma region Input Methods
|
||||||
void PointerPressed(::Microsoft::Console::VirtualTerminal::TerminalInput::MouseButtonState buttonState,
|
void PointerPressed(Control::MouseButtonState buttonState,
|
||||||
const unsigned int pointerUpdateKind,
|
const unsigned int pointerUpdateKind,
|
||||||
const uint64_t timestamp,
|
const uint64_t timestamp,
|
||||||
const ::Microsoft::Terminal::Core::ControlKeyStates modifiers,
|
const ::Microsoft::Terminal::Core::ControlKeyStates modifiers,
|
||||||
const til::point pixelPosition);
|
const til::point pixelPosition);
|
||||||
void TouchPressed(const til::point contactPoint);
|
void TouchPressed(const til::point contactPoint);
|
||||||
|
|
||||||
void PointerMoved(::Microsoft::Console::VirtualTerminal::TerminalInput::MouseButtonState buttonState,
|
void PointerMoved(Control::MouseButtonState buttonState,
|
||||||
const unsigned int pointerUpdateKind,
|
const unsigned int pointerUpdateKind,
|
||||||
const ::Microsoft::Terminal::Core::ControlKeyStates modifiers,
|
const ::Microsoft::Terminal::Core::ControlKeyStates modifiers,
|
||||||
const bool focused,
|
const bool focused,
|
||||||
|
@ -63,7 +62,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
void TouchMoved(const til::point newTouchPoint,
|
void TouchMoved(const til::point newTouchPoint,
|
||||||
const bool focused);
|
const bool focused);
|
||||||
|
|
||||||
void PointerReleased(::Microsoft::Console::VirtualTerminal::TerminalInput::MouseButtonState buttonState,
|
void PointerReleased(Control::MouseButtonState buttonState,
|
||||||
const unsigned int pointerUpdateKind,
|
const unsigned int pointerUpdateKind,
|
||||||
const ::Microsoft::Terminal::Core::ControlKeyStates modifiers,
|
const ::Microsoft::Terminal::Core::ControlKeyStates modifiers,
|
||||||
const til::point pixelPosition);
|
const til::point pixelPosition);
|
||||||
|
@ -72,7 +71,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
bool MouseWheel(const ::Microsoft::Terminal::Core::ControlKeyStates modifiers,
|
bool MouseWheel(const ::Microsoft::Terminal::Core::ControlKeyStates modifiers,
|
||||||
const int32_t delta,
|
const int32_t delta,
|
||||||
const til::point pixelPosition,
|
const til::point pixelPosition,
|
||||||
const ::Microsoft::Console::VirtualTerminal::TerminalInput::MouseButtonState state);
|
const Control::MouseButtonState state);
|
||||||
|
|
||||||
void UpdateScrollbar(const double newValue);
|
void UpdateScrollbar(const double newValue);
|
||||||
|
|
||||||
|
@ -83,7 +82,20 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
void RequestPasteTextFromClipboard();
|
void RequestPasteTextFromClipboard();
|
||||||
void SetEndSelectionPoint(const til::point pixelPosition);
|
void SetEndSelectionPoint(const til::point pixelPosition);
|
||||||
|
|
||||||
|
TYPED_EVENT(OpenHyperlink, IInspectable, Control::OpenHyperlinkEventArgs);
|
||||||
|
TYPED_EVENT(PasteFromClipboard, IInspectable, Control::PasteFromClipboardEventArgs);
|
||||||
|
TYPED_EVENT(ScrollPositionChanged, IInspectable, Control::ScrollPositionChangedArgs);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// NOTE: _uiaEngine must be ordered before _core.
|
||||||
|
//
|
||||||
|
// ControlCore::AttachUiaEngine receives a IRenderEngine as a raw pointer, which we own.
|
||||||
|
// We must ensure that we first destroy the ControlCore before the UiaEngine instance
|
||||||
|
// in order to safely resolve this unsafe pointer dependency. Otherwise a deallocated
|
||||||
|
// IRenderEngine is accessed when ControlCore calls Renderer::TriggerTeardown.
|
||||||
|
// (C++ class members are destroyed in reverse order.)
|
||||||
|
std::unique_ptr<::Microsoft::Console::Render::UiaEngine> _uiaEngine;
|
||||||
|
|
||||||
winrt::com_ptr<ControlCore> _core{ nullptr };
|
winrt::com_ptr<ControlCore> _core{ nullptr };
|
||||||
unsigned int _rowsToScroll;
|
unsigned int _rowsToScroll;
|
||||||
double _internalScrollbarPosition{ 0.0 };
|
double _internalScrollbarPosition{ 0.0 };
|
||||||
|
@ -129,10 +141,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
void _sendPastedTextToConnection(std::wstring_view wstr);
|
void _sendPastedTextToConnection(std::wstring_view wstr);
|
||||||
til::point _getTerminalPosition(const til::point& pixelPosition);
|
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::ControlCoreTests;
|
||||||
friend class ControlUnitTests::ControlInteractivityTests;
|
friend class ControlUnitTests::ControlInteractivityTests;
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,6 +5,8 @@ import "ICoreState.idl";
|
||||||
import "IControlSettings.idl";
|
import "IControlSettings.idl";
|
||||||
import "ControlCore.idl";
|
import "ControlCore.idl";
|
||||||
import "EventArgs.idl";
|
import "EventArgs.idl";
|
||||||
|
import "InteractivityAutomationPeer.idl";
|
||||||
|
|
||||||
|
|
||||||
namespace Microsoft.Terminal.Control
|
namespace Microsoft.Terminal.Control
|
||||||
{
|
{
|
||||||
|
@ -13,5 +15,51 @@ namespace Microsoft.Terminal.Control
|
||||||
{
|
{
|
||||||
ControlInteractivity(IControlSettings settings,
|
ControlInteractivity(IControlSettings settings,
|
||||||
Microsoft.Terminal.TerminalConnection.ITerminalConnection connection);
|
Microsoft.Terminal.TerminalConnection.ITerminalConnection connection);
|
||||||
|
|
||||||
|
ControlCore Core { get; };
|
||||||
|
void UpdateSettings();
|
||||||
|
void Initialize();
|
||||||
|
void GotFocus();
|
||||||
|
void LostFocus();
|
||||||
|
|
||||||
|
InteractivityAutomationPeer OnCreateAutomationPeer();
|
||||||
|
|
||||||
|
Boolean CopySelectionToClipboard(Boolean singleLine, Windows.Foundation.IReference<CopyFormat> 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<Object, OpenHyperlinkEventArgs> OpenHyperlink;
|
||||||
|
event Windows.Foundation.TypedEventHandler<Object, ScrollPositionChangedArgs> ScrollPositionChanged;
|
||||||
|
event Windows.Foundation.TypedEventHandler<Object, PasteFromClipboardEventArgs> PasteFromClipboard;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ namespace Microsoft.Terminal.Control
|
||||||
|
|
||||||
Int32 ScrollOffset { get; };
|
Int32 ScrollOffset { get; };
|
||||||
Int32 ViewHeight { get; };
|
Int32 ViewHeight { get; };
|
||||||
|
Int32 BufferHeight { get; };
|
||||||
|
|
||||||
Boolean BracketedPasteEnabled { get; };
|
Boolean BracketedPasteEnabled { get; };
|
||||||
|
|
||||||
|
|
208
src/cascadia/TerminalControl/InteractivityAutomationPeer.cpp
Normal file
208
src/cascadia/TerminalControl/InteractivityAutomationPeer.cpp
Normal file
|
@ -0,0 +1,208 @@
|
||||||
|
// Copyright (c) Microsoft Corporation.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
#include "pch.h"
|
||||||
|
#include <UIAutomationCore.h>
|
||||||
|
#include <LibraryResources.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->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
|
||||||
|
// - 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()
|
||||||
|
{
|
||||||
|
_SelectionChangedHandlers(*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()
|
||||||
|
{
|
||||||
|
_TextChangedHandlers(*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()
|
||||||
|
{
|
||||||
|
_CursorChangedHandlers(*this, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
#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));
|
||||||
|
|
||||||
|
const auto parentProvider = this->ProviderFromPeer(*this);
|
||||||
|
const auto xutr = winrt::make_self<XamlUiaTextRange>(returnVal, parentProvider);
|
||||||
|
return xutr.as<XamlAutomation::ITextRangeProvider>();
|
||||||
|
}
|
||||||
|
|
||||||
|
XamlAutomation::ITextRangeProvider InteractivityAutomationPeer::RangeFromPoint(Windows::Foundation::Point screenLocation)
|
||||||
|
{
|
||||||
|
UIA::ITextRangeProvider* returnVal;
|
||||||
|
THROW_IF_FAILED(_uiaProvider->RangeFromPoint({ screenLocation.X, screenLocation.Y }, &returnVal));
|
||||||
|
|
||||||
|
const auto parentProvider = this->ProviderFromPeer(*this);
|
||||||
|
const auto xutr = winrt::make_self<XamlUiaTextRange>(returnVal, parentProvider);
|
||||||
|
return xutr.as<XamlAutomation::ITextRangeProvider>();
|
||||||
|
}
|
||||||
|
|
||||||
|
XamlAutomation::ITextRangeProvider InteractivityAutomationPeer::DocumentRange()
|
||||||
|
{
|
||||||
|
UIA::ITextRangeProvider* returnVal;
|
||||||
|
THROW_IF_FAILED(_uiaProvider->get_DocumentRange(&returnVal));
|
||||||
|
|
||||||
|
const auto parentProvider = this->ProviderFromPeer(*this);
|
||||||
|
const auto xutr = winrt::make_self<XamlUiaTextRange>(returnVal, parentProvider);
|
||||||
|
return xutr.as<XamlAutomation::ITextRangeProvider>();
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
COORD InteractivityAutomationPeer::GetFontSize() const
|
||||||
|
{
|
||||||
|
return til::size{ til::math::rounding, _interactivity->Core().FontSize() };
|
||||||
|
}
|
||||||
|
|
||||||
|
RECT InteractivityAutomationPeer::GetBounds() const
|
||||||
|
{
|
||||||
|
return _controlBounds;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT InteractivityAutomationPeer::GetHostUiaProvider(IRawElementProviderSimple** provider)
|
||||||
|
{
|
||||||
|
RETURN_HR_IF(E_INVALIDARG, provider == nullptr);
|
||||||
|
*provider = nullptr;
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
RECT InteractivityAutomationPeer::GetPadding() const
|
||||||
|
{
|
||||||
|
return _controlPadding;
|
||||||
|
}
|
||||||
|
|
||||||
|
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<XamlAutomation::ITextRangeProvider> InteractivityAutomationPeer::WrapArrayOfTextRangeProviders(SAFEARRAY* textRanges)
|
||||||
|
{
|
||||||
|
// transfer ownership of UiaTextRanges to this new vector
|
||||||
|
auto providers = SafeArrayToOwningVector<::Microsoft::Terminal::TermControlUiaTextRange>(textRanges);
|
||||||
|
int count = gsl::narrow<int>(providers.size());
|
||||||
|
|
||||||
|
std::vector<XamlAutomation::ITextRangeProvider> vec;
|
||||||
|
vec.reserve(count);
|
||||||
|
auto parentProvider = this->ProviderFromPeer(*this);
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
auto xutr = make_self<XamlUiaTextRange>(providers[i].detach(), parentProvider);
|
||||||
|
vec.emplace_back(xutr.as<XamlAutomation::ITextRangeProvider>());
|
||||||
|
}
|
||||||
|
|
||||||
|
com_array<XamlAutomation::ITextRangeProvider> result{ vec };
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
85
src/cascadia/TerminalControl/InteractivityAutomationPeer.h
Normal file
85
src/cascadia/TerminalControl/InteractivityAutomationPeer.h
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
/*++
|
||||||
|
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);
|
||||||
|
|
||||||
|
#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<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 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
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
til::rectangle _controlBounds{};
|
||||||
|
til::rectangle _controlPadding{};
|
||||||
|
|
||||||
|
winrt::com_array<Windows::UI::Xaml::Automation::Provider::ITextRangeProvider> WrapArrayOfTextRangeProviders(SAFEARRAY* textRanges);
|
||||||
|
};
|
||||||
|
}
|
18
src/cascadia/TerminalControl/InteractivityAutomationPeer.idl
Normal file
18
src/cascadia/TerminalControl/InteractivityAutomationPeer.idl
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
// 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
|
||||||
|
{
|
||||||
|
|
||||||
|
void SetControlBounds(Windows.Foundation.Rect bounds);
|
||||||
|
void SetControlPadding(Microsoft.Terminal.Core.Padding padding);
|
||||||
|
|
||||||
|
event Windows.Foundation.TypedEventHandler<Object, Object> SelectionChanged;
|
||||||
|
event Windows.Foundation.TypedEventHandler<Object, Object> TextChanged;
|
||||||
|
event Windows.Foundation.TypedEventHandler<Object, Object> CursorChanged;
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,7 +8,6 @@
|
||||||
#include <unicode.hpp>
|
#include <unicode.hpp>
|
||||||
#include <Utf16Parser.hpp>
|
#include <Utf16Parser.hpp>
|
||||||
#include <Utils.h>
|
#include <Utils.h>
|
||||||
#include <WinUser.h>
|
|
||||||
#include <LibraryResources.h>
|
#include <LibraryResources.h>
|
||||||
#include "../../types/inc/GlyphWidth.hpp"
|
#include "../../types/inc/GlyphWidth.hpp"
|
||||||
#include "../../types/inc/Utils.hpp"
|
#include "../../types/inc/Utils.hpp"
|
||||||
|
@ -44,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::CopyFormat);
|
||||||
|
|
||||||
|
DEFINE_ENUM_FLAG_OPERATORS(winrt::Microsoft::Terminal::Control::MouseButtonState);
|
||||||
|
|
||||||
namespace winrt::Microsoft::Terminal::Control::implementation
|
namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
{
|
{
|
||||||
TermControl::TermControl(IControlSettings settings,
|
TermControl::TermControl(IControlSettings settings,
|
||||||
|
@ -60,33 +61,33 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
_interactivity = winrt::make_self<ControlInteractivity>(settings, connection);
|
_interactivity = winrt::make<implementation::ControlInteractivity>(settings, connection);
|
||||||
_core = _interactivity->GetCore();
|
_core = _interactivity.Core();
|
||||||
|
|
||||||
// Use a manual revoker on the output event, so we can immediately stop
|
// Use a manual revoker on the output event, so we can immediately stop
|
||||||
// worrying about it on destruction.
|
// 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
|
// These events might all be triggered by the connection, but that
|
||||||
// should be drained and closed before we complete destruction. So these
|
// should be drained and closed before we complete destruction. So these
|
||||||
// are safe.
|
// are safe.
|
||||||
_core->ScrollPositionChanged({ this, &TermControl::_ScrollPositionChanged });
|
_core.ScrollPositionChanged({ this, &TermControl::_ScrollPositionChanged });
|
||||||
_core->WarningBell({ this, &TermControl::_coreWarningBell });
|
_core.WarningBell({ this, &TermControl::_coreWarningBell });
|
||||||
_core->CursorPositionChanged({ this, &TermControl::_CursorPositionChanged });
|
_core.CursorPositionChanged({ this, &TermControl::_CursorPositionChanged });
|
||||||
|
|
||||||
// This event is specifically triggered by the renderer thread, a BG thread. Use a weak ref here.
|
// 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
|
// 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
|
// they don't need weak refs - they can't be triggered unless we're
|
||||||
// alive.
|
// alive.
|
||||||
_core->BackgroundColorChanged({ this, &TermControl::_BackgroundColorChangedHandler });
|
_core.BackgroundColorChanged({ this, &TermControl::_BackgroundColorChangedHandler });
|
||||||
_core->FontSizeChanged({ this, &TermControl::_coreFontSizeChanged });
|
_core.FontSizeChanged({ this, &TermControl::_coreFontSizeChanged });
|
||||||
_core->TransparencyChanged({ this, &TermControl::_coreTransparencyChanged });
|
_core.TransparencyChanged({ this, &TermControl::_coreTransparencyChanged });
|
||||||
_core->RaiseNotice({ this, &TermControl::_coreRaisedNotice });
|
_core.RaiseNotice({ this, &TermControl::_coreRaisedNotice });
|
||||||
_core->HoveredHyperlinkChanged({ this, &TermControl::_hoveredHyperlinkChanged });
|
_core.HoveredHyperlinkChanged({ this, &TermControl::_hoveredHyperlinkChanged });
|
||||||
_interactivity->OpenHyperlink({ this, &TermControl::_HyperlinkHandler });
|
_interactivity.OpenHyperlink({ this, &TermControl::_HyperlinkHandler });
|
||||||
_interactivity->ScrollPositionChanged({ this, &TermControl::_ScrollPositionChanged });
|
_interactivity.ScrollPositionChanged({ this, &TermControl::_ScrollPositionChanged });
|
||||||
|
|
||||||
// Initialize the terminal only once the swapchainpanel is loaded - that
|
// 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
|
// way, we'll be able to query the real pixel size it got on layout
|
||||||
|
@ -128,7 +129,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
[weakThis = get_weak()]() {
|
[weakThis = get_weak()]() {
|
||||||
if (auto control{ weakThis.get() }; !control->_IsClosing())
|
if (auto control{ weakThis.get() }; !control->_IsClosing())
|
||||||
{
|
{
|
||||||
control->_core->UpdatePatternLocations();
|
control->_core.UpdatePatternLocations();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -187,16 +188,16 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
|
|
||||||
// If a text is selected inside terminal, use it to populate the search box.
|
// 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 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.
|
// Currently we populate the search box only if a single line is selected.
|
||||||
// Empirically, multi-line selection works as well on sample scenarios,
|
// Empirically, multi-line selection works as well on sample scenarios,
|
||||||
// but since code paths differ, extra work is required to ensure correctness.
|
// 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)
|
if (bufferText.Size() == 1)
|
||||||
{
|
{
|
||||||
const auto selectedLine{ til::at(bufferText, 0) };
|
const auto selectedLine{ bufferText.GetAt(0) };
|
||||||
_searchBox->PopulateTextbox(selectedLine.data());
|
_searchBox->PopulateTextbox(selectedLine);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,7 +218,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_core->Search(_searchBox->TextBox().Text(), goForward, false);
|
_core.Search(_searchBox->TextBox().Text(), goForward, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,7 +235,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
const bool goForward,
|
const bool goForward,
|
||||||
const bool caseSensitive)
|
const bool caseSensitive)
|
||||||
{
|
{
|
||||||
_core->Search(text, goForward, caseSensitive);
|
_core.Search(text, goForward, caseSensitive);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
|
@ -303,7 +304,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_core->UpdateSettings(_settings);
|
_core.UpdateSettings(_settings);
|
||||||
|
|
||||||
// Update our control settings
|
// Update our control settings
|
||||||
_ApplyUISettings(_settings);
|
_ApplyUISettings(_settings);
|
||||||
|
@ -362,7 +363,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
foregroundBrush.Color(static_cast<til::color>(newAppearance.DefaultForeground()));
|
foregroundBrush.Color(static_cast<til::color>(newAppearance.DefaultForeground()));
|
||||||
TSFInputControl().Foreground(foregroundBrush);
|
TSFInputControl().Foreground(foregroundBrush);
|
||||||
|
|
||||||
_core->UpdateAppearance(newAppearance);
|
_core.UpdateAppearance(newAppearance);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
|
@ -373,12 +374,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
// - <none>
|
// - <none>
|
||||||
void TermControl::SendInput(const winrt::hstring& wstr)
|
void TermControl::SendInput(const winrt::hstring& wstr)
|
||||||
{
|
{
|
||||||
_core->SendInput(wstr);
|
_core.SendInput(wstr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TermControl::ToggleShaderEffects()
|
void TermControl::ToggleShaderEffects()
|
||||||
{
|
{
|
||||||
_core->ToggleShaderEffects();
|
_core.ToggleShaderEffects();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
|
@ -401,7 +402,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
_changeBackgroundColor(bg);
|
_changeBackgroundColor(bg);
|
||||||
|
|
||||||
// Apply padding as swapChainPanel's margin
|
// Apply padding as swapChainPanel's margin
|
||||||
auto newMargin = _ParseThicknessFromPadding(newSettings.Padding());
|
auto newMargin = ParseThicknessFromPadding(newSettings.Padding());
|
||||||
SwapChainPanel().Margin(newMargin);
|
SwapChainPanel().Margin(newMargin);
|
||||||
|
|
||||||
TSFInputControl().Margin(newMargin);
|
TSFInputControl().Margin(newMargin);
|
||||||
|
@ -422,7 +423,14 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
ScrollBar().Visibility(Visibility::Visible);
|
ScrollBar().Visibility(Visibility::Visible);
|
||||||
}
|
}
|
||||||
|
|
||||||
_interactivity->UpdateSettings();
|
_interactivity.UpdateSettings();
|
||||||
|
if (_automationPeer)
|
||||||
|
{
|
||||||
|
_automationPeer.SetControlPadding(Core::Padding{ newMargin.Left,
|
||||||
|
newMargin.Top,
|
||||||
|
newMargin.Right,
|
||||||
|
newMargin.Bottom });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
|
@ -471,7 +479,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
}
|
}
|
||||||
|
|
||||||
// GH#5098: Inform the engine of the new opacity of the default text background.
|
// GH#5098: Inform the engine of the new opacity of the default text background.
|
||||||
_core->SetBackgroundOpacity(::base::saturated_cast<float>(_settings.TintOpacity()));
|
_core.SetBackgroundOpacity(::base::saturated_cast<float>(_settings.TintOpacity()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -479,7 +487,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
RootGrid().Background(solidColor);
|
RootGrid().Background(solidColor);
|
||||||
|
|
||||||
// GH#5098: Inform the engine of the new opacity of the default text background.
|
// GH#5098: Inform the engine of the new opacity of the default text background.
|
||||||
_core->SetBackgroundOpacity(1.0f);
|
_core.SetBackgroundOpacity(1.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -492,7 +500,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
void TermControl::_BackgroundColorChangedHandler(const IInspectable& /*sender*/,
|
void TermControl::_BackgroundColorChangedHandler(const IInspectable& /*sender*/,
|
||||||
const IInspectable& /*args*/)
|
const IInspectable& /*args*/)
|
||||||
{
|
{
|
||||||
til::color newBgColor{ _core->BackgroundColor() };
|
til::color newBgColor{ _core.BackgroundColor() };
|
||||||
_changeBackgroundColor(newBgColor);
|
_changeBackgroundColor(newBgColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -527,37 +535,25 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - The automation peer for our control
|
// - The automation peer for our control
|
||||||
Windows::UI::Xaml::Automation::Peers::AutomationPeer TermControl::OnCreateAutomationPeer()
|
Windows::UI::Xaml::Automation::Peers::AutomationPeer TermControl::OnCreateAutomationPeer()
|
||||||
try
|
|
||||||
{
|
{
|
||||||
if (_initializedTerminal && !_IsClosing()) // only set up the automation peer if we're ready to go live
|
if (_initializedTerminal && !_IsClosing()) // only set up the automation peer if we're ready to go live
|
||||||
{
|
{
|
||||||
// create a custom automation peer with this code pattern:
|
// create a custom automation peer with this code pattern:
|
||||||
// (https://docs.microsoft.com/en-us/windows/uwp/design/accessibility/custom-automation-peers)
|
// (https://docs.microsoft.com/en-us/windows/uwp/design/accessibility/custom-automation-peers)
|
||||||
auto autoPeer = winrt::make_self<implementation::TermControlAutomationPeer>(this);
|
if (const auto& interactivityAutoPeer = _interactivity.OnCreateAutomationPeer())
|
||||||
|
{
|
||||||
_uiaEngine = std::make_unique<::Microsoft::Console::Render::UiaEngine>(autoPeer.get());
|
_automationPeer = winrt::make<implementation::TermControlAutomationPeer>(this, interactivityAutoPeer);
|
||||||
_core->AttachUiaEngine(_uiaEngine.get());
|
return _automationPeer;
|
||||||
_automationPeer = *autoPeer;
|
}
|
||||||
return _automationPeer;
|
|
||||||
}
|
}
|
||||||
return nullptr;
|
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
|
// This is needed for TermControlAutomationPeer. We probably could find a
|
||||||
// clever way around asking the core for this.
|
// clever way around asking the core for this.
|
||||||
til::point TermControl::GetFontSize() const
|
til::point TermControl::GetFontSize() const
|
||||||
{
|
{
|
||||||
return _core->GetFont().GetSize();
|
return til::point{ til::math::rounding, _core.FontSize().Width, _core.FontSize().Height };
|
||||||
}
|
}
|
||||||
|
|
||||||
const Windows::UI::Xaml::Thickness TermControl::GetPadding()
|
const Windows::UI::Xaml::Thickness TermControl::GetPadding()
|
||||||
|
@ -567,7 +563,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
|
|
||||||
TerminalConnection::ConnectionState TermControl::ConnectionState() const
|
TerminalConnection::ConnectionState TermControl::ConnectionState() const
|
||||||
{
|
{
|
||||||
return _core->ConnectionState();
|
return _core.ConnectionState();
|
||||||
}
|
}
|
||||||
|
|
||||||
winrt::fire_and_forget TermControl::RenderEngineSwapChainChanged(IInspectable /*sender*/, IInspectable /*args*/)
|
winrt::fire_and_forget TermControl::RenderEngineSwapChainChanged(IInspectable /*sender*/, IInspectable /*args*/)
|
||||||
|
@ -581,7 +577,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
|
|
||||||
if (auto control{ weakThis.get() })
|
if (auto control{ weakThis.get() })
|
||||||
{
|
{
|
||||||
const auto chainHandle = _core->GetSwapChainHandle();
|
const HANDLE chainHandle = reinterpret_cast<HANDLE>(control->_core.SwapChainHandle());
|
||||||
_AttachDxgiSwapChainToXaml(chainHandle);
|
_AttachDxgiSwapChainToXaml(chainHandle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -658,23 +654,23 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
// after Enable, then it'll be possible to paint the frame once
|
// after Enable, then it'll be possible to paint the frame once
|
||||||
// _before_ the warning handler is set up, and then warnings from
|
// _before_ the warning handler is set up, and then warnings from
|
||||||
// the first paint will be ignored!
|
// the first paint will be ignored!
|
||||||
_core->RendererWarning({ get_weak(), &TermControl::_RendererWarning });
|
_core.RendererWarning({ get_weak(), &TermControl::_RendererWarning });
|
||||||
|
|
||||||
const auto coreInitialized = _core->Initialize(panelWidth,
|
const auto coreInitialized = _core.Initialize(panelWidth,
|
||||||
panelHeight,
|
panelHeight,
|
||||||
panelScaleX);
|
panelScaleX);
|
||||||
if (!coreInitialized)
|
if (!coreInitialized)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
_interactivity->Initialize();
|
_interactivity.Initialize();
|
||||||
|
|
||||||
_AttachDxgiSwapChainToXaml(_core->GetSwapChainHandle());
|
_AttachDxgiSwapChainToXaml(reinterpret_cast<HANDLE>(_core.SwapChainHandle()));
|
||||||
|
|
||||||
// Tell the DX Engine to notify us when the swap chain changes. We do
|
// 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
|
// this after we initially set the swapchain so as to avoid unnecessary
|
||||||
// callbacks (and locking problems)
|
// callbacks (and locking problems)
|
||||||
_core->SwapChainChanged({ get_weak(), &TermControl::RenderEngineSwapChainChanged });
|
_core.SwapChainChanged({ get_weak(), &TermControl::RenderEngineSwapChainChanged });
|
||||||
|
|
||||||
// !! LOAD BEARING !!
|
// !! LOAD BEARING !!
|
||||||
// Make sure you enable painting _AFTER_ calling _AttachDxgiSwapChainToXaml
|
// Make sure you enable painting _AFTER_ calling _AttachDxgiSwapChainToXaml
|
||||||
|
@ -684,9 +680,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
// issues where the Renderer starts trying to paint before we've
|
// issues where the Renderer starts trying to paint before we've
|
||||||
// actually attached the swapchain to anything, and the DxEngine is not
|
// actually attached the swapchain to anything, and the DxEngine is not
|
||||||
// prepared to handle that.
|
// prepared to handle that.
|
||||||
_core->EnablePainting();
|
_core.EnablePainting();
|
||||||
|
|
||||||
auto bufferHeight = _core->BufferHeight();
|
auto bufferHeight = _core.BufferHeight();
|
||||||
|
|
||||||
ScrollBar().Maximum(bufferHeight - bufferHeight);
|
ScrollBar().Maximum(bufferHeight - bufferHeight);
|
||||||
ScrollBar().Minimum(0);
|
ScrollBar().Minimum(0);
|
||||||
|
@ -763,7 +759,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
{
|
{
|
||||||
modifiers |= ControlKeyStates::EnhancedKey;
|
modifiers |= ControlKeyStates::EnhancedKey;
|
||||||
}
|
}
|
||||||
const bool handled = _core->SendCharEvent(ch, scanCode, modifiers);
|
const bool handled = _core.SendCharEvent(ch, scanCode, modifiers);
|
||||||
e.Handled(handled);
|
e.Handled(handled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -775,7 +771,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
bool TermControl::OnDirectKeyEvent(const uint32_t vkey, const uint8_t scanCode, const bool down)
|
bool TermControl::OnDirectKeyEvent(const uint32_t vkey, const uint8_t scanCode, const bool down)
|
||||||
{
|
{
|
||||||
// Short-circuit isReadOnly check to avoid warning dialog
|
// Short-circuit isReadOnly check to avoid warning dialog
|
||||||
if (_core->IsInReadOnlyMode())
|
if (_core.IsInReadOnlyMode())
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -861,7 +857,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
const auto scanCode = gsl::narrow_cast<WORD>(e.KeyStatus().ScanCode);
|
const auto scanCode = gsl::narrow_cast<WORD>(e.KeyStatus().ScanCode);
|
||||||
|
|
||||||
// Short-circuit isReadOnly check to avoid warning dialog
|
// Short-circuit isReadOnly check to avoid warning dialog
|
||||||
if (_core->IsInReadOnlyMode())
|
if (_core.IsInReadOnlyMode())
|
||||||
{
|
{
|
||||||
e.Handled(!keyDown || _TryHandleKeyBinding(vkey, scanCode, modifiers));
|
e.Handled(!keyDown || _TryHandleKeyBinding(vkey, scanCode, modifiers));
|
||||||
return;
|
return;
|
||||||
|
@ -993,17 +989,17 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
// This will prevent the system from trying to get the character out
|
// This will prevent the system from trying to get the character out
|
||||||
// of it and sending us a CharacterReceived event.
|
// of it and sending us a CharacterReceived event.
|
||||||
const auto handled = vkey ?
|
const auto handled = vkey ?
|
||||||
_core->TrySendKeyEvent(vkey,
|
_core.TrySendKeyEvent(vkey,
|
||||||
scanCode,
|
scanCode,
|
||||||
modifiers,
|
modifiers,
|
||||||
keyDown) :
|
keyDown) :
|
||||||
true;
|
true;
|
||||||
|
|
||||||
if (_cursorTimer)
|
if (_cursorTimer)
|
||||||
{
|
{
|
||||||
// Manually show the cursor when a key is pressed. Restarting
|
// Manually show the cursor when a key is pressed. Restarting
|
||||||
// the timer prevents flickering.
|
// the timer prevents flickering.
|
||||||
_core->CursorOn(true);
|
_core.CursorOn(true);
|
||||||
_cursorTimer->Start();
|
_cursorTimer->Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1057,16 +1053,16 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
{
|
{
|
||||||
const auto contactRect = point.Properties().ContactRect();
|
const auto contactRect = point.Properties().ContactRect();
|
||||||
auto anchor = til::point{ til::math::rounding, contactRect.X, contactRect.Y };
|
auto anchor = til::point{ til::math::rounding, contactRect.X, contactRect.Y };
|
||||||
_interactivity->TouchPressed(anchor);
|
_interactivity.TouchPressed(anchor);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const auto cursorPosition = point.Position();
|
const auto cursorPosition = point.Position();
|
||||||
_interactivity->PointerPressed(TermControl::GetPressedMouseButtons(point),
|
_interactivity.PointerPressed(TermControl::GetPressedMouseButtons(point),
|
||||||
TermControl::GetPointerUpdateKind(point),
|
TermControl::GetPointerUpdateKind(point),
|
||||||
point.Timestamp(),
|
point.Timestamp(),
|
||||||
ControlKeyStates{ args.KeyModifiers() },
|
ControlKeyStates{ args.KeyModifiers() },
|
||||||
_toTerminalOrigin(cursorPosition));
|
_toTerminalOrigin(cursorPosition));
|
||||||
}
|
}
|
||||||
|
|
||||||
args.Handled(true);
|
args.Handled(true);
|
||||||
|
@ -1101,11 +1097,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
if (type == Windows::Devices::Input::PointerDeviceType::Mouse ||
|
if (type == Windows::Devices::Input::PointerDeviceType::Mouse ||
|
||||||
type == Windows::Devices::Input::PointerDeviceType::Pen)
|
type == Windows::Devices::Input::PointerDeviceType::Pen)
|
||||||
{
|
{
|
||||||
_interactivity->PointerMoved(TermControl::GetPressedMouseButtons(point),
|
_interactivity.PointerMoved(TermControl::GetPressedMouseButtons(point),
|
||||||
TermControl::GetPointerUpdateKind(point),
|
TermControl::GetPointerUpdateKind(point),
|
||||||
ControlKeyStates(args.KeyModifiers()),
|
ControlKeyStates(args.KeyModifiers()),
|
||||||
_focused,
|
_focused,
|
||||||
pixelPosition);
|
pixelPosition);
|
||||||
|
|
||||||
if (_focused && point.Properties().IsLeftButtonPressed())
|
if (_focused && point.Properties().IsLeftButtonPressed())
|
||||||
{
|
{
|
||||||
|
@ -1138,7 +1134,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
const auto contactRect = point.Properties().ContactRect();
|
const auto contactRect = point.Properties().ContactRect();
|
||||||
til::point newTouchPoint{ til::math::rounding, contactRect.X, contactRect.Y };
|
til::point newTouchPoint{ til::math::rounding, contactRect.X, contactRect.Y };
|
||||||
|
|
||||||
_interactivity->TouchMoved(newTouchPoint, _focused);
|
_interactivity.TouchMoved(newTouchPoint, _focused);
|
||||||
}
|
}
|
||||||
|
|
||||||
args.Handled(true);
|
args.Handled(true);
|
||||||
|
@ -1169,14 +1165,14 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
if (type == Windows::Devices::Input::PointerDeviceType::Mouse ||
|
if (type == Windows::Devices::Input::PointerDeviceType::Mouse ||
|
||||||
type == Windows::Devices::Input::PointerDeviceType::Pen)
|
type == Windows::Devices::Input::PointerDeviceType::Pen)
|
||||||
{
|
{
|
||||||
_interactivity->PointerReleased(TermControl::GetPressedMouseButtons(point),
|
_interactivity.PointerReleased(TermControl::GetPressedMouseButtons(point),
|
||||||
TermControl::GetPointerUpdateKind(point),
|
TermControl::GetPointerUpdateKind(point),
|
||||||
ControlKeyStates(args.KeyModifiers()),
|
ControlKeyStates(args.KeyModifiers()),
|
||||||
pixelPosition);
|
pixelPosition);
|
||||||
}
|
}
|
||||||
else if (type == Windows::Devices::Input::PointerDeviceType::Touch)
|
else if (type == Windows::Devices::Input::PointerDeviceType::Touch)
|
||||||
{
|
{
|
||||||
_interactivity->TouchReleased();
|
_interactivity.TouchReleased();
|
||||||
}
|
}
|
||||||
|
|
||||||
_TryStopAutoScroll(ptr.PointerId());
|
_TryStopAutoScroll(ptr.PointerId());
|
||||||
|
@ -1204,10 +1200,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
|
|
||||||
const auto point = args.GetCurrentPoint(*this);
|
const auto point = args.GetCurrentPoint(*this);
|
||||||
|
|
||||||
auto result = _interactivity->MouseWheel(ControlKeyStates{ args.KeyModifiers() },
|
auto result = _interactivity.MouseWheel(ControlKeyStates{ args.KeyModifiers() },
|
||||||
point.Properties().MouseWheelDelta(),
|
point.Properties().MouseWheelDelta(),
|
||||||
_toTerminalOrigin(point.Position()),
|
_toTerminalOrigin(point.Position()),
|
||||||
TermControl::GetPressedMouseButtons(point));
|
TermControl::GetPressedMouseButtons(point));
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
args.Handled(true);
|
args.Handled(true);
|
||||||
|
@ -1231,10 +1227,13 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
const bool rightButtonDown)
|
const bool rightButtonDown)
|
||||||
{
|
{
|
||||||
const auto modifiers = _GetPressedModifierKeys();
|
const auto modifiers = _GetPressedModifierKeys();
|
||||||
TerminalInput::MouseButtonState state{ leftButtonDown,
|
|
||||||
midButtonDown,
|
Control::MouseButtonState state{};
|
||||||
rightButtonDown };
|
WI_SetFlagIf(state, Control::MouseButtonState::IsLeftButtonDown, leftButtonDown);
|
||||||
return _interactivity->MouseWheel(modifiers, delta, _toTerminalOrigin(location), state);
|
WI_SetFlagIf(state, Control::MouseButtonState::IsMiddleButtonDown, midButtonDown);
|
||||||
|
WI_SetFlagIf(state, Control::MouseButtonState::IsRightButtonDown, rightButtonDown);
|
||||||
|
|
||||||
|
return _interactivity.MouseWheel(modifiers, delta, _toTerminalOrigin(location), state);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
|
@ -1282,7 +1281,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
// - none
|
// - none
|
||||||
void TermControl::ResetFontSize()
|
void TermControl::ResetFontSize()
|
||||||
{
|
{
|
||||||
_core->ResetFontSize();
|
_core.ResetFontSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
|
@ -1291,7 +1290,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
// - fontSizeDelta: The amount to increase or decrease the font size by.
|
// - fontSizeDelta: The amount to increase or decrease the font size by.
|
||||||
void TermControl::AdjustFontSize(int fontSizeDelta)
|
void TermControl::AdjustFontSize(int fontSizeDelta)
|
||||||
{
|
{
|
||||||
_core->AdjustFontSize(fontSizeDelta);
|
_core.AdjustFontSize(fontSizeDelta);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TermControl::_ScrollbarChangeHandler(Windows::Foundation::IInspectable const& /*sender*/,
|
void TermControl::_ScrollbarChangeHandler(Windows::Foundation::IInspectable const& /*sender*/,
|
||||||
|
@ -1306,7 +1305,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto newValue = args.NewValue();
|
const auto newValue = args.NewValue();
|
||||||
_interactivity->UpdateScrollbar(newValue);
|
_interactivity.UpdateScrollbar(newValue);
|
||||||
|
|
||||||
// User input takes priority over terminal events so cancel
|
// User input takes priority over terminal events so cancel
|
||||||
// any pending scroll bar update if the user scrolls.
|
// any pending scroll bar update if the user scrolls.
|
||||||
|
@ -1452,10 +1451,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
|
|
||||||
// GH#5421: Enable the UiaEngine before checking for the SearchBox
|
// GH#5421: Enable the UiaEngine before checking for the SearchBox
|
||||||
// That way, new selections are notified to automation clients.
|
// That way, new selections are notified to automation clients.
|
||||||
if (_uiaEngine.get())
|
// The _uiaEngine lives in _interactivity, so call into there to enable it.
|
||||||
{
|
_interactivity.GotFocus();
|
||||||
THROW_IF_FAILED(_uiaEngine->Enable());
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the searchbox is focused, we don't want TSFInputControl to think
|
// 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
|
// it has focus so it doesn't intercept IME input. We also don't want the
|
||||||
|
@ -1473,7 +1470,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
if (_cursorTimer)
|
if (_cursorTimer)
|
||||||
{
|
{
|
||||||
// When the terminal focuses, show the cursor immediately
|
// When the terminal focuses, show the cursor immediately
|
||||||
_core->CursorOn(true);
|
_core.CursorOn(true);
|
||||||
_cursorTimer->Start();
|
_cursorTimer->Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1482,8 +1479,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
_blinkTimer->Start();
|
_blinkTimer->Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
_interactivity->GainFocus();
|
|
||||||
|
|
||||||
// Only update the appearance here if an unfocused config exists -
|
// Only update the appearance here if an unfocused config exists -
|
||||||
// if an unfocused config does not exist then we never would have switched
|
// 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
|
// appearances anyway so there's no need to switch back upon gaining focus
|
||||||
|
@ -1509,10 +1504,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
|
|
||||||
_focused = false;
|
_focused = false;
|
||||||
|
|
||||||
if (_uiaEngine.get())
|
// This will disable the accessibility notifications, because the
|
||||||
{
|
// UiaEngine lives in ControlInteractivity
|
||||||
THROW_IF_FAILED(_uiaEngine->Disable());
|
_interactivity.LostFocus();
|
||||||
}
|
|
||||||
|
|
||||||
if (TSFInputControl() != nullptr)
|
if (TSFInputControl() != nullptr)
|
||||||
{
|
{
|
||||||
|
@ -1522,7 +1516,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
if (_cursorTimer)
|
if (_cursorTimer)
|
||||||
{
|
{
|
||||||
_cursorTimer->Stop();
|
_cursorTimer->Stop();
|
||||||
_core->CursorOn(false);
|
_core.CursorOn(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_blinkTimer)
|
if (_blinkTimer)
|
||||||
|
@ -1552,7 +1546,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto newSize = e.NewSize();
|
const auto newSize = e.NewSize();
|
||||||
_core->SizeChanged(newSize.Width, newSize.Height);
|
_core.SizeChanged(newSize.Width, newSize.Height);
|
||||||
|
|
||||||
|
if (_automationPeer)
|
||||||
|
{
|
||||||
|
_automationPeer.UpdateControlBounds();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
|
@ -1587,7 +1586,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
{
|
{
|
||||||
const auto scaleX = sender.CompositionScaleX();
|
const auto scaleX = sender.CompositionScaleX();
|
||||||
|
|
||||||
_core->ScaleChanged(scaleX);
|
_core.ScaleChanged(scaleX);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
|
@ -1600,7 +1599,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
{
|
{
|
||||||
if (!_IsClosing())
|
if (!_IsClosing())
|
||||||
{
|
{
|
||||||
_core->BlinkCursor();
|
_core.BlinkCursor();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1614,7 +1613,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
{
|
{
|
||||||
if (!_IsClosing())
|
if (!_IsClosing())
|
||||||
{
|
{
|
||||||
_core->BlinkAttributeTick();
|
_core.BlinkAttributeTick();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1624,7 +1623,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
// - cursorPosition: in pixels, relative to the origin of the control
|
// - cursorPosition: in pixels, relative to the origin of the control
|
||||||
void TermControl::_SetEndSelectionPointAtCursor(Windows::Foundation::Point const& cursorPosition)
|
void TermControl::_SetEndSelectionPointAtCursor(Windows::Foundation::Point const& cursorPosition)
|
||||||
{
|
{
|
||||||
_interactivity->SetEndSelectionPoint(_toTerminalOrigin(cursorPosition));
|
_interactivity.SetEndSelectionPoint(_toTerminalOrigin(cursorPosition));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
|
@ -1664,7 +1663,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
|
|
||||||
hstring TermControl::Title()
|
hstring TermControl::Title()
|
||||||
{
|
{
|
||||||
return _core->Title();
|
return _core.Title();
|
||||||
}
|
}
|
||||||
|
|
||||||
hstring TermControl::GetProfileName() const
|
hstring TermControl::GetProfileName() const
|
||||||
|
@ -1674,12 +1673,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
|
|
||||||
hstring TermControl::WorkingDirectory() const
|
hstring TermControl::WorkingDirectory() const
|
||||||
{
|
{
|
||||||
return _core->WorkingDirectory();
|
return _core.WorkingDirectory();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TermControl::BracketedPasteEnabled() const noexcept
|
bool TermControl::BracketedPasteEnabled() const noexcept
|
||||||
{
|
{
|
||||||
return _core->BracketedPasteEnabled();
|
return _core.BracketedPasteEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
|
@ -1697,14 +1696,14 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return _interactivity->CopySelectionToClipboard(singleLine, formats);
|
return _interactivity.CopySelectionToClipboard(singleLine, formats);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
// - Initiate a paste operation.
|
// - Initiate a paste operation.
|
||||||
void TermControl::PasteTextFromClipboard()
|
void TermControl::PasteTextFromClipboard()
|
||||||
{
|
{
|
||||||
_interactivity->RequestPasteTextFromClipboard();
|
_interactivity.RequestPasteTextFromClipboard();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TermControl::Close()
|
void TermControl::Close()
|
||||||
|
@ -1713,13 +1712,13 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
{
|
{
|
||||||
_closing = true;
|
_closing = true;
|
||||||
|
|
||||||
_core->ReceivedOutput(_coreOutputEventToken);
|
_core.ReceivedOutput(_coreOutputEventToken);
|
||||||
_RestorePointerCursorHandlers(*this, nullptr);
|
_RestorePointerCursorHandlers(*this, nullptr);
|
||||||
// Disconnect the TSF input control so it doesn't receive EditContext events.
|
// Disconnect the TSF input control so it doesn't receive EditContext events.
|
||||||
TSFInputControl().Close();
|
TSFInputControl().Close();
|
||||||
_autoScrollTimer.Stop();
|
_autoScrollTimer.Stop();
|
||||||
|
|
||||||
_core->Close();
|
_core.Close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1732,9 +1731,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
ScrollBar().Value(viewTop);
|
ScrollBar().Value(viewTop);
|
||||||
}
|
}
|
||||||
|
|
||||||
int TermControl::ScrollOffset()
|
int TermControl::ScrollOffset() const
|
||||||
{
|
{
|
||||||
return _core->ScrollOffset();
|
return _core.ScrollOffset();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function Description:
|
// Function Description:
|
||||||
|
@ -1743,7 +1742,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
// - The height of the terminal in lines of text
|
// - The height of the terminal in lines of text
|
||||||
int TermControl::ViewHeight() const
|
int TermControl::ViewHeight() const
|
||||||
{
|
{
|
||||||
return _core->ViewHeight();
|
return _core.ViewHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
int TermControl::BufferHeight() const
|
||||||
|
{
|
||||||
|
return _core.BufferHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function Description:
|
// Function Description:
|
||||||
|
@ -1844,7 +1848,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
}
|
}
|
||||||
|
|
||||||
double height = rows * fontSize.Y;
|
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
|
// GH#2061 - make sure to account for the size the padding _will be_ scaled to
|
||||||
width += scale * (thickness.Left + thickness.Right);
|
width += scale * (thickness.Left + thickness.Right);
|
||||||
height += scale * (thickness.Top + thickness.Bottom);
|
height += scale * (thickness.Top + thickness.Bottom);
|
||||||
|
@ -1862,8 +1866,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
// - The dimensions of a single character of this control, in DIPs
|
// - The dimensions of a single character of this control, in DIPs
|
||||||
winrt::Windows::Foundation::Size TermControl::CharacterDimensions() const
|
winrt::Windows::Foundation::Size TermControl::CharacterDimensions() const
|
||||||
{
|
{
|
||||||
const auto fontSize = _core->GetFont().GetSize();
|
return _core.FontSize();
|
||||||
return { gsl::narrow_cast<float>(fontSize.X), gsl::narrow_cast<float>(fontSize.Y) };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
|
@ -1879,9 +1882,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
{
|
{
|
||||||
if (_initializedTerminal)
|
if (_initializedTerminal)
|
||||||
{
|
{
|
||||||
const auto fontSize = _core->GetFont().GetSize();
|
const auto fontSize = _core.FontSize();
|
||||||
double width = fontSize.X;
|
double width = fontSize.Width;
|
||||||
double height = fontSize.Y;
|
double height = fontSize.Height;
|
||||||
// Reserve additional space if scrollbar is intended to be visible
|
// Reserve additional space if scrollbar is intended to be visible
|
||||||
if (_settings.ScrollState() == ScrollbarState::Visible)
|
if (_settings.ScrollState() == ScrollbarState::Visible)
|
||||||
{
|
{
|
||||||
|
@ -1924,8 +1927,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
// - A dimension that would be aligned to the character grid.
|
// - A dimension that would be aligned to the character grid.
|
||||||
float TermControl::SnapDimensionToGrid(const bool widthOrHeight, const float dimension)
|
float TermControl::SnapDimensionToGrid(const bool widthOrHeight, const float dimension)
|
||||||
{
|
{
|
||||||
const auto fontSize = _core->GetFont().GetSize();
|
const auto fontSize = _core.FontSize();
|
||||||
const auto fontDimension = widthOrHeight ? fontSize.X : fontSize.Y;
|
const auto fontDimension = widthOrHeight ? fontSize.Width : fontSize.Height;
|
||||||
|
|
||||||
const auto padding = GetPadding();
|
const auto padding = GetPadding();
|
||||||
auto nonTerminalArea = gsl::narrow_cast<float>(widthOrHeight ?
|
auto nonTerminalArea = gsl::narrow_cast<float>(widthOrHeight ?
|
||||||
|
@ -1952,7 +1955,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
// Four Double values provide independent padding for 4 sides of the bounding rectangle
|
// Four Double values provide independent padding for 4 sides of the bounding rectangle
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - Windows::UI::Xaml::Thickness object
|
// - 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',';
|
const wchar_t singleCharDelim = L',';
|
||||||
std::wstringstream tokenStream(padding.c_str());
|
std::wstringstream tokenStream(padding.c_str());
|
||||||
|
@ -2085,7 +2088,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_core->SendInput(text);
|
_core.SendInput(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
|
@ -2105,7 +2108,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const til::point cursorPos = _core->CursorPosition();
|
const til::point cursorPos = _core.CursorPosition();
|
||||||
Windows::Foundation::Point p = { ::base::ClampedNumeric<float>(cursorPos.x()),
|
Windows::Foundation::Point p = { ::base::ClampedNumeric<float>(cursorPos.x()),
|
||||||
::base::ClampedNumeric<float>(cursorPos.y()) };
|
::base::ClampedNumeric<float>(cursorPos.y()) };
|
||||||
eventArgs.CurrentPosition(p);
|
eventArgs.CurrentPosition(p);
|
||||||
|
@ -2121,11 +2124,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
void TermControl::_FontInfoHandler(const IInspectable& /*sender*/,
|
void TermControl::_FontInfoHandler(const IInspectable& /*sender*/,
|
||||||
const FontInfoEventArgs& eventArgs)
|
const FontInfoEventArgs& eventArgs)
|
||||||
{
|
{
|
||||||
const auto fontInfo = _core->GetFont();
|
|
||||||
eventArgs.FontSize(CharacterDimensions());
|
eventArgs.FontSize(CharacterDimensions());
|
||||||
eventArgs.FontFace(fontInfo.GetFaceName());
|
eventArgs.FontFace(_core.FontFaceName());
|
||||||
::winrt::Windows::UI::Text::FontWeight weight;
|
::winrt::Windows::UI::Text::FontWeight weight;
|
||||||
weight.Weight = static_cast<uint16_t>(fontInfo.GetWeight());
|
weight.Weight = _core.FontWeight();
|
||||||
eventArgs.FontWeight(weight);
|
eventArgs.FontWeight(weight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2167,7 +2169,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Windows::Foundation::Uri link{ co_await e.DataView().GetApplicationLinkAsync() };
|
Windows::Foundation::Uri link{ co_await e.DataView().GetApplicationLinkAsync() };
|
||||||
_core->PasteText(link.AbsoluteUri());
|
_core.PasteText(link.AbsoluteUri());
|
||||||
}
|
}
|
||||||
CATCH_LOG();
|
CATCH_LOG();
|
||||||
}
|
}
|
||||||
|
@ -2176,7 +2178,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Windows::Foundation::Uri link{ co_await e.DataView().GetWebLinkAsync() };
|
Windows::Foundation::Uri link{ co_await e.DataView().GetWebLinkAsync() };
|
||||||
_core->PasteText(link.AbsoluteUri());
|
_core.PasteText(link.AbsoluteUri());
|
||||||
}
|
}
|
||||||
CATCH_LOG();
|
CATCH_LOG();
|
||||||
}
|
}
|
||||||
|
@ -2185,7 +2187,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
auto text{ co_await e.DataView().GetTextAsync() };
|
auto text{ co_await e.DataView().GetTextAsync() };
|
||||||
_core->PasteText(text);
|
_core.PasteText(text);
|
||||||
}
|
}
|
||||||
CATCH_LOG();
|
CATCH_LOG();
|
||||||
}
|
}
|
||||||
|
@ -2226,7 +2228,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
|
|
||||||
allPaths += fullPath;
|
allPaths += fullPath;
|
||||||
}
|
}
|
||||||
_core->PasteText(winrt::hstring{ allPaths });
|
_core.PasteText(winrt::hstring{ allPaths });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2321,7 +2323,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
{
|
{
|
||||||
// It's already loaded if we get here, so just hide it.
|
// It's already loaded if we get here, so just hide it.
|
||||||
RendererFailedNotice().Visibility(Visibility::Collapsed);
|
RendererFailedNotice().Visibility(Visibility::Collapsed);
|
||||||
_core->ResumeRendering();
|
_core.ResumeRendering();
|
||||||
}
|
}
|
||||||
|
|
||||||
IControlSettings TermControl::Settings() const
|
IControlSettings TermControl::Settings() const
|
||||||
|
@ -2340,25 +2342,25 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
// hypothetical future where we allow an application to set the tab
|
// hypothetical future where we allow an application to set the tab
|
||||||
// color with VT sequences like they're currently allowed to with the
|
// color with VT sequences like they're currently allowed to with the
|
||||||
// title.
|
// title.
|
||||||
return _core->TabColor();
|
return _core.TabColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
// - Gets the internal taskbar state value
|
// - Gets the internal taskbar state value
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - The taskbar state of this control
|
// - The taskbar state of this control
|
||||||
const size_t TermControl::TaskbarState() const noexcept
|
const uint64_t TermControl::TaskbarState() const noexcept
|
||||||
{
|
{
|
||||||
return _core->TaskbarState();
|
return _core.TaskbarState();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
// - Gets the internal taskbar progress value
|
// - Gets the internal taskbar progress value
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - The taskbar progress of this control
|
// - The taskbar progress of this control
|
||||||
const size_t TermControl::TaskbarProgress() const noexcept
|
const uint64_t TermControl::TaskbarProgress() const noexcept
|
||||||
{
|
{
|
||||||
return _core->TaskbarProgress();
|
return _core.TaskbarProgress();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TermControl::BellLightOn()
|
void TermControl::BellLightOn()
|
||||||
|
@ -2418,15 +2420,15 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
// - True if the mode is read-only
|
// - True if the mode is read-only
|
||||||
bool TermControl::ReadOnly() const noexcept
|
bool TermControl::ReadOnly() const noexcept
|
||||||
{
|
{
|
||||||
return _core->IsInReadOnlyMode();
|
return _core.IsInReadOnlyMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
// - Toggles the read-only flag, raises event describing the value change
|
// - Toggles the read-only flag, raises event describing the value change
|
||||||
void TermControl::ToggleReadOnly()
|
void TermControl::ToggleReadOnly()
|
||||||
{
|
{
|
||||||
_core->ToggleReadOnlyMode();
|
_core.ToggleReadOnlyMode();
|
||||||
_ReadOnlyChangedHandlers(*this, winrt::box_value(_core->IsInReadOnlyMode()));
|
_ReadOnlyChangedHandlers(*this, winrt::box_value(_core.IsInReadOnlyMode()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
|
@ -2435,9 +2437,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// - sender: not used
|
// - sender: not used
|
||||||
// - args: event data
|
// - 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.ClearHoveredCell();
|
||||||
}
|
}
|
||||||
|
|
||||||
winrt::fire_and_forget TermControl::_hoveredHyperlinkChanged(IInspectable sender,
|
winrt::fire_and_forget TermControl::_hoveredHyperlinkChanged(IInspectable sender,
|
||||||
|
@ -2447,10 +2450,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
co_await resume_foreground(Dispatcher());
|
co_await resume_foreground(Dispatcher());
|
||||||
if (auto self{ weakThis.get() })
|
if (auto self{ weakThis.get() })
|
||||||
{
|
{
|
||||||
auto lastHoveredCell = _core->GetHoveredCell();
|
auto lastHoveredCell = _core.HoveredCell();
|
||||||
if (lastHoveredCell)
|
if (lastHoveredCell)
|
||||||
{
|
{
|
||||||
const auto uriText = _core->GetHoveredUriText();
|
const auto uriText = _core.HoveredUriText();
|
||||||
if (!uriText.empty())
|
if (!uriText.empty())
|
||||||
{
|
{
|
||||||
// Update the tooltip with the URI
|
// Update the tooltip with the URI
|
||||||
|
@ -2465,8 +2468,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
|
|
||||||
// Compute the location of the top left corner of the cell in DIPS
|
// 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::size marginsInDips{ til::math::rounding, GetPadding().Left, GetPadding().Top };
|
||||||
const til::point startPos{ *lastHoveredCell };
|
const til::point startPos{ lastHoveredCell.Value() };
|
||||||
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 posInPixels{ startPos * fontSize };
|
||||||
const til::point posInDIPs{ posInPixels / SwapChainPanel().CompositionScaleX() };
|
const til::point posInDIPs{ posInPixels / SwapChainPanel().CompositionScaleX() };
|
||||||
const til::point locationInDIPs{ posInDIPs + marginsInDips };
|
const til::point locationInDIPs{ posInDIPs + marginsInDips };
|
||||||
|
@ -2502,11 +2505,13 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
_RaiseNoticeHandlers(*this, eventArgs);
|
_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(),
|
Control::MouseButtonState state{};
|
||||||
point.Properties().IsMiddleButtonPressed(),
|
WI_SetFlagIf(state, Control::MouseButtonState::IsLeftButtonDown, point.Properties().IsLeftButtonPressed());
|
||||||
point.Properties().IsRightButtonPressed() };
|
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)
|
unsigned int TermControl::GetPointerUpdateKind(const winrt::Windows::UI::Input::PointerPoint point)
|
||||||
|
|
|
@ -40,8 +40,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
float SnapDimensionToGrid(const bool widthOrHeight, const float dimension);
|
float SnapDimensionToGrid(const bool widthOrHeight, const float dimension);
|
||||||
|
|
||||||
#pragma region ICoreState
|
#pragma region ICoreState
|
||||||
const size_t TaskbarState() const noexcept;
|
const uint64_t TaskbarState() const noexcept;
|
||||||
const size_t TaskbarProgress() const noexcept;
|
const uint64_t TaskbarProgress() const noexcept;
|
||||||
|
|
||||||
hstring Title();
|
hstring Title();
|
||||||
Windows::Foundation::IReference<winrt::Windows::UI::Color> TabColor() noexcept;
|
Windows::Foundation::IReference<winrt::Windows::UI::Color> TabColor() noexcept;
|
||||||
|
@ -49,7 +49,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
|
|
||||||
TerminalConnection::ConnectionState ConnectionState() const;
|
TerminalConnection::ConnectionState ConnectionState() const;
|
||||||
|
|
||||||
int ScrollOffset();
|
int ScrollOffset() const;
|
||||||
int ViewHeight() const;
|
int ViewHeight() const;
|
||||||
int BufferHeight() const;
|
int BufferHeight() const;
|
||||||
|
|
||||||
|
@ -84,7 +84,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
~TermControl();
|
~TermControl();
|
||||||
|
|
||||||
Windows::UI::Xaml::Automation::Peers::AutomationPeer OnCreateAutomationPeer();
|
Windows::UI::Xaml::Automation::Peers::AutomationPeer OnCreateAutomationPeer();
|
||||||
::Microsoft::Console::Types::IUiaData* GetUiaData() const;
|
|
||||||
const Windows::UI::Xaml::Thickness GetPadding();
|
const Windows::UI::Xaml::Thickness GetPadding();
|
||||||
|
|
||||||
IControlSettings Settings() const;
|
IControlSettings Settings() const;
|
||||||
|
@ -104,19 +103,21 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
bool ReadOnly() const noexcept;
|
bool ReadOnly() const noexcept;
|
||||||
void ToggleReadOnly();
|
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);
|
static unsigned int GetPointerUpdateKind(const winrt::Windows::UI::Input::PointerPoint point);
|
||||||
|
static Windows::UI::Xaml::Thickness ParseThicknessFromPadding(const hstring padding);
|
||||||
|
|
||||||
// -------------------------------- WinRT Events ---------------------------------
|
// -------------------------------- WinRT Events ---------------------------------
|
||||||
// clang-format off
|
// clang-format off
|
||||||
WINRT_CALLBACK(FontSizeChanged, Control::FontSizeChangedEventArgs);
|
WINRT_CALLBACK(FontSizeChanged, Control::FontSizeChangedEventArgs);
|
||||||
|
|
||||||
FORWARDED_TYPED_EVENT(CopyToClipboard, IInspectable, Control::CopyToClipboardEventArgs, _core, CopyToClipboard);
|
PROJECTED_FORWARDED_TYPED_EVENT(CopyToClipboard, IInspectable, Control::CopyToClipboardEventArgs, _core, CopyToClipboard);
|
||||||
FORWARDED_TYPED_EVENT(TitleChanged, IInspectable, Control::TitleChangedEventArgs, _core, TitleChanged);
|
PROJECTED_FORWARDED_TYPED_EVENT(TitleChanged, IInspectable, Control::TitleChangedEventArgs, _core, TitleChanged);
|
||||||
FORWARDED_TYPED_EVENT(TabColorChanged, IInspectable, IInspectable, _core, TabColorChanged);
|
PROJECTED_FORWARDED_TYPED_EVENT(TabColorChanged, IInspectable, IInspectable, _core, TabColorChanged);
|
||||||
FORWARDED_TYPED_EVENT(SetTaskbarProgress, IInspectable, IInspectable, _core, TaskbarProgressChanged);
|
PROJECTED_FORWARDED_TYPED_EVENT(SetTaskbarProgress, IInspectable, IInspectable, _core, TaskbarProgressChanged);
|
||||||
FORWARDED_TYPED_EVENT(ConnectionStateChanged, IInspectable, IInspectable, _core, ConnectionStateChanged);
|
PROJECTED_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(OpenHyperlink, IInspectable, Control::OpenHyperlinkEventArgs);
|
||||||
TYPED_EVENT(RaiseNotice, IInspectable, Control::NoticeEventArgs);
|
TYPED_EVENT(RaiseNotice, IInspectable, Control::NoticeEventArgs);
|
||||||
|
@ -141,11 +142,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
// IRenderEngine is accessed when ControlCore calls Renderer::TriggerTeardown.
|
// IRenderEngine is accessed when ControlCore calls Renderer::TriggerTeardown.
|
||||||
// (C++ class members are destroyed in reverse order.)
|
// (C++ class members are destroyed in reverse order.)
|
||||||
// Further, the TermControlAutomationPeer must be destructed after _uiaEngine!
|
// Further, the TermControlAutomationPeer must be destructed after _uiaEngine!
|
||||||
winrt::Windows::UI::Xaml::Automation::Peers::AutomationPeer _automationPeer{ nullptr };
|
Control::TermControlAutomationPeer _automationPeer{ nullptr };
|
||||||
std::unique_ptr<::Microsoft::Console::Render::UiaEngine> _uiaEngine;
|
Control::ControlInteractivity _interactivity{ nullptr };
|
||||||
|
Control::ControlCore _core{ nullptr };
|
||||||
|
|
||||||
winrt::com_ptr<ControlCore> _core;
|
|
||||||
winrt::com_ptr<ControlInteractivity> _interactivity;
|
|
||||||
winrt::com_ptr<SearchBoxControl> _searchBox;
|
winrt::com_ptr<SearchBoxControl> _searchBox;
|
||||||
|
|
||||||
IControlSettings _settings;
|
IControlSettings _settings;
|
||||||
|
@ -240,8 +240,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
void _TryStopAutoScroll(const uint32_t pointerId);
|
void _TryStopAutoScroll(const uint32_t pointerId);
|
||||||
void _UpdateAutoScroll(Windows::Foundation::IInspectable const& sender, Windows::Foundation::IInspectable const& e);
|
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);
|
void _KeyHandler(Windows::UI::Xaml::Input::KeyRoutedEventArgs const& e, const bool keyDown);
|
||||||
::Microsoft::Terminal::Core::ControlKeyStates _GetPressedModifierKeys() const;
|
::Microsoft::Terminal::Core::ControlKeyStates _GetPressedModifierKeys() const;
|
||||||
bool _TryHandleKeyBinding(const WORD vkey, const WORD scanCode, ::Microsoft::Terminal::Core::ControlKeyStates modifiers) const;
|
bool _TryHandleKeyBinding(const WORD vkey, const WORD scanCode, ::Microsoft::Terminal::Core::ControlKeyStates modifiers) const;
|
||||||
|
|
|
@ -30,13 +30,42 @@ namespace XamlAutomation
|
||||||
|
|
||||||
namespace winrt::Microsoft::Terminal::Control::implementation
|
namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
{
|
{
|
||||||
TermControlAutomationPeer::TermControlAutomationPeer(winrt::Microsoft::Terminal::Control::implementation::TermControl* owner) :
|
TermControlAutomationPeer::TermControlAutomationPeer(TermControl* owner,
|
||||||
|
Control::InteractivityAutomationPeer impl) :
|
||||||
TermControlAutomationPeerT<TermControlAutomationPeer>(*owner), // pass owner to FrameworkElementAutomationPeer
|
TermControlAutomationPeerT<TermControlAutomationPeer>(*owner), // pass owner to FrameworkElementAutomationPeer
|
||||||
_termControl{ owner }
|
_termControl{ owner },
|
||||||
|
_contentAutomationPeer{ impl }
|
||||||
{
|
{
|
||||||
THROW_IF_FAILED(::Microsoft::WRL::MakeAndInitialize<::Microsoft::Terminal::TermControlUiaProvider>(&_uiaProvider, _termControl->GetUiaData(), this));
|
UpdateControlBounds();
|
||||||
|
|
||||||
|
// 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:
|
||||||
|
// - 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);
|
||||||
|
}
|
||||||
|
|
||||||
// Method Description:
|
// 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
|
||||||
// Arguments:
|
// Arguments:
|
||||||
|
@ -167,106 +196,36 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
#pragma region ITextProvider
|
#pragma region ITextProvider
|
||||||
com_array<XamlAutomation::ITextRangeProvider> TermControlAutomationPeer::GetSelection()
|
com_array<XamlAutomation::ITextRangeProvider> TermControlAutomationPeer::GetSelection()
|
||||||
{
|
{
|
||||||
SAFEARRAY* pReturnVal;
|
return _contentAutomationPeer.GetSelection();
|
||||||
THROW_IF_FAILED(_uiaProvider->GetSelection(&pReturnVal));
|
|
||||||
return WrapArrayOfTextRangeProviders(pReturnVal);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
com_array<XamlAutomation::ITextRangeProvider> TermControlAutomationPeer::GetVisibleRanges()
|
com_array<XamlAutomation::ITextRangeProvider> TermControlAutomationPeer::GetVisibleRanges()
|
||||||
{
|
{
|
||||||
SAFEARRAY* pReturnVal;
|
return _contentAutomationPeer.GetVisibleRanges();
|
||||||
THROW_IF_FAILED(_uiaProvider->GetVisibleRanges(&pReturnVal));
|
|
||||||
return WrapArrayOfTextRangeProviders(pReturnVal);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
XamlAutomation::ITextRangeProvider TermControlAutomationPeer::RangeFromChild(XamlAutomation::IRawElementProviderSimple childElement)
|
XamlAutomation::ITextRangeProvider TermControlAutomationPeer::RangeFromChild(XamlAutomation::IRawElementProviderSimple childElement)
|
||||||
{
|
{
|
||||||
UIA::ITextRangeProvider* returnVal;
|
return _contentAutomationPeer.RangeFromChild(childElement);
|
||||||
// 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<XamlUiaTextRange>(returnVal, parentProvider);
|
|
||||||
return xutr.as<XamlAutomation::ITextRangeProvider>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
XamlAutomation::ITextRangeProvider TermControlAutomationPeer::RangeFromPoint(Windows::Foundation::Point screenLocation)
|
XamlAutomation::ITextRangeProvider TermControlAutomationPeer::RangeFromPoint(Windows::Foundation::Point screenLocation)
|
||||||
{
|
{
|
||||||
UIA::ITextRangeProvider* returnVal;
|
return _contentAutomationPeer.RangeFromPoint(screenLocation);
|
||||||
THROW_IF_FAILED(_uiaProvider->RangeFromPoint({ screenLocation.X, screenLocation.Y }, &returnVal));
|
|
||||||
|
|
||||||
auto parentProvider = this->ProviderFromPeer(*this);
|
|
||||||
auto xutr = winrt::make_self<XamlUiaTextRange>(returnVal, parentProvider);
|
|
||||||
return xutr.as<XamlAutomation::ITextRangeProvider>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
XamlAutomation::ITextRangeProvider TermControlAutomationPeer::DocumentRange()
|
XamlAutomation::ITextRangeProvider TermControlAutomationPeer::DocumentRange()
|
||||||
{
|
{
|
||||||
UIA::ITextRangeProvider* returnVal;
|
return _contentAutomationPeer.DocumentRange();
|
||||||
THROW_IF_FAILED(_uiaProvider->get_DocumentRange(&returnVal));
|
|
||||||
|
|
||||||
auto parentProvider = this->ProviderFromPeer(*this);
|
|
||||||
auto xutr = winrt::make_self<XamlUiaTextRange>(returnVal, parentProvider);
|
|
||||||
return xutr.as<XamlAutomation::ITextRangeProvider>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
XamlAutomation::SupportedTextSelection TermControlAutomationPeer::SupportedTextSelection()
|
XamlAutomation::SupportedTextSelection TermControlAutomationPeer::SupportedTextSelection()
|
||||||
{
|
{
|
||||||
UIA::SupportedTextSelection returnVal;
|
return _contentAutomationPeer.SupportedTextSelection();
|
||||||
THROW_IF_FAILED(_uiaProvider->get_SupportedTextSelection(&returnVal));
|
|
||||||
return static_cast<XamlAutomation::SupportedTextSelection>(returnVal);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
#pragma region IControlAccessibilityInfo
|
|
||||||
COORD TermControlAutomationPeer::GetFontSize() const
|
|
||||||
{
|
|
||||||
return _termControl->GetFontSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
RECT TermControlAutomationPeer::GetBounds() const
|
|
||||||
{
|
|
||||||
auto rect = GetBoundingRectangle();
|
|
||||||
return {
|
|
||||||
gsl::narrow_cast<LONG>(rect.X),
|
|
||||||
gsl::narrow_cast<LONG>(rect.Y),
|
|
||||||
gsl::narrow_cast<LONG>(rect.X + rect.Width),
|
|
||||||
gsl::narrow_cast<LONG>(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<LONG>(padding.Left),
|
|
||||||
gsl::narrow_cast<LONG>(padding.Top),
|
|
||||||
gsl::narrow_cast<LONG>(padding.Right),
|
|
||||||
gsl::narrow_cast<LONG>(padding.Bottom)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
double TermControlAutomationPeer::GetScaleFactor() const
|
|
||||||
{
|
|
||||||
return DisplayInformation::GetForCurrentView().RawPixelsPerViewPixel();
|
|
||||||
}
|
|
||||||
|
|
||||||
void TermControlAutomationPeer::ChangeViewport(const SMALL_RECT NewWindow)
|
|
||||||
{
|
|
||||||
_termControl->ScrollViewport(NewWindow.Top);
|
|
||||||
}
|
|
||||||
#pragma endregion
|
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
// - extracts the UiaTextRanges from the SAFEARRAY and converts them to Xaml ITextRangeProviders
|
// - extracts the UiaTextRanges from the SAFEARRAY and converts them to Xaml ITextRangeProviders
|
||||||
// Arguments:
|
// Arguments:
|
||||||
|
|
|
@ -20,13 +20,17 @@ Abstract:
|
||||||
|
|
||||||
Author(s):
|
Author(s):
|
||||||
- Carlos Zamora (CaZamor) 2019
|
- Carlos Zamora (CaZamor) 2019
|
||||||
|
|
||||||
|
Modifications:
|
||||||
|
- May 2021: Pulled the core logic of ITextProvider implementation into the
|
||||||
|
InteractivityAutomationPeer, to support tab tear out.
|
||||||
--*/
|
--*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "TermControl.h"
|
#include "TermControl.h"
|
||||||
|
#include "ControlInteractivity.h"
|
||||||
#include "TermControlAutomationPeer.g.h"
|
#include "TermControlAutomationPeer.g.h"
|
||||||
#include <winrt/Microsoft.Terminal.Control.h>
|
|
||||||
#include "../types/TermControlUiaProvider.hpp"
|
#include "../types/TermControlUiaProvider.hpp"
|
||||||
#include "../types/IUiaEventDispatcher.h"
|
#include "../types/IUiaEventDispatcher.h"
|
||||||
#include "../types/IControlAccessibilityInfo.h"
|
#include "../types/IControlAccessibilityInfo.h"
|
||||||
|
@ -35,11 +39,14 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
{
|
{
|
||||||
struct TermControlAutomationPeer :
|
struct TermControlAutomationPeer :
|
||||||
public TermControlAutomationPeerT<TermControlAutomationPeer>,
|
public TermControlAutomationPeerT<TermControlAutomationPeer>,
|
||||||
::Microsoft::Console::Types::IUiaEventDispatcher,
|
::Microsoft::Console::Types::IUiaEventDispatcher
|
||||||
::Microsoft::Console::Types::IControlAccessibilityInfo
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TermControlAutomationPeer(Microsoft::Terminal::Control::implementation::TermControl* owner);
|
TermControlAutomationPeer(Microsoft::Terminal::Control::implementation::TermControl* owner,
|
||||||
|
Control::InteractivityAutomationPeer implementation);
|
||||||
|
|
||||||
|
void UpdateControlBounds();
|
||||||
|
void SetControlPadding(const Core::Padding padding);
|
||||||
|
|
||||||
#pragma region FrameworkElementAutomationPeer
|
#pragma region FrameworkElementAutomationPeer
|
||||||
hstring GetClassNameCore() const;
|
hstring GetClassNameCore() const;
|
||||||
|
@ -67,21 +74,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||||
Windows::UI::Xaml::Automation::Provider::ITextRangeProvider DocumentRange();
|
Windows::UI::Xaml::Automation::Provider::ITextRangeProvider DocumentRange();
|
||||||
#pragma endregion
|
#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:
|
private:
|
||||||
::Microsoft::WRL::ComPtr<::Microsoft::Terminal::TermControlUiaProvider> _uiaProvider;
|
|
||||||
winrt::Microsoft::Terminal::Control::implementation::TermControl* _termControl;
|
winrt::Microsoft::Terminal::Control::implementation::TermControl* _termControl;
|
||||||
|
Control::InteractivityAutomationPeer _contentAutomationPeer;
|
||||||
|
|
||||||
winrt::com_array<Windows::UI::Xaml::Automation::Provider::ITextRangeProvider> WrapArrayOfTextRangeProviders(SAFEARRAY* textRanges);
|
winrt::com_array<Windows::UI::Xaml::Automation::Provider::ITextRangeProvider> WrapArrayOfTextRangeProviders(SAFEARRAY* textRanges);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,5 +9,8 @@ namespace Microsoft.Terminal.Control
|
||||||
Windows.UI.Xaml.Automation.Peers.FrameworkElementAutomationPeer,
|
Windows.UI.Xaml.Automation.Peers.FrameworkElementAutomationPeer,
|
||||||
Windows.UI.Xaml.Automation.Provider.ITextProvider
|
Windows.UI.Xaml.Automation.Provider.ITextProvider
|
||||||
{
|
{
|
||||||
|
|
||||||
|
void UpdateControlBounds();
|
||||||
|
void SetControlPadding(Microsoft.Terminal.Core.Padding padding);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,6 +52,9 @@
|
||||||
<ClInclude Include="TermControlAutomationPeer.h">
|
<ClInclude Include="TermControlAutomationPeer.h">
|
||||||
<DependentUpon>TermControlAutomationPeer.idl</DependentUpon>
|
<DependentUpon>TermControlAutomationPeer.idl</DependentUpon>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="InteractivityAutomationPeer.h">
|
||||||
|
<DependentUpon>InteractivityAutomationPeer.idl</DependentUpon>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="TSFInputControl.h">
|
<ClInclude Include="TSFInputControl.h">
|
||||||
<DependentUpon>TSFInputControl.xaml</DependentUpon>
|
<DependentUpon>TSFInputControl.xaml</DependentUpon>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
@ -91,6 +94,9 @@
|
||||||
<ClCompile Include="TermControlAutomationPeer.cpp">
|
<ClCompile Include="TermControlAutomationPeer.cpp">
|
||||||
<DependentUpon>TermControlAutomationPeer.idl</DependentUpon>
|
<DependentUpon>TermControlAutomationPeer.idl</DependentUpon>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="InteractivityAutomationPeer.cpp">
|
||||||
|
<DependentUpon>InteractivityAutomationPeer.idl</DependentUpon>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="XamlUiaTextRange.cpp" />
|
<ClCompile Include="XamlUiaTextRange.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<!-- ========================= idl Files ======================== -->
|
<!-- ========================= idl Files ======================== -->
|
||||||
|
@ -112,6 +118,7 @@
|
||||||
<DependentUpon>TermControl.xaml</DependentUpon>
|
<DependentUpon>TermControl.xaml</DependentUpon>
|
||||||
</Midl>
|
</Midl>
|
||||||
<Midl Include="TermControlAutomationPeer.idl" />
|
<Midl Include="TermControlAutomationPeer.idl" />
|
||||||
|
<Midl Include="InteractivityAutomationPeer.idl" />
|
||||||
<Midl Include="IMouseWheelListener.idl" />
|
<Midl Include="IMouseWheelListener.idl" />
|
||||||
<Midl Include="TSFInputControl.idl">
|
<Midl Include="TSFInputControl.idl">
|
||||||
<DependentUpon>TSFInputControl.xaml</DependentUpon>
|
<DependentUpon>TSFInputControl.xaml</DependentUpon>
|
||||||
|
|
|
@ -57,6 +57,8 @@
|
||||||
TRACELOGGING_DECLARE_PROVIDER(g_hTerminalControlProvider);
|
TRACELOGGING_DECLARE_PROVIDER(g_hTerminalControlProvider);
|
||||||
#include <telemetry/ProjectTelemetry.h>
|
#include <telemetry/ProjectTelemetry.h>
|
||||||
|
|
||||||
|
#include <WinUser.h>
|
||||||
|
|
||||||
#include "til.h"
|
#include "til.h"
|
||||||
|
|
||||||
#include "ThrottledFunc.h"
|
#include "ThrottledFunc.h"
|
||||||
|
|
|
@ -82,6 +82,20 @@ public:
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
constexpr DWORD Value() const noexcept
|
||||||
{
|
{
|
||||||
return _value;
|
return _value;
|
||||||
|
|
|
@ -24,11 +24,38 @@ namespace Microsoft.Terminal.Core
|
||||||
UInt8 A;
|
UInt8 A;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// TerminalCore declares its own Color struct to avoid depending on
|
||||||
|
// 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
|
||||||
|
{
|
||||||
|
Int32 X;
|
||||||
|
Int32 Y;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Same thing here, but with padding. Can't use Windows.UI.Thickness, so
|
||||||
|
// we'll declare our own.
|
||||||
|
struct Padding {
|
||||||
|
Double Left;
|
||||||
|
Double Top;
|
||||||
|
Double Right;
|
||||||
|
Double Bottom;
|
||||||
|
};
|
||||||
|
|
||||||
|
// This is a projection of Microsoft::Terminal::Core::ControlKeyStates,
|
||||||
|
// for conversions in and out of WinRT land.
|
||||||
|
struct ControlKeyStates
|
||||||
|
{
|
||||||
|
UInt32 Value;
|
||||||
|
};
|
||||||
|
|
||||||
declare
|
declare
|
||||||
{
|
{
|
||||||
// Forward declare this parameterized specialization so that it lives
|
// Forward declare this parameterized specialization so that it lives
|
||||||
// in TerminalCore instead of being flung to the winds of all IDL dependents.
|
// in TerminalCore instead of being flung to the winds of all IDL dependents.
|
||||||
interface Windows.Foundation.IReference<Microsoft.Terminal.Core.Color>;
|
interface Windows.Foundation.IReference<Microsoft.Terminal.Core.Color>;
|
||||||
|
interface Windows.Foundation.IReference<Microsoft.Terminal.Core.Point>;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ICoreAppearance
|
interface ICoreAppearance
|
||||||
|
|
|
@ -118,6 +118,7 @@ namespace ControlUnitTests
|
||||||
core->TransparencyChanged(opacityCallback);
|
core->TransparencyChanged(opacityCallback);
|
||||||
|
|
||||||
const auto modifiers = ControlKeyStates(ControlKeyStates::RightCtrlPressed | ControlKeyStates::ShiftPressed);
|
const auto modifiers = ControlKeyStates(ControlKeyStates::RightCtrlPressed | ControlKeyStates::ShiftPressed);
|
||||||
|
const Control::MouseButtonState buttonState{};
|
||||||
|
|
||||||
Log::Comment(L"Scroll in the positive direction, increasing opacity");
|
Log::Comment(L"Scroll in the positive direction, increasing opacity");
|
||||||
// Scroll more than enough times to get to 1.0 from .5.
|
// Scroll more than enough times to get to 1.0 from .5.
|
||||||
|
@ -134,7 +135,7 @@ namespace ControlUnitTests
|
||||||
interactivity->MouseWheel(modifiers,
|
interactivity->MouseWheel(modifiers,
|
||||||
30,
|
30,
|
||||||
til::point{ 0, 0 },
|
til::point{ 0, 0 },
|
||||||
{ false, false, false });
|
buttonState);
|
||||||
}
|
}
|
||||||
|
|
||||||
Log::Comment(L"Scroll in the negative direction, decreasing opacity");
|
Log::Comment(L"Scroll in the negative direction, decreasing opacity");
|
||||||
|
@ -152,7 +153,7 @@ namespace ControlUnitTests
|
||||||
interactivity->MouseWheel(modifiers,
|
interactivity->MouseWheel(modifiers,
|
||||||
30,
|
30,
|
||||||
til::point{ 0, 0 },
|
til::point{ 0, 0 },
|
||||||
{ false, false, false });
|
buttonState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,6 +198,7 @@ namespace ControlUnitTests
|
||||||
VERIFY_ARE_EQUAL(41, core->BufferHeight());
|
VERIFY_ARE_EQUAL(41, core->BufferHeight());
|
||||||
|
|
||||||
Log::Comment(L"Scroll up a line");
|
Log::Comment(L"Scroll up a line");
|
||||||
|
const Control::MouseButtonState buttonState{};
|
||||||
const auto modifiers = ControlKeyStates();
|
const auto modifiers = ControlKeyStates();
|
||||||
expectedBufferHeight = 41;
|
expectedBufferHeight = 41;
|
||||||
expectedTop = 20;
|
expectedTop = 20;
|
||||||
|
@ -204,7 +206,7 @@ namespace ControlUnitTests
|
||||||
interactivity->MouseWheel(modifiers,
|
interactivity->MouseWheel(modifiers,
|
||||||
WHEEL_DELTA,
|
WHEEL_DELTA,
|
||||||
til::point{ 0, 0 },
|
til::point{ 0, 0 },
|
||||||
{ false, false, false });
|
buttonState);
|
||||||
|
|
||||||
Log::Comment(L"Scroll up 19 more times, to the top");
|
Log::Comment(L"Scroll up 19 more times, to the top");
|
||||||
for (int i = 0; i < 20; ++i)
|
for (int i = 0; i < 20; ++i)
|
||||||
|
@ -213,18 +215,18 @@ namespace ControlUnitTests
|
||||||
interactivity->MouseWheel(modifiers,
|
interactivity->MouseWheel(modifiers,
|
||||||
WHEEL_DELTA,
|
WHEEL_DELTA,
|
||||||
til::point{ 0, 0 },
|
til::point{ 0, 0 },
|
||||||
{ false, false, false });
|
buttonState);
|
||||||
}
|
}
|
||||||
Log::Comment(L"Scrolling up more should do nothing");
|
Log::Comment(L"Scrolling up more should do nothing");
|
||||||
expectedTop = 0;
|
expectedTop = 0;
|
||||||
interactivity->MouseWheel(modifiers,
|
interactivity->MouseWheel(modifiers,
|
||||||
WHEEL_DELTA,
|
WHEEL_DELTA,
|
||||||
til::point{ 0, 0 },
|
til::point{ 0, 0 },
|
||||||
{ false, false, false });
|
buttonState);
|
||||||
interactivity->MouseWheel(modifiers,
|
interactivity->MouseWheel(modifiers,
|
||||||
WHEEL_DELTA,
|
WHEEL_DELTA,
|
||||||
til::point{ 0, 0 },
|
til::point{ 0, 0 },
|
||||||
{ false, false, false });
|
buttonState);
|
||||||
|
|
||||||
Log::Comment(L"Scroll down 21 more times, to the bottom");
|
Log::Comment(L"Scroll down 21 more times, to the bottom");
|
||||||
for (int i = 0; i < 21; ++i)
|
for (int i = 0; i < 21; ++i)
|
||||||
|
@ -234,7 +236,7 @@ namespace ControlUnitTests
|
||||||
interactivity->MouseWheel(modifiers,
|
interactivity->MouseWheel(modifiers,
|
||||||
-WHEEL_DELTA,
|
-WHEEL_DELTA,
|
||||||
til::point{ 0, 0 },
|
til::point{ 0, 0 },
|
||||||
{ false, false, false });
|
buttonState);
|
||||||
Log::Comment(NoThrowString().Format(L"internal scrollbar pos:%f", interactivity->_internalScrollbarPosition));
|
Log::Comment(NoThrowString().Format(L"internal scrollbar pos:%f", interactivity->_internalScrollbarPosition));
|
||||||
}
|
}
|
||||||
Log::Comment(L"Scrolling up more should do nothing");
|
Log::Comment(L"Scrolling up more should do nothing");
|
||||||
|
@ -242,11 +244,11 @@ namespace ControlUnitTests
|
||||||
interactivity->MouseWheel(modifiers,
|
interactivity->MouseWheel(modifiers,
|
||||||
-WHEEL_DELTA,
|
-WHEEL_DELTA,
|
||||||
til::point{ 0, 0 },
|
til::point{ 0, 0 },
|
||||||
{ false, false, false });
|
buttonState);
|
||||||
interactivity->MouseWheel(modifiers,
|
interactivity->MouseWheel(modifiers,
|
||||||
-WHEEL_DELTA,
|
-WHEEL_DELTA,
|
||||||
til::point{ 0, 0 },
|
til::point{ 0, 0 },
|
||||||
{ false, false, false });
|
buttonState);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ControlInteractivityTests::CreateSubsequentSelectionWithDragging()
|
void ControlInteractivityTests::CreateSubsequentSelectionWithDragging()
|
||||||
|
@ -260,8 +262,8 @@ namespace ControlUnitTests
|
||||||
|
|
||||||
// For this test, don't use any modifiers
|
// For this test, don't use any modifiers
|
||||||
const auto modifiers = ControlKeyStates();
|
const auto modifiers = ControlKeyStates();
|
||||||
const TerminalInput::MouseButtonState leftMouseDown{ true, false, false };
|
const Control::MouseButtonState leftMouseDown{ Control::MouseButtonState::IsLeftButtonDown };
|
||||||
const TerminalInput::MouseButtonState noMouseDown{ false, false, false };
|
const Control::MouseButtonState noMouseDown{};
|
||||||
|
|
||||||
const til::size fontSize{ 9, 21 };
|
const til::size fontSize{ 9, 21 };
|
||||||
|
|
||||||
|
@ -358,8 +360,8 @@ namespace ControlUnitTests
|
||||||
|
|
||||||
// For this test, don't use any modifiers
|
// For this test, don't use any modifiers
|
||||||
const auto modifiers = ControlKeyStates();
|
const auto modifiers = ControlKeyStates();
|
||||||
const TerminalInput::MouseButtonState leftMouseDown{ true, false, false };
|
const Control::MouseButtonState leftMouseDown{ Control::MouseButtonState::IsLeftButtonDown };
|
||||||
const TerminalInput::MouseButtonState noMouseDown{ false, false, false };
|
const Control::MouseButtonState noMouseDown{};
|
||||||
|
|
||||||
const til::size fontSize{ 9, 21 };
|
const til::size fontSize{ 9, 21 };
|
||||||
|
|
||||||
|
@ -401,7 +403,7 @@ namespace ControlUnitTests
|
||||||
interactivity->MouseWheel(modifiers,
|
interactivity->MouseWheel(modifiers,
|
||||||
WHEEL_DELTA,
|
WHEEL_DELTA,
|
||||||
cursorPosition1,
|
cursorPosition1,
|
||||||
{ true, false, false });
|
leftMouseDown);
|
||||||
|
|
||||||
Log::Comment(L"Verify the location of the selection");
|
Log::Comment(L"Verify the location of the selection");
|
||||||
// The viewport is now on row 20, so the selection will be on:
|
// 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 int delta = WHEEL_DELTA / 5;
|
||||||
const til::point mousePos{ 0, 0 };
|
const til::point mousePos{ 0, 0 };
|
||||||
TerminalInput::MouseButtonState state{ false, false, false };
|
Control::MouseButtonState state{};
|
||||||
|
|
||||||
interactivity->MouseWheel(modifiers, delta, mousePos, state); // 1/5
|
interactivity->MouseWheel(modifiers, delta, mousePos, state); // 1/5
|
||||||
VERIFY_ARE_EQUAL(21, core->ScrollOffset());
|
VERIFY_ARE_EQUAL(21, core->ScrollOffset());
|
||||||
|
@ -508,8 +510,8 @@ namespace ControlUnitTests
|
||||||
|
|
||||||
// For this test, don't use any modifiers
|
// For this test, don't use any modifiers
|
||||||
const auto modifiers = ControlKeyStates();
|
const auto modifiers = ControlKeyStates();
|
||||||
const TerminalInput::MouseButtonState leftMouseDown{ true, false, false };
|
const Control::MouseButtonState leftMouseDown{ Control::MouseButtonState::IsLeftButtonDown };
|
||||||
const TerminalInput::MouseButtonState noMouseDown{ false, false, false };
|
const Control::MouseButtonState noMouseDown{};
|
||||||
|
|
||||||
const til::size fontSize{ 9, 21 };
|
const til::size fontSize{ 9, 21 };
|
||||||
|
|
||||||
|
|
|
@ -96,6 +96,12 @@ public:
|
||||||
winrt::event_token name(Windows::Foundation::TypedEventHandler<sender, args> const& h) { return handler->handlerName(h); } \
|
winrt::event_token name(Windows::Foundation::TypedEventHandler<sender, args> const& h) { return handler->handlerName(h); } \
|
||||||
void name(winrt::event_token const& token) noexcept { handler->handlerName(token); }
|
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<sender, args> 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.
|
// 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
|
// This should only be used for simple types where there's no logic in the
|
||||||
// getter/setter beyond just accessing/updating the value.
|
// getter/setter beyond just accessing/updating the value.
|
||||||
|
|
|
@ -338,6 +338,21 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned"
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
||||||
|
{
|
||||||
|
winrt::Microsoft::Terminal::Core::Point ret;
|
||||||
|
ret.X = x<int>();
|
||||||
|
ret.Y = y<int>();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
std::wstring to_string() const
|
std::wstring to_string() const
|
||||||
{
|
{
|
||||||
return wil::str_printf<std::wstring>(L"(X:%td, Y:%td)", x(), y());
|
return wil::str_printf<std::wstring>(L"(X:%td, Y:%td)", x(), y());
|
||||||
|
|
|
@ -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<typename TilMath, typename TOther>
|
||||||
|
constexpr rectangle(TilMath, const TOther& other, std::enable_if_t<std::is_floating_point_v<decltype(std::declval<TOther>().X)> && std::is_floating_point_v<decltype(std::declval<TOther>().Y)> && std::is_floating_point_v<decltype(std::declval<TOther>().Width)> && std::is_floating_point_v<decltype(std::declval<TOther>().Height)>, int> /*sentinel*/ = 0) :
|
||||||
|
rectangle(til::point{ TilMath::template cast<ptrdiff_t>(other.X), TilMath::template cast<ptrdiff_t>(other.Y) }, til::size{ TilMath::template cast<ptrdiff_t>(other.Width), TilMath::template cast<ptrdiff_t>(other.Height) })
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
// This template will convert to rectangle from anything that has a left, top, right, and bottom field that are floating-point;
|
// 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.
|
// a math type is required.
|
||||||
template<typename TilMath, typename TOther>
|
template<typename TilMath, typename TOther>
|
||||||
|
@ -875,6 +883,22 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned"
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef WINRT_Microsoft_Terminal_Core_H
|
||||||
|
operator winrt::Microsoft::Terminal::Core::Padding() const
|
||||||
|
{
|
||||||
|
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
|
std::wstring to_string() const
|
||||||
{
|
{
|
||||||
return wil::str_printf<std::wstring>(L"(L:%td, T:%td, R:%td, B:%td) [W:%td, H:%td]", left(), top(), right(), bottom(), width(), height());
|
return wil::str_printf<std::wstring>(L"(L:%td, T:%td, R:%td, B:%td) [W:%td, H:%td]", left(), top(), right(), bottom(), width(), height());
|
||||||
|
|
Loading…
Reference in a new issue