Commit graph

11 commits

Author SHA1 Message Date
Till Wegmueller
f648a8af39 Wire WM protocol requests to compositor and add keybinding support
Complete the Phase 2.5 protocol wiring so external WMs can actually
control the compositor:

- Add compositor action methods to WmProtocolHandler: configure_window,
  focus_window, close_window, set_fullscreen, set_decoration
- Wire manage-phase requests (propose_dimensions, set_focus, close,
  fullscreen grant/deny, decorations) through to Smithay ToplevelSurface
- Trigger manage_start on new toplevel, render_start each frame, and
  notify_window_closed on toplevel destruction when external WM connected
- Apply external WM render commands in headless render loop
- Keybinding dispatch: bind_key/unbind_key storage, mode support,
  binding_pressed/released events sent to WM seat
- Built-in floating WM: Alt+F4 close, Alt+Tab focus cycling with tests
2026-04-07 22:51:50 +02:00
Till Wegmueller
f2aebe04a6 Implement pluggable window management protocol (Phase 2.5)
Add a custom Wayland protocol (wayray_wm_v1) that allows external
window manager processes to control layout, focus, and keybindings
in the WayRay compositor, inspired by River's two-phase transaction
model.

New crates:
- wayray-wm-protocol: Wayland protocol XML + generated server/client
  bindings via wayland-scanner for four interfaces (manager, window,
  seat, workspace)
- wr-wm-tiling: Reference BSP tiling WM demonstrating the protocol

Compositor changes:
- WindowManager trait + WmState coordinator abstracts WM behavior
- Built-in floating WM (centered windows, click-to-focus, z-ordering)
- Protocol server with GlobalDispatch/Dispatch for all interfaces
- Hot-swap (replaced event) and crash resilience (fallback to built-in)
- new_toplevel delegates to WM instead of hardcoding 800x600 at (0,0)
- WM render phase integrated into headless frame pipeline
2026-04-07 22:29:19 +02:00
Till Wegmueller
974511277b Fix keycode mapping, client disconnect, and server shutdown
- Keycodes: add +8 offset for XKB (evdev scancode + 8 = XKB keycode)
- Client: force exit on Cmd+Q/close (network thread may block)
- Server: force exit on Ctrl+C (network thread may block on accept)

Proper graceful shutdown with tokio CancellationToken deferred.
2026-04-07 19:37:41 +02:00
Till Wegmueller
c4e3920c79 Fix client surface rendering: add window.on_commit() and space.refresh()
Root cause: Window::bbox() stayed at 0x0 because Window::on_commit()
was never called after surface commits. The Space then never associated
the window with the output (no overlap), so render_elements_for_output
returned empty.

Two fixes:
- Call window.on_commit() in CompositorHandler::commit() to update
  the window's bounding box from the committed surface tree
- Call space.refresh() each frame to update output-element mappings

Also: send xdg_toplevel configure with suggested 800x600 size.
2026-04-07 19:15:52 +02:00
Till Wegmueller
8d248a8f52 Debug: send initial configure in new_toplevel, add window state logging
- Send xdg_toplevel configure before mapping window (foot needs this)
- Add window bbox and configure state debug logging
- Still investigating: foot connects but bbox stays 0x0 (no buffer committed)
2026-04-07 18:59:17 +02:00
Till Wegmueller
9fc27d3b56 Fix PixmanRenderer compositing: remove EGL features from default build
renderer_gl and backend_winit pulled in backend_egl, which changed the
ImportAll blanket impl to require ImportEgl — a trait PixmanRenderer
doesn't implement. This caused render_output to silently skip client
surface compositing (only the clear color rendered).

Fix: move renderer_gl and backend_winit behind a "winit" cargo feature.
Default build uses only renderer_pixman, which satisfies ImportAll via
the simpler ImportMemWl + ImportDmaWl blanket impl.

Winit backend: cargo build -p wrsrvd --features winit
Headless (default): cargo build -p wrsrvd
2026-04-07 18:44:19 +02:00
Till Wegmueller
3c6430c982 Add framebuffer content debug check (temp diagnostic) 2026-04-07 18:34:25 +02:00
Till Wegmueller
6968bcd69c Fix stride handling and add render debug logging
Use pixman Image's actual stride instead of width*4 for pixel reads.
Add debug logging for element count and damage presence per frame.
2026-04-07 18:26:07 +02:00
Till Wegmueller
8bd8f2490c Read pixels directly from pixman Image instead of ExportMem
ExportMem::copy_framebuffer may not capture composited client surfaces.
Read pixels directly from the pixman Image's CPU memory after rendering,
since PixmanRenderer composites in-place. This should fix missing
client windows in the remote display.
2026-04-07 18:16:05 +02:00
Till Wegmueller
564c473ab4 Wire end-to-end frame encoding and network into headless backend
Start QUIC server in wrsrvd main.rs before dispatching to backend,
passing NetworkHandle to the headless backend. The headless render loop
now encodes each frame as XOR diff against the previous frame, compresses
damage regions with zstd, and sends FrameUpdate messages to connected
clients via the network channel.

Network input from remote clients is drained each iteration of the main
event loop and injected into the compositor via inject_network_input().
Connection state (client connected/disconnected) is tracked to avoid
encoding frames when no client is listening.
2026-04-07 17:08:55 +02:00
Till Wegmueller
8a3d14ff19 Add headless backend with PixmanRenderer, refactor into backend modules
Restructure wrsrvd to support two backends: a headless PixmanRenderer
(default) for running without a display server, and the existing Winit
backend (via --backend winit). The render logic is split into per-backend
modules, and the old render.rs is removed.
2026-04-07 16:29:32 +02:00