wayland: Phase 64 — zxdg_decoration_manager_v1; CSD negotiation

Advertise the XDG decoration manager protocol so clients that support
server-side decoration negotiation can communicate with the compositor.
Since the Wayland path has no X11 frame rendering, respond to all
new_toplevel_decoration events with CLIENT_SIDE mode, directing clients
to draw their own title bars and borders.

Smoke test gains two new checks: compositor logs "xdg-decoration-manager
created" at startup, and weston-info reports zxdg_decoration_manager_v1
in the global registry.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Levi Neely 2026-03-28 09:26:52 +01:00
parent 36b024d849
commit cc846daeca
2 changed files with 49 additions and 1 deletions

View File

@ -51,6 +51,9 @@
* (all XDG toplevels support close); wClientSendProtocol dispatches
* client_close in the Wayland path so MC_CLOSE is enabled and kill_close=0.
* wManageWindow succeeded log now includes kill_close= field.
* Phase 64: zxdg_decoration_manager_v1 advertised; new_toplevel_decoration
* listener responds immediately with CLIENT_SIDE mode so clients draw their
* own title bars (no X11 frame rendering in the Wayland path).
*/
#ifdef HAVE_CONFIG_H
@ -74,6 +77,7 @@
#include <wlr/types/wlr_seat.h>
#include <wlr/types/wlr_keyboard.h>
#include <wlr/types/wlr_xdg_shell.h>
#include <wlr/types/wlr_xdg_decoration_v1.h>
#include <wlr/util/box.h>
/* Generated xdg-shell protocol implementation (Wayland glue code) */
#include "protocols/xdg-shell-protocol.c"
@ -135,6 +139,9 @@ struct wl_compositor_state {
struct wlr_seat *seat;
struct wlr_data_device_manager *data_device_mgr;
struct wlr_xdg_shell *xdg_shell;
/* Phase 64: XDG decoration manager — tell clients to use CSD */
struct wlr_xdg_decoration_manager_v1 *decoration_manager;
struct wl_listener decoration_new_listener;
/* Phase 36: XDG toplevel tracking */
struct wl_listener xdg_new_surface_listener;
int managed_surface_count; /* surfaces seen */
@ -306,6 +313,21 @@ handle_toplevel_destroy(struct wl_listener *listener, void *data)
wfree(view);
}
/*
* Phase 64: new_toplevel_decoration listener.
* Immediately respond with CLIENT_SIDE so clients draw their own
* title bars and borders (the Wayland path has no X11 frame rendering).
*/
static void
handle_new_toplevel_decoration(struct wl_listener *listener, void *data)
{
struct wlr_xdg_toplevel_decoration_v1 *deco = data;
(void)listener;
wlr_xdg_toplevel_decoration_v1_set_mode(deco,
WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE);
wwarning("wl_backend: decoration mode=client_side for new toplevel");
}
/*
* Phase 36 / 38: new XDG surface listener.
* Allocates a wl_toplevel_view, assigns a synthetic WNativeWindow ID,
@ -428,6 +450,18 @@ wl_display_open(const char *name)
wlr_data_device_manager_create(wl_state.display);
wl_state.xdg_shell = wlr_xdg_shell_create(wl_state.display);
/* Phase 64: advertise zxdg_decoration_manager_v1 so clients that
* support server-side decorations can negotiate; we respond with
* CLIENT_SIDE since the Wayland path has no X11 frame rendering. */
wl_state.decoration_manager =
wlr_xdg_decoration_manager_v1_create(wl_state.display);
if (wl_state.decoration_manager) {
wl_state.decoration_new_listener.notify = handle_new_toplevel_decoration;
wl_signal_add(&wl_state.decoration_manager->events.new_toplevel_decoration,
&wl_state.decoration_new_listener);
wwarning("wl_backend: xdg-decoration-manager created");
}
/* Phase 36: advertise wl_shm (needed by SHM buffer clients) and
* expose the headless output as a wl_output global. */
wlr_renderer_init_wl_shm(wl_state.renderer, wl_state.display);

View File

@ -47,6 +47,9 @@
# 21. (Phase 63) PropGetProtocols sets DELETE_WINDOW=1 for Wayland windows;
# wClientSendProtocol dispatches client_close so MC_CLOSE is enabled and
# polite close works; verified by wManageWindow logging kill_close=0.
# 22. (Phase 64) zxdg_decoration_manager_v1 advertised in global registry;
# compositor logs "xdg-decoration-manager created"; new toplevels receive
# CLIENT_SIDE mode ("decoration mode=client_side" logged).
#
# This test grows as wl_backend vtable slots are implemented.
#
@ -151,6 +154,14 @@ PTR_POS=$(grep -o 'virtual pointer initialised at [0-9]*,[0-9]*' /tmp/wl-smoke-s
| head -1 | sed 's/virtual pointer initialised at //')
echo " pointer check: virtual pointer initialised at $PTR_POS"
# -- 4c. Phase 64: XDG decoration manager must be created ----------------
#
# wl_display_open() logs "xdg-decoration-manager created" when
# wlr_xdg_decoration_manager_v1_create() succeeds.
grep -q 'xdg-decoration-manager created' /tmp/wl-smoke-stderr \
|| die "compositor did not log xdg-decoration-manager creation"
echo " decoration check: xdg-decoration-manager created"
# -- 5. Core Wayland globals must be advertised ---------------------------
#
# Phase 35: wl_compositor, wl_seat, and xdg_wm_base must appear in the
@ -172,7 +183,10 @@ if command -v weston-info >/dev/null 2>&1; then
# Phase 53: seat must advertise pointer capability
echo "$WI" | grep -q 'pointer' \
|| die "wl_seat does not advertise pointer capability"
echo " globals check: wl_compositor, wl_seat, xdg_wm_base, wl_shm, wl_output present; seat has pointer capability"
# Phase 64: zxdg_decoration_manager_v1 must be in the global registry
echo "$WI" | grep -q 'zxdg_decoration_manager_v1' \
|| die "zxdg_decoration_manager_v1 not in Wayland global registry"
echo " globals check: wl_compositor, wl_seat, xdg_wm_base, wl_shm, wl_output, zxdg_decoration_manager_v1 present; seat has pointer capability"
else
echo " globals check: skipped (weston-info not installed)"
fi