Commit Graph

17 Commits

Author SHA1 Message Date
Levi Neely ec98ed3d21 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>
2026-03-28 07:19:01 +01:00
Levi Neely c36bd7384e wayland: Phase 51 — multi-client: two simultaneous toplevels managed cleanly
Run two weston-simple-shm processes in parallel during the smoke test
and verify that all three toplevels (one from the single-client section
plus two from the parallel section) are managed and unmanaged without
crashing the compositor.  The synthetic-ID counter, focus chain, and
wUnmanageWindow path all survive the multi-client scenario.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-28 07:06:26 +01:00
Levi Neely 14da9a65ae wayland: Phase 50 — client_get_pid via wl_client_get_credentials; misc guards
Implement wl_client_get_pid using wl_resource_get_client +
wl_client_get_credentials so the WM can retrieve the OS PID of
Wayland clients.  Guard getCommandForWindow in misc.c against NULL
dpy to prevent XGetCommand crash when the real PID path fires.
Guard wWindowChangeWorkspace against NULL frame for frameless
Wayland windows.  Log pid= in the wManageWindow-succeeded line;
add Phase 50 pid check to smoke test.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-28 07:03:55 +01:00
Levi Neely 69cee6fb15 wayland: Phase 45 — pointer_query returns on-screen; focus path guarded
pointer_query / pointer_query_full: return 1 when compositor is running
(wl_state.started) so the same_screen check in wManageWindow passes and
wSetFocusTo is called for newly mapped XDG toplevels.

Guard frame-dependent calls in the focus update path:
  - wWindowFocus (window.c): guard wFrameWindowChangeState on frame!=NULL
  - wWindowUnfocus (window.c): same; also guard wFrameWindowPaint on
    owner->frame when clearing semi-focus on transient owner

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-28 06:43:16 +01:00
Levi Neely 0fe2960995 wayland: Phase 43 — focus_set delivers keyboard focus via wlr_seat
Create a headless keyboard input device during wl_display_open and
attach it to wlr_seat so wlr_seat_keyboard_notify_enter() can deliver
keyboard focus to XDG toplevel surfaces.

Implement wl_focus_set: look up the view by synthetic ID, call
wlr_seat_keyboard_notify_enter with the xdg_surface->surface.
Call wl_focus_set from handle_toplevel_map immediately after
wManageWindow so newly mapped toplevels receive keyboard focus.

Smoke test: add Phase 43 check — grep "focus_set id=" in stderr.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-28 06:40:16 +01:00
Levi Neely d9a70e9177 wayland: Phase 42 — window_get_client_attrs returns real map/geometry
Implement wl_window_get_client_attrs: look up the toplevel view, return
WCLIENT_VIEWABLE with width/height from wlr_surface.current for mapped
surfaces; WCLIENT_UNMAPPED for unknown IDs.

Extend the wManageWindow success log to include geo=WxH so the smoke
test can verify the geometry is non-zero after the client commits a frame.

Smoke test: add Phase 42 check — grep geo= and verify it is logged.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-28 06:37:59 +01:00
Levi Neely 0ea33dc830 wayland: Phase 41 — prop_get_wm_class/window_fetch_name from XDG metadata
Add wl_find_view_by_id() helper that walks toplevel_list to recover a
wl_toplevel_view from its synthetic WNativeWindow ID.

Implement vtable slots:
  - prop_get_wm_class: returns XDG app_id as both WM_CLASS and WM_INSTANCE
  - window_fetch_name: returns XDG toplevel title

Extend the wManageWindow success log to include class= and name= so
the smoke test can verify these fields are populated from Wayland metadata.

Smoke test: add Phase 41 check — grep for
"class=org.freedesktop.weston.simple-shm" in manage log.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-28 06:36:22 +01:00
Levi Neely 490ecb34ff wayland: Phase 40 — wire toplevel unmap to wUnmanageWindow
Guard all dpy==NULL / frame==NULL crash sites in the unmanage path:
  - wUnmanageWindow (window.c): frame ptr set to NULL-safe expression;
    window_unmap, raise_delay timer, and owner border change all
    guarded on frame != NULL
  - wSelectWindow (actions.c): early return if !wwin->frame
  - wNETCleanupFrameExtents (wmspec.c): early return if !dpy
  - wClientRestore (client.c): early return if !dpy

Wire handle_toplevel_unmap → context_find → wUnmanageWindow(destroyed=True)
so XDG toplevels are removed from scr->focused_window on client disconnect.

Smoke test: add Phase 40 check — grep "toplevel unmapped".

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-28 06:34:15 +01:00
Levi Neely ca09635129 wayland: Phase 39 — wire toplevel map to wManageWindow
Guard all dpy==NULL crash sites reached from wManageWindow:
  - wNETWMGetPidForWindow (wmspec.c) — XGetWindowProperty with NULL dpy
  - wNETWMCheckClientHints (wmspec.c) — XGetWindowProperty
  - wNETWMCheckInitialClientState (wmspec.c) — XChangeProperty chain
  - getMWMHints (motif.c) — XInternAtom before NULL dpy check
  - wClientSetState (client.c) — XChangeProperty
  - wColormapInstallForWindow (colormap.c) — XGetWindowAttributes
  - wWindowSetKeyGrabs (window.c) — frame->core->window dereference

Wire handle_toplevel_map → wManageWindow(scr, view->id) so mapped
XDG toplevels appear in scr->focused_window.  Log success via
"wl_backend: wManageWindow succeeded id=0x%lx".

Smoke test: add Phase 39 check — grep "wManageWindow succeeded".

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-28 06:23:23 +01:00
Levi Neely 74a43f0180 wayland: Phase 38 — per-toplevel view lifecycle and context store
Introduce struct wl_toplevel_view with map/unmap/destroy wl_signal
listeners and a synthetic WNativeWindow ID (>= 0x10000000).
Implement context_save/find/delete as a per-key linked list of
(WNativeWindow, void*) entries — enables downstream policy code to
look up views by handle.  wl-smoke-test now verifies "toplevel mapped"
appears in compositor stderr when weston-simple-shm creates its surface.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 23:19:18 +01:00
Levi Neely 3e1fd061e9 wayland: Phase 37 — frame timer drives client frame callbacks at 60 fps
Replace the output frame listener + render pipeline approach (which
required a swapchain allocator) with a simple wl_event_loop timer that
calls wlr_output_send_frame every 16 ms.  Clients (weston-simple-shm)
now complete their render loops without the compositor needing a GPU
allocator.  Also schedule an initial xdg_surface configure on new
toplevels so they can commit their first buffer.  wl-smoke-test verifies
weston-simple-shm runs for 3 s without crashing the compositor.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 23:15:59 +01:00
Levi Neely 2182ec0fc1 wayland: Phase 36 — wl_shm, wl_output, XDG toplevel listener
Advertise wl_shm (via wlr_renderer_init_wl_shm) and expose the headless
output as a wl_output global so SHM buffer clients can render.  Wire up
the xdg_shell new_surface listener to track incoming XDG toplevels
(management hook placeholder).  wl-smoke-test now verifies wl_shm and
wl_output in the registry and that weston-simple-shm can connect without
crashing the compositor.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 23:12:21 +01:00
Levi Neely 075b648021 wayland: Phase 35 — advertise core Wayland protocol globals
Register wl_compositor (+ wl_subcompositor), wl_seat, wl_data_device_manager,
and xdg_wm_base in the compositor's global registry so that Wayland clients
can enumerate and bind them.  Add generated xdg-shell-protocol.{h,c} from
wayland-scanner.  wl-smoke-test now uses weston-info to verify all three
key globals are present.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 23:09:39 +01:00
Levi Neely 97a9209b4f wayland: Phase 34 — Wayland socket, output layout, real monitors_query
Create the compositor UNIX socket via wl_display_add_socket_auto so
Wayland clients can connect; store socket name and set WAYLAND_DISPLAY.
Add wlr_output_layout for multi-head tracking and implement monitors_query
to return real 1920x1080 head geometry from the headless output.
wl-smoke-test now verifies the socket file exists in XDG_RUNTIME_DIR.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 23:06:49 +01:00
Levi Neely f7dfc50f26 wayland: Phase 33 — event_loop_run/atom_intern vtable; wmaker starts and exits cleanly under Wayland
Add display_default_screen, atom_intern, and event_loop_run vtable slots.
Guard all X11-only paths in startup.c/screen.c/shutdown.c/event.c/xdnd.c
with if (!dpy) so the Wayland path reaches wl_display_run() and exits
cleanly (exit 0) on SIGTERM.  wl-smoke-test.sh now PASSES.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 23:02:26 +01:00
Levi Neely e8e230b2db wayland: add WMAKER_USE_WAYLAND backend selector and split smoke tests
- startup.c: include wl_backend.h when USE_WAYLAND_BACKEND is defined;
  select wl_backend when WMAKER_USE_WAYLAND env var is set, otherwise
  fall back to x11_backend (no-op for non-Wayland builds)
- tests/smoke-test.sh renamed to tests/x11-smoke-test.sh (X11-only path)
- tests/wl-smoke-test.sh: new Wayland smoke test; currently verifies
  wl_backend symbol presence and wlroots linkage; headless compositor
  tests will be added as vtable slots are implemented

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 22:29:27 +01:00
Levi Neely a486329b52 Wayland backend abstraction: WMBackend vtable (Phases 0–30)
Introduce a display-system-agnostic WMBackend vtable that routes all
display operations through function pointers, making the WM policy
layer independent of X11.  The X11 implementation is preserved in
src/backend/x11/ and behaviour is unchanged.

Key structural changes
──────────────────────
• src/backend/backend_types.h — backend-neutral type definitions:
    WNativeWindow, WKeyCode, WContextKey, WBackendScreen,
    WBackendEvent (+typed fields), WNormalHints, WWMHints,
    WNETWindowType, WHeadGeometry, WClientAttributes, WClientVisual,
    WSegment, WPoint, WM_KEY_* keysym constants, WA_* atom IDs,
    WKB_GROUP*_INDEX, WCUR_NONE

• src/backend/backend.h — WMBackend vtable (~100 function-pointer
    slots) covering: frame/context lifecycle, stacking, focus, grabs,
    pointer, keyboard, overlays, properties, ICCCM, EWMH/NETWM,
    monitors, screen setup, cursors, extensions, error handlers.
    No <X11/> headers remain in this file after Phase 30.

• src/backend/x11/ — X11 backend implementation:
    x11_backend.c  full vtable; all display calls confined here
    x11_props.c    WM_NORMAL_HINTS / WM_HINTS translation
    x11_event.c    XEvent → WBackendEvent translation
    x11_monitor.c  Xinerama / RandR monitor query

Policy files cleaned
────────────────────
All 47 files in WM_POLICY_CLEAN_FILES pass check-no-x11-policy
(no direct #include <X11/> anywhere).  X11 types that still appear
in policy structs (Visual*, Colormap, Window, Atom …) arrive only
transitively via WINGs.h; the vtable boundary itself is X11-free.

Tests
─────
• tests/smoke-test.sh — full Xvfb lifecycle test (PASS)
• tests/test_geom.c   — geometry / constraint unit tests
• tests/test_x11_event.c — WBackendEvent field extraction tests

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 19:20:00 +01:00