diff --git a/src/backend/wayland/wl_backend.c b/src/backend/wayland/wl_backend.c index bdbe701..d3a30e2 100644 --- a/src/backend/wayland/wl_backend.c +++ b/src/backend/wayland/wl_backend.c @@ -31,6 +31,8 @@ * title_listener updates wwin->wm_instance/wm_class on set_title signal; * wClientSendProtocol/wClientKill guarded for Wayland. * Phase 47: prop_get_normal_hints returns XDG toplevel min/max/current size. + * Phase 53: headless pointer device added to seat; seat advertises both + * WL_SEAT_CAPABILITY_KEYBOARD and WL_SEAT_CAPABILITY_POINTER. */ #ifdef HAVE_CONFIG_H @@ -121,6 +123,8 @@ struct wl_compositor_state { unsigned long next_synthetic_id; /* >= 0x10000000 */ /* Phase 43: headless keyboard device for seat keyboard focus */ struct wlr_input_device *keyboard_dev; + /* Phase 53: headless pointer device so seat advertises pointer capability */ + struct wlr_input_device *pointer_dev; char socket_name[64]; /* Phase 34: e.g. "wayland-0" */ int started; /* non-zero after successful display_open */ }; @@ -400,9 +404,19 @@ wl_display_open(const char *name) * wlr_seat_keyboard_notify_enter() can deliver keyboard focus. */ wl_state.keyboard_dev = wlr_headless_add_input_device(wl_state.backend, WLR_INPUT_DEVICE_KEYBOARD); - if (wl_state.keyboard_dev) { + if (wl_state.keyboard_dev) wlr_seat_set_keyboard(wl_state.seat, wl_state.keyboard_dev); - wlr_seat_set_capabilities(wl_state.seat, WL_SEAT_CAPABILITY_KEYBOARD); + + /* Phase 53: create a headless pointer so the seat advertises pointer + * capability to clients (required for clients that bind wl_pointer). */ + wl_state.pointer_dev = + wlr_headless_add_input_device(wl_state.backend, WLR_INPUT_DEVICE_POINTER); + + { + uint32_t caps = 0; + if (wl_state.keyboard_dev) caps |= WL_SEAT_CAPABILITY_KEYBOARD; + if (wl_state.pointer_dev) caps |= WL_SEAT_CAPABILITY_POINTER; + if (caps) wlr_seat_set_capabilities(wl_state.seat, caps); } /* Phase 38: initialise per-toplevel tracking and context store. */ diff --git a/tests/wl-smoke-test.sh b/tests/wl-smoke-test.sh index a5c62b3..6e6d01f 100755 --- a/tests/wl-smoke-test.sh +++ b/tests/wl-smoke-test.sh @@ -36,6 +36,8 @@ # logged as pid= in wManageWindow succeeded line # 17. (Phase 51) two simultaneous clients both managed and unmanaged cleanly; # compositor survives multi-client scenario +# 18. (Phase 53) wl_seat advertises pointer capability (headless pointer +# device added); verified via weston-info if available # # This test grows as wl_backend vtable slots are implemented. # @@ -79,6 +81,13 @@ ldd "$WMAKER" 2>/dev/null | grep -qi 'wlroots\|libwlr' \ # verifies the Wayland socket was created, sends SIGTERM, and checks # for clean exit. +# Ensure XDG_RUNTIME_DIR is set and writable (wl_display_add_socket_auto needs it) +if [ -z "$XDG_RUNTIME_DIR" ]; then + XDG_RUNTIME_DIR="/tmp/wl-smoke-run-$$" + mkdir -p "$XDG_RUNTIME_DIR" + export XDG_RUNTIME_DIR +fi + WMAKER_USE_WAYLAND=1 src/wmaker \ --no-dock --no-clip --no-autolaunch \ --dont-restore --static \ @@ -140,7 +149,10 @@ if command -v weston-info >/dev/null 2>&1; then || die "wl_shm not in Wayland global registry" echo "$WI" | grep -q 'wl_output' \ || die "wl_output not in Wayland global registry" - echo " globals check: wl_compositor, wl_seat, xdg_wm_base, wl_shm, wl_output present" + # 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" else echo " globals check: skipped (weston-info not installed)" fi