| Age | Commit message (Collapse) | Author | Files | Lines |
|
Implements the protocols that were blocking srdwm-wayland from being a real
session, plus multi-monitor, and splits the backend into modules. Everything
here was verified by running it against real clients, not just compiled.
Protocols
- wlr-layer-shell + xdg-output: bars/launchers/notifications. xdg-output is
not optional in practice - without it wofi segfaults rather than
degrading, since it calls get_xdg_output without null-checking.
- Clipboard: wl_data_device_manager, primary selection, and wlr-data-control.
Data-control is what `wl-paste --watch cliphist store` needs, as it reads
the selection without holding focus. Selection focus now follows keyboard
focus, without which a focused window can neither copy nor paste.
- ext-session-lock: `locked` gates rendering and input. No key is treated as
a WM binding while locked - the config binds Mod4+Return to spawn a
terminal, so honouring bindings at a locked screen would defeat the lock.
The lock is confirmed only after a client-content-free frame has actually
been presented, never at request time.
- wlr-screencopy (hand-written; smithay ships no helper) for grim/slurp.
Multi-monitor
Every connected connector becomes a head with its own buffers, damage
tracker and page-flip state, matched by CRTC so differing refresh rates
don't gate each other. Outputs are reached through primary_output/output_at/
output_for_wl rather than a single field, which kept the change to ~11 call
sites. Session lock creates one lock surface per output and waits for all of
them, so a second monitor can't still show the desktop when the locker is
told the session is safe. Modes are picked by the PREFERRED flag, not list
order, and CRTCs are never double-assigned.
Bugs found by testing, not review
- Nothing gave a newly-created window Wayland focus: a freshly-opened app
received no keystrokes and could not paste until clicked.
- Opening a window at a locked screen stole keyboard focus. Caught by
counting wl_keyboard.enter delivered to a client launched while locked:
1 before the guard, 0 after. A killed locker correctly leaves it locked.
- Reading back the winit EGL window surface destroyed the GL context on the
first screencopy capture, taking the compositor down. Root-caused by
A/B-ing the same build with only the readback removed; capture now renders
an offscreen pass.
- Output mode was resent every frame at 60Hz, flooding any client bound to
wl_output with duplicate mode/done events.
- general.default_layout was defaulted and validated but never read, so
setting it did nothing. srdwm is dynamic-first (Windows/macOS style, with
drag-to-edge snapping); tiling is one opt-in layout, and that stays true.
- .gitignore's unanchored `srdwm` matched any path component of that name,
silently excluding the whole crates/srdwm source crate - the binary crate
the workspace lists as a member, so a fresh clone could not build.
Modularization
lib.rs went from ~1260 lines to 78: state, protocols, input, lock,
screencopy, winit and udev now each own one responsibility. lock is grouped
by feature rather than kind on purpose, since its security invariant spans
state, protocol handling and rendering at once.
Multi-monitor was verified in the QEMU VM with a two-output virtio-gpu: both
heads screendumped at their own resolution showing srdwm's clear colour, and
a window forced to global x=1500 landed on head 1 at head-local x=220 while
head 0 stayed empty. Known limitation, now documented: the nested winit
backend stalls while its window is occluded, because the host stops
scheduling frames and eglSwapBuffers blocks.
|
|
layer-shell, clipboard (wl_data_device_manager), session-lock, and
udev-backend multi-monitor support are the gaps identified when deciding
srdwm isn't ready to add to a session picker yet - recorded in
docs/IMPLEMENTATION_STATUS.md's "Not implemented anywhere yet" section
and as inline TODOs at the relevant code (CompState's delegate_*! list,
udev.rs's find_connected_output).
|
|
Three real bugs found and fixed via WAYLAND_DEBUG=1 protocol tracing in
the QEMU VM, plus a fourth found along the way:
- XWayland tried glamor (GBM rendering) first, which fails against this
deliberately software-only compositor; its post-failure fallback path
never used the xwayland_shell_v1 protocol at all, so X11Surface::
wl_surface() never resolved. Fixed by shadowing `Xwayland` on PATH with
a wrapper script that always re-execs it with -shm (smithay's
XWayland::spawn hardcodes its own argv and can't be bypassed either,
since XWaylandClientData's fields are private).
- Even with -shm, set_mapped(true) was only called after wl_surface()
already resolved, deadlocking XWayland (it never advances a window past
surface creation until the map is granted). Fixed by calling
set_mapped(true) unconditionally in map_window_request.
- The window then rendered as a ~1px sliver: initial geometry was seeded
from X11Surface::geometry(), which can still be a tiny default at
MapRequest time. Fixed by using the same 800x600 default the xdg-shell
path already uses.
- Typing didn't reach the window until a broader, XWayland-independent
bug was fixed: nothing in the Wayland backend ever called
KeyboardHandle::set_focus, so no window (native or X11) could ever
receive keyboard input. Fixed in handle_pointer_button, along with
TitlebarHit::Close being X11-surface-blind.
Verified live: xterm launched via XWayland renders correctly sized and
decorated, and a synthetic keypress sequence (ls + Enter) executed in its
shell, screendump-confirmed.
|
|
- srd.rule(): match windows by title/class, apply floating/maximized/
workspace/geometry/decoration actions on creation (crates/core/src/rules.rs)
- srd.validate_config()/srd.debug.*: real range/format checks and
status/profiling helpers, replacing the always-true stub
- Wayland titlebar text rendering via fontdue, unit-tested without a
display (crates/wayland/src/decoration.rs)
- Wayland precise keybinding matching, replacing the "any Super-held key"
heuristic, sharing the keysym table with X11 (moved to
crates/core/src/keysyms.rs)
- Wayland DRM/udev backend (crates/wayland/src/udev.rs): runs as the real
compositor on a bare TTY via libseat/libinput/KMS, software rendering
via Pixman + dumb buffers (no GBM/EGL required)
- srdwm_platform::detect() fix, found via VM testing: a bare TTY with no
DISPLAY/WAYLAND_DISPLAY now correctly resolves to Wayland instead of an
X11 backend that can never work there
- XWayland integration groundwork (crates/wayland/src/xwayland.rs): spawn,
X11Wm, and full XwmHandler event routing into the same WindowManager/
Space pipeline as native clients. Windows don't render yet - a real
glamor-vs-software-renderer conflict in XWayland's own fallback path,
root-caused via WAYLAND_DEBUG tracing and documented in
docs/IMPLEMENTATION_STATUS.md rather than worked around blind.
All verified live in an isolated QEMU VM: X11 backend shows two
decorated, correctly-tiled xterms with real title text; the DRM/udev
Wayland backend opens the GPU, initializes input, and scans out a
rendered frame via KMS page-flip.
|
|
The C++ prototype (moved to legacy-cpp/) was mostly a design skeleton:
X11 and Windows backends were partially real, Wayland created the
wlroots object graph but never wired a single event listener, macOS
was stub except monitor enumeration, and the Lua engine's srd.bind()
stored a key-combo string but never the actual closure. See
docs/PRIOR_ART.md for the full audit.
This replaces it with a Cargo workspace:
- srdwm-core: platform-independent window/workspace/monitor state,
a real master-stack tiling layout, and SmartPlacement grid/cascade/
snap-to-edge placement - fixing several bugs in the C++ version
(hardcoded 2-column grid, cascade that never cascaded, snap-to-edge
that always returned a fixed rect). 35 unit tests.
- srdwm-config: the srd Lua API via mlua, implementing the surface
docs/DEFAULTS.md always documented but the C++ engine never actually
built (srd.window.close()/focus(direction), srd.workspace.next(),
real keybinding closures, require("srd") support). 10 unit tests.
- srdwm-x11: a real reparenting WM with a drawn title bar (buttons,
drag, resize), verified live under Xephyr - frame placement and
client offset match srdwm-core's computed geometry exactly, and the
decoration renders correctly on screen.
- srdwm-wayland: a from-scratch smithay compositor (the C++ version
had nothing working to port from) - runs via the winit backend,
tracks xdg-shell toplevels through the same WindowManager and
hit-testing code X11 uses, verified to start/render/run without
crashing. Decorations are solid-color (no text yet); see
docs/IMPLEMENTATION_STATUS.md for exact scope.
- srdwm-windows / srdwm-macos: structured, cfg-gated designs informed
by komorebi/glazewm and yabai/AeroSpace respectively (see
docs/PRIOR_ART.md), honestly marked as unbuilt/unverified since this
sandbox has no Windows or macOS target.
|
|
|