srdusr
aboutsummaryrefslogtreecommitdiffstats
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/core/src/theme.rs23
-rw-r--r--crates/srdwm/src/main.rs1
-rw-r--r--crates/wayland/src/protocols/xdg_decoration.rs5
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);
});