Commit 8a64b4d4 authored by Rahul Arakeri's avatar Rahul Arakeri Committed by Commit Bot

Simplify thumb drag.

This CL simplifies the implementation of thumb drag for the Compositor
threaded scrollbar scrolling feature. It also aligns the implementation
to main thread thumb drag more than before. The aim of doing this is to
reduce the possibility of bugs arising from the disparity between main
and cc manipulated scrollbars.

Bug: 1067518
Change-Id: I501c68e9993afcb4b1e097d0aafce7670d8bec4d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2136412
Commit-Queue: Rahul Arakeri <arakeri@microsoft.com>
Reviewed-by: default avatarDavid Bokan <bokan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#756892}
parent beefb20f
...@@ -34,21 +34,6 @@ void ScrollbarController::WillBeginImplFrame() { ...@@ -34,21 +34,6 @@ void ScrollbarController::WillBeginImplFrame() {
RecomputeAutoscrollStateIfNeeded(); RecomputeAutoscrollStateIfNeeded();
} }
gfx::Vector2dF ScrollbarController::GetThumbRelativePoint(
const ScrollbarLayerImplBase* scrollbar,
const gfx::PointF position_in_widget) {
bool clipped;
const gfx::PointF position_in_layer =
GetScrollbarRelativePosition(scrollbar, position_in_widget, &clipped);
if (clipped)
return gfx::Vector2d(0, 0);
const gfx::RectF thumb_rect(scrollbar->ComputeThumbQuadRect());
DCHECK(thumb_rect.Contains(position_in_layer));
return position_in_layer - gfx::PointF(thumb_rect.origin());
}
// Retrieves the ScrollbarLayerImplBase corresponding to the stashed ElementId. // Retrieves the ScrollbarLayerImplBase corresponding to the stashed ElementId.
ScrollbarLayerImplBase* ScrollbarController::ScrollbarLayer() { ScrollbarLayerImplBase* ScrollbarController::ScrollbarLayer() {
if (!captured_scrollbar_metadata_.has_value()) if (!captured_scrollbar_metadata_.has_value())
...@@ -111,8 +96,7 @@ InputHandlerPointerResult ScrollbarController::HandlePointerDown( ...@@ -111,8 +96,7 @@ InputHandlerPointerResult ScrollbarController::HandlePointerDown(
scroll_result.scroll_units = Granularity(scrollbar_part, shift_modifier); scroll_result.scroll_units = Granularity(scrollbar_part, shift_modifier);
if (scrollbar_part == ScrollbarPart::THUMB) { if (scrollbar_part == ScrollbarPart::THUMB) {
drag_state_ = DragState(); drag_state_ = DragState();
drag_state_->anchor_relative_to_thumb_ = drag_state_->drag_origin = position_in_widget;
GetThumbRelativePoint(scrollbar, position_in_widget);
// Record the current scroller offset. This will be needed to snap the // Record the current scroller offset. This will be needed to snap the
// thumb back to its original position if the pointer moves too far away // thumb back to its original position if the pointer moves too far away
...@@ -249,69 +233,23 @@ float ScrollbarController::GetScrollDeltaForAbsoluteJump( ...@@ -249,69 +233,23 @@ float ScrollbarController::GetScrollDeltaForAbsoluteJump(
return delta * GetScrollerToScrollbarRatio(scrollbar); return delta * GetScrollerToScrollbarRatio(scrollbar);
} }
gfx::ScrollOffset ScrollbarController::GetScrollOffsetForDragPosition( gfx::ScrollOffset ScrollbarController::GetScrollDeltaForDragPosition(
const ScrollbarLayerImplBase* scrollbar, const ScrollbarLayerImplBase* scrollbar,
const gfx::PointF pointer_position_in_widget) { const gfx::PointF pointer_position_in_widget) {
layer_tree_host_impl_->active_tree()->UpdateScrollbarGeometries(); const float pointer_delta =
if (SnapToDragOrigin(scrollbar, pointer_position_in_widget)) {
const float delta =
scrollbar->current_pos() - drag_state_->scroll_position_at_start_;
return scrollbar->orientation() == ScrollbarOrientation::VERTICAL
? gfx::ScrollOffset(0, -delta)
: gfx::ScrollOffset(-delta, 0);
}
const gfx::Rect thumb_rect(scrollbar->ComputeThumbQuadRect());
const gfx::PointF drag_position_relative_to_layer =
gfx::PointF(thumb_rect.origin()) + drag_state_->anchor_relative_to_thumb_;
bool clipped = false;
const gfx::PointF pointer_position_in_layer = GetScrollbarRelativePosition(
scrollbar, pointer_position_in_widget, &clipped);
if (clipped)
return gfx::ScrollOffset(0, 0);
// Calculate the delta based on the previously known thumb drag point.
const gfx::Vector2dF pointer_delta =
pointer_position_in_layer - drag_position_relative_to_layer;
float scaled_scroller_to_scrollbar_ratio =
GetScrollerToScrollbarRatio(scrollbar);
float current_scroll_position = scrollbar->current_pos();
// Thumb position needs to be floored and Values between 0 and 1 are rounded
// to one to match main thread per pixel behavior. Corresponding main thread
// code in ScrollbarTheme::ThumbPosition
float thumb_position = std::max(0.0f, current_scroll_position) /
scaled_scroller_to_scrollbar_ratio;
thumb_position = (thumb_position < 1.0 && thumb_position > 0.0)
? 1.0
: floorf(thumb_position);
float delta_in_orientation =
scrollbar->orientation() == ScrollbarOrientation::VERTICAL scrollbar->orientation() == ScrollbarOrientation::VERTICAL
? pointer_delta.y() ? pointer_position_in_widget.y() - drag_state_->drag_origin.y()
: pointer_delta.x(); : pointer_position_in_widget.x() - drag_state_->drag_origin.x();
// This is effectively equal to delta_in_orientation *
// scaled_scroller_to_scrollbar_ratio but is necessary due to truncated delta
// value. Floored thumb_position cancels out the rounding error introduced
// in pointer_delta due to static_cast<int> in
// ScrollbarLayerImplBase::ComputeThumbQuadRectWithThumbThicknessScale
float scroll_delta = (delta_in_orientation + thumb_position) *
scaled_scroller_to_scrollbar_ratio -
current_scroll_position;
gfx::ScrollOffset scaled_thumb_drag_delta; const float new_offset =
pointer_delta * GetScrollerToScrollbarRatio(scrollbar);
const float scroll_delta = drag_state_->scroll_position_at_start_ +
new_offset - scrollbar->current_pos();
// Scroll delta floored to match main thread per pixel behavior // Scroll delta floored to match main thread per pixel behavior
scrollbar->orientation() == ScrollbarOrientation::VERTICAL return scrollbar->orientation() == ScrollbarOrientation::VERTICAL
? scaled_thumb_drag_delta.set_y(floorf(scroll_delta)) ? gfx::ScrollOffset(0, floorf(scroll_delta))
: scaled_thumb_drag_delta.set_x(floorf(scroll_delta)); : gfx::ScrollOffset(floorf(scroll_delta), 0);
return scaled_thumb_drag_delta;
} }
// Performs hit test and prepares scroll deltas that will be used by GSU. // Performs hit test and prepares scroll deltas that will be used by GSU.
...@@ -338,6 +276,18 @@ InputHandlerPointerResult ScrollbarController::HandlePointerMove( ...@@ -338,6 +276,18 @@ InputHandlerPointerResult ScrollbarController::HandlePointerMove(
if (drag_processed_for_current_frame_) if (drag_processed_for_current_frame_)
return scroll_result; return scroll_result;
if (SnapToDragOrigin(scrollbar, position_in_widget)) {
const float delta =
scrollbar->current_pos() - drag_state_->scroll_position_at_start_;
scroll_result.scroll_units = ui::ScrollGranularity::kScrollByPrecisePixel;
scroll_result.scroll_offset =
scrollbar->orientation() == ScrollbarOrientation::VERTICAL
? gfx::ScrollOffset(0, -delta)
: gfx::ScrollOffset(-delta, 0);
drag_processed_for_current_frame_ = true;
return scroll_result;
}
// When initiating a thumb drag, a pointerdown and a pointermove can both // When initiating a thumb drag, a pointerdown and a pointermove can both
// arrive a the ScrollbarController in succession before a GSB would have // arrive a the ScrollbarController in succession before a GSB would have
// been dispatched. So, querying LayerTreeHostImpl::CurrentlyScrollingNode() // been dispatched. So, querying LayerTreeHostImpl::CurrentlyScrollingNode()
...@@ -354,7 +304,7 @@ InputHandlerPointerResult ScrollbarController::HandlePointerMove( ...@@ -354,7 +304,7 @@ InputHandlerPointerResult ScrollbarController::HandlePointerMove(
// If scroll_offset can't be consumed, there's no point in continuing on. // If scroll_offset can't be consumed, there's no point in continuing on.
const gfx::ScrollOffset scroll_offset( const gfx::ScrollOffset scroll_offset(
GetScrollOffsetForDragPosition(scrollbar, position_in_widget)); GetScrollDeltaForDragPosition(scrollbar, position_in_widget));
const gfx::Vector2dF clamped_scroll_offset( const gfx::Vector2dF clamped_scroll_offset(
layer_tree_host_impl_->ComputeScrollDelta( layer_tree_host_impl_->ComputeScrollDelta(
*target_node, ScrollOffsetToVector2dF(scroll_offset))); *target_node, ScrollOffsetToVector2dF(scroll_offset)));
......
...@@ -163,9 +163,8 @@ class CC_EXPORT ScrollbarController { ...@@ -163,9 +163,8 @@ class CC_EXPORT ScrollbarController {
}; };
struct CC_EXPORT DragState { struct CC_EXPORT DragState {
// This is used to track the pointer location relative to the thumb origin // This marks the point at which the drag initiated (relative to the widget)
// when a drag has started. gfx::PointF drag_origin;
gfx::Vector2dF anchor_relative_to_thumb_;
// This is needed for thumb snapping when the pointer moves too far away // This is needed for thumb snapping when the pointer moves too far away
// from the track while scrolling. // from the track while scrolling.
...@@ -233,16 +232,11 @@ class CC_EXPORT ScrollbarController { ...@@ -233,16 +232,11 @@ class CC_EXPORT ScrollbarController {
ui::ScrollGranularity Granularity(const ScrollbarPart scrollbar_part, ui::ScrollGranularity Granularity(const ScrollbarPart scrollbar_part,
bool shift_modifier); bool shift_modifier);
// Calculates the scroll_offset based on position_in_widget and // Calculates the scroll_offset based on position_in_widget and drag_origin.
// drag_anchor_relative_to_thumb_. gfx::ScrollOffset GetScrollDeltaForDragPosition(
gfx::ScrollOffset GetScrollOffsetForDragPosition(
const ScrollbarLayerImplBase* scrollbar, const ScrollbarLayerImplBase* scrollbar,
const gfx::PointF pointer_position_in_widget); const gfx::PointF pointer_position_in_widget);
// Returns a Vector2dF for position_in_widget relative to the scrollbar thumb.
gfx::Vector2dF GetThumbRelativePoint(const ScrollbarLayerImplBase* scrollbar,
const gfx::PointF position_in_widget);
// Returns the ratio of the scroller length to the scrollbar length. This is // Returns the ratio of the scroller length to the scrollbar length. This is
// needed to scale the scroll delta for thumb drag. // needed to scale the scroll delta for thumb drag.
float GetScrollerToScrollbarRatio(const ScrollbarLayerImplBase* scrollbar); float GetScrollerToScrollbarRatio(const ScrollbarLayerImplBase* scrollbar);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment