Skip to content

Commit 30cc4e9

Browse files
committed
Add popups { opacity } window and layer rule
1 parent c5f8a70 commit 30cc4e9

File tree

7 files changed

+65
-6
lines changed

7 files changed

+65
-6
lines changed

niri-config/src/layer_rule.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::appearance::{BackgroundEffectRule, BlockOutFrom, CornerRadius, ShadowRule};
22
use crate::utils::RegexEq;
3+
use crate::window_rule::PopupsRule;
34

45
#[derive(knuffel::Decode, Debug, Default, Clone, PartialEq)]
56
pub struct LayerRule {
@@ -22,6 +23,8 @@ pub struct LayerRule {
2223
pub baba_is_float: Option<bool>,
2324
#[knuffel(child, default)]
2425
pub background_effect: BackgroundEffectRule,
26+
#[knuffel(child, default)]
27+
pub popups: PopupsRule,
2528
}
2629

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

niri-config/src/lib.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,9 @@ use crate::recent_windows::RecentWindowsPart;
5959
pub use crate::recent_windows::{MruDirection, MruFilter, MruPreviews, MruScope, RecentWindows};
6060
pub use crate::utils::FloatOrInt;
6161
use crate::utils::{Flag, MergeWith as _};
62-
pub use crate::window_rule::{FloatingPosition, RelativeTo, WindowRule};
62+
pub use crate::window_rule::{
63+
FloatingPosition, PopupsRule, RelativeTo, ResolvedPopupsRules, WindowRule,
64+
};
6365
pub use crate::workspace::{Workspace, WorkspaceLayoutPart};
6466

6567
const RECURSION_LIMIT: u8 = 10;
@@ -1860,6 +1862,9 @@ mod tests {
18601862
noise: None,
18611863
saturation: None,
18621864
},
1865+
popups: PopupsRule {
1866+
opacity: None,
1867+
},
18631868
},
18641869
],
18651870
layer_rules: [
@@ -1901,6 +1906,9 @@ mod tests {
19011906
noise: None,
19021907
saturation: None,
19031908
},
1909+
popups: PopupsRule {
1910+
opacity: None,
1911+
},
19041912
},
19051913
],
19061914
binds: Binds(

niri-config/src/window_rule.rs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::appearance::{
44
BackgroundEffectRule, BlockOutFrom, BorderRule, CornerRadius, ShadowRule, TabIndicatorRule,
55
};
66
use crate::layout::DefaultPresetSize;
7-
use crate::utils::RegexEq;
7+
use crate::utils::{MergeWith, RegexEq};
88
use crate::FloatOrInt;
99

1010
#[derive(knuffel::Decode, Debug, Default, Clone, PartialEq)]
@@ -76,6 +76,30 @@ pub struct WindowRule {
7676
pub tiled_state: Option<bool>,
7777
#[knuffel(child, default)]
7878
pub background_effect: BackgroundEffectRule,
79+
#[knuffel(child, default)]
80+
pub popups: PopupsRule,
81+
}
82+
83+
/// Rules for popup surfaces.
84+
#[derive(knuffel::Decode, Debug, Default, Clone, PartialEq)]
85+
pub struct PopupsRule {
86+
#[knuffel(child, unwrap(argument))]
87+
pub opacity: Option<f32>,
88+
}
89+
90+
/// Resolved popup-specific rules.
91+
#[derive(Debug, Default, Clone, Copy, PartialEq)]
92+
pub struct ResolvedPopupsRules {
93+
/// Extra opacity to draw popups with.
94+
pub opacity: Option<f32>,
95+
}
96+
97+
impl MergeWith<PopupsRule> for ResolvedPopupsRules {
98+
fn merge_with(&mut self, part: &PopupsRule) {
99+
if let Some(x) = part.opacity {
100+
self.opacity = Some(x);
101+
}
102+
}
79103
}
80104

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

src/layer/mapped.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use niri_config::utils::MergeWith as _;
22
use niri_config::{Config, LayerRule};
33
use smithay::backend::renderer::element::surface::WaylandSurfaceRenderElement;
44
use smithay::backend::renderer::element::Kind;
5-
use smithay::desktop::{LayerSurface, PopupManager};
5+
use smithay::desktop::{LayerSurface, PopupKind, PopupManager};
66
use smithay::utils::{Logical, Point, Rectangle, Scale, Size};
77
use smithay::wayland::compositor::{remove_pre_commit_hook, HookId};
88
use smithay::wayland::shell::wlr_layer::{ExclusiveZone, Layer};
@@ -270,6 +270,13 @@ impl MappedLayer {
270270

271271
let surface = self.surface.wl_surface();
272272
for (popup, offset) in PopupManager::popups_for_surface(surface) {
273+
let popup_rules = match popup {
274+
PopupKind::Xdg(_) => self.rules.popups,
275+
// IME popups aren't affected by rules for regular popups.
276+
PopupKind::InputMethod(_) => niri_config::ResolvedPopupsRules::default(),
277+
};
278+
let alpha = alpha * popup_rules.opacity.unwrap_or(1.).clamp(0., 1.);
279+
273280
let surface = popup.wl_surface();
274281
let surface_loc = location + (offset - popup.geometry().loc).to_f64();
275282

src/layer/mod.rs

Lines changed: 6 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::{BackgroundEffect, BlockOutFrom, CornerRadius, ShadowRule};
3+
use niri_config::{BackgroundEffect, BlockOutFrom, CornerRadius, ResolvedPopupsRules, ShadowRule};
44
use smithay::desktop::LayerSurface;
55
use smithay::wayland::shell::wlr_layer::Layer;
66

@@ -30,6 +30,9 @@ pub struct ResolvedLayerRules {
3030

3131
/// Background effect configuration.
3232
pub background_effect: BackgroundEffect,
33+
34+
/// Rules for this layer surface's popups.
35+
pub popups: ResolvedPopupsRules,
3336
}
3437

3538
impl ResolvedLayerRules {
@@ -78,6 +81,8 @@ impl ResolvedLayerRules {
7881
resolved
7982
.background_effect
8083
.merge_with(&rule.background_effect);
84+
85+
resolved.popups.merge_with(&rule.popups);
8186
}
8287

8388
resolved

src/window/mapped.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use smithay::backend::renderer::element::surface::WaylandSurfaceRenderElement;
66
use smithay::backend::renderer::element::Kind;
77
use smithay::backend::renderer::gles::GlesRenderer;
88
use smithay::desktop::space::SpaceElement as _;
9-
use smithay::desktop::{PopupManager, Window};
9+
use smithay::desktop::{PopupKind, PopupManager, Window};
1010
use smithay::output::{self, Output};
1111
use smithay::reexports::wayland_protocols::xdg::decoration::zv1::server::zxdg_toplevel_decoration_v1;
1212
use smithay::reexports::wayland_protocols::xdg::shell::server::xdg_toplevel;
@@ -670,6 +670,13 @@ impl LayoutElement for Mapped {
670670

671671
let surface = self.toplevel().wl_surface();
672672
for (popup, offset) in PopupManager::popups_for_surface(surface) {
673+
let popup_rules = match popup {
674+
PopupKind::Xdg(_) => self.rules.popups,
675+
// IME popups aren't affected by rules for regular popups.
676+
PopupKind::InputMethod(_) => niri_config::ResolvedPopupsRules::default(),
677+
};
678+
let alpha = alpha * popup_rules.opacity.unwrap_or(1.).clamp(0., 1.);
679+
673680
let surface = popup.wl_surface();
674681
let surface_loc = location + (offset - popup.geometry().loc).to_f64();
675682

src/window/mod.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use niri_config::utils::MergeWith as _;
44
use niri_config::window_rule::{Match, WindowRule};
55
use niri_config::{
66
BackgroundEffect, BlockOutFrom, BorderRule, CornerRadius, FloatingPosition, PresetSize,
7-
ShadowRule, TabIndicatorRule,
7+
ResolvedPopupsRules, ShadowRule, TabIndicatorRule,
88
};
99
use niri_ipc::ColumnDisplay;
1010
use smithay::reexports::wayland_protocols::xdg::shell::server::xdg_toplevel;
@@ -122,6 +122,9 @@ pub struct ResolvedWindowRules {
122122

123123
/// Background effect configuration.
124124
pub background_effect: BackgroundEffect,
125+
126+
/// Rules for this window's popups.
127+
pub popups: ResolvedPopupsRules,
125128
}
126129

127130
impl<'a> WindowRef<'a> {
@@ -303,6 +306,8 @@ impl ResolvedWindowRules {
303306
resolved
304307
.background_effect
305308
.merge_with(&rule.background_effect);
309+
310+
resolved.popups.merge_with(&rule.popups);
306311
}
307312

308313
resolved.open_on_output = open_on_output.map(|x| x.to_owned());

0 commit comments

Comments
 (0)