mirror of
https://github.com/niri-wm/niri.git
synced 2026-06-21 02:01:55 +07:00
Add popups { opacity } window and layer rule
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
use crate::appearance::{BackgroundEffectRule, BlockOutFrom, CornerRadius, ShadowRule};
|
||||
use crate::utils::RegexEq;
|
||||
use crate::window_rule::PopupsRule;
|
||||
|
||||
#[derive(knuffel::Decode, Debug, Default, Clone, PartialEq)]
|
||||
pub struct LayerRule {
|
||||
@@ -22,6 +23,8 @@ pub struct LayerRule {
|
||||
pub baba_is_float: Option<bool>,
|
||||
#[knuffel(child, default)]
|
||||
pub background_effect: BackgroundEffectRule,
|
||||
#[knuffel(child, default)]
|
||||
pub popups: PopupsRule,
|
||||
}
|
||||
|
||||
#[derive(knuffel::Decode, Debug, Default, Clone, PartialEq)]
|
||||
|
||||
@@ -59,7 +59,9 @@ use crate::recent_windows::RecentWindowsPart;
|
||||
pub use crate::recent_windows::{MruDirection, MruFilter, MruPreviews, MruScope, RecentWindows};
|
||||
pub use crate::utils::FloatOrInt;
|
||||
use crate::utils::{Flag, MergeWith as _};
|
||||
pub use crate::window_rule::{FloatingPosition, RelativeTo, WindowRule};
|
||||
pub use crate::window_rule::{
|
||||
FloatingPosition, PopupsRule, RelativeTo, ResolvedPopupsRules, WindowRule,
|
||||
};
|
||||
pub use crate::workspace::{Workspace, WorkspaceLayoutPart};
|
||||
|
||||
const RECURSION_LIMIT: u8 = 10;
|
||||
@@ -1860,6 +1862,9 @@ mod tests {
|
||||
noise: None,
|
||||
saturation: None,
|
||||
},
|
||||
popups: PopupsRule {
|
||||
opacity: None,
|
||||
},
|
||||
},
|
||||
],
|
||||
layer_rules: [
|
||||
@@ -1901,6 +1906,9 @@ mod tests {
|
||||
noise: None,
|
||||
saturation: None,
|
||||
},
|
||||
popups: PopupsRule {
|
||||
opacity: None,
|
||||
},
|
||||
},
|
||||
],
|
||||
binds: Binds(
|
||||
|
||||
@@ -4,7 +4,7 @@ use crate::appearance::{
|
||||
BackgroundEffectRule, BlockOutFrom, BorderRule, CornerRadius, ShadowRule, TabIndicatorRule,
|
||||
};
|
||||
use crate::layout::DefaultPresetSize;
|
||||
use crate::utils::RegexEq;
|
||||
use crate::utils::{MergeWith, RegexEq};
|
||||
use crate::FloatOrInt;
|
||||
|
||||
#[derive(knuffel::Decode, Debug, Default, Clone, PartialEq)]
|
||||
@@ -76,6 +76,30 @@ pub struct WindowRule {
|
||||
pub tiled_state: Option<bool>,
|
||||
#[knuffel(child, default)]
|
||||
pub background_effect: BackgroundEffectRule,
|
||||
#[knuffel(child, default)]
|
||||
pub popups: PopupsRule,
|
||||
}
|
||||
|
||||
/// Rules for popup surfaces.
|
||||
#[derive(knuffel::Decode, Debug, Default, Clone, PartialEq)]
|
||||
pub struct PopupsRule {
|
||||
#[knuffel(child, unwrap(argument))]
|
||||
pub opacity: Option<f32>,
|
||||
}
|
||||
|
||||
/// Resolved popup-specific rules.
|
||||
#[derive(Debug, Default, Clone, Copy, PartialEq)]
|
||||
pub struct ResolvedPopupsRules {
|
||||
/// Extra opacity to draw popups with.
|
||||
pub opacity: Option<f32>,
|
||||
}
|
||||
|
||||
impl MergeWith<PopupsRule> for ResolvedPopupsRules {
|
||||
fn merge_with(&mut self, part: &PopupsRule) {
|
||||
if let Some(x) = part.opacity {
|
||||
self.opacity = Some(x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(knuffel::Decode, Debug, Default, Clone, PartialEq)]
|
||||
|
||||
+8
-1
@@ -2,7 +2,7 @@ use niri_config::utils::MergeWith as _;
|
||||
use niri_config::{Config, LayerRule};
|
||||
use smithay::backend::renderer::element::surface::WaylandSurfaceRenderElement;
|
||||
use smithay::backend::renderer::element::Kind;
|
||||
use smithay::desktop::{LayerSurface, PopupManager};
|
||||
use smithay::desktop::{LayerSurface, PopupKind, PopupManager};
|
||||
use smithay::utils::{Logical, Point, Rectangle, Scale, Size};
|
||||
use smithay::wayland::compositor::{remove_pre_commit_hook, HookId};
|
||||
use smithay::wayland::shell::wlr_layer::{ExclusiveZone, Layer};
|
||||
@@ -275,6 +275,13 @@ impl MappedLayer {
|
||||
|
||||
let surface = self.surface.wl_surface();
|
||||
for (popup, offset) in PopupManager::popups_for_surface(surface) {
|
||||
let popup_rules = match popup {
|
||||
PopupKind::Xdg(_) => self.rules.popups,
|
||||
// IME popups aren't affected by rules for regular popups.
|
||||
PopupKind::InputMethod(_) => niri_config::ResolvedPopupsRules::default(),
|
||||
};
|
||||
let alpha = alpha * popup_rules.opacity.unwrap_or(1.).clamp(0., 1.);
|
||||
|
||||
let surface = popup.wl_surface();
|
||||
let popup_geo = popup.geometry();
|
||||
let surface_loc = location + (offset - popup_geo.loc).to_f64();
|
||||
|
||||
+6
-1
@@ -1,6 +1,6 @@
|
||||
use niri_config::layer_rule::{LayerRule, Match};
|
||||
use niri_config::utils::MergeWith as _;
|
||||
use niri_config::{BackgroundEffect, BlockOutFrom, CornerRadius, ShadowRule};
|
||||
use niri_config::{BackgroundEffect, BlockOutFrom, CornerRadius, ResolvedPopupsRules, ShadowRule};
|
||||
use smithay::desktop::LayerSurface;
|
||||
use smithay::wayland::shell::wlr_layer::Layer;
|
||||
|
||||
@@ -30,6 +30,9 @@ pub struct ResolvedLayerRules {
|
||||
|
||||
/// Background effect configuration.
|
||||
pub background_effect: BackgroundEffect,
|
||||
|
||||
/// Rules for this layer surface's popups.
|
||||
pub popups: ResolvedPopupsRules,
|
||||
}
|
||||
|
||||
impl ResolvedLayerRules {
|
||||
@@ -78,6 +81,8 @@ impl ResolvedLayerRules {
|
||||
resolved
|
||||
.background_effect
|
||||
.merge_with(&rule.background_effect);
|
||||
|
||||
resolved.popups.merge_with(&rule.popups);
|
||||
}
|
||||
|
||||
resolved
|
||||
|
||||
@@ -6,7 +6,7 @@ use smithay::backend::renderer::element::surface::WaylandSurfaceRenderElement;
|
||||
use smithay::backend::renderer::element::Kind;
|
||||
use smithay::backend::renderer::gles::GlesRenderer;
|
||||
use smithay::desktop::space::SpaceElement as _;
|
||||
use smithay::desktop::{PopupManager, Window};
|
||||
use smithay::desktop::{PopupKind, PopupManager, Window};
|
||||
use smithay::output::{self, Output};
|
||||
use smithay::reexports::wayland_protocols::xdg::decoration::zv1::server::zxdg_toplevel_decoration_v1;
|
||||
use smithay::reexports::wayland_protocols::xdg::shell::server::xdg_toplevel;
|
||||
@@ -669,6 +669,13 @@ impl LayoutElement for Mapped {
|
||||
|
||||
let surface = self.toplevel().wl_surface();
|
||||
for (popup, offset) in PopupManager::popups_for_surface(surface) {
|
||||
let popup_rules = match popup {
|
||||
PopupKind::Xdg(_) => self.rules.popups,
|
||||
// IME popups aren't affected by rules for regular popups.
|
||||
PopupKind::InputMethod(_) => niri_config::ResolvedPopupsRules::default(),
|
||||
};
|
||||
let alpha = alpha * popup_rules.opacity.unwrap_or(1.).clamp(0., 1.);
|
||||
|
||||
let surface = popup.wl_surface();
|
||||
let popup_geo = popup.geometry();
|
||||
let surface_loc = location + (offset - popup.geometry().loc).to_f64();
|
||||
|
||||
+6
-1
@@ -4,7 +4,7 @@ use niri_config::utils::MergeWith as _;
|
||||
use niri_config::window_rule::{Match, WindowRule};
|
||||
use niri_config::{
|
||||
BackgroundEffect, BlockOutFrom, BorderRule, CornerRadius, FloatingPosition, PresetSize,
|
||||
ShadowRule, TabIndicatorRule,
|
||||
ResolvedPopupsRules, ShadowRule, TabIndicatorRule,
|
||||
};
|
||||
use niri_ipc::ColumnDisplay;
|
||||
use smithay::reexports::wayland_protocols::xdg::shell::server::xdg_toplevel;
|
||||
@@ -122,6 +122,9 @@ pub struct ResolvedWindowRules {
|
||||
|
||||
/// Background effect configuration.
|
||||
pub background_effect: BackgroundEffect,
|
||||
|
||||
/// Rules for this window's popups.
|
||||
pub popups: ResolvedPopupsRules,
|
||||
}
|
||||
|
||||
impl<'a> WindowRef<'a> {
|
||||
@@ -303,6 +306,8 @@ impl ResolvedWindowRules {
|
||||
resolved
|
||||
.background_effect
|
||||
.merge_with(&rule.background_effect);
|
||||
|
||||
resolved.popups.merge_with(&rule.popups);
|
||||
}
|
||||
|
||||
resolved.open_on_output = open_on_output.map(|x| x.to_owned());
|
||||
|
||||
Reference in New Issue
Block a user