aboutsummaryrefslogtreecommitdiff
path: root/src/layer/mod.rs
diff options
context:
space:
mode:
authorIvan Molodetskikh <yalterz@gmail.com>2024-11-14 11:33:08 +0300
committerIvan Molodetskikh <yalterz@gmail.com>2024-11-14 12:05:30 +0300
commit1a0612cbfd0abee0796efa86470226686ae78f21 (patch)
tree809037c94948e0107614f5d01564712512468332 /src/layer/mod.rs
parentfbbd3ba349223f7cc4ebeaa397f7c48e880a7c30 (diff)
downloadniri-1a0612cbfd0abee0796efa86470226686ae78f21.tar.gz
niri-1a0612cbfd0abee0796efa86470226686ae78f21.tar.bz2
niri-1a0612cbfd0abee0796efa86470226686ae78f21.zip
Implement layer rules: opacity and block-out-from
Diffstat (limited to 'src/layer/mod.rs')
-rw-r--r--src/layer/mod.rs69
1 files changed, 69 insertions, 0 deletions
diff --git a/src/layer/mod.rs b/src/layer/mod.rs
new file mode 100644
index 00000000..4d4d7819
--- /dev/null
+++ b/src/layer/mod.rs
@@ -0,0 +1,69 @@
+use niri_config::layer_rule::{LayerRule, Match};
+use niri_config::BlockOutFrom;
+use smithay::desktop::LayerSurface;
+
+pub mod mapped;
+pub use mapped::MappedLayer;
+
+/// Rules fully resolved for a layer-shell surface.
+#[derive(Debug, PartialEq)]
+pub struct ResolvedLayerRules {
+ /// Extra opacity to draw this window with.
+ pub opacity: Option<f32>,
+ /// Whether to block out this window from certain render targets.
+ pub block_out_from: Option<BlockOutFrom>,
+}
+
+impl ResolvedLayerRules {
+ pub const fn empty() -> Self {
+ Self {
+ opacity: None,
+ block_out_from: None,
+ }
+ }
+
+ pub fn compute(rules: &[LayerRule], surface: &LayerSurface, is_at_startup: bool) -> Self {
+ let _span = tracy_client::span!("ResolvedLayerRules::compute");
+
+ let mut resolved = ResolvedLayerRules::empty();
+
+ for rule in rules {
+ let matches = |m: &Match| {
+ if let Some(at_startup) = m.at_startup {
+ if at_startup != is_at_startup {
+ return false;
+ }
+ }
+
+ surface_matches(surface, m)
+ };
+
+ if !(rule.matches.is_empty() || rule.matches.iter().any(matches)) {
+ continue;
+ }
+
+ if rule.excludes.iter().any(matches) {
+ continue;
+ }
+
+ if let Some(x) = rule.opacity {
+ resolved.opacity = Some(x);
+ }
+ if let Some(x) = rule.block_out_from {
+ resolved.block_out_from = Some(x);
+ }
+ }
+
+ resolved
+ }
+}
+
+fn surface_matches(surface: &LayerSurface, m: &Match) -> bool {
+ if let Some(namespace_re) = &m.namespace {
+ if !namespace_re.0.is_match(surface.namespace()) {
+ return false;
+ }
+ }
+
+ true
+}