From 36b024d84961e708a4fa93111712f7aab7b52040 Mon Sep 17 00:00:00 2001 From: Levi Neely Date: Sat, 28 Mar 2026 09:24:22 +0100 Subject: [PATCH] =?UTF-8?q?wayland:=20Phase=2063=20=E2=80=94=20DELETE=5FWI?= =?UTF-8?q?NDOW=3D1=20for=20Wayland;=20wClientSendProtocol=20dispatches=20?= =?UTF-8?q?client=5Fclose?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All XDG toplevels support polite close via wlr_xdg_toplevel_send_close. PropGetProtocols now sets DELETE_WINDOW=1 in the Wayland path so wManageWindow sets kill_close=0 (prefer polite close over force-kill) and the MC_CLOSE menu item is enabled for Wayland windows. wClientSendProtocol dispatches wm_backend->client_close in the Wayland path instead of returning early; since all atoms are 0 in Wayland, atom comparison is unreliable, but all callers that reach wClientSendProtocol are requesting a polite close — the only Wayland-meaningful WM_PROTOCOL. wManageWindow succeeded log gains a kill_close= field; smoke test check 21 verifies kill_close=0 for each managed Wayland toplevel. Co-Authored-By: Claude Sonnet 4.6 --- src/backend/wayland/wl_backend.c | 9 +++++++-- src/client.c | 10 ++++++++-- src/properties.c | 9 +++++++-- tests/wl-smoke-test.sh | 13 +++++++++++++ 4 files changed, 35 insertions(+), 6 deletions(-) diff --git a/src/backend/wayland/wl_backend.c b/src/backend/wayland/wl_backend.c index 983d75b..3745ef9 100644 --- a/src/backend/wayland/wl_backend.c +++ b/src/backend/wayland/wl_backend.c @@ -47,6 +47,10 @@ * and calls wlr_seat_keyboard_clear_focus; wl_focus_set recognises * WNATIVE_NONE as "clear focus" and calls wlr_seat_keyboard_clear_focus * instead of delivering focus to a nonexistent surface. + * Phase 63: PropGetProtocols sets DELETE_WINDOW=1 for all Wayland windows + * (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. */ #ifdef HAVE_CONFIG_H @@ -241,11 +245,12 @@ handle_toplevel_map(struct wl_listener *listener, void *data) if (wwin) { int pid = wl_client_get_pid(view->id); wwarning("wl_backend: wManageWindow succeeded id=0x%lx " - "class=%s name=%s geo=%dx%d pid=%d", + "class=%s name=%s geo=%dx%d pid=%d kill_close=%d", view->id, wwin->wm_class ? wwin->wm_class : "(none)", wwin->wm_instance ? wwin->wm_instance : "(none)", - wwin->client.width, wwin->client.height, pid); + wwin->client.width, wwin->client.height, pid, + wwin->client_flags.kill_close); /* Phase 62: focus delivered by wManageWindow via wSetFocusTo * (auto_focus=1 set in wl_screen_create_internals); the * direct wl_focus_set() call is no longer needed here. */ diff --git a/src/client.c b/src/client.c index f2abdaf..8bad05a 100644 --- a/src/client.c +++ b/src/client.c @@ -250,8 +250,14 @@ void wClientSendProtocol(WWindow * wwin, Atom protocol, Time time) { XEvent event; - if (!dpy) - return; /* Wayland: no X11 ClientMessage */ + if (!dpy) { + /* Phase 63: Wayland — there are no X11 ClientMessages. All atoms + * are 0 in the Wayland path so atom comparison is unreliable; all + * callers that reach here are requesting a polite close (the only + * Wayland-meaningful WM_PROTOCOL), so dispatch client_close. */ + wm_backend->client_close(wwin->client_win); + return; + } event.xclient.type = ClientMessage; event.xclient.message_type = w_global.atom.wm.protocols; diff --git a/src/properties.c b/src/properties.c index 82bb874..1aae0f7 100644 --- a/src/properties.c +++ b/src/properties.c @@ -41,8 +41,13 @@ void PropGetProtocols(Window window, WProtocols * prots) int count, i; memset(prots, 0, sizeof(WProtocols)); - if (!dpy) - return; /* Wayland: no ICCCM WM_PROTOCOLS */ + if (!dpy) { + /* Phase 63: all XDG toplevels support close (wlr_xdg_toplevel_send_close). + * Advertise DELETE_WINDOW so wManageWindow sets kill_close=0 and the + * close menu item is enabled. */ + prots->DELETE_WINDOW = 1; + return; + } if (!XGetWMProtocols(dpy, window, &protocols, &count)) { return; } diff --git a/tests/wl-smoke-test.sh b/tests/wl-smoke-test.sh index 85a8e04..1da024c 100755 --- a/tests/wl-smoke-test.sh +++ b/tests/wl-smoke-test.sh @@ -44,6 +44,9 @@ # 20. (Phase 62) wl_screen_create_internals sets no_focus_win=WNATIVE_NONE; # wl_focus_set(WNATIVE_NONE) calls wlr_seat_keyboard_clear_focus and logs # "focus_clear" when the last managed window unmaps. +# 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. # # This test grows as wl_backend vtable slots are implemented. # @@ -233,6 +236,16 @@ if command -v weston-simple-shm >/dev/null 2>&1; then || die "compositor did not log 'focus_clear' (wl_focus_set WNATIVE_NONE path not reached)" echo " focus_clear check: keyboard focus cleared after last window unmap" + # -- 21. Phase 63: DELETE_WINDOW=1 → kill_close=0 for Wayland toplevels -- + # + # PropGetProtocols now sets DELETE_WINDOW=1 for all Wayland windows so + # wManageWindow sets kill_close=0 (polite close preferred over force-kill). + # Verified by the kill_close= field in the wManageWindow succeeded log. + KC=$(grep -o 'kill_close=[0-9]*' /tmp/wl-smoke-stderr | head -1 | sed 's/kill_close=//') + [ "$KC" = "0" ] \ + || die "expected kill_close=0 for Wayland toplevel (DELETE_WINDOW not set?), got kill_close=${KC:-missing}" + echo " kill_close check: kill_close=0 (DELETE_WINDOW=1, polite close enabled)" + # -- 15. Phase 51: two simultaneous clients both managed -------------- # # Launch two weston-simple-shm processes in parallel (2s and 3s).