diff options
| author | srdusr <[email protected]> | 2026-07-16 16:21:00 +0200 |
|---|---|---|
| committer | srdusr <[email protected]> | 2026-07-16 16:21:00 +0200 |
| commit | a1f1135ec7054a5aaec545c24d4d95b45d8d8d75 (patch) | |
| tree | ce93d3c103516a91a5cfc093fc05c534c58b8b44 /crates | |
| parent | 0091bcd39406d88ceb075f03de4f3bfe12fed316 (diff) | |
| download | srdwm-a1f1135ec7054a5aaec545c24d4d95b45d8d8d75.tar.gz srdwm-a1f1135ec7054a5aaec545c24d4d95b45d8d8d75.zip | |
Never let a nested srdwm rewrite the real session's desktop config
My own testing changed the owner's GTK button style. Nested instances were
started with a scratch srdwm config, which naturally does not set
button_style, so the built-in default applied and publish_gtk_stylesheet
wrote traffic-light CSS into the real ~/.config/gtk-3.0/srdwm-buttons.css --
changing how every GTK app looked in the actual session, from a throwaway
compositor that was testing something unrelated. Their own config and the
running compositor both said "traditional" the whole time; only the
generated file disagreed, which is why it looked like the feature had
regressed.
Both publishers now return early when running nested, using the same test
srdwm_wayland::connect uses to choose the winit backend over udev/DRM: a
host WAYLAND_DISPLAY or DISPLAY means there is already a session and this
process is a window inside it. A nested instance is a test window, not the
shell, and has no business rewriting settings the real session is using.
Verified: with the guard in place a nested run leaves the file byte-identical
(md5 before and after), where before it would have rewritten it from the
default.
This is the same class of mistake as sending synthetic clicks to the wrong
compositor earlier - a test instance reaching outside its own sandbox --
and it wants a structural guard rather than remembering to set HOME.
533 tests pass, clippy clean.
Diffstat (limited to 'crates')
| -rw-r--r-- | crates/srdwm/src/main.rs | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/crates/srdwm/src/main.rs b/crates/srdwm/src/main.rs index 940db50..a0cfc39 100644 --- a/crates/srdwm/src/main.rs +++ b/crates/srdwm/src/main.rs @@ -126,6 +126,26 @@ const CONFIG_POLL_INTERVAL: std::time::Duration = std::time::Duration::from_secs /// not an error worth interrupting startup for. The compositor's own /// titlebars are already correct either way; this only brings the /// self-decorating clients into line. +/// True when this srdwm is running nested inside another compositor's +/// session rather than owning the machine's own. +/// +/// Same test `srdwm_wayland::connect` uses to pick the winit backend over +/// udev/DRM: a host `WAYLAND_DISPLAY` or `DISPLAY` means there is already a +/// session, and this process is a window inside it. +/// +/// Anything that writes to the *user's own desktop configuration* must be +/// gated on this. A nested instance is a test or development window; it is +/// not the shell, and it has no business rewriting the settings the real +/// session is using. Learned the hard way: nested runs started with a +/// scratch srdwm config, which naturally does not set `button_style`, took +/// the built-in default and wrote traffic-light CSS straight into the real +/// `~/.config/gtk-3.0/srdwm-buttons.css` - silently changing the look of +/// every GTK app in the actual session, from a throwaway compositor that +/// was testing something unrelated. +fn running_nested() -> bool { + std::env::var_os("WAYLAND_DISPLAY").is_some() || std::env::var_os("DISPLAY").is_some() +} + /// The stylesheet srdwm owns and rewrites, named so it is obvious in a /// directory listing which file is generated and which is the user's. const GTK_STYLE_FILE: &str = "srdwm-buttons.css"; @@ -186,6 +206,9 @@ fn gtk_button_css(traffic_lights: bool) -> String { /// Best-effort: a missing directory or an unwritable file is logged at /// debug and skipped. srdwm's own titlebars are already correct regardless. fn publish_gtk_stylesheet(wm: &Rc<RefCell<WindowManager>>) { + if running_nested() { + return; + } let Ok(home) = std::env::var("HOME") else { return }; let traffic_lights = wm.borrow().theme.traffic_light_buttons; let css = gtk_button_css(traffic_lights); @@ -216,6 +239,9 @@ fn publish_gtk_stylesheet(wm: &Rc<RefCell<WindowManager>>) { } fn publish_gtk_button_layout(wm: &Rc<RefCell<WindowManager>>) { + if running_nested() { + return; + } let layout = if wm.borrow().theme.buttons_left { "close,minimize,maximize:" } else { ":minimize,maximize,close" }; match std::process::Command::new("gsettings") .args(["set", "org.gnome.desktop.wm.preferences", "button-layout", layout]) |