Chromium Code Reviews| Index: third_party/WebKit/Source/core/input/MouseWheelEventManager.cpp |
| diff --git a/third_party/WebKit/Source/core/input/MouseWheelEventManager.cpp b/third_party/WebKit/Source/core/input/MouseWheelEventManager.cpp |
| index e830907851620108275d6043da95b7b8d3ed2e5f..b8c8a1f74724505821125a327486260c49ddf4ea 100644 |
| --- a/third_party/WebKit/Source/core/input/MouseWheelEventManager.cpp |
| +++ b/third_party/WebKit/Source/core/input/MouseWheelEventManager.cpp |
| @@ -18,54 +18,111 @@ |
| namespace blink { |
| MouseWheelEventManager::MouseWheelEventManager(LocalFrame& frame, |
| ScrollManager& scroll_manager) |
| - : frame_(frame), scroll_manager_(scroll_manager) {} |
| + : frame_(frame), wheel_target_(nullptr), scroll_manager_(scroll_manager) {} |
| DEFINE_TRACE(MouseWheelEventManager) { |
| visitor->Trace(frame_); |
| + visitor->Trace(wheel_target_); |
| visitor->Trace(scroll_manager_); |
| } |
| +void MouseWheelEventManager::Clear() { |
| + wheel_target_ = nullptr; |
| +} |
| + |
| WebInputEventResult MouseWheelEventManager::HandleWheelEvent( |
| const WebMouseWheelEvent& event) { |
| + bool wheel_scroll_latching = |
| + RuntimeEnabledFeatures::TouchpadAndWheelScrollLatchingEnabled(); |
| + |
| + if (wheel_scroll_latching) { |
| + const int kWheelEventPhaseNoEventMask = |
| + WebMouseWheelEvent::kPhaseEnded | WebMouseWheelEvent::kPhaseCancelled | |
| + WebMouseWheelEvent::kPhaseMayBegin; |
|
bokan
2017/06/15 15:47:18
Do we really need to clear the target on MayBegin?
sahel
2017/06/16 14:56:20
Done.
|
| + |
| + if ((event.phase & kWheelEventPhaseNoEventMask) || |
| + (event.momentum_phase & kWheelEventPhaseNoEventMask)) { |
| + // Filter wheel events with zero deltas and reset the wheel_target_ node. |
| + DCHECK(!event.delta_x && !event.delta_y); |
| + wheel_target_ = nullptr; |
| + return WebInputEventResult::kNotHandled; |
| + } |
| + |
| + if (event.phase == WebMouseWheelEvent::kPhaseBegan) { |
| + // Find and save the wheel_target_, this target will be used for the rest |
| + // of the current scrolling sequence. |
| + DCHECK(!wheel_target_); |
| + Document* doc = frame_->GetDocument(); |
| + |
| + if (doc->GetLayoutViewItem().IsNull()) |
| + return WebInputEventResult::kNotHandled; |
| + |
| + LocalFrameView* view = frame_->View(); |
| + if (!view) |
| + return WebInputEventResult::kNotHandled; |
|
bokan
2017/06/15 15:47:18
Add the early out at the top of the method if ther
sahel
2017/06/16 14:56:20
Done.
|
| + |
| + LayoutPoint v_point = view->RootFrameToContents( |
| + FlooredIntPoint(event.PositionInRootFrame())); |
| + |
| + HitTestRequest request(HitTestRequest::kReadOnly); |
| + HitTestResult result(request, v_point); |
| + doc->GetLayoutViewItem().HitTest(result); |
| + |
| + wheel_target_ = result.InnerNode(); |
| + // Wheel events should not dispatch to text nodes. |
| + if (wheel_target_ && wheel_target_->IsTextNode()) |
| + wheel_target_ = FlatTreeTraversal::Parent(*wheel_target_); |
| + |
| + // If we're over the frame scrollbar, scroll the document. |
| + if (!wheel_target_ && result.GetScrollbar()) |
| + wheel_target_ = doc->documentElement(); |
| + } |
| + } else { // !wheel_scroll_latching, wheel_target_ will be updated for each |
| + // wheel event. |
| #if OS(MACOSX) |
| - // Filter Mac OS specific phases, usually with a zero-delta. |
| - // https://crbug.com/553732 |
| - // TODO(chongz): EventSender sends events with |
| - // |WebMouseWheelEvent::PhaseNone|, |
| - // but it shouldn't. |
| - const int kWheelEventPhaseNoEventMask = WebMouseWheelEvent::kPhaseEnded | |
| - WebMouseWheelEvent::kPhaseCancelled | |
| - WebMouseWheelEvent::kPhaseMayBegin; |
| - if ((event.phase & kWheelEventPhaseNoEventMask) || |
| - (event.momentum_phase & kWheelEventPhaseNoEventMask)) |
| - return WebInputEventResult::kNotHandled; |
| + // Filter Mac OS specific phases, usually with a zero-delta. |
| + // https://crbug.com/553732 |
| + // TODO(chongz): EventSender sends events with |
| + // |WebMouseWheelEvent::PhaseNone|, |
| + // but it shouldn't. |
| + const int kWheelEventPhaseNoEventMask = |
| + WebMouseWheelEvent::kPhaseEnded | WebMouseWheelEvent::kPhaseCancelled | |
| + WebMouseWheelEvent::kPhaseMayBegin; |
| + if ((event.phase & kWheelEventPhaseNoEventMask) || |
| + (event.momentum_phase & kWheelEventPhaseNoEventMask)) |
| + return WebInputEventResult::kNotHandled; |
| #endif |
| - Document* doc = frame_->GetDocument(); |
| - if (doc->GetLayoutViewItem().IsNull()) |
| - return WebInputEventResult::kNotHandled; |
| + Document* doc = frame_->GetDocument(); |
| - LocalFrameView* view = frame_->View(); |
| - if (!view) |
| - return WebInputEventResult::kNotHandled; |
| + if (doc->GetLayoutViewItem().IsNull()) |
| + return WebInputEventResult::kNotHandled; |
| - LayoutPoint v_point = |
| - view->RootFrameToContents(FlooredIntPoint(event.PositionInRootFrame())); |
| + LocalFrameView* view = frame_->View(); |
| + if (!view) |
| + return WebInputEventResult::kNotHandled; |
| - HitTestRequest request(HitTestRequest::kReadOnly); |
| - HitTestResult result(request, v_point); |
| - doc->GetLayoutViewItem().HitTest(result); |
| + LayoutPoint v_point = |
|
bokan
2017/06/15 15:47:17
Everything from here to end of the block is identi
sahel
2017/06/16 14:56:20
Done.
|
| + view->RootFrameToContents(FlooredIntPoint(event.PositionInRootFrame())); |
| - Node* node = result.InnerNode(); |
| - // Wheel events should not dispatch to text nodes. |
| - if (node && node->IsTextNode()) |
| - node = FlatTreeTraversal::Parent(*node); |
| + HitTestRequest request(HitTestRequest::kReadOnly); |
| + HitTestResult result(request, v_point); |
| + doc->GetLayoutViewItem().HitTest(result); |
| - // If we're over the frame scrollbar, scroll the document. |
| - if (!node && result.GetScrollbar()) |
| - node = doc->documentElement(); |
| + Node* node = result.InnerNode(); |
| + // Wheel events should not dispatch to text nodes. |
| + if (node && node->IsTextNode()) |
| + node = FlatTreeTraversal::Parent(*node); |
| + |
| + // If we're over the frame scrollbar, scroll the document. |
| + if (!node && result.GetScrollbar()) |
| + node = doc->documentElement(); |
| + |
| + wheel_target_ = node; |
| + } |
| - LocalFrame* subframe = EventHandlingUtil::SubframeForTargetNode(node); |
| + LocalFrame* subframe = |
| + EventHandlingUtil::SubframeForTargetNode(wheel_target_.Get()); |
| if (subframe) { |
| WebInputEventResult result = |
| subframe->GetEventHandler().HandleWheelEvent(event); |
| @@ -74,10 +131,11 @@ WebInputEventResult MouseWheelEventManager::HandleWheelEvent( |
| return result; |
| } |
| - if (node) { |
| + if (wheel_target_) { |
| WheelEvent* dom_event = |
| - WheelEvent::Create(event, node->GetDocument().domWindow()); |
| - DispatchEventResult dom_event_result = node->DispatchEvent(dom_event); |
| + WheelEvent::Create(event, wheel_target_->GetDocument().domWindow()); |
| + DispatchEventResult dom_event_result = |
| + wheel_target_->DispatchEvent(dom_event); |
| if (dom_event_result != DispatchEventResult::kNotCanceled) |
| return EventHandlingUtil::ToWebInputEventResult(dom_event_result); |
| } |