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