aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Molodetskikh <yalterz@gmail.com>2023-09-26 13:44:37 +0400
committerIvan Molodetskikh <yalterz@gmail.com>2023-09-26 13:45:03 +0400
commit80928632ba38210242832e316b57e2e153da7efd (patch)
tree2ed62ffc89913f060dc4633b3f75aa7ff1740540
parentdc10e464ad3bd95007873875bf44e9280392e15a (diff)
downloadniri-80928632ba38210242832e316b57e2e153da7efd.tar.gz
niri-80928632ba38210242832e316b57e2e153da7efd.tar.bz2
niri-80928632ba38210242832e316b57e2e153da7efd.zip
Add prefer-no-csd option
-rw-r--r--resources/default-config.kdl4
-rw-r--r--src/config.rs5
-rw-r--r--src/handlers/xdg_shell.rs38
-rw-r--r--src/niri.rs4
4 files changed, 50 insertions, 1 deletions
diff --git a/resources/default-config.kdl b/resources/default-config.kdl
index 00e0bcaa..5ed8e7ce 100644
--- a/resources/default-config.kdl
+++ b/resources/default-config.kdl
@@ -56,6 +56,10 @@ focus-ring {
inactive-color 0.3 0.3 0.3 1.0
}
+// Uncomment this line to ask the clients to omit their client-side decorations if possible.
+// If the client will specifically ask for CSD, the request will be honored.
+// prefer-no-csd
+
binds {
// Keys consist of modifiers separated by + signs, followed by an XKB key name
// in the end. To find an XKB name for a particular key, you may use a program
diff --git a/src/config.rs b/src/config.rs
index aae77fde..91b4c2e1 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -19,6 +19,8 @@ pub struct Config {
#[knuffel(child, default)]
pub focus_ring: FocusRing,
#[knuffel(child, default)]
+ pub prefer_no_csd: bool,
+ #[knuffel(child, default)]
pub binds: Binds,
#[knuffel(child, default)]
pub debug: DebugConfig,
@@ -350,6 +352,8 @@ mod tests {
inactive-color 1.0 0.5 0.25 0.0
}
+ prefer-no-csd
+
binds {
Mod+T { spawn "alacritty"; }
Mod+Q { close-window; }
@@ -403,6 +407,7 @@ mod tests {
a: 0.,
},
},
+ prefer_no_csd: true,
binds: Binds(vec![
Bind {
key: Key {
diff --git a/src/handlers/xdg_shell.rs b/src/handlers/xdg_shell.rs
index b1dd9d4f..75b03add 100644
--- a/src/handlers/xdg_shell.rs
+++ b/src/handlers/xdg_shell.rs
@@ -1,16 +1,18 @@
-use smithay::delegate_xdg_shell;
use smithay::desktop::{find_popup_root_surface, PopupKind, Window};
use smithay::output::Output;
+use smithay::reexports::wayland_protocols::xdg::decoration::zv1::server::zxdg_toplevel_decoration_v1;
use smithay::reexports::wayland_protocols::xdg::shell::server::xdg_toplevel::{self, ResizeEdge};
use smithay::reexports::wayland_server::protocol::wl_output;
use smithay::reexports::wayland_server::protocol::wl_seat::WlSeat;
use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;
use smithay::utils::Serial;
use smithay::wayland::compositor::with_states;
+use smithay::wayland::shell::xdg::decoration::XdgDecorationHandler;
use smithay::wayland::shell::xdg::{
PopupSurface, PositionerState, ToplevelSurface, XdgPopupSurfaceData, XdgShellHandler,
XdgShellState, XdgToplevelSurfaceData,
};
+use smithay::{delegate_xdg_decoration, delegate_xdg_shell};
use crate::layout::{configure_new_window, output_size};
use crate::niri::State;
@@ -164,6 +166,40 @@ impl XdgShellHandler for State {
delegate_xdg_shell!(State);
+impl XdgDecorationHandler for State {
+ fn new_decoration(&mut self, toplevel: ToplevelSurface) {
+ let mode = if self.niri.config.borrow().prefer_no_csd {
+ Some(zxdg_toplevel_decoration_v1::Mode::ServerSide)
+ } else {
+ None
+ };
+ toplevel.with_pending_state(|state| {
+ state.decoration_mode = mode;
+ });
+ toplevel.send_configure();
+ }
+
+ fn request_mode(&mut self, toplevel: ToplevelSurface, mode: zxdg_toplevel_decoration_v1::Mode) {
+ toplevel.with_pending_state(|state| {
+ state.decoration_mode = Some(mode);
+ });
+ toplevel.send_configure();
+ }
+
+ fn unset_mode(&mut self, toplevel: ToplevelSurface) {
+ let mode = if self.niri.config.borrow().prefer_no_csd {
+ Some(zxdg_toplevel_decoration_v1::Mode::ServerSide)
+ } else {
+ None
+ };
+ toplevel.with_pending_state(|state| {
+ state.decoration_mode = mode;
+ });
+ toplevel.send_configure();
+ }
+}
+delegate_xdg_decoration!(State);
+
pub fn send_initial_configure_if_needed(window: &Window) {
let initial_configure_sent = with_states(window.toplevel().wl_surface(), |states| {
states
diff --git a/src/niri.rs b/src/niri.rs
index 58952a35..ea061bc3 100644
--- a/src/niri.rs
+++ b/src/niri.rs
@@ -54,6 +54,7 @@ use smithay::wayland::output::OutputManagerState;
use smithay::wayland::pointer_gestures::PointerGesturesState;
use smithay::wayland::presentation::PresentationState;
use smithay::wayland::shell::wlr_layer::{Layer, WlrLayerShellState};
+use smithay::wayland::shell::xdg::decoration::XdgDecorationState;
use smithay::wayland::shell::xdg::XdgShellState;
use smithay::wayland::shm::ShmState;
use smithay::wayland::socket::ListeningSocketSource;
@@ -94,6 +95,7 @@ pub struct Niri {
// Smithay state.
pub compositor_state: CompositorState,
pub xdg_shell_state: XdgShellState,
+ pub xdg_decoration_state: XdgDecorationState,
pub layer_shell_state: WlrLayerShellState,
pub shm_state: ShmState,
pub output_manager_state: OutputManagerState,
@@ -213,6 +215,7 @@ impl Niri {
&display_handle,
[WmCapabilities::Fullscreen],
);
+ let xdg_decoration_state = XdgDecorationState::new::<State>(&display_handle);
let layer_shell_state = WlrLayerShellState::new::<State>(&display_handle);
let shm_state = ShmState::new::<State>(&display_handle, vec![]);
let output_manager_state =
@@ -563,6 +566,7 @@ impl Niri {
compositor_state,
xdg_shell_state,
+ xdg_decoration_state,
layer_shell_state,
shm_state,
output_manager_state,