Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(42)

Side by Side Diff: third_party/WebKit/Source/core/input/ScrollManager.cpp

Issue 2907053004: GSB uses delta_hints to calculate scrolling chain. (Closed)
Patch Set: Merged with master. Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "core/input/ScrollManager.h" 5 #include "core/input/ScrollManager.h"
6 6
7 #include <memory> 7 #include <memory>
8 #include "core/dom/DOMNodeIds.h" 8 #include "core/dom/DOMNodeIds.h"
9 #include "core/events/GestureEvent.h" 9 #include "core/events/GestureEvent.h"
10 #include "core/frame/BrowserControls.h" 10 #include "core/frame/BrowserControls.h"
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 GetAutoscrollController()->MiddleClickAutoscrollInProgress(); 73 GetAutoscrollController()->MiddleClickAutoscrollInProgress();
74 } 74 }
75 75
76 AutoscrollController* ScrollManager::GetAutoscrollController() const { 76 AutoscrollController* ScrollManager::GetAutoscrollController() const {
77 if (Page* page = frame_->GetPage()) 77 if (Page* page = frame_->GetPage())
78 return &page->GetAutoscrollController(); 78 return &page->GetAutoscrollController();
79 return nullptr; 79 return nullptr;
80 } 80 }
81 81
82 void ScrollManager::RecomputeScrollChain(const Node& start_node, 82 void ScrollManager::RecomputeScrollChain(const Node& start_node,
83 const ScrollState& scroll_state,
83 std::deque<int>& scroll_chain) { 84 std::deque<int>& scroll_chain) {
85 DCHECK(!scroll_chain.size());
84 scroll_chain.clear(); 86 scroll_chain.clear();
85 87
86 DCHECK(start_node.GetLayoutObject()); 88 DCHECK(start_node.GetLayoutObject());
87 LayoutBox* cur_box = start_node.GetLayoutObject()->EnclosingBox(); 89 LayoutBox* cur_box = start_node.GetLayoutObject()->EnclosingBox();
88 Element* document_element = frame_->GetDocument()->documentElement(); 90 Element* document_element = frame_->GetDocument()->documentElement();
89 91
90 // Scrolling propagates along the containing block chain and ends at the 92 // Scrolling propagates along the containing block chain and ends at the
91 // RootScroller element. The RootScroller element will have a custom 93 // RootScroller element. The RootScroller element will have a custom
92 // applyScroll callback that scrolls the frame or element. 94 // applyScroll callback that scrolls the frame or element.
93 while (cur_box) { 95 while (cur_box) {
94 Node* cur_node = cur_box->GetNode(); 96 Node* cur_node = cur_box->GetNode();
95 Element* cur_element = nullptr; 97 Element* cur_element = nullptr;
96 98
97 // FIXME: this should reject more elements, as part of crbug.com/410974. 99 // FIXME: this should reject more elements, as part of crbug.com/410974.
98 if (cur_node && cur_node->IsElementNode()) { 100 if (cur_node && cur_node->IsElementNode()) {
99 cur_element = ToElement(cur_node); 101 cur_element = ToElement(cur_node);
100 } else if (cur_node && cur_node->IsDocumentNode()) { 102 } else if (cur_node && cur_node->IsDocumentNode()) {
101 // In normal circumastances, the documentElement will be the root 103 // In normal circumastances, the documentElement will be the root
102 // scroller but the documentElement itself isn't a containing block, 104 // scroller but the documentElement itself isn't a containing block,
103 // that'll be the document node rather than the element. 105 // that'll be the document node rather than the element.
104 cur_element = document_element; 106 cur_element = document_element;
105 } 107 }
106 108
107 if (cur_element) { 109 if (cur_element) {
108 scroll_chain.push_front(DOMNodeIds::IdForNode(cur_element)); 110 if (CanScroll(scroll_state, cur_element))
bokan 2017/06/19 21:43:17 Do we have to do this after we've added our first
sahel 2017/06/22 16:34:20 Once scroll latching is enabled, we can get rid of
bokan 2017/06/22 21:44:37 Right, but I don't mean making the chain just one
sahel 2017/06/23 18:22:03 When scroll latching is off, there will be one GSB
bokan 2017/06/23 18:56:44 Right, thanks for the explanation.
111 scroll_chain.push_front(DOMNodeIds::IdForNode(cur_element));
109 if (IsViewportScrollingElement(*cur_element) || 112 if (IsViewportScrollingElement(*cur_element) ||
110 cur_element == document_element) 113 cur_element == document_element)
111 break; 114 break;
112 } 115 }
113 116
114 cur_box = cur_box->ContainingBlock(); 117 cur_box = cur_box->ContainingBlock();
115 } 118 }
116 } 119 }
117 120
121 bool ScrollManager::CanScroll(const ScrollState& scroll_state,
122 const Element* current_element) {
123 const double delta_x = scroll_state.isBeginning() ? scroll_state.deltaXHint()
124 : scroll_state.deltaX();
125 const double delta_y = scroll_state.isBeginning() ? scroll_state.deltaYHint()
126 : scroll_state.deltaY();
127 if (!delta_x && !delta_y)
128 return true;
129
130 if (scroll_state.ignoreDeltaHints()) {
131 DCHECK(scroll_state.isBeginning());
132 return true;
133 }
134
135 DCHECK(current_element);
bokan 2017/06/19 21:43:17 Rather than DCHECK, just pass the Element by const
sahel 2017/06/22 16:34:18 Done.
136
137 if (IsViewportScrollingElement(*current_element))
138 return true;
139
140 if (current_element == frame_->GetDocument()->documentElement())
141 return true;
142
143 ScrollableArea* scrollable_area =
144 current_element->GetLayoutBox()
145 ? current_element->GetLayoutBox()->GetScrollableArea()
146 : nullptr;
147 if (!scrollable_area)
148 return false;
149
150 ScrollOffset current_offset = scrollable_area->GetScrollOffset();
151 ScrollOffset target_offset = current_offset + ScrollOffset(delta_x, delta_y);
152 ScrollOffset clamped_offset =
153 scrollable_area->ClampScrollOffset(target_offset);
154 return clamped_offset != current_offset;
155 }
156
118 bool ScrollManager::LogicalScroll(ScrollDirection direction, 157 bool ScrollManager::LogicalScroll(ScrollDirection direction,
119 ScrollGranularity granularity, 158 ScrollGranularity granularity,
120 Node* start_node, 159 Node* start_node,
121 Node* mouse_press_node) { 160 Node* mouse_press_node) {
122 Node* node = start_node; 161 Node* node = start_node;
123 162
124 if (!node) 163 if (!node)
125 node = frame_->GetDocument()->FocusedElement(); 164 node = frame_->GetDocument()->FocusedElement();
126 165
127 if (!node) 166 if (!node)
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
177 return ToLocalFrame(parent_frame) 216 return ToLocalFrame(parent_frame)
178 ->GetEventHandler() 217 ->GetEventHandler()
179 .BubblingScroll(direction, granularity, frame_->DeprecatedLocalOwner()); 218 .BubblingScroll(direction, granularity, frame_->DeprecatedLocalOwner());
180 } 219 }
181 220
182 void ScrollManager::SetFrameWasScrolledByUser() { 221 void ScrollManager::SetFrameWasScrolledByUser() {
183 if (DocumentLoader* document_loader = frame_->Loader().GetDocumentLoader()) 222 if (DocumentLoader* document_loader = frame_->Loader().GetDocumentLoader())
184 document_loader->GetInitialScrollState().was_scrolled_by_user = true; 223 document_loader->GetInitialScrollState().was_scrolled_by_user = true;
185 } 224 }
186 225
187 void ScrollManager::CustomizedScroll(const Node& start_node, 226 void ScrollManager::CustomizedScroll(ScrollState& scroll_state) {
188 ScrollState& scroll_state) {
189 if (scroll_state.FullyConsumed()) 227 if (scroll_state.FullyConsumed())
190 return; 228 return;
191 229
192 if (scroll_state.deltaX() || scroll_state.deltaY()) 230 if (scroll_state.deltaX() || scroll_state.deltaY())
193 frame_->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets(); 231 frame_->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
194 232
195 if (current_scroll_chain_.empty()) 233 DCHECK(!current_scroll_chain_.empty());
196 RecomputeScrollChain(start_node, current_scroll_chain_);
197 scroll_state.SetScrollChain(current_scroll_chain_); 234 scroll_state.SetScrollChain(current_scroll_chain_);
198 235
199 scroll_state.distributeToScrollChainDescendant(); 236 scroll_state.distributeToScrollChainDescendant();
200 } 237 }
201 238
202 void ScrollManager::ComputeScrollRelatedMetrics( 239 void ScrollManager::ComputeScrollRelatedMetrics(
203 uint32_t* non_composited_main_thread_scrolling_reasons, 240 uint32_t* non_composited_main_thread_scrolling_reasons,
204 int* scroller_size, 241 int* scroller_size,
205 bool* scroller_size_updated) { 242 bool* scroller_size_updated) {
206 // When scrolling on the main thread, the scrollableArea may or may not be 243 // When scrolling on the main thread, the scrollableArea may or may not be
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
311 scroll_gesture_handling_node_->GetLayoutObject()); 348 scroll_gesture_handling_node_->GetLayoutObject());
312 349
313 RecordScrollRelatedMetrics(gesture_event.source_device); 350 RecordScrollRelatedMetrics(gesture_event.source_device);
314 351
315 current_scroll_chain_.clear(); 352 current_scroll_chain_.clear();
316 std::unique_ptr<ScrollStateData> scroll_state_data = 353 std::unique_ptr<ScrollStateData> scroll_state_data =
317 WTF::MakeUnique<ScrollStateData>(); 354 WTF::MakeUnique<ScrollStateData>();
318 IntPoint position = FlooredIntPoint(gesture_event.PositionInRootFrame()); 355 IntPoint position = FlooredIntPoint(gesture_event.PositionInRootFrame());
319 scroll_state_data->position_x = position.X(); 356 scroll_state_data->position_x = position.X();
320 scroll_state_data->position_y = position.Y(); 357 scroll_state_data->position_y = position.Y();
358 scroll_state_data->delta_x_hint = -gesture_event.DeltaXInRootFrame();
359 scroll_state_data->delta_y_hint = -gesture_event.DeltaYInRootFrame();
360 scroll_state_data->ignore_delta_hints =
361 gesture_event.data.scroll_begin.ignore_delta_hints;
321 scroll_state_data->is_beginning = true; 362 scroll_state_data->is_beginning = true;
322 scroll_state_data->from_user_input = true; 363 scroll_state_data->from_user_input = true;
323 scroll_state_data->is_direct_manipulation = 364 scroll_state_data->is_direct_manipulation =
324 gesture_event.source_device == kWebGestureDeviceTouchscreen; 365 gesture_event.source_device == kWebGestureDeviceTouchscreen;
325 scroll_state_data->delta_consumed_for_scroll_sequence = 366 scroll_state_data->delta_consumed_for_scroll_sequence =
326 delta_consumed_for_scroll_sequence_; 367 delta_consumed_for_scroll_sequence_;
327 ScrollState* scroll_state = ScrollState::Create(std::move(scroll_state_data)); 368 ScrollState* scroll_state = ScrollState::Create(std::move(scroll_state_data));
328 CustomizedScroll(*scroll_gesture_handling_node_.Get(), *scroll_state); 369 RecomputeScrollChain(*scroll_gesture_handling_node_.Get(), *scroll_state,
370 current_scroll_chain_);
371 if (current_scroll_chain_.empty()) {
bokan 2017/06/19 21:43:17 Nit: no {}
sahel 2017/06/22 16:34:18 Done.
372 return WebInputEventResult::kNotHandled;
373 }
374 CustomizedScroll(*scroll_state);
329 375
330 if (gesture_event.source_device == kWebGestureDeviceTouchscreen) 376 if (gesture_event.source_device == kWebGestureDeviceTouchscreen)
331 UseCounter::Count(frame_->GetDocument(), WebFeature::kScrollByTouch); 377 UseCounter::Count(frame_->GetDocument(), WebFeature::kScrollByTouch);
332 else 378 else
333 UseCounter::Count(frame_->GetDocument(), WebFeature::kScrollByWheel); 379 UseCounter::Count(frame_->GetDocument(), WebFeature::kScrollByWheel);
334 380
335 return WebInputEventResult::kHandledSystem; 381 return WebInputEventResult::kHandledSystem;
336 } 382 }
337 383
338 WebInputEventResult ScrollManager::HandleGestureScrollUpdate( 384 WebInputEventResult ScrollManager::HandleGestureScrollUpdate(
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 delta_consumed_for_scroll_sequence_; 433 delta_consumed_for_scroll_sequence_;
388 ScrollState* scroll_state = ScrollState::Create(std::move(scroll_state_data)); 434 ScrollState* scroll_state = ScrollState::Create(std::move(scroll_state_data));
389 if (previous_gesture_scrolled_element_) { 435 if (previous_gesture_scrolled_element_) {
390 // The ScrollState needs to know what the current 436 // The ScrollState needs to know what the current
391 // native scrolling element is, so that for an 437 // native scrolling element is, so that for an
392 // inertial scroll that shouldn't propagate, only the 438 // inertial scroll that shouldn't propagate, only the
393 // currently scrolling element responds. 439 // currently scrolling element responds.
394 scroll_state->SetCurrentNativeScrollingElement( 440 scroll_state->SetCurrentNativeScrollingElement(
395 previous_gesture_scrolled_element_); 441 previous_gesture_scrolled_element_);
396 } 442 }
397 CustomizedScroll(*node, *scroll_state); 443
444 if (current_scroll_chain_.empty())
bokan 2017/06/19 21:43:17 We can early out before creating and initializing
sahel 2017/06/22 16:34:19 Done.
445 return WebInputEventResult::kNotHandled;
446
447 CustomizedScroll(*scroll_state);
398 previous_gesture_scrolled_element_ = 448 previous_gesture_scrolled_element_ =
399 scroll_state->CurrentNativeScrollingElement(); 449 scroll_state->CurrentNativeScrollingElement();
400 delta_consumed_for_scroll_sequence_ = 450 delta_consumed_for_scroll_sequence_ =
401 scroll_state->DeltaConsumedForScrollSequence(); 451 scroll_state->DeltaConsumedForScrollSequence();
402 452
403 bool did_scroll_x = scroll_state->deltaX() != delta.Width(); 453 bool did_scroll_x = scroll_state->deltaX() != delta.Width();
404 bool did_scroll_y = scroll_state->deltaY() != delta.Height(); 454 bool did_scroll_y = scroll_state->deltaY() != delta.Height();
405 455
406 if ((!previous_gesture_scrolled_element_ || 456 if ((!previous_gesture_scrolled_element_ ||
407 !IsViewportScrollingElement(*previous_gesture_scrolled_element_)) && 457 !IsViewportScrollingElement(*previous_gesture_scrolled_element_)) &&
(...skipping 20 matching lines...) Expand all
428 scroll_state_data->is_ending = true; 478 scroll_state_data->is_ending = true;
429 scroll_state_data->is_in_inertial_phase = 479 scroll_state_data->is_in_inertial_phase =
430 gesture_event.InertialPhase() == WebGestureEvent::kMomentumPhase; 480 gesture_event.InertialPhase() == WebGestureEvent::kMomentumPhase;
431 scroll_state_data->from_user_input = true; 481 scroll_state_data->from_user_input = true;
432 scroll_state_data->is_direct_manipulation = 482 scroll_state_data->is_direct_manipulation =
433 gesture_event.source_device == kWebGestureDeviceTouchscreen; 483 gesture_event.source_device == kWebGestureDeviceTouchscreen;
434 scroll_state_data->delta_consumed_for_scroll_sequence = 484 scroll_state_data->delta_consumed_for_scroll_sequence =
435 delta_consumed_for_scroll_sequence_; 485 delta_consumed_for_scroll_sequence_;
436 ScrollState* scroll_state = 486 ScrollState* scroll_state =
437 ScrollState::Create(std::move(scroll_state_data)); 487 ScrollState::Create(std::move(scroll_state_data));
438 CustomizedScroll(*node, *scroll_state); 488 if (!current_scroll_chain_.empty())
bokan 2017/06/19 21:43:17 We should skip the scroll_state_data initializatio
sahel 2017/06/22 16:34:18 Done.
489 CustomizedScroll(*scroll_state);
439 } 490 }
440 491
441 ClearGestureScrollState(); 492 ClearGestureScrollState();
442 return WebInputEventResult::kNotHandled; 493 return WebInputEventResult::kNotHandled;
443 } 494 }
444 495
445 Page* ScrollManager::GetPage() const { 496 Page* ScrollManager::GetPage() const {
446 return frame_->GetPage(); 497 return frame_->GetPage();
447 } 498 }
448 499
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
656 &should_update_capture)) { 707 &should_update_capture)) {
657 if (should_update_capture) 708 if (should_update_capture)
658 scrollbar_handling_scroll_gesture_ = scrollbar; 709 scrollbar_handling_scroll_gesture_ = scrollbar;
659 return true; 710 return true;
660 } 711 }
661 } 712 }
662 return false; 713 return false;
663 } 714 }
664 715
665 } // namespace blink 716 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698