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

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: 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
« no previous file with comments | « third_party/WebKit/Source/core/input/MouseWheelEventManager.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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) {
30 #if OS(MACOSX) 35 bool wheel_scroll_latching =
31 // Filter Mac OS specific phases, usually with a zero-delta. 36 RuntimeEnabledFeatures::TouchpadAndWheelScrollLatchingEnabled();
32 // https://crbug.com/553732 37
33 // TODO(chongz): EventSender sends events with
34 // |WebMouseWheelEvent::PhaseNone|,
35 // but it shouldn't.
36 const int kWheelEventPhaseNoEventMask = WebMouseWheelEvent::kPhaseEnded |
37 WebMouseWheelEvent::kPhaseCancelled |
38 WebMouseWheelEvent::kPhaseMayBegin;
39 if ((event.phase & kWheelEventPhaseNoEventMask) ||
40 (event.momentum_phase & kWheelEventPhaseNoEventMask))
41 return WebInputEventResult::kNotHandled;
42 #endif
43 Document* doc = frame_->GetDocument(); 38 Document* doc = frame_->GetDocument();
44 39 if (!doc || doc->GetLayoutViewItem().IsNull())
45 if (doc->GetLayoutViewItem().IsNull())
46 return WebInputEventResult::kNotHandled; 40 return WebInputEventResult::kNotHandled;
47 41
48 LocalFrameView* view = frame_->View(); 42 LocalFrameView* view = frame_->View();
49 if (!view) 43 if (!view)
50 return WebInputEventResult::kNotHandled; 44 return WebInputEventResult::kNotHandled;
51 45
52 LayoutPoint v_point = 46 if (wheel_scroll_latching) {
53 view->RootFrameToContents(FlooredIntPoint(event.PositionInRootFrame())); 47 const int kWheelEventPhaseEndedEventMask =
48 WebMouseWheelEvent::kPhaseEnded | WebMouseWheelEvent::kPhaseCancelled;
49 const int kWheelEventPhaseNoEventMask =
50 kWheelEventPhaseEndedEventMask | WebMouseWheelEvent::kPhaseMayBegin;
54 51
55 HitTestRequest request(HitTestRequest::kReadOnly); 52 if ((event.phase & kWheelEventPhaseEndedEventMask) ||
56 HitTestResult result(request, v_point); 53 (event.momentum_phase & kWheelEventPhaseEndedEventMask)) {
57 doc->GetLayoutViewItem().HitTest(result); 54 wheel_target_ = nullptr;
55 }
58 56
59 Node* node = result.InnerNode(); 57 if ((event.phase & kWheelEventPhaseNoEventMask) ||
60 // Wheel events should not dispatch to text nodes. 58 (event.momentum_phase & kWheelEventPhaseNoEventMask)) {
61 if (node && node->IsTextNode()) 59 // Filter wheel events with zero deltas and reset the wheel_target_ node.
62 node = FlatTreeTraversal::Parent(*node); 60 DCHECK(!event.delta_x && !event.delta_y);
61 return WebInputEventResult::kNotHandled;
62 }
63 63
64 // If we're over the frame scrollbar, scroll the document. 64 if (event.phase == WebMouseWheelEvent::kPhaseBegan) {
65 if (!node && result.GetScrollbar()) 65 // Find and save the wheel_target_, this target will be used for the rest
66 node = doc->documentElement(); 66 // of the current scrolling sequence.
67 DCHECK(!wheel_target_);
68 wheel_target_ = FindTargetNode(event, doc, view);
69 }
70 } else { // !wheel_scroll_latching, wheel_target_ will be updated for each
71 // wheel event.
72 #if OS(MACOSX)
73 // Filter Mac OS specific phases, usually with a zero-delta.
74 // https://crbug.com/553732
75 // TODO(chongz): EventSender sends events with
76 // |WebMouseWheelEvent::PhaseNone|,
77 // but it shouldn't.
78 const int kWheelEventPhaseNoEventMask =
79 WebMouseWheelEvent::kPhaseEnded | WebMouseWheelEvent::kPhaseCancelled |
80 WebMouseWheelEvent::kPhaseMayBegin;
81 if ((event.phase & kWheelEventPhaseNoEventMask) ||
82 (event.momentum_phase & kWheelEventPhaseNoEventMask))
83 return WebInputEventResult::kNotHandled;
84 #endif
67 85
68 LocalFrame* subframe = EventHandlingUtil::SubframeForTargetNode(node); 86 wheel_target_ = FindTargetNode(event, doc, view);
87 }
88
89 LocalFrame* subframe =
90 EventHandlingUtil::SubframeForTargetNode(wheel_target_.Get());
69 if (subframe) { 91 if (subframe) {
70 WebInputEventResult result = 92 WebInputEventResult result =
71 subframe->GetEventHandler().HandleWheelEvent(event); 93 subframe->GetEventHandler().HandleWheelEvent(event);
72 if (result != WebInputEventResult::kNotHandled) 94 if (result != WebInputEventResult::kNotHandled)
73 scroll_manager_->SetFrameWasScrolledByUser(); 95 scroll_manager_->SetFrameWasScrolledByUser();
74 return result; 96 return result;
75 } 97 }
76 98
77 if (node) { 99 if (wheel_target_) {
78 WheelEvent* dom_event = 100 WheelEvent* dom_event =
79 WheelEvent::Create(event, node->GetDocument().domWindow()); 101 WheelEvent::Create(event, wheel_target_->GetDocument().domWindow());
80 DispatchEventResult dom_event_result = node->DispatchEvent(dom_event); 102 DispatchEventResult dom_event_result =
103 wheel_target_->DispatchEvent(dom_event);
81 if (dom_event_result != DispatchEventResult::kNotCanceled) 104 if (dom_event_result != DispatchEventResult::kNotCanceled)
82 return EventHandlingUtil::ToWebInputEventResult(dom_event_result); 105 return EventHandlingUtil::ToWebInputEventResult(dom_event_result);
83 } 106 }
84 107
85 return WebInputEventResult::kNotHandled; 108 return WebInputEventResult::kNotHandled;
86 } 109 }
87 110
111 Node* MouseWheelEventManager::FindTargetNode(const WebMouseWheelEvent& event,
112 const Document* doc,
113 const LocalFrameView* view) {
114 DCHECK(doc && !doc->GetLayoutViewItem().IsNull() && view);
115 LayoutPoint v_point =
116 view->RootFrameToContents(FlooredIntPoint(event.PositionInRootFrame()));
117
118 HitTestRequest request(HitTestRequest::kReadOnly);
119 HitTestResult result(request, v_point);
120 doc->GetLayoutViewItem().HitTest(result);
121
122 Node* node = result.InnerNode();
123 // Wheel events should not dispatch to text nodes.
124 if (node && node->IsTextNode())
125 node = FlatTreeTraversal::Parent(*node);
126
127 // If we're over the frame scrollbar, scroll the document.
128 if (!node && result.GetScrollbar())
129 node = doc->documentElement();
130
131 return node;
132 }
133
88 } // namespace blink 134 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/input/MouseWheelEventManager.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698