diff --git a/library/common/glfw/embedder.cc b/library/common/glfw/embedder.cc index 8c05b249c..63d9e2bed 100644 --- a/library/common/glfw/embedder.cc +++ b/library/common/glfw/embedder.cc @@ -89,9 +89,9 @@ static FlutterEmbedderState *GetSavedEmbedderState(GLFWwindow *window) { } // Converts a FlutterPlatformMessage to an equivalent FlutterEmbedderMessage. -static flutter_desktop_embedding::FlutterEmbedderMessage -ConvertToEmbedderMessage(const FlutterPlatformMessage &engine_message) { - flutter_desktop_embedding::FlutterEmbedderMessage embedder_message = {}; +static FlutterEmbedderMessage ConvertToEmbedderMessage( + const FlutterPlatformMessage &engine_message) { + FlutterEmbedderMessage embedder_message = {}; embedder_message.struct_size = sizeof(embedder_message); embedder_message.channel = engine_message.channel; embedder_message.message = engine_message.message; @@ -284,17 +284,18 @@ static void GLFWErrorCallback(int error_code, const char *description) { // the necessary callbacks for rendering within a GLFWwindow. // // Returns a caller-owned pointer to the engine. -static FlutterEngine RunFlutterEngine( - GLFWwindow *window, const std::string &assets_path, - const std::string &icu_data_path, - const std::vector &arguments) { +static FlutterEngine RunFlutterEngine(GLFWwindow *window, + const char *assets_path, + const char *icu_data_path, + const char **arguments, + size_t arguments_count) { // FlutterProjectArgs is expecting a full argv, so when processing it for // flags the first item is treated as the executable and ignored. Add a dummy // value so that all provided arguments are used. std::vector argv = {"placeholder"}; - std::transform( - arguments.begin(), arguments.end(), std::back_inserter(argv), - [](const std::string &arg) -> const char * { return arg.c_str(); }); + if (arguments_count > 0) { + argv.insert(argv.end(), &arguments[0], &arguments[arguments_count]); + } FlutterRendererConfig config = {}; config.type = kOpenGL; @@ -306,8 +307,8 @@ static FlutterEngine RunFlutterEngine( config.open_gl.gl_proc_resolver = GLFWProcResolver; FlutterProjectArgs args = {}; args.struct_size = sizeof(FlutterProjectArgs); - args.assets_path = assets_path.c_str(); - args.icu_data_path = icu_data_path.c_str(); + args.assets_path = assets_path; + args.icu_data_path = icu_data_path; args.command_line_argc = argv.size(); args.command_line_argv = &argv[0]; args.platform_message_callback = GLFWOnFlutterPlatformMessage; @@ -322,20 +323,17 @@ static FlutterEngine RunFlutterEngine( return engine; } -namespace flutter_desktop_embedding { - -bool FlutterInit() { +bool FlutterEmbedderInit() { // Before making any GLFW calls, set up a logging error handler. glfwSetErrorCallback(GLFWErrorCallback); return glfwInit(); } -void FlutterTerminate() { glfwTerminate(); } +void FlutterEmbedderTerminate() { glfwTerminate(); } -FlutterWindowRef CreateFlutterWindow( - size_t initial_width, size_t initial_height, const std::string &assets_path, - const std::string &icu_data_path, - const std::vector &arguments) { +FlutterWindowRef FlutterEmbedderCreateWindow( + size_t initial_width, size_t initial_height, const char *assets_path, + const char *icu_data_path, const char **arguments, size_t argument_count) { #ifdef __linux__ gtk_init(0, nullptr); #endif @@ -348,7 +346,8 @@ FlutterWindowRef CreateFlutterWindow( GLFWClearCanvas(window); // Start the engine. - auto engine = RunFlutterEngine(window, assets_path, icu_data_path, arguments); + auto engine = RunFlutterEngine(window, assets_path, icu_data_path, arguments, + argument_count); if (engine == nullptr) { glfwDestroyWindow(window); return nullptr; @@ -360,14 +359,18 @@ FlutterWindowRef CreateFlutterWindow( glfwSetWindowUserPointer(window, state); state->engine = engine; state->message_dispatcher = - std::make_unique(state); - state->plugin_handler = std::make_unique(state); + std::make_unique( + state); + state->plugin_handler = + std::make_unique(state); // Set up the keyboard handlers. state->keyboard_hook_handlers.push_back( - std::make_unique(state->plugin_handler.get())); + std::make_unique( + state->plugin_handler.get())); state->keyboard_hook_handlers.push_back( - std::make_unique(state->plugin_handler.get())); + std::make_unique( + state->plugin_handler.get())); // Trigger an initial size callback to send size information to Flutter. state->monitor_screen_coordinates_per_inch = GetScreenCoordinatesPerInch(); @@ -382,7 +385,7 @@ FlutterWindowRef CreateFlutterWindow( return state; } -void FlutterWindowLoop(FlutterWindowRef flutter_window) { +void FlutterEmbedderRunWindowLoop(FlutterWindowRef flutter_window) { GLFWwindow *window = flutter_window->window; #ifdef __linux__ // Necessary for GTK thread safety. @@ -438,5 +441,3 @@ void FlutterEmbedderEnableInputBlocking(FlutterWindowRef flutter_window, const char *channel) { flutter_window->message_dispatcher->EnableInputBlockingForChannel(channel); } - -} // namespace flutter_desktop_embedding diff --git a/library/common/glfw/flutter_window_controller.cc b/library/common/glfw/flutter_window_controller.cc index cfe8fe5de..919a33646 100644 --- a/library/common/glfw/flutter_window_controller.cc +++ b/library/common/glfw/flutter_window_controller.cc @@ -14,6 +14,7 @@ #include "library/include/flutter_desktop_embedding/glfw/flutter_window_controller.h" +#include #include #include "library/common/internal/plugin_handler.h" @@ -22,12 +23,12 @@ namespace flutter_desktop_embedding { FlutterWindowController::FlutterWindowController(std::string &icu_data_path) : icu_data_path_(icu_data_path) { - init_succeeded_ = FlutterInit(); + init_succeeded_ = FlutterEmbedderInit(); } FlutterWindowController::~FlutterWindowController() { if (init_succeeded_) { - FlutterTerminate(); + FlutterEmbedderTerminate(); } } @@ -35,7 +36,8 @@ bool FlutterWindowController::CreateWindow( size_t width, size_t height, const std::string &assets_path, const std::vector &arguments) { if (!init_succeeded_) { - std::cerr << "Could not create window; FlutterInit failed." << std::endl; + std::cerr << "Could not create window; FlutterEmbedderInit failed." + << std::endl; return false; } @@ -44,8 +46,14 @@ bool FlutterWindowController::CreateWindow( return false; } - window_ = CreateFlutterWindow(width, height, assets_path, icu_data_path_, - arguments); + std::vector engine_arguments; + std::transform( + arguments.begin(), arguments.end(), std::back_inserter(engine_arguments), + [](const std::string &arg) -> const char * { return arg.c_str(); }); + + window_ = FlutterEmbedderCreateWindow( + width, height, assets_path.c_str(), icu_data_path_.c_str(), + &engine_arguments[0], engine_arguments.size()); if (!window_) { std::cerr << "Failed to create window." << std::endl; return false; @@ -69,7 +77,7 @@ PluginRegistrar *FlutterWindowController::GetRegistrarForPlugin( void FlutterWindowController::RunEventLoop() { if (window_) { - FlutterWindowLoop(window_); + FlutterEmbedderRunWindowLoop(window_); } } diff --git a/library/include/flutter_desktop_embedding/glfw/embedder.h b/library/include/flutter_desktop_embedding/glfw/embedder.h index 669bab07d..771b7796d 100644 --- a/library/include/flutter_desktop_embedding/glfw/embedder.h +++ b/library/include/flutter_desktop_embedding/glfw/embedder.h @@ -15,9 +15,8 @@ #ifndef LIBRARY_INCLUDE_FLUTTER_DESKTOP_EMBEDDING_GLFW_EMBEDDER_H_ #define LIBRARY_INCLUDE_FLUTTER_DESKTOP_EMBEDDING_GLFW_EMBEDDER_H_ -#include -#include -#include +#include +#include // On Linux, the header output is always flattened; on Windows the GN build // is still optional. Once GN is required on Windows, eliminate this and just @@ -34,6 +33,10 @@ #include "../fde_export.h" #endif +#if defined(__cplusplus) +extern "C" { +#endif + // Opaque reference to a Flutter window. typedef struct FlutterEmbedderState *FlutterWindowRef; @@ -41,22 +44,20 @@ typedef struct FlutterEmbedderState *FlutterWindowRef; typedef struct _FlutterPlatformMessageResponseHandle FlutterEmbedderMessageResponseHandle; -namespace flutter_desktop_embedding { - // Sets up the embedder's graphic context. Must be called before any other // methods. // // Note: Internally, this library uses GLFW, which does not support multiple // copies within the same process. Internally this calls glfwInit, which will // fail if you have called glfwInit elsewhere in the process. -FDE_EXPORT bool FlutterInit(); +FDE_EXPORT bool FlutterEmbedderInit(); // Tears down embedder state. Must be called before the process terminates. -FDE_EXPORT void FlutterTerminate(); +FDE_EXPORT void FlutterEmbedderTerminate(); // Creates a Window running a Flutter Application. // -// FlutterInit() must be called prior to this function. +// FlutterEmbedderInit() must be called prior to this function. // // The |assets_path| is the path to the flutter_assets folder for the Flutter // application to be run. |icu_data_path| is the path to the icudtl.dat file @@ -67,19 +68,18 @@ FDE_EXPORT void FlutterTerminate(); // for details. Not all arguments will apply to embedding mode. // // Returns a null pointer in the event of an error. Otherwise, the pointer is -// valid until FlutterWindowLoop has been called and returned. Note that calling -// CreateFlutterWindow without later calling FlutterWindowLoop on that pointer -// is a memory leak. -FDE_EXPORT FlutterWindowRef CreateFlutterWindow( - size_t initial_width, size_t initial_height, const std::string &assets_path, - const std::string &icu_data_path, - const std::vector &arguments); +// valid until FlutterEmbedderRunWindowLoop has been called and returned. +// Note that calling FlutterEmbedderCreateWindow without later calling +// FlutterEmbedderRunWindowLoop on the returned reference is a memory leak. +FDE_EXPORT FlutterWindowRef FlutterEmbedderCreateWindow( + size_t initial_width, size_t initial_height, const char *assets_path, + const char *icu_data_path, const char **arguments, size_t argument_count); // Loops on Flutter window events until the window is closed. // // Once this function returns, FlutterWindowRef is no longer valid, and must // not be used again. -FDE_EXPORT void FlutterWindowLoop(FlutterWindowRef flutter_window); +FDE_EXPORT void FlutterEmbedderRunWindowLoop(FlutterWindowRef flutter_window); // A received from Flutter. typedef struct { @@ -141,6 +141,8 @@ FDE_EXPORT void FlutterEmbedderSetMessageCallback( FDE_EXPORT void FlutterEmbedderEnableInputBlocking( FlutterWindowRef flutter_window, const char *channel); -} // namespace flutter_desktop_embedding +#if defined(__cplusplus) +} // extern "C" +#endif #endif // LIBRARY_INCLUDE_FLUTTER_DESKTOP_EMBEDDING_GLFW_EMBEDDER_H_ diff --git a/library/include/flutter_desktop_embedding/glfw/flutter_window_controller.h b/library/include/flutter_desktop_embedding/glfw/flutter_window_controller.h index 1a926c777..7f2ce4f52 100644 --- a/library/include/flutter_desktop_embedding/glfw/flutter_window_controller.h +++ b/library/include/flutter_desktop_embedding/glfw/flutter_window_controller.h @@ -79,7 +79,7 @@ class FDE_EXPORT FlutterWindowController { // for any window created. std::string icu_data_path_; - // Whether or not FlutterInit succeeded at creation time. + // Whether or not FlutterEmbedderInit succeeded at creation time. bool init_succeeded_ = false; // The curent Flutter window, if any.