GHOST/Wayland: use XDG_CURRENT_DESKTOP to detect GNOME
This change was made previously [0] but reverted as it caused the
title-bar to disappear on Ubuntu (see #121241).
Check if the value is set to GNOME delimited by `:`.
Previously checking the interfaces was used which has the down-side
that any compositor that adds `gtk_shell*` support may hang on startup
because of bugs in Blender/LIBDECOR as happened with WAYFIRE,
see reply to #76428.
[0]: 3a5389d5ab
This commit is contained in:
@@ -191,15 +191,6 @@ static bool use_gnome_confine_hack = false;
|
||||
*/
|
||||
#define USE_KDE_TABLET_HIDDEN_CURSOR_HACK
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
|
||||
# define USE_GNOME_NEEDS_LIBDECOR_HACK
|
||||
#endif
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
@@ -1362,12 +1353,6 @@ struct GWL_Display {
|
||||
|
||||
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
|
||||
GWL_LibDecor_System *libdecor = nullptr;
|
||||
bool libdecor_required = false;
|
||||
/**
|
||||
* When true, behave as if `libdecor_required` is false.
|
||||
* `libdecor_required` can't simply be set to false because the order of assignment is undefined.
|
||||
*/
|
||||
bool libdecor_required_ignore = false;
|
||||
#endif
|
||||
GWL_XDG_Decor_System *xdg_decor = nullptr;
|
||||
|
||||
@@ -1778,6 +1763,35 @@ static void gwl_registry_entry_update_all(GWL_Display *display, const int interf
|
||||
/** \name Private Utility Functions
|
||||
* \{ */
|
||||
|
||||
static const char *strchr_or_end(const char *str, const char ch)
|
||||
{
|
||||
const char *p = str;
|
||||
while (!ELEM(*p, ch, '\0')) {
|
||||
p++;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
static bool string_elem_split_by_delim(const char *haystack, const char delim, const char *needle)
|
||||
{
|
||||
/* Local copy of #BLI_string_elem_split_by_delim (would be a bad level call). */
|
||||
|
||||
/* May be zero, returns true when an empty span exists. */
|
||||
const size_t needle_len = strlen(needle);
|
||||
const char *p = haystack, *p_next;
|
||||
while (true) {
|
||||
p_next = strchr_or_end(p, delim);
|
||||
if ((size_t(p_next - p) == needle_len) && (memcmp(p, needle, needle_len) == 0)) {
|
||||
return true;
|
||||
}
|
||||
if (*p_next == '\0') {
|
||||
break;
|
||||
}
|
||||
p = p_next + 1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static uint64_t sub_abs_u64(const uint64_t a, const uint64_t b)
|
||||
{
|
||||
return a > b ? a - b : b - a;
|
||||
@@ -6985,35 +6999,6 @@ static void global_handle_add(void *data,
|
||||
|
||||
added = display->registry_entry != registry_entry_prev;
|
||||
}
|
||||
else {
|
||||
/* Not found. */
|
||||
#ifdef USE_GNOME_NEEDS_LIBDECOR_HACK
|
||||
/* NOTE(@ideasman42): I'm not happy with the logic here because it's fairly fragile
|
||||
* and will cause problems whenever any non-GNOME compositor adds support for `gtk_shell*`
|
||||
* Ideally there would be a way to:
|
||||
* - Detect when server-side-decorations aren't supported.
|
||||
* `zxdg_decoration_manager_v1` looks like it *could* be used
|
||||
* but it's not supported by GNOME.
|
||||
* - Detect the underlying compositor.
|
||||
* `XDG_CURRENT_DESKTOP` could be used but isn't always set, see: #121241.
|
||||
*
|
||||
* All things considered, inspecting interface names seems least terrible (sigh).
|
||||
*/
|
||||
|
||||
/* `gtk_shell1` at time of writing. */
|
||||
if (STRPREFIX(interface, "gtk_shell")) {
|
||||
/* Only require `libdecor` when built with X11 support,
|
||||
* otherwise there is nothing to fall back on. */
|
||||
display->libdecor_required = true;
|
||||
}
|
||||
/* `zwf_shell_manager_v2` at time of writing. */
|
||||
else if (STRPREFIX(interface, "zwf_shell_manager_v")) {
|
||||
/* Needed when non GNOME compositors provide the `gtk_shell*` interface.
|
||||
* WAYFIRE in this case. */
|
||||
display->libdecor_required_ignore = true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
CLOG_INFO(LOG,
|
||||
2,
|
||||
@@ -7171,28 +7156,33 @@ GHOST_SystemWayland::GHOST_SystemWayland(bool background)
|
||||
}
|
||||
|
||||
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
|
||||
if (display_->libdecor_required_ignore) {
|
||||
display_->libdecor_required = false;
|
||||
bool libdecor_required = false;
|
||||
if (const char *xdg_current_desktop = getenv("XDG_CURRENT_DESKTOP")) {
|
||||
/* See the free-desktop specifications for details on `XDG_CURRENT_DESKTOP`.
|
||||
* https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html */
|
||||
if (string_elem_split_by_delim(xdg_current_desktop, ':', "GNOME")) {
|
||||
libdecor_required = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (display_->libdecor_required) {
|
||||
if (libdecor_required) {
|
||||
/* Ignore windowing requirements when running in background mode,
|
||||
* as it doesn't make sense to fall back to X11 because of windowing functionality
|
||||
* in background mode, also LIBDECOR is crashing in background mode `blender -b -f 1`
|
||||
* for e.g. while it could be fixed, requiring the library at all makes no sense. */
|
||||
if (background) {
|
||||
display_->libdecor_required = false;
|
||||
libdecor_required = false;
|
||||
}
|
||||
# ifdef WITH_GHOST_X11
|
||||
else if (!has_libdecor && !ghost_wayland_is_x11_available()) {
|
||||
/* Only require LIBDECOR when X11 is available, otherwise there is nothing to fall back to.
|
||||
* It's better to open without window decorations than failing entirely. */
|
||||
display_->libdecor_required = false;
|
||||
libdecor_required = false;
|
||||
}
|
||||
# endif /* WITH_GHOST_X11 */
|
||||
}
|
||||
|
||||
if (display_->libdecor_required) {
|
||||
if (libdecor_required) {
|
||||
gwl_xdg_decor_system_destroy(display_, display_->xdg_decor);
|
||||
display_->xdg_decor = nullptr;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user