diff --git a/example/linux_fde/flutter_embedder_example.cc b/example/linux_fde/flutter_embedder_example.cc index cfbd64f3e..2dc82fc99 100644 --- a/example/linux_fde/flutter_embedder_example.cc +++ b/example/linux_fde/flutter_embedder_example.cc @@ -24,9 +24,9 @@ #include #ifdef USE_FLATTENED_INCLUDES -#include +#include #else -#include +#include #endif namespace { @@ -53,11 +53,6 @@ std::string GetExecutableDirectory() { } // namespace int main(int argc, char **argv) { - if (!flutter_desktop_embedding::FlutterInit()) { - std::cerr << "Unable to init GLFW; exiting." << std::endl; - return EXIT_FAILURE; - } - // Resources are located relative to the executable. std::string base_directory = GetExecutableDirectory(); if (base_directory.empty()) { @@ -72,27 +67,27 @@ int main(int argc, char **argv) { #ifdef NDEBUG arguments.push_back("--disable-dart-asserts"); #endif + + flutter_desktop_embedding::FlutterWindowController flutter_controller( + icu_data_path); + // Start the engine. - auto window = flutter_desktop_embedding::CreateFlutterWindow( - 640, 480, assets_path, icu_data_path, arguments); - if (window == nullptr) { - flutter_desktop_embedding::FlutterTerminate(); - std::cerr << "Unable to create Flutter window; exiting." << std::endl; + if (!flutter_controller.CreateWindow(640, 480, assets_path, arguments)) { return EXIT_FAILURE; } // Register any native plugins. plugins_menubar::MenubarPlugin::RegisterWithRegistrar( - flutter_desktop_embedding::GetRegistrarForPlugin( - window, "plugins_menubar::MenubarPlugin")); + flutter_controller.GetRegistrarForPlugin( + "plugins_menubar::MenubarPlugin")); plugins_color_panel::ColorPanelPlugin::RegisterWithRegistrar( - flutter_desktop_embedding::GetRegistrarForPlugin( - window, "plugins_color_panel::ColorPanelPlugin")); + flutter_controller.GetRegistrarForPlugin( + "plugins_color_panel::ColorPanelPlugin")); plugins_file_chooser::FileChooserPlugin::RegisterWithRegistrar( - flutter_desktop_embedding::GetRegistrarForPlugin( - window, "plugins_file_chooser::FileChooserPlugin")); + flutter_controller.GetRegistrarForPlugin( + "plugins_file_chooser::FileChooserPlugin")); - flutter_desktop_embedding::FlutterWindowLoop(window); - glfwTerminate(); + // Run until the window is closed. + flutter_controller.RunEventLoop(); return EXIT_SUCCESS; } diff --git a/example/windows_fde/flutter_embedder_example.cpp b/example/windows_fde/flutter_embedder_example.cpp index 9ea8d70a7..34b8530eb 100644 --- a/example/windows_fde/flutter_embedder_example.cpp +++ b/example/windows_fde/flutter_embedder_example.cpp @@ -13,32 +13,31 @@ // limitations under the License. #include +#include #include -#include "flutter_desktop_embedding/glfw/embedder.h" +#include "flutter_desktop_embedding/glfw/flutter_window_controller.h" int main(int argc, char **argv) { - if (!flutter_desktop_embedding::FlutterInit()) { - std::cerr << "Unable to init GLFW; exiting." << std::endl; - return EXIT_FAILURE; - } + // TODO: Make paths relative to the executable so it can be run from anywhere. + std::string assets_path = "..\\build\\flutter_assets"; + std::string icu_data_path = + "..\\..\\library\\windows\\dependencies\\engine\\icudtl.dat"; + // Arguments for the Flutter Engine. std::vector arguments; #ifndef _DEBUG arguments.push_back("--disable-dart-asserts"); #endif + flutter_desktop_embedding::FlutterWindowController flutter_controller( + icu_data_path); + // Start the engine. - // TODO: Make paths relative to the executable so it can be run from anywhere. - auto window = flutter_desktop_embedding::CreateFlutterWindow( - 640, 480, "..\\build\\flutter_assets", - "..\\..\\library\\windows\\dependencies\\engine\\icudtl.dat", arguments); - if (window == nullptr) { - flutter_desktop_embedding::FlutterTerminate(); - std::cerr << "Unable to create Flutter window; exiting." << std::endl; + if (!flutter_controller.CreateWindow(640, 480, assets_path, arguments)) { return EXIT_FAILURE; } - flutter_desktop_embedding::FlutterWindowLoop(window); - flutter_desktop_embedding::FlutterTerminate(); + // Run until the window is closed. + flutter_controller.RunEventLoop(); return EXIT_SUCCESS; } diff --git a/library/BUILD.gn b/library/BUILD.gn index 12aedfb09..e4d786eec 100644 --- a/library/BUILD.gn +++ b/library/BUILD.gn @@ -21,9 +21,11 @@ published_shared_library("flutter_embedder") { if (is_linux || is_win) { public = [ "include/flutter_desktop_embedding/glfw/embedder.h", + "include/flutter_desktop_embedding/glfw/flutter_window_controller.h", ] sources = [ "common/glfw/embedder.cc", + "common/glfw/flutter_window_controller.cc", "common/glfw/key_event_handler.cc", "common/glfw/key_event_handler.h", "common/glfw/keyboard_hook_handler.h", diff --git a/library/README.md b/library/README.md index 98447350f..2cd62a2a9 100644 --- a/library/README.md +++ b/library/README.md @@ -55,7 +55,8 @@ $ sudo apt-get install libglfw3-dev libepoxy-dev libjsoncpp-dev libgtk-3-dev \ #### Using the Library Run `make` under `linux/`, then link `libflutter_embedder.so` into your -binary. See [embedder.h](include/flutter_desktop_embedding/glfw/embedder.h) +binary. See +[flutter_window_controller.h](include/flutter_desktop_embedding/glfw/flutter_window_controller.h) for details on calling into the library. You will also need to link `libflutter_engine.so` into your binary. @@ -96,8 +97,8 @@ You must have a copy of Visual Studio installed. Build the GLFW Library project under `windows/` in Visual Studio into a static or dynamic library, then link `flutter_embedder.lib` into your binary and make -sure `embedder.h` is in your include paths. Also ensure that the -`flutter_engine.dll`, and if using a dynamic library +sure `flutter_window_controller.h` is in your include paths. Also ensure that +the `flutter_engine.dll`, and if using a dynamic library `flutter_embedder.dll`, are in valid DLL include paths. The output files are located in `bin\x64\$(Configuration)\GLFW Library\`. diff --git a/library/common/glfw/flutter_window_controller.cc b/library/common/glfw/flutter_window_controller.cc new file mode 100644 index 000000000..5e686130e --- /dev/null +++ b/library/common/glfw/flutter_window_controller.cc @@ -0,0 +1,68 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "library/include/flutter_desktop_embedding/glfw/flutter_window_controller.h" + +#include + +namespace flutter_desktop_embedding { + +FlutterWindowController::FlutterWindowController(std::string &icu_data_path) + : icu_data_path_(icu_data_path) { + init_succeeded_ = FlutterInit(); +} + +FlutterWindowController::~FlutterWindowController() { + if (init_succeeded_) { + FlutterTerminate(); + } +} + +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; + return false; + } + + if (window_) { + std::cerr << "Only one Flutter window can exist at a time." << std::endl; + return false; + } + + window_ = CreateFlutterWindow(width, height, assets_path, icu_data_path_, + arguments); + if (!window_) { + std::cerr << "Failed to create window." << std::endl; + return false; + } + return true; +} + +PluginRegistrar *FlutterWindowController::GetRegistrarForPlugin( + const std::string &plugin_name) { + if (!window_) { + return nullptr; + } + return flutter_desktop_embedding::GetRegistrarForPlugin(window_, plugin_name); +} + +void FlutterWindowController::RunEventLoop() { + if (window_) { + FlutterWindowLoop(window_); + } +} + +} // namespace flutter_desktop_embedding diff --git a/library/include/flutter_desktop_embedding/glfw/flutter_window_controller.h b/library/include/flutter_desktop_embedding/glfw/flutter_window_controller.h new file mode 100644 index 000000000..01e0092a0 --- /dev/null +++ b/library/include/flutter_desktop_embedding/glfw/flutter_window_controller.h @@ -0,0 +1,89 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef LIBRARY_INCLUDE_FLUTTER_DESKTOP_EMBEDDING_GLFW_FLUTTER_WINDOW_CONTROLLER_H_ +#define LIBRARY_INCLUDE_FLUTTER_DESKTOP_EMBEDDING_GLFW_FLUTTER_WINDOW_CONTROLLER_H_ + +#include +#include + +#include "embedder.h" + +#ifdef USE_FLATTENED_INCLUDES +#include "fde_export.h" +#include "plugin_registrar.h" +#else +#include "../fde_export.h" +#include "../plugin_registrar.h" +#endif + +namespace flutter_desktop_embedding { + +// A controller for a window displaying Flutter content. +// +// This is the primary wrapper class for the desktop embedding C API. +// If you use this class, you should not call any of the setup or teardown +// methods in embedder.h directly, as this class will do that internally. +// +// Note: This is an early implementation (using GLFW internally) which +// requires control of the application's event loop, and is thus useful +// primarily for building a simple one-window shell hosting a Flutter +// application. The final implementation and API will be very different. +class FDE_EXPORT FlutterWindowController { + public: + // There must be only one instance of this class in an application at any + // given time, as Flutter does not support multiple engines in one process, + // or multiple views in one engine. + explicit FlutterWindowController(std::string &icu_data_path); + + ~FlutterWindowController(); + + // Creates and displays a window for displaying Flutter content. + // + // 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 + // for the version of Flutter you are using. + // + // The |arguments| are passed to the Flutter engine. See: + // https://github.com/flutter/engine/blob/master/shell/common/switches.h for + // for details. Not all arguments will apply to embedding mode. + // + // Only one Flutter window can exist at a time; see constructor comment. + bool CreateWindow(size_t width, size_t height, const std::string &assets_path, + const std::vector &arguments); + + // Returns the PluginRegistrar to register a plugin with the given name. + // + // The name must be unique across the application, so the recommended approach + // is to use the fully namespace-qualified name of the plugin class. + PluginRegistrar *GetRegistrarForPlugin(const std::string &plugin_name); + + // Loops on Flutter window events until the window closes. + void RunEventLoop(); + + private: + // The path to the ICU data file. Set at creation time since it is the same + // for any window created. + std::string icu_data_path_; + + // Whether or not FlutterInit succeeded at creation time. + bool init_succeeded_ = false; + + // The curent Flutter window, if any. + GLFWwindow *window_ = nullptr; +}; + +} // namespace flutter_desktop_embedding + +#endif // LIBRARY_INCLUDE_FLUTTER_DESKTOP_EMBEDDING_GLFW_FLUTTER_WINDOW_CONTROLLER_H_ diff --git a/library/windows/GLFW Library.vcxproj b/library/windows/GLFW Library.vcxproj index d7dfa8a2f..c14747a6e 100644 --- a/library/windows/GLFW Library.vcxproj +++ b/library/windows/GLFW Library.vcxproj @@ -148,6 +148,7 @@ + diff --git a/library/windows/GLFW Library.vcxproj.filters b/library/windows/GLFW Library.vcxproj.filters index bf62d4890..ad4017e40 100644 --- a/library/windows/GLFW Library.vcxproj.filters +++ b/library/windows/GLFW Library.vcxproj.filters @@ -1,48 +1,51 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;ipp;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + \ No newline at end of file