20
20
#include < cstdlib>
21
21
#include < iostream>
22
22
23
+ #ifdef __linux__
24
+ // Epoxy must be included before any graphics-related code.
25
+ #include < epoxy/gl.h>
26
+ #endif
27
+
28
+ #include < GLFW/glfw3.h>
29
+
23
30
#include < flutter_embedder.h>
24
31
25
32
#include " library/common/glfw/key_event_handler.h"
@@ -48,7 +55,13 @@ static constexpr double kDpPerInch = 160.0;
48
55
49
56
// Struct for storing state within an instance of the GLFW Window.
50
57
struct FlutterEmbedderState {
58
+ // The GLFW window that owns this state object.
59
+ GLFWwindow *window;
60
+
61
+ // The handle to the Flutter engine instance.
51
62
FlutterEngine engine;
63
+
64
+ // The helper class managing plugin registration and messaging.
52
65
std::unique_ptr<flutter_desktop_embedding::PluginHandler> plugin_handler;
53
66
54
67
// Handlers for keyboard events from GLFW.
@@ -300,62 +313,69 @@ bool FlutterInit() {
300
313
301
314
void FlutterTerminate () { glfwTerminate (); }
302
315
303
- PluginRegistrar *GetRegistrarForPlugin (GLFWwindow * flutter_window,
316
+ PluginRegistrar *GetRegistrarForPlugin (FlutterWindowRef flutter_window,
304
317
const std::string &plugin_name) {
305
- auto *state = GetSavedEmbedderState (flutter_window);
306
318
// Currently, PluginHandler acts as the registrar for all plugins, so the
307
319
// name is ignored. It is part of the API to reduce churn in the future when
308
320
// aligning more closely with the Flutter registrar system.
309
- return state ->plugin_handler .get ();
321
+ return flutter_window ->plugin_handler .get ();
310
322
}
311
323
312
- GLFWwindow * CreateFlutterWindow (size_t initial_width, size_t initial_height,
313
- const std::string &assets_path,
314
- const std::string &icu_data_path,
315
- const std::vector<std::string> &arguments) {
324
+ FlutterWindowRef CreateFlutterWindow (
325
+ size_t initial_width, size_t initial_height, const std::string &assets_path,
326
+ const std::string &icu_data_path,
327
+ const std::vector<std::string> &arguments) {
316
328
#ifdef __linux__
317
329
gtk_init (0 , nullptr );
318
330
#endif
331
+ // Create the window.
319
332
auto window = glfwCreateWindow (initial_width, initial_height,
320
333
kDefaultWindowTitle , NULL , NULL );
321
334
if (window == nullptr ) {
322
335
return nullptr ;
323
336
}
324
337
GLFWClearCanvas (window);
338
+
339
+ // Start the engine.
325
340
auto engine = RunFlutterEngine (window, assets_path, icu_data_path, arguments);
326
341
if (engine == nullptr ) {
327
342
glfwDestroyWindow (window);
328
343
return nullptr ;
329
344
}
330
345
346
+ // Create an embedder state object attached to the window.
331
347
FlutterEmbedderState *state = new FlutterEmbedderState ();
332
- state->plugin_handler = std::make_unique<PluginHandler>(engine);
348
+ state->window = window;
349
+ glfwSetWindowUserPointer (window, state);
333
350
state->engine = engine;
351
+ state->plugin_handler = std::make_unique<PluginHandler>(engine);
334
352
335
353
// Set up the keyboard handlers.
336
354
state->keyboard_hook_handlers .push_back (
337
355
std::make_unique<KeyEventHandler>(state->plugin_handler .get ()));
338
356
state->keyboard_hook_handlers .push_back (
339
357
std::make_unique<TextInputPlugin>(state->plugin_handler .get ()));
340
358
341
- glfwSetWindowUserPointer (window, state);
342
-
359
+ // Trigger an initial size callback to send size information to Flutter.
343
360
state->monitor_screen_coordinates_per_inch = GetScreenCoordinatesPerInch ();
344
361
int width_px, height_px;
345
362
glfwGetFramebufferSize (window, &width_px, &height_px);
346
- glfwSetFramebufferSizeCallback (window, GLFWFramebufferSizeCallback);
347
363
GLFWFramebufferSizeCallback (window, width_px, height_px);
348
364
365
+ // Set up GLFW callbacks for the window.
366
+ glfwSetFramebufferSizeCallback (window, GLFWFramebufferSizeCallback);
349
367
GLFWAssignEventCallbacks (window);
350
- return window;
368
+
369
+ return state;
351
370
}
352
371
353
- void FlutterWindowLoop (GLFWwindow *flutter_window) {
372
+ void FlutterWindowLoop (FlutterWindowRef flutter_window) {
373
+ GLFWwindow *window = flutter_window->window ;
354
374
#ifdef __linux__
355
375
// Necessary for GTK thread safety.
356
376
XInitThreads ();
357
377
#endif
358
- while (!glfwWindowShouldClose (flutter_window )) {
378
+ while (!glfwWindowShouldClose (window )) {
359
379
#ifdef __linux__
360
380
glfwPollEvents ();
361
381
if (gtk_events_pending ()) {
@@ -367,10 +387,9 @@ void FlutterWindowLoop(GLFWwindow *flutter_window) {
367
387
// TODO(awdavies): This will be deprecated soon.
368
388
__FlutterEngineFlushPendingTasksNow ();
369
389
}
370
- auto state = GetSavedEmbedderState (flutter_window);
371
- FlutterEngineShutdown (state->engine );
372
- delete state;
373
- glfwDestroyWindow (flutter_window);
390
+ FlutterEngineShutdown (flutter_window->engine );
391
+ delete flutter_window;
392
+ glfwDestroyWindow (window);
374
393
}
375
394
376
395
} // namespace flutter_desktop_embedding
0 commit comments