|
5 | 5 | #include "fl_renderer_x11.h" |
6 | 6 | #ifdef GDK_WINDOWING_X11 |
7 | 7 |
|
| 8 | +#include <X11/X.h> |
| 9 | + |
8 | 10 | #include "flutter/shell/platform/linux/egl_utils.h" |
9 | 11 |
|
10 | 12 | struct _FlRendererX11 { |
11 | 13 | FlRenderer parent_instance; |
| 14 | + |
| 15 | + /// Connection to the X server. |
| 16 | + Display* display; |
12 | 17 | }; |
13 | 18 |
|
14 | 19 | G_DEFINE_TYPE(FlRendererX11, fl_renderer_x11, fl_renderer_get_type()) |
15 | 20 |
|
| 21 | +static void fl_renderer_x11_dispose(GObject* object) { |
| 22 | + FlRendererX11* self = FL_RENDERER_X11(object); |
| 23 | + |
| 24 | + if (self->display != nullptr) { |
| 25 | + XCloseDisplay(self->display); |
| 26 | + self->display = nullptr; |
| 27 | + } |
| 28 | + |
| 29 | + G_OBJECT_CLASS(fl_renderer_x11_parent_class)->dispose(object); |
| 30 | +} |
| 31 | + |
16 | 32 | // Implements FlRenderer::setup_window_attr. |
17 | 33 | static gboolean fl_renderer_x11_setup_window_attr( |
18 | 34 | FlRenderer* renderer, |
@@ -50,11 +66,16 @@ static gboolean fl_renderer_x11_setup_window_attr( |
50 | 66 |
|
51 | 67 | // Implements FlRenderer::create_display. |
52 | 68 | static EGLDisplay fl_renderer_x11_create_display(FlRenderer* renderer) { |
53 | | - // Note the use of EGL_DEFAULT_DISPLAY rather than sharing the existing |
54 | | - // display connection from GTK. This is because this EGL display is going to |
55 | | - // be accessed by a thread from Flutter. The GTK/X11 display connection is not |
56 | | - // thread safe and would cause a crash. |
57 | | - return eglGetDisplay(EGL_DEFAULT_DISPLAY); |
| 69 | + FlRendererX11* self = FL_RENDERER_X11(renderer); |
| 70 | + |
| 71 | + // We make our own connection to the X server because the EGL calls are made |
| 72 | + // from Flutter on a different thread to GTK. If we re-used the existing GTK |
| 73 | + // connection then this would crash as Xlib is not thread safe. |
| 74 | + if (self->display == nullptr) { |
| 75 | + Display* display = gdk_x11_get_default_xdisplay(); |
| 76 | + self->display = XOpenDisplay(DisplayString(display)); |
| 77 | + } |
| 78 | + return eglGetDisplay(self->display); |
58 | 79 | } |
59 | 80 |
|
60 | 81 | // Implements FlRenderer::create_surfaces. |
@@ -99,6 +120,7 @@ static gboolean fl_renderer_x11_create_surfaces(FlRenderer* renderer, |
99 | 120 | } |
100 | 121 |
|
101 | 122 | static void fl_renderer_x11_class_init(FlRendererX11Class* klass) { |
| 123 | + G_OBJECT_CLASS(klass)->dispose = fl_renderer_x11_dispose; |
102 | 124 | FL_RENDERER_CLASS(klass)->setup_window_attr = |
103 | 125 | fl_renderer_x11_setup_window_attr; |
104 | 126 | FL_RENDERER_CLASS(klass)->create_display = fl_renderer_x11_create_display; |
|
0 commit comments