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

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: review comments addressed. 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 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
78 GetAutoscrollController()->MiddleClickAutoscrollInProgress(); 78 GetAutoscrollController()->MiddleClickAutoscrollInProgress();
79 } 79 }
80 80
81 AutoscrollController* ScrollManager::GetAutoscrollController() const { 81 AutoscrollController* ScrollManager::GetAutoscrollController() const {
82 if (Page* page = frame_->GetPage()) 82 if (Page* page = frame_->GetPage())
83 return &page->GetAutoscrollController(); 83 return &page->GetAutoscrollController();
84 return nullptr; 84 return nullptr;
85 } 85 }
86 86
87 void ScrollManager::RecomputeScrollChain(const Node& start_node, 87 void ScrollManager::RecomputeScrollChain(const Node& start_node,
88 const ScrollState& scroll_state,
88 std::deque<int>& scroll_chain) { 89 std::deque<int>& scroll_chain) {
90 DCHECK(!scroll_chain.size());
89 scroll_chain.clear(); 91 scroll_chain.clear();
90 92
91 DCHECK(start_node.GetLayoutObject()); 93 DCHECK(start_node.GetLayoutObject());
92 LayoutBox* cur_box = start_node.GetLayoutObject()->EnclosingBox(); 94 LayoutBox* cur_box = start_node.GetLayoutObject()->EnclosingBox();
93 Element* document_element = frame_->GetDocument()->documentElement(); 95 Element* document_element = frame_->GetDocument()->documentElement();
94 96
95 // Scrolling propagates along the containing block chain and ends at the 97 // Scrolling propagates along the containing block chain and ends at the
96 // RootScroller element. The RootScroller element will have a custom 98 // RootScroller element. The RootScroller element will have a custom
97 // applyScroll callback that scrolls the frame or element. 99 // applyScroll callback that scrolls the frame or element.
98 while (cur_box) { 100 while (cur_box) {
99 Node* cur_node = cur_box->GetNode(); 101 Node* cur_node = cur_box->GetNode();
100 Element* cur_element = nullptr; 102 Element* cur_element = nullptr;
101 103
102 // FIXME: this should reject more elements, as part of crbug.com/410974. 104 // FIXME: this should reject more elements, as part of crbug.com/410974.
103 if (cur_node && cur_node->IsElementNode()) { 105 if (cur_node && cur_node->IsElementNode()) {
104 cur_element = ToElement(cur_node); 106 cur_element = ToElement(cur_node);
105 } else if (cur_node && cur_node->IsDocumentNode()) { 107 } else if (cur_node && cur_node->IsDocumentNode()) {
106 // In normal circumastances, the documentElement will be the root 108 // In normal circumastances, the documentElement will be the root
107 // scroller but the documentElement itself isn't a containing block, 109 // scroller but the documentElement itself isn't a containing block,
108 // that'll be the document node rather than the element. 110 // that'll be the document node rather than the element.
109 cur_element = document_element; 111 cur_element = document_element;
110 } 112 }
111 113
112 if (cur_element) { 114 if (cur_element) {
113 scroll_chain.push_front(DOMNodeIds::IdForNode(cur_element)); 115 if (CanScroll(scroll_state, *cur_element))
116 scroll_chain.push_front(DOMNodeIds::IdForNode(cur_element));
114 if (IsViewportScrollingElement(*cur_element) || 117 if (IsViewportScrollingElement(*cur_element) ||
115 cur_element == document_element) 118 cur_element == document_element)
116 break; 119 break;
117 } 120 }
118 121
119 cur_box = cur_box->ContainingBlock(); 122 cur_box = cur_box->ContainingBlock();
120 } 123 }
121 } 124 }
122 125
126 bool ScrollManager::CanScroll(const ScrollState& scroll_state,
127 const Element& current_element) {
128 const double delta_x = scroll_state.isBeginning() ? scroll_state.deltaXHint()
129 : scroll_state.deltaX();
130 const double delta_y = scroll_state.isBeginning() ? scroll_state.deltaYHint()
131 : scroll_state.deltaY();
132 if (!delta_x && !delta_y)
133 return true;
134
135 if (scroll_state.ignoreDeltaHints()) {
136 DCHECK(scroll_state.isBeginning());
137 return true;
138 }
139
140 if (IsViewportScrollingElement(current_element))
141 return true;
142
143 if (current_element == *(frame_->GetDocument()->documentElement()))
144 return true;
145
146 ScrollableArea* scrollable_area =
147 current_element.GetLayoutBox()
148 ? current_element.GetLayoutBox()->GetScrollableArea()
149 : nullptr;
150 if (!scrollable_area)
151 return false;
152
153 ScrollOffset current_offset = scrollable_area->GetScrollOffset();
154 ScrollOffset target_offset = current_offset + ScrollOffset(delta_x, delta_y);
155 ScrollOffset clamped_offset =
156 scrollable_area->ClampScrollOffset(target_offset);
157 return clamped_offset != current_offset;
158 }
159
123 bool ScrollManager::LogicalScroll(ScrollDirection direction, 160 bool ScrollManager::LogicalScroll(ScrollDirection direction,
124 ScrollGranularity granularity, 161 ScrollGranularity granularity,
125 Node* start_node, 162 Node* start_node,
126 Node* mouse_press_node) { 163 Node* mouse_press_node) {
127 Node* node = start_node; 164 Node* node = start_node;
128 165
129 if (!node) 166 if (!node)
130 node = frame_->GetDocument()->FocusedElement(); 167 node = frame_->GetDocument()->FocusedElement();
131 168
132 if (!node) 169 if (!node)
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 return ToLocalFrame(parent_frame) 219 return ToLocalFrame(parent_frame)
183 ->GetEventHandler() 220 ->GetEventHandler()
184 .BubblingScroll(direction, granularity, frame_->DeprecatedLocalOwner()); 221 .BubblingScroll(direction, granularity, frame_->DeprecatedLocalOwner());
185 } 222 }
186 223
187 void ScrollManager::SetFrameWasScrolledByUser() { 224 void ScrollManager::SetFrameWasScrolledByUser() {
188 if (DocumentLoader* document_loader = frame_->Loader().GetDocumentLoader()) 225 if (DocumentLoader* document_loader = frame_->Loader().GetDocumentLoader())
189 document_loader->GetInitialScrollState().was_scrolled_by_user = true; 226 document_loader->GetInitialScrollState().was_scrolled_by_user = true;
190 } 227 }
191 228
192 void ScrollManager::CustomizedScroll(const Node& start_node, 229 void ScrollManager::CustomizedScroll(ScrollState& scroll_state) {
193 ScrollState& scroll_state) {
194 if (scroll_state.FullyConsumed()) 230 if (scroll_state.FullyConsumed())
195 return; 231 return;
196 232
197 if (scroll_state.deltaX() || scroll_state.deltaY()) 233 if (scroll_state.deltaX() || scroll_state.deltaY())
198 frame_->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets(); 234 frame_->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
199 235
200 if (current_scroll_chain_.empty()) 236 DCHECK(!current_scroll_chain_.empty());
201 RecomputeScrollChain(start_node, current_scroll_chain_);
202 scroll_state.SetScrollChain(current_scroll_chain_); 237 scroll_state.SetScrollChain(current_scroll_chain_);
203 238
204 scroll_state.distributeToScrollChainDescendant(); 239 scroll_state.distributeToScrollChainDescendant();
205 } 240 }
206 241
207 void ScrollManager::ComputeScrollRelatedMetrics( 242 void ScrollManager::ComputeScrollRelatedMetrics(
208 uint32_t* non_composited_main_thread_scrolling_reasons, 243 uint32_t* non_composited_main_thread_scrolling_reasons,
209 int* scroller_size, 244 int* scroller_size,
210 bool* scroller_size_updated) { 245 bool* scroller_size_updated) {
211 // When scrolling on the main thread, the scrollableArea may or may not be 246 // 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
316 scroll_gesture_handling_node_->GetLayoutObject()); 351 scroll_gesture_handling_node_->GetLayoutObject());
317 352
318 RecordScrollRelatedMetrics(gesture_event.source_device); 353 RecordScrollRelatedMetrics(gesture_event.source_device);
319 354
320 current_scroll_chain_.clear(); 355 current_scroll_chain_.clear();
321 std::unique_ptr<ScrollStateData> scroll_state_data = 356 std::unique_ptr<ScrollStateData> scroll_state_data =
322 WTF::MakeUnique<ScrollStateData>(); 357 WTF::MakeUnique<ScrollStateData>();
323 IntPoint position = FlooredIntPoint(gesture_event.PositionInRootFrame()); 358 IntPoint position = FlooredIntPoint(gesture_event.PositionInRootFrame());
324 scroll_state_data->position_x = position.X(); 359 scroll_state_data->position_x = position.X();
325 scroll_state_data->position_y = position.Y(); 360 scroll_state_data->position_y = position.Y();
361 scroll_state_data->delta_x_hint = -gesture_event.DeltaXInRootFrame();
362 scroll_state_data->delta_y_hint = -gesture_event.DeltaYInRootFrame();
363 scroll_state_data->ignore_delta_hints =
364 gesture_event.data.scroll_begin.ignore_delta_hints;
326 scroll_state_data->is_beginning = true; 365 scroll_state_data->is_beginning = true;
327 scroll_state_data->from_user_input = true; 366 scroll_state_data->from_user_input = true;
328 scroll_state_data->is_direct_manipulation = 367 scroll_state_data->is_direct_manipulation =
329 gesture_event.source_device == kWebGestureDeviceTouchscreen; 368 gesture_event.source_device == kWebGestureDeviceTouchscreen;
330 scroll_state_data->delta_consumed_for_scroll_sequence = 369 scroll_state_data->delta_consumed_for_scroll_sequence =
331 delta_consumed_for_scroll_sequence_; 370 delta_consumed_for_scroll_sequence_;
332 ScrollState* scroll_state = ScrollState::Create(std::move(scroll_state_data)); 371 ScrollState* scroll_state = ScrollState::Create(std::move(scroll_state_data));
333 CustomizedScroll(*scroll_gesture_handling_node_.Get(), *scroll_state); 372 RecomputeScrollChain(*scroll_gesture_handling_node_.Get(), *scroll_state,
373 current_scroll_chain_);
374 if (current_scroll_chain_.empty())
375 return WebInputEventResult::kNotHandled;
376
377 CustomizedScroll(*scroll_state);
334 378
335 if (gesture_event.source_device == kWebGestureDeviceTouchscreen) 379 if (gesture_event.source_device == kWebGestureDeviceTouchscreen)
336 UseCounter::Count(frame_->GetDocument(), WebFeature::kScrollByTouch); 380 UseCounter::Count(frame_->GetDocument(), WebFeature::kScrollByTouch);
337 else 381 else
338 UseCounter::Count(frame_->GetDocument(), WebFeature::kScrollByWheel); 382 UseCounter::Count(frame_->GetDocument(), WebFeature::kScrollByWheel);
339 383
340 return WebInputEventResult::kHandledSystem; 384 return WebInputEventResult::kHandledSystem;
341 } 385 }
342 386
343 WebInputEventResult ScrollManager::HandleGestureScrollUpdate( 387 WebInputEventResult ScrollManager::HandleGestureScrollUpdate(
(...skipping 21 matching lines...) Expand all
365 // Try to send the event to the correct view. 409 // Try to send the event to the correct view.
366 WebInputEventResult result = 410 WebInputEventResult result =
367 PassScrollGestureEvent(gesture_event, layout_object); 411 PassScrollGestureEvent(gesture_event, layout_object);
368 if (result != WebInputEventResult::kNotHandled) { 412 if (result != WebInputEventResult::kNotHandled) {
369 // FIXME: we should allow simultaneous scrolling of nested 413 // FIXME: we should allow simultaneous scrolling of nested
370 // iframes along perpendicular axes. See crbug.com/466991. 414 // iframes along perpendicular axes. See crbug.com/466991.
371 delta_consumed_for_scroll_sequence_ = true; 415 delta_consumed_for_scroll_sequence_ = true;
372 return result; 416 return result;
373 } 417 }
374 418
419 if (current_scroll_chain_.empty())
420 return WebInputEventResult::kNotHandled;
421
375 std::unique_ptr<ScrollStateData> scroll_state_data = 422 std::unique_ptr<ScrollStateData> scroll_state_data =
376 WTF::MakeUnique<ScrollStateData>(); 423 WTF::MakeUnique<ScrollStateData>();
377 scroll_state_data->delta_x = delta.Width(); 424 scroll_state_data->delta_x = delta.Width();
378 scroll_state_data->delta_y = delta.Height(); 425 scroll_state_data->delta_y = delta.Height();
379 scroll_state_data->delta_granularity = static_cast<double>( 426 scroll_state_data->delta_granularity = static_cast<double>(
380 ToPlatformScrollGranularity(gesture_event.DeltaUnits())); 427 ToPlatformScrollGranularity(gesture_event.DeltaUnits()));
381 scroll_state_data->velocity_x = velocity.Width(); 428 scroll_state_data->velocity_x = velocity.Width();
382 scroll_state_data->velocity_y = velocity.Height(); 429 scroll_state_data->velocity_y = velocity.Height();
383 scroll_state_data->position_x = position.X(); 430 scroll_state_data->position_x = position.X();
384 scroll_state_data->position_y = position.Y(); 431 scroll_state_data->position_y = position.Y();
385 scroll_state_data->should_propagate = !gesture_event.PreventPropagation(); 432 scroll_state_data->should_propagate = !gesture_event.PreventPropagation();
386 scroll_state_data->is_in_inertial_phase = 433 scroll_state_data->is_in_inertial_phase =
387 gesture_event.InertialPhase() == WebGestureEvent::kMomentumPhase; 434 gesture_event.InertialPhase() == WebGestureEvent::kMomentumPhase;
388 scroll_state_data->is_direct_manipulation = 435 scroll_state_data->is_direct_manipulation =
389 gesture_event.source_device == kWebGestureDeviceTouchscreen; 436 gesture_event.source_device == kWebGestureDeviceTouchscreen;
390 scroll_state_data->from_user_input = true; 437 scroll_state_data->from_user_input = true;
391 scroll_state_data->delta_consumed_for_scroll_sequence = 438 scroll_state_data->delta_consumed_for_scroll_sequence =
392 delta_consumed_for_scroll_sequence_; 439 delta_consumed_for_scroll_sequence_;
393 ScrollState* scroll_state = ScrollState::Create(std::move(scroll_state_data)); 440 ScrollState* scroll_state = ScrollState::Create(std::move(scroll_state_data));
394 if (previous_gesture_scrolled_element_) { 441 if (previous_gesture_scrolled_element_) {
395 // The ScrollState needs to know what the current 442 // The ScrollState needs to know what the current
396 // native scrolling element is, so that for an 443 // native scrolling element is, so that for an
397 // inertial scroll that shouldn't propagate, only the 444 // inertial scroll that shouldn't propagate, only the
398 // currently scrolling element responds. 445 // currently scrolling element responds.
399 scroll_state->SetCurrentNativeScrollingElement( 446 scroll_state->SetCurrentNativeScrollingElement(
400 previous_gesture_scrolled_element_); 447 previous_gesture_scrolled_element_);
401 } 448 }
402 CustomizedScroll(*node, *scroll_state); 449
450 CustomizedScroll(*scroll_state);
403 previous_gesture_scrolled_element_ = 451 previous_gesture_scrolled_element_ =
404 scroll_state->CurrentNativeScrollingElement(); 452 scroll_state->CurrentNativeScrollingElement();
405 delta_consumed_for_scroll_sequence_ = 453 delta_consumed_for_scroll_sequence_ =
406 scroll_state->DeltaConsumedForScrollSequence(); 454 scroll_state->DeltaConsumedForScrollSequence();
407 455
408 bool did_scroll_x = scroll_state->deltaX() != delta.Width(); 456 bool did_scroll_x = scroll_state->deltaX() != delta.Width();
409 bool did_scroll_y = scroll_state->deltaY() != delta.Height(); 457 bool did_scroll_y = scroll_state->deltaY() != delta.Height();
410 458
411 if ((!previous_gesture_scrolled_element_ || 459 if ((!previous_gesture_scrolled_element_ ||
412 !IsViewportScrollingElement(*previous_gesture_scrolled_element_)) && 460 !IsViewportScrollingElement(*previous_gesture_scrolled_element_)) &&
413 GetPage()) 461 GetPage())
414 GetPage()->GetOverscrollController().ResetAccumulated(did_scroll_x, 462 GetPage()->GetOverscrollController().ResetAccumulated(did_scroll_x,
415 did_scroll_y); 463 did_scroll_y);
416 464
417 if (did_scroll_x || did_scroll_y) { 465 if (did_scroll_x || did_scroll_y) {
418 SetFrameWasScrolledByUser(); 466 SetFrameWasScrolledByUser();
419 return WebInputEventResult::kHandledSystem; 467 return WebInputEventResult::kHandledSystem;
420 } 468 }
421 469
422 return WebInputEventResult::kNotHandled; 470 return WebInputEventResult::kNotHandled;
423 } 471 }
424 472
425 WebInputEventResult ScrollManager::HandleGestureScrollEnd( 473 WebInputEventResult ScrollManager::HandleGestureScrollEnd(
426 const WebGestureEvent& gesture_event) { 474 const WebGestureEvent& gesture_event) {
427 Node* node = scroll_gesture_handling_node_; 475 Node* node = scroll_gesture_handling_node_;
428 476
429 if (node && node->GetLayoutObject()) { 477 if (node && node->GetLayoutObject()) {
430 PassScrollGestureEvent(gesture_event, node->GetLayoutObject()); 478 PassScrollGestureEvent(gesture_event, node->GetLayoutObject());
479 if (current_scroll_chain_.empty()) {
480 ClearGestureScrollState();
481 return WebInputEventResult::kNotHandled;
482 }
431 std::unique_ptr<ScrollStateData> scroll_state_data = 483 std::unique_ptr<ScrollStateData> scroll_state_data =
432 WTF::MakeUnique<ScrollStateData>(); 484 WTF::MakeUnique<ScrollStateData>();
433 scroll_state_data->is_ending = true; 485 scroll_state_data->is_ending = true;
434 scroll_state_data->is_in_inertial_phase = 486 scroll_state_data->is_in_inertial_phase =
435 gesture_event.InertialPhase() == WebGestureEvent::kMomentumPhase; 487 gesture_event.InertialPhase() == WebGestureEvent::kMomentumPhase;
436 scroll_state_data->from_user_input = true; 488 scroll_state_data->from_user_input = true;
437 scroll_state_data->is_direct_manipulation = 489 scroll_state_data->is_direct_manipulation =
438 gesture_event.source_device == kWebGestureDeviceTouchscreen; 490 gesture_event.source_device == kWebGestureDeviceTouchscreen;
439 scroll_state_data->delta_consumed_for_scroll_sequence = 491 scroll_state_data->delta_consumed_for_scroll_sequence =
440 delta_consumed_for_scroll_sequence_; 492 delta_consumed_for_scroll_sequence_;
441 ScrollState* scroll_state = 493 ScrollState* scroll_state =
442 ScrollState::Create(std::move(scroll_state_data)); 494 ScrollState::Create(std::move(scroll_state_data));
443 CustomizedScroll(*node, *scroll_state); 495 CustomizedScroll(*scroll_state);
444 } 496 }
445 497
446 ClearGestureScrollState(); 498 ClearGestureScrollState();
447 return WebInputEventResult::kNotHandled; 499 return WebInputEventResult::kNotHandled;
448 } 500 }
449 501
450 Page* ScrollManager::GetPage() const { 502 Page* ScrollManager::GetPage() const {
451 return frame_->GetPage(); 503 return frame_->GetPage();
452 } 504 }
453 505
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
661 &should_update_capture)) { 713 &should_update_capture)) {
662 if (should_update_capture) 714 if (should_update_capture)
663 scrollbar_handling_scroll_gesture_ = scrollbar; 715 scrollbar_handling_scroll_gesture_ = scrollbar;
664 return true; 716 return true;
665 } 717 }
666 } 718 }
667 return false; 719 return false;
668 } 720 }
669 721
670 } // namespace blink 722 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698