Skip to content

Commit d1afd6e

Browse files
committed
commit
1 parent f30db16 commit d1afd6e

File tree

21 files changed

+1044
-17
lines changed

21 files changed

+1044
-17
lines changed

Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,13 @@ tracy-client = { version = "0.18.4", default-features = false }
3232
# version = "0.4.1"
3333
git = "https://github.com/Smithay/smithay.git"
3434
# path = "../smithay"
35+
rev = "fbbcd475743f96f67fcfc4b4b6a5120e822fcfe2"
3536
default-features = false
3637

3738
[workspace.dependencies.smithay-drm-extras]
3839
# version = "0.1.0"
3940
git = "https://github.com/Smithay/smithay.git"
41+
rev = "fbbcd475743f96f67fcfc4b4b6a5120e822fcfe2"
4042
# path = "../smithay/smithay-drm-extras"
4143

4244
[package]

niri-config/src/appearance.rs

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1006,6 +1006,101 @@ where
10061006
}
10071007
}
10081008

1009+
#[derive(Debug, Clone, Copy, PartialEq)]
1010+
pub struct Blur {
1011+
pub off: bool,
1012+
pub passes: u8,
1013+
pub offset: f64,
1014+
}
1015+
1016+
impl Default for Blur {
1017+
fn default() -> Self {
1018+
Self {
1019+
off: false,
1020+
// TODO: tune, reduce passes
1021+
passes: 3,
1022+
offset: 3.,
1023+
}
1024+
}
1025+
}
1026+
1027+
#[derive(knuffel::Decode, Debug, Default, Clone, Copy, PartialEq)]
1028+
pub struct BlurPart {
1029+
#[knuffel(child)]
1030+
pub off: bool,
1031+
#[knuffel(child)]
1032+
pub on: bool,
1033+
#[knuffel(child, unwrap(argument))]
1034+
pub passes: Option<u8>,
1035+
#[knuffel(child, unwrap(argument))]
1036+
pub offset: Option<FloatOrInt<0, 100>>,
1037+
}
1038+
1039+
impl MergeWith<BlurPart> for Blur {
1040+
fn merge_with(&mut self, part: &BlurPart) {
1041+
self.off |= part.off;
1042+
if part.on {
1043+
self.off = false;
1044+
}
1045+
1046+
merge_clone!((self, part), passes);
1047+
merge!((self, part), offset);
1048+
}
1049+
}
1050+
1051+
#[derive(knuffel::Decode, Debug, Default, Clone, Copy, PartialEq)]
1052+
pub struct BlurRule {
1053+
#[knuffel(child)]
1054+
pub off: bool,
1055+
#[knuffel(child)]
1056+
pub on: bool,
1057+
}
1058+
1059+
#[derive(knuffel::Decode, Debug, Default, Clone, Copy, PartialEq)]
1060+
pub struct BackgroundEffectRule {
1061+
#[knuffel(child, unwrap(argument))]
1062+
pub xray: Option<bool>,
1063+
#[knuffel(child, default)]
1064+
pub blur: BlurRule,
1065+
}
1066+
1067+
impl MergeWith<Self> for BackgroundEffectRule {
1068+
fn merge_with(&mut self, part: &Self) {
1069+
merge_clone_opt!((self, part), xray);
1070+
merge_on_off!((self.blur, part.blur));
1071+
}
1072+
}
1073+
1074+
/// Resolved background effect rule.
1075+
#[derive(Debug, Default, Clone, Copy, PartialEq)]
1076+
pub struct BackgroundEffect {
1077+
/// Whether to render with xray effect (see through).
1078+
pub xray: bool,
1079+
1080+
/// Whether to blur the background.
1081+
///
1082+
/// - `None`: blur when the window/layer requests it (e.g. through ext-background-effect
1083+
/// protocol)
1084+
/// - `Some(false)`: never blur
1085+
/// - `Some(true)`: always blur
1086+
pub blur: Option<bool>,
1087+
}
1088+
1089+
impl MergeWith<BackgroundEffectRule> for BackgroundEffect {
1090+
fn merge_with(&mut self, part: &BackgroundEffectRule) {
1091+
if let Some(x) = part.xray {
1092+
self.xray = x;
1093+
}
1094+
1095+
if part.blur.on {
1096+
self.blur = Some(true);
1097+
}
1098+
if part.blur.off {
1099+
self.blur = Some(false);
1100+
}
1101+
}
1102+
}
1103+
10091104
#[cfg(test)]
10101105
mod tests {
10111106
use insta::{assert_debug_snapshot, assert_snapshot};

niri-config/src/layer_rule.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::appearance::{BlockOutFrom, CornerRadius, ShadowRule};
1+
use crate::appearance::{BackgroundEffectRule, BlockOutFrom, CornerRadius, ShadowRule};
22
use crate::utils::RegexEq;
33

44
#[derive(knuffel::Decode, Debug, Default, Clone, PartialEq)]
@@ -20,6 +20,8 @@ pub struct LayerRule {
2020
pub place_within_backdrop: Option<bool>,
2121
#[knuffel(child, unwrap(argument))]
2222
pub baba_is_float: Option<bool>,
23+
#[knuffel(child, default)]
24+
pub background_effect: BackgroundEffectRule,
2325
}
2426

2527
#[derive(knuffel::Decode, Debug, Default, Clone, PartialEq)]

niri-config/src/lib.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ pub struct Config {
7878
pub hotkey_overlay: HotkeyOverlay,
7979
pub config_notification: ConfigNotification,
8080
pub animations: Animations,
81+
pub blur: Blur,
8182
pub gestures: Gestures,
8283
pub overview: Overview,
8384
pub environment: Environment,
@@ -194,6 +195,7 @@ where
194195
"hotkey-overlay" => m_merge!(hotkey_overlay),
195196
"config-notification" => m_merge!(config_notification),
196197
"animations" => m_merge!(animations),
198+
"blur" => m_merge!(blur),
197199
"gestures" => m_merge!(gestures),
198200
"overview" => m_merge!(overview),
199201
"xwayland-satellite" => m_merge!(xwayland_satellite),
@@ -1616,6 +1618,11 @@ mod tests {
16161618
},
16171619
),
16181620
},
1621+
blur: Blur {
1622+
off: false,
1623+
passes: 3,
1624+
offset: 3.0,
1625+
},
16191626
gestures: Gestures {
16201627
dnd_edge_view_scroll: DndEdgeViewScroll {
16211628
trigger_width: 10.0,
@@ -1845,6 +1852,13 @@ mod tests {
18451852
),
18461853
scroll_factor: None,
18471854
tiled_state: None,
1855+
background_effect: BackgroundEffectRule {
1856+
xray: None,
1857+
blur: BlurRule {
1858+
off: false,
1859+
on: false,
1860+
},
1861+
},
18481862
},
18491863
],
18501864
layer_rules: [
@@ -1879,6 +1893,13 @@ mod tests {
18791893
geometry_corner_radius: None,
18801894
place_within_backdrop: None,
18811895
baba_is_float: None,
1896+
background_effect: BackgroundEffectRule {
1897+
xray: None,
1898+
blur: BlurRule {
1899+
off: false,
1900+
on: false,
1901+
},
1902+
},
18821903
},
18831904
],
18841905
binds: Binds(

niri-config/src/window_rule.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use niri_ipc::ColumnDisplay;
22

3-
use crate::appearance::{BlockOutFrom, BorderRule, CornerRadius, ShadowRule, TabIndicatorRule};
3+
use crate::appearance::{
4+
BackgroundEffectRule, BlockOutFrom, BorderRule, CornerRadius, ShadowRule, TabIndicatorRule,
5+
};
46
use crate::layout::DefaultPresetSize;
57
use crate::utils::RegexEq;
68
use crate::FloatOrInt;
@@ -72,6 +74,8 @@ pub struct WindowRule {
7274
pub scroll_factor: Option<FloatOrInt<0, 100>>,
7375
#[knuffel(child, unwrap(argument))]
7476
pub tiled_state: Option<bool>,
77+
#[knuffel(child, default)]
78+
pub background_effect: BackgroundEffectRule,
7579
}
7680

7781
#[derive(knuffel::Decode, Debug, Default, Clone, PartialEq)]

src/layer/mapped.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@ use niri_config::{Config, LayerRule};
33
use smithay::backend::renderer::element::surface::WaylandSurfaceRenderElement;
44
use smithay::backend::renderer::element::Kind;
55
use smithay::desktop::{LayerSurface, PopupManager};
6-
use smithay::utils::{Logical, Point, Scale, Size};
6+
use smithay::utils::{Logical, Point, Rectangle, Scale, Size};
77
use smithay::wayland::shell::wlr_layer::{ExclusiveZone, Layer};
88

99
use super::ResolvedLayerRules;
1010
use crate::animation::Clock;
1111
use crate::layout::shadow::Shadow;
1212
use crate::niri_render_elements;
13+
use crate::render_helpers::background_effect::{BackgroundEffect, BackgroundEffectConfig};
1314
use crate::render_helpers::renderer::NiriRenderer;
1415
use crate::render_helpers::shadow::ShadowRenderElement;
1516
use crate::render_helpers::solid_color::{SolidColorBuffer, SolidColorRenderElement};
@@ -46,6 +47,7 @@ niri_render_elements! {
4647
Wayland = WaylandSurfaceRenderElement<R>,
4748
SolidColor = SolidColorRenderElement,
4849
Shadow = ShadowRenderElement,
50+
BackgroundEffect = BackgroundEffect,
4951
}
5052
}
5153

@@ -197,6 +199,24 @@ impl MappedLayer {
197199
let location = location.to_physical_precise_round(scale).to_logical(scale);
198200
self.shadow
199201
.render(renderer, location, &mut |elem| push(elem.into()));
202+
203+
// TODO subsurfaces peeking out of the main surface? Ext background effect subsurfaces?
204+
let effect = self.rules.background_effect;
205+
let effect = BackgroundEffectConfig {
206+
xray: effect.xray,
207+
// TODO: ext-background-effect
208+
blur: effect.blur == Some(true),
209+
};
210+
if effect.xray || effect.blur {
211+
let location = location.to_physical_precise_round(scale).to_logical(scale);
212+
let size = self.surface.geometry().size.to_f64();
213+
let size = size.to_physical_precise_round(scale).to_logical(scale);
214+
let area = Rectangle::new(location, size);
215+
let radius = self.rules.geometry_corner_radius.unwrap_or_default();
216+
217+
let elem = BackgroundEffect::new(area, radius, effect);
218+
push(elem.into());
219+
}
200220
}
201221

202222
pub fn render_popups<R: NiriRenderer>(

src/layer/mod.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use niri_config::layer_rule::{LayerRule, Match};
22
use niri_config::utils::MergeWith as _;
3-
use niri_config::{BlockOutFrom, CornerRadius, ShadowRule};
3+
use niri_config::{BackgroundEffect, BlockOutFrom, CornerRadius, ShadowRule};
44
use smithay::desktop::LayerSurface;
55

66
pub mod mapped;
@@ -26,6 +26,9 @@ pub struct ResolvedLayerRules {
2626

2727
/// Whether to bob this window up and down.
2828
pub baba_is_float: bool,
29+
30+
/// Background effect configuration.
31+
pub background_effect: BackgroundEffect,
2932
}
3033

3134
impl ResolvedLayerRules {
@@ -70,6 +73,10 @@ impl ResolvedLayerRules {
7073
}
7174

7275
resolved.shadow.merge_with(&rule.shadow);
76+
77+
resolved
78+
.background_effect
79+
.merge_with(&rule.background_effect);
7380
}
7481

7582
resolved

src/layout/tile.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use super::{
1818
use crate::animation::{Animation, Clock};
1919
use crate::layout::SizingMode;
2020
use crate::niri_render_elements;
21+
use crate::render_helpers::background_effect::{BackgroundEffect, BackgroundEffectConfig};
2122
use crate::render_helpers::border::BorderRenderElement;
2223
use crate::render_helpers::clipped_surface::{ClippedSurfaceRenderElement, RoundedCornerDamage};
2324
use crate::render_helpers::damage::ExtraDamage;
@@ -130,6 +131,7 @@ niri_render_elements! {
130131
ClippedSurface = ClippedSurfaceRenderElement<R>,
131132
Offscreen = OffscreenRenderElement,
132133
ExtraDamage = ExtraDamage,
134+
BackgroundEffect = BackgroundEffect,
133135
}
134136
}
135137

@@ -1283,6 +1285,18 @@ impl<W: LayoutElement> Tile<W> {
12831285
self.shadow
12841286
.render(renderer, location, &mut |elem| push(elem.into()));
12851287
}
1288+
1289+
// TODO subsurfaces peeking out of the main surface? Ext background effect subsurfaces?
1290+
let effect = rules.background_effect;
1291+
let effect = BackgroundEffectConfig {
1292+
xray: effect.xray,
1293+
// TODO: ext-background-effect
1294+
blur: effect.blur == Some(true),
1295+
};
1296+
if effect.xray || effect.blur {
1297+
let elem = BackgroundEffect::new(area, radius, effect);
1298+
push(elem.into());
1299+
}
12861300
}
12871301

12881302
pub fn render<R: NiriRenderer>(

0 commit comments

Comments
 (0)