diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index bebb7ac2b958c..2430f8730bb8f 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -45032,8 +45032,6 @@ ORIGIN: ../../../flutter/shell/platform/linux/fl_renderer_test.cc + ../../../flu ORIGIN: ../../../flutter/shell/platform/linux/fl_scrolling_manager.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/linux/fl_scrolling_manager.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/linux/fl_scrolling_manager_test.cc + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/shell/platform/linux/fl_scrolling_view_delegate.cc + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/shell/platform/linux/fl_scrolling_view_delegate.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/linux/fl_settings.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/linux/fl_settings.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/linux/fl_settings_handler.cc + ../../../flutter/LICENSE @@ -47930,8 +47928,6 @@ FILE: ../../../flutter/shell/platform/linux/fl_renderer_test.cc FILE: ../../../flutter/shell/platform/linux/fl_scrolling_manager.cc FILE: ../../../flutter/shell/platform/linux/fl_scrolling_manager.h FILE: ../../../flutter/shell/platform/linux/fl_scrolling_manager_test.cc -FILE: ../../../flutter/shell/platform/linux/fl_scrolling_view_delegate.cc -FILE: ../../../flutter/shell/platform/linux/fl_scrolling_view_delegate.h FILE: ../../../flutter/shell/platform/linux/fl_settings.cc FILE: ../../../flutter/shell/platform/linux/fl_settings.h FILE: ../../../flutter/shell/platform/linux/fl_settings_handler.cc diff --git a/shell/platform/linux/BUILD.gn b/shell/platform/linux/BUILD.gn index 691358221fdb7..b15f655dac90c 100644 --- a/shell/platform/linux/BUILD.gn +++ b/shell/platform/linux/BUILD.gn @@ -135,7 +135,6 @@ source_set("flutter_linux_sources") { "fl_renderer_gdk.cc", "fl_renderer_headless.cc", "fl_scrolling_manager.cc", - "fl_scrolling_view_delegate.cc", "fl_settings.cc", "fl_settings_handler.cc", "fl_settings_portal.cc", diff --git a/shell/platform/linux/fl_scrolling_manager.cc b/shell/platform/linux/fl_scrolling_manager.cc index 7bfe1a263b97c..e49924a2cae37 100644 --- a/shell/platform/linux/fl_scrolling_manager.cc +++ b/shell/platform/linux/fl_scrolling_manager.cc @@ -3,13 +3,17 @@ // found in the LICENSE file. #include "flutter/shell/platform/linux/fl_scrolling_manager.h" +#include "flutter/shell/platform/embedder/embedder.h" +#include "flutter/shell/platform/linux/fl_engine_private.h" static constexpr int kMicrosecondsPerMillisecond = 1000; struct _FlScrollingManager { GObject parent_instance; - GWeakRef view_delegate; + GWeakRef engine; + + FlutterViewId view_id; gdouble last_x; gdouble last_y; @@ -29,7 +33,7 @@ G_DEFINE_TYPE(FlScrollingManager, fl_scrolling_manager, G_TYPE_OBJECT); static void fl_scrolling_manager_dispose(GObject* object) { FlScrollingManager* self = FL_SCROLLING_MANAGER(object); - g_weak_ref_clear(&self->view_delegate); + g_weak_ref_clear(&self->engine); G_OBJECT_CLASS(fl_scrolling_manager_parent_class)->dispose(object); } @@ -40,14 +44,15 @@ static void fl_scrolling_manager_class_init(FlScrollingManagerClass* klass) { static void fl_scrolling_manager_init(FlScrollingManager* self) {} -FlScrollingManager* fl_scrolling_manager_new( - FlScrollingViewDelegate* view_delegate) { - g_return_val_if_fail(FL_IS_SCROLLING_VIEW_DELEGATE(view_delegate), nullptr); +FlScrollingManager* fl_scrolling_manager_new(FlEngine* engine, + FlutterViewId view_id) { + g_return_val_if_fail(FL_IS_ENGINE(engine), nullptr); FlScrollingManager* self = FL_SCROLLING_MANAGER( g_object_new(fl_scrolling_manager_get_type(), nullptr)); - g_weak_ref_init(&self->view_delegate, view_delegate); + g_weak_ref_init(&self->engine, engine); + self->view_id = view_id; self->pan_started = FALSE; self->zoom_started = FALSE; self->rotate_started = FALSE; @@ -68,9 +73,8 @@ void fl_scrolling_manager_handle_scroll_event(FlScrollingManager* self, gint scale_factor) { g_return_if_fail(FL_IS_SCROLLING_MANAGER(self)); - g_autoptr(FlScrollingViewDelegate) view_delegate = - FL_SCROLLING_VIEW_DELEGATE(g_weak_ref_get(&self->view_delegate)); - if (view_delegate == nullptr) { + g_autoptr(FlEngine) engine = FL_ENGINE(g_weak_ref_get(&self->engine)); + if (engine == nullptr) { return; } @@ -110,8 +114,8 @@ void fl_scrolling_manager_handle_scroll_event(FlScrollingManager* self, scroll_delta_x *= -1; scroll_delta_y *= -1; if (gdk_event_is_scroll_stop_event(event)) { - fl_scrolling_view_delegate_send_pointer_pan_zoom_event( - view_delegate, event_time * kMicrosecondsPerMillisecond, + fl_engine_send_pointer_pan_zoom_event( + engine, self->view_id, event_time * kMicrosecondsPerMillisecond, event_x * scale_factor, event_y * scale_factor, kPanZoomEnd, self->pan_x, self->pan_y, 0, 0); self->pan_started = FALSE; @@ -119,24 +123,24 @@ void fl_scrolling_manager_handle_scroll_event(FlScrollingManager* self, if (!self->pan_started) { self->pan_x = 0; self->pan_y = 0; - fl_scrolling_view_delegate_send_pointer_pan_zoom_event( - view_delegate, event_time * kMicrosecondsPerMillisecond, + fl_engine_send_pointer_pan_zoom_event( + engine, self->view_id, event_time * kMicrosecondsPerMillisecond, event_x * scale_factor, event_y * scale_factor, kPanZoomStart, 0, 0, 0, 0); self->pan_started = TRUE; } self->pan_x += scroll_delta_x; self->pan_y += scroll_delta_y; - fl_scrolling_view_delegate_send_pointer_pan_zoom_event( - view_delegate, event_time * kMicrosecondsPerMillisecond, + fl_engine_send_pointer_pan_zoom_event( + engine, self->view_id, event_time * kMicrosecondsPerMillisecond, event_x * scale_factor, event_y * scale_factor, kPanZoomUpdate, self->pan_x, self->pan_y, 1, 0); } } else { self->last_x = event_x * scale_factor; self->last_y = event_y * scale_factor; - fl_scrolling_view_delegate_send_mouse_pointer_event( - view_delegate, + fl_engine_send_mouse_pointer_event( + engine, self->view_id, FlutterPointerPhase::kMove /* arbitrary value, phase will be ignored as this is a discrete scroll event */ , @@ -149,9 +153,8 @@ void fl_scrolling_manager_handle_scroll_event(FlScrollingManager* self, void fl_scrolling_manager_handle_rotation_begin(FlScrollingManager* self) { g_return_if_fail(FL_IS_SCROLLING_MANAGER(self)); - g_autoptr(FlScrollingViewDelegate) view_delegate = - FL_SCROLLING_VIEW_DELEGATE(g_weak_ref_get(&self->view_delegate)); - if (view_delegate == nullptr) { + g_autoptr(FlEngine) engine = FL_ENGINE(g_weak_ref_get(&self->engine)); + if (engine == nullptr) { return; } @@ -159,8 +162,8 @@ void fl_scrolling_manager_handle_rotation_begin(FlScrollingManager* self) { if (!self->zoom_started) { self->scale = 1; self->rotation = 0; - fl_scrolling_view_delegate_send_pointer_pan_zoom_event( - view_delegate, g_get_real_time(), self->last_x, self->last_y, + fl_engine_send_pointer_pan_zoom_event( + engine, self->view_id, g_get_real_time(), self->last_x, self->last_y, kPanZoomStart, 0, 0, 0, 0); } } @@ -169,31 +172,29 @@ void fl_scrolling_manager_handle_rotation_update(FlScrollingManager* self, gdouble rotation) { g_return_if_fail(FL_IS_SCROLLING_MANAGER(self)); - g_autoptr(FlScrollingViewDelegate) view_delegate = - FL_SCROLLING_VIEW_DELEGATE(g_weak_ref_get(&self->view_delegate)); - if (view_delegate == nullptr) { + g_autoptr(FlEngine) engine = FL_ENGINE(g_weak_ref_get(&self->engine)); + if (engine == nullptr) { return; } self->rotation = rotation; - fl_scrolling_view_delegate_send_pointer_pan_zoom_event( - view_delegate, g_get_real_time(), self->last_x, self->last_y, + fl_engine_send_pointer_pan_zoom_event( + engine, self->view_id, g_get_real_time(), self->last_x, self->last_y, kPanZoomUpdate, 0, 0, self->scale, self->rotation); } void fl_scrolling_manager_handle_rotation_end(FlScrollingManager* self) { g_return_if_fail(FL_IS_SCROLLING_MANAGER(self)); - g_autoptr(FlScrollingViewDelegate) view_delegate = - FL_SCROLLING_VIEW_DELEGATE(g_weak_ref_get(&self->view_delegate)); - if (view_delegate == nullptr) { + g_autoptr(FlEngine) engine = FL_ENGINE(g_weak_ref_get(&self->engine)); + if (engine == nullptr) { return; } self->rotate_started = FALSE; if (!self->zoom_started) { - fl_scrolling_view_delegate_send_pointer_pan_zoom_event( - view_delegate, g_get_real_time(), self->last_x, self->last_y, + fl_engine_send_pointer_pan_zoom_event( + engine, self->view_id, g_get_real_time(), self->last_x, self->last_y, kPanZoomEnd, 0, 0, 0, 0); } } @@ -201,9 +202,8 @@ void fl_scrolling_manager_handle_rotation_end(FlScrollingManager* self) { void fl_scrolling_manager_handle_zoom_begin(FlScrollingManager* self) { g_return_if_fail(FL_IS_SCROLLING_MANAGER(self)); - g_autoptr(FlScrollingViewDelegate) view_delegate = - FL_SCROLLING_VIEW_DELEGATE(g_weak_ref_get(&self->view_delegate)); - if (view_delegate == nullptr) { + g_autoptr(FlEngine) engine = FL_ENGINE(g_weak_ref_get(&self->engine)); + if (engine == nullptr) { return; } @@ -211,8 +211,8 @@ void fl_scrolling_manager_handle_zoom_begin(FlScrollingManager* self) { if (!self->rotate_started) { self->scale = 1; self->rotation = 0; - fl_scrolling_view_delegate_send_pointer_pan_zoom_event( - view_delegate, g_get_real_time(), self->last_x, self->last_y, + fl_engine_send_pointer_pan_zoom_event( + engine, self->view_id, g_get_real_time(), self->last_x, self->last_y, kPanZoomStart, 0, 0, 0, 0); } } @@ -221,31 +221,29 @@ void fl_scrolling_manager_handle_zoom_update(FlScrollingManager* self, gdouble scale) { g_return_if_fail(FL_IS_SCROLLING_MANAGER(self)); - g_autoptr(FlScrollingViewDelegate) view_delegate = - FL_SCROLLING_VIEW_DELEGATE(g_weak_ref_get(&self->view_delegate)); - if (view_delegate == nullptr) { + g_autoptr(FlEngine) engine = FL_ENGINE(g_weak_ref_get(&self->engine)); + if (engine == nullptr) { return; } self->scale = scale; - fl_scrolling_view_delegate_send_pointer_pan_zoom_event( - view_delegate, g_get_real_time(), self->last_x, self->last_y, + fl_engine_send_pointer_pan_zoom_event( + engine, self->view_id, g_get_real_time(), self->last_x, self->last_y, kPanZoomUpdate, 0, 0, self->scale, self->rotation); } void fl_scrolling_manager_handle_zoom_end(FlScrollingManager* self) { g_return_if_fail(FL_IS_SCROLLING_MANAGER(self)); - g_autoptr(FlScrollingViewDelegate) view_delegate = - FL_SCROLLING_VIEW_DELEGATE(g_weak_ref_get(&self->view_delegate)); - if (view_delegate == nullptr) { + g_autoptr(FlEngine) engine = FL_ENGINE(g_weak_ref_get(&self->engine)); + if (engine == nullptr) { return; } self->zoom_started = FALSE; if (!self->rotate_started) { - fl_scrolling_view_delegate_send_pointer_pan_zoom_event( - view_delegate, g_get_real_time(), self->last_x, self->last_y, + fl_engine_send_pointer_pan_zoom_event( + engine, self->view_id, g_get_real_time(), self->last_x, self->last_y, kPanZoomEnd, 0, 0, 0, 0); } } diff --git a/shell/platform/linux/fl_scrolling_manager.h b/shell/platform/linux/fl_scrolling_manager.h index db862317ba5df..551a38e89943d 100644 --- a/shell/platform/linux/fl_scrolling_manager.h +++ b/shell/platform/linux/fl_scrolling_manager.h @@ -7,7 +7,8 @@ #include -#include "flutter/shell/platform/linux/fl_scrolling_view_delegate.h" +#include "flutter/shell/platform/embedder/embedder.h" +#include "flutter/shell/platform/linux/public/flutter_linux/fl_engine.h" G_BEGIN_DECLS @@ -19,15 +20,15 @@ G_DECLARE_FINAL_TYPE(FlScrollingManager, /** * fl_scrolling_manager_new: - * @view_delegate: An interface that the manager requires to communicate with - * the platform. Usually implemented by FlView. + * @engine: an #FlEngine. + * @view_id: the view being managed. * * Create a new #FlScrollingManager. * * Returns: a new #FlScrollingManager. */ -FlScrollingManager* fl_scrolling_manager_new( - FlScrollingViewDelegate* view_delegate); +FlScrollingManager* fl_scrolling_manager_new(FlEngine* engine, + FlutterViewId view_id); /** * fl_scrolling_manager_set_last_mouse_position: diff --git a/shell/platform/linux/fl_scrolling_manager_test.cc b/shell/platform/linux/fl_scrolling_manager_test.cc index 6445b531712d5..05fe2adc31967 100644 --- a/shell/platform/linux/fl_scrolling_manager_test.cc +++ b/shell/platform/linux/fl_scrolling_manager_test.cc @@ -3,247 +3,14 @@ // found in the LICENSE file. #include "flutter/shell/platform/linux/fl_scrolling_manager.h" +#include "flutter/shell/platform/embedder/test_utils/proc_table_replacement.h" +#include "flutter/shell/platform/linux/fl_engine_private.h" +#include "flutter/shell/platform/linux/testing/fl_test.h" #include #include #include "gtest/gtest.h" -namespace { -typedef std::function - MousePointerCallHandler; -typedef std::function - PointerPanZoomCallHandler; - -typedef struct { - FlutterPointerPhase phase; - size_t timestamp; - double x; - double y; - FlutterPointerDeviceKind device_kind; - double scroll_delta_x; - double scroll_delta_y; - int64_t buttons; -} MousePointerEventRecord; - -typedef struct { - size_t timestamp; - double x; - double y; - FlutterPointerPhase phase; - double pan_x; - double pan_y; - double scale; - double rotation; -} PointerPanZoomEventRecord; - -G_BEGIN_DECLS - -G_DECLARE_FINAL_TYPE(FlMockScrollingViewDelegate, - fl_mock_scrolling_view_delegate, - FL, - MOCK_SCROLLING_VIEW_DELEGATE, - GObject) - -G_END_DECLS - -/***** FlMockScrollingViewDelegate *****/ - -struct _FlMockScrollingViewDelegate { - GObject parent_instance; -}; - -struct FlMockScrollingViewDelegatePrivate { - MousePointerCallHandler mouse_handler; - PointerPanZoomCallHandler pan_zoom_handler; -}; - -static void fl_mock_view_scroll_delegate_iface_init( - FlScrollingViewDelegateInterface* iface); - -G_DEFINE_TYPE_WITH_CODE( - FlMockScrollingViewDelegate, - fl_mock_scrolling_view_delegate, - G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE(fl_scrolling_view_delegate_get_type(), - fl_mock_view_scroll_delegate_iface_init); - G_ADD_PRIVATE(FlMockScrollingViewDelegate)) - -#define FL_MOCK_SCROLLING_VIEW_DELEGATE_GET_PRIVATE(obj) \ - static_cast( \ - fl_mock_scrolling_view_delegate_get_instance_private( \ - FL_MOCK_SCROLLING_VIEW_DELEGATE(obj))) - -static void fl_mock_scrolling_view_delegate_init( - FlMockScrollingViewDelegate* self) { - FlMockScrollingViewDelegatePrivate* priv = - FL_MOCK_SCROLLING_VIEW_DELEGATE_GET_PRIVATE(self); - - new (priv) FlMockScrollingViewDelegatePrivate(); -} - -static void fl_mock_scrolling_view_delegate_dispose(GObject* object) { - FL_MOCK_SCROLLING_VIEW_DELEGATE_GET_PRIVATE(object) - ->~FlMockScrollingViewDelegatePrivate(); - - G_OBJECT_CLASS(fl_mock_scrolling_view_delegate_parent_class)->dispose(object); -} - -static void fl_mock_scrolling_view_delegate_class_init( - FlMockScrollingViewDelegateClass* klass) { - G_OBJECT_CLASS(klass)->dispose = fl_mock_scrolling_view_delegate_dispose; -} - -static void fl_mock_view_send_mouse_pointer_event( - FlScrollingViewDelegate* delegate, - FlutterPointerPhase phase, - size_t timestamp, - double x, - double y, - FlutterPointerDeviceKind device_kind, - double scroll_delta_x, - double scroll_delta_y, - int64_t buttons) { - FlMockScrollingViewDelegatePrivate* priv = - FL_MOCK_SCROLLING_VIEW_DELEGATE_GET_PRIVATE(delegate); - priv->mouse_handler(phase, timestamp, x, y, device_kind, scroll_delta_x, - scroll_delta_y, buttons); -} - -static void fl_mock_view_send_pointer_pan_zoom_event( - FlScrollingViewDelegate* delegate, - size_t timestamp, - double x, - double y, - FlutterPointerPhase phase, - double pan_x, - double pan_y, - double scale, - double rotation) { - FlMockScrollingViewDelegatePrivate* priv = - FL_MOCK_SCROLLING_VIEW_DELEGATE_GET_PRIVATE(delegate); - priv->pan_zoom_handler(timestamp, x, y, phase, pan_x, pan_y, scale, rotation); -} - -static void fl_mock_view_scroll_delegate_iface_init( - FlScrollingViewDelegateInterface* iface) { - iface->send_mouse_pointer_event = fl_mock_view_send_mouse_pointer_event; - iface->send_pointer_pan_zoom_event = fl_mock_view_send_pointer_pan_zoom_event; -} - -static FlMockScrollingViewDelegate* fl_mock_scrolling_view_delegate_new() { - FlMockScrollingViewDelegate* self = FL_MOCK_SCROLLING_VIEW_DELEGATE( - g_object_new(fl_mock_scrolling_view_delegate_get_type(), nullptr)); - - // Added to stop compiler complaining about an unused function. - FL_IS_MOCK_SCROLLING_VIEW_DELEGATE(self); - - return self; -} - -static void fl_mock_scrolling_view_set_mouse_handler( - FlMockScrollingViewDelegate* self, - MousePointerCallHandler handler) { - FlMockScrollingViewDelegatePrivate* priv = - FL_MOCK_SCROLLING_VIEW_DELEGATE_GET_PRIVATE(self); - - priv->mouse_handler = std::move(handler); -} - -static void fl_mock_scrolling_view_set_pan_zoom_handler( - FlMockScrollingViewDelegate* self, - PointerPanZoomCallHandler handler) { - FlMockScrollingViewDelegatePrivate* priv = - FL_MOCK_SCROLLING_VIEW_DELEGATE_GET_PRIVATE(self); - - priv->pan_zoom_handler = std::move(handler); -} - -/***** End FlMockScrollingViewDelegate *****/ - -class ScrollingTester { - public: - ScrollingTester() { - view_ = fl_mock_scrolling_view_delegate_new(); - manager_ = fl_scrolling_manager_new(FL_SCROLLING_VIEW_DELEGATE(view_)); - fl_mock_scrolling_view_set_mouse_handler( - view_, - [](FlutterPointerPhase phase, size_t timestamp, double x, double y, - FlutterPointerDeviceKind device_kind, double scroll_delta_x, - double scroll_delta_y, int64_t buttons) { - // do nothing - }); - fl_mock_scrolling_view_set_pan_zoom_handler( - view_, - [](size_t timestamp, double x, double y, FlutterPointerPhase phase, - double pan_x, double pan_y, double scale, double rotation) { - // do nothing - }); - } - - ~ScrollingTester() { - g_clear_object(&view_); - g_clear_object(&manager_); - } - - FlScrollingManager* manager() { return manager_; } - - void recordMousePointerCallsTo( - std::vector& storage) { - fl_mock_scrolling_view_set_mouse_handler( - view_, [&storage](FlutterPointerPhase phase, size_t timestamp, double x, - double y, FlutterPointerDeviceKind device_kind, - double scroll_delta_x, double scroll_delta_y, - int64_t buttons) { - storage.push_back(MousePointerEventRecord{ - .phase = phase, - .timestamp = timestamp, - .x = x, - .y = y, - .device_kind = device_kind, - .scroll_delta_x = scroll_delta_x, - .scroll_delta_y = scroll_delta_y, - .buttons = buttons, - }); - }); - } - - void recordPointerPanZoomCallsTo( - std::vector& storage) { - fl_mock_scrolling_view_set_pan_zoom_handler( - view_, [&storage](size_t timestamp, double x, double y, - FlutterPointerPhase phase, double pan_x, double pan_y, - double scale, double rotation) { - storage.push_back(PointerPanZoomEventRecord{ - .timestamp = timestamp, - .x = x, - .y = y, - .phase = phase, - .pan_x = pan_x, - .pan_y = pan_y, - .scale = scale, - .rotation = rotation, - }); - }); - } - - private: - FlMockScrollingViewDelegate* view_; - FlScrollingManager* manager_; -}; // Disgusting hack but could not find any way to create a GdkDevice struct _FakeGdkDevice { @@ -262,12 +29,23 @@ GdkDevice* makeFakeDevice(GdkInputSource source) { return reinterpret_cast(device); } -TEST(FlScrollingManagerTest, DiscreteDirectionional) { - ScrollingTester tester; - std::vector mouse_records; - std::vector pan_zoom_records; - tester.recordMousePointerCallsTo(mouse_records); - tester.recordPointerPanZoomCallsTo(pan_zoom_records); +TEST(FlScrollingManagerTest, DiscreteDirectional) { + g_autoptr(FlEngine) engine = make_mock_engine(); + FlutterEngineProcTable* embedder_api = fl_engine_get_embedder_api(engine); + std::vector pointer_events; + embedder_api->SendPointerEvent = MOCK_ENGINE_PROC( + SendPointerEvent, + ([&pointer_events](auto engine, const FlutterPointerEvent* events, + size_t events_count) { + for (size_t i = 0; i < events_count; i++) { + pointer_events.push_back(events[i]); + } + + return kSuccess; + })); + + g_autoptr(FlScrollingManager) manager = fl_scrolling_manager_new(engine, 0); + GdkDevice* mouse = makeFakeDevice(GDK_SOURCE_MOUSE); GdkEventScroll* event = reinterpret_cast(gdk_event_new(GDK_SCROLL)); @@ -276,57 +54,64 @@ TEST(FlScrollingManagerTest, DiscreteDirectionional) { event->y = 8.0; event->device = mouse; event->direction = GDK_SCROLL_UP; - fl_scrolling_manager_handle_scroll_event(tester.manager(), event, 1.0); - EXPECT_EQ(pan_zoom_records.size(), 0u); - EXPECT_EQ(mouse_records.size(), 1u); - EXPECT_EQ(mouse_records[0].x, 4.0); - EXPECT_EQ(mouse_records[0].y, 8.0); - EXPECT_EQ(mouse_records[0].device_kind, kFlutterPointerDeviceKindMouse); - EXPECT_EQ(mouse_records[0].timestamp, + fl_scrolling_manager_handle_scroll_event(manager, event, 1.0); + EXPECT_EQ(pointer_events.size(), 1u); + EXPECT_EQ(pointer_events[0].x, 4.0); + EXPECT_EQ(pointer_events[0].y, 8.0); + EXPECT_EQ(pointer_events[0].device_kind, kFlutterPointerDeviceKindMouse); + EXPECT_EQ(pointer_events[0].timestamp, 1000lu); // Milliseconds -> Microseconds - EXPECT_EQ(mouse_records[0].scroll_delta_x, 0); - EXPECT_EQ(mouse_records[0].scroll_delta_y, 53 * -1.0); + EXPECT_EQ(pointer_events[0].scroll_delta_x, 0); + EXPECT_EQ(pointer_events[0].scroll_delta_y, 53 * -1.0); event->direction = GDK_SCROLL_DOWN; - fl_scrolling_manager_handle_scroll_event(tester.manager(), event, 1.0); - EXPECT_EQ(pan_zoom_records.size(), 0u); - EXPECT_EQ(mouse_records.size(), 2u); - EXPECT_EQ(mouse_records[1].x, 4.0); - EXPECT_EQ(mouse_records[1].y, 8.0); - EXPECT_EQ(mouse_records[1].device_kind, kFlutterPointerDeviceKindMouse); - EXPECT_EQ(mouse_records[1].timestamp, + fl_scrolling_manager_handle_scroll_event(manager, event, 1.0); + EXPECT_EQ(pointer_events.size(), 2u); + EXPECT_EQ(pointer_events[1].x, 4.0); + EXPECT_EQ(pointer_events[1].y, 8.0); + EXPECT_EQ(pointer_events[1].device_kind, kFlutterPointerDeviceKindMouse); + EXPECT_EQ(pointer_events[1].timestamp, 1000lu); // Milliseconds -> Microseconds - EXPECT_EQ(mouse_records[1].scroll_delta_x, 0); - EXPECT_EQ(mouse_records[1].scroll_delta_y, 53 * 1.0); + EXPECT_EQ(pointer_events[1].scroll_delta_x, 0); + EXPECT_EQ(pointer_events[1].scroll_delta_y, 53 * 1.0); event->direction = GDK_SCROLL_LEFT; - fl_scrolling_manager_handle_scroll_event(tester.manager(), event, 1.0); - EXPECT_EQ(pan_zoom_records.size(), 0u); - EXPECT_EQ(mouse_records.size(), 3u); - EXPECT_EQ(mouse_records[2].x, 4.0); - EXPECT_EQ(mouse_records[2].y, 8.0); - EXPECT_EQ(mouse_records[2].device_kind, kFlutterPointerDeviceKindMouse); - EXPECT_EQ(mouse_records[2].timestamp, + fl_scrolling_manager_handle_scroll_event(manager, event, 1.0); + EXPECT_EQ(pointer_events.size(), 3u); + EXPECT_EQ(pointer_events[2].x, 4.0); + EXPECT_EQ(pointer_events[2].y, 8.0); + EXPECT_EQ(pointer_events[2].device_kind, kFlutterPointerDeviceKindMouse); + EXPECT_EQ(pointer_events[2].timestamp, 1000lu); // Milliseconds -> Microseconds - EXPECT_EQ(mouse_records[2].scroll_delta_x, 53 * -1.0); - EXPECT_EQ(mouse_records[2].scroll_delta_y, 0); + EXPECT_EQ(pointer_events[2].scroll_delta_x, 53 * -1.0); + EXPECT_EQ(pointer_events[2].scroll_delta_y, 0); event->direction = GDK_SCROLL_RIGHT; - fl_scrolling_manager_handle_scroll_event(tester.manager(), event, 1.0); - EXPECT_EQ(pan_zoom_records.size(), 0u); - EXPECT_EQ(mouse_records.size(), 4u); - EXPECT_EQ(mouse_records[3].x, 4.0); - EXPECT_EQ(mouse_records[3].y, 8.0); - EXPECT_EQ(mouse_records[3].device_kind, kFlutterPointerDeviceKindMouse); - EXPECT_EQ(mouse_records[3].timestamp, + fl_scrolling_manager_handle_scroll_event(manager, event, 1.0); + EXPECT_EQ(pointer_events.size(), 4u); + EXPECT_EQ(pointer_events[3].x, 4.0); + EXPECT_EQ(pointer_events[3].y, 8.0); + EXPECT_EQ(pointer_events[3].device_kind, kFlutterPointerDeviceKindMouse); + EXPECT_EQ(pointer_events[3].timestamp, 1000lu); // Milliseconds -> Microseconds - EXPECT_EQ(mouse_records[3].scroll_delta_x, 53 * 1.0); - EXPECT_EQ(mouse_records[3].scroll_delta_y, 0); + EXPECT_EQ(pointer_events[3].scroll_delta_x, 53 * 1.0); + EXPECT_EQ(pointer_events[3].scroll_delta_y, 0); } TEST(FlScrollingManagerTest, DiscreteScrolling) { - ScrollingTester tester; - std::vector mouse_records; - std::vector pan_zoom_records; - tester.recordMousePointerCallsTo(mouse_records); - tester.recordPointerPanZoomCallsTo(pan_zoom_records); + g_autoptr(FlEngine) engine = make_mock_engine(); + FlutterEngineProcTable* embedder_api = fl_engine_get_embedder_api(engine); + std::vector pointer_events; + embedder_api->SendPointerEvent = MOCK_ENGINE_PROC( + SendPointerEvent, + ([&pointer_events](auto engine, const FlutterPointerEvent* events, + size_t events_count) { + for (size_t i = 0; i < events_count; i++) { + pointer_events.push_back(events[i]); + } + + return kSuccess; + })); + + g_autoptr(FlScrollingManager) manager = fl_scrolling_manager_new(engine, 0); + GdkDevice* mouse = makeFakeDevice(GDK_SOURCE_MOUSE); GdkEventScroll* event = reinterpret_cast(gdk_event_new(GDK_SCROLL)); @@ -337,24 +122,34 @@ TEST(FlScrollingManagerTest, DiscreteScrolling) { event->delta_y = 2.0; event->device = mouse; event->direction = GDK_SCROLL_SMOOTH; - fl_scrolling_manager_handle_scroll_event(tester.manager(), event, 1.0); - EXPECT_EQ(pan_zoom_records.size(), 0u); - EXPECT_EQ(mouse_records.size(), 1u); - EXPECT_EQ(mouse_records[0].x, 4.0); - EXPECT_EQ(mouse_records[0].y, 8.0); - EXPECT_EQ(mouse_records[0].device_kind, kFlutterPointerDeviceKindMouse); - EXPECT_EQ(mouse_records[0].timestamp, + fl_scrolling_manager_handle_scroll_event(manager, event, 1.0); + EXPECT_EQ(pointer_events.size(), 1u); + EXPECT_EQ(pointer_events[0].x, 4.0); + EXPECT_EQ(pointer_events[0].y, 8.0); + EXPECT_EQ(pointer_events[0].device_kind, kFlutterPointerDeviceKindMouse); + EXPECT_EQ(pointer_events[0].timestamp, 1000lu); // Milliseconds -> Microseconds - EXPECT_EQ(mouse_records[0].scroll_delta_x, 53 * 1.0); - EXPECT_EQ(mouse_records[0].scroll_delta_y, 53 * 2.0); + EXPECT_EQ(pointer_events[0].scroll_delta_x, 53 * 1.0); + EXPECT_EQ(pointer_events[0].scroll_delta_y, 53 * 2.0); } TEST(FlScrollingManagerTest, Panning) { - ScrollingTester tester; - std::vector mouse_records; - std::vector pan_zoom_records; - tester.recordMousePointerCallsTo(mouse_records); - tester.recordPointerPanZoomCallsTo(pan_zoom_records); + g_autoptr(FlEngine) engine = make_mock_engine(); + FlutterEngineProcTable* embedder_api = fl_engine_get_embedder_api(engine); + std::vector pointer_events; + embedder_api->SendPointerEvent = MOCK_ENGINE_PROC( + SendPointerEvent, + ([&pointer_events](auto engine, const FlutterPointerEvent* events, + size_t events_count) { + for (size_t i = 0; i < events_count; i++) { + pointer_events.push_back(events[i]); + } + + return kSuccess; + })); + + g_autoptr(FlScrollingManager) manager = fl_scrolling_manager_new(engine, 0); + GdkDevice* touchpad = makeFakeDevice(GDK_SOURCE_TOUCHPAD); GdkEventScroll* event = reinterpret_cast(gdk_event_new(GDK_SCROLL)); @@ -365,224 +160,248 @@ TEST(FlScrollingManagerTest, Panning) { event->delta_y = 2.0; event->device = touchpad; event->direction = GDK_SCROLL_SMOOTH; - fl_scrolling_manager_handle_scroll_event(tester.manager(), event, 1.0); - EXPECT_EQ(pan_zoom_records.size(), 2u); - EXPECT_EQ(mouse_records.size(), 0u); - EXPECT_EQ(pan_zoom_records[0].x, 4.0); - EXPECT_EQ(pan_zoom_records[0].y, 8.0); - EXPECT_EQ(pan_zoom_records[0].timestamp, + fl_scrolling_manager_handle_scroll_event(manager, event, 1.0); + EXPECT_EQ(pointer_events.size(), 2u); + EXPECT_EQ(pointer_events[0].x, 4.0); + EXPECT_EQ(pointer_events[0].y, 8.0); + EXPECT_EQ(pointer_events[0].timestamp, 1000lu); // Milliseconds -> Microseconds - EXPECT_EQ(pan_zoom_records[0].phase, kPanZoomStart); - EXPECT_EQ(pan_zoom_records[1].x, 4.0); - EXPECT_EQ(pan_zoom_records[1].y, 8.0); - EXPECT_EQ(pan_zoom_records[1].timestamp, + EXPECT_EQ(pointer_events[0].phase, kPanZoomStart); + EXPECT_EQ(pointer_events[1].x, 4.0); + EXPECT_EQ(pointer_events[1].y, 8.0); + EXPECT_EQ(pointer_events[1].timestamp, 1000lu); // Milliseconds -> Microseconds - EXPECT_EQ(pan_zoom_records[1].phase, kPanZoomUpdate); - EXPECT_EQ(pan_zoom_records[1].pan_x, 53 * -1.0); // directions get swapped - EXPECT_EQ(pan_zoom_records[1].pan_y, 53 * -2.0); - EXPECT_EQ(pan_zoom_records[1].scale, 1.0); - EXPECT_EQ(pan_zoom_records[1].rotation, 0.0); - fl_scrolling_manager_handle_scroll_event(tester.manager(), event, 1.0); - EXPECT_EQ(pan_zoom_records.size(), 3u); - EXPECT_EQ(mouse_records.size(), 0u); - EXPECT_EQ(pan_zoom_records[2].x, 4.0); - EXPECT_EQ(pan_zoom_records[2].y, 8.0); - EXPECT_EQ(pan_zoom_records[2].timestamp, + EXPECT_EQ(pointer_events[1].phase, kPanZoomUpdate); + EXPECT_EQ(pointer_events[1].pan_x, 53 * -1.0); // directions get swapped + EXPECT_EQ(pointer_events[1].pan_y, 53 * -2.0); + EXPECT_EQ(pointer_events[1].scale, 1.0); + EXPECT_EQ(pointer_events[1].rotation, 0.0); + fl_scrolling_manager_handle_scroll_event(manager, event, 1.0); + EXPECT_EQ(pointer_events.size(), 3u); + EXPECT_EQ(pointer_events[2].x, 4.0); + EXPECT_EQ(pointer_events[2].y, 8.0); + EXPECT_EQ(pointer_events[2].timestamp, 1000lu); // Milliseconds -> Microseconds - EXPECT_EQ(pan_zoom_records[2].phase, kPanZoomUpdate); - EXPECT_EQ(pan_zoom_records[2].pan_x, 53 * -2.0); // directions get swapped - EXPECT_EQ(pan_zoom_records[2].pan_y, 53 * -4.0); - EXPECT_EQ(pan_zoom_records[2].scale, 1.0); - EXPECT_EQ(pan_zoom_records[2].rotation, 0.0); + EXPECT_EQ(pointer_events[2].phase, kPanZoomUpdate); + EXPECT_EQ(pointer_events[2].pan_x, 53 * -2.0); // directions get swapped + EXPECT_EQ(pointer_events[2].pan_y, 53 * -4.0); + EXPECT_EQ(pointer_events[2].scale, 1.0); + EXPECT_EQ(pointer_events[2].rotation, 0.0); event->is_stop = true; - fl_scrolling_manager_handle_scroll_event(tester.manager(), event, 1.0); - EXPECT_EQ(pan_zoom_records.size(), 4u); - EXPECT_EQ(mouse_records.size(), 0u); - EXPECT_EQ(pan_zoom_records[3].x, 4.0); - EXPECT_EQ(pan_zoom_records[3].y, 8.0); - EXPECT_EQ(pan_zoom_records[3].timestamp, + fl_scrolling_manager_handle_scroll_event(manager, event, 1.0); + EXPECT_EQ(pointer_events.size(), 4u); + EXPECT_EQ(pointer_events[3].x, 4.0); + EXPECT_EQ(pointer_events[3].y, 8.0); + EXPECT_EQ(pointer_events[3].timestamp, 1000lu); // Milliseconds -> Microseconds - EXPECT_EQ(pan_zoom_records[3].phase, kPanZoomEnd); + EXPECT_EQ(pointer_events[3].phase, kPanZoomEnd); } TEST(FlScrollingManagerTest, Zooming) { - ScrollingTester tester; - std::vector mouse_records; - std::vector pan_zoom_records; - tester.recordMousePointerCallsTo(mouse_records); - tester.recordPointerPanZoomCallsTo(pan_zoom_records); + g_autoptr(FlEngine) engine = make_mock_engine(); + FlutterEngineProcTable* embedder_api = fl_engine_get_embedder_api(engine); + std::vector pointer_events; + embedder_api->SendPointerEvent = MOCK_ENGINE_PROC( + SendPointerEvent, + ([&pointer_events](auto engine, const FlutterPointerEvent* events, + size_t events_count) { + for (size_t i = 0; i < events_count; i++) { + pointer_events.push_back(events[i]); + } + + return kSuccess; + })); + + g_autoptr(FlScrollingManager) manager = fl_scrolling_manager_new(engine, 0); + size_t time_start = g_get_real_time(); - fl_scrolling_manager_handle_zoom_begin(tester.manager()); - EXPECT_EQ(pan_zoom_records.size(), 1u); - EXPECT_EQ(mouse_records.size(), 0u); - EXPECT_EQ(pan_zoom_records[0].x, 0); - EXPECT_EQ(pan_zoom_records[0].y, 0); - EXPECT_EQ(pan_zoom_records[0].phase, kPanZoomStart); - EXPECT_GE(pan_zoom_records[0].timestamp, time_start); - fl_scrolling_manager_handle_zoom_update(tester.manager(), 1.1); - EXPECT_EQ(pan_zoom_records.size(), 2u); - EXPECT_EQ(mouse_records.size(), 0u); - EXPECT_EQ(pan_zoom_records[1].x, 0); - EXPECT_EQ(pan_zoom_records[1].y, 0); - EXPECT_EQ(pan_zoom_records[1].phase, kPanZoomUpdate); - EXPECT_GE(pan_zoom_records[1].timestamp, pan_zoom_records[0].timestamp); - EXPECT_EQ(pan_zoom_records[1].pan_x, 0); - EXPECT_EQ(pan_zoom_records[1].pan_y, 0); - EXPECT_EQ(pan_zoom_records[1].scale, 1.1); - EXPECT_EQ(pan_zoom_records[1].rotation, 0); - fl_scrolling_manager_handle_zoom_end(tester.manager()); - EXPECT_EQ(pan_zoom_records.size(), 3u); - EXPECT_EQ(mouse_records.size(), 0u); - EXPECT_EQ(pan_zoom_records[2].x, 0); - EXPECT_EQ(pan_zoom_records[2].y, 0); - EXPECT_EQ(pan_zoom_records[2].phase, kPanZoomEnd); - EXPECT_GE(pan_zoom_records[2].timestamp, pan_zoom_records[1].timestamp); + fl_scrolling_manager_handle_zoom_begin(manager); + EXPECT_EQ(pointer_events.size(), 1u); + EXPECT_EQ(pointer_events[0].x, 0); + EXPECT_EQ(pointer_events[0].y, 0); + EXPECT_EQ(pointer_events[0].phase, kPanZoomStart); + EXPECT_GE(pointer_events[0].timestamp, time_start); + fl_scrolling_manager_handle_zoom_update(manager, 1.1); + EXPECT_EQ(pointer_events.size(), 2u); + EXPECT_EQ(pointer_events[1].x, 0); + EXPECT_EQ(pointer_events[1].y, 0); + EXPECT_EQ(pointer_events[1].phase, kPanZoomUpdate); + EXPECT_GE(pointer_events[1].timestamp, pointer_events[0].timestamp); + EXPECT_EQ(pointer_events[1].pan_x, 0); + EXPECT_EQ(pointer_events[1].pan_y, 0); + EXPECT_EQ(pointer_events[1].scale, 1.1); + EXPECT_EQ(pointer_events[1].rotation, 0); + fl_scrolling_manager_handle_zoom_end(manager); + EXPECT_EQ(pointer_events.size(), 3u); + EXPECT_EQ(pointer_events[2].x, 0); + EXPECT_EQ(pointer_events[2].y, 0); + EXPECT_EQ(pointer_events[2].phase, kPanZoomEnd); + EXPECT_GE(pointer_events[2].timestamp, pointer_events[1].timestamp); } TEST(FlScrollingManagerTest, Rotating) { - ScrollingTester tester; - std::vector mouse_records; - std::vector pan_zoom_records; - tester.recordMousePointerCallsTo(mouse_records); - tester.recordPointerPanZoomCallsTo(pan_zoom_records); + g_autoptr(FlEngine) engine = make_mock_engine(); + FlutterEngineProcTable* embedder_api = fl_engine_get_embedder_api(engine); + std::vector pointer_events; + embedder_api->SendPointerEvent = MOCK_ENGINE_PROC( + SendPointerEvent, + ([&pointer_events](auto engine, const FlutterPointerEvent* events, + size_t events_count) { + for (size_t i = 0; i < events_count; i++) { + pointer_events.push_back(events[i]); + } + + return kSuccess; + })); + + g_autoptr(FlScrollingManager) manager = fl_scrolling_manager_new(engine, 0); + size_t time_start = g_get_real_time(); - fl_scrolling_manager_handle_rotation_begin(tester.manager()); - EXPECT_EQ(pan_zoom_records.size(), 1u); - EXPECT_EQ(mouse_records.size(), 0u); - EXPECT_EQ(pan_zoom_records[0].x, 0); - EXPECT_EQ(pan_zoom_records[0].y, 0); - EXPECT_EQ(pan_zoom_records[0].phase, kPanZoomStart); - EXPECT_GE(pan_zoom_records[0].timestamp, time_start); - fl_scrolling_manager_handle_rotation_update(tester.manager(), 0.5); - EXPECT_EQ(pan_zoom_records.size(), 2u); - EXPECT_EQ(mouse_records.size(), 0u); - EXPECT_EQ(pan_zoom_records[1].x, 0); - EXPECT_EQ(pan_zoom_records[1].y, 0); - EXPECT_EQ(pan_zoom_records[1].phase, kPanZoomUpdate); - EXPECT_GE(pan_zoom_records[1].timestamp, pan_zoom_records[0].timestamp); - EXPECT_EQ(pan_zoom_records[1].pan_x, 0); - EXPECT_EQ(pan_zoom_records[1].pan_y, 0); - EXPECT_EQ(pan_zoom_records[1].scale, 1.0); - EXPECT_EQ(pan_zoom_records[1].rotation, 0.5); - fl_scrolling_manager_handle_rotation_end(tester.manager()); - EXPECT_EQ(pan_zoom_records.size(), 3u); - EXPECT_EQ(mouse_records.size(), 0u); - EXPECT_EQ(pan_zoom_records[2].x, 0); - EXPECT_EQ(pan_zoom_records[2].y, 0); - EXPECT_EQ(pan_zoom_records[2].phase, kPanZoomEnd); - EXPECT_GE(pan_zoom_records[2].timestamp, pan_zoom_records[1].timestamp); + fl_scrolling_manager_handle_rotation_begin(manager); + EXPECT_EQ(pointer_events.size(), 1u); + EXPECT_EQ(pointer_events[0].x, 0); + EXPECT_EQ(pointer_events[0].y, 0); + EXPECT_EQ(pointer_events[0].phase, kPanZoomStart); + EXPECT_GE(pointer_events[0].timestamp, time_start); + fl_scrolling_manager_handle_rotation_update(manager, 0.5); + EXPECT_EQ(pointer_events.size(), 2u); + EXPECT_EQ(pointer_events[1].x, 0); + EXPECT_EQ(pointer_events[1].y, 0); + EXPECT_EQ(pointer_events[1].phase, kPanZoomUpdate); + EXPECT_GE(pointer_events[1].timestamp, pointer_events[0].timestamp); + EXPECT_EQ(pointer_events[1].pan_x, 0); + EXPECT_EQ(pointer_events[1].pan_y, 0); + EXPECT_EQ(pointer_events[1].scale, 1.0); + EXPECT_EQ(pointer_events[1].rotation, 0.5); + fl_scrolling_manager_handle_rotation_end(manager); + EXPECT_EQ(pointer_events.size(), 3u); + EXPECT_EQ(pointer_events[2].x, 0); + EXPECT_EQ(pointer_events[2].y, 0); + EXPECT_EQ(pointer_events[2].phase, kPanZoomEnd); + EXPECT_GE(pointer_events[2].timestamp, pointer_events[1].timestamp); } TEST(FlScrollingManagerTest, SynchronizedZoomingAndRotating) { - ScrollingTester tester; - std::vector mouse_records; - std::vector pan_zoom_records; - tester.recordMousePointerCallsTo(mouse_records); - tester.recordPointerPanZoomCallsTo(pan_zoom_records); + g_autoptr(FlEngine) engine = make_mock_engine(); + FlutterEngineProcTable* embedder_api = fl_engine_get_embedder_api(engine); + std::vector pointer_events; + embedder_api->SendPointerEvent = MOCK_ENGINE_PROC( + SendPointerEvent, + ([&pointer_events](auto engine, const FlutterPointerEvent* events, + size_t events_count) { + for (size_t i = 0; i < events_count; i++) { + pointer_events.push_back(events[i]); + } + + return kSuccess; + })); + + g_autoptr(FlScrollingManager) manager = fl_scrolling_manager_new(engine, 0); + size_t time_start = g_get_real_time(); - fl_scrolling_manager_handle_zoom_begin(tester.manager()); - EXPECT_EQ(pan_zoom_records.size(), 1u); - EXPECT_EQ(mouse_records.size(), 0u); - EXPECT_EQ(pan_zoom_records[0].x, 0); - EXPECT_EQ(pan_zoom_records[0].y, 0); - EXPECT_EQ(pan_zoom_records[0].phase, kPanZoomStart); - EXPECT_GE(pan_zoom_records[0].timestamp, time_start); - fl_scrolling_manager_handle_zoom_update(tester.manager(), 1.1); - EXPECT_EQ(pan_zoom_records.size(), 2u); - EXPECT_EQ(mouse_records.size(), 0u); - EXPECT_EQ(pan_zoom_records[1].x, 0); - EXPECT_EQ(pan_zoom_records[1].y, 0); - EXPECT_EQ(pan_zoom_records[1].phase, kPanZoomUpdate); - EXPECT_GE(pan_zoom_records[1].timestamp, pan_zoom_records[0].timestamp); - EXPECT_EQ(pan_zoom_records[1].pan_x, 0); - EXPECT_EQ(pan_zoom_records[1].pan_y, 0); - EXPECT_EQ(pan_zoom_records[1].scale, 1.1); - EXPECT_EQ(pan_zoom_records[1].rotation, 0); - fl_scrolling_manager_handle_rotation_begin(tester.manager()); - EXPECT_EQ(pan_zoom_records.size(), 2u); - EXPECT_EQ(mouse_records.size(), 0u); - fl_scrolling_manager_handle_rotation_update(tester.manager(), 0.5); - EXPECT_EQ(pan_zoom_records.size(), 3u); - EXPECT_EQ(pan_zoom_records[2].x, 0); - EXPECT_EQ(pan_zoom_records[2].y, 0); - EXPECT_EQ(pan_zoom_records[2].phase, kPanZoomUpdate); - EXPECT_GE(pan_zoom_records[2].timestamp, pan_zoom_records[1].timestamp); - EXPECT_EQ(pan_zoom_records[2].pan_x, 0); - EXPECT_EQ(pan_zoom_records[2].pan_y, 0); - EXPECT_EQ(pan_zoom_records[2].scale, 1.1); - EXPECT_EQ(pan_zoom_records[2].rotation, 0.5); - fl_scrolling_manager_handle_zoom_end(tester.manager()); + fl_scrolling_manager_handle_zoom_begin(manager); + EXPECT_EQ(pointer_events.size(), 1u); + EXPECT_EQ(pointer_events[0].x, 0); + EXPECT_EQ(pointer_events[0].y, 0); + EXPECT_EQ(pointer_events[0].phase, kPanZoomStart); + EXPECT_GE(pointer_events[0].timestamp, time_start); + fl_scrolling_manager_handle_zoom_update(manager, 1.1); + EXPECT_EQ(pointer_events.size(), 2u); + EXPECT_EQ(pointer_events[1].x, 0); + EXPECT_EQ(pointer_events[1].y, 0); + EXPECT_EQ(pointer_events[1].phase, kPanZoomUpdate); + EXPECT_GE(pointer_events[1].timestamp, pointer_events[0].timestamp); + EXPECT_EQ(pointer_events[1].pan_x, 0); + EXPECT_EQ(pointer_events[1].pan_y, 0); + EXPECT_EQ(pointer_events[1].scale, 1.1); + EXPECT_EQ(pointer_events[1].rotation, 0); + fl_scrolling_manager_handle_rotation_begin(manager); + EXPECT_EQ(pointer_events.size(), 2u); + fl_scrolling_manager_handle_rotation_update(manager, 0.5); + EXPECT_EQ(pointer_events.size(), 3u); + EXPECT_EQ(pointer_events[2].x, 0); + EXPECT_EQ(pointer_events[2].y, 0); + EXPECT_EQ(pointer_events[2].phase, kPanZoomUpdate); + EXPECT_GE(pointer_events[2].timestamp, pointer_events[1].timestamp); + EXPECT_EQ(pointer_events[2].pan_x, 0); + EXPECT_EQ(pointer_events[2].pan_y, 0); + EXPECT_EQ(pointer_events[2].scale, 1.1); + EXPECT_EQ(pointer_events[2].rotation, 0.5); + fl_scrolling_manager_handle_zoom_end(manager); // End event should only be sent after both zoom and rotate complete. - EXPECT_EQ(pan_zoom_records.size(), 3u); - fl_scrolling_manager_handle_rotation_end(tester.manager()); - EXPECT_EQ(pan_zoom_records.size(), 4u); - EXPECT_EQ(mouse_records.size(), 0u); - EXPECT_EQ(pan_zoom_records[3].x, 0); - EXPECT_EQ(pan_zoom_records[3].y, 0); - EXPECT_EQ(pan_zoom_records[3].phase, kPanZoomEnd); - EXPECT_GE(pan_zoom_records[3].timestamp, pan_zoom_records[2].timestamp); + EXPECT_EQ(pointer_events.size(), 3u); + fl_scrolling_manager_handle_rotation_end(manager); + EXPECT_EQ(pointer_events.size(), 4u); + EXPECT_EQ(pointer_events[3].x, 0); + EXPECT_EQ(pointer_events[3].y, 0); + EXPECT_EQ(pointer_events[3].phase, kPanZoomEnd); + EXPECT_GE(pointer_events[3].timestamp, pointer_events[2].timestamp); } // Make sure that zoom and rotate sequences which don't end at the same time // don't cause any problems. TEST(FlScrollingManagerTest, UnsynchronizedZoomingAndRotating) { - ScrollingTester tester; - std::vector mouse_records; - std::vector pan_zoom_records; - tester.recordMousePointerCallsTo(mouse_records); - tester.recordPointerPanZoomCallsTo(pan_zoom_records); + g_autoptr(FlEngine) engine = make_mock_engine(); + FlutterEngineProcTable* embedder_api = fl_engine_get_embedder_api(engine); + std::vector pointer_events; + embedder_api->SendPointerEvent = MOCK_ENGINE_PROC( + SendPointerEvent, + ([&pointer_events](auto engine, const FlutterPointerEvent* events, + size_t events_count) { + for (size_t i = 0; i < events_count; i++) { + pointer_events.push_back(events[i]); + } + + return kSuccess; + })); + + g_autoptr(FlScrollingManager) manager = fl_scrolling_manager_new(engine, 0); + size_t time_start = g_get_real_time(); - fl_scrolling_manager_handle_zoom_begin(tester.manager()); - EXPECT_EQ(pan_zoom_records.size(), 1u); - EXPECT_EQ(mouse_records.size(), 0u); - EXPECT_EQ(pan_zoom_records[0].x, 0); - EXPECT_EQ(pan_zoom_records[0].y, 0); - EXPECT_EQ(pan_zoom_records[0].phase, kPanZoomStart); - EXPECT_GE(pan_zoom_records[0].timestamp, time_start); - fl_scrolling_manager_handle_zoom_update(tester.manager(), 1.1); - EXPECT_EQ(pan_zoom_records.size(), 2u); - EXPECT_EQ(mouse_records.size(), 0u); - EXPECT_EQ(pan_zoom_records[1].x, 0); - EXPECT_EQ(pan_zoom_records[1].y, 0); - EXPECT_EQ(pan_zoom_records[1].phase, kPanZoomUpdate); - EXPECT_GE(pan_zoom_records[1].timestamp, pan_zoom_records[0].timestamp); - EXPECT_EQ(pan_zoom_records[1].pan_x, 0); - EXPECT_EQ(pan_zoom_records[1].pan_y, 0); - EXPECT_EQ(pan_zoom_records[1].scale, 1.1); - EXPECT_EQ(pan_zoom_records[1].rotation, 0); - fl_scrolling_manager_handle_rotation_begin(tester.manager()); - EXPECT_EQ(pan_zoom_records.size(), 2u); - EXPECT_EQ(mouse_records.size(), 0u); - fl_scrolling_manager_handle_rotation_update(tester.manager(), 0.5); - EXPECT_EQ(pan_zoom_records.size(), 3u); - EXPECT_EQ(pan_zoom_records[2].x, 0); - EXPECT_EQ(pan_zoom_records[2].y, 0); - EXPECT_EQ(pan_zoom_records[2].phase, kPanZoomUpdate); - EXPECT_GE(pan_zoom_records[2].timestamp, pan_zoom_records[1].timestamp); - EXPECT_EQ(pan_zoom_records[2].pan_x, 0); - EXPECT_EQ(pan_zoom_records[2].pan_y, 0); - EXPECT_EQ(pan_zoom_records[2].scale, 1.1); - EXPECT_EQ(pan_zoom_records[2].rotation, 0.5); - fl_scrolling_manager_handle_zoom_end(tester.manager()); - EXPECT_EQ(pan_zoom_records.size(), 3u); - fl_scrolling_manager_handle_rotation_update(tester.manager(), 1.0); - EXPECT_EQ(pan_zoom_records.size(), 4u); - EXPECT_EQ(mouse_records.size(), 0u); - EXPECT_EQ(pan_zoom_records[3].x, 0); - EXPECT_EQ(pan_zoom_records[3].y, 0); - EXPECT_EQ(pan_zoom_records[3].phase, kPanZoomUpdate); - EXPECT_GE(pan_zoom_records[3].timestamp, pan_zoom_records[2].timestamp); - EXPECT_EQ(pan_zoom_records[3].pan_x, 0); - EXPECT_EQ(pan_zoom_records[3].pan_y, 0); - EXPECT_EQ(pan_zoom_records[3].scale, 1.1); - EXPECT_EQ(pan_zoom_records[3].rotation, 1.0); - fl_scrolling_manager_handle_rotation_end(tester.manager()); - EXPECT_EQ(pan_zoom_records.size(), 5u); - EXPECT_EQ(mouse_records.size(), 0u); - EXPECT_EQ(pan_zoom_records[4].x, 0); - EXPECT_EQ(pan_zoom_records[4].y, 0); - EXPECT_EQ(pan_zoom_records[4].phase, kPanZoomEnd); - EXPECT_GE(pan_zoom_records[4].timestamp, pan_zoom_records[3].timestamp); + fl_scrolling_manager_handle_zoom_begin(manager); + EXPECT_EQ(pointer_events.size(), 1u); + EXPECT_EQ(pointer_events[0].x, 0); + EXPECT_EQ(pointer_events[0].y, 0); + EXPECT_EQ(pointer_events[0].phase, kPanZoomStart); + EXPECT_GE(pointer_events[0].timestamp, time_start); + fl_scrolling_manager_handle_zoom_update(manager, 1.1); + EXPECT_EQ(pointer_events.size(), 2u); + EXPECT_EQ(pointer_events[1].x, 0); + EXPECT_EQ(pointer_events[1].y, 0); + EXPECT_EQ(pointer_events[1].phase, kPanZoomUpdate); + EXPECT_GE(pointer_events[1].timestamp, pointer_events[0].timestamp); + EXPECT_EQ(pointer_events[1].pan_x, 0); + EXPECT_EQ(pointer_events[1].pan_y, 0); + EXPECT_EQ(pointer_events[1].scale, 1.1); + EXPECT_EQ(pointer_events[1].rotation, 0); + fl_scrolling_manager_handle_rotation_begin(manager); + EXPECT_EQ(pointer_events.size(), 2u); + fl_scrolling_manager_handle_rotation_update(manager, 0.5); + EXPECT_EQ(pointer_events.size(), 3u); + EXPECT_EQ(pointer_events[2].x, 0); + EXPECT_EQ(pointer_events[2].y, 0); + EXPECT_EQ(pointer_events[2].phase, kPanZoomUpdate); + EXPECT_GE(pointer_events[2].timestamp, pointer_events[1].timestamp); + EXPECT_EQ(pointer_events[2].pan_x, 0); + EXPECT_EQ(pointer_events[2].pan_y, 0); + EXPECT_EQ(pointer_events[2].scale, 1.1); + EXPECT_EQ(pointer_events[2].rotation, 0.5); + fl_scrolling_manager_handle_zoom_end(manager); + EXPECT_EQ(pointer_events.size(), 3u); + fl_scrolling_manager_handle_rotation_update(manager, 1.0); + EXPECT_EQ(pointer_events.size(), 4u); + EXPECT_EQ(pointer_events[3].x, 0); + EXPECT_EQ(pointer_events[3].y, 0); + EXPECT_EQ(pointer_events[3].phase, kPanZoomUpdate); + EXPECT_GE(pointer_events[3].timestamp, pointer_events[2].timestamp); + EXPECT_EQ(pointer_events[3].pan_x, 0); + EXPECT_EQ(pointer_events[3].pan_y, 0); + EXPECT_EQ(pointer_events[3].scale, 1.1); + EXPECT_EQ(pointer_events[3].rotation, 1.0); + fl_scrolling_manager_handle_rotation_end(manager); + EXPECT_EQ(pointer_events.size(), 5u); + EXPECT_EQ(pointer_events[4].x, 0); + EXPECT_EQ(pointer_events[4].y, 0); + EXPECT_EQ(pointer_events[4].phase, kPanZoomEnd); + EXPECT_GE(pointer_events[4].timestamp, pointer_events[3].timestamp); } - -} // namespace diff --git a/shell/platform/linux/fl_scrolling_view_delegate.cc b/shell/platform/linux/fl_scrolling_view_delegate.cc deleted file mode 100644 index 2d8ce60aaae14..0000000000000 --- a/shell/platform/linux/fl_scrolling_view_delegate.cc +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "flutter/shell/platform/linux/fl_scrolling_view_delegate.h" - -G_DEFINE_INTERFACE(FlScrollingViewDelegate, - fl_scrolling_view_delegate, - G_TYPE_OBJECT) - -static void fl_scrolling_view_delegate_default_init( - FlScrollingViewDelegateInterface* iface) {} - -void fl_scrolling_view_delegate_send_mouse_pointer_event( - FlScrollingViewDelegate* self, - FlutterPointerPhase phase, - size_t timestamp, - double x, - double y, - FlutterPointerDeviceKind device_kind, - double scroll_delta_x, - double scroll_delta_y, - int64_t buttons) { - g_return_if_fail(FL_IS_SCROLLING_VIEW_DELEGATE(self)); - - FL_SCROLLING_VIEW_DELEGATE_GET_IFACE(self)->send_mouse_pointer_event( - self, phase, timestamp, x, y, device_kind, scroll_delta_x, scroll_delta_y, - buttons); -} -void fl_scrolling_view_delegate_send_pointer_pan_zoom_event( - FlScrollingViewDelegate* self, - size_t timestamp, - double x, - double y, - FlutterPointerPhase phase, - double pan_x, - double pan_y, - double scale, - double rotation) { - g_return_if_fail(FL_IS_SCROLLING_VIEW_DELEGATE(self)); - - FL_SCROLLING_VIEW_DELEGATE_GET_IFACE(self)->send_pointer_pan_zoom_event( - self, timestamp, x, y, phase, pan_x, pan_y, scale, rotation); -} diff --git a/shell/platform/linux/fl_scrolling_view_delegate.h b/shell/platform/linux/fl_scrolling_view_delegate.h deleted file mode 100644 index e0def169824df..0000000000000 --- a/shell/platform/linux/fl_scrolling_view_delegate.h +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef FLUTTER_SHELL_PLATFORM_LINUX_FL_SCROLLING_VIEW_DELEGATE_H_ -#define FLUTTER_SHELL_PLATFORM_LINUX_FL_SCROLLING_VIEW_DELEGATE_H_ - -#include -#include -#include - -#include "flutter/shell/platform/embedder/embedder.h" -#include "flutter/shell/platform/linux/fl_key_event.h" -#include "flutter/shell/platform/linux/public/flutter_linux/fl_binary_messenger.h" - -G_BEGIN_DECLS - -G_DECLARE_INTERFACE(FlScrollingViewDelegate, - fl_scrolling_view_delegate, - FL, - SCROLLING_VIEW_DELEGATE, - GObject); - -/** - * FlScrollingViewDelegate: - * - * An interface for a class that provides `FlScrollingManager` with - * platform-related features. - * - * This interface is typically implemented by `FlView`. - */ - -struct _FlScrollingViewDelegateInterface { - GTypeInterface g_iface; - - void (*send_mouse_pointer_event)(FlScrollingViewDelegate* delegate, - FlutterPointerPhase phase, - size_t timestamp, - double x, - double y, - FlutterPointerDeviceKind device_kind, - double scroll_delta_x, - double scroll_delta_y, - int64_t buttons); - - void (*send_pointer_pan_zoom_event)(FlScrollingViewDelegate* delegate, - size_t timestamp, - double x, - double y, - FlutterPointerPhase phase, - double pan_x, - double pan_y, - double scale, - double rotation); -}; - -void fl_scrolling_view_delegate_send_mouse_pointer_event( - FlScrollingViewDelegate* delegate, - FlutterPointerPhase phase, - size_t timestamp, - double x, - double y, - FlutterPointerDeviceKind device_kind, - double scroll_delta_x, - double scroll_delta_y, - int64_t buttons); -void fl_scrolling_view_delegate_send_pointer_pan_zoom_event( - FlScrollingViewDelegate* delegate, - size_t timestamp, - double x, - double y, - FlutterPointerPhase phase, - double pan_x, - double pan_y, - double scale, - double rotation); - -G_END_DECLS - -#endif // FLUTTER_SHELL_PLATFORM_LINUX_FL_SCROLLING_VIEW_DELEGATE_H_ diff --git a/shell/platform/linux/fl_view.cc b/shell/platform/linux/fl_view.cc index adda943e0fffe..6a07c3cb76064 100644 --- a/shell/platform/linux/fl_view.cc +++ b/shell/platform/linux/fl_view.cc @@ -20,7 +20,6 @@ #include "flutter/shell/platform/linux/fl_plugin_registrar_private.h" #include "flutter/shell/platform/linux/fl_renderer_gdk.h" #include "flutter/shell/platform/linux/fl_scrolling_manager.h" -#include "flutter/shell/platform/linux/fl_scrolling_view_delegate.h" #include "flutter/shell/platform/linux/fl_socket_accessible.h" #include "flutter/shell/platform/linux/fl_text_input_handler.h" #include "flutter/shell/platform/linux/fl_text_input_view_delegate.h" @@ -93,9 +92,6 @@ static void fl_view_plugin_registry_iface_init( static void fl_view_keyboard_delegate_iface_init( FlKeyboardViewDelegateInterface* iface); -static void fl_view_scrolling_delegate_iface_init( - FlScrollingViewDelegateInterface* iface); - static void fl_view_text_input_delegate_iface_init( FlTextInputViewDelegateInterface* iface); @@ -108,11 +104,8 @@ G_DEFINE_TYPE_WITH_CODE( fl_view_plugin_registry_iface_init) G_IMPLEMENT_INTERFACE(fl_keyboard_view_delegate_get_type(), fl_view_keyboard_delegate_iface_init) - G_IMPLEMENT_INTERFACE(fl_scrolling_view_delegate_get_type(), - fl_view_scrolling_delegate_iface_init) - G_IMPLEMENT_INTERFACE( - fl_text_input_view_delegate_get_type(), - fl_view_text_input_delegate_iface_init)) + G_IMPLEMENT_INTERFACE(fl_text_input_view_delegate_get_type(), + fl_view_text_input_delegate_iface_init)) // Emit the first frame signal in the main thread. static gboolean first_frame_idle_cb(gpointer user_data) { @@ -154,7 +147,7 @@ static void init_keyboard(FlView* self) { static void init_scrolling(FlView* self) { g_clear_object(&self->scrolling_manager); self->scrolling_manager = - fl_scrolling_manager_new(FL_SCROLLING_VIEW_DELEGATE(self)); + fl_scrolling_manager_new(self->engine, self->view_id); } static FlutterPointerDeviceKind get_device_kind(GdkEvent* event) { @@ -369,33 +362,6 @@ static void fl_view_keyboard_delegate_iface_init( }; } -static void fl_view_scrolling_delegate_iface_init( - FlScrollingViewDelegateInterface* iface) { - iface->send_mouse_pointer_event = - [](FlScrollingViewDelegate* view_delegate, FlutterPointerPhase phase, - size_t timestamp, double x, double y, - FlutterPointerDeviceKind device_kind, double scroll_delta_x, - double scroll_delta_y, int64_t buttons) { - FlView* self = FL_VIEW(view_delegate); - if (self->engine != nullptr) { - fl_engine_send_mouse_pointer_event( - self->engine, self->view_id, phase, timestamp, x, y, device_kind, - scroll_delta_x, scroll_delta_y, buttons); - } - }; - iface->send_pointer_pan_zoom_event = - [](FlScrollingViewDelegate* view_delegate, size_t timestamp, double x, - double y, FlutterPointerPhase phase, double pan_x, double pan_y, - double scale, double rotation) { - FlView* self = FL_VIEW(view_delegate); - if (self->engine != nullptr) { - fl_engine_send_pointer_pan_zoom_event(self->engine, self->view_id, - timestamp, x, y, phase, pan_x, - pan_y, scale, rotation); - }; - }; -} - static void fl_view_text_input_delegate_iface_init( FlTextInputViewDelegateInterface* iface) { iface->translate_coordinates = [](FlTextInputViewDelegate* delegate,