diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 495476655d7ff..eca6c7ddc273a 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -717,7 +717,9 @@ FILE: ../../../flutter/shell/platform/embedder/vsync_waiter_embedder.cc FILE: ../../../flutter/shell/platform/embedder/vsync_waiter_embedder.h FILE: ../../../flutter/shell/platform/glfw/client_wrapper/flutter_window_controller.cc FILE: ../../../flutter/shell/platform/glfw/client_wrapper/flutter_window_controller_unittests.cc +FILE: ../../../flutter/shell/platform/glfw/client_wrapper/include/flutter/flutter_window.h FILE: ../../../flutter/shell/platform/glfw/client_wrapper/include/flutter/flutter_window_controller.h +FILE: ../../../flutter/shell/platform/glfw/client_wrapper/include/flutter/plugin_registrar_glfw.h FILE: ../../../flutter/shell/platform/glfw/flutter_glfw.cc FILE: ../../../flutter/shell/platform/glfw/key_event_handler.cc FILE: ../../../flutter/shell/platform/glfw/key_event_handler.h diff --git a/shell/platform/common/cpp/client_wrapper/include/flutter/plugin_registrar.h b/shell/platform/common/cpp/client_wrapper/include/flutter/plugin_registrar.h index 228a6a311fad0..5fbe1b5b6297c 100644 --- a/shell/platform/common/cpp/client_wrapper/include/flutter/plugin_registrar.h +++ b/shell/platform/common/cpp/client_wrapper/include/flutter/plugin_registrar.h @@ -28,7 +28,7 @@ class PluginRegistrar { // provides must remain valid as long as this object exists. explicit PluginRegistrar(FlutterDesktopPluginRegistrarRef core_registrar); - ~PluginRegistrar(); + virtual ~PluginRegistrar(); // Prevent copying. PluginRegistrar(PluginRegistrar const&) = delete; diff --git a/shell/platform/glfw/client_wrapper/BUILD.gn b/shell/platform/glfw/client_wrapper/BUILD.gn index 4a59ee8f4aae7..1ba2c7e431237 100644 --- a/shell/platform/glfw/client_wrapper/BUILD.gn +++ b/shell/platform/glfw/client_wrapper/BUILD.gn @@ -4,7 +4,11 @@ import("$flutter_root/shell/platform/common/cpp/client_wrapper/publish.gni") -_wrapper_includes = [ "include/flutter/flutter_window_controller.h" ] +_wrapper_includes = [ + "include/flutter/flutter_window.h", + "include/flutter/flutter_window_controller.h", + "include/flutter/plugin_registrar_glfw.h", +] _wrapper_sources = [ "flutter_window_controller.cc" ] diff --git a/shell/platform/glfw/client_wrapper/flutter_window_controller.cc b/shell/platform/glfw/client_wrapper/flutter_window_controller.cc index 235be0b2bd6b3..42535974fc57f 100644 --- a/shell/platform/glfw/client_wrapper/flutter_window_controller.cc +++ b/shell/platform/glfw/client_wrapper/flutter_window_controller.cc @@ -16,6 +16,9 @@ FlutterWindowController::FlutterWindowController( } FlutterWindowController::~FlutterWindowController() { + if (controller_) { + FlutterDesktopDestroyWindow(controller_); + } if (init_succeeded_) { FlutterDesktopTerminate(); } @@ -33,7 +36,7 @@ bool FlutterWindowController::CreateWindow( return false; } - if (window_) { + if (controller_) { std::cerr << "Only one Flutter window can exist at a time." << std::endl; return false; } @@ -44,45 +47,35 @@ bool FlutterWindowController::CreateWindow( [](const std::string& arg) -> const char* { return arg.c_str(); }); size_t arg_count = engine_arguments.size(); - window_ = FlutterDesktopCreateWindow( + controller_ = FlutterDesktopCreateWindow( width, height, title.c_str(), assets_path.c_str(), icu_data_path_.c_str(), arg_count > 0 ? &engine_arguments[0] : nullptr, arg_count); - if (!window_) { + if (!controller_) { std::cerr << "Failed to create window." << std::endl; return false; } + window_ = + std::make_unique(FlutterDesktopGetWindow(controller_)); return true; } FlutterDesktopPluginRegistrarRef FlutterWindowController::GetRegistrarForPlugin( const std::string& plugin_name) { - if (!window_) { + if (!controller_) { std::cerr << "Cannot get plugin registrar without a window; call " "CreateWindow first." << std::endl; return nullptr; } - return FlutterDesktopGetPluginRegistrar(window_, plugin_name.c_str()); -} - -void FlutterWindowController::SetHoverEnabled(bool enabled) { - FlutterDesktopSetHoverEnabled(window_, enabled); -} - -void FlutterWindowController::SetTitle(const std::string& title) { - FlutterDesktopSetWindowTitle(window_, title.c_str()); -} - -void FlutterWindowController::SetIcon(uint8_t* pixel_data, - int width, - int height) { - FlutterDesktopSetWindowIcon(window_, pixel_data, width, height); + return FlutterDesktopGetPluginRegistrar(controller_, plugin_name.c_str()); } void FlutterWindowController::RunEventLoop() { - if (window_) { - FlutterDesktopRunWindowLoop(window_); + if (controller_) { + FlutterDesktopRunWindowLoop(controller_); } + window_ = nullptr; + controller_ = nullptr; } } // namespace flutter diff --git a/shell/platform/glfw/client_wrapper/include/flutter/flutter_window.h b/shell/platform/glfw/client_wrapper/include/flutter/flutter_window.h new file mode 100644 index 0000000000000..4b6b646a08974 --- /dev/null +++ b/shell/platform/glfw/client_wrapper/include/flutter/flutter_window.h @@ -0,0 +1,60 @@ +// 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_GLFW_CLIENT_WRAPPER_INCLUDE_FLUTTER_FLUTTER_WINDOW_H_ +#define FLUTTER_SHELL_PLATFORM_GLFW_CLIENT_WRAPPER_INCLUDE_FLUTTER_FLUTTER_WINDOW_H_ + +#include +#include + +#include + +#include "plugin_registrar.h" + +namespace flutter { + +// A window displaying Flutter content. +class FlutterWindow { + public: + explicit FlutterWindow(FlutterDesktopWindowRef window) : window_(window) {} + + ~FlutterWindow() = default; + + // Prevent copying. + FlutterWindow(FlutterWindow const&) = delete; + FlutterWindow& operator=(FlutterWindow const&) = delete; + + // Enables or disables hover tracking. + // + // If hover is enabled, mouse movement will send hover events to the Flutter + // engine, rather than only tracking the mouse while the button is pressed. + // Defaults to off. + void SetHoverEnabled(bool enabled) { + FlutterDesktopWindowSetHoverEnabled(window_, enabled); + } + + // Sets the displayed title of the window. + void SetTitle(const std::string& title) { + FlutterDesktopWindowSetTitle(window_, title.c_str()); + } + + // Sets the displayed icon for the window. + // + // The pixel format is 32-bit RGBA. The provided image data only needs to be + // valid for the duration of the call to this method. Pass a nullptr to revert + // to the default icon. + void SetIcon(uint8_t* pixel_data, int width, int height) { + FlutterDesktopWindowSetIcon(window_, pixel_data, width, height); + } + + private: + // Handle for interacting with the C API's window. + // + // Note: window_ is conceptually owned by the controller, not this object. + FlutterDesktopWindowRef window_; +}; + +} // namespace flutter + +#endif // FLUTTER_SHELL_PLATFORM_GLFW_CLIENT_WRAPPER_INCLUDE_FLUTTER_FLUTTER_WINDOW_H_ diff --git a/shell/platform/glfw/client_wrapper/include/flutter/flutter_window_controller.h b/shell/platform/glfw/client_wrapper/include/flutter/flutter_window_controller.h index 70169e48cc79a..5c54b42d773c1 100644 --- a/shell/platform/glfw/client_wrapper/include/flutter/flutter_window_controller.h +++ b/shell/platform/glfw/client_wrapper/include/flutter/flutter_window_controller.h @@ -5,11 +5,13 @@ #ifndef FLUTTER_SHELL_PLATFORM_GLFW_CLIENT_WRAPPER_INCLUDE_FLUTTER_FLUTTER_WINDOW_CONTROLLER_H_ #define FLUTTER_SHELL_PLATFORM_GLFW_CLIENT_WRAPPER_INCLUDE_FLUTTER_FLUTTER_WINDOW_CONTROLLER_H_ +#include #include #include #include +#include "flutter_window.h" #include "plugin_registrar.h" namespace flutter { @@ -33,6 +35,10 @@ class FlutterWindowController { ~FlutterWindowController(); + // Prevent copying. + FlutterWindowController(FlutterWindowController const&) = delete; + FlutterWindowController& operator=(FlutterWindowController const&) = delete; + // Creates and displays a window for displaying Flutter content. // // The |assets_path| is the path to the flutter_assets folder for the Flutter @@ -57,22 +63,9 @@ class FlutterWindowController { FlutterDesktopPluginRegistrarRef GetRegistrarForPlugin( const std::string& plugin_name); - // Enables or disables hover tracking. - // - // If hover is enabled, mouse movement will send hover events to the Flutter - // engine, rather than only tracking the mouse while the button is pressed. - // Defaults to off. - void SetHoverEnabled(bool enabled); - - // Sets the displayed title of the window. - void SetTitle(const std::string& title); - - // Sets the displayed icon for the window. - // - // The pixel format is 32-bit RGBA. The provided image data only needs to be - // valid for the duration of the call to this method. Pass a nullptr to revert - // to the default icon. - void SetIcon(uint8_t* pixel_data, int width, int height); + // The FlutterWindow managed by this controller, if any. Returns nullptr + // before CreateWindow is called, and after RunEventLoop returns; + FlutterWindow* window() { return window_.get(); } // Loops on Flutter window events until the window closes. void RunEventLoop(); @@ -85,8 +78,11 @@ class FlutterWindowController { // Whether or not FlutterDesktopInit succeeded at creation time. bool init_succeeded_ = false; - // The curent Flutter window, if any. - FlutterDesktopWindowRef window_ = nullptr; + // The owned FlutterWindow, if any. + std::unique_ptr window_; + + // Handle for interacting with the C API's window controller, if any. + FlutterDesktopWindowControllerRef controller_ = nullptr; }; } // namespace flutter diff --git a/shell/platform/glfw/client_wrapper/include/flutter/plugin_registrar_glfw.h b/shell/platform/glfw/client_wrapper/include/flutter/plugin_registrar_glfw.h new file mode 100644 index 0000000000000..a2a9da9ef3f8b --- /dev/null +++ b/shell/platform/glfw/client_wrapper/include/flutter/plugin_registrar_glfw.h @@ -0,0 +1,44 @@ +// 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_GLFW_CLIENT_WRAPPER_INCLUDE_FLUTTER_PLUGIN_REGISTRAR_GLFW_H_ +#define FLUTTER_SHELL_PLATFORM_GLFW_CLIENT_WRAPPER_INCLUDE_FLUTTER_PLUGIN_REGISTRAR_GLFW_H_ + +#include + +#include + +#include "flutter_window.h" +#include "plugin_registrar.h" + +namespace flutter { + +// An extension to PluginRegistrar providing access to GLFW-shell-specific +// functionality. +class PluginRegistrarGlfw : public PluginRegistrar { + public: + // Creates a new PluginRegistrar. |core_registrar| and the messenger it + // provides must remain valid as long as this object exists. + explicit PluginRegistrarGlfw(FlutterDesktopPluginRegistrarRef core_registrar) + : PluginRegistrar(core_registrar) { + window_ = std::make_unique( + FlutterDesktopRegistrarGetWindow(core_registrar)); + } + + virtual ~PluginRegistrarGlfw() = default; + + // Prevent copying. + PluginRegistrarGlfw(PluginRegistrarGlfw const&) = delete; + PluginRegistrarGlfw& operator=(PluginRegistrarGlfw const&) = delete; + + FlutterWindow* window() { return window_.get(); } + + private: + // The owned FlutterWindow, if any. + std::unique_ptr window_; +}; + +} // namespace flutter + +#endif // FLUTTER_SHELL_PLATFORM_GLFW_CLIENT_WRAPPER_INCLUDE_FLUTTER_PLUGIN_REGISTRAR_GLFW_H_ diff --git a/shell/platform/glfw/client_wrapper/testing/stub_flutter_glfw_api.cc b/shell/platform/glfw/client_wrapper/testing/stub_flutter_glfw_api.cc index db564018bc412..6965739ee9d7c 100644 --- a/shell/platform/glfw/client_wrapper/testing/stub_flutter_glfw_api.cc +++ b/shell/platform/glfw/client_wrapper/testing/stub_flutter_glfw_api.cc @@ -48,13 +48,14 @@ void FlutterDesktopTerminate() { } } -FlutterDesktopWindowRef FlutterDesktopCreateWindow(int initial_width, - int initial_height, - const char* title, - const char* assets_path, - const char* icu_data_path, - const char** arguments, - size_t argument_count) { +FlutterDesktopWindowControllerRef FlutterDesktopCreateWindow( + int initial_width, + int initial_height, + const char* title, + const char* assets_path, + const char* icu_data_path, + const char** arguments, + size_t argument_count) { if (s_stub_implementation) { return s_stub_implementation->CreateWindow( initial_width, initial_height, title, assets_path, icu_data_path, @@ -63,21 +64,27 @@ FlutterDesktopWindowRef FlutterDesktopCreateWindow(int initial_width, return nullptr; } -void FlutterDesktopSetHoverEnabled(FlutterDesktopWindowRef flutter_window, - bool enabled) { +void FlutterDesktopDestroyWindow(FlutterDesktopWindowControllerRef controller) { + if (s_stub_implementation) { + s_stub_implementation->DestroyWindow(); + } +} + +void FlutterDesktopWindowSetHoverEnabled(FlutterDesktopWindowRef flutter_window, + bool enabled) { if (s_stub_implementation) { s_stub_implementation->SetHoverEnabled(enabled); } } -void FlutterDesktopSetWindowTitle(FlutterDesktopWindowRef flutter_window, +void FlutterDesktopWindowSetTitle(FlutterDesktopWindowRef flutter_window, const char* title) { if (s_stub_implementation) { s_stub_implementation->SetWindowTitle(title); } } -void FlutterDesktopSetWindowIcon(FlutterDesktopWindowRef flutter_window, +void FlutterDesktopWindowSetIcon(FlutterDesktopWindowRef flutter_window, uint8_t* pixel_data, int width, int height) { @@ -86,7 +93,7 @@ void FlutterDesktopSetWindowIcon(FlutterDesktopWindowRef flutter_window, } } -void FlutterDesktopRunWindowLoop(FlutterDesktopWindowRef flutter_window) { +void FlutterDesktopRunWindowLoop(FlutterDesktopWindowControllerRef controller) { if (s_stub_implementation) { s_stub_implementation->RunWindowLoop(); } @@ -110,9 +117,15 @@ bool FlutterDesktopShutDownEngine(FlutterDesktopEngineRef engine_ref) { return true; } +FlutterDesktopWindowRef FlutterDesktopGetWindow( + FlutterDesktopWindowControllerRef controller) { + // The stub ignores this, so just return an arbitrary non-zero value. + return reinterpret_cast(1); +} + FlutterDesktopPluginRegistrarRef FlutterDesktopGetPluginRegistrar( - FlutterDesktopWindowRef flutter_window, + FlutterDesktopWindowControllerRef controller, const char* plugin_name) { // The stub ignores this, so just return an arbitrary non-zero value. - return reinterpret_cast(1); + return reinterpret_cast(2); } diff --git a/shell/platform/glfw/client_wrapper/testing/stub_flutter_glfw_api.h b/shell/platform/glfw/client_wrapper/testing/stub_flutter_glfw_api.h index 95f2be2148d01..0b2ee455fb8dc 100644 --- a/shell/platform/glfw/client_wrapper/testing/stub_flutter_glfw_api.h +++ b/shell/platform/glfw/client_wrapper/testing/stub_flutter_glfw_api.h @@ -36,23 +36,27 @@ class StubFlutterGlfwApi { virtual void Terminate() {} // Called for FlutterDesktopCreateWindow. - virtual FlutterDesktopWindowRef CreateWindow(int initial_width, - int initial_height, - const char* title, - const char* assets_path, - const char* icu_data_path, - const char** arguments, - size_t argument_count) { + virtual FlutterDesktopWindowControllerRef CreateWindow( + int initial_width, + int initial_height, + const char* title, + const char* assets_path, + const char* icu_data_path, + const char** arguments, + size_t argument_count) { return nullptr; } - // Called for FlutterDesktopSetHoverEnabled. + // Called for FlutterDesktopDestroyWindow + virtual void DestroyWindow() {} + + // Called for FlutterDesktopWindowSetHoverEnabled. virtual void SetHoverEnabled(bool enabled) {} - // Called for FlutterDesktopSetWindowTitle. + // Called for FlutterDesktopWindowSetTitle. virtual void SetWindowTitle(const char* title) {} - // Called for FlutterDesktopSetWindowIcon. + // Called for FlutterDesktopWindowSetIcon. virtual void SetWindowIcon(uint8_t* pixel_data, int width, int height) {} // Called for FlutterDesktopRunWindowLoop. diff --git a/shell/platform/glfw/flutter_glfw.cc b/shell/platform/glfw/flutter_glfw.cc index 12354f46679c6..7b124cc35357e 100644 --- a/shell/platform/glfw/flutter_glfw.cc +++ b/shell/platform/glfw/flutter_glfw.cc @@ -39,13 +39,16 @@ static_assert(FLUTTER_ENGINE_VERSION == 1, ""); static constexpr double kDpPerInch = 160.0; // Struct for storing state within an instance of the GLFW Window. -struct FlutterDesktopWindowState { +struct FlutterDesktopWindowControllerState { // The GLFW window that owns this state object. GLFWwindow* window; // The handle to the Flutter engine instance. FlutterEngine engine; + // The window handle given to API clients. + std::unique_ptr window_wrapper; + // The plugin registrar handle given to API clients. std::unique_ptr plugin_registrar; @@ -59,9 +62,6 @@ struct FlutterDesktopWindowState { std::vector> keyboard_hook_handlers; - // Whether or not to track mouse movements to send kHover events. - bool hover_tracking_enabled = false; - // Whether or not the pointer has been added (or if tracking is enabled, has // been added since it was last removed). bool pointer_currently_added = false; @@ -73,6 +73,17 @@ struct FlutterDesktopWindowState { double window_pixels_per_screen_coordinate = 1.0; }; +// Opaque reference for the GLFW window itself. This is separate from the +// controller so that it can be provided to plugins without giving them access +// to all of the controller-based functionality. +struct FlutterDesktopWindow { + // The GLFW window that (indirectly) owns this state object. + GLFWwindow* window; + + // Whether or not to track mouse movements to send kHover events. + bool hover_tracking_enabled = false; +}; + // Struct for storing state of a Flutter engine instance. struct FlutterDesktopEngineState { // The handle to the Flutter engine instance. @@ -83,6 +94,9 @@ struct FlutterDesktopEngineState { struct FlutterDesktopPluginRegistrar { // The plugin messenger handle given to API clients. std::unique_ptr messenger; + + // The handle for the window associated with this registrar. + FlutterDesktopWindow* window; }; // State associated with the messenger used to communicate with the engine. @@ -95,8 +109,9 @@ struct FlutterDesktopMessenger { }; // Retrieves state bag for the window in question from the GLFWWindow. -static FlutterDesktopWindowState* GetSavedWindowState(GLFWwindow* window) { - return reinterpret_cast( +static FlutterDesktopWindowControllerState* GetSavedWindowState( + GLFWwindow* window) { + return reinterpret_cast( glfwGetWindowUserPointer(window)); } @@ -254,7 +269,8 @@ static void GLFWMouseButtonCallback(GLFWwindow* window, // If mouse tracking isn't already enabled, turn it on for the duration of // the drag to generate kMove events. - bool hover_enabled = GetSavedWindowState(window)->hover_tracking_enabled; + bool hover_enabled = + GetSavedWindowState(window)->window_wrapper->hover_tracking_enabled; if (!hover_enabled) { glfwSetCursorPosCallback( window, (action == GLFW_PRESS) ? GLFWCursorPositionCallback : nullptr); @@ -319,7 +335,7 @@ static void GLFWAssignEventCallbacks(GLFWwindow* window) { glfwSetCharCallback(window, GLFWCharCallback); glfwSetMouseButtonCallback(window, GLFWMouseButtonCallback); glfwSetScrollCallback(window, GLFWScrollCallback); - if (GetSavedWindowState(window)->hover_tracking_enabled) { + if (GetSavedWindowState(window)->window_wrapper->hover_tracking_enabled) { SetHoverCallbacksEnabled(window, true); } } @@ -469,18 +485,19 @@ void FlutterDesktopTerminate() { glfwTerminate(); } -FlutterDesktopWindowRef FlutterDesktopCreateWindow(int initial_width, - int initial_height, - const char* title, - const char* assets_path, - const char* icu_data_path, - const char** arguments, - size_t argument_count) { +FlutterDesktopWindowControllerRef FlutterDesktopCreateWindow( + int initial_width, + int initial_height, + const char* title, + const char* assets_path, + const char* icu_data_path, + const char** arguments, + size_t argument_count) { #ifdef __linux__ gtk_init(0, nullptr); #endif // Create the window. - auto window = + auto* window = glfwCreateWindow(initial_width, initial_height, title, NULL, NULL); if (window == nullptr) { return nullptr; @@ -496,7 +513,7 @@ FlutterDesktopWindowRef FlutterDesktopCreateWindow(int initial_width, } // Create a state object attached to the window. - FlutterDesktopWindowState* state = new FlutterDesktopWindowState(); + auto* state = new FlutterDesktopWindowControllerState(); state->window = window; glfwSetWindowUserPointer(window, state); state->engine = engine; @@ -509,8 +526,12 @@ FlutterDesktopWindowRef FlutterDesktopCreateWindow(int initial_width, messenger->engine = engine; messenger->dispatcher = state->message_dispatcher.get(); + state->window_wrapper = std::make_unique(); + state->window_wrapper->window = window; + state->plugin_registrar = std::make_unique(); state->plugin_registrar->messenger = std::move(messenger); + state->plugin_registrar->window = state->window_wrapper.get(); state->internal_plugin_registrar = std::make_unique(state->plugin_registrar.get()); @@ -536,19 +557,25 @@ FlutterDesktopWindowRef FlutterDesktopCreateWindow(int initial_width, return state; } -void FlutterDesktopSetHoverEnabled(FlutterDesktopWindowRef flutter_window, - bool enabled) { +void FlutterDesktopDestroyWindow(FlutterDesktopWindowControllerRef controller) { + FlutterEngineShutdown(controller->engine); + glfwDestroyWindow(controller->window); + delete controller; +} + +void FlutterDesktopWindowSetHoverEnabled(FlutterDesktopWindowRef flutter_window, + bool enabled) { flutter_window->hover_tracking_enabled = enabled; SetHoverCallbacksEnabled(flutter_window->window, enabled); } -void FlutterDesktopSetWindowTitle(FlutterDesktopWindowRef flutter_window, +void FlutterDesktopWindowSetTitle(FlutterDesktopWindowRef flutter_window, const char* title) { GLFWwindow* window = flutter_window->window; glfwSetWindowTitle(window, title); } -void FlutterDesktopSetWindowIcon(FlutterDesktopWindowRef flutter_window, +void FlutterDesktopWindowSetIcon(FlutterDesktopWindowRef flutter_window, uint8_t* pixel_data, int width, int height) { @@ -557,8 +584,8 @@ void FlutterDesktopSetWindowIcon(FlutterDesktopWindowRef flutter_window, glfwSetWindowIcon(window, pixel_data ? 1 : 0, &image); } -void FlutterDesktopRunWindowLoop(FlutterDesktopWindowRef flutter_window) { - GLFWwindow* window = flutter_window->window; +void FlutterDesktopRunWindowLoop(FlutterDesktopWindowControllerRef controller) { + GLFWwindow* window = controller->window; #ifdef __linux__ // Necessary for GTK thread safety. XInitThreads(); @@ -573,9 +600,24 @@ void FlutterDesktopRunWindowLoop(FlutterDesktopWindowRef flutter_window) { // TODO(awdavies): This will be deprecated soon. __FlutterEngineFlushPendingTasksNow(); } - FlutterEngineShutdown(flutter_window->engine); - delete flutter_window; - glfwDestroyWindow(window); + FlutterDesktopDestroyWindow(controller); +} + +FlutterDesktopWindowRef FlutterDesktopGetWindow( + FlutterDesktopWindowControllerRef controller) { + // Currently, one registrar acts as the registrar for all plugins, so the + // name is ignored. It is part of the API to reduce churn in the future when + // aligning more closely with the Flutter registrar system. + return controller->window_wrapper.get(); +} + +FlutterDesktopPluginRegistrarRef FlutterDesktopGetPluginRegistrar( + FlutterDesktopWindowControllerRef controller, + const char* plugin_name) { + // Currently, one registrar acts as the registrar for all plugins, so the + // name is ignored. It is part of the API to reduce churn in the future when + // aligning more closely with the Flutter registrar system. + return controller->plugin_registrar.get(); } FlutterDesktopEngineRef FlutterDesktopRunEngine(const char* assets_path, @@ -599,15 +641,6 @@ bool FlutterDesktopShutDownEngine(FlutterDesktopEngineRef engine_ref) { return (result == kSuccess); } -FlutterDesktopPluginRegistrarRef FlutterDesktopGetPluginRegistrar( - FlutterDesktopWindowRef flutter_window, - const char* plugin_name) { - // Currently, one registrar acts as the registrar for all plugins, so the - // name is ignored. It is part of the API to reduce churn in the future when - // aligning more closely with the Flutter registrar system. - return flutter_window->plugin_registrar.get(); -} - void FlutterDesktopRegistrarEnableInputBlocking( FlutterDesktopPluginRegistrarRef registrar, const char* channel) { @@ -619,6 +652,11 @@ FlutterDesktopMessengerRef FlutterDesktopRegistrarGetMessenger( return registrar->messenger.get(); } +FlutterDesktopWindowRef FlutterDesktopRegistrarGetWindow( + FlutterDesktopPluginRegistrarRef registrar) { + return registrar->window; +} + void FlutterDesktopMessengerSend(FlutterDesktopMessengerRef messenger, const char* channel, const uint8_t* message, diff --git a/shell/platform/glfw/public/flutter_glfw.h b/shell/platform/glfw/public/flutter_glfw.h index 85dbe14325da1..bffc769a3cffa 100644 --- a/shell/platform/glfw/public/flutter_glfw.h +++ b/shell/platform/glfw/public/flutter_glfw.h @@ -16,8 +16,12 @@ extern "C" { #endif +// Opaque reference to a Flutter window controller. +typedef struct FlutterDesktopWindowControllerState* + FlutterDesktopWindowControllerRef; + // Opaque reference to a Flutter window. -typedef struct FlutterDesktopWindowState* FlutterDesktopWindowRef; +typedef struct FlutterDesktopWindow* FlutterDesktopWindowRef; // Opaque reference to a Flutter engine instance. typedef struct FlutterDesktopEngineState* FlutterDesktopEngineRef; @@ -46,10 +50,11 @@ FLUTTER_EXPORT void FlutterDesktopTerminate(); // for details. Not all arguments will apply to desktop. // // Returns a null pointer in the event of an error. Otherwise, the pointer is -// valid until FlutterDesktopRunWindowLoop has been called and returned. +// valid until FlutterDesktopRunWindowLoop has been called and returned, or +// FlutterDesktopDestroyWindow is called. // Note that calling FlutterDesktopCreateWindow without later calling -// FlutterDesktopRunWindowLoop on the returned reference is a memory leak. -FLUTTER_EXPORT FlutterDesktopWindowRef +// one of those two methods on the returned reference is a memory leak. +FLUTTER_EXPORT FlutterDesktopWindowControllerRef FlutterDesktopCreateWindow(int initial_width, int initial_height, const char* title, @@ -58,17 +63,48 @@ FlutterDesktopCreateWindow(int initial_width, const char** arguments, size_t argument_count); +// Shuts down the engine instance associated with |controller|, and cleans up +// associated state. +// +// |controller| is no longer valid after this call. +FLUTTER_EXPORT void FlutterDesktopDestroyWindow( + FlutterDesktopWindowControllerRef controller); + +// Loops on Flutter window events until the window is closed. +// +// Once this function returns, |controller| is no longer valid, and must not be +// be used again, as it calls FlutterDesktopDestroyWindow internally. +// +// TODO: Replace this with a method that allows running the runloop +// incrementally. +FLUTTER_EXPORT void FlutterDesktopRunWindowLoop( + FlutterDesktopWindowControllerRef controller); + +// Returns the window handle for the window associated with +// FlutterDesktopWindowControllerRef. +// +// Its lifetime is the same as the |controller|'s. +FLUTTER_EXPORT FlutterDesktopWindowRef +FlutterDesktopGetWindow(FlutterDesktopWindowControllerRef controller); + +// Returns the plugin registrar handle for the plugin with the given name. +// +// The name must be unique across the application. +FLUTTER_EXPORT FlutterDesktopPluginRegistrarRef +FlutterDesktopGetPluginRegistrar(FlutterDesktopWindowControllerRef controller, + const char* plugin_name); + // Enables or disables hover tracking. // // If hover is enabled, mouse movement will send hover events to the Flutter // engine, rather than only tracking the mouse while the button is pressed. // Defaults to off. -FLUTTER_EXPORT void FlutterDesktopSetHoverEnabled( +FLUTTER_EXPORT void FlutterDesktopWindowSetHoverEnabled( FlutterDesktopWindowRef flutter_window, bool enabled); // Sets the displayed title for |flutter_window|. -FLUTTER_EXPORT void FlutterDesktopSetWindowTitle( +FLUTTER_EXPORT void FlutterDesktopWindowSetTitle( FlutterDesktopWindowRef flutter_window, const char* title); @@ -77,19 +113,12 @@ FLUTTER_EXPORT void FlutterDesktopSetWindowTitle( // The pixel format is 32-bit RGBA. The provided image data only needs to be // valid for the duration of the call to this method. Pass a nullptr to revert // to the default icon. -FLUTTER_EXPORT void FlutterDesktopSetWindowIcon( +FLUTTER_EXPORT void FlutterDesktopWindowSetIcon( FlutterDesktopWindowRef flutter_window, uint8_t* pixel_data, int width, int height); -// Loops on Flutter window events until the window is closed. -// -// Once this function returns, FlutterDesktopWindowRef is no longer valid, and -// must not be used again. -FLUTTER_EXPORT void FlutterDesktopRunWindowLoop( - FlutterDesktopWindowRef flutter_window); - // Runs an instance of a headless Flutter engine. // // The |assets_path| is the path to the flutter_assets folder for the Flutter @@ -112,12 +141,10 @@ FlutterDesktopRunEngine(const char* assets_path, FLUTTER_EXPORT bool FlutterDesktopShutDownEngine( FlutterDesktopEngineRef engine_ref); -// Returns the plugin registrar handle for the plugin with the given name. -// -// The name must be unique across the application. -FLUTTER_EXPORT FlutterDesktopPluginRegistrarRef -FlutterDesktopGetPluginRegistrar(FlutterDesktopWindowRef flutter_window, - const char* plugin_name); +// Returns the window associated with this registrar's engine instance. +// This is a GLFW shell-specific extension to flutter_plugin_registrar.h +FLUTTER_EXPORT FlutterDesktopWindowRef +FlutterDesktopRegistrarGetWindow(FlutterDesktopPluginRegistrarRef registrar); #if defined(__cplusplus) } // extern "C"