aboutsummaryrefslogtreecommitdiff
path: root/niri-config
diff options
context:
space:
mode:
authorIvan Molodetskikh <yalterz@gmail.com>2025-01-15 14:16:05 +0300
committerIvan Molodetskikh <yalterz@gmail.com>2025-01-17 23:10:01 +0300
commitbd559a26602874f4104e342e2ce02317ae1ae605 (patch)
tree5ba6d9d511f3ca1342a5874afdc33ecb3f93953f /niri-config
parentb4add625b2ffdad3e003b3e437891daacf53a12f (diff)
downloadniri-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.rs150
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),