WIP: Add native Wayland support for Linux (#13197)

* Add runtime display backend detection for Wayland support

Add LinuxDisplayBackend utility to detect X11 vs Wayland at runtime
using GDK_IS_X11_DISPLAY / GDK_IS_WAYLAND_DISPLAY macros. This is
the foundation for removing the forced GDK_BACKEND=x11 and enabling
native Wayland support.

- New files: LinuxDisplayBackend.hpp/.cpp with get_linux_display_backend(),
  is_running_on_wayland(), and is_running_on_x11()
- Propagate wxHAVE_GDK_X11 / wxHAVE_GDK_WAYLAND from FindGTK3.cmake
  as compile definitions to libslic3r_gui
- No-op on non-Linux platforms (returns Unknown / false)

* Fix Phase 1 code quality: pragma once, source ordering, static cache

* Make X11 initialization conditional for Wayland support

Remove the unconditional GDK_BACKEND=x11 force that blocked native
Wayland. Replace with conditional logic:

- EGL safety fallback: re-force X11 only when wxUSE_GLCANVAS_EGL is
  off and WAYLAND_DISPLAY is set, with a warning log
- XInitThreads() only called when DISPLAY is set (X11 in use)
- __GLX_VENDOR_LIBRARY_NAME only set when DISPLAY is present (GLX-specific)
- WEBKIT_DISABLE_COMPOSITING_MODE only set under XWayland (both
  DISPLAY and WAYLAND_DISPLAY present)
- Guard X11/Xlib.h include with __has_include for robustness
- Restore display validation to accept either DISPLAY or WAYLAND_DISPLAY

This is Phase 2 of the Wayland support plan.

* Fix Phase 2: safer EGL macro check, add clarifying comments

* Add GLAD2 library and replace GLEW linkage in build system

Set up GLAD2 as a static library to replace GLEW for OpenGL loading.
GLAD2 supports both GLX and EGL, which is required for Wayland support.

- Create src/glad/ with pre-generated GLAD2 sources (GL 4.6 compat)
- Add src/glad/CMakeLists.txt building glad as a static library
- Wire glad into src/CMakeLists.txt before libvgcode
- Modify libvgcode to use shared glad for GL path (keeps local copy
  only for GLES2/Emscripten) to avoid duplicate symbol conflicts
- Replace GLEW::GLEW with glad in libslic3r_gui link libraries

Note: GLEW is kept in deps for OpenCSG. Code migration from GL/glew.h
to glad/gl.h headers will follow in Phase 3B+3C.

* Fix Phase 3A+3D: libvgcode GLAD include, dead files, dlopen dep, OpenGL link var

* Migrate from GLEW to GLAD: replace headers and API calls across codebase

Replace all #include <GL/glew.h> with <glad/gl.h> across 49 source files.
Migrate GLEW API calls to GLAD equivalents:
- glewInit/glewExperimental -> gladLoaderLoadGL()
- GLEW_EXT_* / GLEW_ARB_* extension checks -> GLAD_GL_EXT_* / GLAD_GL_ARB_*
- Remove GLEW-specific EGL/GLX mismatch #error guards (not needed with GLAD)
- Replace unavailable EXT symbols with core GL equivalents in
  GLCanvas3D.cpp (GL_MAX_SAMPLES, glRenderbufferStorageMultisample,
  glBlitFramebuffer, GL_READ/DRAW_FRAMEBUFFER)
- Update log messages from glewInit to gladLoadGL

* Fix Phase 3B+3C: remove GLEW find, clean EXT symbols, update attribution

- Remove find_package(GLEW) block from root CMakeLists.txt since GLEW
  is no longer linked by any main application code
- Remove "glew" from SLIC3R_STATIC option description
- Replace all remaining EXT framebuffer symbols with core equivalents
  in render_thumbnail_framebuffer_ext and _rectangular_selection_picking_pass
- Update AboutDialog credits from GLEW to GLAD

* Enable EGL in wxWidgets and add runtime GLX/EGL selection for Wayland

- Set wxUSE_GLCANVAS_EGL=ON in wxWidgets build and Flatpak manifest
- Add PreferGLX() call on X11 sessions for driver compatibility
- Remove Phase 2 safety fallback (EGL is now always compiled in)
- Guard SwapBuffers against hidden canvases to prevent Wayland stalls

* Fix Phase 4: move PreferGLX to app startup, fix FPS counter guard

Move wxGLCanvas::PreferGLX() from OpenGLManager::create_wxglcanvas()
(static initializer) to GUI_App::on_init_inner() before any wxGLCanvas
is constructed. This prevents a race where SkipPartCanvas could trigger
wxGLBackend::Init() before the GLX preference is set. The new location
also adds explicit is_running_on_wayland() detection with a warning for
unknown backends.

Move increment_fps_counter() inside the IsShownOnScreen() guard so FPS
is only counted when a frame is actually swapped.

* Update GLFW from 3.3.7 to 3.4 for runtime Wayland/X11 backend selection

Replace the compile-time GLFW_USE_WAYLAND flag (which locked to a single
backend) with GLFW 3.4's GLFW_BUILD_WAYLAND + GLFW_BUILD_X11 flags that
build both backends and auto-select at runtime based on the available
display server. This enables the CLI thumbnail renderer to work on both
Wayland and X11 sessions without separate builds.

* wayland: Fix UI call sites that rely on global screen coordinates

On Wayland, wxGetMousePosition() returns (0,0) and SetPosition() is a
no-op for top-level windows. Fix the highest-impact call sites:

- GLCanvas3D: Use cached m_mouse.position from event handlers instead
  of wxGetMousePosition() + ScreenToClient() in get_local_mouse_position()
- Plater: Use event-relative coords via ClientToScreen(e.GetPosition())
  instead of wxGetMousePosition() in 3 leave-window handlers
- BBLTopbar: Use event.GetPosition() and FindToolByPosition() directly
  in mouse handlers instead of wxGetMousePosition()/FindToolByCurrentPosition()
- Search: Use focus-based dismiss logic on Wayland instead of
  wxGetMousePosition()-based rect checks in SearchDialog and
  SearchObjectDialog
- GUI_App: Skip SetPosition() in window_pos_restore() on Wayland where
  it is a no-op; still restore size and maximize state
- Button: Position tooltip relative to button widget via ClientToScreen
  instead of wxGetMousePosition()

* Fix SearchDialog Wayland dismiss: guard against search_line focus

* flatpak: Add Wayland socket permission for native Wayland support

* spec

* Fix crash on Wayland when wxWidgets lacks EGL support

Restore the safety fallback that forces GDK_BACKEND=x11 when wxWidgets
was not built with wxUSE_GLCANVAS_EGL=ON. Without this, the GLX backend
tries to access a non-existent X11 display on native Wayland, crashing
in wxGLCanvas::IsDisplaySupported() with SIGSEGV at offset 0xe4.

Also add a defense-in-depth guard in detect_multisample() that skips
the IsDisplaySupported call entirely on Wayland without EGL.

Root cause: deps/wxWidgets must be rebuilt after enabling EGL. The
compile-time check in OrcaSlicer.cpp detects the mismatch and falls
back safely.

* Fix EGL detection: use wxHAS_EGL instead of wxUSE_GLCANVAS_EGL

wxUSE_GLCANVAS_EGL is a CMake build option, NOT a C++ preprocessor
macro. The actual macro defined in wxWidgets setup.h is wxHAS_EGL.
All compile-time EGL checks were using the wrong macro, causing
the safety fallback to always trigger even with a properly built
EGL-enabled wxWidgets.

* Fix GL function pointers invalidated on Wayland/EGL

gladLoaderLoadGL() dlopen's libGL.so.1 to resolve GL function pointers
via dlsym, then immediately dlclose's the handle. On X11/GLX this is
fine because the GLX context keeps libGL.so mapped. On Wayland/EGL,
nothing else holds libGL.so open, so dlclose unmaps it and all function
pointers become dangling — causing SIGSEGV on the first GL call.

Fix: on Wayland, use gladLoadGL(eglGetProcAddress) which resolves
function pointers through the EGL loader without opening/closing
libGL.so.

* fix crash on start and various rendering issues

* fix crash on close

* small refactor

* move GPU selection to desktop file

* clean up a bit

* clean up more

* fix appimage error
This commit is contained in:
SoftFever
2026-04-13 19:45:39 +08:00
committed by GitHub
parent 106cbaa503
commit be2a2d4873
83 changed files with 3485 additions and 239 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff