mirror of
https://github.com/microsoft/terminal.git
synced 2026-04-06 14:19:45 +00:00
Compare commits
5 Commits
dev/cazamo
...
dev/migrie
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fb460d7f60 | ||
|
|
df2fe4fe66 | ||
|
|
3f9e4559cd | ||
|
|
cd1ebb6e67 | ||
|
|
e7882c33c1 |
1567
enc_temp_folder/5546b56897bd46fa17b04a1ed558c1/Terminal.cpp
Normal file
1567
enc_temp_folder/5546b56897bd46fa17b04a1ed558c1/Terminal.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@@ -355,9 +355,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
_renderEngine->SetSelectionBackground(til::color{ _settings->SelectionBackground() });
|
||||
|
||||
const auto vp = _renderEngine->GetViewportInCharacters(viewInPixels);
|
||||
const auto width = vp.Width();
|
||||
const auto height = vp.Height();
|
||||
_connection.Resize(height, width);
|
||||
const auto visibleWidth = vp.Width();
|
||||
const auto visibleHeight = vp.Height();
|
||||
// _connection.Resize(height, width);
|
||||
|
||||
if (_owningHwnd != 0)
|
||||
{
|
||||
@@ -368,11 +368,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
}
|
||||
|
||||
// Override the default width and height to match the size of the swapChainPanel
|
||||
_settings->InitialCols(width);
|
||||
_settings->InitialRows(height);
|
||||
_settings->InitialCols(visibleWidth);
|
||||
_settings->InitialRows(visibleHeight);
|
||||
|
||||
_terminal->CreateFromSettings(*_settings, *_renderer);
|
||||
|
||||
const auto realSize{ _terminal->GetRealViewportSize() };
|
||||
_connection.Resize(realSize.height, realSize.width);
|
||||
// IMPORTANT! Set this callback up sooner than later. If we do it
|
||||
// after Enable, then it'll be possible to paint the frame once
|
||||
// _before_ the warning handler is set up, and then warnings from
|
||||
@@ -659,6 +660,22 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
}
|
||||
}
|
||||
|
||||
void ControlCore::UserScrollViewportHorizontally(const int viewLeft)
|
||||
{
|
||||
// Clear the regex pattern tree so the renderer does not try to render them while scrolling
|
||||
_terminal->ClearPatternTree();
|
||||
|
||||
// This is a scroll event that wasn't initiated by the terminal
|
||||
// itself - it was initiated by the mouse wheel, or the scrollbar.
|
||||
_terminal->UserScrollViewportHorizontally(viewLeft);
|
||||
|
||||
const auto shared = _shared.lock_shared();
|
||||
if (shared->updatePatternLocations)
|
||||
{
|
||||
(*shared->updatePatternLocations)();
|
||||
}
|
||||
}
|
||||
|
||||
void ControlCore::AdjustOpacity(const double adjustment)
|
||||
{
|
||||
if (adjustment == 0)
|
||||
@@ -1392,6 +1409,19 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
return _terminal->GetBufferHeight();
|
||||
}
|
||||
|
||||
int ControlCore::HorizontalScrollOffset()
|
||||
{
|
||||
return _terminal->_horizontalOffset;
|
||||
}
|
||||
int ControlCore::ViewWidth() const
|
||||
{
|
||||
return _terminal->_visibleWidth;
|
||||
}
|
||||
int ControlCore::BufferWidth() const
|
||||
{
|
||||
return _terminal->GetRealViewportSize().width;
|
||||
}
|
||||
|
||||
void ControlCore::_terminalWarningBell()
|
||||
{
|
||||
// Since this can only ever be triggered by output from the connection,
|
||||
@@ -1447,10 +1477,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
viewHeight,
|
||||
bufferSize) };
|
||||
|
||||
if (_inUnitTests) [[unlikely]]
|
||||
{
|
||||
_ScrollPositionChangedHandlers(*this, update);
|
||||
}
|
||||
if (_inUnitTests)
|
||||
[[unlikely]]
|
||||
{
|
||||
_ScrollPositionChangedHandlers(*this, update);
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto shared = _shared.lock_shared();
|
||||
|
||||
@@ -139,10 +139,16 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
TerminalConnection::ConnectionState ConnectionState() const;
|
||||
|
||||
// Vertical scrolling
|
||||
int ScrollOffset();
|
||||
int ViewHeight() const;
|
||||
int BufferHeight() const;
|
||||
|
||||
// Horizontal scrolling
|
||||
int HorizontalScrollOffset();
|
||||
int ViewWidth() const;
|
||||
int BufferWidth() const;
|
||||
|
||||
bool HasSelection() const;
|
||||
Windows::Foundation::Collections::IVector<winrt::hstring> SelectedText(bool trimTrailingWhitespace) const;
|
||||
|
||||
@@ -175,6 +181,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
const short wheelDelta,
|
||||
const ::Microsoft::Console::VirtualTerminal::TerminalInput::MouseButtonState state);
|
||||
void UserScrollViewport(const int viewTop);
|
||||
void UserScrollViewportHorizontally(const int viewLeft);
|
||||
|
||||
void ClearBuffer(Control::ClearBufferType clearType);
|
||||
|
||||
|
||||
@@ -632,6 +632,25 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
}
|
||||
}
|
||||
|
||||
void ControlInteractivity::UpdateHorizontalScrollbar(const double newValue)
|
||||
{
|
||||
// Set this as the new value of our internal scrollbar representation.
|
||||
// We're doing this so we can accumulate fractional amounts of a row to
|
||||
// scroll each time the mouse scrolls.
|
||||
_internalHorizontalScrollbarPosition = std::clamp<double>(newValue, 0.0, _core->BufferWidth());
|
||||
auto viewLeft = ::base::saturated_cast<int>(::std::round(_internalHorizontalScrollbarPosition));
|
||||
if (viewLeft != _core->HorizontalScrollOffset())
|
||||
{
|
||||
_core->UserScrollViewportHorizontally(viewLeft);
|
||||
|
||||
// _core->ScrollOffset() is now set to newValue
|
||||
_HorizontalScrollPositionChangedHandlers(*this,
|
||||
winrt::make<ScrollPositionChangedArgs>(_core->HorizontalScrollOffset(),
|
||||
_core->ViewWidth(),
|
||||
_core->BufferWidth()));
|
||||
}
|
||||
}
|
||||
|
||||
void ControlInteractivity::_hyperlinkHandler(const std::wstring_view uri)
|
||||
{
|
||||
_OpenHyperlinkHandlers(*this, winrt::make<OpenHyperlinkEventArgs>(winrt::hstring{ uri }));
|
||||
|
||||
@@ -79,6 +79,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
const Control::MouseButtonState state);
|
||||
|
||||
void UpdateScrollbar(const double newValue);
|
||||
void UpdateHorizontalScrollbar(const double newValue);
|
||||
|
||||
#pragma endregion
|
||||
|
||||
@@ -94,6 +95,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
TYPED_EVENT(OpenHyperlink, IInspectable, Control::OpenHyperlinkEventArgs);
|
||||
TYPED_EVENT(PasteFromClipboard, IInspectable, Control::PasteFromClipboardEventArgs);
|
||||
TYPED_EVENT(ScrollPositionChanged, IInspectable, Control::ScrollPositionChangedArgs);
|
||||
TYPED_EVENT(HorizontalScrollPositionChanged, IInspectable, Control::ScrollPositionChangedArgs);
|
||||
TYPED_EVENT(ContextMenuRequested, IInspectable, Control::ContextMenuRequestedEventArgs);
|
||||
|
||||
TYPED_EVENT(Attached, IInspectable, IInspectable);
|
||||
@@ -112,6 +114,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
winrt::com_ptr<ControlCore> _core{ nullptr };
|
||||
unsigned int _rowsToScroll;
|
||||
double _internalScrollbarPosition{ 0.0 };
|
||||
double _internalHorizontalScrollbarPosition{ 0.0 };
|
||||
|
||||
// If this is set, then we assume we are in the middle of panning the
|
||||
// viewport via touch input.
|
||||
|
||||
@@ -65,11 +65,13 @@ namespace Microsoft.Terminal.Control
|
||||
MouseButtonState state);
|
||||
|
||||
void UpdateScrollbar(Double newValue);
|
||||
void UpdateHorizontalScrollbar(Double newValue);
|
||||
|
||||
Boolean ManglePathsForWsl { get; };
|
||||
|
||||
event Windows.Foundation.TypedEventHandler<Object, OpenHyperlinkEventArgs> OpenHyperlink;
|
||||
event Windows.Foundation.TypedEventHandler<Object, ScrollPositionChangedArgs> ScrollPositionChanged;
|
||||
event Windows.Foundation.TypedEventHandler<Object, ScrollPositionChangedArgs> HorizontalScrollPositionChanged;
|
||||
event Windows.Foundation.TypedEventHandler<Object, PasteFromClipboardEventArgs> PasteFromClipboard;
|
||||
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> Closed;
|
||||
|
||||
@@ -45,6 +45,10 @@ namespace Microsoft.Terminal.Control
|
||||
Int32 ViewHeight { get; };
|
||||
Int32 BufferHeight { get; };
|
||||
|
||||
Int32 HorizontalScrollOffset { get; };
|
||||
Int32 ViewWidth { get; };
|
||||
Int32 BufferWidth { get; };
|
||||
|
||||
Boolean HasSelection { get; };
|
||||
IVector<String> SelectedText(Boolean trimTrailingWhitespace);
|
||||
|
||||
|
||||
@@ -94,6 +94,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
_revokers.coreOpenHyperlink = _core.OpenHyperlink(winrt::auto_revoke, { get_weak(), &TermControl::_HyperlinkHandler });
|
||||
_revokers.interactivityOpenHyperlink = _interactivity.OpenHyperlink(winrt::auto_revoke, { get_weak(), &TermControl::_HyperlinkHandler });
|
||||
_revokers.interactivityScrollPositionChanged = _interactivity.ScrollPositionChanged(winrt::auto_revoke, { get_weak(), &TermControl::_ScrollPositionChanged });
|
||||
_revokers.interactivityHorizontalScrollPositionChanged = _interactivity.HorizontalScrollPositionChanged(winrt::auto_revoke, { get_weak(), &TermControl::_HorizontalScrollPositionChanged });
|
||||
_revokers.ContextMenuRequested = _interactivity.ContextMenuRequested(winrt::auto_revoke, { get_weak(), &TermControl::_contextMenuHandler });
|
||||
|
||||
// "Bubbled" events - ones we want to handle, by raising our own event.
|
||||
@@ -157,6 +158,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// _updateScrollBar func. Otherwise, we could get a callback from an
|
||||
// attached content before we set up the throttled func, and that'll A/V
|
||||
_revokers.coreScrollPositionChanged = _core.ScrollPositionChanged(winrt::auto_revoke, { get_weak(), &TermControl::_ScrollPositionChanged });
|
||||
// TODO! Horizontal?
|
||||
_revokers.WarningBell = _core.WarningBell(winrt::auto_revoke, { get_weak(), &TermControl::_coreWarningBell });
|
||||
_revokers.CursorPositionChanged = _core.CursorPositionChanged(winrt::auto_revoke, { get_weak(), &TermControl::_CursorPositionChanged });
|
||||
|
||||
@@ -280,7 +282,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
_isInternalScrollBarUpdate = true;
|
||||
|
||||
auto scrollBar = ScrollBar();
|
||||
auto scrollBar = update.horizontal ? HorizontalScrollBar() : ScrollBar();
|
||||
if (update.newValue)
|
||||
{
|
||||
scrollBar.Value(*update.newValue);
|
||||
@@ -293,7 +295,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
_isInternalScrollBarUpdate = false;
|
||||
|
||||
if (_showMarksInScrollbar)
|
||||
if (!update.horizontal && _showMarksInScrollbar)
|
||||
{
|
||||
// Update scrollbar marks
|
||||
ScrollBarCanvas().Children().Clear();
|
||||
@@ -977,6 +979,15 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
ScrollBar().ViewportSize(bufferHeight);
|
||||
ScrollBar().LargeChange(bufferHeight); // scroll one "screenful" at a time when the scroll bar is clicked
|
||||
|
||||
auto bufferWidth = _core.BufferWidth();
|
||||
auto viewWidth = _core.ViewWidth();
|
||||
|
||||
HorizontalScrollBar().Maximum(bufferWidth - viewWidth);
|
||||
HorizontalScrollBar().Minimum(0);
|
||||
HorizontalScrollBar().Value(0);
|
||||
HorizontalScrollBar().ViewportSize(viewWidth);
|
||||
HorizontalScrollBar().LargeChange(viewWidth); // scroll one "screenful" at a time when the scroll bar is clicked
|
||||
|
||||
// Set up blinking cursor
|
||||
int blinkTime = GetCaretBlinkTime();
|
||||
if (blinkTime != INFINITE)
|
||||
@@ -1671,6 +1682,27 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
update.newValue.reset();
|
||||
});
|
||||
}
|
||||
void TermControl::_HorizontalScrollbarChangeHandler(const Windows::Foundation::IInspectable& /*sender*/,
|
||||
const Controls::Primitives::RangeBaseValueChangedEventArgs& args)
|
||||
{
|
||||
if (_isInternalScrollBarUpdate || _IsClosing())
|
||||
{
|
||||
// The update comes from ourselves, more specifically from the
|
||||
// terminal. So we don't have to update the terminal because it
|
||||
// already knows.
|
||||
return;
|
||||
}
|
||||
|
||||
const auto newValue = args.NewValue();
|
||||
newValue;
|
||||
_interactivity.UpdateHorizontalScrollbar(newValue);
|
||||
|
||||
// // User input takes priority over terminal events so cancel
|
||||
// // any pending scroll bar update if the user scrolls.
|
||||
// _updateScrollBar->ModifyPending([](auto& update) {
|
||||
// update.newValue.reset();
|
||||
// });
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - captures the pointer so that none of the other XAML elements respond to pointer events
|
||||
@@ -2009,6 +2041,27 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
update.newMinimum = 0;
|
||||
update.newViewportSize = args.ViewHeight();
|
||||
update.newValue = args.ViewTop();
|
||||
update.horizontal = false;
|
||||
|
||||
_updateScrollBar->Run(update);
|
||||
|
||||
// if a selection marker is already visible,
|
||||
// update the position of those markers
|
||||
if (SelectionStartMarker().Visibility() == Visibility::Visible || SelectionEndMarker().Visibility() == Visibility::Visible)
|
||||
{
|
||||
_updateSelectionMarkers(nullptr, winrt::make<UpdateSelectionMarkersEventArgs>(false));
|
||||
}
|
||||
}
|
||||
void TermControl::_HorizontalScrollPositionChanged(const IInspectable& /*sender*/,
|
||||
const Control::ScrollPositionChangedArgs& args)
|
||||
{
|
||||
ScrollBarUpdate update;
|
||||
const auto hiddenContent = args.BufferSize() - args.ViewHeight();
|
||||
update.newMaximum = hiddenContent;
|
||||
update.newMinimum = 0;
|
||||
update.newViewportSize = args.ViewHeight();
|
||||
update.newValue = args.ViewTop();
|
||||
update.horizontal = true;
|
||||
|
||||
_updateScrollBar->Run(update);
|
||||
|
||||
@@ -2183,6 +2236,19 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
return _core.BufferHeight();
|
||||
}
|
||||
|
||||
int TermControl::HorizontalScrollOffset() const
|
||||
{
|
||||
return _core.HorizontalScrollOffset();
|
||||
}
|
||||
int TermControl::ViewWidth() const
|
||||
{
|
||||
return _core.ViewWidth();
|
||||
}
|
||||
int TermControl::BufferWidth() const
|
||||
{
|
||||
return _core.BufferWidth();
|
||||
}
|
||||
|
||||
// Function Description:
|
||||
// - Determines how much space (in pixels) an app would need to reserve to
|
||||
// create a control with the settings stored in the settings param. This
|
||||
|
||||
@@ -68,6 +68,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
int ScrollOffset() const;
|
||||
int ViewHeight() const;
|
||||
int BufferHeight() const;
|
||||
// Horizontal scrolling
|
||||
int HorizontalScrollOffset() const;
|
||||
int ViewWidth() const;
|
||||
int BufferWidth() const;
|
||||
|
||||
bool HasSelection() const;
|
||||
Windows::Foundation::Collections::IVector<winrt::hstring> SelectedText(bool trimTrailingWhitespace) const;
|
||||
@@ -217,6 +221,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
double newMaximum;
|
||||
double newMinimum;
|
||||
double newViewportSize;
|
||||
bool horizontal;
|
||||
};
|
||||
|
||||
std::shared_ptr<ThrottledFuncTrailing<ScrollBarUpdate>> _updateScrollBar;
|
||||
@@ -292,6 +297,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
void _PointerExitedHandler(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::Input::PointerRoutedEventArgs& e);
|
||||
void _MouseWheelHandler(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::Input::PointerRoutedEventArgs& e);
|
||||
void _ScrollbarChangeHandler(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::Controls::Primitives::RangeBaseValueChangedEventArgs& e);
|
||||
void _HorizontalScrollbarChangeHandler(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::Controls::Primitives::RangeBaseValueChangedEventArgs& e);
|
||||
|
||||
void _GotFocusHandler(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& e);
|
||||
void _LostFocusHandler(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& e);
|
||||
@@ -313,6 +319,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
void _TerminalTabColorChanged(const std::optional<til::color> color);
|
||||
|
||||
void _ScrollPositionChanged(const IInspectable& sender, const Control::ScrollPositionChangedArgs& args);
|
||||
void _HorizontalScrollPositionChanged(const IInspectable& sender, const Control::ScrollPositionChangedArgs& args);
|
||||
winrt::fire_and_forget _CursorPositionChanged(const IInspectable& sender, const IInspectable& args);
|
||||
|
||||
bool _CapturePointer(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::Input::PointerRoutedEventArgs& e);
|
||||
@@ -393,6 +400,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
Control::ControlInteractivity::OpenHyperlink_revoker interactivityOpenHyperlink;
|
||||
Control::ControlInteractivity::ScrollPositionChanged_revoker interactivityScrollPositionChanged;
|
||||
Control::ControlInteractivity::HorizontalScrollPositionChanged_revoker interactivityHorizontalScrollPositionChanged;
|
||||
Control::ControlInteractivity::PasteFromClipboard_revoker PasteFromClipboard;
|
||||
Control::ControlInteractivity::ContextMenuRequested_revoker ContextMenuRequested;
|
||||
} _revokers{};
|
||||
|
||||
@@ -1260,7 +1260,13 @@
|
||||
PointerReleased="_PointerReleasedHandler"
|
||||
Visibility="Visible">
|
||||
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<SwapChainPanel x:Name="SwapChainPanel"
|
||||
Grid.Row="0"
|
||||
CompositionScaleChanged="_SwapChainScaleChanged"
|
||||
SizeChanged="_SwapChainSizeChanged">
|
||||
<Canvas x:Name="OverlayCanvas"
|
||||
@@ -1297,12 +1303,27 @@
|
||||
ensures that it's always aligned w/ the scrollbar
|
||||
-->
|
||||
<local:SearchBoxControl x:Name="SearchBox"
|
||||
Grid.Row="0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Top"
|
||||
x:Load="False"
|
||||
Closed="_CloseSearchBoxControl"
|
||||
Search="_Search"
|
||||
Visibility="Collapsed" />
|
||||
|
||||
<ScrollBar x:Name="HorizontalScrollBar"
|
||||
Grid.Row="1"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Bottom"
|
||||
IndicatorMode="MouseIndicator"
|
||||
IsTabStop="False"
|
||||
LargeChange="4"
|
||||
Maximum="1"
|
||||
Orientation="Horizontal"
|
||||
SmallChange="1"
|
||||
Style="{StaticResource ForkedScrollbarTemplate}"
|
||||
ValueChanged="_HorizontalScrollbarChangeHandler"
|
||||
ViewportSize="10" />
|
||||
</Grid>
|
||||
|
||||
<ScrollBar x:Name="ScrollBar"
|
||||
|
||||
@@ -22,6 +22,7 @@ namespace Microsoft::Terminal::Core
|
||||
|
||||
[[nodiscard]] virtual HRESULT UserResize(const til::size size) noexcept = 0;
|
||||
virtual void UserScrollViewport(const int viewTop) = 0;
|
||||
virtual void UserScrollViewportHorizontally(const int viewLeft) = 0;
|
||||
virtual int GetScrollOffset() = 0;
|
||||
|
||||
virtual void TrySnapOnInput() = 0;
|
||||
|
||||
@@ -30,9 +30,12 @@ Terminal::Terminal()
|
||||
|
||||
void Terminal::Create(til::size viewportSize, til::CoordType scrollbackLines, Renderer& renderer)
|
||||
{
|
||||
_mutableViewport = Viewport::FromDimensions({ 0, 0 }, viewportSize);
|
||||
_visibleWidth = viewportSize.width;
|
||||
auto realWidth = std::max(_visibleWidth, _minWidth);
|
||||
|
||||
_mutableViewport = Viewport::FromDimensions({ 0, 0 }, { realWidth, viewportSize.height });
|
||||
_scrollbackLines = scrollbackLines;
|
||||
const til::size bufferSize{ viewportSize.width,
|
||||
const til::size bufferSize{ realWidth,
|
||||
Utils::ClampToShortMax(viewportSize.height + scrollbackLines, 1) };
|
||||
const TextAttribute attr{};
|
||||
const UINT cursorSize = 12;
|
||||
@@ -227,18 +230,30 @@ std::wstring_view Terminal::GetWorkingDirectory() noexcept
|
||||
// appropriate HRESULT for failing to resize.
|
||||
[[nodiscard]] HRESULT Terminal::UserResize(const til::size viewportSize) noexcept
|
||||
{
|
||||
const auto oldDimensions = _GetMutableViewport().Dimensions();
|
||||
if (viewportSize == oldDimensions)
|
||||
const auto oldBackingDimensions = _GetMutableViewport().Dimensions();
|
||||
const auto oldVisibleDimensions = _GetVisibleViewport().Dimensions();
|
||||
if (oldVisibleDimensions == viewportSize)
|
||||
{
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
// IMPORTANT: Make sure to change the visible view width, even if we no-op the rest of the resize.
|
||||
_visibleWidth = viewportSize.width;
|
||||
|
||||
// const auto oldDimensions = _GetMutableViewport().Dimensions();
|
||||
// if (viewportSize == oldDimensions)
|
||||
// {
|
||||
// return S_FALSE;
|
||||
// }
|
||||
|
||||
// Shortcut: if we're in the alt buffer, just resize the
|
||||
// alt buffer and put off resizing the main buffer till we switch back. Fortunately, this is easy. We don't need to
|
||||
// worry about the viewport and scrollback at all! The alt buffer never has
|
||||
// any scrollback, so we just need to resize it and presto, we're done.
|
||||
if (_inAltBuffer())
|
||||
{
|
||||
// TODO! deal with the alt buffer
|
||||
|
||||
// stash this resize for the future.
|
||||
_deferredResize = viewportSize;
|
||||
|
||||
@@ -259,10 +274,16 @@ std::wstring_view Terminal::GetWorkingDirectory() noexcept
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
const auto dx = viewportSize.width - oldDimensions.width;
|
||||
const auto newBufferHeight = std::clamp(viewportSize.height + _scrollbackLines, 0, SHRT_MAX);
|
||||
const til::size newRealSize{ std::max(viewportSize.width, _minWidth), viewportSize.height };
|
||||
if (newRealSize == oldBackingDimensions)
|
||||
{
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
til::size bufferSize{ viewportSize.width, newBufferHeight };
|
||||
const auto dx = newRealSize.width - oldBackingDimensions.width;
|
||||
const auto newBufferHeight = std::clamp(newRealSize.height + _scrollbackLines, 0, SHRT_MAX);
|
||||
|
||||
til::size bufferSize{ newRealSize.width, newBufferHeight };
|
||||
|
||||
// This will be used to determine where the viewport should be in the new buffer.
|
||||
const auto oldViewportTop = _mutableViewport.Top();
|
||||
@@ -365,7 +386,7 @@ std::wstring_view Terminal::GetWorkingDirectory() noexcept
|
||||
|
||||
const auto maxRow = std::max(newLastChar.y, newCursorPos.y);
|
||||
|
||||
const auto proposedTopFromLastLine = maxRow - viewportSize.height + 1;
|
||||
const auto proposedTopFromLastLine = maxRow - newRealSize.height + 1;
|
||||
const auto proposedTopFromScrollback = newViewportTop;
|
||||
|
||||
auto proposedTop = std::max(proposedTopFromLastLine,
|
||||
@@ -386,7 +407,7 @@ std::wstring_view Terminal::GetWorkingDirectory() noexcept
|
||||
// this proposed top position.
|
||||
if (proposedTop == proposedTopFromScrollback)
|
||||
{
|
||||
const auto proposedViewFromTop = Viewport::FromDimensions({ 0, proposedTopFromScrollback }, viewportSize);
|
||||
const auto proposedViewFromTop = Viewport::FromDimensions({ 0, proposedTopFromScrollback }, newRealSize);
|
||||
if (maxRow < proposedViewFromTop.BottomInclusive())
|
||||
{
|
||||
if (dx < 0 && proposedTop > 0)
|
||||
@@ -407,7 +428,7 @@ std::wstring_view Terminal::GetWorkingDirectory() noexcept
|
||||
// If the new bottom would be higher than the last row of text, then we
|
||||
// definitely want to use the last row of text to determine where the
|
||||
// viewport should be.
|
||||
const auto proposedViewFromTop = Viewport::FromDimensions({ 0, proposedTopFromScrollback }, viewportSize);
|
||||
const auto proposedViewFromTop = Viewport::FromDimensions({ 0, proposedTopFromScrollback }, newRealSize);
|
||||
if (maxRow > proposedViewFromTop.BottomInclusive())
|
||||
{
|
||||
proposedTop = proposedTopFromLastLine;
|
||||
@@ -419,14 +440,14 @@ std::wstring_view Terminal::GetWorkingDirectory() noexcept
|
||||
|
||||
// If the new bottom would be below the bottom of the buffer, then slide the
|
||||
// top up so that we'll still fit within the buffer.
|
||||
const auto newView = Viewport::FromDimensions({ 0, proposedTop }, viewportSize);
|
||||
const auto newView = Viewport::FromDimensions({ 0, proposedTop }, newRealSize);
|
||||
const auto proposedBottom = newView.BottomExclusive();
|
||||
if (proposedBottom > bufferSize.height)
|
||||
{
|
||||
proposedTop = ::base::ClampSub(proposedTop, ::base::ClampSub(proposedBottom, bufferSize.height));
|
||||
}
|
||||
|
||||
_mutableViewport = Viewport::FromDimensions({ 0, proposedTop }, viewportSize);
|
||||
_mutableViewport = Viewport::FromDimensions({ 0, proposedTop }, newRealSize);
|
||||
|
||||
_mainBuffer.swap(newTextBuffer);
|
||||
|
||||
@@ -440,6 +461,8 @@ std::wstring_view Terminal::GetWorkingDirectory() noexcept
|
||||
// before, and shouldn't be now either.
|
||||
_scrollOffset = originalOffsetWasZero ? 0 : static_cast<int>(::base::ClampSub(_mutableViewport.Top(), newVisibleTop));
|
||||
|
||||
// _visibleWidth = viewportSize.width;
|
||||
|
||||
// GH#5029 - make sure to InvalidateAll here, so that we'll paint the entire visible viewport.
|
||||
try
|
||||
{
|
||||
@@ -1049,11 +1072,11 @@ Viewport Terminal::_GetVisibleViewport() const noexcept
|
||||
// GH#3493: if we're in the alt buffer, then it's possible that the mutable
|
||||
// viewport's size hasn't been updated yet. In that case, use the
|
||||
// temporarily stashed _altBufferSize instead.
|
||||
const til::point origin{ 0, _VisibleStartIndex() };
|
||||
const til::point origin{ _horizontalOffset, _VisibleStartIndex() };
|
||||
const auto size{ _inAltBuffer() ? _altBufferSize :
|
||||
_mutableViewport.Dimensions() };
|
||||
return Viewport::FromDimensions(origin,
|
||||
size);
|
||||
{ _visibleWidth, size.height });
|
||||
}
|
||||
|
||||
void Terminal::_PreserveUserScrollOffset(const int viewportDelta) noexcept
|
||||
@@ -1091,6 +1114,31 @@ void Terminal::UserScrollViewport(const int viewTop)
|
||||
// from the previous frame drawn.
|
||||
_activeBuffer().TriggerScroll();
|
||||
}
|
||||
void Terminal::UserScrollViewportHorizontally(const int viewLeft)
|
||||
{
|
||||
if (_inAltBuffer())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// we're going to modify state here that the renderer could be reading.
|
||||
auto lock = LockForWriting();
|
||||
|
||||
const auto clampedNewLeft = std::max(0, viewLeft);
|
||||
// const auto realLeft = _horizontalOffset;
|
||||
// const auto newDelta = realLeft - clampedNewLeft;
|
||||
// if viewTop > realTop, we want the offset to be 0.
|
||||
|
||||
// _scrollOffset = std::max(0, newDelta);
|
||||
|
||||
// We need to clamp to the right though too.
|
||||
// We can't scroll past the right edge of the buffer.
|
||||
const auto maxScrollOffset = _mutableViewport.Width() - _visibleWidth;
|
||||
_horizontalOffset = std::min(clampedNewLeft, maxScrollOffset);
|
||||
|
||||
// TODO! I'm just redrawing all cause I'm pretty sure the renderers HATE horizontal scrolling.
|
||||
_activeBuffer().TriggerRedrawAll();
|
||||
}
|
||||
|
||||
int Terminal::GetScrollOffset() noexcept
|
||||
{
|
||||
|
||||
@@ -150,6 +150,7 @@ public:
|
||||
|
||||
[[nodiscard]] HRESULT UserResize(const til::size viewportSize) noexcept override;
|
||||
void UserScrollViewport(const int viewTop) override;
|
||||
void UserScrollViewportHorizontally(const int viewLeft) override;
|
||||
int GetScrollOffset() noexcept override;
|
||||
|
||||
void TrySnapOnInput() override;
|
||||
@@ -287,6 +288,16 @@ public:
|
||||
const TextBuffer::TextAndColor RetrieveSelectedTextFromBuffer(bool trimTrailingWhitespace);
|
||||
#pragma endregion
|
||||
|
||||
til::CoordType _minWidth = 128;
|
||||
til::CoordType _visibleWidth;
|
||||
til::CoordType _horizontalOffset = 0;
|
||||
til::size GetRealViewportSize()
|
||||
{
|
||||
const auto mutableView{ _GetMutableViewport() };
|
||||
// return til::size{ std::min(_minWidth, mutableView.Width()), mutableView.Height() };
|
||||
return til::size{ mutableView.Width(), mutableView.Height() };
|
||||
}
|
||||
|
||||
private:
|
||||
std::function<void(std::wstring_view)> _pfnWriteInput;
|
||||
std::function<void()> _pfnWarningBell;
|
||||
|
||||
@@ -509,7 +509,7 @@ CATCH_RETURN()
|
||||
clipRect.top = origin.y + drawingContext->topClipOffset;
|
||||
clipRect.bottom = origin.y + drawingContext->cellSize.height - drawingContext->bottomClipOffset;
|
||||
clipRect.left = 0;
|
||||
clipRect.right = drawingContext->targetSize.width;
|
||||
clipRect.right = origin.x + drawingContext->targetSize.width;
|
||||
|
||||
// If we already have a clip rectangle, check if it different than the previous one.
|
||||
if (_clipRect.has_value())
|
||||
|
||||
Reference in New Issue
Block a user