diff options
| author | Ivan Molodetskikh <yalterz@gmail.com> | 2025-01-21 09:40:00 +0300 |
|---|---|---|
| committer | Ivan Molodetskikh <yalterz@gmail.com> | 2025-01-21 11:31:30 +0300 |
| commit | acd4cb51aa0e013bfec14444ee48a01c60ebaf8a (patch) | |
| tree | 8530bbe3697d4af8a6e6391e5be5997a4b68c6f4 /src/layer | |
| parent | 5ebcae997e672dcf0b9c73da383fa40f55a85fcc (diff) | |
| download | niri-acd4cb51aa0e013bfec14444ee48a01c60ebaf8a.tar.gz niri-acd4cb51aa0e013bfec14444ee48a01c60ebaf8a.tar.bz2 niri-acd4cb51aa0e013bfec14444ee48a01c60ebaf8a.zip | |
Implement shadows for layer surfaces
Diffstat (limited to 'src/layer')
| -rw-r--r-- | src/layer/mapped.rs | 37 | ||||
| -rw-r--r-- | src/layer/mod.rs | 24 |
2 files changed, 59 insertions, 2 deletions
diff --git a/src/layer/mapped.rs b/src/layer/mapped.rs index dfc09fe3..493bbc58 100644 --- a/src/layer/mapped.rs +++ b/src/layer/mapped.rs @@ -1,4 +1,5 @@ use niri_config::layer_rule::LayerRule; +use niri_config::Config; use smithay::backend::renderer::element::surface::{ render_elements_from_surface_tree, WaylandSurfaceRenderElement, }; @@ -7,8 +8,10 @@ use smithay::desktop::{LayerSurface, PopupManager}; use smithay::utils::{Logical, Point, Scale, Size}; use super::ResolvedLayerRules; +use crate::layout::shadow::Shadow; use crate::niri_render_elements; use crate::render_helpers::renderer::NiriRenderer; +use crate::render_helpers::shadow::ShadowRenderElement; use crate::render_helpers::solid_color::{SolidColorBuffer, SolidColorRenderElement}; use crate::render_helpers::{RenderTarget, SplitElements}; @@ -22,29 +25,56 @@ pub struct MappedLayer { /// Buffer to draw instead of the surface when it should be blocked out. block_out_buffer: SolidColorBuffer, + + /// The shadow around the surface. + shadow: Shadow, } niri_render_elements! { LayerSurfaceRenderElement<R> => { Wayland = WaylandSurfaceRenderElement<R>, SolidColor = SolidColorRenderElement, + Shadow = ShadowRenderElement, } } impl MappedLayer { - pub fn new(surface: LayerSurface, rules: ResolvedLayerRules) -> Self { + pub fn new(surface: LayerSurface, rules: ResolvedLayerRules, config: &Config) -> Self { + let mut shadow_config = config.layout.shadow; + // Shadows for layer surfaces need to be explicitly enabled. + shadow_config.on = false; + let shadow_config = rules.shadow.resolve_against(shadow_config); + Self { surface, rules, block_out_buffer: SolidColorBuffer::new((0., 0.), [0., 0., 0., 1.]), + shadow: Shadow::new(shadow_config), } } + pub fn update_config(&mut self, config: &Config) { + let mut shadow_config = config.layout.shadow; + // Shadows for layer surfaces need to be explicitly enabled. + shadow_config.on = false; + let shadow_config = self.rules.shadow.resolve_against(shadow_config); + self.shadow.update_config(shadow_config); + } + + pub fn update_shaders(&mut self) { + self.shadow.update_shaders(); + } + pub fn update_render_elements(&mut self, size: Size<f64, Logical>, scale: Scale<f64>) { // Round to physical pixels. let size = size.to_physical_precise_round(scale).to_logical(scale); self.block_out_buffer.resize(size); + + let radius = self.rules.geometry_corner_radius.unwrap_or_default(); + // FIXME: is_active based on keyboard focus? + self.shadow + .update_render_elements(size, true, radius, scale.x); } pub fn surface(&self) -> &LayerSurface { @@ -81,6 +111,7 @@ impl MappedLayer { // Round to physical pixels. let location = location.to_physical_precise_round(scale).to_logical(scale); + // FIXME: take geometry-corner-radius into account. let elem = SolidColorRenderElement::from_buffer( &self.block_out_buffer, location, @@ -117,6 +148,10 @@ impl MappedLayer { ); } + let location = location.to_physical_precise_round(scale).to_logical(scale); + rv.normal + .extend(self.shadow.render(renderer, location).map(Into::into)); + rv } } diff --git a/src/layer/mod.rs b/src/layer/mod.rs index 72e804d5..36e7ee67 100644 --- a/src/layer/mod.rs +++ b/src/layer/mod.rs @@ -1,5 +1,5 @@ use niri_config::layer_rule::{LayerRule, Match}; -use niri_config::BlockOutFrom; +use niri_config::{BlockOutFrom, CornerRadius, ShadowRule}; use smithay::desktop::LayerSurface; pub mod mapped; @@ -13,6 +13,12 @@ pub struct ResolvedLayerRules { /// Whether to block out this layer surface from certain render targets. pub block_out_from: Option<BlockOutFrom>, + + /// Shadow overrides. + pub shadow: ShadowRule, + + /// Corner radius to assume this layer surface has. + pub geometry_corner_radius: Option<CornerRadius>, } impl ResolvedLayerRules { @@ -20,6 +26,17 @@ impl ResolvedLayerRules { Self { opacity: None, block_out_from: None, + shadow: ShadowRule { + off: false, + on: false, + offset: None, + softness: None, + spread: None, + draw_behind_window: None, + color: None, + inactive_color: None, + }, + geometry_corner_radius: None, } } @@ -53,6 +70,11 @@ impl ResolvedLayerRules { if let Some(x) = rule.block_out_from { resolved.block_out_from = Some(x); } + if let Some(x) = rule.geometry_corner_radius { + resolved.geometry_corner_radius = Some(x); + } + + resolved.shadow.merge_with(&rule.shadow); } resolved |
