Convert TermControl to .xaml (#4729)
This commit removes all of the custom UI initialization code in TermControl and replaces it with a xaml file. Some dead or reundant code was removed as part of this refactoring. It also fixes two (quasi-related) issues: * The search box, on first launch, was offset by the scrollbar even if the scrollbar was invisible. * The scrollbar state wasn't hot-reloadable.
This commit is contained in:
parent
9f53107f00
commit
1de07aa3ab
|
@ -18,6 +18,7 @@
|
||||||
using namespace ::Microsoft::Console::Types;
|
using namespace ::Microsoft::Console::Types;
|
||||||
using namespace ::Microsoft::Terminal::Core;
|
using namespace ::Microsoft::Terminal::Core;
|
||||||
using namespace winrt::Windows::UI::Xaml;
|
using namespace winrt::Windows::UI::Xaml;
|
||||||
|
using namespace winrt::Windows::UI::Xaml::Input;
|
||||||
using namespace winrt::Windows::UI::Xaml::Automation::Peers;
|
using namespace winrt::Windows::UI::Xaml::Automation::Peers;
|
||||||
using namespace winrt::Windows::UI::Core;
|
using namespace winrt::Windows::UI::Core;
|
||||||
using namespace winrt::Windows::System;
|
using namespace winrt::Windows::System;
|
||||||
|
@ -53,8 +54,6 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||||
TermControl::TermControl(Settings::IControlSettings settings, TerminalConnection::ITerminalConnection connection) :
|
TermControl::TermControl(Settings::IControlSettings settings, TerminalConnection::ITerminalConnection connection) :
|
||||||
_connection{ connection },
|
_connection{ connection },
|
||||||
_initializedTerminal{ false },
|
_initializedTerminal{ false },
|
||||||
_root{ nullptr },
|
|
||||||
_swapChainPanel{ nullptr },
|
|
||||||
_settings{ settings },
|
_settings{ settings },
|
||||||
_closing{ false },
|
_closing{ false },
|
||||||
_isTerminalInitiatedScroll{ false },
|
_isTerminalInitiatedScroll{ false },
|
||||||
|
@ -69,56 +68,15 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||||
_lastMouseClick{},
|
_lastMouseClick{},
|
||||||
_lastMouseClickPos{},
|
_lastMouseClickPos{},
|
||||||
_searchBox{ nullptr },
|
_searchBox{ nullptr },
|
||||||
_tsfInputControl{ nullptr },
|
|
||||||
_unfocusedClickPos{ std::nullopt },
|
_unfocusedClickPos{ std::nullopt },
|
||||||
_isClickDragSelection{ false }
|
_isClickDragSelection{ false }
|
||||||
{
|
{
|
||||||
_EnsureStaticInitialization();
|
_EnsureStaticInitialization();
|
||||||
_Create();
|
InitializeComponent();
|
||||||
}
|
|
||||||
|
|
||||||
void TermControl::_Create()
|
|
||||||
{
|
|
||||||
Controls::Grid container;
|
|
||||||
|
|
||||||
Controls::ColumnDefinition contentColumn{};
|
|
||||||
Controls::ColumnDefinition scrollbarColumn{};
|
|
||||||
contentColumn.Width(GridLength{ 1.0, GridUnitType::Star });
|
|
||||||
scrollbarColumn.Width(GridLength{ 1.0, GridUnitType::Auto });
|
|
||||||
|
|
||||||
container.ColumnDefinitions().Append(contentColumn);
|
|
||||||
container.ColumnDefinitions().Append(scrollbarColumn);
|
|
||||||
|
|
||||||
_scrollBar = Controls::Primitives::ScrollBar{};
|
|
||||||
_scrollBar.Orientation(Controls::Orientation::Vertical);
|
|
||||||
_scrollBar.IndicatorMode(Controls::Primitives::ScrollingIndicatorMode::MouseIndicator);
|
|
||||||
_scrollBar.HorizontalAlignment(HorizontalAlignment::Right);
|
|
||||||
_scrollBar.VerticalAlignment(VerticalAlignment::Stretch);
|
|
||||||
|
|
||||||
// Initialize the scrollbar with some placeholder values.
|
|
||||||
// The scrollbar will be updated with real values on _Initialize
|
|
||||||
_scrollBar.Maximum(1);
|
|
||||||
_scrollBar.ViewportSize(10);
|
|
||||||
_scrollBar.IsTabStop(false);
|
|
||||||
_scrollBar.SmallChange(1);
|
|
||||||
_scrollBar.LargeChange(4);
|
|
||||||
_scrollBar.Visibility(Visibility::Visible);
|
|
||||||
|
|
||||||
_tsfInputControl = TSFInputControl();
|
|
||||||
_tsfInputControl.CompositionCompleted({ this, &TermControl::_CompositionCompleted });
|
|
||||||
_tsfInputControl.CurrentCursorPosition({ this, &TermControl::_CurrentCursorPositionHandler });
|
|
||||||
_tsfInputControl.CurrentFontInfo({ this, &TermControl::_FontInfoHandler });
|
|
||||||
container.Children().Append(_tsfInputControl);
|
|
||||||
|
|
||||||
// Create the SwapChainPanel that will display our content
|
|
||||||
Controls::SwapChainPanel swapChainPanel;
|
|
||||||
|
|
||||||
_sizeChangedRevoker = swapChainPanel.SizeChanged(winrt::auto_revoke, { this, &TermControl::_SwapChainSizeChanged });
|
|
||||||
_compositionScaleChangedRevoker = swapChainPanel.CompositionScaleChanged(winrt::auto_revoke, { this, &TermControl::_SwapChainScaleChanged });
|
|
||||||
|
|
||||||
// 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
|
||||||
_layoutUpdatedRevoker = swapChainPanel.LayoutUpdated(winrt::auto_revoke, [this](auto /*s*/, auto /*e*/) {
|
_layoutUpdatedRevoker = SwapChainPanel().LayoutUpdated(winrt::auto_revoke, [this](auto /*s*/, auto /*e*/) {
|
||||||
// This event fires every time the layout changes, but it is always the last one to fire
|
// This event fires every time the layout changes, but it is always the last one to fire
|
||||||
// in any layout change chain. That gives us great flexibility in finding the right point
|
// in any layout change chain. That gives us great flexibility in finding the right point
|
||||||
// at which to initialize our renderer (and our terminal).
|
// at which to initialize our renderer (and our terminal).
|
||||||
|
@ -131,74 +89,29 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
container.Children().Append(swapChainPanel);
|
|
||||||
container.Children().Append(_scrollBar);
|
|
||||||
Controls::Grid::SetColumn(swapChainPanel, 0);
|
|
||||||
Controls::Grid::SetColumn(_scrollBar, 1);
|
|
||||||
|
|
||||||
Controls::Grid root{};
|
|
||||||
Controls::Image bgImageLayer{};
|
|
||||||
root.Children().Append(bgImageLayer);
|
|
||||||
root.Children().Append(container);
|
|
||||||
|
|
||||||
_root = root;
|
|
||||||
_bgImageLayer = bgImageLayer;
|
|
||||||
|
|
||||||
_swapChainPanel = swapChainPanel;
|
|
||||||
this->Content(_root);
|
|
||||||
|
|
||||||
_ApplyUISettings();
|
|
||||||
|
|
||||||
// These are important:
|
|
||||||
// 1. When we get tapped, focus us
|
|
||||||
_tappedRevoker = this->Tapped(winrt::auto_revoke, [this](auto&, auto& e) {
|
|
||||||
Focus(FocusState::Pointer);
|
|
||||||
e.Handled(true);
|
|
||||||
});
|
|
||||||
// 2. Make sure we can be focused (why this isn't `Focusable` I'll never know)
|
|
||||||
this->IsTabStop(true);
|
|
||||||
// 3. Actually not sure about this one. Maybe it isn't necessary either.
|
|
||||||
this->AllowFocusOnInteraction(true);
|
|
||||||
|
|
||||||
// DON'T CALL _InitializeTerminal here - wait until the swap chain is loaded to do that.
|
|
||||||
|
|
||||||
// Subscribe to the connection's disconnected event and call our connection closed handlers.
|
// Subscribe to the connection's disconnected event and call our connection closed handlers.
|
||||||
_connectionStateChangedRevoker = _connection.StateChanged(winrt::auto_revoke, [this](auto&& /*s*/, auto&& /*v*/) {
|
_connectionStateChangedRevoker = _connection.StateChanged(winrt::auto_revoke, [this](auto&& /*s*/, auto&& /*v*/) {
|
||||||
_ConnectionStateChangedHandlers(*this, nullptr);
|
_ConnectionStateChangedHandlers(*this, nullptr);
|
||||||
});
|
});
|
||||||
|
|
||||||
_root.AllowDrop(true);
|
_ApplyUISettings();
|
||||||
_root.Drop({ get_weak(), &TermControl::_DragDropHandler });
|
|
||||||
_root.DragOver({ get_weak(), &TermControl::_DragOverHandler });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
// - Create the SearchBoxControl object, and attach it
|
// - Loads the search box from the xaml UI and focuses it.
|
||||||
// to the Terminal Control root
|
|
||||||
// Arguments:
|
|
||||||
// - <none>
|
|
||||||
// Return Value:
|
|
||||||
// - <none>
|
|
||||||
void TermControl::CreateSearchBoxControl()
|
void TermControl::CreateSearchBoxControl()
|
||||||
{
|
{
|
||||||
if (!_searchBox)
|
// Lazy load the search box control.
|
||||||
|
if (auto loadedSearchBox{ FindName(L"SearchBox") })
|
||||||
{
|
{
|
||||||
_searchBox = winrt::make_self<SearchBoxControl>();
|
if (auto searchBox{ loadedSearchBox.try_as<::winrt::Microsoft::Terminal::TerminalControl::SearchBoxControl>() })
|
||||||
_searchBox->HorizontalAlignment(HorizontalAlignment::Right);
|
{
|
||||||
_searchBox->VerticalAlignment(VerticalAlignment::Top);
|
// get at its private implementation
|
||||||
// We need to make sure the searchbox does not overlap
|
_searchBox.copy_from(winrt::get_self<implementation::SearchBoxControl>(searchBox));
|
||||||
// with the scroll bar
|
_searchBox->Visibility(Visibility::Visible);
|
||||||
Thickness searchBoxPadding = { 0, 0, _scrollBar.ActualWidth(), 0 };
|
_searchBox->SetFocusOnTextbox();
|
||||||
_searchBox->Margin(searchBoxPadding);
|
}
|
||||||
|
|
||||||
_root.Children().Append(*_searchBox);
|
|
||||||
|
|
||||||
// Event handlers
|
|
||||||
_searchBox->Search({ get_weak(), &TermControl::_Search });
|
|
||||||
_searchBox->Closed({ get_weak(), &TermControl::_CloseSearchBoxControl });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_searchBox->SetFocusOnTextbox();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
|
@ -238,8 +151,6 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||||
// Method Description:
|
// Method Description:
|
||||||
// - The handler for the close button or pressing "Esc" when focusing on the
|
// - The handler for the close button or pressing "Esc" when focusing on the
|
||||||
// search dialog.
|
// search dialog.
|
||||||
// This removes the SearchBoxControl object from the XAML tree,
|
|
||||||
// reset smart pointer and set focus back to Terminal
|
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// - IInspectable: not used
|
// - IInspectable: not used
|
||||||
// - RoutedEventArgs: not used
|
// - RoutedEventArgs: not used
|
||||||
|
@ -247,11 +158,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||||
// - <none>
|
// - <none>
|
||||||
void TermControl::_CloseSearchBoxControl(const winrt::Windows::Foundation::IInspectable& /*sender*/, RoutedEventArgs const& /*args*/)
|
void TermControl::_CloseSearchBoxControl(const winrt::Windows::Foundation::IInspectable& /*sender*/, RoutedEventArgs const& /*args*/)
|
||||||
{
|
{
|
||||||
unsigned int idx;
|
_searchBox->Visibility(Visibility::Collapsed);
|
||||||
_root.Children().IndexOf(*_searchBox, idx);
|
|
||||||
_root.Children().RemoveAt(idx);
|
|
||||||
|
|
||||||
_searchBox = nullptr;
|
|
||||||
|
|
||||||
// Set focus back to terminal control
|
// Set focus back to terminal control
|
||||||
this->Focus(FocusState::Programmatic);
|
this->Focus(FocusState::Programmatic);
|
||||||
|
@ -270,7 +177,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||||
|
|
||||||
// Dispatch a call to the UI thread to apply the new settings to the
|
// Dispatch a call to the UI thread to apply the new settings to the
|
||||||
// terminal.
|
// terminal.
|
||||||
co_await winrt::resume_foreground(_root.Dispatcher());
|
co_await winrt::resume_foreground(Dispatcher());
|
||||||
|
|
||||||
// If 'weakThis' is locked, then we can safely work with 'this'
|
// If 'weakThis' is locked, then we can safely work with 'this'
|
||||||
if (auto control{ weakThis.get() })
|
if (auto control{ weakThis.get() })
|
||||||
|
@ -287,8 +194,8 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||||
// Refresh our font with the renderer
|
// Refresh our font with the renderer
|
||||||
_UpdateFont();
|
_UpdateFont();
|
||||||
|
|
||||||
const auto width = _swapChainPanel.ActualWidth();
|
const auto width = SwapChainPanel().ActualWidth();
|
||||||
const auto height = _swapChainPanel.ActualHeight();
|
const auto height = SwapChainPanel().ActualHeight();
|
||||||
if (width != 0 && height != 0)
|
if (width != 0 && height != 0)
|
||||||
{
|
{
|
||||||
// If the font size changed, or the _swapchainPanel's size changed
|
// If the font size changed, or the _swapchainPanel's size changed
|
||||||
|
@ -297,11 +204,6 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||||
auto lock = _terminal->LockForWriting();
|
auto lock = _terminal->LockForWriting();
|
||||||
_DoResize(width, height);
|
_DoResize(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
// set TSF Foreground
|
|
||||||
Media::SolidColorBrush foregroundBrush{};
|
|
||||||
foregroundBrush.Color(ColorRefToColor(_settings.DefaultForeground()));
|
|
||||||
_tsfInputControl.Foreground(foregroundBrush);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,8 +228,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||||
|
|
||||||
// Apply padding as swapChainPanel's margin
|
// Apply padding as swapChainPanel's margin
|
||||||
auto newMargin = _ParseThicknessFromPadding(_settings.Padding());
|
auto newMargin = _ParseThicknessFromPadding(_settings.Padding());
|
||||||
auto existingMargin = _swapChainPanel.Margin();
|
SwapChainPanel().Margin(newMargin);
|
||||||
_swapChainPanel.Margin(newMargin);
|
|
||||||
|
|
||||||
// Initialize our font information.
|
// Initialize our font information.
|
||||||
const auto fontFace = _settings.FontFace();
|
const auto fontFace = _settings.FontFace();
|
||||||
|
@ -344,8 +245,24 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||||
// set TSF Foreground
|
// set TSF Foreground
|
||||||
Media::SolidColorBrush foregroundBrush{};
|
Media::SolidColorBrush foregroundBrush{};
|
||||||
foregroundBrush.Color(ColorRefToColor(_settings.DefaultForeground()));
|
foregroundBrush.Color(ColorRefToColor(_settings.DefaultForeground()));
|
||||||
_tsfInputControl.Foreground(foregroundBrush);
|
TSFInputControl().Foreground(foregroundBrush);
|
||||||
_tsfInputControl.Margin(newMargin);
|
TSFInputControl().Margin(newMargin);
|
||||||
|
|
||||||
|
// Apply settings for scrollbar
|
||||||
|
if (_settings.ScrollState() == ScrollbarState::Hidden)
|
||||||
|
{
|
||||||
|
// In the scenario where the user has turned off the OS setting to automatically hide scollbars, the
|
||||||
|
// Terminal scrollbar would still be visible; so, we need to set the control's visibility accordingly to
|
||||||
|
// achieve the intended effect.
|
||||||
|
ScrollBar().IndicatorMode(Controls::Primitives::ScrollingIndicatorMode::None);
|
||||||
|
ScrollBar().Visibility(Visibility::Collapsed);
|
||||||
|
}
|
||||||
|
else // (default or Visible)
|
||||||
|
{
|
||||||
|
// Default behavior
|
||||||
|
ScrollBar().IndicatorMode(Controls::Primitives::ScrollingIndicatorMode::MouseIndicator);
|
||||||
|
ScrollBar().Visibility(Visibility::Visible);
|
||||||
|
}
|
||||||
|
|
||||||
// set number of rows to scroll at a time
|
// set number of rows to scroll at a time
|
||||||
_rowsToScroll = _settings.RowsToScroll();
|
_rowsToScroll = _settings.RowsToScroll();
|
||||||
|
@ -371,7 +288,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||||
{
|
{
|
||||||
// See if we've already got an acrylic background brush
|
// See if we've already got an acrylic background brush
|
||||||
// to avoid the flicker when setting up a new one
|
// to avoid the flicker when setting up a new one
|
||||||
auto acrylic = _root.Background().try_as<Media::AcrylicBrush>();
|
auto acrylic = RootGrid().Background().try_as<Media::AcrylicBrush>();
|
||||||
|
|
||||||
// Instantiate a brush if there's not already one there
|
// Instantiate a brush if there's not already one there
|
||||||
if (acrylic == nullptr)
|
if (acrylic == nullptr)
|
||||||
|
@ -396,15 +313,15 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||||
acrylic.TintOpacity(_settings.TintOpacity());
|
acrylic.TintOpacity(_settings.TintOpacity());
|
||||||
|
|
||||||
// Apply brush to control if it's not already there
|
// Apply brush to control if it's not already there
|
||||||
if (_root.Background() != acrylic)
|
if (RootGrid().Background() != acrylic)
|
||||||
{
|
{
|
||||||
_root.Background(acrylic);
|
RootGrid().Background(acrylic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Media::SolidColorBrush solidColor{};
|
Media::SolidColorBrush solidColor{};
|
||||||
_root.Background(solidColor);
|
RootGrid().Background(solidColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_settings.BackgroundImage().empty())
|
if (!_settings.BackgroundImage().empty())
|
||||||
|
@ -414,7 +331,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||||
// Check if the image brush is already pointing to the image
|
// Check if the image brush is already pointing to the image
|
||||||
// in the modified settings; if it isn't (or isn't there),
|
// in the modified settings; if it isn't (or isn't there),
|
||||||
// set a new image source for the brush
|
// set a new image source for the brush
|
||||||
auto imageSource = _bgImageLayer.Source().try_as<Media::Imaging::BitmapImage>();
|
auto imageSource = BackgroundImage().Source().try_as<Media::Imaging::BitmapImage>();
|
||||||
|
|
||||||
if (imageSource == nullptr ||
|
if (imageSource == nullptr ||
|
||||||
imageSource.UriSource() == nullptr ||
|
imageSource.UriSource() == nullptr ||
|
||||||
|
@ -425,18 +342,18 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||||
// may well be both large and somewhere out on the
|
// may well be both large and somewhere out on the
|
||||||
// internet.
|
// internet.
|
||||||
Media::Imaging::BitmapImage image(imageUri);
|
Media::Imaging::BitmapImage image(imageUri);
|
||||||
_bgImageLayer.Source(image);
|
BackgroundImage().Source(image);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply stretch, opacity and alignment settings
|
// Apply stretch, opacity and alignment settings
|
||||||
_bgImageLayer.Stretch(_settings.BackgroundImageStretchMode());
|
BackgroundImage().Stretch(_settings.BackgroundImageStretchMode());
|
||||||
_bgImageLayer.Opacity(_settings.BackgroundImageOpacity());
|
BackgroundImage().Opacity(_settings.BackgroundImageOpacity());
|
||||||
_bgImageLayer.HorizontalAlignment(_settings.BackgroundImageHorizontalAlignment());
|
BackgroundImage().HorizontalAlignment(_settings.BackgroundImageHorizontalAlignment());
|
||||||
_bgImageLayer.VerticalAlignment(_settings.BackgroundImageVerticalAlignment());
|
BackgroundImage().VerticalAlignment(_settings.BackgroundImageVerticalAlignment());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_bgImageLayer.Source(nullptr);
|
BackgroundImage().Source(nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -450,7 +367,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||||
{
|
{
|
||||||
auto weakThis{ get_weak() };
|
auto weakThis{ get_weak() };
|
||||||
|
|
||||||
co_await winrt::resume_foreground(_root.Dispatcher());
|
co_await winrt::resume_foreground(Dispatcher());
|
||||||
|
|
||||||
if (auto control{ weakThis.get() })
|
if (auto control{ weakThis.get() })
|
||||||
{
|
{
|
||||||
|
@ -464,12 +381,12 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||||
bgColor.B = B;
|
bgColor.B = B;
|
||||||
bgColor.A = 255;
|
bgColor.A = 255;
|
||||||
|
|
||||||
if (auto acrylic = _root.Background().try_as<Media::AcrylicBrush>())
|
if (auto acrylic = RootGrid().Background().try_as<Media::AcrylicBrush>())
|
||||||
{
|
{
|
||||||
acrylic.FallbackColor(bgColor);
|
acrylic.FallbackColor(bgColor);
|
||||||
acrylic.TintColor(bgColor);
|
acrylic.TintColor(bgColor);
|
||||||
}
|
}
|
||||||
else if (auto solidColor = _root.Background().try_as<Media::SolidColorBrush>())
|
else if (auto solidColor = RootGrid().Background().try_as<Media::SolidColorBrush>())
|
||||||
{
|
{
|
||||||
solidColor.Color(bgColor);
|
solidColor.Color(bgColor);
|
||||||
}
|
}
|
||||||
|
@ -522,9 +439,9 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||||
return _actualFont;
|
return _actualFont;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Windows::UI::Xaml::Thickness TermControl::GetPadding() const
|
const Windows::UI::Xaml::Thickness TermControl::GetPadding()
|
||||||
{
|
{
|
||||||
return _swapChainPanel.Margin();
|
return SwapChainPanel().Margin();
|
||||||
}
|
}
|
||||||
|
|
||||||
TerminalConnection::ConnectionState TermControl::ConnectionState() const
|
TerminalConnection::ConnectionState TermControl::ConnectionState() const
|
||||||
|
@ -542,13 +459,13 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||||
auto chain = _renderEngine->GetSwapChain();
|
auto chain = _renderEngine->GetSwapChain();
|
||||||
auto weakThis{ get_weak() };
|
auto weakThis{ get_weak() };
|
||||||
|
|
||||||
co_await winrt::resume_foreground(_swapChainPanel.Dispatcher());
|
co_await winrt::resume_foreground(Dispatcher());
|
||||||
|
|
||||||
// If 'weakThis' is locked, then we can safely work with 'this'
|
// If 'weakThis' is locked, then we can safely work with 'this'
|
||||||
if (auto control{ weakThis.get() })
|
if (auto control{ weakThis.get() })
|
||||||
{
|
{
|
||||||
auto lock = _terminal->LockForWriting();
|
auto lock = _terminal->LockForWriting();
|
||||||
auto nativePanel = _swapChainPanel.as<ISwapChainPanelNative>();
|
auto nativePanel = SwapChainPanel().as<ISwapChainPanelNative>();
|
||||||
nativePanel->SetSwapChain(chain.Get());
|
nativePanel->SetSwapChain(chain.Get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -558,12 +475,12 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||||
auto chain = _renderEngine->GetSwapChain();
|
auto chain = _renderEngine->GetSwapChain();
|
||||||
auto weakThis{ get_weak() };
|
auto weakThis{ get_weak() };
|
||||||
|
|
||||||
co_await winrt::resume_foreground(_swapChainPanel.Dispatcher());
|
co_await winrt::resume_foreground(Dispatcher());
|
||||||
|
|
||||||
if (auto control{ weakThis.get() })
|
if (auto control{ weakThis.get() })
|
||||||
{
|
{
|
||||||
_terminal->LockConsole();
|
_terminal->LockConsole();
|
||||||
auto nativePanel = _swapChainPanel.as<ISwapChainPanelNative>();
|
auto nativePanel = SwapChainPanel().as<ISwapChainPanelNative>();
|
||||||
nativePanel->SetSwapChain(chain.Get());
|
nativePanel->SetSwapChain(chain.Get());
|
||||||
_terminal->UnlockConsole();
|
_terminal->UnlockConsole();
|
||||||
}
|
}
|
||||||
|
@ -576,8 +493,8 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto windowWidth = _swapChainPanel.ActualWidth(); // Width() and Height() are NaN?
|
const auto windowWidth = SwapChainPanel().ActualWidth(); // Width() and Height() are NaN?
|
||||||
const auto windowHeight = _swapChainPanel.ActualHeight();
|
const auto windowHeight = SwapChainPanel().ActualHeight();
|
||||||
|
|
||||||
if (windowWidth == 0 || windowHeight == 0)
|
if (windowWidth == 0 || windowHeight == 0)
|
||||||
{
|
{
|
||||||
|
@ -672,62 +589,13 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||||
auto bottom = _terminal->GetViewport().BottomExclusive();
|
auto bottom = _terminal->GetViewport().BottomExclusive();
|
||||||
auto bufferHeight = bottom;
|
auto bufferHeight = bottom;
|
||||||
|
|
||||||
const auto originalMaximum = _scrollBar.Maximum();
|
ScrollBar().Maximum(bufferHeight - bufferHeight);
|
||||||
const auto originalMinimum = _scrollBar.Minimum();
|
ScrollBar().Minimum(0);
|
||||||
const auto originalValue = _scrollBar.Value();
|
ScrollBar().Value(0);
|
||||||
const auto originalViewportSize = _scrollBar.ViewportSize();
|
ScrollBar().ViewportSize(bufferHeight);
|
||||||
|
|
||||||
_scrollBar.Maximum(bufferHeight - bufferHeight);
|
|
||||||
_scrollBar.Minimum(0);
|
|
||||||
_scrollBar.Value(0);
|
|
||||||
_scrollBar.ViewportSize(bufferHeight);
|
|
||||||
_scrollBar.ValueChanged({ this, &TermControl::_ScrollbarChangeHandler });
|
|
||||||
_scrollBar.PointerPressed({ this, &TermControl::_CapturePointer });
|
|
||||||
_scrollBar.PointerReleased({ this, &TermControl::_ReleasePointerCapture });
|
|
||||||
|
|
||||||
// Apply settings for scrollbar
|
|
||||||
if (_settings.ScrollState() == ScrollbarState::Visible)
|
|
||||||
{
|
|
||||||
_scrollBar.IndicatorMode(Controls::Primitives::ScrollingIndicatorMode::MouseIndicator);
|
|
||||||
}
|
|
||||||
else if (_settings.ScrollState() == ScrollbarState::Hidden)
|
|
||||||
{
|
|
||||||
_scrollBar.IndicatorMode(Controls::Primitives::ScrollingIndicatorMode::None);
|
|
||||||
|
|
||||||
// In the scenario where the user has turned off the OS setting to automatically hide scollbars, the
|
|
||||||
// Terminal scrollbar would still be visible; so, we need to set the control's visibility accordingly to
|
|
||||||
// achieve the intended effect.
|
|
||||||
_scrollBar.Visibility(Visibility::Collapsed);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Default behavior
|
|
||||||
_scrollBar.IndicatorMode(Controls::Primitives::ScrollingIndicatorMode::MouseIndicator);
|
|
||||||
}
|
|
||||||
|
|
||||||
_root.PointerWheelChanged({ this, &TermControl::_MouseWheelHandler });
|
|
||||||
|
|
||||||
// These need to be hooked up to the SwapChainPanel because we don't want the scrollbar to respond to pointer events (GitHub #950)
|
|
||||||
_swapChainPanel.PointerPressed({ this, &TermControl::_PointerPressedHandler });
|
|
||||||
_swapChainPanel.PointerMoved({ this, &TermControl::_PointerMovedHandler });
|
|
||||||
_swapChainPanel.PointerReleased({ this, &TermControl::_PointerReleasedHandler });
|
|
||||||
|
|
||||||
localPointerToThread->EnablePainting();
|
localPointerToThread->EnablePainting();
|
||||||
|
|
||||||
// No matter what order these guys are in, The KeyDown's will fire
|
|
||||||
// before the CharacterReceived, so we can't easily get characters
|
|
||||||
// first, then fallback to getting keys from vkeys.
|
|
||||||
// TODO: This apparently handles keys and characters correctly, though
|
|
||||||
// I'd keep an eye on it, and test more.
|
|
||||||
// I presume that the characters that aren't translated by terminalInput
|
|
||||||
// just end up getting ignored, and the rest of the input comes
|
|
||||||
// through CharacterReceived.
|
|
||||||
// I don't believe there's a difference between KeyDown and
|
|
||||||
// PreviewKeyDown for our purposes
|
|
||||||
// These two handlers _must_ be on this, not _root.
|
|
||||||
this->PreviewKeyDown({ this, &TermControl::_KeyDownHandler });
|
|
||||||
this->CharacterReceived({ this, &TermControl::_CharacterHandler });
|
|
||||||
|
|
||||||
auto pfnTitleChanged = std::bind(&TermControl::_TerminalTitleChanged, this, std::placeholders::_1);
|
auto pfnTitleChanged = std::bind(&TermControl::_TerminalTitleChanged, this, std::placeholders::_1);
|
||||||
_terminal->SetTitleChangedCallback(pfnTitleChanged);
|
_terminal->SetTitleChangedCallback(pfnTitleChanged);
|
||||||
|
|
||||||
|
@ -760,10 +628,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||||
// import value from WinUser (convert from milli-seconds to micro-seconds)
|
// import value from WinUser (convert from milli-seconds to micro-seconds)
|
||||||
_multiClickTimer = GetDoubleClickTime() * 1000;
|
_multiClickTimer = GetDoubleClickTime() * 1000;
|
||||||
|
|
||||||
_gotFocusRevoker = this->GotFocus(winrt::auto_revoke, { this, &TermControl::_GotFocusHandler });
|
// Focus the control here. If we do it during control initialization, then
|
||||||
_lostFocusRevoker = this->LostFocus(winrt::auto_revoke, { this, &TermControl::_LostFocusHandler });
|
|
||||||
|
|
||||||
// Focus the control here. If we do it up above (in _Create_), then the
|
|
||||||
// focus won't actually get passed to us. I believe this is because
|
// focus won't actually get passed to us. I believe this is because
|
||||||
// we're not technically a part of the UI tree yet, so focusing us
|
// we're not technically a part of the UI tree yet, so focusing us
|
||||||
// becomes a no-op.
|
// becomes a no-op.
|
||||||
|
@ -892,6 +757,17 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||||
return handled;
|
return handled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Method Description:
|
||||||
|
// - handle a tap event by taking focus
|
||||||
|
// Arguments:
|
||||||
|
// - sender: the XAML element responding to the tap event
|
||||||
|
// - args: event data
|
||||||
|
void TermControl::_TappedHandler(const IInspectable& /*sender*/, const TappedRoutedEventArgs& e)
|
||||||
|
{
|
||||||
|
Focus(FocusState::Pointer);
|
||||||
|
e.Handled(true);
|
||||||
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
// - handle a mouse click event. Begin selection process.
|
// - handle a mouse click event. Begin selection process.
|
||||||
// Arguments:
|
// Arguments:
|
||||||
|
@ -903,7 +779,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||||
_CapturePointer(sender, args);
|
_CapturePointer(sender, args);
|
||||||
|
|
||||||
const auto ptr = args.Pointer();
|
const auto ptr = args.Pointer();
|
||||||
const auto point = args.GetCurrentPoint(_root);
|
const auto point = args.GetCurrentPoint(*this);
|
||||||
|
|
||||||
if (!_focused)
|
if (!_focused)
|
||||||
{
|
{
|
||||||
|
@ -1007,7 +883,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||||
Input::PointerRoutedEventArgs const& args)
|
Input::PointerRoutedEventArgs const& args)
|
||||||
{
|
{
|
||||||
const auto ptr = args.Pointer();
|
const auto ptr = args.Pointer();
|
||||||
const auto point = args.GetCurrentPoint(_root);
|
const auto point = args.GetCurrentPoint(*this);
|
||||||
|
|
||||||
if (ptr.PointerDeviceType() == Windows::Devices::Input::PointerDeviceType::Mouse || ptr.PointerDeviceType() == Windows::Devices::Input::PointerDeviceType::Pen)
|
if (ptr.PointerDeviceType() == Windows::Devices::Input::PointerDeviceType::Mouse || ptr.PointerDeviceType() == Windows::Devices::Input::PointerDeviceType::Pen)
|
||||||
{
|
{
|
||||||
|
@ -1027,8 +903,8 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||||
const auto cursorPosition = point.Position();
|
const auto cursorPosition = point.Position();
|
||||||
_SetEndSelectionPointAtCursor(cursorPosition);
|
_SetEndSelectionPointAtCursor(cursorPosition);
|
||||||
|
|
||||||
const double cursorBelowBottomDist = cursorPosition.Y - _swapChainPanel.Margin().Top - _swapChainPanel.ActualHeight();
|
const double cursorBelowBottomDist = cursorPosition.Y - SwapChainPanel().Margin().Top - SwapChainPanel().ActualHeight();
|
||||||
const double cursorAboveTopDist = -1 * cursorPosition.Y + _swapChainPanel.Margin().Top;
|
const double cursorAboveTopDist = -1 * cursorPosition.Y + SwapChainPanel().Margin().Top;
|
||||||
|
|
||||||
constexpr double MinAutoScrollDist = 2.0; // Arbitrary value
|
constexpr double MinAutoScrollDist = 2.0; // Arbitrary value
|
||||||
double newAutoScrollVelocity = 0.0;
|
double newAutoScrollVelocity = 0.0;
|
||||||
|
@ -1071,10 +947,10 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||||
// panning down)
|
// panning down)
|
||||||
const float numRows = -1.0f * (dy / fontHeight);
|
const float numRows = -1.0f * (dy / fontHeight);
|
||||||
|
|
||||||
const auto currentOffset = ::base::ClampedNumeric<double>(_scrollBar.Value());
|
const auto currentOffset = ::base::ClampedNumeric<double>(ScrollBar().Value());
|
||||||
const auto newValue = numRows + currentOffset;
|
const auto newValue = numRows + currentOffset;
|
||||||
|
|
||||||
_scrollBar.Value(newValue);
|
ScrollBar().Value(newValue);
|
||||||
|
|
||||||
// Use this point as our new scroll anchor.
|
// Use this point as our new scroll anchor.
|
||||||
_touchAnchor = newTouchPoint;
|
_touchAnchor = newTouchPoint;
|
||||||
|
@ -1135,7 +1011,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||||
void TermControl::_MouseWheelHandler(Windows::Foundation::IInspectable const& /*sender*/,
|
void TermControl::_MouseWheelHandler(Windows::Foundation::IInspectable const& /*sender*/,
|
||||||
Input::PointerRoutedEventArgs const& args)
|
Input::PointerRoutedEventArgs const& args)
|
||||||
{
|
{
|
||||||
const auto point = args.GetCurrentPoint(_root);
|
const auto point = args.GetCurrentPoint(*this);
|
||||||
const auto delta = point.Properties().MouseWheelDelta();
|
const auto delta = point.Properties().MouseWheelDelta();
|
||||||
|
|
||||||
// Get the state of the Ctrl & Shift keys
|
// Get the state of the Ctrl & Shift keys
|
||||||
|
@ -1173,7 +1049,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
auto acrylicBrush = _root.Background().as<Media::AcrylicBrush>();
|
auto acrylicBrush = RootGrid().Background().as<Media::AcrylicBrush>();
|
||||||
acrylicBrush.TintOpacity(acrylicBrush.TintOpacity() + effectiveDelta);
|
acrylicBrush.TintOpacity(acrylicBrush.TintOpacity() + effectiveDelta);
|
||||||
}
|
}
|
||||||
CATCH_LOG();
|
CATCH_LOG();
|
||||||
|
@ -1216,7 +1092,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||||
// - mouseDelta: the mouse wheel delta that triggered this event.
|
// - mouseDelta: the mouse wheel delta that triggered this event.
|
||||||
void TermControl::_MouseScrollHandler(const double mouseDelta, Windows::UI::Input::PointerPoint const& pointerPoint)
|
void TermControl::_MouseScrollHandler(const double mouseDelta, Windows::UI::Input::PointerPoint const& pointerPoint)
|
||||||
{
|
{
|
||||||
const auto currentOffset = _scrollBar.Value();
|
const auto currentOffset = ScrollBar().Value();
|
||||||
|
|
||||||
// negative = down, positive = up
|
// negative = down, positive = up
|
||||||
// However, for us, the signs are flipped.
|
// However, for us, the signs are flipped.
|
||||||
|
@ -1229,7 +1105,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||||
|
|
||||||
// The scroll bar's ValueChanged handler will actually move the viewport
|
// The scroll bar's ValueChanged handler will actually move the viewport
|
||||||
// for us.
|
// for us.
|
||||||
_scrollBar.Value(newValue);
|
ScrollBar().Value(newValue);
|
||||||
|
|
||||||
if (_terminal->IsSelectionActive() && pointerPoint.Properties().IsLeftButtonPressed())
|
if (_terminal->IsSelectionActive() && pointerPoint.Properties().IsLeftButtonPressed())
|
||||||
{
|
{
|
||||||
|
@ -1360,7 +1236,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||||
{
|
{
|
||||||
static constexpr double microSecPerSec = 1000000.0;
|
static constexpr double microSecPerSec = 1000000.0;
|
||||||
const double deltaTime = std::chrono::duration_cast<std::chrono::microseconds>(timeNow - _lastAutoScrollUpdateTime.value()).count() / microSecPerSec;
|
const double deltaTime = std::chrono::duration_cast<std::chrono::microseconds>(timeNow - _lastAutoScrollUpdateTime.value()).count() / microSecPerSec;
|
||||||
_scrollBar.Value(_scrollBar.Value() + _autoScrollVelocity * deltaTime);
|
ScrollBar().Value(ScrollBar().Value() + _autoScrollVelocity * deltaTime);
|
||||||
|
|
||||||
if (_autoScrollingPointerPoint.has_value())
|
if (_autoScrollingPointerPoint.has_value())
|
||||||
{
|
{
|
||||||
|
@ -1400,9 +1276,9 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||||
THROW_IF_FAILED(_uiaEngine->Enable());
|
THROW_IF_FAILED(_uiaEngine->Enable());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_tsfInputControl != nullptr)
|
if (TSFInputControl() != nullptr)
|
||||||
{
|
{
|
||||||
_tsfInputControl.NotifyFocusEnter();
|
TSFInputControl().NotifyFocusEnter();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_cursorTimer.has_value())
|
if (_cursorTimer.has_value())
|
||||||
|
@ -1432,9 +1308,9 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||||
THROW_IF_FAILED(_uiaEngine->Disable());
|
THROW_IF_FAILED(_uiaEngine->Disable());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_tsfInputControl != nullptr)
|
if (TSFInputControl() != nullptr)
|
||||||
{
|
{
|
||||||
_tsfInputControl.NotifyFocusLeave();
|
TSFInputControl().NotifyFocusLeave();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_cursorTimer.has_value())
|
if (_cursorTimer.has_value())
|
||||||
|
@ -1498,7 +1374,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||||
{
|
{
|
||||||
auto lock = _terminal->LockForWriting();
|
auto lock = _terminal->LockForWriting();
|
||||||
|
|
||||||
const int newDpi = static_cast<int>(static_cast<double>(USER_DEFAULT_SCREEN_DPI) * _swapChainPanel.CompositionScaleX());
|
const int newDpi = static_cast<int>(static_cast<double>(USER_DEFAULT_SCREEN_DPI) * SwapChainPanel().CompositionScaleX());
|
||||||
|
|
||||||
// TODO: MSFT:20895307 If the font doesn't exist, this doesn't
|
// TODO: MSFT:20895307 If the font doesn't exist, this doesn't
|
||||||
// actually fail. We need a way to gracefully fallback.
|
// actually fail. We need a way to gracefully fallback.
|
||||||
|
@ -1529,7 +1405,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||||
// problems (like what happens when you change the font size while the
|
// problems (like what happens when you change the font size while the
|
||||||
// window is maximized?)
|
// window is maximized?)
|
||||||
auto lock = _terminal->LockForWriting();
|
auto lock = _terminal->LockForWriting();
|
||||||
_DoResize(_swapChainPanel.ActualWidth(), _swapChainPanel.ActualHeight());
|
_DoResize(SwapChainPanel().ActualWidth(), SwapChainPanel().ActualHeight());
|
||||||
}
|
}
|
||||||
CATCH_LOG();
|
CATCH_LOG();
|
||||||
}
|
}
|
||||||
|
@ -1706,7 +1582,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||||
|
|
||||||
auto weakThis{ get_weak() };
|
auto weakThis{ get_weak() };
|
||||||
|
|
||||||
co_await winrt::resume_foreground(_scrollBar.Dispatcher());
|
co_await winrt::resume_foreground(Dispatcher());
|
||||||
|
|
||||||
// Even if we weren't closed/closing few lines above, we might be
|
// Even if we weren't closed/closing few lines above, we might be
|
||||||
// while waiting for this block of code to be dispatched.
|
// while waiting for this block of code to be dispatched.
|
||||||
|
@ -1716,7 +1592,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||||
if (!_closing.load())
|
if (!_closing.load())
|
||||||
{
|
{
|
||||||
// Update our scrollbar
|
// Update our scrollbar
|
||||||
_ScrollbarUpdater(_scrollBar, viewTop, viewHeight, bufferSize);
|
_ScrollbarUpdater(ScrollBar(), viewTop, viewHeight, bufferSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1802,7 +1678,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||||
_connection.TerminalOutput(_connectionOutputEventToken);
|
_connection.TerminalOutput(_connectionOutputEventToken);
|
||||||
_connectionStateChangedRevoker.revoke();
|
_connectionStateChangedRevoker.revoke();
|
||||||
|
|
||||||
_tsfInputControl.Close(); // Disconnect the TSF input control so it doesn't receive EditContext events.
|
TSFInputControl().Close(); // Disconnect the TSF input control so it doesn't receive EditContext events.
|
||||||
|
|
||||||
if (auto localConnection{ std::exchange(_connection, nullptr) })
|
if (auto localConnection{ std::exchange(_connection, nullptr) })
|
||||||
{
|
{
|
||||||
|
@ -1834,7 +1710,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||||
// - viewTop: the viewTop to scroll to
|
// - viewTop: the viewTop to scroll to
|
||||||
void TermControl::ScrollViewport(int viewTop)
|
void TermControl::ScrollViewport(int viewTop)
|
||||||
{
|
{
|
||||||
_scrollBar.Value(viewTop);
|
ScrollBar().Value(viewTop);
|
||||||
}
|
}
|
||||||
|
|
||||||
int TermControl::GetScrollOffset()
|
int TermControl::GetScrollOffset()
|
||||||
|
@ -1949,7 +1825,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - The minimum size that this terminal control can be resized to and still
|
// - The minimum size that this terminal control can be resized to and still
|
||||||
// have a visible character.
|
// have a visible character.
|
||||||
winrt::Windows::Foundation::Size TermControl::MinimumSize() const
|
winrt::Windows::Foundation::Size TermControl::MinimumSize()
|
||||||
{
|
{
|
||||||
const auto fontSize = _actualFont.GetSize();
|
const auto fontSize = _actualFont.GetSize();
|
||||||
double width = fontSize.X;
|
double width = fontSize.X;
|
||||||
|
@ -1957,11 +1833,11 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||||
// 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)
|
||||||
{
|
{
|
||||||
width += _scrollBar.ActualWidth();
|
width += ScrollBar().ActualWidth();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Account for the size of any padding
|
// Account for the size of any padding
|
||||||
const auto padding = _swapChainPanel.Margin();
|
const auto padding = SwapChainPanel().Margin();
|
||||||
width += padding.Left + padding.Right;
|
width += padding.Left + padding.Right;
|
||||||
height += padding.Top + padding.Bottom;
|
height += padding.Top + padding.Bottom;
|
||||||
|
|
||||||
|
@ -1976,19 +1852,19 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||||
// - dimension: a dimension (width or height) to be snapped
|
// - dimension: a dimension (width or height) to be snapped
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - 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) const
|
float TermControl::SnapDimensionToGrid(const bool widthOrHeight, const float dimension)
|
||||||
{
|
{
|
||||||
const auto fontSize = _actualFont.GetSize();
|
const auto fontSize = _actualFont.GetSize();
|
||||||
const auto fontDimension = widthOrHeight ? fontSize.X : fontSize.Y;
|
const auto fontDimension = widthOrHeight ? fontSize.X : fontSize.Y;
|
||||||
|
|
||||||
const auto padding = _swapChainPanel.Margin();
|
const auto padding = SwapChainPanel().Margin();
|
||||||
auto nonTerminalArea = gsl::narrow_cast<float>(widthOrHeight ?
|
auto nonTerminalArea = gsl::narrow_cast<float>(widthOrHeight ?
|
||||||
padding.Left + padding.Right :
|
padding.Left + padding.Right :
|
||||||
padding.Top + padding.Bottom);
|
padding.Top + padding.Bottom);
|
||||||
|
|
||||||
if (widthOrHeight && _settings.ScrollState() == ScrollbarState::Visible)
|
if (widthOrHeight && _settings.ScrollState() == ScrollbarState::Visible)
|
||||||
{
|
{
|
||||||
nonTerminalArea += gsl::narrow_cast<float>(_scrollBar.ActualWidth());
|
nonTerminalArea += gsl::narrow_cast<float>(ScrollBar().ActualWidth());
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto gridSize = dimension - nonTerminalArea;
|
const auto gridSize = dimension - nonTerminalArea;
|
||||||
|
@ -2113,8 +1989,8 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||||
{
|
{
|
||||||
// Exclude padding from cursor position calculation
|
// Exclude padding from cursor position calculation
|
||||||
COORD terminalPosition = {
|
COORD terminalPosition = {
|
||||||
static_cast<SHORT>(cursorPosition.X - _swapChainPanel.Margin().Left),
|
static_cast<SHORT>(cursorPosition.X - SwapChainPanel().Margin().Left),
|
||||||
static_cast<SHORT>(cursorPosition.Y - _swapChainPanel.Margin().Top)
|
static_cast<SHORT>(cursorPosition.Y - SwapChainPanel().Margin().Top)
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto fontSize = _actualFont.GetSize();
|
const auto fontSize = _actualFont.GetSize();
|
||||||
|
|
|
@ -66,8 +66,8 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||||
void PasteTextFromClipboard();
|
void PasteTextFromClipboard();
|
||||||
void Close();
|
void Close();
|
||||||
Windows::Foundation::Size CharacterDimensions() const;
|
Windows::Foundation::Size CharacterDimensions() const;
|
||||||
Windows::Foundation::Size MinimumSize() const;
|
Windows::Foundation::Size MinimumSize();
|
||||||
float SnapDimensionToGrid(const bool widthOrHeight, const float dimension) const;
|
float SnapDimensionToGrid(const bool widthOrHeight, const float dimension);
|
||||||
|
|
||||||
void ScrollViewport(int viewTop);
|
void ScrollViewport(int viewTop);
|
||||||
int GetScrollOffset();
|
int GetScrollOffset();
|
||||||
|
@ -85,7 +85,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||||
Windows::UI::Xaml::Automation::Peers::AutomationPeer OnCreateAutomationPeer();
|
Windows::UI::Xaml::Automation::Peers::AutomationPeer OnCreateAutomationPeer();
|
||||||
::Microsoft::Console::Types::IUiaData* GetUiaData() const;
|
::Microsoft::Console::Types::IUiaData* GetUiaData() const;
|
||||||
const FontInfo GetActualFont() const;
|
const FontInfo GetActualFont() const;
|
||||||
const Windows::UI::Xaml::Thickness GetPadding() const;
|
const Windows::UI::Xaml::Thickness GetPadding();
|
||||||
|
|
||||||
TerminalConnection::ConnectionState ConnectionState() const;
|
TerminalConnection::ConnectionState ConnectionState() const;
|
||||||
|
|
||||||
|
@ -105,20 +105,13 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
friend struct TermControlT<TermControl>; // friend our parent so it can bind private event handlers
|
||||||
TerminalConnection::ITerminalConnection _connection;
|
TerminalConnection::ITerminalConnection _connection;
|
||||||
bool _initializedTerminal;
|
bool _initializedTerminal;
|
||||||
|
|
||||||
Windows::UI::Xaml::Controls::Grid _root;
|
|
||||||
Windows::UI::Xaml::Controls::Image _bgImageLayer;
|
|
||||||
Windows::UI::Xaml::Controls::SwapChainPanel _swapChainPanel;
|
|
||||||
Windows::UI::Xaml::Controls::Primitives::ScrollBar _scrollBar;
|
|
||||||
|
|
||||||
winrt::com_ptr<SearchBoxControl> _searchBox;
|
winrt::com_ptr<SearchBoxControl> _searchBox;
|
||||||
|
|
||||||
TSFInputControl _tsfInputControl;
|
|
||||||
|
|
||||||
event_token _connectionOutputEventToken;
|
event_token _connectionOutputEventToken;
|
||||||
TermControl::Tapped_revoker _tappedRevoker;
|
|
||||||
TerminalConnection::ITerminalConnection::StateChanged_revoker _connectionStateChangedRevoker;
|
TerminalConnection::ITerminalConnection::StateChanged_revoker _connectionStateChangedRevoker;
|
||||||
|
|
||||||
std::unique_ptr<::Microsoft::Terminal::Core::Terminal> _terminal;
|
std::unique_ptr<::Microsoft::Terminal::Core::Terminal> _terminal;
|
||||||
|
@ -165,21 +158,15 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||||
std::optional<winrt::Windows::Foundation::Point> _unfocusedClickPos;
|
std::optional<winrt::Windows::Foundation::Point> _unfocusedClickPos;
|
||||||
bool _isClickDragSelection;
|
bool _isClickDragSelection;
|
||||||
|
|
||||||
// Event revokers -- we need to deregister ourselves before we die,
|
|
||||||
// lest we get callbacks afterwards.
|
|
||||||
winrt::Windows::UI::Xaml::Controls::Control::SizeChanged_revoker _sizeChangedRevoker;
|
|
||||||
winrt::Windows::UI::Xaml::Controls::SwapChainPanel::CompositionScaleChanged_revoker _compositionScaleChangedRevoker;
|
|
||||||
winrt::Windows::UI::Xaml::Controls::SwapChainPanel::LayoutUpdated_revoker _layoutUpdatedRevoker;
|
winrt::Windows::UI::Xaml::Controls::SwapChainPanel::LayoutUpdated_revoker _layoutUpdatedRevoker;
|
||||||
winrt::Windows::UI::Xaml::UIElement::LostFocus_revoker _lostFocusRevoker;
|
|
||||||
winrt::Windows::UI::Xaml::UIElement::GotFocus_revoker _gotFocusRevoker;
|
|
||||||
|
|
||||||
void _Create();
|
|
||||||
void _ApplyUISettings();
|
void _ApplyUISettings();
|
||||||
void _InitializeBackgroundBrush();
|
void _InitializeBackgroundBrush();
|
||||||
winrt::fire_and_forget _BackgroundColorChanged(const uint32_t color);
|
winrt::fire_and_forget _BackgroundColorChanged(const uint32_t color);
|
||||||
bool _InitializeTerminal();
|
bool _InitializeTerminal();
|
||||||
void _UpdateFont(const bool initialUpdate = false);
|
void _UpdateFont(const bool initialUpdate = false);
|
||||||
void _SetFontSize(int fontSize);
|
void _SetFontSize(int fontSize);
|
||||||
|
void _TappedHandler(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::Input::TappedRoutedEventArgs const& e);
|
||||||
void _KeyDownHandler(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::Input::KeyRoutedEventArgs const& e);
|
void _KeyDownHandler(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::Input::KeyRoutedEventArgs const& e);
|
||||||
void _CharacterHandler(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::Input::CharacterReceivedRoutedEventArgs const& e);
|
void _CharacterHandler(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::Input::CharacterReceivedRoutedEventArgs const& e);
|
||||||
void _PointerPressedHandler(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs const& e);
|
void _PointerPressedHandler(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs const& e);
|
||||||
|
|
81
src/cascadia/TerminalControl/TermControl.xaml
Normal file
81
src/cascadia/TerminalControl/TermControl.xaml
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
<UserControl
|
||||||
|
x:Class="Microsoft.Terminal.TerminalControl.TermControl"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:local="using:Microsoft.Terminal.TerminalControl"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
VerticalAlignment="Stretch"
|
||||||
|
d:DesignHeight="768"
|
||||||
|
d:DesignWidth="1024"
|
||||||
|
TabNavigation="Cycle"
|
||||||
|
IsTabStop="True"
|
||||||
|
AllowFocusOnInteraction="True"
|
||||||
|
AllowDrop="True"
|
||||||
|
Drop="_DragDropHandler"
|
||||||
|
DragOver="_DragOverHandler"
|
||||||
|
Tapped="_TappedHandler"
|
||||||
|
PointerWheelChanged="_MouseWheelHandler"
|
||||||
|
PreviewKeyDown="_KeyDownHandler"
|
||||||
|
CharacterReceived="_CharacterHandler"
|
||||||
|
GotFocus="_GotFocusHandler"
|
||||||
|
LostFocus="_LostFocusHandler">
|
||||||
|
<!--
|
||||||
|
TODO GH#4031: We've investigated whether we should be using KeyDown or PreviewKeyDown
|
||||||
|
but not necessarily come to a consensus. It's possible that moving input to the SwapChainPanel
|
||||||
|
will solve a bunch of the search input issues we found last time we switched.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<Grid x:Name="RootGrid">
|
||||||
|
<Image x:Name="BackgroundImage" />
|
||||||
|
<Grid>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<Grid Grid.Column="0">
|
||||||
|
<SwapChainPanel x:Name="SwapChainPanel"
|
||||||
|
SizeChanged="_SwapChainSizeChanged"
|
||||||
|
CompositionScaleChanged="_SwapChainScaleChanged"
|
||||||
|
PointerPressed="_PointerPressedHandler"
|
||||||
|
PointerMoved="_PointerMovedHandler"
|
||||||
|
PointerReleased="_PointerReleasedHandler" />
|
||||||
|
|
||||||
|
<!-- Putting this in a grid w/ the SwapChainPanel
|
||||||
|
ensures that it's always aligned w/ the scrollbar -->
|
||||||
|
<local:SearchBoxControl x:Name="SearchBox"
|
||||||
|
x:Load="False"
|
||||||
|
Visibility="Collapsed"
|
||||||
|
HorizontalAlignment="Right"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
Search="_Search"
|
||||||
|
Closed="_CloseSearchBoxControl" />
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<ScrollBar Grid.Column="1"
|
||||||
|
x:Name="ScrollBar"
|
||||||
|
Orientation="Vertical"
|
||||||
|
IndicatorMode="MouseIndicator"
|
||||||
|
HorizontalAlignment="Right"
|
||||||
|
VerticalAlignment="Stretch"
|
||||||
|
Maximum="1"
|
||||||
|
ViewportSize="10"
|
||||||
|
IsTabStop="False"
|
||||||
|
SmallChange="1"
|
||||||
|
LargeChange="4"
|
||||||
|
ValueChanged="_ScrollbarChangeHandler"
|
||||||
|
PointerPressed="_CapturePointer"
|
||||||
|
PointerReleased="_ReleasePointerCapture" />
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<local:TSFInputControl x:Name="TSFInputControl"
|
||||||
|
CompositionCompleted="_CompositionCompleted"
|
||||||
|
CurrentCursorPosition="_CurrentCursorPositionHandler"
|
||||||
|
CurrentFontInfo="_FontInfoHandler" />
|
||||||
|
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
</UserControl>
|
|
@ -37,7 +37,7 @@
|
||||||
<DependentUpon>SearchBoxControl.xaml</DependentUpon>
|
<DependentUpon>SearchBoxControl.xaml</DependentUpon>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="TermControl.h">
|
<ClInclude Include="TermControl.h">
|
||||||
<DependentUpon>TermControl.idl</DependentUpon>
|
<DependentUpon>TermControl.xaml</DependentUpon>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="TermControlAutomationPeer.h">
|
<ClInclude Include="TermControlAutomationPeer.h">
|
||||||
<DependentUpon>TermControlAutomationPeer.idl</DependentUpon>
|
<DependentUpon>TermControlAutomationPeer.idl</DependentUpon>
|
||||||
|
@ -56,7 +56,7 @@
|
||||||
<DependentUpon>SearchBoxControl.xaml</DependentUpon>
|
<DependentUpon>SearchBoxControl.xaml</DependentUpon>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="TermControl.cpp">
|
<ClCompile Include="TermControl.cpp">
|
||||||
<DependentUpon>TermControl.idl</DependentUpon>
|
<DependentUpon>TermControl.xaml</DependentUpon>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="TSFInputControl.cpp">
|
<ClCompile Include="TSFInputControl.cpp">
|
||||||
<DependentUpon>TSFInputControl.idl</DependentUpon>
|
<DependentUpon>TSFInputControl.idl</DependentUpon>
|
||||||
|
@ -71,7 +71,9 @@
|
||||||
<Midl Include="SearchBoxControl.idl">
|
<Midl Include="SearchBoxControl.idl">
|
||||||
<DependentUpon>SearchBoxControl.xaml</DependentUpon>
|
<DependentUpon>SearchBoxControl.xaml</DependentUpon>
|
||||||
</Midl>
|
</Midl>
|
||||||
<Midl Include="TermControl.idl" />
|
<Midl Include="TermControl.idl">
|
||||||
|
<DependentUpon>TermControl.xaml</DependentUpon>
|
||||||
|
</Midl>
|
||||||
<Midl Include="TermControlAutomationPeer.idl" />
|
<Midl Include="TermControlAutomationPeer.idl" />
|
||||||
<Midl Include="TSFInputControl.idl" />
|
<Midl Include="TSFInputControl.idl" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -109,6 +111,9 @@
|
||||||
<Page Include="SearchBoxControl.xaml">
|
<Page Include="SearchBoxControl.xaml">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</Page>
|
</Page>
|
||||||
|
<Page Include="TermControl.xaml">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</Page>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.post.props" />
|
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.post.props" />
|
||||||
|
|
Loading…
Reference in a new issue