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 
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 
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 
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 =
94 
95  new (priv) FlMockScrollingViewDelegatePrivate();
96 }
97 
98 static void fl_mock_scrolling_view_delegate_finalize(GObject* 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 =
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 =
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 =
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 =
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();
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);
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);
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);
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);
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);
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