From 3ef173d1e333f477f0b0aec54a8720f2c126ff6f Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Wed, 1 May 2019 18:41:58 -0400 Subject: [PATCH 1/7] Provide access to GLFW window in plugins Plugins may need to be able to access functions affecting the GLFW window (e.g., a plugin to resize the window). This restructures the API to create a distinction at both the C and C++ level between the window controller, which provides access to high-level behaviors driving the Flutter application, and the window, which provides access to functions to affect the UI state of the window (i.e., wrapped GLFWwindow functions). Also provides a PluginRegistrar extension for plugins that need access to GLFW-specific functionality. --- .../include/flutter/plugin_registrar.h | 2 +- shell/platform/glfw/BUILD.gn | 5 +- shell/platform/glfw/client_wrapper/BUILD.gn | 6 +- .../flutter_window_controller.cc | 32 +++---- .../flutter/flutter_plugin_registrar_glfw.h | 44 +++++++++ .../include/flutter/flutter_window.h | 58 ++++++++++++ .../flutter/flutter_window_controller.h | 32 +++---- .../testing/stub_flutter_glfw_api.cc | 36 ++++--- .../testing/stub_flutter_glfw_api.h | 21 +++-- shell/platform/glfw/flutter_glfw.cc | 94 +++++++++++++------ shell/platform/glfw/public/flutter_glfw.h | 49 ++++++---- .../public/flutter_plugin_registrar_glfw.h | 25 +++++ 12 files changed, 289 insertions(+), 115 deletions(-) create mode 100644 shell/platform/glfw/client_wrapper/include/flutter/flutter_plugin_registrar_glfw.h create mode 100644 shell/platform/glfw/client_wrapper/include/flutter/flutter_window.h create mode 100644 shell/platform/glfw/public/flutter_plugin_registrar_glfw.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/BUILD.gn b/shell/platform/glfw/BUILD.gn index 478d2e80e3255..c04df24efe9d7 100644 --- a/shell/platform/glfw/BUILD.gn +++ b/shell/platform/glfw/BUILD.gn @@ -2,7 +2,10 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -_public_headers = [ "public/flutter_glfw.h" ] +_public_headers = [ + "public/flutter_glfw.h", + "public/flutter_plugin_registrar_glfw.h", +] # Any files that are built by clients (client_wrapper code, library headers for # implementations using this shared code, etc.) include the public headers diff --git a/shell/platform/glfw/client_wrapper/BUILD.gn b/shell/platform/glfw/client_wrapper/BUILD.gn index 4a59ee8f4aae7..ee63ee7f3fae2 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_plugin_registrar_glfw.h", + "include/flutter/flutter_window.h", + "include/flutter/flutter_window_controller.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..9080e6456785d 100644 --- a/shell/platform/glfw/client_wrapper/flutter_window_controller.cc +++ b/shell/platform/glfw/client_wrapper/flutter_window_controller.cc @@ -33,7 +33,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 +44,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_plugin_registrar_glfw.h b/shell/platform/glfw/client_wrapper/include/flutter/flutter_plugin_registrar_glfw.h new file mode 100644 index 0000000000000..9cf589dd71cd0 --- /dev/null +++ b/shell/platform/glfw/client_wrapper/include/flutter/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_FLUTTER_PLUGIN_REGISTRAR_GLFW_H_ +#define FLUTTER_SHELL_PLATFORM_GLFW_CLIENT_WRAPPER_INCLUDE_FLUTTER_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(); + + // 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_FLUTTER_PLUGIN_REGISTRAR_GLFW_H_ 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..a6304bc075428 --- /dev/null +++ b/shell/platform/glfw/client_wrapper/include/flutter/flutter_window.h @@ -0,0 +1,58 @@ +// 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. + 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/testing/stub_flutter_glfw_api.cc b/shell/platform/glfw/client_wrapper/testing/stub_flutter_glfw_api.cc index db564018bc412..a93310de7737d 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,22 @@ FlutterDesktopWindowRef FlutterDesktopCreateWindow(int initial_width, return nullptr; } -void FlutterDesktopSetHoverEnabled(FlutterDesktopWindowRef flutter_window, - bool enabled) { +void FlutterDesktopWindowSetHoverEnabled( + FlutterDesktopWindowControllerRef controller, + 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 +88,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 +112,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..b76e9f91dafba 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,24 @@ 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 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..bc0a2f5dcf273 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()); @@ -557,8 +578,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,11 +594,28 @@ void FlutterDesktopRunWindowLoop(FlutterDesktopWindowRef flutter_window) { // TODO(awdavies): This will be deprecated soon. __FlutterEngineFlushPendingTasksNow(); } - FlutterEngineShutdown(flutter_window->engine); - delete flutter_window; + FlutterEngineShutdown(controller->engine); + delete controller; glfwDestroyWindow(window); } +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, const char* icu_data_path, const char** arguments, @@ -599,15 +637,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 +648,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..db1c61a8f31f9 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; @@ -49,7 +53,7 @@ FLUTTER_EXPORT void FlutterDesktopTerminate(); // valid until FlutterDesktopRunWindowLoop has been called and returned. // Note that calling FlutterDesktopCreateWindow without later calling // FlutterDesktopRunWindowLoop on the returned reference is a memory leak. -FLUTTER_EXPORT FlutterDesktopWindowRef +FLUTTER_EXPORT FlutterDesktopWindowControllerRef FlutterDesktopCreateWindow(int initial_width, int initial_height, const char* title, @@ -58,17 +62,38 @@ FlutterDesktopCreateWindow(int initial_width, const char** arguments, size_t argument_count); +// Loops on Flutter window events until the window is closed. +// +// Once this function returns, |controller| is no longer +// valid, and must not be used again. +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 +102,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,13 +130,6 @@ 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); - #if defined(__cplusplus) } // extern "C" #endif diff --git a/shell/platform/glfw/public/flutter_plugin_registrar_glfw.h b/shell/platform/glfw/public/flutter_plugin_registrar_glfw.h new file mode 100644 index 0000000000000..fc323724f35d1 --- /dev/null +++ b/shell/platform/glfw/public/flutter_plugin_registrar_glfw.h @@ -0,0 +1,25 @@ +// 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_PUBLIC_FLUTTER_PLUGIN_REGISTRAR_GLFW_H_ +#define FLUTTER_SHELL_PLATFORM_GLFW_PUBLIC_FLUTTER_PLUGIN_REGISTRAR_GLFW_H_ + +// This file contains additional plugin registrar-based functions available for +// the GLFW shell. + +#include "flutter_glfw.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +// Returns the window associated with this registrar's engine instance. +FLUTTER_EXPORT FlutterDesktopWindowRef +FlutterDesktopRegistrarGetWindow(FlutterDesktopPluginRegistrarRef registrar); + +#if defined(__cplusplus) +} // extern "C" +#endif + +#endif // FLUTTER_SHELL_PLATFORM_GLFW_PUBLIC_FLUTTER_PLUGIN_REGISTRAR_GLFW_H_ From ede8a67563ae5d74b45ca4187c5033af14d8d43f Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Wed, 1 May 2019 19:39:04 -0400 Subject: [PATCH 2/7] Rename a header to match class name --- shell/platform/glfw/client_wrapper/BUILD.gn | 2 +- ...tter_plugin_registrar_glfw.h => plugin_registrar_glfw.h} | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) rename shell/platform/glfw/client_wrapper/include/flutter/{flutter_plugin_registrar_glfw.h => plugin_registrar_glfw.h} (92%) diff --git a/shell/platform/glfw/client_wrapper/BUILD.gn b/shell/platform/glfw/client_wrapper/BUILD.gn index ee63ee7f3fae2..1ba2c7e431237 100644 --- a/shell/platform/glfw/client_wrapper/BUILD.gn +++ b/shell/platform/glfw/client_wrapper/BUILD.gn @@ -5,9 +5,9 @@ import("$flutter_root/shell/platform/common/cpp/client_wrapper/publish.gni") _wrapper_includes = [ - "include/flutter/flutter_plugin_registrar_glfw.h", "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/include/flutter/flutter_plugin_registrar_glfw.h b/shell/platform/glfw/client_wrapper/include/flutter/plugin_registrar_glfw.h similarity index 92% rename from shell/platform/glfw/client_wrapper/include/flutter/flutter_plugin_registrar_glfw.h rename to shell/platform/glfw/client_wrapper/include/flutter/plugin_registrar_glfw.h index 9cf589dd71cd0..65af8c7b99b47 100644 --- a/shell/platform/glfw/client_wrapper/include/flutter/flutter_plugin_registrar_glfw.h +++ b/shell/platform/glfw/client_wrapper/include/flutter/plugin_registrar_glfw.h @@ -2,8 +2,8 @@ // 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_PLUGIN_REGISTRAR_GLFW_H_ -#define FLUTTER_SHELL_PLATFORM_GLFW_CLIENT_WRAPPER_INCLUDE_FLUTTER_FLUTTER_PLUGIN_REGISTRAR_GLFW_H_ +#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 @@ -41,4 +41,4 @@ class PluginRegistrarGlfw : public PluginRegistrar { } // namespace flutter -#endif // FLUTTER_SHELL_PLATFORM_GLFW_CLIENT_WRAPPER_INCLUDE_FLUTTER_FLUTTER_PLUGIN_REGISTRAR_GLFW_H_ +#endif // FLUTTER_SHELL_PLATFORM_GLFW_CLIENT_WRAPPER_INCLUDE_FLUTTER_PLUGIN_REGISTRAR_GLFW_H_ From 9d1fe8650d67d817091f780d4263b80aae331d8b Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Wed, 1 May 2019 19:46:12 -0400 Subject: [PATCH 3/7] Fold new header back into flutter_glfw to avoid recipe changes --- shell/platform/glfw/BUILD.gn | 1 - .../include/flutter/plugin_registrar_glfw.h | 2 +- shell/platform/glfw/public/flutter_glfw.h | 5 ++++ .../public/flutter_plugin_registrar_glfw.h | 25 ------------------- 4 files changed, 6 insertions(+), 27 deletions(-) delete mode 100644 shell/platform/glfw/public/flutter_plugin_registrar_glfw.h diff --git a/shell/platform/glfw/BUILD.gn b/shell/platform/glfw/BUILD.gn index c04df24efe9d7..42c3112c90965 100644 --- a/shell/platform/glfw/BUILD.gn +++ b/shell/platform/glfw/BUILD.gn @@ -4,7 +4,6 @@ _public_headers = [ "public/flutter_glfw.h", - "public/flutter_plugin_registrar_glfw.h", ] # Any files that are built by clients (client_wrapper code, library headers for 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 index 65af8c7b99b47..71a916fee9966 100644 --- a/shell/platform/glfw/client_wrapper/include/flutter/plugin_registrar_glfw.h +++ b/shell/platform/glfw/client_wrapper/include/flutter/plugin_registrar_glfw.h @@ -7,7 +7,7 @@ #include -#include +#include #include "flutter_window.h" #include "plugin_registrar.h" diff --git a/shell/platform/glfw/public/flutter_glfw.h b/shell/platform/glfw/public/flutter_glfw.h index db1c61a8f31f9..df688381ae57d 100644 --- a/shell/platform/glfw/public/flutter_glfw.h +++ b/shell/platform/glfw/public/flutter_glfw.h @@ -130,6 +130,11 @@ FlutterDesktopRunEngine(const char* assets_path, FLUTTER_EXPORT bool FlutterDesktopShutDownEngine( FlutterDesktopEngineRef engine_ref); +// 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" #endif diff --git a/shell/platform/glfw/public/flutter_plugin_registrar_glfw.h b/shell/platform/glfw/public/flutter_plugin_registrar_glfw.h deleted file mode 100644 index fc323724f35d1..0000000000000 --- a/shell/platform/glfw/public/flutter_plugin_registrar_glfw.h +++ /dev/null @@ -1,25 +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_GLFW_PUBLIC_FLUTTER_PLUGIN_REGISTRAR_GLFW_H_ -#define FLUTTER_SHELL_PLATFORM_GLFW_PUBLIC_FLUTTER_PLUGIN_REGISTRAR_GLFW_H_ - -// This file contains additional plugin registrar-based functions available for -// the GLFW shell. - -#include "flutter_glfw.h" - -#if defined(__cplusplus) -extern "C" { -#endif - -// Returns the window associated with this registrar's engine instance. -FLUTTER_EXPORT FlutterDesktopWindowRef -FlutterDesktopRegistrarGetWindow(FlutterDesktopPluginRegistrarRef registrar); - -#if defined(__cplusplus) -} // extern "C" -#endif - -#endif // FLUTTER_SHELL_PLATFORM_GLFW_PUBLIC_FLUTTER_PLUGIN_REGISTRAR_GLFW_H_ From bb29d0dc9a05972b1214a61d651e3246263c8f11 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Wed, 1 May 2019 19:52:24 -0400 Subject: [PATCH 4/7] Fix link bugs --- .../include/flutter/plugin_registrar_glfw.h | 2 +- shell/platform/glfw/flutter_glfw.cc | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) 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 index 71a916fee9966..a2a9da9ef3f8b 100644 --- a/shell/platform/glfw/client_wrapper/include/flutter/plugin_registrar_glfw.h +++ b/shell/platform/glfw/client_wrapper/include/flutter/plugin_registrar_glfw.h @@ -26,7 +26,7 @@ class PluginRegistrarGlfw : public PluginRegistrar { FlutterDesktopRegistrarGetWindow(core_registrar)); } - virtual ~PluginRegistrarGlfw(); + virtual ~PluginRegistrarGlfw() = default; // Prevent copying. PluginRegistrarGlfw(PluginRegistrarGlfw const&) = delete; diff --git a/shell/platform/glfw/flutter_glfw.cc b/shell/platform/glfw/flutter_glfw.cc index bc0a2f5dcf273..84f61be78dc70 100644 --- a/shell/platform/glfw/flutter_glfw.cc +++ b/shell/platform/glfw/flutter_glfw.cc @@ -557,19 +557,19 @@ FlutterDesktopWindowControllerRef FlutterDesktopCreateWindow( return state; } -void FlutterDesktopSetHoverEnabled(FlutterDesktopWindowRef flutter_window, - bool enabled) { +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) { From 71fb7f5125cae9cdc05854038d3a499995418e47 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Wed, 1 May 2019 19:54:54 -0400 Subject: [PATCH 5/7] GN format --- shell/platform/glfw/BUILD.gn | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/shell/platform/glfw/BUILD.gn b/shell/platform/glfw/BUILD.gn index 42c3112c90965..478d2e80e3255 100644 --- a/shell/platform/glfw/BUILD.gn +++ b/shell/platform/glfw/BUILD.gn @@ -2,9 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -_public_headers = [ - "public/flutter_glfw.h", -] +_public_headers = [ "public/flutter_glfw.h" ] # Any files that are built by clients (client_wrapper code, library headers for # implementations using this shared code, etc.) include the public headers From fb62eef19d574835f291c09439011153d472536b Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Thu, 2 May 2019 23:41:31 -0400 Subject: [PATCH 6/7] Add new files to license list --- ci/licenses_golden/licenses_flutter | 2 ++ 1 file changed, 2 insertions(+) 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 From 2dbc2692f47231f234dd0ad5b30336994530d261 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Mon, 6 May 2019 15:17:24 -0400 Subject: [PATCH 7/7] Add a way to destroy a window without running the runloop --- .../flutter_window_controller.cc | 3 +++ .../include/flutter/flutter_window.h | 2 ++ .../testing/stub_flutter_glfw_api.cc | 11 ++++++++--- .../testing/stub_flutter_glfw_api.h | 3 +++ shell/platform/glfw/flutter_glfw.cc | 10 +++++++--- shell/platform/glfw/public/flutter_glfw.h | 19 +++++++++++++++---- 6 files changed, 38 insertions(+), 10 deletions(-) diff --git a/shell/platform/glfw/client_wrapper/flutter_window_controller.cc b/shell/platform/glfw/client_wrapper/flutter_window_controller.cc index 9080e6456785d..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(); } diff --git a/shell/platform/glfw/client_wrapper/include/flutter/flutter_window.h b/shell/platform/glfw/client_wrapper/include/flutter/flutter_window.h index a6304bc075428..4b6b646a08974 100644 --- a/shell/platform/glfw/client_wrapper/include/flutter/flutter_window.h +++ b/shell/platform/glfw/client_wrapper/include/flutter/flutter_window.h @@ -50,6 +50,8 @@ class FlutterWindow { private: // Handle for interacting with the C API's window. + // + // Note: window_ is conceptually owned by the controller, not this object. FlutterDesktopWindowRef window_; }; 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 a93310de7737d..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 @@ -64,9 +64,14 @@ FlutterDesktopWindowControllerRef FlutterDesktopCreateWindow( return nullptr; } -void FlutterDesktopWindowSetHoverEnabled( - FlutterDesktopWindowControllerRef controller, - 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); } 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 b76e9f91dafba..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 @@ -47,6 +47,9 @@ class StubFlutterGlfwApi { return nullptr; } + // Called for FlutterDesktopDestroyWindow + virtual void DestroyWindow() {} + // Called for FlutterDesktopWindowSetHoverEnabled. virtual void SetHoverEnabled(bool enabled) {} diff --git a/shell/platform/glfw/flutter_glfw.cc b/shell/platform/glfw/flutter_glfw.cc index 84f61be78dc70..7b124cc35357e 100644 --- a/shell/platform/glfw/flutter_glfw.cc +++ b/shell/platform/glfw/flutter_glfw.cc @@ -557,6 +557,12 @@ FlutterDesktopWindowControllerRef FlutterDesktopCreateWindow( return state; } +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; @@ -594,9 +600,7 @@ void FlutterDesktopRunWindowLoop(FlutterDesktopWindowControllerRef controller) { // TODO(awdavies): This will be deprecated soon. __FlutterEngineFlushPendingTasksNow(); } - FlutterEngineShutdown(controller->engine); - delete controller; - glfwDestroyWindow(window); + FlutterDesktopDestroyWindow(controller); } FlutterDesktopWindowRef FlutterDesktopGetWindow( diff --git a/shell/platform/glfw/public/flutter_glfw.h b/shell/platform/glfw/public/flutter_glfw.h index df688381ae57d..bffc769a3cffa 100644 --- a/shell/platform/glfw/public/flutter_glfw.h +++ b/shell/platform/glfw/public/flutter_glfw.h @@ -50,9 +50,10 @@ 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. +// one of those two methods on the returned reference is a memory leak. FLUTTER_EXPORT FlutterDesktopWindowControllerRef FlutterDesktopCreateWindow(int initial_width, int initial_height, @@ -62,10 +63,20 @@ 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 used again. +// 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);