wayland: Phase 53 — headless pointer device; seat advertises pointer capability

Add a headless pointer input device (WLR_INPUT_DEVICE_POINTER) to the
Wayland seat alongside the existing keyboard device.  wlr_seat now
advertises both WL_SEAT_CAPABILITY_KEYBOARD and WL_SEAT_CAPABILITY_POINTER
to clients that bind wl_seat.

Also fix the smoke test to set XDG_RUNTIME_DIR when it is unset so
wl_display_add_socket_auto() can always create the compositor socket.

Smoke test gains a Phase 53 check: weston-info must show 'pointer' in the
wl_seat capabilities output.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Levi Neely 2026-03-28 07:19:01 +01:00
parent c03581c81f
commit ec98ed3d21
2 changed files with 29 additions and 3 deletions

View File

@ -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. */

View File

@ -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