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

Side by Side Diff: content/browser/renderer_host/input/wheel_scroll_latching_browsertest.cc

Issue 2928793003: Re-target wheel events only when a new scroll sequence has started. (Closed)
Patch Set: browser test updated. 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "base/test/scoped_feature_list.h"
6 #include "content/browser/renderer_host/render_widget_host_impl.h"
7 #include "content/browser/renderer_host/render_widget_host_input_event_router.h"
8 #include "content/browser/web_contents/web_contents_impl.h"
9 #include "content/common/input/synthetic_web_input_event_builders.h"
10 #include "content/public/common/content_features.h"
11 #include "content/public/test/browser_test_utils.h"
12 #include "content/public/test/content_browser_test.h"
13 #include "content/public/test/content_browser_test_utils.h"
14 #include "content/shell/browser/shell.h"
15 #include "ui/events/gesture_detection/gesture_configuration.h"
16
17 #if defined(OS_ANDROID)
18 #include "content/browser/renderer_host/render_widget_host_view_android.h"
19 #endif
20
21 using blink::WebMouseWheelEvent;
22
23 namespace {
24 void GiveItSomeTime() {
25 base::RunLoop run_loop;
26 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
27 FROM_HERE, run_loop.QuitClosure(), base::TimeDelta::FromMilliseconds(10));
28 run_loop.Run();
29 }
30
31 const char kWheelEventLatchingDataURL[] =
32 "data:text/html;charset=utf-8,"
33 "<!DOCTYPE html>"
34 "<style>"
35 "body { height: 10000px;"
tdresser 2017/06/09 18:13:11 This brace style is atypical - we'd normally put t
sahel 2017/06/13 15:43:20 Done.
36 "}"
37 "#scrollableDiv { position: absolute;"
38 " left: 100px;"
39 " top: 200px;"
40 " width: 400px;"
41 " height: 800px;"
42 " overflow: scroll;"
43 " background: red;"
44 "}"
45 "#nestedDiv { width: 400px;"
46 " height: 8000px;"
47 " opacity: 0;"
48 "}"
49 "</style>"
50 "<div id='scrollableDiv'>"
51 " <div id='nestedDiv'></div>"
52 "</div>"
53 "<script>"
54 " var scrollableDiv = document.getElementById('scrollableDiv');"
55 " var scrollableDivWheelEventCounter = 0;"
56 " var documentWheelEventCounter = 0;"
57 " scrollableDiv.addEventListener('wheel',"
58 " function(e) { scrollableDivWheelEventCounter++;"
59 " e.stopPropagation(); });"
60 " document.scrollingElement.addEventListener('wheel',"
61 " function(e) { documentWheelEventCounter++; });"
62 "</script>";
63 } // namespace
64
65 namespace content {
66 class WheelScrollLatchingBrowserTest : public ContentBrowserTest {
67 public:
68 WheelScrollLatchingBrowserTest(bool wheel_scroll_latching_enabled = true)
69 : wheel_scroll_latching_enabled_(wheel_scroll_latching_enabled) {
70 ui::GestureConfiguration::GetInstance()->set_scroll_debounce_interval_in_ms(
71 0);
72
73 if (wheel_scroll_latching_enabled_)
74 EnableWheelScrollLatching();
75 else
76 DisableWheelScrollLatching();
77 }
78 ~WheelScrollLatchingBrowserTest() override {}
79
80 protected:
81 RenderWidgetHostImpl* GetWidgetHost() {
82 return RenderWidgetHostImpl::From(
83 web_contents()->GetRenderViewHost()->GetWidget());
84 }
85
86 WebContentsImpl* web_contents() const {
87 return static_cast<WebContentsImpl*>(shell()->web_contents());
88 }
89
90 RenderWidgetHostInputEventRouter* GetRouter() {
91 return web_contents()->GetInputEventRouter();
92 }
93
94 RenderWidgetHostViewBase* GetRootView() {
95 return static_cast<RenderWidgetHostViewBase*>(web_contents()
96 ->GetFrameTree()
97 ->root()
98 ->current_frame_host()
99 ->GetView());
100 }
101
102 float GetPageScaleFactor() {
103 return GetWidgetHost()->last_frame_metadata().page_scale_factor;
104 }
105
106 void LoadURL() {
107 const GURL data_url(kWheelEventLatchingDataURL);
108 NavigateToURL(shell(), data_url);
109
110 RenderWidgetHostImpl* host = GetWidgetHost();
111 host->GetView()->SetSize(gfx::Size(600, 600));
112
113 // The page is loaded in the renderer, wait for a new frame to arrive.
114 while (!host->ScheduleComposite())
115 GiveItSomeTime();
116 }
117 int ExecuteScriptAndExtractInt(const std::string& script) {
118 int value = 0;
119 EXPECT_TRUE(content::ExecuteScriptAndExtractInt(
120 shell(), "domAutomationController.send(" + script + ")", &value));
121 return value;
122 }
123 void EnableWheelScrollLatching() {
124 feature_list_.InitFromCommandLine(
125 features::kTouchpadAndWheelScrollLatching.name, "");
126 }
127 void DisableWheelScrollLatching() {
128 feature_list_.InitFromCommandLine(
129 "", features::kTouchpadAndWheelScrollLatching.name);
130 }
131
132 void WheelEventTargetTest() {
133 LoadURL();
134 EXPECT_EQ(0, ExecuteScriptAndExtractInt("documentWheelEventCounter"));
135 EXPECT_EQ(0, ExecuteScriptAndExtractInt("scrollableDivWheelEventCounter"));
136
137 FrameWatcher frame_watcher(shell()->web_contents());
138 scoped_refptr<InputMsgWatcher> input_msg_watcher(new InputMsgWatcher(
139 GetWidgetHost(), blink::WebInputEvent::kMouseWheel));
140 float scale_factor = GetPageScaleFactor();
141
142 float scrollable_div_top =
143 ExecuteScriptAndExtractInt("scrollableDiv.getBoundingClientRect().top");
144 float x = scale_factor *
145 (ExecuteScriptAndExtractInt(
146 "scrollableDiv.getBoundingClientRect().left") +
147 ExecuteScriptAndExtractInt(
148 "scrollableDiv.getBoundingClientRect().right")) /
149 2;
150 float y = scale_factor * 0.5 * scrollable_div_top;
151 float delta_x = 0;
152 float delta_y = -0.5 * scrollable_div_top;
153 blink::WebMouseWheelEvent wheel_event =
154 SyntheticWebMouseWheelEventBuilder::Build(x, y, x, y, delta_x, delta_y,
155 0, true);
156 if (wheel_scroll_latching_enabled_)
157 wheel_event.phase = blink::WebMouseWheelEvent::kPhaseBegan;
158 GetRouter()->RouteMouseWheelEvent(GetRootView(), &wheel_event,
159 ui::LatencyInfo());
160
161 // Runs until we get the InputMsgAck callback
tdresser 2017/06/09 18:13:11 Trailing .
sahel 2017/06/13 15:43:20 Done.
162 EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED,
163 input_msg_watcher->WaitForAck());
164
165 while (ExecuteScriptAndExtractInt("document.scrollingElement.scrollTop") <
166 -delta_y)
167 frame_watcher.WaitFrames(1);
168
169 EXPECT_EQ(0, ExecuteScriptAndExtractInt("scrollableDiv.scrollTop"));
170 EXPECT_EQ(1, ExecuteScriptAndExtractInt("documentWheelEventCounter"));
171 EXPECT_EQ(0, ExecuteScriptAndExtractInt("scrollableDivWheelEventCounter"));
172
173 if (wheel_scroll_latching_enabled_)
174 wheel_event.phase = blink::WebMouseWheelEvent::kPhaseChanged;
175 GetRouter()->RouteMouseWheelEvent(GetRootView(), &wheel_event,
176 ui::LatencyInfo());
177
178 // Runs until we get the InputMsgAck callback
tdresser 2017/06/09 18:13:11 Trailing .
sahel 2017/06/13 15:43:20 Done.
179 EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED,
180 input_msg_watcher->WaitForAck());
181
182 if (wheel_scroll_latching_enabled_) {
183 while (frame_watcher.LastMetadata().root_scroll_offset.y() < -2 * delta_y)
184 frame_watcher.WaitFrames(1);
185
186 EXPECT_EQ(0, ExecuteScriptAndExtractInt("scrollableDiv.scrollTop"));
187 EXPECT_EQ(2, ExecuteScriptAndExtractInt("documentWheelEventCounter"));
188 EXPECT_EQ(0,
189 ExecuteScriptAndExtractInt("scrollableDivWheelEventCounter"));
190 } else {
191 while (ExecuteScriptAndExtractInt("scrollableDiv.scrollTop") < -delta_y)
192 frame_watcher.WaitFrames(1);
193
194 EXPECT_EQ(1, ExecuteScriptAndExtractInt("documentWheelEventCounter"));
195 EXPECT_EQ(1,
196 ExecuteScriptAndExtractInt("scrollableDivWheelEventCounter"));
197 }
198 }
199
200 private:
201 base::test::ScopedFeatureList feature_list_;
202 bool wheel_scroll_latching_enabled_;
203 };
204
205 class WheelScrollLatchingDisabledBrowserTest
206 : public WheelScrollLatchingBrowserTest {
207 public:
208 WheelScrollLatchingDisabledBrowserTest()
209 : WheelScrollLatchingBrowserTest(false) {}
210 ~WheelScrollLatchingDisabledBrowserTest() override {}
211 };
212
213 // Start scrolling by mouse wheel on the document: the wheel event will be sent
214 // to the document's scrolling element, the scrollable div will be under the
215 // cursor after applying the scrolling. Continue scrolling by mouse wheel, since
216 // wheel scroll latching is enabled the wheel event will be still sent to the
217 // document's scrolling element and the document's scrolling element will
218 // continue scrolling.
219 IN_PROC_BROWSER_TEST_F(WheelScrollLatchingBrowserTest, WheelEventTarget) {
220 WheelEventTargetTest();
221 }
222
223 // Start scrolling by mouse wheel on the document: the wheel event will be sent
224 // to the document's scrolling element, the scrollable div will be under the
225 // cursor after applying the scrolloffsets. Continue scrolling by mouse wheel,
226 // since wheel scroll latching is disabled the wheel event will be still sent to
227 // the scrollable div which is currently under the cursor. The div will start
228 // scrolling.
229 IN_PROC_BROWSER_TEST_F(WheelScrollLatchingDisabledBrowserTest,
230 WheelEventTarget) {
231 WheelEventTargetTest();
232 }
233
234 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698