diff options
| author | srdusr <[email protected]> | 2024-04-02 01:07:00 +0200 |
|---|---|---|
| committer | srdusr <[email protected]> | 2024-04-02 01:07:00 +0200 |
| commit | 43175c78a5b450eb108738187b72e80d36a7bf5d (patch) | |
| tree | dbbadbcc18162f766f5af653d81882aaaa6f5e41 /crates/platform/src | |
| parent | 8110bb2773b6c841029a51eca7971f42a36f480c (diff) | |
| download | srdwm-43175c78a5b450eb108738187b72e80d36a7bf5d.tar.gz srdwm-43175c78a5b450eb108738187b72e80d36a7bf5d.zip | |
Add window rules, real config validation, and a Wayland DRM/udev backend
- 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.
Diffstat (limited to 'crates/platform/src')
| -rw-r--r-- | crates/platform/src/lib.rs | 61 |
1 files changed, 54 insertions, 7 deletions
diff --git a/crates/platform/src/lib.rs b/crates/platform/src/lib.rs index fdad291..23854e8 100644 --- a/crates/platform/src/lib.rs +++ b/crates/platform/src/lib.rs @@ -32,6 +32,14 @@ impl PlatformKind { /// Chooses a backend the way the legacy `PlatformFactory` did: prefer /// Wayland when a compositor is reachable, fall back to X11, otherwise use /// the compile-time native backend on Windows/macOS. +/// +/// X11 is only chosen when there's actual evidence of a running X server +/// (`DISPLAY` set) and no Wayland evidence - `srdwm_x11::X11Platform` +/// only ever *connects to* an existing server (Xephyr, or the real system +/// Xorg started separately), it never spawns one itself. Every other case, +/// including a bare TTY with neither env var set, resolves to Wayland: +/// `srdwm_wayland::connect` is the only backend that can run standalone +/// there, via its udev/DRM backend. pub fn detect() -> PlatformKind { #[cfg(target_os = "windows")] { @@ -43,13 +51,52 @@ pub fn detect() -> PlatformKind { } #[cfg(all(unix, not(target_os = "macos")))] { - let wayland = std::env::var_os("WAYLAND_DISPLAY").is_some() - || std::env::var("XDG_SESSION_TYPE").map(|v| v == "wayland").unwrap_or(false); - if wayland { - PlatformKind::Wayland - } else { - PlatformKind::X11 - } + detect_unix( + std::env::var_os("WAYLAND_DISPLAY").is_some(), + std::env::var("XDG_SESSION_TYPE").map(|v| v == "wayland").unwrap_or(false), + std::env::var_os("DISPLAY").is_some(), + ) + } +} + +/// The env-var decision logic behind [`detect`]'s unix branch, pulled out +/// as a pure function so it's testable without mutating real process env +/// vars (which would be racy across parallel test threads). +#[cfg(all(unix, not(target_os = "macos")))] +fn detect_unix(wayland_display: bool, xdg_session_type_wayland: bool, display: bool) -> PlatformKind { + let wayland_evidence = wayland_display || xdg_session_type_wayland; + if display && !wayland_evidence { + PlatformKind::X11 + } else { + PlatformKind::Wayland + } +} + +#[cfg(all(unix, not(target_os = "macos")))] +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn display_set_alone_picks_x11() { + assert_eq!(detect_unix(false, false, true), PlatformKind::X11); + } + + #[test] + fn bare_tty_with_nothing_set_picks_wayland() { + assert_eq!(detect_unix(false, false, false), PlatformKind::Wayland); + } + + #[test] + fn wayland_display_set_picks_wayland_even_if_display_also_set() { + // XWayland-style setups often have both DISPLAY and WAYLAND_DISPLAY + // set; Wayland should win. + assert_eq!(detect_unix(true, false, true), PlatformKind::Wayland); + } + + #[test] + fn xdg_session_type_wayland_picks_wayland() { + assert_eq!(detect_unix(false, true, false), PlatformKind::Wayland); } } |