Skip to content

Commit 1b51eaa

Browse files
committed
commit
1 parent f30db16 commit 1b51eaa

File tree

21 files changed

+1257
-17
lines changed

21 files changed

+1257
-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: 30 additions & 2 deletions
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::{self, BackgroundEffect, BackgroundEffectElement};
1314
use crate::render_helpers::renderer::NiriRenderer;
1415
use crate::render_helpers::shadow::ShadowRenderElement;
1516
use crate::render_helpers::solid_color::{SolidColorBuffer, SolidColorRenderElement};
@@ -31,6 +32,9 @@ pub struct MappedLayer {
3132
/// The shadow around the surface.
3233
shadow: Shadow,
3334

35+
/// The background effect underneath the layer surface geometry.
36+
pub background_effect: BackgroundEffect,
37+
3438
/// The view size for the layer surface's output.
3539
view_size: Size<f64, Logical>,
3640

@@ -46,6 +50,7 @@ niri_render_elements! {
4650
Wayland = WaylandSurfaceRenderElement<R>,
4751
SolidColor = SolidColorRenderElement,
4852
Shadow = ShadowRenderElement,
53+
BackgroundEffect = BackgroundEffectElement,
4954
}
5055
}
5156

@@ -70,6 +75,7 @@ impl MappedLayer {
7075
view_size,
7176
scale,
7277
shadow: Shadow::new(shadow_config),
78+
background_effect: BackgroundEffect::new(),
7379
clock,
7480
}
7581
}
@@ -91,7 +97,11 @@ impl MappedLayer {
9197
self.scale = scale;
9298
}
9399

94-
pub fn update_render_elements(&mut self, size: Size<f64, Logical>) {
100+
pub fn update_render_elements(
101+
&mut self,
102+
size: Size<f64, Logical>,
103+
view_rect: Rectangle<f64, Logical>,
104+
) {
95105
// Round to physical pixels.
96106
let size = size
97107
.to_physical_precise_round(self.scale)
@@ -103,6 +113,18 @@ impl MappedLayer {
103113
// FIXME: is_active based on keyboard focus?
104114
self.shadow
105115
.update_render_elements(size, true, radius, self.scale, 1.);
116+
117+
let effect = self.rules.background_effect;
118+
self.background_effect
119+
.update_params(background_effect::Parameters {
120+
view_rect_loc: view_rect.loc,
121+
scale: self.scale as f32,
122+
corner_radius: radius,
123+
xray: effect.xray,
124+
// TODO: ext-background-effect
125+
blur: effect.blur == Some(true),
126+
});
127+
self.background_effect.update_size(size);
106128
}
107129

108130
pub fn are_animations_ongoing(&self) -> bool {
@@ -197,6 +219,12 @@ impl MappedLayer {
197219
let location = location.to_physical_precise_round(scale).to_logical(scale);
198220
self.shadow
199221
.render(renderer, location, &mut |elem| push(elem.into()));
222+
223+
// TODO subsurfaces peeking out of the main surface? Ext background effect subsurfaces?
224+
if let Some(elem) = self.background_effect.render(renderer.as_gles_renderer()) {
225+
let location = location.to_physical_precise_round(scale).to_logical(scale);
226+
push(elem.with_location(location).into());
227+
}
200228
}
201229

202230
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

0 commit comments

Comments
 (0)