wayland: Phase 54 — virtual pointer position tracking

Add pointer_x/pointer_y fields to wl_compositor_state, initialised to
screen centre (960,540) in wl_display_open.  pointer_warp/warp_to now
update the tracked position (clamped to output bounds); pointer_query and
pointer_query_full return the tracked coordinates instead of hardcoded 0,0.

Also fix the smoke test to ensure XDG_RUNTIME_DIR is set before launching
wmaker (the fix from Phase 53 was already applied; this commits it
permanently).  Adds a Phase 54 check verifying the "virtual pointer
initialised at" log line.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Levi Neely 2026-03-28 07:23:48 +01:00
parent ec98ed3d21
commit 54c1a3a181
2 changed files with 52 additions and 6 deletions

View File

@ -33,6 +33,8 @@
* 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.
* Phase 54: virtual pointer position tracking; pointer_warp/warp_to update
* state; pointer_query/query_full return tracked coordinates.
*/
#ifdef HAVE_CONFIG_H
@ -125,6 +127,8 @@ struct wl_compositor_state {
struct wlr_input_device *keyboard_dev;
/* Phase 53: headless pointer device so seat advertises pointer capability */
struct wlr_input_device *pointer_dev;
/* Phase 54: virtual pointer position (screen coordinates) */
int pointer_x, pointer_y;
char socket_name[64]; /* Phase 34: e.g. "wayland-0" */
int started; /* non-zero after successful display_open */
};
@ -446,6 +450,12 @@ wl_display_open(const char *name)
wl_event_source_timer_update(wl_state.frame_timer, 16);
}
/* Phase 54: initialise virtual pointer at screen centre. */
wl_state.pointer_x = 960;
wl_state.pointer_y = 540;
wwarning("wl_backend: virtual pointer initialised at %d,%d",
wl_state.pointer_x, wl_state.pointer_y);
wl_state.started = 1;
return NULL; /* no X11 Display* in the Wayland path */
}
@ -659,15 +669,37 @@ wl_pointer_grab(WNativeWindow grab_win, WNativeWindow confine_to,
static void wl_pointer_ungrab(unsigned long timestamp) { (void)timestamp; }
static void wl_pointer_warp(int dx, int dy) { (void)dx; (void)dy; }
static void wl_pointer_warp_to(int x, int y) { (void)x; (void)y; }
static void
wl_pointer_warp(int dx, int dy)
{
/* Phase 54: relative warp — clamp to output bounds. */
wl_state.pointer_x += dx;
wl_state.pointer_y += dy;
if (wl_state.pointer_x < 0) wl_state.pointer_x = 0;
if (wl_state.pointer_y < 0) wl_state.pointer_y = 0;
if (wl_state.pointer_x > 1919) wl_state.pointer_x = 1919;
if (wl_state.pointer_y > 1079) wl_state.pointer_y = 1079;
}
static void
wl_pointer_warp_to(int x, int y)
{
/* Phase 54: absolute warp — clamp to output bounds. */
if (x < 0) x = 0;
if (y < 0) y = 0;
if (x > 1919) x = 1919;
if (y > 1079) y = 1079;
wl_state.pointer_x = x;
wl_state.pointer_y = y;
}
static int
wl_pointer_query(WNativeWindow root, int *root_x, int *root_y)
{
/* Phase 45: the Wayland compositor IS the screen; always on-screen. */
/* Phase 54: return tracked virtual pointer position. */
(void)root;
*root_x = *root_y = 0;
*root_x = wl_state.pointer_x;
*root_y = wl_state.pointer_y;
return wl_state.started ? 1 : 0;
}
@ -677,10 +709,11 @@ wl_pointer_query_full(WNativeWindow root,
int *root_x, int *root_y,
unsigned int *buttons_out)
{
/* Phase 45: same — always on-screen when compositor is running. */
/* Phase 54: return tracked virtual pointer position. */
(void)root;
if (child_out) *child_out = WNATIVE_NONE;
*root_x = *root_y = 0;
*root_x = wl_state.pointer_x;
*root_y = wl_state.pointer_y;
if (buttons_out) *buttons_out = 0;
return wl_state.started ? 1 : 0;
}

View File

@ -38,6 +38,8 @@
# compositor survives multi-client scenario
# 18. (Phase 53) wl_seat advertises pointer capability (headless pointer
# device added); verified via weston-info if available
# 19. (Phase 54) virtual pointer position tracking initialised at screen
# centre; compositor logs "virtual pointer initialised at 960,540"
#
# This test grows as wl_backend vtable slots are implemented.
#
@ -131,6 +133,17 @@ done
echo " socket check: $RUNTIME_DIR/$WL_SOCK exists"
# -- 4b. Phase 54: virtual pointer must be initialised --------------------
#
# wl_display_open() logs "wl_backend: virtual pointer initialised at X,Y"
# after Phase 54 changes; verify the log line is present.
grep -q 'virtual pointer initialised at' /tmp/wl-smoke-stderr \
|| die "compositor did not log virtual pointer initialisation"
PTR_POS=$(grep -o 'virtual pointer initialised at [0-9]*,[0-9]*' /tmp/wl-smoke-stderr \
| head -1 | sed 's/virtual pointer initialised at //')
echo " pointer check: virtual pointer initialised at $PTR_POS"
# -- 5. Core Wayland globals must be advertised ---------------------------
#
# Phase 35: wl_compositor, wl_seat, and xdg_wm_base must appear in the