srdusr
aboutsummaryrefslogtreecommitdiffstats
path: root/crates/platform
diff options
context:
space:
mode:
authorsrdusr <[email protected]>2024-04-02 01:07:00 +0200
committersrdusr <[email protected]>2024-04-02 01:07:00 +0200
commit43175c78a5b450eb108738187b72e80d36a7bf5d (patch)
treedbbadbcc18162f766f5af653d81882aaaa6f5e41 /crates/platform
parent8110bb2773b6c841029a51eca7971f42a36f480c (diff)
downloadsrdwm-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')
-rw-r--r--crates/platform/src/lib.rs61
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);
}
}