diff options
Diffstat (limited to 'crates')
| -rw-r--r-- | crates/core/src/theme.rs | 23 | ||||
| -rw-r--r-- | crates/srdwm/src/main.rs | 1 | ||||
| -rw-r--r-- | crates/wayland/src/protocols/xdg_decoration.rs | 5 |
3 files changed, 29 insertions, 0 deletions
diff --git a/crates/core/src/theme.rs b/crates/core/src/theme.rs index 026688a..649ec64 100644 --- a/crates/core/src/theme.rs +++ b/crates/core/src/theme.rs @@ -175,6 +175,28 @@ pub struct ThemeConfig { /// Asked for as titlebars able to use "decorations/buttons of the /// program/dynamic". pub dynamic_buttons: bool, + /// Enforce server-side decoration on every client that negotiates it, + /// instead of honouring what the client asked for. + /// + /// `xdg-decoration` explicitly allows this: "The compositor can decide + /// not to use the client's mode and enforce a different mode instead", + /// and "the specified mode must be obeyed by the client". So a toolkit + /// that asks for client-side - winit does, measured - can be given + /// srdwm's titlebar anyway, which is what makes every negotiating + /// window look the same. + /// + /// Off by default, because it cannot help the case it looks like it + /// should. A client that never creates a decoration object at all is + /// outside the protocol: "if compositor and client do not negotiate + /// the use of a server-side decoration ... clients continue to + /// self-decorate as they see fit". GTK is exactly that client - it + /// creates no decoration object, measured directly - so forcing this + /// on cannot move a single GTK button, while it *can* stack srdwm's + /// titlebar on top of a client that draws its own regardless (the + /// Firefox case this project already hit once). Turn it on to make + /// negotiating toolkits uniform; use `rules.lua`'s `decorated = false` + /// for the ones that draw their own anyway. + pub force_server_side: bool, } impl Default for ThemeConfig { @@ -194,6 +216,7 @@ impl Default for ThemeConfig { button_glyph_always: false, traffic_light_buttons: true, dynamic_buttons: true, + force_server_side: false, } } } diff --git a/crates/srdwm/src/main.rs b/crates/srdwm/src/main.rs index 6c2f04b..9772e65 100644 --- a/crates/srdwm/src/main.rs +++ b/crates/srdwm/src/main.rs @@ -321,6 +321,7 @@ fn apply_general_settings(engine: &Engine, wm: &Rc<RefCell<WindowManager>>) { // "dynamic" (default: only the buttons the window can actually use) or // "fixed" (always the full set) - see `ThemeConfig::dynamic_buttons`. theme.dynamic_buttons = engine.get_string("theme.decorations.title_bar.button_mode", "dynamic") != "fixed"; + theme.force_server_side = engine.get_bool("theme.decorations.force_server_side", false); let border_width = engine.get_f64("theme.decorations.border.width", 2.0).max(0.0) as u32; theme.default_border_width = border_width; // 12, not the original 6: matches real macOS's own ~0.36 radius-to- diff --git a/crates/wayland/src/protocols/xdg_decoration.rs b/crates/wayland/src/protocols/xdg_decoration.rs index 25973c0..c3c7f0b 100644 --- a/crates/wayland/src/protocols/xdg_decoration.rs +++ b/crates/wayland/src/protocols/xdg_decoration.rs @@ -37,7 +37,12 @@ impl XdgDecorationHandler for CompState { /// the way for exactly those clients, while everything that accepts /// (or has no preference and gets offered) server-side still gets our /// titlebar as before. + /// `theme.decorations.force_server_side` overrides the client's request + /// - see `ThemeConfig::force_server_side` for why that is allowed and + /// why it is off by default. fn request_mode(&mut self, toplevel: ToplevelSurface, mode: DecorationMode) { + let forced = self.wm.borrow().theme.force_server_side; + let mode = if forced { DecorationMode::ServerSide } else { mode }; toplevel.with_pending_state(|state| { state.decoration_mode = Some(mode); }); |