diff --git a/engine/src/flutter/ci/licenses_golden/licenses_flutter b/engine/src/flutter/ci/licenses_golden/licenses_flutter index 24274f98c99..9c2ebc77f49 100644 --- a/engine/src/flutter/ci/licenses_golden/licenses_flutter +++ b/engine/src/flutter/ci/licenses_golden/licenses_flutter @@ -2321,6 +2321,8 @@ FILE: ../../../flutter/shell/platform/linux/fl_task_runner.h FILE: ../../../flutter/shell/platform/linux/fl_text_input_plugin.cc FILE: ../../../flutter/shell/platform/linux/fl_text_input_plugin.h FILE: ../../../flutter/shell/platform/linux/fl_text_input_plugin_test.cc +FILE: ../../../flutter/shell/platform/linux/fl_text_input_view_delegate.cc +FILE: ../../../flutter/shell/platform/linux/fl_text_input_view_delegate.h FILE: ../../../flutter/shell/platform/linux/fl_texture.cc FILE: ../../../flutter/shell/platform/linux/fl_texture_gl.cc FILE: ../../../flutter/shell/platform/linux/fl_texture_gl_private.h diff --git a/engine/src/flutter/shell/platform/linux/BUILD.gn b/engine/src/flutter/shell/platform/linux/BUILD.gn index 6e70e491620..4c1cbc4a75d 100644 --- a/engine/src/flutter/shell/platform/linux/BUILD.gn +++ b/engine/src/flutter/shell/platform/linux/BUILD.gn @@ -141,6 +141,7 @@ source_set("flutter_linux_sources") { "fl_task_runner.cc", "fl_task_runner.h", "fl_text_input_plugin.cc", + "fl_text_input_view_delegate.cc", "fl_texture.cc", "fl_texture_gl.cc", "fl_texture_registrar.cc", @@ -234,6 +235,7 @@ executable("flutter_linux_unittests") { "testing/mock_settings.cc", "testing/mock_signal_handler.cc", "testing/mock_text_input_plugin.cc", + "testing/mock_text_input_view_delegate.cc", "testing/mock_texture_registrar.cc", ] diff --git a/engine/src/flutter/shell/platform/linux/fl_text_input_plugin.cc b/engine/src/flutter/shell/platform/linux/fl_text_input_plugin.cc index b4974c27101..bdc0762fe1f 100644 --- a/engine/src/flutter/shell/platform/linux/fl_text_input_plugin.cc +++ b/engine/src/flutter/shell/platform/linux/fl_text_input_plugin.cc @@ -80,6 +80,8 @@ struct FlTextInputPluginPrivate { // Input method. GtkIMContext* im_context; + FlTextInputViewDelegate* view_delegate; + flutter::TextInputModel* text_model; // A 4x4 matrix that maps from `EditableText` local coordinates to the @@ -487,9 +489,13 @@ static void update_im_cursor_position(FlTextInputPlugin* self) { priv->composing_rect.y * priv->editabletext_transform[1][1] + priv->editabletext_transform[3][1] + priv->composing_rect.height; + // Transform from Flutter view coordinates to GTK window coordinates. + GdkRectangle preedit_rect = {}; + fl_text_input_view_delegate_translate_coordinates( + priv->view_delegate, x, y, &preedit_rect.x, &preedit_rect.y); + // Set the cursor location in window coordinates so that GTK can position any // system input method windows. - GdkRectangle preedit_rect = {x, y, 0, 0}; gtk_im_context_set_cursor_location(priv->im_context, &preedit_rect); } @@ -587,6 +593,12 @@ static void fl_text_input_plugin_dispose(GObject* object) { delete priv->text_model; priv->text_model = nullptr; } + if (priv->view_delegate != nullptr) { + g_object_remove_weak_pointer( + G_OBJECT(priv->view_delegate), + reinterpret_cast(&(priv->view_delegate))); + priv->view_delegate = nullptr; + } G_OBJECT_CLASS(fl_text_input_plugin_parent_class)->dispose(object); } @@ -719,10 +731,13 @@ static void init_im_context(FlTextInputPlugin* self, GtkIMContext* im_context) { G_CONNECT_SWAPPED); } -FlTextInputPlugin* fl_text_input_plugin_new(FlBinaryMessenger* messenger, - GtkIMContext* im_context) { +FlTextInputPlugin* fl_text_input_plugin_new( + FlBinaryMessenger* messenger, + GtkIMContext* im_context, + FlTextInputViewDelegate* view_delegate) { g_return_val_if_fail(FL_IS_BINARY_MESSENGER(messenger), nullptr); g_return_val_if_fail(GTK_IS_IM_CONTEXT(im_context), nullptr); + g_return_val_if_fail(FL_IS_TEXT_INPUT_VIEW_DELEGATE(view_delegate), nullptr); FlTextInputPlugin* self = FL_TEXT_INPUT_PLUGIN( g_object_new(fl_text_input_plugin_get_type(), nullptr)); @@ -737,6 +752,11 @@ FlTextInputPlugin* fl_text_input_plugin_new(FlBinaryMessenger* messenger, init_im_context(self, im_context); + priv->view_delegate = view_delegate; + g_object_add_weak_pointer( + G_OBJECT(view_delegate), + reinterpret_cast(&(priv->view_delegate))); + return self; } diff --git a/engine/src/flutter/shell/platform/linux/fl_text_input_plugin.h b/engine/src/flutter/shell/platform/linux/fl_text_input_plugin.h index d432698ea5f..d2c25ebb16b 100644 --- a/engine/src/flutter/shell/platform/linux/fl_text_input_plugin.h +++ b/engine/src/flutter/shell/platform/linux/fl_text_input_plugin.h @@ -8,6 +8,7 @@ #include #include "flutter/shell/platform/linux/fl_key_event.h" +#include "flutter/shell/platform/linux/fl_text_input_view_delegate.h" #include "flutter/shell/platform/linux/public/flutter_linux/fl_binary_messenger.h" G_BEGIN_DECLS @@ -38,14 +39,17 @@ struct _FlTextInputPluginClass { * fl_text_input_plugin_new: * @messenger: an #FlBinaryMessenger. * @im_context: (allow-none): a #GtkIMContext. + * @view_delegate: an #FlTextInputViewDelegate. * * Creates a new plugin that implements SystemChannels.textInput from the * Flutter services library. * * Returns: a new #FlTextInputPlugin. */ -FlTextInputPlugin* fl_text_input_plugin_new(FlBinaryMessenger* messenger, - GtkIMContext* im_context); +FlTextInputPlugin* fl_text_input_plugin_new( + FlBinaryMessenger* messenger, + GtkIMContext* im_context, + FlTextInputViewDelegate* view_delegate); /** * fl_text_input_plugin_filter_keypress diff --git a/engine/src/flutter/shell/platform/linux/fl_text_input_plugin_test.cc b/engine/src/flutter/shell/platform/linux/fl_text_input_plugin_test.cc index 3692e6584c9..8f0c55ccb02 100644 --- a/engine/src/flutter/shell/platform/linux/fl_text_input_plugin_test.cc +++ b/engine/src/flutter/shell/platform/linux/fl_text_input_plugin_test.cc @@ -11,6 +11,7 @@ #include "flutter/shell/platform/linux/testing/mock_binary_messenger.h" #include "flutter/shell/platform/linux/testing/mock_binary_messenger_response_handle.h" #include "flutter/shell/platform/linux/testing/mock_im_context.h" +#include "flutter/shell/platform/linux/testing/mock_text_input_view_delegate.h" #include "flutter/testing/testing.h" #include "gmock/gmock.h" @@ -189,9 +190,10 @@ static void send_key_event(FlTextInputPlugin* plugin, TEST(FlTextInputPluginTest, MessageHandler) { ::testing::NiceMock messenger; ::testing::NiceMock context; + ::testing::NiceMock delegate; g_autoptr(FlTextInputPlugin) plugin = - fl_text_input_plugin_new(messenger, context); + fl_text_input_plugin_new(messenger, context, delegate); EXPECT_NE(plugin, nullptr); EXPECT_TRUE(messenger.HasMessageHandler("flutter/textinput")); @@ -200,9 +202,10 @@ TEST(FlTextInputPluginTest, MessageHandler) { TEST(FlTextInputPluginTest, SetClient) { ::testing::NiceMock messenger; ::testing::NiceMock context; + ::testing::NiceMock delegate; g_autoptr(FlTextInputPlugin) plugin = - fl_text_input_plugin_new(messenger, context); + fl_text_input_plugin_new(messenger, context, delegate); EXPECT_NE(plugin, nullptr); g_autoptr(FlValue) args = build_input_config({.client_id = 1}); @@ -222,9 +225,10 @@ TEST(FlTextInputPluginTest, SetClient) { TEST(FlTextInputPluginTest, Show) { ::testing::NiceMock messenger; ::testing::NiceMock context; + ::testing::NiceMock delegate; g_autoptr(FlTextInputPlugin) plugin = - fl_text_input_plugin_new(messenger, context); + fl_text_input_plugin_new(messenger, context, delegate); EXPECT_NE(plugin, nullptr); EXPECT_CALL(context, @@ -246,9 +250,10 @@ TEST(FlTextInputPluginTest, Show) { TEST(FlTextInputPluginTest, Hide) { ::testing::NiceMock messenger; ::testing::NiceMock context; + ::testing::NiceMock delegate; g_autoptr(FlTextInputPlugin) plugin = - fl_text_input_plugin_new(messenger, context); + fl_text_input_plugin_new(messenger, context, delegate); EXPECT_NE(plugin, nullptr); EXPECT_CALL(context, @@ -270,9 +275,10 @@ TEST(FlTextInputPluginTest, Hide) { TEST(FlTextInputPluginTest, ClearClient) { ::testing::NiceMock messenger; ::testing::NiceMock context; + ::testing::NiceMock delegate; g_autoptr(FlTextInputPlugin) plugin = - fl_text_input_plugin_new(messenger, context); + fl_text_input_plugin_new(messenger, context, delegate); EXPECT_NE(plugin, nullptr); g_autoptr(FlValue) null = fl_value_new_null(); @@ -291,9 +297,10 @@ TEST(FlTextInputPluginTest, ClearClient) { TEST(FlTextInputPluginTest, PerformAction) { ::testing::NiceMock messenger; ::testing::NiceMock context; + ::testing::NiceMock delegate; g_autoptr(FlTextInputPlugin) plugin = - fl_text_input_plugin_new(messenger, context); + fl_text_input_plugin_new(messenger, context, delegate); EXPECT_NE(plugin, nullptr); // set input config @@ -366,9 +373,10 @@ TEST(FlTextInputPluginTest, PerformAction) { TEST(FlTextInputPluginTest, MoveCursor) { ::testing::NiceMock messenger; ::testing::NiceMock context; + ::testing::NiceMock delegate; g_autoptr(FlTextInputPlugin) plugin = - fl_text_input_plugin_new(messenger, context); + fl_text_input_plugin_new(messenger, context, delegate); EXPECT_NE(plugin, nullptr); // set input config @@ -443,9 +451,10 @@ TEST(FlTextInputPluginTest, MoveCursor) { TEST(FlTextInputPluginTest, Select) { ::testing::NiceMock messenger; ::testing::NiceMock context; + ::testing::NiceMock delegate; g_autoptr(FlTextInputPlugin) plugin = - fl_text_input_plugin_new(messenger, context); + fl_text_input_plugin_new(messenger, context, delegate); EXPECT_NE(plugin, nullptr); // set input config @@ -520,9 +529,10 @@ TEST(FlTextInputPluginTest, Select) { TEST(FlTextInputPluginTest, Composing) { ::testing::NiceMock messenger; ::testing::NiceMock context; + ::testing::NiceMock delegate; g_autoptr(FlTextInputPlugin) plugin = - fl_text_input_plugin_new(messenger, context); + fl_text_input_plugin_new(messenger, context, delegate); EXPECT_NE(plugin, nullptr); g_signal_emit_by_name(context, "preedit-start", nullptr); @@ -589,9 +599,10 @@ TEST(FlTextInputPluginTest, Composing) { TEST(FlTextInputPluginTest, SurroundingText) { ::testing::NiceMock messenger; ::testing::NiceMock context; + ::testing::NiceMock delegate; g_autoptr(FlTextInputPlugin) plugin = - fl_text_input_plugin_new(messenger, context); + fl_text_input_plugin_new(messenger, context, delegate); EXPECT_NE(plugin, nullptr); // set input config @@ -658,9 +669,10 @@ TEST(FlTextInputPluginTest, SurroundingText) { TEST(FlTextInputPluginTest, SetMarkedTextRect) { ::testing::NiceMock messenger; ::testing::NiceMock context; + ::testing::NiceMock delegate; g_autoptr(FlTextInputPlugin) plugin = - fl_text_input_plugin_new(messenger, context); + fl_text_input_plugin_new(messenger, context, delegate); EXPECT_NE(plugin, nullptr); g_signal_emit_by_name(context, "preedit-start", nullptr); @@ -719,11 +731,18 @@ TEST(FlTextInputPluginTest, SetMarkedTextRect) { ::testing::_, SuccessResponse(null), ::testing::_)) .WillOnce(::testing::Return(true)); + EXPECT_CALL(delegate, fl_text_input_view_delegate_translate_coordinates( + ::testing::Eq(delegate), + ::testing::Eq(27), ::testing::Eq(32), ::testing::_, + ::testing::_)) + .WillOnce(::testing::DoAll(::testing::SetArgPointee<3>(123), + ::testing::SetArgPointee<4>(456))); + EXPECT_CALL(context, gtk_im_context_set_cursor_location( ::testing::Eq(context), ::testing::Pointee(::testing::AllOf( - ::testing::Field(&GdkRectangle::x, 27), - ::testing::Field(&GdkRectangle::y, 32), + ::testing::Field(&GdkRectangle::x, 123), + ::testing::Field(&GdkRectangle::y, 456), ::testing::Field(&GdkRectangle::width, 0), ::testing::Field(&GdkRectangle::height, 0))))); @@ -733,9 +752,10 @@ TEST(FlTextInputPluginTest, SetMarkedTextRect) { TEST(FlTextInputPluginTest, TextInputTypeNone) { ::testing::NiceMock messenger; ::testing::NiceMock context; + ::testing::NiceMock delegate; g_autoptr(FlTextInputPlugin) plugin = - fl_text_input_plugin_new(messenger, context); + fl_text_input_plugin_new(messenger, context, delegate); EXPECT_NE(plugin, nullptr); g_autoptr(FlValue) args = build_input_config({ @@ -775,9 +795,10 @@ TEST(FlTextInputPluginTest, TextInputTypeNone) { TEST(FlTextInputPluginTest, TextEditingDelta) { ::testing::NiceMock messenger; ::testing::NiceMock context; + ::testing::NiceMock delegate; g_autoptr(FlTextInputPlugin) plugin = - fl_text_input_plugin_new(messenger, context); + fl_text_input_plugin_new(messenger, context, delegate); EXPECT_NE(plugin, nullptr); // set config @@ -846,9 +867,10 @@ TEST(FlTextInputPluginTest, TextEditingDelta) { TEST(FlTextInputPluginTest, ComposingDelta) { ::testing::NiceMock messenger; ::testing::NiceMock context; + ::testing::NiceMock delegate; g_autoptr(FlTextInputPlugin) plugin = - fl_text_input_plugin_new(messenger, context); + fl_text_input_plugin_new(messenger, context, delegate); EXPECT_NE(plugin, nullptr); // set config diff --git a/engine/src/flutter/shell/platform/linux/fl_text_input_view_delegate.cc b/engine/src/flutter/shell/platform/linux/fl_text_input_view_delegate.cc new file mode 100644 index 00000000000..52e94d4391a --- /dev/null +++ b/engine/src/flutter/shell/platform/linux/fl_text_input_view_delegate.cc @@ -0,0 +1,24 @@ +// 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_text_input_view_delegate.h" + +G_DEFINE_INTERFACE(FlTextInputViewDelegate, + fl_text_input_view_delegate, + G_TYPE_OBJECT) + +static void fl_text_input_view_delegate_default_init( + FlTextInputViewDelegateInterface* iface) {} + +void fl_text_input_view_delegate_translate_coordinates( + FlTextInputViewDelegate* self, + gint view_x, + gint view_y, + gint* window_x, + gint* window_y) { + g_return_if_fail(FL_IS_TEXT_INPUT_VIEW_DELEGATE(self)); + + FL_TEXT_INPUT_VIEW_DELEGATE_GET_IFACE(self)->translate_coordinates( + self, view_x, view_y, window_x, window_y); +} diff --git a/engine/src/flutter/shell/platform/linux/fl_text_input_view_delegate.h b/engine/src/flutter/shell/platform/linux/fl_text_input_view_delegate.h new file mode 100644 index 00000000000..6c8b491f19f --- /dev/null +++ b/engine/src/flutter/shell/platform/linux/fl_text_input_view_delegate.h @@ -0,0 +1,48 @@ +// 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_TEXT_INPUT_VIEW_DELEGATE_H_ +#define FLUTTER_SHELL_PLATFORM_LINUX_FL_TEXT_INPUT_VIEW_DELEGATE_H_ + +#include + +#include "flutter/shell/platform/embedder/embedder.h" + +G_BEGIN_DECLS + +G_DECLARE_INTERFACE(FlTextInputViewDelegate, + fl_text_input_view_delegate, + FL, + TEXT_INPUT_VIEW_DELEGATE, + GObject); + +/** + * FlTextInputViewDelegate: + * + * An interface for a class that provides `FlTextInputPlugin` with + * view-related features. + * + * This interface is typically implemented by `FlView`. + */ + +struct _FlTextInputViewDelegateInterface { + GTypeInterface g_iface; + + void (*translate_coordinates)(FlTextInputViewDelegate* delegate, + gint view_x, + gint view_y, + gint* window_x, + gint* window_y); +}; + +void fl_text_input_view_delegate_translate_coordinates( + FlTextInputViewDelegate* delegate, + gint view_x, + gint view_y, + gint* window_x, + gint* window_y); + +G_END_DECLS + +#endif // FLUTTER_SHELL_PLATFORM_LINUX_FL_TEXT_INPUT_VIEW_DELEGATE_H_ diff --git a/engine/src/flutter/shell/platform/linux/fl_view.cc b/engine/src/flutter/shell/platform/linux/fl_view.cc index de676c90b09..445fc77a238 100644 --- a/engine/src/flutter/shell/platform/linux/fl_view.cc +++ b/engine/src/flutter/shell/platform/linux/fl_view.cc @@ -20,6 +20,7 @@ #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_text_input_plugin.h" +#include "flutter/shell/platform/linux/fl_text_input_view_delegate.h" #include "flutter/shell/platform/linux/fl_view_accessible.h" #include "flutter/shell/platform/linux/public/flutter_linux/fl_engine.h" #include "flutter/shell/platform/linux/public/flutter_linux/fl_plugin_registry.h" @@ -82,6 +83,9 @@ static void fl_view_keyboard_delegate_iface_init( static void fl_view_scrolling_delegate_iface_init( FlScrollingViewDelegateInterface* iface); +static void fl_view_text_input_delegate_iface_init( + FlTextInputViewDelegateInterface* iface); + G_DEFINE_TYPE_WITH_CODE( FlView, fl_view, @@ -91,18 +95,22 @@ G_DEFINE_TYPE_WITH_CODE( 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)) + fl_view_scrolling_delegate_iface_init) + G_IMPLEMENT_INTERFACE(fl_text_input_view_delegate_get_type(), + fl_view_text_input_delegate_iface_init)) // Initialize keyboard manager. static void init_keyboard(FlView* self) { FlBinaryMessenger* messenger = fl_engine_get_binary_messenger(self->engine); - GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(self)); + GdkWindow* window = + gtk_widget_get_window(gtk_widget_get_toplevel(GTK_WIDGET(self))); g_return_if_fail(GDK_IS_WINDOW(window)); g_autoptr(GtkIMContext) im_context = gtk_im_multicontext_new(); gtk_im_context_set_client_window(im_context, window); - self->text_input_plugin = fl_text_input_plugin_new(messenger, im_context); + self->text_input_plugin = fl_text_input_plugin_new( + messenger, im_context, FL_TEXT_INPUT_VIEW_DELEGATE(self)); self->keyboard_manager = fl_keyboard_manager_new(FL_KEYBOARD_VIEW_DELEGATE(self)); } @@ -333,6 +341,18 @@ static void fl_view_scrolling_delegate_iface_init( }; } +static void fl_view_text_input_delegate_iface_init( + FlTextInputViewDelegateInterface* iface) { + iface->translate_coordinates = [](FlTextInputViewDelegate* delegate, + gint view_x, gint view_y, gint* window_x, + gint* window_y) { + FlView* self = FL_VIEW(delegate); + gtk_widget_translate_coordinates(GTK_WIDGET(self), + gtk_widget_get_toplevel(GTK_WIDGET(self)), + view_x, view_y, window_x, window_y); + }; +} + // Signal handler for GtkWidget::button-press-event static gboolean button_press_event_cb(GtkWidget* widget, GdkEventButton* event, diff --git a/engine/src/flutter/shell/platform/linux/testing/mock_text_input_view_delegate.cc b/engine/src/flutter/shell/platform/linux/testing/mock_text_input_view_delegate.cc new file mode 100644 index 00000000000..fa8259cb269 --- /dev/null +++ b/engine/src/flutter/shell/platform/linux/testing/mock_text_input_view_delegate.cc @@ -0,0 +1,74 @@ +// 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/testing/mock_text_input_view_delegate.h" + +using namespace flutter::testing; + +G_DECLARE_FINAL_TYPE(FlMockTextInputViewDelegate, + fl_mock_text_input_view_delegate, + FL, + MOCK_TEXT_INPUT_VIEW_DELEGATE, + GObject) + +struct _FlMockTextInputViewDelegate { + GObject parent_instance; + MockTextInputViewDelegate* mock; +}; + +static FlTextInputViewDelegate* fl_mock_text_input_view_delegate_new( + MockTextInputViewDelegate* mock) { + FlMockTextInputViewDelegate* self = FL_MOCK_TEXT_INPUT_VIEW_DELEGATE( + g_object_new(fl_mock_text_input_view_delegate_get_type(), nullptr)); + self->mock = mock; + return FL_TEXT_INPUT_VIEW_DELEGATE(self); +} + +MockTextInputViewDelegate::MockTextInputViewDelegate() + : instance_(fl_mock_text_input_view_delegate_new(this)) {} + +MockTextInputViewDelegate::~MockTextInputViewDelegate() { + if (FL_IS_TEXT_INPUT_VIEW_DELEGATE(instance_)) { + g_clear_object(&instance_); + } +} + +MockTextInputViewDelegate::operator FlTextInputViewDelegate*() { + return instance_; +} + +static void fl_mock_text_input_view_delegate_iface_init( + FlTextInputViewDelegateInterface* iface); + +G_DEFINE_TYPE_WITH_CODE( + FlMockTextInputViewDelegate, + fl_mock_text_input_view_delegate, + G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE(fl_text_input_view_delegate_get_type(), + fl_mock_text_input_view_delegate_iface_init)) + +static void fl_mock_text_input_view_delegate_class_init( + FlMockTextInputViewDelegateClass* klass) {} + +static void fl_mock_text_input_view_delegate_translate_coordinates( + FlTextInputViewDelegate* view_delegate, + gint view_x, + gint view_y, + gint* window_x, + gint* window_y) { + g_return_if_fail(FL_IS_MOCK_TEXT_INPUT_VIEW_DELEGATE(view_delegate)); + FlMockTextInputViewDelegate* self = + FL_MOCK_TEXT_INPUT_VIEW_DELEGATE(view_delegate); + self->mock->fl_text_input_view_delegate_translate_coordinates( + view_delegate, view_x, view_y, window_x, window_y); +} + +static void fl_mock_text_input_view_delegate_iface_init( + FlTextInputViewDelegateInterface* iface) { + iface->translate_coordinates = + fl_mock_text_input_view_delegate_translate_coordinates; +} + +static void fl_mock_text_input_view_delegate_init( + FlMockTextInputViewDelegate* self) {} diff --git a/engine/src/flutter/shell/platform/linux/testing/mock_text_input_view_delegate.h b/engine/src/flutter/shell/platform/linux/testing/mock_text_input_view_delegate.h new file mode 100644 index 00000000000..ae43045e15d --- /dev/null +++ b/engine/src/flutter/shell/platform/linux/testing/mock_text_input_view_delegate.h @@ -0,0 +1,39 @@ +// 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_TESTING_MOCK_TEXT_INPUT_VIEW_DELEGATE_H_ +#define FLUTTER_SHELL_PLATFORM_LINUX_TESTING_MOCK_TEXT_INPUT_VIEW_DELEGATE_H_ + +#include + +#include "flutter/shell/platform/linux/fl_text_input_view_delegate.h" + +#include "gmock/gmock.h" + +namespace flutter { +namespace testing { + +// Mock for FlTextInputVuewDelegate. +class MockTextInputViewDelegate { + public: + MockTextInputViewDelegate(); + ~MockTextInputViewDelegate(); + + operator FlTextInputViewDelegate*(); + + MOCK_METHOD5(fl_text_input_view_delegate_translate_coordinates, + void(FlTextInputViewDelegate* delegate, + gint view_x, + gint view_y, + gint* window_x, + gint* window_y)); + + private: + FlTextInputViewDelegate* instance_ = nullptr; +}; + +} // namespace testing +} // namespace flutter + +#endif // FLUTTER_SHELL_PLATFORM_LINUX_TESTING_MOCK_TEXT_INPUT_VIEW_DELEGATE_H_