Skip to content

[linux/windows] Add FlutterWindowController #253

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jan 29, 2019
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 15 additions & 20 deletions example/linux_fde/flutter_embedder_example.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@
#include <menubar/menubar_plugin.h>

#ifdef USE_FLATTENED_INCLUDES
#include <flutter_desktop_embedding/embedder.h>
#include <flutter_desktop_embedding/flutter_window_controller.h>
#else
#include <flutter_desktop_embedding/glfw/embedder.h>
#include <flutter_desktop_embedding/glfw/flutter_window_controller.h>
#endif

namespace {
Expand All @@ -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()) {
Expand All @@ -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;
}
27 changes: 13 additions & 14 deletions example/windows_fde/flutter_embedder_example.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,32 +13,31 @@
// limitations under the License.

#include <iostream>
#include <string>
#include <vector>

#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<std::string> 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;
}
2 changes: 2 additions & 0 deletions library/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
68 changes: 68 additions & 0 deletions library/common/glfw/flutter_window_controller.cc
Original file line number Diff line number Diff line change
@@ -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 <iostream>

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<std::string> &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
Original file line number Diff line number Diff line change
@@ -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 <string>
#include <vector>

#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.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason this is just a comment rather an actual enforced singleton design is that my hope is that the C++ wrapper layer I'm working on extracting for #230 (which this would be part of) could be header-only, which wouldn't work with a singleton, so I'm structuring it this way to allow flipping to header-only without more API churn.

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<std::string> &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_
1 change: 1 addition & 0 deletions library/windows/GLFW Library.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@
<ItemGroup>
<ClCompile Include="..\common\engine_method_result.cc" />
<ClCompile Include="..\common\glfw\embedder.cc" />
<ClCompile Include="..\common\glfw\flutter_window_controller.cc" />
<ClCompile Include="..\common\glfw\key_event_handler.cc" />
<ClCompile Include="..\common\glfw\text_input_plugin.cc" />
<ClCompile Include="..\common\internal\plugin_handler.cc" />
Expand Down
99 changes: 51 additions & 48 deletions library/windows/GLFW Library.vcxproj.filters
Original file line number Diff line number Diff line change
@@ -1,48 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\common\glfw\embedder.cc">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\common\glfw\text_input_plugin.cc">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\common\engine_method_result.cc">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\common\json_message_codec.cc">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\common\internal\text_input_model.cc">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\common\json_method_codec.cc">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\common\glfw\key_event_handler.cc">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\common\internal\plugin_handler.cc">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\include\flutter_desktop_embedding\windows\embedder.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\common\glfw\embedder.cc">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\common\glfw\text_input_plugin.cc">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\common\engine_method_result.cc">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\common\json_message_codec.cc">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\common\internal\text_input_model.cc">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\common\json_method_codec.cc">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\common\glfw\key_event_handler.cc">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\common\internal\plugin_handler.cc">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\common\glfw\flutter_window_controller.cc">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\include\flutter_desktop_embedding\windows\embedder.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>