| Flutter Linux Embedder |

fl_scrolling_manager_test.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter 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 "flutter/shell/platform/linux/fl_scrolling_manager.h"
6
7 #include <cstring>
8 #include <vector>
9
10 #include "gtest/gtest.h"
11 namespace {
12 typedef std::function<void(FlutterPointerPhase phase,
13 size_t timestamp,
14 double x,
15 double y,
16 FlutterPointerDeviceKind device_kind,
17 double scroll_delta_x,
18 double scroll_delta_y,
19 int64_t buttons)>
20 MousePointerCallHandler;
21 typedef std::function<void(size_t timestamp,
22 double x,
23 double y,
24 FlutterPointerPhase phase,
25 double pan_x,
26 double pan_y,
27 double scale,
28 double rotation)>
29 PointerPanZoomCallHandler;
30
31 typedef struct {
32 FlutterPointerPhase phase;
33 size_t timestamp;
34 double x;
35 double y;
36 FlutterPointerDeviceKind device_kind;
37 double scroll_delta_x;
38 double scroll_delta_y;
39 int64_t buttons;
40 } MousePointerEventRecord;
41
42 typedef struct {
43 size_t timestamp;
44 double x;
45 double y;
46 FlutterPointerPhase phase;
47 double pan_x;
48 double pan_y;
49 double scale;
50 double rotation;
51 } PointerPanZoomEventRecord;
52
53 G_BEGIN_DECLS
54
55 G_DECLARE_FINAL_TYPE(FlMockScrollingViewDelegate,
56 fl_mock_scrolling_view_delegate,
57 FL,
58 MOCK_SCROLLING_VIEW_DELEGATE,
59 GObject)
60
61 G_END_DECLS
62
63 /***** FlMockScrollingViewDelegate *****/
64
65 struct _FlMockScrollingViewDelegate {
66 GObject parent_instance;
67 };
68
69 struct FlMockScrollingViewDelegatePrivate {
70 MousePointerCallHandler mouse_handler;
71 PointerPanZoomCallHandler pan_zoom_handler;
72 };
73
74 static void fl_mock_view_scroll_delegate_iface_init(
75 FlScrollingViewDelegateInterface* iface);
76
77 G_DEFINE_TYPE_WITH_CODE(
78 FlMockScrollingViewDelegate,
79 fl_mock_scrolling_view_delegate,
80 G_TYPE_OBJECT,
81 G_IMPLEMENT_INTERFACE(fl_scrolling_view_delegate_get_type(),
82 fl_mock_view_scroll_delegate_iface_init);
83 G_ADD_PRIVATE(FlMockScrollingViewDelegate))
84
85 #define FL_MOCK_SCROLLING_VIEW_DELEGATE_GET_PRIVATE(obj) \
86 static_cast<FlMockScrollingViewDelegatePrivate*>( \
87 fl_mock_scrolling_view_delegate_get_instance_private( \
88 FL_MOCK_SCROLLING_VIEW_DELEGATE(obj)))
89
90 static void fl_mock_scrolling_view_delegate_init(
91 FlMockScrollingViewDelegate* self) {
92 FlMockScrollingViewDelegatePrivate* priv =
93 FL_MOCK_SCROLLING_VIEW_DELEGATE_GET_PRIVATE(self);
94
95 new (priv) FlMockScrollingViewDelegatePrivate();
96 }
97
98 static void fl_mock_scrolling_view_delegate_finalize(GObject* object) {
99 FL_MOCK_SCROLLING_VIEW_DELEGATE_GET_PRIVATE(object)
100 ->~FlMockScrollingViewDelegatePrivate();
101 }
102
103 static void fl_mock_scrolling_view_delegate_dispose(GObject* object) {
104 G_OBJECT_CLASS(fl_mock_scrolling_view_delegate_parent_class)->dispose(object);
105 }
106
107 static void fl_mock_scrolling_view_delegate_class_init(
108 FlMockScrollingViewDelegateClass* klass) {
109 G_OBJECT_CLASS(klass)->dispose = fl_mock_scrolling_view_delegate_dispose;
110 G_OBJECT_CLASS(klass)->finalize = fl_mock_scrolling_view_delegate_finalize;
111 }
112
113 static void fl_mock_view_send_mouse_pointer_event(
114 FlScrollingViewDelegate* delegate,
115 FlutterPointerPhase phase,
116 size_t timestamp,
117 double x,
118 double y,
119 FlutterPointerDeviceKind device_kind,
120 double scroll_delta_x,
121 double scroll_delta_y,
122 int64_t buttons) {
123 FlMockScrollingViewDelegatePrivate* priv =
124 FL_MOCK_SCROLLING_VIEW_DELEGATE_GET_PRIVATE(delegate);
125 priv->mouse_handler(phase, timestamp, x, y, device_kind, scroll_delta_x,
126 scroll_delta_y, buttons);
127 }
128
129 static void fl_mock_view_send_pointer_pan_zoom_event(
130 FlScrollingViewDelegate* delegate,
131 size_t timestamp,
132 double x,
133 double y,
134 FlutterPointerPhase phase,
135 double pan_x,
136 double pan_y,
137 double scale,
138 double rotation) {
139 FlMockScrollingViewDelegatePrivate* priv =
140 FL_MOCK_SCROLLING_VIEW_DELEGATE_GET_PRIVATE(delegate);
141 priv->pan_zoom_handler(timestamp, x, y, phase, pan_x, pan_y, scale, rotation);
142 }
143
144 static void fl_mock_view_scroll_delegate_iface_init(
145 FlScrollingViewDelegateInterface* iface) {
146 iface->send_mouse_pointer_event = fl_mock_view_send_mouse_pointer_event;
147 iface->send_pointer_pan_zoom_event = fl_mock_view_send_pointer_pan_zoom_event;
148 }
149
150 static FlMockScrollingViewDelegate* fl_mock_scrolling_view_delegate_new() {
151 FlMockScrollingViewDelegate* self = FL_MOCK_SCROLLING_VIEW_DELEGATE(
152 g_object_new(fl_mock_scrolling_view_delegate_get_type(), nullptr));
153
154 // Added to stop compiler complaining about an unused function.
155 FL_IS_MOCK_SCROLLING_VIEW_DELEGATE(self);
156
157 return self;
158 }
159
160 static void fl_mock_scrolling_view_set_mouse_handler(
161 FlMockScrollingViewDelegate* self,
162 MousePointerCallHandler handler) {
163 FlMockScrollingViewDelegatePrivate* priv =
164 FL_MOCK_SCROLLING_VIEW_DELEGATE_GET_PRIVATE(self);
165
166 priv->mouse_handler = std::move(handler);
167 }
168
169 static void fl_mock_scrolling_view_set_pan_zoom_handler(
170 FlMockScrollingViewDelegate* self,
171 PointerPanZoomCallHandler handler) {
172 FlMockScrollingViewDelegatePrivate* priv =
173 FL_MOCK_SCROLLING_VIEW_DELEGATE_GET_PRIVATE(self);
174
175 priv->pan_zoom_handler = std::move(handler);
176 }
177
178 /***** End FlMockScrollingViewDelegate *****/
179
180 class ScrollingTester {
181 public:
182 ScrollingTester() {
183 view_ = fl_mock_scrolling_view_delegate_new();
184 manager_ = fl_scrolling_manager_new(FL_SCROLLING_VIEW_DELEGATE(view_));
185 fl_mock_scrolling_view_set_mouse_handler(
186 view_,
187 [](FlutterPointerPhase phase, size_t timestamp, double x, double y,
188 FlutterPointerDeviceKind device_kind, double scroll_delta_x,
189 double scroll_delta_y, int64_t buttons) {
190 // do nothing
191 });
192 fl_mock_scrolling_view_set_pan_zoom_handler(
193 view_,
194 [](size_t timestamp, double x, double y, FlutterPointerPhase phase,
195 double pan_x, double pan_y, double scale, double rotation) {
196 // do nothing
197 });
198 }
199
200 ~ScrollingTester() {
201 g_clear_object(&view_);
202 g_clear_object(&manager_);
203 }
204
205 FlScrollingManager* manager() { return manager_; }
206
207 void recordMousePointerCallsTo(
208 std::vector<MousePointerEventRecord>& storage) {
209 fl_mock_scrolling_view_set_mouse_handler(
210 view_, [&storage](FlutterPointerPhase phase, size_t timestamp, double x,
211 double y, FlutterPointerDeviceKind device_kind,
212 double scroll_delta_x, double scroll_delta_y,
213 int64_t buttons) {
214 storage.push_back(MousePointerEventRecord{
215 .phase = phase,
216 .timestamp = timestamp,
217 .x = x,
218 .y = y,
219 .device_kind = device_kind,
220 .scroll_delta_x = scroll_delta_x,
221 .scroll_delta_y = scroll_delta_y,
222 .buttons = buttons,
223 });
224 });
225 }
226
227 void recordPointerPanZoomCallsTo(
228 std::vector<PointerPanZoomEventRecord>& storage) {
229 fl_mock_scrolling_view_set_pan_zoom_handler(
230 view_, [&storage](size_t timestamp, double x, double y,
231 FlutterPointerPhase phase, double pan_x, double pan_y,
232 double scale, double rotation) {
233 storage.push_back(PointerPanZoomEventRecord{
234 .timestamp = timestamp,
235 .x = x,
236 .y = y,
237 .phase = phase,
238 .pan_x = pan_x,
239 .pan_y = pan_y,
240 .scale = scale,
241 .rotation = rotation,
242 });
243 });
244 }
245
246 private:
247 FlMockScrollingViewDelegate* view_;
248 FlScrollingManager* manager_;
249 };
250
251 // Disgusting hack but could not find any way to create a GdkDevice
252 struct _FakeGdkDevice {
253 GObject parent_instance;
254 gchar* name;
255 GdkInputSource source;
256 };
257 GdkDevice* makeFakeDevice(GdkInputSource source) {
258 _FakeGdkDevice* device =
259 static_cast<_FakeGdkDevice*>(g_malloc0(sizeof(_FakeGdkDevice)));
260 device->source = source;
261 // Bully the type checker
262 (reinterpret_cast<GTypeInstance*>(device))->g_class =
263 static_cast<GTypeClass*>(g_malloc0(sizeof(GTypeClass)));
264 (reinterpret_cast<GTypeInstance*>(device))->g_class->g_type = GDK_TYPE_DEVICE;
265 return reinterpret_cast<GdkDevice*>(device);
266 }
267
268 TEST(FlScrollingManagerTest, DiscreteDirectionional) {
269 ScrollingTester tester;
270 std::vector<MousePointerEventRecord> mouse_records;
271 std::vector<PointerPanZoomEventRecord> pan_zoom_records;
272 tester.recordMousePointerCallsTo(mouse_records);
273 tester.recordPointerPanZoomCallsTo(pan_zoom_records);
274 GdkDevice* mouse = makeFakeDevice(GDK_SOURCE_MOUSE);
275 GdkEventScroll* event =
276 reinterpret_cast<GdkEventScroll*>(gdk_event_new(GDK_SCROLL));
277 event->time = 1;
278 event->x = 4.0;
279 event->y = 8.0;
280 event->device = mouse;
281 event->direction = GDK_SCROLL_UP;
282 fl_scrolling_manager_handle_scroll_event(tester.manager(), event, 1.0);
283 EXPECT_EQ(pan_zoom_records.size(), 0u);
284 EXPECT_EQ(mouse_records.size(), 1u);
285 EXPECT_EQ(mouse_records[0].x, 4.0);
286 EXPECT_EQ(mouse_records[0].y, 8.0);
287 EXPECT_EQ(mouse_records[0].device_kind, kFlutterPointerDeviceKindMouse);
288 EXPECT_EQ(mouse_records[0].timestamp,
289 1000lu); // Milliseconds -> Microseconds
290 EXPECT_EQ(mouse_records[0].scroll_delta_x, 0);
291 EXPECT_EQ(mouse_records[0].scroll_delta_y, 53 * -1.0);
292 event->direction = GDK_SCROLL_DOWN;
293 fl_scrolling_manager_handle_scroll_event(tester.manager(), event, 1.0);
294 EXPECT_EQ(pan_zoom_records.size(), 0u);
295 EXPECT_EQ(mouse_records.size(), 2u);
296 EXPECT_EQ(mouse_records[1].x, 4.0);
297 EXPECT_EQ(mouse_records[1].y, 8.0);
298 EXPECT_EQ(mouse_records[1].device_kind, kFlutterPointerDeviceKindMouse);
299 EXPECT_EQ(mouse_records[1].timestamp,
300 1000lu); // Milliseconds -> Microseconds
301 EXPECT_EQ(mouse_records[1].scroll_delta_x, 0);
302 EXPECT_EQ(mouse_records[1].scroll_delta_y, 53 * 1.0);
303 event->direction = GDK_SCROLL_LEFT;
304 fl_scrolling_manager_handle_scroll_event(tester.manager(), event, 1.0);
305 EXPECT_EQ(pan_zoom_records.size(), 0u);
306 EXPECT_EQ(mouse_records.size(), 3u);
307 EXPECT_EQ(mouse_records[2].x, 4.0);
308 EXPECT_EQ(mouse_records[2].y, 8.0);
309 EXPECT_EQ(mouse_records[2].device_kind, kFlutterPointerDeviceKindMouse);
310 EXPECT_EQ(mouse_records[2].timestamp,
311 1000lu); // Milliseconds -> Microseconds
312 EXPECT_EQ(mouse_records[2].scroll_delta_x, 53 * -1.0);
313 EXPECT_EQ(mouse_records[2].scroll_delta_y, 0);
314 event->direction = GDK_SCROLL_RIGHT;
315 fl_scrolling_manager_handle_scroll_event(tester.manager(), event, 1.0);
316 EXPECT_EQ(pan_zoom_records.size(), 0u);
317 EXPECT_EQ(mouse_records.size(), 4u);
318 EXPECT_EQ(mouse_records[3].x, 4.0);
319 EXPECT_EQ(mouse_records[3].y, 8.0);
320 EXPECT_EQ(mouse_records[3].device_kind, kFlutterPointerDeviceKindMouse);
321 EXPECT_EQ(mouse_records[3].timestamp,
322 1000lu); // Milliseconds -> Microseconds
323 EXPECT_EQ(mouse_records[3].scroll_delta_x, 53 * 1.0);
324 EXPECT_EQ(mouse_records[3].scroll_delta_y, 0);
325 }
326
327 TEST(FlScrollingManagerTest, DiscreteScrolling) {
328 ScrollingTester tester;
329 std::vector<MousePointerEventRecord> mouse_records;
330 std::vector<PointerPanZoomEventRecord> pan_zoom_records;
331 tester.recordMousePointerCallsTo(mouse_records);
332 tester.recordPointerPanZoomCallsTo(pan_zoom_records);
333 GdkDevice* mouse = makeFakeDevice(GDK_SOURCE_MOUSE);
334 GdkEventScroll* event =
335 reinterpret_cast<GdkEventScroll*>(gdk_event_new(GDK_SCROLL));
336 event->time = 1;
337 event->x = 4.0;
338 event->y = 8.0;
339 event->delta_x = 1.0;
340 event->delta_y = 2.0;
341 event->device = mouse;
342 event->direction = GDK_SCROLL_SMOOTH;
343 fl_scrolling_manager_handle_scroll_event(tester.manager(), event, 1.0);
344 EXPECT_EQ(pan_zoom_records.size(), 0u);
345 EXPECT_EQ(mouse_records.size(), 1u);
346 EXPECT_EQ(mouse_records[0].x, 4.0);
347 EXPECT_EQ(mouse_records[0].y, 8.0);
348 EXPECT_EQ(mouse_records[0].device_kind, kFlutterPointerDeviceKindMouse);
349 EXPECT_EQ(mouse_records[0].timestamp,
350 1000lu); // Milliseconds -> Microseconds
351 EXPECT_EQ(mouse_records[0].scroll_delta_x, 53 * 1.0);
352 EXPECT_EQ(mouse_records[0].scroll_delta_y, 53 * 2.0);
353 }
354
355 TEST(FlScrollingManagerTest, Panning) {
356 ScrollingTester tester;
357 std::vector<MousePointerEventRecord> mouse_records;
358 std::vector<PointerPanZoomEventRecord> pan_zoom_records;
359 tester.recordMousePointerCallsTo(mouse_records);
360 tester.recordPointerPanZoomCallsTo(pan_zoom_records);
361 GdkDevice* touchpad = makeFakeDevice(GDK_SOURCE_TOUCHPAD);
362 GdkEventScroll* event =
363 reinterpret_cast<GdkEventScroll*>(gdk_event_new(GDK_SCROLL));
364 event->time = 1;
365 event->x = 4.0;
366 event->y = 8.0;
367 event->delta_x = 1.0;
368 event->delta_y = 2.0;
369 event->device = touchpad;
370 event->direction = GDK_SCROLL_SMOOTH;
371 fl_scrolling_manager_handle_scroll_event(tester.manager(), event, 1.0);
372 EXPECT_EQ(pan_zoom_records.size(), 2u);
373 EXPECT_EQ(mouse_records.size(), 0u);
374 EXPECT_EQ(pan_zoom_records[0].x, 4.0);
375 EXPECT_EQ(pan_zoom_records[0].y, 8.0);
376 EXPECT_EQ(pan_zoom_records[0].timestamp,
377 1000lu); // Milliseconds -> Microseconds
378 EXPECT_EQ(pan_zoom_records[0].phase, kPanZoomStart);
379 EXPECT_EQ(pan_zoom_records[1].x, 4.0);
380 EXPECT_EQ(pan_zoom_records[1].y, 8.0);
381 EXPECT_EQ(pan_zoom_records[1].timestamp,
382 1000lu); // Milliseconds -> Microseconds
383 EXPECT_EQ(pan_zoom_records[1].phase, kPanZoomUpdate);
384 EXPECT_EQ(pan_zoom_records[1].pan_x, 53 * -1.0); // directions get swapped
385 EXPECT_EQ(pan_zoom_records[1].pan_y, 53 * -2.0);
386 EXPECT_EQ(pan_zoom_records[1].scale, 1.0);
387 EXPECT_EQ(pan_zoom_records[1].rotation, 0.0);
388 fl_scrolling_manager_handle_scroll_event(tester.manager(), event, 1.0);
389 EXPECT_EQ(pan_zoom_records.size(), 3u);
390 EXPECT_EQ(mouse_records.size(), 0u);
391 EXPECT_EQ(pan_zoom_records[2].x, 4.0);
392 EXPECT_EQ(pan_zoom_records[2].y, 8.0);
393 EXPECT_EQ(pan_zoom_records[2].timestamp,
394 1000lu); // Milliseconds -> Microseconds
395 EXPECT_EQ(pan_zoom_records[2].phase, kPanZoomUpdate);
396 EXPECT_EQ(pan_zoom_records[2].pan_x, 53 * -2.0); // directions get swapped
397 EXPECT_EQ(pan_zoom_records[2].pan_y, 53 * -4.0);
398 EXPECT_EQ(pan_zoom_records[2].scale, 1.0);
399 EXPECT_EQ(pan_zoom_records[2].rotation, 0.0);
400 event->is_stop = true;
401 fl_scrolling_manager_handle_scroll_event(tester.manager(), event, 1.0);
402 EXPECT_EQ(pan_zoom_records.size(), 4u);
403 EXPECT_EQ(mouse_records.size(), 0u);
404 EXPECT_EQ(pan_zoom_records[3].x, 4.0);
405 EXPECT_EQ(pan_zoom_records[3].y, 8.0);
406 EXPECT_EQ(pan_zoom_records[3].timestamp,
407 1000lu); // Milliseconds -> Microseconds
408 EXPECT_EQ(pan_zoom_records[3].phase, kPanZoomEnd);
409 }
410
411 TEST(FlScrollingManagerTest, Zooming) {
412 ScrollingTester tester;
413 std::vector<MousePointerEventRecord> mouse_records;
414 std::vector<PointerPanZoomEventRecord> pan_zoom_records;
415 tester.recordMousePointerCallsTo(mouse_records);
416 tester.recordPointerPanZoomCallsTo(pan_zoom_records);
417 size_t time_start = g_get_real_time();
418 fl_scrolling_manager_handle_zoom_begin(tester.manager());
419 EXPECT_EQ(pan_zoom_records.size(), 1u);
420 EXPECT_EQ(mouse_records.size(), 0u);
421 EXPECT_EQ(pan_zoom_records[0].x, 0);
422 EXPECT_EQ(pan_zoom_records[0].y, 0);
423 EXPECT_EQ(pan_zoom_records[0].phase, kPanZoomStart);
424 EXPECT_GE(pan_zoom_records[0].timestamp, time_start);
425 fl_scrolling_manager_handle_zoom_update(tester.manager(), 1.1);
426 EXPECT_EQ(pan_zoom_records.size(), 2u);
427 EXPECT_EQ(mouse_records.size(), 0u);
428 EXPECT_EQ(pan_zoom_records[1].x, 0);
429 EXPECT_EQ(pan_zoom_records[1].y, 0);
430 EXPECT_EQ(pan_zoom_records[1].phase, kPanZoomUpdate);
431 EXPECT_GE(pan_zoom_records[1].timestamp, pan_zoom_records[0].timestamp);
432 EXPECT_EQ(pan_zoom_records[1].pan_x, 0);
433 EXPECT_EQ(pan_zoom_records[1].pan_y, 0);
434 EXPECT_EQ(pan_zoom_records[1].scale, 1.1);
435 EXPECT_EQ(pan_zoom_records[1].rotation, 0);
436 fl_scrolling_manager_handle_zoom_end(tester.manager());
437 EXPECT_EQ(pan_zoom_records.size(), 3u);
438 EXPECT_EQ(mouse_records.size(), 0u);
439 EXPECT_EQ(pan_zoom_records[2].x, 0);
440 EXPECT_EQ(pan_zoom_records[2].y, 0);
441 EXPECT_EQ(pan_zoom_records[2].phase, kPanZoomEnd);
442 EXPECT_GE(pan_zoom_records[2].timestamp, pan_zoom_records[1].timestamp);
443 }
444
445 TEST(FlScrollingManagerTest, Rotating) {
446 ScrollingTester tester;
447 std::vector<MousePointerEventRecord> mouse_records;
448 std::vector<PointerPanZoomEventRecord> pan_zoom_records;
449 tester.recordMousePointerCallsTo(mouse_records);
450 tester.recordPointerPanZoomCallsTo(pan_zoom_records);
451 size_t time_start = g_get_real_time();
452 fl_scrolling_manager_handle_rotation_begin(tester.manager());
453 EXPECT_EQ(pan_zoom_records.size(), 1u);
454 EXPECT_EQ(mouse_records.size(), 0u);
455 EXPECT_EQ(pan_zoom_records[0].x, 0);
456 EXPECT_EQ(pan_zoom_records[0].y, 0);
457 EXPECT_EQ(pan_zoom_records[0].phase, kPanZoomStart);
458 EXPECT_GE(pan_zoom_records[0].timestamp, time_start);
459 fl_scrolling_manager_handle_rotation_update(tester.manager(), 0.5);
460 EXPECT_EQ(pan_zoom_records.size(), 2u);
461 EXPECT_EQ(mouse_records.size(), 0u);
462 EXPECT_EQ(pan_zoom_records[1].x, 0);
463 EXPECT_EQ(pan_zoom_records[1].y, 0);
464 EXPECT_EQ(pan_zoom_records[1].phase, kPanZoomUpdate);
465 EXPECT_GE(pan_zoom_records[1].timestamp, pan_zoom_records[0].timestamp);
466 EXPECT_EQ(pan_zoom_records[1].pan_x, 0);
467 EXPECT_EQ(pan_zoom_records[1].pan_y, 0);
468 EXPECT_EQ(pan_zoom_records[1].scale, 1.0);
469 EXPECT_EQ(pan_zoom_records[1].rotation, 0.5);
470 fl_scrolling_manager_handle_rotation_end(tester.manager());
471 EXPECT_EQ(pan_zoom_records.size(), 3u);
472 EXPECT_EQ(mouse_records.size(), 0u);
473 EXPECT_EQ(pan_zoom_records[2].x, 0);
474 EXPECT_EQ(pan_zoom_records[2].y, 0);
475 EXPECT_EQ(pan_zoom_records[2].phase, kPanZoomEnd);
476 EXPECT_GE(pan_zoom_records[2].timestamp, pan_zoom_records[1].timestamp);
477 }
478
479 TEST(FlScrollingManagerTest, SynchronizedZoomingAndRotating) {
480 ScrollingTester tester;
481 std::vector<MousePointerEventRecord> mouse_records;
482 std::vector<PointerPanZoomEventRecord> pan_zoom_records;
483 tester.recordMousePointerCallsTo(mouse_records);
484 tester.recordPointerPanZoomCallsTo(pan_zoom_records);
485 size_t time_start = g_get_real_time();
486 fl_scrolling_manager_handle_zoom_begin(tester.manager());
487 EXPECT_EQ(pan_zoom_records.size(), 1u);
488 EXPECT_EQ(mouse_records.size(), 0u);
489 EXPECT_EQ(pan_zoom_records[0].x, 0);
490 EXPECT_EQ(pan_zoom_records[0].y, 0);
491 EXPECT_EQ(pan_zoom_records[0].phase, kPanZoomStart);
492 EXPECT_GE(pan_zoom_records[0].timestamp, time_start);
493 fl_scrolling_manager_handle_zoom_update(tester.manager(), 1.1);
494 EXPECT_EQ(pan_zoom_records.size(), 2u);
495 EXPECT_EQ(mouse_records.size(), 0u);
496 EXPECT_EQ(pan_zoom_records[1].x, 0);
497 EXPECT_EQ(pan_zoom_records[1].y, 0);
498 EXPECT_EQ(pan_zoom_records[1].phase, kPanZoomUpdate);
499 EXPECT_GE(pan_zoom_records[1].timestamp, pan_zoom_records[0].timestamp);
500 EXPECT_EQ(pan_zoom_records[1].pan_x, 0);
501 EXPECT_EQ(pan_zoom_records[1].pan_y, 0);
502 EXPECT_EQ(pan_zoom_records[1].scale, 1.1);
503 EXPECT_EQ(pan_zoom_records[1].rotation, 0);
504 fl_scrolling_manager_handle_rotation_begin(tester.manager());
505 EXPECT_EQ(pan_zoom_records.size(), 2u);
506 EXPECT_EQ(mouse_records.size(), 0u);
507 fl_scrolling_manager_handle_rotation_update(tester.manager(), 0.5);
508 EXPECT_EQ(pan_zoom_records.size(), 3u);
509 EXPECT_EQ(pan_zoom_records[2].x, 0);
510 EXPECT_EQ(pan_zoom_records[2].y, 0);
511 EXPECT_EQ(pan_zoom_records[2].phase, kPanZoomUpdate);
512 EXPECT_GE(pan_zoom_records[2].timestamp, pan_zoom_records[1].timestamp);
513 EXPECT_EQ(pan_zoom_records[2].pan_x, 0);
514 EXPECT_EQ(pan_zoom_records[2].pan_y, 0);
515 EXPECT_EQ(pan_zoom_records[2].scale, 1.1);
516 EXPECT_EQ(pan_zoom_records[2].rotation, 0.5);
517 fl_scrolling_manager_handle_zoom_end(tester.manager());
518 // End event should only be sent after both zoom and rotate complete.
519 EXPECT_EQ(pan_zoom_records.size(), 3u);
520 fl_scrolling_manager_handle_rotation_end(tester.manager());
521 EXPECT_EQ(pan_zoom_records.size(), 4u);
522 EXPECT_EQ(mouse_records.size(), 0u);
523 EXPECT_EQ(pan_zoom_records[3].x, 0);
524 EXPECT_EQ(pan_zoom_records[3].y, 0);
525 EXPECT_EQ(pan_zoom_records[3].phase, kPanZoomEnd);
526 EXPECT_GE(pan_zoom_records[3].timestamp, pan_zoom_records[2].timestamp);
527 }
528
529 // Make sure that zoom and rotate sequences which don't end at the same time
530 // don't cause any problems.
531 TEST(FlScrollingManagerTest, UnsynchronizedZoomingAndRotating) {
532 ScrollingTester tester;
533 std::vector<MousePointerEventRecord> mouse_records;
534 std::vector<PointerPanZoomEventRecord> pan_zoom_records;
535 tester.recordMousePointerCallsTo(mouse_records);
536 tester.recordPointerPanZoomCallsTo(pan_zoom_records);
537 size_t time_start = g_get_real_time();
538 fl_scrolling_manager_handle_zoom_begin(tester.manager());
539 EXPECT_EQ(pan_zoom_records.size(), 1u);
540 EXPECT_EQ(mouse_records.size(), 0u);
541 EXPECT_EQ(pan_zoom_records[0].x, 0);
542 EXPECT_EQ(pan_zoom_records[0].y, 0);
543 EXPECT_EQ(pan_zoom_records[0].phase, kPanZoomStart);
544 EXPECT_GE(pan_zoom_records[0].timestamp, time_start);
545 fl_scrolling_manager_handle_zoom_update(tester.manager(), 1.1);
546 EXPECT_EQ(pan_zoom_records.size(), 2u);
547 EXPECT_EQ(mouse_records.size(), 0u);
548 EXPECT_EQ(pan_zoom_records[1].x, 0);
549 EXPECT_EQ(pan_zoom_records[1].y, 0);
550 EXPECT_EQ(pan_zoom_records[1].phase, kPanZoomUpdate);
551 EXPECT_GE(pan_zoom_records[1].timestamp, pan_zoom_records[0].timestamp);
552 EXPECT_EQ(pan_zoom_records[1].pan_x, 0);
553 EXPECT_EQ(pan_zoom_records[1].pan_y, 0);
554 EXPECT_EQ(pan_zoom_records[1].scale, 1.1);
555 EXPECT_EQ(pan_zoom_records[1].rotation, 0);
556 fl_scrolling_manager_handle_rotation_begin(tester.manager());
557 EXPECT_EQ(pan_zoom_records.size(), 2u);
558 EXPECT_EQ(mouse_records.size(), 0u);
559 fl_scrolling_manager_handle_rotation_update(tester.manager(), 0.5);
560 EXPECT_EQ(pan_zoom_records.size(), 3u);
561 EXPECT_EQ(pan_zoom_records[2].x, 0);
562 EXPECT_EQ(pan_zoom_records[2].y, 0);
563 EXPECT_EQ(pan_zoom_records[2].phase, kPanZoomUpdate);
564 EXPECT_GE(pan_zoom_records[2].timestamp, pan_zoom_records[1].timestamp);
565 EXPECT_EQ(pan_zoom_records[2].pan_x, 0);
566 EXPECT_EQ(pan_zoom_records[2].pan_y, 0);
567 EXPECT_EQ(pan_zoom_records[2].scale, 1.1);
568 EXPECT_EQ(pan_zoom_records[2].rotation, 0.5);
569 fl_scrolling_manager_handle_zoom_end(tester.manager());
570 EXPECT_EQ(pan_zoom_records.size(), 3u);
571 fl_scrolling_manager_handle_rotation_update(tester.manager(), 1.0);
572 EXPECT_EQ(pan_zoom_records.size(), 4u);
573 EXPECT_EQ(mouse_records.size(), 0u);
574 EXPECT_EQ(pan_zoom_records[3].x, 0);
575 EXPECT_EQ(pan_zoom_records[3].y, 0);
576 EXPECT_EQ(pan_zoom_records[3].phase, kPanZoomUpdate);
577 EXPECT_GE(pan_zoom_records[3].timestamp, pan_zoom_records[2].timestamp);
578 EXPECT_EQ(pan_zoom_records[3].pan_x, 0);
579 EXPECT_EQ(pan_zoom_records[3].pan_y, 0);
580 EXPECT_EQ(pan_zoom_records[3].scale, 1.1);
581 EXPECT_EQ(pan_zoom_records[3].rotation, 1.0);
582 fl_scrolling_manager_handle_rotation_end(tester.manager());
583 EXPECT_EQ(pan_zoom_records.size(), 5u);
584 EXPECT_EQ(mouse_records.size(), 0u);
585 EXPECT_EQ(pan_zoom_records[4].x, 0);
586 EXPECT_EQ(pan_zoom_records[4].y, 0);
587 EXPECT_EQ(pan_zoom_records[4].phase, kPanZoomEnd);
588 EXPECT_GE(pan_zoom_records[4].timestamp, pan_zoom_records[3].timestamp);
589 }
590
591 } // namespace
event
FlKeyEvent * event
Definition: fl_key_channel_responder.cc:118
fl_scrolling_manager_handle_zoom_end
void fl_scrolling_manager_handle_zoom_end(FlScrollingManager *self)
Definition: fl_scrolling_manager.cc:208
FL_MOCK_SCROLLING_VIEW_DELEGATE_GET_PRIVATE
#define FL_MOCK_SCROLLING_VIEW_DELEGATE_GET_PRIVATE(obj)
fl_scrolling_manager_handle_scroll_event
void fl_scrolling_manager_handle_scroll_event(FlScrollingManager *self, GdkEventScroll *scroll_event, gint scale_factor)
Definition: fl_scrolling_manager.cc:74
priv
FlPixelBufferTexturePrivate * priv
Definition: fl_pixel_buffer_texture.cc:30
fl_scrolling_manager_new
FlScrollingManager * fl_scrolling_manager_new(FlScrollingViewDelegate *view_delegate)
Definition: fl_scrolling_manager.cc:47
fl_scrolling_manager.h
fl_scrolling_manager_handle_zoom_update
void fl_scrolling_manager_handle_zoom_update(FlScrollingManager *self, gdouble scale)
Definition: fl_scrolling_manager.cc:198
G_DECLARE_FINAL_TYPE
G_BEGIN_DECLS G_DECLARE_FINAL_TYPE(FlAccessibleTextField, fl_accessible_text_field, FL, ACCESSIBLE_TEXT_FIELD, FlAccessibleNode)
fl_scrolling_manager_handle_rotation_update
void fl_scrolling_manager_handle_rotation_update(FlScrollingManager *self, gdouble rotation)
Definition: fl_scrolling_manager.cc:164
FL
FL
Definition: fl_binary_messenger.cc:27
fl_scrolling_manager_handle_rotation_end
void fl_scrolling_manager_handle_rotation_end(FlScrollingManager *self)
Definition: fl_scrolling_manager.cc:174
TEST
TEST(FlAccessibleNodeTest, BuildTree)
Definition: fl_accessible_node_test.cc:12
fl_scrolling_manager_handle_rotation_begin
void fl_scrolling_manager_handle_rotation_begin(FlScrollingManager *self)
Definition: fl_scrolling_manager.cc:151
fl_scrolling_manager_handle_zoom_begin
void fl_scrolling_manager_handle_zoom_begin(FlScrollingManager *self)
Definition: fl_scrolling_manager.cc:185
G_DEFINE_TYPE_WITH_CODE
G_DEFINE_TYPE_WITH_CODE(FlAccessibleNode, fl_accessible_node, ATK_TYPE_OBJECT, G_IMPLEMENT_INTERFACE(ATK_TYPE_COMPONENT, fl_accessible_node_component_interface_init) G_IMPLEMENT_INTERFACE(ATK_TYPE_ACTION, fl_accessible_node_action_interface_init)) static gboolean flag_is_changed(FlutterSemanticsFlag old_flags