From 8a41fd01d1c08e97ef38701d556ed128efd2e53c Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 27 Apr 2026 17:16:11 +0200 Subject: [PATCH] Fix creating wxGLCanvas when using EGL 1.4 with X11 The changes of 602b80d (Support EGL 1.4 instead of previously required 1.5, 2025-11-23) were wrong for X11 because eglCreateWindowSurface(), used as the fallback when newer EGL functions are not available, requires passing it the actual X11 Window (i.e. an XID) rather than a pointer to it. Fix this by passing both the XID and a pointer to it to this function and calling the different functions with the appropriate parameter. Note that we still need to pass wl_egl_window pointer to this function when using Wayland and we need to pass a pointer to XID when using newer EGL functions. Closes #26410. --- include/wx/unix/private/glegl.h | 23 ++++++++++++++++++++--- src/unix/glegl.cpp | 14 +++++++------- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/include/wx/unix/private/glegl.h b/include/wx/unix/private/glegl.h index 76500ea1a8..ee066da0bc 100644 --- a/include/wx/unix/private/glegl.h +++ b/include/wx/unix/private/glegl.h @@ -106,9 +106,26 @@ private: // fall back on eglCreateWindowSurface() otherwise. // // This function uses m_display and m_config which must be initialized - // before using it and should be passed either m_xwindow or m_wlEGLWindow - // depending on whether we are using X11 or Wayland. - EGLSurface CallCreatePlatformWindowSurface(void *window) const; + // before using it. + // + // Window parameter is passed twice because some of the functions above + // take it by value while others take it by pointer and this depends on + // whether we use X11 or Wayland. Use wrappers below taking correct window + // type instead of calling this function directly. + EGLSurface + DoCallCreatePlatformWindowSurface(wxUIntPtr windowID, void* windowPtr) const; + + // This one is for X11. + EGLSurface CallCreatePlatformWindowSurface(wxUIntPtr xwindow) const + { + return DoCallCreatePlatformWindowSurface(xwindow, &xwindow); + } + + // And this one is for Wayland. + EGLSurface CallCreatePlatformWindowSurface(struct wl_egl_window* window) const + { + return DoCallCreatePlatformWindowSurface(wxPtrToUInt(window), window); + } EGLConfig m_config = nullptr; diff --git a/src/unix/glegl.cpp b/src/unix/glegl.cpp index 98d3a4faa9..8486d70a2c 100644 --- a/src/unix/glegl.cpp +++ b/src/unix/glegl.cpp @@ -551,7 +551,9 @@ static void gtk_glcanvas_scale_factor_notify(GtkWidget* widget, } // extern "C" #endif // GDK_WINDOWING_WAYLAND -EGLSurface wxGLCanvasEGL::CallCreatePlatformWindowSurface(void *window) const +EGLSurface +wxGLCanvasEGL::DoCallCreatePlatformWindowSurface(wxUIntPtr windowID, + void* windowPtr) const { // Type of eglCreatePlatformWindowSurface[EXT](). typedef EGLSurface (*CreatePlatformWindowSurface)(EGLDisplay display, @@ -577,7 +579,7 @@ EGLSurface wxGLCanvasEGL::CallCreatePlatformWindowSurface(void *window) const if ( s_eglCreatePlatformWindowSurface ) { return s_eglCreatePlatformWindowSurface(m_display, m_config, - window, + windowPtr, nullptr); } } @@ -601,14 +603,12 @@ EGLSurface wxGLCanvasEGL::CallCreatePlatformWindowSurface(void *window) const if ( s_eglCreatePlatformWindowSurfaceEXT ) { return s_eglCreatePlatformWindowSurfaceEXT(m_display, m_config, - window, + windowPtr, nullptr); } else { - return eglCreateWindowSurface(m_display, m_config, - reinterpret_cast(window), - nullptr); + return eglCreateWindowSurface(m_display, m_config, windowID, nullptr); } } @@ -632,7 +632,7 @@ void wxGLCanvasEGL::OnRealized() } m_xwindow = GDK_WINDOW_XID(window); - m_surface = CallCreatePlatformWindowSurface(&m_xwindow); + m_surface = CallCreatePlatformWindowSurface(m_xwindow); } #endif #ifdef GDK_WINDOWING_WAYLAND