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