[Bf-blender-cvs] [f0e1089a33f] master: GHOST/Wayland: only require libdecor when running in gnome-shell
Campbell Barton
noreply at git.blender.org
Wed Oct 12 08:03:20 CEST 2022
Commit: f0e1089a33f4054998c96a50b92503251a47aa97
Author: Campbell Barton
Date: Wed Oct 12 16:54:31 2022 +1100
Branches: master
https://developer.blender.org/rBf0e1089a33f4054998c96a50b92503251a47aa97
GHOST/Wayland: only require libdecor when running in gnome-shell
- Support switching between libdecor and xdg_shell at run-time.
- Require libdecor when using gnome-shell, otherwise use xdg_shell.
- Gnome-shell detection checks for a gtk_shell* interface which
isn't ideal however it's not possible to check server-side-decorations
are supported without first creating a window.
- Unload Wayland libraries when Wayland fails to load.
===================================================================
M intern/ghost/CMakeLists.txt
M intern/ghost/intern/GHOST_ISystem.cpp
M intern/ghost/intern/GHOST_SystemWayland.cpp
M intern/ghost/intern/GHOST_SystemWayland.h
M intern/ghost/intern/GHOST_WindowWayland.cpp
===================================================================
diff --git a/intern/ghost/CMakeLists.txt b/intern/ghost/CMakeLists.txt
index 9e3a15dd543..2f8ea1f9065 100644
--- a/intern/ghost/CMakeLists.txt
+++ b/intern/ghost/CMakeLists.txt
@@ -349,16 +349,16 @@ elseif(WITH_GHOST_X11 OR WITH_GHOST_WAYLAND)
${INC_DST}
)
- if(NOT WITH_GHOST_WAYLAND_LIBDECOR)
- # `xdg-shell`.
- generate_protocol_bindings(
- "${WAYLAND_PROTOCOLS_DIR}/stable/xdg-shell/xdg-shell.xml"
- )
- # `xdg-decoration`.
- generate_protocol_bindings(
- "${WAYLAND_PROTOCOLS_DIR}/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml"
- )
- endif()
+ # Used when: LIBDECOR is not needed.
+ # `xdg-shell`.
+ generate_protocol_bindings(
+ "${WAYLAND_PROTOCOLS_DIR}/stable/xdg-shell/xdg-shell.xml"
+ )
+ # `xdg-decoration`.
+ generate_protocol_bindings(
+ "${WAYLAND_PROTOCOLS_DIR}/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml"
+ )
+ # End LIBDECOR alternative.
# `xdg-output`.
generate_protocol_bindings(
diff --git a/intern/ghost/intern/GHOST_ISystem.cpp b/intern/ghost/intern/GHOST_ISystem.cpp
index 0a35d1af5a4..8e2859ca1e1 100644
--- a/intern/ghost/intern/GHOST_ISystem.cpp
+++ b/intern/ghost/intern/GHOST_ISystem.cpp
@@ -48,7 +48,7 @@ GHOST_TSuccess GHOST_ISystem::createSystem(bool verbose)
/* Pass. */
#elif defined(WITH_GHOST_WAYLAND)
# if defined(WITH_GHOST_WAYLAND_DYNLOAD)
- const bool has_wayland_libraries = ghost_wl_dynload_libraries();
+ const bool has_wayland_libraries = ghost_wl_dynload_libraries_init();
# else
const bool has_wayland_libraries = true;
# endif
@@ -66,6 +66,9 @@ GHOST_TSuccess GHOST_ISystem::createSystem(bool verbose)
catch (const std::runtime_error &) {
delete m_system;
m_system = nullptr;
+# ifdef WITH_GHOST_WAYLAND_DYNLOAD
+ ghost_wl_dynload_libraries_exit();
+# endif
}
}
else {
@@ -101,6 +104,9 @@ GHOST_TSuccess GHOST_ISystem::createSystem(bool verbose)
catch (const std::runtime_error &) {
delete m_system;
m_system = nullptr;
+# ifdef WITH_GHOST_WAYLAND_DYNLOAD
+ ghost_wl_dynload_libraries_exit();
+# endif
}
}
else {
diff --git a/intern/ghost/intern/GHOST_SystemWayland.cpp b/intern/ghost/intern/GHOST_SystemWayland.cpp
index 7e56ed0affb..44b20ae2aef 100644
--- a/intern/ghost/intern/GHOST_SystemWayland.cpp
+++ b/intern/ghost/intern/GHOST_SystemWayland.cpp
@@ -54,6 +54,11 @@
#include <tablet-unstable-v2-client-protocol.h>
#include <xdg-output-unstable-v1-client-protocol.h>
+/* Decorations `xdg_decor`. */
+#include <xdg-decoration-unstable-v1-client-protocol.h>
+#include <xdg-shell-client-protocol.h>
+/* End `xdg_decor`. */
+
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
@@ -64,6 +69,15 @@
/* Logging, use `ghost.wl.*` prefix. */
#include "CLG_log.h"
+#ifdef WITH_GHOST_WAYLAND_LIBDECOR
+static bool use_libdecor = true;
+# ifdef WITH_GHOST_WAYLAND_DYNLOAD
+static bool has_libdecor = false;
+# else
+static bool has_libdecor = true;
+# endif
+#endif
+
static void keyboard_handle_key_repeat_cancel(struct GWL_Seat *seat);
static void output_handle_done(void *data, struct wl_output *wl_output);
@@ -106,6 +120,13 @@ static bool use_gnome_confine_hack = false;
*/
#define USE_GNOME_KEYBOARD_SUPPRESS_WARNING
+/**
+ * When GNOME is found, require `libdecor`.
+ * This is a hack because it seems there is no way to check if the compositor supports
+ * server side decorations when initializing WAYLAND.
+ */
+#define USE_GNOME_NEEDS_LIBDECOR_HACK
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -357,6 +378,36 @@ struct WGL_KeyboardDepressedState {
int16_t mods[GHOST_KEY_MODIFIER_NUM] = {0};
};
+#ifdef WITH_GHOST_WAYLAND_LIBDECOR
+struct WGL_LibDecor_System {
+ struct libdecor *context = nullptr;
+};
+
+static void wgl_libdecor_system_destroy(WGL_LibDecor_System *decor)
+{
+ if (decor->context) {
+ libdecor_unref(decor->context);
+ }
+ delete decor;
+}
+#endif
+
+struct WGL_XDG_Decor_System {
+ struct xdg_wm_base *shell = nullptr;
+ struct zxdg_decoration_manager_v1 *manager = nullptr;
+};
+
+static void wgl_xdg_decor_system_destroy(WGL_XDG_Decor_System *decor)
+{
+ if (decor->manager) {
+ zxdg_decoration_manager_v1_destroy(decor->manager);
+ }
+ if (decor->shell) {
+ xdg_wm_base_destroy(decor->shell);
+ }
+ delete decor;
+}
+
struct GWL_Seat {
GHOST_SystemWayland *system = nullptr;
@@ -455,11 +506,10 @@ struct GWL_Display {
struct wl_compositor *compositor = nullptr;
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
- struct libdecor *decor_context = nullptr;
-#else
- struct xdg_wm_base *xdg_shell = nullptr;
- struct zxdg_decoration_manager_v1 *xdg_decoration_manager = nullptr;
+ WGL_LibDecor_System *libdecor = nullptr;
+ bool libdecor_required = false;
#endif
+ WGL_XDG_Decor_System *xdg_decor = nullptr;
struct zxdg_output_manager_v1 *xdg_output_manager = nullptr;
struct wl_shm *shm = nullptr;
@@ -626,19 +676,19 @@ static void display_destroy(GWL_Display *d)
}
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
- if (d->decor_context) {
- libdecor_unref(d->decor_context);
+ if (use_libdecor) {
+ if (d->libdecor) {
+ wgl_libdecor_system_destroy(d->libdecor);
+ }
}
-#else
- if (d->xdg_decoration_manager) {
- zxdg_decoration_manager_v1_destroy(d->xdg_decoration_manager);
+ else
+#endif
+ {
+ if (d->xdg_decor) {
+ wgl_xdg_decor_system_destroy(d->xdg_decor);
+ }
}
- if (d->xdg_shell) {
- xdg_wm_base_destroy(d->xdg_shell);
- }
-#endif /* !WITH_GHOST_WAYLAND_LIBDECOR */
-
if (eglGetDisplay) {
::eglTerminate(eglGetDisplay(EGLNativeDisplayType(d->display)));
}
@@ -2903,10 +2953,8 @@ static const struct wl_output_listener output_listener = {
/** \name Listener (XDG WM Base), #xdg_wm_base_listener
* \{ */
-#ifndef WITH_GHOST_WAYLAND_LIBDECOR
-
static CLG_LogRef LOG_WL_XDG_WM_BASE = {"ghost.wl.handle.xdg_wm_base"};
-# define LOG (&LOG_WL_XDG_WM_BASE)
+#define LOG (&LOG_WL_XDG_WM_BASE)
static void shell_handle_ping(void * /*data*/,
struct xdg_wm_base *xdg_wm_base,
@@ -2920,9 +2968,7 @@ static const struct xdg_wm_base_listener shell_listener = {
shell_handle_ping,
};
-# undef LOG
-
-#endif /* !WITH_GHOST_WAYLAND_LIBDECOR. */
+#undef LOG
/** \} */
@@ -2978,19 +3024,17 @@ static void global_handle_add(void *data,
display->compositor = static_cast<wl_compositor *>(
wl_registry_bind(wl_registry, name, &wl_compositor_interface, 3));
}
-#ifdef WITH_GHOST_WAYLAND_LIBDECOR
- /* Pass. */
-#else
else if (STREQ(interface, xdg_wm_base_interface.name)) {
- display->xdg_shell = static_cast<xdg_wm_base *>(
+ WGL_XDG_Decor_System &decor = *display->xdg_decor;
+ decor.shell = static_cast<xdg_wm_base *>(
wl_registry_bind(wl_registry, name, &xdg_wm_base_interface, 1));
- xdg_wm_base_add_listener(display->xdg_shell, &shell_listener, nullptr);
+ xdg_wm_base_add_listener(decor.shell, &shell_listener, nullptr);
}
else if (STREQ(interface, zxdg_decoration_manager_v1_interface.name)) {
- display->xdg_decoration_manager = static_cast<zxdg_decoration_manager_v1 *>(
+ WGL_XDG_Decor_System &decor = *display->xdg_decor;
+ decor.manager = static_cast<zxdg_decoration_manager_v1 *>(
wl_registry_bind(wl_registry, name, &zxdg_decoration_manager_v1_interface, 1));
}
-#endif /* !WITH_GHOST_WAYLAND_LIBDECOR. */
else if (STREQ(interface, zxdg_output_manager_v1_interface.name)) {
display->xdg_output_manager = static_cast<zxdg_output_manager_v1 *>(
wl_registry_bind(wl_registry, name, &zxdg_output_manager_v1_interface, 2));
@@ -3048,6 +3092,18 @@ static void global_handle_add(void *data,
}
else {
found = false;
+
+#ifdef USE_GNOME_NEEDS_LIBDECOR_HACK
+# ifdef WITH_GHOST_X11
+# ifdef WITH_GHOST_WAYLAND_LIBDECOR
+ if (STRPREFIX(interface, "gtk_shell")) { /* `gtk_shell1` at time of writing. */
+ /* Only require libdecor when built with X11 support,
+ * otherwise there is nothing to fall back on. */
+ display->libdecor_required = true;
+ }
+# endif /* WITH_GHOST_WAYLAND_LIBDECOR */
+# endif /* WITH_GHOST_X11 */
+#endif /* USE_GNOME_NEEDS_LIBDECOR_HACK */
}
CLOG_INFO(LOG,
@@ -3102,6 +3158,9 @@ GHOST_SystemWayland::GHOST_SystemWayland() : GHOST_System(), d(new GWL_Display)
throw std::runtime_error("Wayland: unable to connect to display!");
}
+ /* This may be removed later if decorations are required, needed as part of registration. */
+ d->xdg_decor = new WGL_XDG_Decor_System;
+
/* Register interfaces. */
struct wl_registry *registry = wl_display_get_registry(d->display);
wl_registry_add_listener(registry, ®istry_listener, d);
@@ -3112,17 +3171,45 @@ GHOST_SystemWayland::GHOST_SystemWayland() : GHOST_System(), d(new GWL_Display)
wl_registry_destroy(registry);
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
- d->decor_context = libdecor_new(d->display, &libdecor_interface);
- if (!d->decor_context) {
- display_destroy(d);
- throw std::runtime_error("Wayland: unable to create window decorations!");
+ if (d->libdecor_required) {
+ wgl_xdg_decor_system_destroy(d->xdg_decor);
+ d->xdg_decor = nullptr;
+
+ if (!has_libdecor) {
+# ifdef WITH_GHOST_X11
+ /* LIBDECOR was the only reason X11 was used, let the user know they need it installed. */
+ fprintf(stderr,
+ "WAYLAND found but libdecor was not, install libdecor for Wayland support, "
+ "falling back to X11\n");
+# endif
+ display_destroy(d);
+ throw std::runtime_error("Wayland: unable to find libdecor!");
+ }
}
-#else
- if (!d->xdg_shell) {
- display_destroy(d);
- throw std::runtime_error("Wayland: unable to access xdg_shell!");
+ else {
+ use_libdecor = false;
}
+#endif /* WITH_GHOST_WAYLAND_LIBDECOR */
+
+#ifdef WITH_GHOST_WAYLAND_LIBDECOR
+ if (use_libdecor) {
+ d->libdecor = new WGL_LibDecor_System;
+ WGL_LibDecor_System &decor = *d->libdecor;
+ decor.context = libdecor_new(d->display, &libdecor_interface);
+ if (!decor.context) {
+ displ
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list