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

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

Issue 2928793003: Re-target wheel events only when a new scroll sequence has started. (Closed)
Patch Set: Landed migration of wheel handling to MouseWheelEventManager separately. 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 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 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/MouseWheelEventManager.h" 5 #include "core/input/MouseWheelEventManager.h"
6 6
7 #include "core/dom/Document.h" 7 #include "core/dom/Document.h"
8 #include "core/events/WheelEvent.h" 8 #include "core/events/WheelEvent.h"
9 #include "core/frame/LocalFrameView.h" 9 #include "core/frame/LocalFrameView.h"
10 #include "core/input/EventHandler.h" 10 #include "core/input/EventHandler.h"
11 #include "core/input/EventHandlingUtil.h" 11 #include "core/input/EventHandlingUtil.h"
12 #include "core/input/ScrollManager.h" 12 #include "core/input/ScrollManager.h"
13 #include "core/layout/HitTestRequest.h" 13 #include "core/layout/HitTestRequest.h"
14 #include "core/layout/HitTestResult.h" 14 #include "core/layout/HitTestResult.h"
15 #include "core/layout/api/LayoutViewItem.h" 15 #include "core/layout/api/LayoutViewItem.h"
16 #include "public/platform/WebMouseWheelEvent.h" 16 #include "public/platform/WebMouseWheelEvent.h"
17 17
18 namespace blink { 18 namespace blink {
19 MouseWheelEventManager::MouseWheelEventManager(LocalFrame& frame, 19 MouseWheelEventManager::MouseWheelEventManager(LocalFrame& frame,
20 ScrollManager& scroll_manager) 20 ScrollManager& scroll_manager)
21 : frame_(frame), scroll_manager_(scroll_manager) {} 21 : frame_(frame), wheel_target_(nullptr), scroll_manager_(scroll_manager) {}
22 22
23 DEFINE_TRACE(MouseWheelEventManager) { 23 DEFINE_TRACE(MouseWheelEventManager) {
24 visitor->Trace(frame_); 24 visitor->Trace(frame_);
25 visitor->Trace(wheel_target_);
25 visitor->Trace(scroll_manager_); 26 visitor->Trace(scroll_manager_);
26 } 27 }
27 28
29 void MouseWheelEventManager::Clear() {
30 wheel_target_ = nullptr;
31 }
32
28 WebInputEventResult MouseWheelEventManager::HandleWheelEvent( 33 WebInputEventResult MouseWheelEventManager::HandleWheelEvent(
29 const WebMouseWheelEvent& event) { 34 const WebMouseWheelEvent& event) {
35 bool wheel_scroll_latching =
36 RuntimeEnabledFeatures::TouchpadAndWheelScrollLatchingEnabled();
37
38 if (wheel_scroll_latching) {
39 const int kWheelEventPhaseNoEventMask =
40 WebMouseWheelEvent::kPhaseEnded | WebMouseWheelEvent::kPhaseCancelled |
41 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.
42
43 if ((event.phase & kWheelEventPhaseNoEventMask) ||
44 (event.momentum_phase & kWheelEventPhaseNoEventMask)) {
45 // Filter wheel events with zero deltas and reset the wheel_target_ node.
46 DCHECK(!event.delta_x && !event.delta_y);
47 wheel_target_ = nullptr;
48 return WebInputEventResult::kNotHandled;
49 }
50
51 if (event.phase == WebMouseWheelEvent::kPhaseBegan) {
52 // Find and save the wheel_target_, this target will be used for the rest
53 // of the current scrolling sequence.
54 DCHECK(!wheel_target_);
55 Document* doc = frame_->GetDocument();
56
57 if (doc->GetLayoutViewItem().IsNull())
58 return WebInputEventResult::kNotHandled;
59
60 LocalFrameView* view = frame_->View();
61 if (!view)
62 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.
63
64 LayoutPoint v_point = view->RootFrameToContents(
65 FlooredIntPoint(event.PositionInRootFrame()));
66
67 HitTestRequest request(HitTestRequest::kReadOnly);
68 HitTestResult result(request, v_point);
69 doc->GetLayoutViewItem().HitTest(result);
70
71 wheel_target_ = result.InnerNode();
72 // Wheel events should not dispatch to text nodes.
73 if (wheel_target_ && wheel_target_->IsTextNode())
74 wheel_target_ = FlatTreeTraversal::Parent(*wheel_target_);
75
76 // If we're over the frame scrollbar, scroll the document.
77 if (!wheel_target_ && result.GetScrollbar())
78 wheel_target_ = doc->documentElement();
79 }
80 } else { // !wheel_scroll_latching, wheel_target_ will be updated for each
81 // wheel event.
30 #if OS(MACOSX) 82 #if OS(MACOSX)
31 // Filter Mac OS specific phases, usually with a zero-delta. 83 // Filter Mac OS specific phases, usually with a zero-delta.
32 // https://crbug.com/553732 84 // https://crbug.com/553732
33 // TODO(chongz): EventSender sends events with 85 // TODO(chongz): EventSender sends events with
34 // |WebMouseWheelEvent::PhaseNone|, 86 // |WebMouseWheelEvent::PhaseNone|,
35 // but it shouldn't. 87 // but it shouldn't.
36 const int kWheelEventPhaseNoEventMask = WebMouseWheelEvent::kPhaseEnded | 88 const int kWheelEventPhaseNoEventMask =
37 WebMouseWheelEvent::kPhaseCancelled | 89 WebMouseWheelEvent::kPhaseEnded | WebMouseWheelEvent::kPhaseCancelled |
38 WebMouseWheelEvent::kPhaseMayBegin; 90 WebMouseWheelEvent::kPhaseMayBegin;
39 if ((event.phase & kWheelEventPhaseNoEventMask) || 91 if ((event.phase & kWheelEventPhaseNoEventMask) ||
40 (event.momentum_phase & kWheelEventPhaseNoEventMask)) 92 (event.momentum_phase & kWheelEventPhaseNoEventMask))
41 return WebInputEventResult::kNotHandled; 93 return WebInputEventResult::kNotHandled;
42 #endif 94 #endif
43 Document* doc = frame_->GetDocument();
44 95
45 if (doc->GetLayoutViewItem().IsNull()) 96 Document* doc = frame_->GetDocument();
46 return WebInputEventResult::kNotHandled;
47 97
48 LocalFrameView* view = frame_->View(); 98 if (doc->GetLayoutViewItem().IsNull())
49 if (!view) 99 return WebInputEventResult::kNotHandled;
50 return WebInputEventResult::kNotHandled;
51 100
52 LayoutPoint v_point = 101 LocalFrameView* view = frame_->View();
53 view->RootFrameToContents(FlooredIntPoint(event.PositionInRootFrame())); 102 if (!view)
103 return WebInputEventResult::kNotHandled;
54 104
55 HitTestRequest request(HitTestRequest::kReadOnly); 105 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.
56 HitTestResult result(request, v_point); 106 view->RootFrameToContents(FlooredIntPoint(event.PositionInRootFrame()));
57 doc->GetLayoutViewItem().HitTest(result);
58 107
59 Node* node = result.InnerNode(); 108 HitTestRequest request(HitTestRequest::kReadOnly);
60 // Wheel events should not dispatch to text nodes. 109 HitTestResult result(request, v_point);
61 if (node && node->IsTextNode()) 110 doc->GetLayoutViewItem().HitTest(result);
62 node = FlatTreeTraversal::Parent(*node);
63 111
64 // If we're over the frame scrollbar, scroll the document. 112 Node* node = result.InnerNode();
65 if (!node && result.GetScrollbar()) 113 // Wheel events should not dispatch to text nodes.
66 node = doc->documentElement(); 114 if (node && node->IsTextNode())
115 node = FlatTreeTraversal::Parent(*node);
67 116
68 LocalFrame* subframe = EventHandlingUtil::SubframeForTargetNode(node); 117 // If we're over the frame scrollbar, scroll the document.
118 if (!node && result.GetScrollbar())
119 node = doc->documentElement();
120
121 wheel_target_ = node;
122 }
123
124 LocalFrame* subframe =
125 EventHandlingUtil::SubframeForTargetNode(wheel_target_.Get());
69 if (subframe) { 126 if (subframe) {
70 WebInputEventResult result = 127 WebInputEventResult result =
71 subframe->GetEventHandler().HandleWheelEvent(event); 128 subframe->GetEventHandler().HandleWheelEvent(event);
72 if (result != WebInputEventResult::kNotHandled) 129 if (result != WebInputEventResult::kNotHandled)
73 scroll_manager_->SetFrameWasScrolledByUser(); 130 scroll_manager_->SetFrameWasScrolledByUser();
74 return result; 131 return result;
75 } 132 }
76 133
77 if (node) { 134 if (wheel_target_) {
78 WheelEvent* dom_event = 135 WheelEvent* dom_event =
79 WheelEvent::Create(event, node->GetDocument().domWindow()); 136 WheelEvent::Create(event, wheel_target_->GetDocument().domWindow());
80 DispatchEventResult dom_event_result = node->DispatchEvent(dom_event); 137 DispatchEventResult dom_event_result =
138 wheel_target_->DispatchEvent(dom_event);
81 if (dom_event_result != DispatchEventResult::kNotCanceled) 139 if (dom_event_result != DispatchEventResult::kNotCanceled)
82 return EventHandlingUtil::ToWebInputEventResult(dom_event_result); 140 return EventHandlingUtil::ToWebInputEventResult(dom_event_result);
83 } 141 }
84 142
85 return WebInputEventResult::kNotHandled; 143 return WebInputEventResult::kNotHandled;
86 } 144 }
87 145
88 } // namespace blink 146 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698