From 3035fa628280d669d847c395bb3f47bdbee3f933 Mon Sep 17 00:00:00 2001 From: Amit Mendapara <282290+cristatus@users.noreply.github.com> Date: Mon, 3 Aug 2026 14:54:59 +0530 Subject: [PATCH] [client] wayland: fix double xdg_toplevel role assignment in libdecor path libdecor_decorate() already creates an xdg_surface and xdg_toplevel internally for the frame. Calling xdg_surface_get_toplevel() again on that same xdg_surface just to fetch the toplevel for icon handling assigns the xdg_toplevel role to the underlying wl_surface a second time, which is a protocol violation. On GNOME Shell 50 (mutter) this is no longer tolerated: mutter terminates the Wayland connection ("WL: error in client communication"), and since libdecor_shellInit() waits for the initial configure with a blocking, error-less libdecor_dispatch(-1) loop, the client hangs forever with no window and no diagnostic output. This made -DENABLE_LIBDECOR=ON (the default when libdecor-0 is present) appear completely broken on current GNOME/Wayland. Use libdecor_frame_get_xdg_toplevel() instead, which returns the xdg_toplevel libdecor already owns, without requesting a second role assignment. Require libdecor-0 >= 0.1.1, which is available in Debian oldstable, so the new accessor is guaranteed by the build dependency. --- AUTHORS | 1 + client/displayservers/Wayland/desktops/CMakeLists.txt | 2 +- client/displayservers/Wayland/desktops/libdecor/libdecor.c | 4 +--- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/AUTHORS b/AUTHORS index 19dffc61..0b5d570c 100644 --- a/AUTHORS +++ b/AUTHORS @@ -75,3 +75,4 @@ Jérôme Poulin (ticpu) Marco Rodolfi (RodoMa92) Stewart Borle (stewi1014) Jannis Lübke (Janrupf) +Amit Mendapara <282290+cristatus@users.noreply.github.com> (cristatus) diff --git a/client/displayservers/Wayland/desktops/CMakeLists.txt b/client/displayservers/Wayland/desktops/CMakeLists.txt index 893fe55c..70f496f5 100644 --- a/client/displayservers/Wayland/desktops/CMakeLists.txt +++ b/client/displayservers/Wayland/desktops/CMakeLists.txt @@ -23,7 +23,7 @@ endfunction() # the first entry here is the default add_desktop(xdg) -pkg_check_modules(LIBDECOR IMPORTED_TARGET libdecor-0) +pkg_check_modules(LIBDECOR IMPORTED_TARGET libdecor-0>=0.1.1) if(LIBDECOR_FOUND) option(ENABLE_LIBDECOR "Build with libdecor support" ON) else() diff --git a/client/displayservers/Wayland/desktops/libdecor/libdecor.c b/client/displayservers/Wayland/desktops/libdecor/libdecor.c index 0eaef2f9..a588fbfc 100644 --- a/client/displayservers/Wayland/desktops/libdecor/libdecor.c +++ b/client/displayservers/Wayland/desktops/libdecor/libdecor.c @@ -145,9 +145,7 @@ static bool libdecor_shellInit( libdecor_frame_map(state.libdecorFrame); // Get the xdg_toplevel for icon setting - struct xdg_surface * xdgSurface = libdecor_frame_get_xdg_surface(state.libdecorFrame); - if (xdgSurface) - wlWm.xdgToplevel = xdg_surface_get_toplevel(xdgSurface); + wlWm.xdgToplevel = libdecor_frame_get_xdg_toplevel(state.libdecorFrame); if (fullscreen) libdecor_frame_set_fullscreen(state.libdecorFrame, NULL);