diff --git a/shell/platform/linux/fl_renderer.cc b/shell/platform/linux/fl_renderer.cc index fd1ed32bafd..c7aff7dc97c 100644 --- a/shell/platform/linux/fl_renderer.cc +++ b/shell/platform/linux/fl_renderer.cc @@ -121,23 +121,14 @@ static gboolean setup_gdk_window(FlRenderer* self, gint window_attributes_mask = GDK_WA_X | GDK_WA_Y; - EGLint visual_id; - if (!eglGetConfigAttrib(priv->egl_display, priv->egl_config, - EGL_NATIVE_VISUAL_ID, &visual_id)) { - g_set_error(error, fl_renderer_error_quark(), FL_RENDERER_ERROR_FAILED, - "Failed to determine EGL configuration visual"); - return FALSE; + if (FL_RENDERER_GET_CLASS(self)->setup_window_attr) { + if (!FL_RENDERER_GET_CLASS(self)->setup_window_attr( + self, widget, priv->egl_display, priv->egl_config, + &window_attributes, &window_attributes_mask, error)) { + return FALSE; + } } - window_attributes.visual = FL_RENDERER_GET_CLASS(self)->get_visual( - self, gtk_widget_get_screen(widget), visual_id); - if (window_attributes.visual == nullptr) { - g_set_error(error, fl_renderer_error_quark(), FL_RENDERER_ERROR_FAILED, - "Failed to find visual 0x%x", visual_id); - return FALSE; - } - window_attributes_mask |= GDK_WA_VISUAL; - GdkWindow* window = gdk_window_new(gtk_widget_get_parent_window(widget), &window_attributes, window_attributes_mask); diff --git a/shell/platform/linux/fl_renderer.h b/shell/platform/linux/fl_renderer.h index 6b922cb054d..4b421d183c6 100644 --- a/shell/platform/linux/fl_renderer.h +++ b/shell/platform/linux/fl_renderer.h @@ -35,10 +35,17 @@ G_DECLARE_DERIVABLE_TYPE(FlRenderer, fl_renderer, FL, RENDERER, GObject) struct _FlRendererClass { GObjectClass parent_class; - // Virtual method called to get the visual that matches the given ID. - GdkVisual* (*get_visual)(FlRenderer* renderer, - GdkScreen* screen, - EGLint visual_id); + /** + * Virtual method called before creating a GdkWindow for the widget. + * Does not need to be implemented. + */ + gboolean (*setup_window_attr)(FlRenderer* renderer, + GtkWidget* widget, + EGLDisplay egl_display, + EGLConfig egl_config, + GdkWindowAttr* window_attributes, + gint* mask, + GError** error); /** * Virtual method called after a GDK window has been created. diff --git a/shell/platform/linux/fl_renderer_x11.cc b/shell/platform/linux/fl_renderer_x11.cc index 16bd1dca6aa..97a7bc679af 100644 --- a/shell/platform/linux/fl_renderer_x11.cc +++ b/shell/platform/linux/fl_renderer_x11.cc @@ -21,11 +21,40 @@ static void fl_renderer_x11_dispose(GObject* object) { G_OBJECT_CLASS(fl_renderer_x11_parent_class)->dispose(object); } -// Implements FlRenderer::get_visual. -static GdkVisual* fl_renderer_x11_get_visual(FlRenderer* renderer, - GdkScreen* screen, - EGLint visual_id) { - return gdk_x11_screen_lookup_visual(GDK_X11_SCREEN(screen), visual_id); +// Implements FlRenderer::setup_window_attr. +static gboolean fl_renderer_x11_setup_window_attr( + FlRenderer* renderer, + GtkWidget* widget, + EGLDisplay egl_display, + EGLConfig egl_config, + GdkWindowAttr* window_attributes, + gint* mask, + GError** error) { + EGLint visual_id; + if (!eglGetConfigAttrib(egl_display, egl_config, EGL_NATIVE_VISUAL_ID, + &visual_id)) { + g_set_error(error, fl_renderer_error_quark(), FL_RENDERER_ERROR_FAILED, + "Failed to determine EGL configuration visual"); + return FALSE; + } + + GdkX11Screen* screen = GDK_X11_SCREEN(gtk_widget_get_screen(widget)); + if (!screen) { + g_set_error(error, fl_renderer_error_quark(), FL_RENDERER_ERROR_FAILED, + "Widget is not on an X11 screen"); + return FALSE; + } + + window_attributes->visual = gdk_x11_screen_lookup_visual(screen, visual_id); + if (window_attributes->visual == nullptr) { + g_set_error(error, fl_renderer_error_quark(), FL_RENDERER_ERROR_FAILED, + "Failed to find visual 0x%x", visual_id); + return FALSE; + } + + *mask |= GDK_WA_VISUAL; + + return TRUE; } // Implements FlRenderer::set_window. @@ -88,7 +117,8 @@ static gboolean fl_renderer_x11_create_surfaces(FlRenderer* renderer, static void fl_renderer_x11_class_init(FlRendererX11Class* klass) { G_OBJECT_CLASS(klass)->dispose = fl_renderer_x11_dispose; - FL_RENDERER_CLASS(klass)->get_visual = fl_renderer_x11_get_visual; + FL_RENDERER_CLASS(klass)->setup_window_attr = + fl_renderer_x11_setup_window_attr; FL_RENDERER_CLASS(klass)->set_window = fl_renderer_x11_set_window; FL_RENDERER_CLASS(klass)->create_display = fl_renderer_x11_create_display; FL_RENDERER_CLASS(klass)->create_surfaces = fl_renderer_x11_create_surfaces; diff --git a/shell/platform/linux/testing/mock_renderer.cc b/shell/platform/linux/testing/mock_renderer.cc index 87934917789..3e6aaa9eb7d 100644 --- a/shell/platform/linux/testing/mock_renderer.cc +++ b/shell/platform/linux/testing/mock_renderer.cc @@ -10,13 +10,6 @@ struct _FlMockRenderer { G_DEFINE_TYPE(FlMockRenderer, fl_mock_renderer, fl_renderer_get_type()) -// Implements FlRenderer::get_visual. -static GdkVisual* fl_mock_renderer_get_visual(FlRenderer* renderer, - GdkScreen* screen, - EGLint visual_id) { - return static_cast(g_object_new(GDK_TYPE_VISUAL, nullptr)); -} - // Implements FlRenderer::create_display. static EGLDisplay fl_mock_renderer_create_display(FlRenderer* renderer) { return eglGetDisplay(EGL_DEFAULT_DISPLAY); @@ -36,7 +29,6 @@ static gboolean fl_mock_renderer_create_surfaces(FlRenderer* renderer, } static void fl_mock_renderer_class_init(FlMockRendererClass* klass) { - FL_RENDERER_CLASS(klass)->get_visual = fl_mock_renderer_get_visual; FL_RENDERER_CLASS(klass)->create_display = fl_mock_renderer_create_display; FL_RENDERER_CLASS(klass)->create_surfaces = fl_mock_renderer_create_surfaces; }