mirror of
https://github.com/niri-wm/niri.git
synced 2026-06-23 02:05:33 +07:00
Implement window shadows
This commit is contained in:
@@ -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(),
|
||||
@@ -608,6 +612,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)]
|
||||
@@ -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),
|
||||
|
||||
Reference in New Issue
Block a user