Skip to content

Commit 5a53ac3

Browse files
Fix warnings on startup about display monitor (#162653)
Create the display monitor at initialization, not engine start. Handle case where the window is not visible and the monitor can't be determined. Don't leak the monitor when the engine is disposed.
1 parent bd055cf commit 5a53ac3

File tree

3 files changed

+54
-20
lines changed

3 files changed

+54
-20
lines changed

engine/src/flutter/shell/platform/linux/fl_engine.cc

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,7 @@ static void fl_engine_dispose(GObject* object) {
467467
fl_texture_registrar_shutdown(self->texture_registrar);
468468

469469
g_clear_object(&self->project);
470+
g_clear_object(&self->display_monitor);
470471
g_clear_object(&self->renderer);
471472
g_clear_object(&self->texture_registrar);
472473
g_clear_object(&self->binary_messenger);
@@ -519,27 +520,46 @@ static void fl_engine_init(FlEngine* self) {
519520
g_warning("Failed get get engine function pointers");
520521
}
521522

523+
self->display_monitor =
524+
fl_display_monitor_new(self, gdk_display_get_default());
525+
self->task_runner = fl_task_runner_new(self);
526+
522527
// Implicit view is 0, so start at 1.
523528
self->next_view_id = 1;
524529

525530
self->texture_registrar = fl_texture_registrar_new(self);
526531
}
527532

528-
FlEngine* fl_engine_new_with_renderer(FlDartProject* project,
529-
FlRenderer* renderer) {
533+
static FlEngine* fl_engine_new_full(FlDartProject* project,
534+
FlRenderer* renderer,
535+
FlBinaryMessenger* binary_messenger) {
530536
g_return_val_if_fail(FL_IS_DART_PROJECT(project), nullptr);
531537
g_return_val_if_fail(FL_IS_RENDERER(renderer), nullptr);
532538

533539
FlEngine* self = FL_ENGINE(g_object_new(fl_engine_get_type(), nullptr));
534540
self->project = FL_DART_PROJECT(g_object_ref(project));
535541
self->renderer = FL_RENDERER(g_object_ref(renderer));
536-
self->binary_messenger = fl_binary_messenger_new(self);
537-
542+
if (binary_messenger != nullptr) {
543+
self->binary_messenger =
544+
FL_BINARY_MESSENGER(g_object_ref(binary_messenger));
545+
} else {
546+
self->binary_messenger = fl_binary_messenger_new(self);
547+
}
548+
self->keyboard_manager = fl_keyboard_manager_new(self);
549+
self->mouse_cursor_handler =
550+
fl_mouse_cursor_handler_new(self->binary_messenger);
538551
fl_renderer_set_engine(self->renderer, self);
539552

540553
return self;
541554
}
542555

556+
FlEngine* fl_engine_new_with_renderer(FlDartProject* project,
557+
FlRenderer* renderer) {
558+
g_return_val_if_fail(FL_IS_DART_PROJECT(project), nullptr);
559+
g_return_val_if_fail(FL_IS_RENDERER(renderer), nullptr);
560+
return fl_engine_new_full(project, renderer, nullptr);
561+
}
562+
543563
G_MODULE_EXPORT FlEngine* fl_engine_new(FlDartProject* project) {
544564
g_autoptr(FlRendererGdk) renderer = fl_renderer_gdk_new();
545565
return fl_engine_new_with_renderer(project, FL_RENDERER(renderer));
@@ -548,10 +568,8 @@ G_MODULE_EXPORT FlEngine* fl_engine_new(FlDartProject* project) {
548568
FlEngine* fl_engine_new_with_binary_messenger(
549569
FlBinaryMessenger* binary_messenger) {
550570
g_autoptr(FlDartProject) project = fl_dart_project_new();
551-
FlEngine* self = fl_engine_new(project);
552-
g_object_unref(self->binary_messenger);
553-
self->binary_messenger = FL_BINARY_MESSENGER(g_object_ref(binary_messenger));
554-
return self;
571+
g_autoptr(FlRendererGdk) renderer = fl_renderer_gdk_new();
572+
return fl_engine_new_full(project, FL_RENDERER(renderer), binary_messenger);
555573
}
556574

557575
G_MODULE_EXPORT FlEngine* fl_engine_new_headless(FlDartProject* project) {
@@ -572,8 +590,6 @@ FlDisplayMonitor* fl_engine_get_display_monitor(FlEngine* self) {
572590
gboolean fl_engine_start(FlEngine* self, GError** error) {
573591
g_return_val_if_fail(FL_IS_ENGINE(self), FALSE);
574592

575-
self->task_runner = fl_task_runner_new(self);
576-
577593
FlutterRendererConfig config = {};
578594
config.type = kOpenGL;
579595
config.open_gl.struct_size = sizeof(FlutterOpenGLRendererConfig);
@@ -671,8 +687,6 @@ gboolean fl_engine_start(FlEngine* self, GError** error) {
671687
fl_settings_handler_start(self->settings_handler, settings);
672688

673689
self->platform_handler = fl_platform_handler_new(self->binary_messenger);
674-
self->mouse_cursor_handler =
675-
fl_mouse_cursor_handler_new(self->binary_messenger);
676690

677691
setup_keyboard(self);
678692

@@ -681,8 +695,6 @@ gboolean fl_engine_start(FlEngine* self, GError** error) {
681695
g_warning("Failed to enable accessibility features on Flutter engine");
682696
}
683697

684-
self->display_monitor =
685-
fl_display_monitor_new(self, gdk_display_get_default());
686698
fl_display_monitor_start(self->display_monitor);
687699

688700
return TRUE;

engine/src/flutter/shell/platform/linux/fl_engine_test.cc

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -946,4 +946,17 @@ TEST(FlEngineTest, SendKeyEventError) {
946946
EXPECT_TRUE(called);
947947
}
948948

949+
TEST(FlEngineTest, ChildObjects) {
950+
g_autoptr(FlDartProject) project = fl_dart_project_new();
951+
g_autoptr(FlEngine) engine = fl_engine_new(project);
952+
953+
// Check objects exist before engine started.
954+
EXPECT_NE(fl_engine_get_binary_messenger(engine), nullptr);
955+
EXPECT_NE(fl_engine_get_renderer(engine), nullptr);
956+
EXPECT_NE(fl_engine_get_display_monitor(engine), nullptr);
957+
EXPECT_NE(fl_engine_get_task_runner(engine), nullptr);
958+
EXPECT_NE(fl_engine_get_keyboard_manager(engine), nullptr);
959+
EXPECT_NE(fl_engine_get_mouse_cursor_handler(engine), nullptr);
960+
}
961+
949962
// NOLINTEND(clang-analyzer-core.StackAddressEscape)

engine/src/flutter/shell/platform/linux/fl_view.cc

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -211,13 +211,22 @@ static void handle_geometry_changed(FlView* self) {
211211

212212
GdkWindow* window =
213213
gtk_widget_get_window(gtk_widget_get_toplevel(GTK_WIDGET(self)));
214-
GdkMonitor* monitor = gdk_display_get_monitor_at_window(
215-
gtk_widget_get_display(GTK_WIDGET(self)), window);
214+
// NOTE(robert-ancell) If we haven't got a window we default to display 0.
215+
// This is probably indicating a problem with this code in that we
216+
// shouldn't be generating anything until the window is created.
217+
// Another event with the correct display ID is generated soon after.
218+
// I haven't changed this code in case there are side-effects but we
219+
// probably shouldn't call handle_geometry_changed after the view is
220+
// added but only when the window is realized.
221+
FlutterEngineDisplayId display_id = 0;
222+
if (window != nullptr) {
223+
GdkMonitor* monitor = gdk_display_get_monitor_at_window(
224+
gtk_widget_get_display(GTK_WIDGET(self)), window);
225+
display_id = fl_display_monitor_get_display_id(
226+
fl_engine_get_display_monitor(self->engine), monitor);
227+
}
216228
fl_engine_send_window_metrics_event(
217-
self->engine,
218-
fl_display_monitor_get_display_id(
219-
fl_engine_get_display_monitor(self->engine), monitor),
220-
self->view_id, allocation.width * scale_factor,
229+
self->engine, display_id, self->view_id, allocation.width * scale_factor,
221230
allocation.height * scale_factor, scale_factor);
222231

223232
// Make sure the view has been realized and its size has been allocated before

0 commit comments

Comments
 (0)