diff options
| author | Ivan Molodetskikh <yalterz@gmail.com> | 2025-01-15 14:16:05 +0300 |
|---|---|---|
| committer | Ivan Molodetskikh <yalterz@gmail.com> | 2025-01-17 23:10:01 +0300 |
| commit | bd559a26602874f4104e342e2ce02317ae1ae605 (patch) | |
| tree | 5ba6d9d511f3ca1342a5874afdc33ecb3f93953f /niri-config | |
| parent | b4add625b2ffdad3e003b3e437891daacf53a12f (diff) | |
| download | niri-bd559a26602874f4104e342e2ce02317ae1ae605.tar.gz niri-bd559a26602874f4104e342e2ce02317ae1ae605.tar.bz2 niri-bd559a26602874f4104e342e2ce02317ae1ae605.zip | |
Implement window shadows
Diffstat (limited to 'niri-config')
| -rw-r--r-- | niri-config/src/lib.rs | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/niri-config/src/lib.rs b/niri-config/src/lib.rs index 7ad013f4..167ef6ac 100644 --- a/niri-config/src/lib.rs +++ b/niri-config/src/lib.rs @@ -3,6 +3,7 @@ extern crate tracing; use std::collections::HashSet; use std::ffi::OsStr; +use std::ops::Mul; use std::path::{Path, PathBuf}; use std::str::FromStr; use std::time::Duration; @@ -436,6 +437,8 @@ pub struct Layout { #[knuffel(child, default)] pub border: Border, #[knuffel(child, default)] + pub shadow: Shadow, + #[knuffel(child, default)] pub insert_hint: InsertHint, #[knuffel(child, unwrap(children), default)] pub preset_column_widths: Vec<PresetSize>, @@ -460,6 +463,7 @@ impl Default for Layout { Self { focus_ring: Default::default(), border: Default::default(), + shadow: Default::default(), insert_hint: Default::default(), preset_column_widths: Default::default(), default_column_width: Default::default(), @@ -609,6 +613,49 @@ impl From<FocusRing> for Border { } #[derive(knuffel::Decode, Debug, Clone, Copy, PartialEq)] +pub struct Shadow { + #[knuffel(child)] + pub on: bool, + #[knuffel(child, default = Self::default().offset)] + pub offset: ShadowOffset, + #[knuffel(child, unwrap(argument), default = Self::default().softness)] + pub softness: FloatOrInt<0, 1024>, + #[knuffel(child, unwrap(argument), default = Self::default().spread)] + pub spread: FloatOrInt<0, 1024>, + #[knuffel(child, unwrap(argument), default = Self::default().draw_behind_window)] + pub draw_behind_window: bool, + #[knuffel(child, default = Self::default().color)] + pub color: Color, + #[knuffel(child)] + pub inactive_color: Option<Color>, +} + +impl Default for Shadow { + fn default() -> Self { + Self { + on: false, + offset: ShadowOffset { + x: FloatOrInt(0.), + y: FloatOrInt(5.), + }, + softness: FloatOrInt(30.), + spread: FloatOrInt(5.), + draw_behind_window: false, + color: Color::from_rgba8_unpremul(0, 0, 0, 0x70), + inactive_color: None, + } + } +} + +#[derive(knuffel::Decode, Debug, Clone, Copy, PartialEq)] +pub struct ShadowOffset { + #[knuffel(property, default)] + pub x: FloatOrInt<-65535, 65535>, + #[knuffel(property, default)] + pub y: FloatOrInt<-65535, 65535>, +} + +#[derive(knuffel::Decode, Debug, Clone, Copy, PartialEq)] pub struct InsertHint { #[knuffel(child)] pub off: bool, @@ -679,6 +726,15 @@ impl Color { } } +impl Mul<f32> for Color { + type Output = Self; + + fn mul(mut self, rhs: f32) -> Self::Output { + self.a *= rhs; + self + } +} + #[derive(knuffel::Decode, Debug, PartialEq)] pub struct Cursor { #[knuffel(child, unwrap(argument), default = String::from("default"))] @@ -1007,6 +1063,8 @@ pub struct WindowRule { pub focus_ring: BorderRule, #[knuffel(child, default)] pub border: BorderRule, + #[knuffel(child, default)] + pub shadow: ShadowRule, #[knuffel(child, unwrap(argument))] pub draw_border_with_background: Option<bool>, #[knuffel(child, unwrap(argument))] @@ -1084,6 +1142,26 @@ pub struct BorderRule { pub inactive_gradient: Option<Gradient>, } +#[derive(knuffel::Decode, Debug, Default, Clone, Copy, PartialEq)] +pub struct ShadowRule { + #[knuffel(child)] + pub off: bool, + #[knuffel(child)] + pub on: bool, + #[knuffel(child)] + pub offset: Option<ShadowOffset>, + #[knuffel(child, unwrap(argument))] + pub softness: Option<FloatOrInt<0, 1024>>, + #[knuffel(child, unwrap(argument))] + pub spread: Option<FloatOrInt<0, 1024>>, + #[knuffel(child, unwrap(argument))] + pub draw_behind_window: Option<bool>, + #[knuffel(child)] + pub color: Option<Color>, + #[knuffel(child)] + pub inactive_color: Option<Color>, +} + #[derive(knuffel::Decode, Debug, Clone, Copy, PartialEq)] pub struct FloatingPosition { #[knuffel(property)] @@ -1803,6 +1881,67 @@ impl BorderRule { } } +impl ShadowRule { + pub fn merge_with(&mut self, other: &Self) { + if other.off { + self.off = true; + self.on = false; + } + + if other.on { + self.off = false; + self.on = true; + } + + if let Some(x) = other.offset { + self.offset = Some(x); + } + if let Some(x) = other.softness { + self.softness = Some(x); + } + if let Some(x) = other.spread { + self.spread = Some(x); + } + if let Some(x) = other.draw_behind_window { + self.draw_behind_window = Some(x); + } + if let Some(x) = other.color { + self.color = Some(x); + } + if let Some(x) = other.inactive_color { + self.inactive_color = Some(x); + } + } + + pub fn resolve_against(&self, mut config: Shadow) -> Shadow { + config.on |= self.on; + if self.off { + config.on = false; + } + + if let Some(x) = self.offset { + config.offset = x; + } + if let Some(x) = self.softness { + config.softness = x; + } + if let Some(x) = self.spread { + config.spread = x; + } + if let Some(x) = self.draw_behind_window { + config.draw_behind_window = x; + } + if let Some(x) = self.color { + config.color = x; + } + if let Some(x) = self.inactive_color { + config.inactive_color = Some(x); + } + + config + } +} + impl CornerRadius { pub fn fit_to(self, width: f32, height: f32) -> Self { // Like in CSS: https://drafts.csswg.org/css-backgrounds/#corner-overlap @@ -3221,6 +3360,10 @@ mod tests { inactive-color "rgba(255, 200, 100, 0.0)" } + shadow { + offset x=10 y=-20 + } + preset-column-widths { proportion 0.25 proportion 0.5 @@ -3460,6 +3603,13 @@ mod tests { active_gradient: None, inactive_gradient: None, }, + shadow: Shadow { + offset: ShadowOffset { + x: FloatOrInt(10.), + y: FloatOrInt(-20.), + }, + ..Default::default() + }, insert_hint: InsertHint { off: false, color: Color::from_rgba8_unpremul(255, 200, 127, 255), |
