aboutsummaryrefslogtreecommitdiff
path: root/src/layout/tile.rs
diff options
context:
space:
mode:
authorIvan Molodetskikh <yalterz@gmail.com>2025-01-15 14:16:05 +0300
committerIvan Molodetskikh <yalterz@gmail.com>2025-01-17 23:10:01 +0300
commitbd559a26602874f4104e342e2ce02317ae1ae605 (patch)
tree5ba6d9d511f3ca1342a5874afdc33ecb3f93953f /src/layout/tile.rs
parentb4add625b2ffdad3e003b3e437891daacf53a12f (diff)
downloadniri-bd559a26602874f4104e342e2ce02317ae1ae605.tar.gz
niri-bd559a26602874f4104e342e2ce02317ae1ae605.tar.bz2
niri-bd559a26602874f4104e342e2ce02317ae1ae605.zip
Implement window shadows
Diffstat (limited to 'src/layout/tile.rs')
-rw-r--r--src/layout/tile.rs40
1 files changed, 32 insertions, 8 deletions
diff --git a/src/layout/tile.rs b/src/layout/tile.rs
index 9cc5237e..a9fd8e13 100644
--- a/src/layout/tile.rs
+++ b/src/layout/tile.rs
@@ -8,6 +8,7 @@ use smithay::utils::{Logical, Point, Rectangle, Scale, Size, Transform};
use super::focus_ring::{FocusRing, FocusRingRenderElement};
use super::opening_window::{OpenAnimation, OpeningWindowRenderElement};
+use super::shadow::Shadow;
use super::{
LayoutElement, LayoutElementRenderElement, LayoutElementRenderSnapshot, Options, SizeFrac,
RESIZE_ANIMATION_THRESHOLD,
@@ -19,6 +20,7 @@ use crate::render_helpers::clipped_surface::{ClippedSurfaceRenderElement, Rounde
use crate::render_helpers::damage::ExtraDamage;
use crate::render_helpers::renderer::NiriRenderer;
use crate::render_helpers::resize::ResizeRenderElement;
+use crate::render_helpers::shadow::ShadowRenderElement;
use crate::render_helpers::snapshot::RenderSnapshot;
use crate::render_helpers::solid_color::{SolidColorBuffer, SolidColorRenderElement};
use crate::render_helpers::{render_to_encompassing_texture, RenderTarget};
@@ -36,6 +38,9 @@ pub struct Tile<W: LayoutElement> {
/// The focus ring around the window.
focus_ring: FocusRing,
+ /// The shadow around the window.
+ shadow: Shadow,
+
/// Whether this tile is fullscreen.
///
/// This will update only when the `window` actually goes fullscreen, rather than right away,
@@ -111,6 +116,7 @@ niri_render_elements! {
Opening = OpeningWindowRenderElement,
Resize = ResizeRenderElement,
Border = BorderRenderElement,
+ Shadow = ShadowRenderElement,
ClippedSurface = ClippedSurfaceRenderElement<R>,
ExtraDamage = ExtraDamage,
}
@@ -143,12 +149,14 @@ impl<W: LayoutElement> Tile<W> {
let rules = window.rules();
let border_config = rules.border.resolve_against(options.border);
let focus_ring_config = rules.focus_ring.resolve_against(options.focus_ring.into());
+ let shadow_config = rules.shadow.resolve_against(options.shadow);
let is_fullscreen = window.is_fullscreen();
Self {
window,
border: FocusRing::new(border_config.into()),
focus_ring: FocusRing::new(focus_ring_config.into()),
+ shadow: Shadow::new(shadow_config),
is_fullscreen,
fullscreen_backdrop: SolidColorBuffer::new(view_size, [0., 0., 0., 1.]),
unfullscreen_to_floating: false,
@@ -198,12 +206,16 @@ impl<W: LayoutElement> Tile<W> {
.resolve_against(self.options.focus_ring.into());
self.focus_ring.update_config(focus_ring_config.into());
+ let shadow_config = rules.shadow.resolve_against(self.options.shadow);
+ self.shadow.update_config(shadow_config);
+
self.fullscreen_backdrop.resize(view_size);
}
pub fn update_shaders(&mut self) {
self.border.update_shaders();
self.focus_ring.update_shaders();
+ self.shadow.update_shaders();
}
pub fn update_window(&mut self) {
@@ -254,6 +266,9 @@ impl<W: LayoutElement> Tile<W> {
.resolve_against(self.options.focus_ring.into());
self.focus_ring.update_config(focus_ring_config.into());
+ let shadow_config = rules.shadow.resolve_against(self.options.shadow);
+ self.shadow.update_config(shadow_config);
+
let window_size = self.window_size();
let radius = rules
.geometry_corner_radius
@@ -323,19 +338,26 @@ impl<W: LayoutElement> Tile<W> {
self.scale,
);
- let draw_focus_ring_with_background = if self.effective_border_width().is_some() {
- false
- } else {
- draw_border_with_background
- };
let radius = if self.is_fullscreen {
CornerRadius::default()
} else if self.effective_border_width().is_some() {
radius
} else {
rules.geometry_corner_radius.unwrap_or_default()
- }
- .expanded_by(self.focus_ring.width() as f32);
+ };
+ self.shadow.update_render_elements(
+ self.animated_tile_size(),
+ is_active,
+ radius,
+ self.scale,
+ );
+
+ let draw_focus_ring_with_background = if self.effective_border_width().is_some() {
+ false
+ } else {
+ draw_border_with_background
+ };
+ let radius = radius.expanded_by(self.focus_ring.width() as f32);
self.focus_ring.update_render_elements(
self.animated_tile_size(),
is_active,
@@ -899,7 +921,9 @@ impl<W: LayoutElement> Tile<W> {
let rv = rv.chain(elem.into_iter().flatten());
let elem = focus_ring.then(|| self.focus_ring.render(renderer, location).map(Into::into));
- rv.chain(elem.into_iter().flatten())
+ let rv = rv.chain(elem.into_iter().flatten());
+
+ rv.chain(self.shadow.render(renderer, location).map(Into::into))
}
pub fn render<R: NiriRenderer>(