From fc87f2df63be86c380b180ed6f469b85f62f773e Mon Sep 17 00:00:00 2001 From: Omar Emara Date: Wed, 4 Nov 2020 05:43:47 +0200 Subject: [PATCH] Fix Linux handling of window exposure events (flutter/engine#22268) Currently, the Linux embedder does not handle window exposure events. This is typically not a problem for users who use compositing window managers, since they keep the display buffers even if the window is completely covered. However, for users that don't use a compositor, the window will not be redrawn by the engine if it was previously covered until another event triggers the redraw. This patch implements the GtkWidget draw callback to handle window exposure events. The callback doesn't actually draw anything, it just schedule a frame for drawing by the engine. The engine doesn't support exposure events, so instead, we force redraw by sending a window metrics event of the same geometry. Since the geometry didn't change, only a frame will be scheduled. --- engine/src/flutter/shell/platform/linux/fl_view.cc | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/engine/src/flutter/shell/platform/linux/fl_view.cc b/engine/src/flutter/shell/platform/linux/fl_view.cc index b65e3da7d42..87decdce97c 100644 --- a/engine/src/flutter/shell/platform/linux/fl_view.cc +++ b/engine/src/flutter/shell/platform/linux/fl_view.cc @@ -257,6 +257,16 @@ static void fl_view_size_allocate(GtkWidget* widget, fl_view_geometry_changed(self); } +// Implements GtkWidget::draw. +static gboolean fl_view_draw(GtkWidget* widget, cairo_t* cr) { + FlView* self = FL_VIEW(widget); + // The engine doesn't support exposure events, so instead, force redraw by + // sending a window metrics event of the same geometry. Since the geometry + // didn't change, only a frame will be scheduled. + fl_view_geometry_changed(self); + return TRUE; +} + // Implements GtkWidget::button_press_event. static gboolean fl_view_button_press_event(GtkWidget* widget, GdkEventButton* event) { @@ -363,6 +373,7 @@ static void fl_view_class_init(FlViewClass* klass) { G_OBJECT_CLASS(klass)->dispose = fl_view_dispose; GTK_WIDGET_CLASS(klass)->realize = fl_view_realize; GTK_WIDGET_CLASS(klass)->size_allocate = fl_view_size_allocate; + GTK_WIDGET_CLASS(klass)->draw = fl_view_draw; GTK_WIDGET_CLASS(klass)->button_press_event = fl_view_button_press_event; GTK_WIDGET_CLASS(klass)->button_release_event = fl_view_button_release_event; GTK_WIDGET_CLASS(klass)->scroll_event = fl_view_scroll_event;