Skip to content

Commit afefd5d

Browse files
[beta] Cherry pick fix GTK redraw call being called from non-GTK thread (flutter#173667)
Cherry pick of flutter#173602 Impacted users: All Linux users of Flutter Impact Description: Due to calling gtk_window_redraw on a Flutter thread a lock up may occur. The Flutter app will then become unresponsive. Workaround: No workaround Risk: Low - fix is to run the GTK call on the GTK thread which is what the correct behaviour should be. Test coverage: Rendering covered by existing tests, use of thread not explicitly tested, but flutter#173660 opened to add this in future. Validation Steps: Run test program in flutter#173447 which generates many frames and maximizes the chance of a lock up.
1 parent 1ddd180 commit afefd5d

File tree

1 file changed

+10
-11
lines changed

1 file changed

+10
-11
lines changed

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

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,16 @@ G_DEFINE_TYPE_WITH_CODE(
9595
G_IMPLEMENT_INTERFACE(fl_plugin_registry_get_type(),
9696
fl_view_plugin_registry_iface_init))
9797

98-
// Emit the first frame signal in the main thread.
99-
static gboolean first_frame_idle_cb(gpointer user_data) {
98+
// Redraw the view from the GTK thread.
99+
static gboolean redraw_cb(gpointer user_data) {
100100
FlView* self = FL_VIEW(user_data);
101101

102-
g_signal_emit(self, fl_view_signals[SIGNAL_FIRST_FRAME], 0);
102+
gtk_widget_queue_draw(GTK_WIDGET(self->render_area));
103+
104+
if (!self->have_first_frame) {
105+
self->have_first_frame = TRUE;
106+
g_signal_emit(self, fl_view_signals[SIGNAL_FIRST_FRAME], 0);
107+
}
103108

104109
return FALSE;
105110
}
@@ -256,14 +261,8 @@ static void fl_view_present_layers(FlRenderable* renderable,
256261

257262
fl_compositor_present_layers(self->compositor, layers, layers_count);
258263

259-
gtk_widget_queue_draw(self->render_area);
260-
261-
if (!self->have_first_frame) {
262-
self->have_first_frame = TRUE;
263-
// This is not the main thread, so the signal needs to be done via an idle
264-
// callback.
265-
g_idle_add(first_frame_idle_cb, self);
266-
}
264+
// Perform the redraw in the GTK thead.
265+
g_idle_add(redraw_cb, self);
267266
}
268267

269268
// Implements FlPluginRegistry::get_registrar_for_plugin.

0 commit comments

Comments
 (0)