-
Notifications
You must be signed in to change notification settings - Fork 8.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
First three interactivity fixes #9980
Changes from 7 commits
5d05e95
167ff7c
9d33e89
be7ea6f
4f4df01
33d29fa
0fefc5b
0ad3770
7a2bc6a
9fb46b1
20018bd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -35,6 +35,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation | |||||
_selectionNeedsToBeCopied{ false } | ||||||
{ | ||||||
_core = winrt::make_self<ControlCore>(settings, connection); | ||||||
|
||||||
_core->ScrollPositionChanged({ this, &ControlInteractivity::_coreScrollPositionChanged }); | ||||||
} | ||||||
|
||||||
void ControlInteractivity::UpdateSettings() | ||||||
|
@@ -197,7 +199,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation | |||||
if (multiClickMapper == 1) | ||||||
{ | ||||||
_singleClickTouchdownPos = pixelPosition; | ||||||
_singleClickTouchdownTerminalPos = terminalPosition; | ||||||
|
||||||
if (!_core->HasSelection()) | ||||||
{ | ||||||
|
@@ -266,10 +267,14 @@ namespace winrt::Microsoft::Terminal::Control::implementation | |||||
const auto fontSizeInDips{ _core->FontSizeInDips() }; | ||||||
if (distance >= (std::min(fontSizeInDips.width(), fontSizeInDips.height()) / 4.f)) | ||||||
{ | ||||||
_core->SetSelectionAnchor(terminalPosition); | ||||||
// GH#9955.c: Make sure to use the temrinal location of the | ||||||
// _touchdown_ point here. We want to start the selection | ||||||
// from where the user initially clicked, not where they are | ||||||
// now. | ||||||
_core->SetSelectionAnchor(_getTerminalPosition(touchdownPoint)); | ||||||
|
||||||
// stop tracking the touchdown point | ||||||
_singleClickTouchdownPos = std::nullopt; | ||||||
_singleClickTouchdownTerminalPos = std::nullopt; | ||||||
} | ||||||
} | ||||||
|
||||||
|
@@ -303,12 +308,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation | |||||
// panning down) | ||||||
const float numRows = -1.0f * (dy / fontSizeInDips.height<float>()); | ||||||
|
||||||
const auto currentOffset = ::base::ClampedNumeric<double>(_core->ScrollOffset()); | ||||||
const auto newValue = numRows + currentOffset; | ||||||
const double currentOffset = ::base::ClampedNumeric<double>(_core->ScrollOffset()); | ||||||
const double newValue = numRows + currentOffset; | ||||||
|
||||||
// Update the Core's viewport position, and raise a | ||||||
// ScrollPositionChanged event to update the scrollbar | ||||||
_updateScrollbar(newValue); | ||||||
UpdateScrollbar(newValue); | ||||||
|
||||||
// Use this point as our new scroll anchor. | ||||||
_touchAnchor = newTouchPoint; | ||||||
|
@@ -341,7 +346,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation | |||||
} | ||||||
|
||||||
_singleClickTouchdownPos = std::nullopt; | ||||||
_singleClickTouchdownTerminalPos = std::nullopt; | ||||||
} | ||||||
|
||||||
void ControlInteractivity::TouchReleased() | ||||||
|
@@ -396,7 +400,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation | |||||
} | ||||||
else | ||||||
{ | ||||||
_mouseScrollHandler(delta, terminalPosition, state.isLeftButtonDown); | ||||||
_mouseScrollHandler(delta, pixelPosition, state.isLeftButtonDown); | ||||||
} | ||||||
return false; | ||||||
} | ||||||
|
@@ -428,35 +432,40 @@ namespace winrt::Microsoft::Terminal::Control::implementation | |||||
// - Scroll the visible viewport in response to a mouse wheel event. | ||||||
// Arguments: | ||||||
// - mouseDelta: the mouse wheel delta that triggered this event. | ||||||
// - point: the location of the mouse during this event | ||||||
// - pixelPosition: the location of the mouse during this event | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. eh. i hate when the name is obvious and we are forced to document the obvious name |
||||||
// - isLeftButtonPressed: true iff the left mouse button was pressed during this event. | ||||||
void ControlInteractivity::_mouseScrollHandler(const double mouseDelta, | ||||||
const til::point terminalPosition, | ||||||
const til::point pixelPosition, | ||||||
const bool isLeftButtonPressed) | ||||||
{ | ||||||
const auto currentOffset = _core->ScrollOffset(); | ||||||
// GH#9955.b: Start scrolling from our internal scrollbar position. This | ||||||
// lets us accumulate fractional numbers of rows to scroll with each | ||||||
// event. Especially for precision trackpads, we might be getting scroll | ||||||
// deltas smaller than a single row, but we still want lots of those to | ||||||
// accumulate. | ||||||
const double currentOffset = _internalScrollbarPosition; | ||||||
|
||||||
// negative = down, positive = up | ||||||
// However, for us, the signs are flipped. | ||||||
// With one of the precision mice, one click is always a multiple of 120 (WHEEL_DELTA), | ||||||
// but the "smooth scrolling" mode results in non-int values | ||||||
const auto rowDelta = mouseDelta / (-1.0 * WHEEL_DELTA); | ||||||
const double rowDelta = mouseDelta / (-1.0 * 120.0); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems very important to continue using the correct constant. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yea I just got spooked by int math vs float math. I'll revert this bit |
||||||
|
||||||
// WHEEL_PAGESCROLL is a Win32 constant that represents the "scroll one page | ||||||
// at a time" setting. If we ignore it, we will scroll a truly absurd number | ||||||
// of rows. | ||||||
const auto rowsToScroll{ _rowsToScroll == WHEEL_PAGESCROLL ? _core->ViewHeight() : _rowsToScroll }; | ||||||
const double rowsToScroll{ _rowsToScroll == WHEEL_PAGESCROLL ? ::base::saturated_cast<double>(_core->ViewHeight()) : _rowsToScroll }; | ||||||
double newValue = (rowsToScroll * rowDelta) + (currentOffset); | ||||||
|
||||||
// Update the Core's viewport position, and raise a | ||||||
// ScrollPositionChanged event to update the scrollbar | ||||||
_updateScrollbar(::base::saturated_cast<int>(newValue)); | ||||||
UpdateScrollbar(newValue); | ||||||
|
||||||
if (isLeftButtonPressed) | ||||||
{ | ||||||
// If user is mouse selecting and scrolls, they then point at new | ||||||
// character. Make sure selection reflects that immediately. | ||||||
SetEndSelectionPoint(terminalPosition); | ||||||
SetEndSelectionPoint(pixelPosition); | ||||||
} | ||||||
} | ||||||
|
||||||
|
@@ -476,15 +485,42 @@ namespace winrt::Microsoft::Terminal::Control::implementation | |||||
// - newValue: The new top of the viewport | ||||||
// Return Value: | ||||||
// - <none> | ||||||
void ControlInteractivity::_updateScrollbar(const int newValue) | ||||||
void ControlInteractivity::UpdateScrollbar(const double newValue) | ||||||
{ | ||||||
_core->UserScrollViewport(newValue); | ||||||
// Set this as the new value of our internal scrollbar representation. | ||||||
// We're doing this so we can accumulate fractional amounts of a row to | ||||||
// scroll each time the mouse scrolls. | ||||||
_internalScrollbarPosition = std::clamp<double>(newValue, 0.0, _core->BufferHeight()); | ||||||
|
||||||
// If the new scrollbar position, rounded to an int, is at a different | ||||||
// row, then actually update the scroll position in the core, and raise | ||||||
// a ScrollPositionChanged to inform the control. | ||||||
int viewTop = ::base::saturated_cast<int>(::std::round(_internalScrollbarPosition)); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm. Does rounding match the pre-split behavior? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It might actually be better, a little smoother in both directions now. Hard to say for sure comparing Debug vs Release There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
if (viewTop != _core->ScrollOffset()) | ||||||
{ | ||||||
_core->UserScrollViewport(viewTop); | ||||||
|
||||||
// _core->ScrollOffset() is now set to newValue | ||||||
_ScrollPositionChangedHandlers(*this, | ||||||
winrt::make<ScrollPositionChangedArgs>(_core->ScrollOffset(), | ||||||
_core->ViewHeight(), | ||||||
_core->BufferHeight())); | ||||||
// _core->ScrollOffset() is now set to newValue | ||||||
_ScrollPositionChangedHandlers(*this, | ||||||
winrt::make<ScrollPositionChangedArgs>(_core->ScrollOffset(), | ||||||
_core->ViewHeight(), | ||||||
_core->BufferHeight())); | ||||||
} | ||||||
} | ||||||
|
||||||
// Method Description: | ||||||
// - Event handler for the core's ScrollPositionChanged event. This is | ||||||
// called when the core changes its viewport position, due to more text | ||||||
// being output. We'll use this event to update our own internal scrollbar | ||||||
// tracker to the position the viewport is at now. | ||||||
// Arguments: | ||||||
// - args: args containing infor about the position of the viewport in the buffer. | ||||||
// Return Value: | ||||||
// - <none> | ||||||
void ControlInteractivity::_coreScrollPositionChanged(const IInspectable& /*sender*/, | ||||||
const Control::ScrollPositionChangedArgs& args) | ||||||
{ | ||||||
_internalScrollbarPosition = args.ViewTop(); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just making sure: this fires every single time a line is printed to the terminal for the first 9001 lines. Is adding another event recipient worth it? Is there a way you can do this without having a double version of the viewport top every time it changes? :/ There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You know, I was being cautious here. I'm not positive this is needed. The event might get caught by the TermControl, throttled, then have TermControl call UpdateScrollbar, which might fix it for us. |
||||||
} | ||||||
|
||||||
void ControlInteractivity::_hyperlinkHandler(const std::wstring_view uri) | ||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1302,8 +1302,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation | |
return; | ||
} | ||
|
||
const auto newValue = static_cast<int>(args.NewValue()); | ||
_core->UserScrollViewport(newValue); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. hey, good! |
||
const auto newValue = args.NewValue(); | ||
_interactivity->UpdateScrollbar(newValue); | ||
|
||
// User input takes priority over terminal events so cancel | ||
// any pending scroll bar update if the user scrolls. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought you'd want to keep
auto currentOffset
. That way you get a safe chromium math add fornewValue
.