mirror of
https://github.com/niri-wm/niri.git
synced 2026-06-22 02:01:55 +07:00
Damage window on corner radius changes
This commit is contained in:
+22
-1
@@ -19,7 +19,8 @@ use super::{
|
|||||||
use crate::animation::Animation;
|
use crate::animation::Animation;
|
||||||
use crate::niri_render_elements;
|
use crate::niri_render_elements;
|
||||||
use crate::render_helpers::border::BorderRenderElement;
|
use crate::render_helpers::border::BorderRenderElement;
|
||||||
use crate::render_helpers::clipped_surface::ClippedSurfaceRenderElement;
|
use crate::render_helpers::clipped_surface::{ClippedSurfaceRenderElement, RoundedCornerDamage};
|
||||||
|
use crate::render_helpers::damage::ExtraDamage;
|
||||||
use crate::render_helpers::offscreen::OffscreenRenderElement;
|
use crate::render_helpers::offscreen::OffscreenRenderElement;
|
||||||
use crate::render_helpers::renderer::NiriRenderer;
|
use crate::render_helpers::renderer::NiriRenderer;
|
||||||
use crate::render_helpers::resize::ResizeRenderElement;
|
use crate::render_helpers::resize::ResizeRenderElement;
|
||||||
@@ -68,6 +69,9 @@ pub struct Tile<W: LayoutElement> {
|
|||||||
/// Snapshot of the last render for use in the close animation.
|
/// Snapshot of the last render for use in the close animation.
|
||||||
unmap_snapshot: RefCell<Option<TileRenderSnapshot>>,
|
unmap_snapshot: RefCell<Option<TileRenderSnapshot>>,
|
||||||
|
|
||||||
|
/// Extra damage for clipped surface corner radius changes.
|
||||||
|
rounded_corner_damage: RoundedCornerDamage,
|
||||||
|
|
||||||
/// Configurable properties of the layout.
|
/// Configurable properties of the layout.
|
||||||
pub options: Rc<Options>,
|
pub options: Rc<Options>,
|
||||||
}
|
}
|
||||||
@@ -81,6 +85,7 @@ niri_render_elements! {
|
|||||||
Resize = ResizeRenderElement,
|
Resize = ResizeRenderElement,
|
||||||
Border = BorderRenderElement,
|
Border = BorderRenderElement,
|
||||||
ClippedSurface = ClippedSurfaceRenderElement<R>,
|
ClippedSurface = ClippedSurfaceRenderElement<R>,
|
||||||
|
ExtraDamage = ExtraDamage,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,6 +123,7 @@ impl<W: LayoutElement> Tile<W> {
|
|||||||
move_x_animation: None,
|
move_x_animation: None,
|
||||||
move_y_animation: None,
|
move_y_animation: None,
|
||||||
unmap_snapshot: RefCell::new(None),
|
unmap_snapshot: RefCell::new(None),
|
||||||
|
rounded_corner_damage: Default::default(),
|
||||||
options,
|
options,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -180,6 +186,14 @@ impl<W: LayoutElement> Tile<W> {
|
|||||||
.focus_ring
|
.focus_ring
|
||||||
.resolve_against(self.options.focus_ring.into());
|
.resolve_against(self.options.focus_ring.into());
|
||||||
self.focus_ring.update_config(focus_ring_config.into());
|
self.focus_ring.update_config(focus_ring_config.into());
|
||||||
|
|
||||||
|
let window_size = self.window_size();
|
||||||
|
let radius = rules
|
||||||
|
.geometry_corner_radius
|
||||||
|
.unwrap_or_default()
|
||||||
|
.fit_to(window_size.w as f32, window_size.h as f32);
|
||||||
|
self.rounded_corner_damage.set_corner_radius(radius);
|
||||||
|
self.rounded_corner_damage.set_size(window_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn advance_animations(&mut self, current_time: Duration, is_active: bool) {
|
pub fn advance_animations(&mut self, current_time: Duration, is_active: bool) {
|
||||||
@@ -650,6 +664,7 @@ impl<W: LayoutElement> Tile<W> {
|
|||||||
// If we're not resizing, render the window itself.
|
// If we're not resizing, render the window itself.
|
||||||
let mut window_surface = None;
|
let mut window_surface = None;
|
||||||
let mut window_popups = None;
|
let mut window_popups = None;
|
||||||
|
let mut rounded_corner_damage = None;
|
||||||
if resize_shader.is_none() && resize_fallback.is_none() {
|
if resize_shader.is_none() && resize_fallback.is_none() {
|
||||||
let window = self
|
let window = self
|
||||||
.window
|
.window
|
||||||
@@ -667,6 +682,11 @@ impl<W: LayoutElement> Tile<W> {
|
|||||||
let clip_shader = ClippedSurfaceRenderElement::shader(renderer).cloned();
|
let clip_shader = ClippedSurfaceRenderElement::shader(renderer).cloned();
|
||||||
let border_shader = BorderRenderElement::shader(renderer).cloned();
|
let border_shader = BorderRenderElement::shader(renderer).cloned();
|
||||||
|
|
||||||
|
if clip_to_geometry && clip_shader.is_some() {
|
||||||
|
let damage = self.rounded_corner_damage.element();
|
||||||
|
rounded_corner_damage = Some(damage.with_location(window_render_loc).into());
|
||||||
|
}
|
||||||
|
|
||||||
window_surface = Some(window.normal.into_iter().map(move |elem| match elem {
|
window_surface = Some(window.normal.into_iter().map(move |elem| match elem {
|
||||||
LayoutElementRenderElement::Wayland(elem) => {
|
LayoutElementRenderElement::Wayland(elem) => {
|
||||||
// If we should clip to geometry, render a clipped window.
|
// If we should clip to geometry, render a clipped window.
|
||||||
@@ -727,6 +747,7 @@ impl<W: LayoutElement> Tile<W> {
|
|||||||
.chain(resize_shader)
|
.chain(resize_shader)
|
||||||
.chain(resize_fallback)
|
.chain(resize_fallback)
|
||||||
.chain(window_popups.into_iter().flatten())
|
.chain(window_popups.into_iter().flatten())
|
||||||
|
.chain(rounded_corner_damage)
|
||||||
.chain(window_surface.into_iter().flatten());
|
.chain(window_surface.into_iter().flatten());
|
||||||
|
|
||||||
let elem = self.is_fullscreen.then(|| {
|
let elem = self.is_fullscreen.then(|| {
|
||||||
|
|||||||
@@ -6,8 +6,9 @@ use smithay::backend::renderer::gles::{
|
|||||||
GlesError, GlesFrame, GlesRenderer, GlesTexProgram, Uniform,
|
GlesError, GlesFrame, GlesRenderer, GlesTexProgram, Uniform,
|
||||||
};
|
};
|
||||||
use smithay::backend::renderer::utils::{CommitCounter, DamageSet};
|
use smithay::backend::renderer::utils::{CommitCounter, DamageSet};
|
||||||
use smithay::utils::{Buffer, Logical, Physical, Rectangle, Scale, Transform};
|
use smithay::utils::{Buffer, Logical, Physical, Rectangle, Scale, Size, Transform};
|
||||||
|
|
||||||
|
use super::damage::ExtraDamage;
|
||||||
use super::renderer::{AsGlesFrame as _, NiriRenderer};
|
use super::renderer::{AsGlesFrame as _, NiriRenderer};
|
||||||
use super::shaders::{mat3_uniform, Shaders};
|
use super::shaders::{mat3_uniform, Shaders};
|
||||||
use crate::backend::tty::{TtyFrame, TtyRenderer, TtyRendererError};
|
use crate::backend::tty::{TtyFrame, TtyRenderer, TtyRendererError};
|
||||||
@@ -21,6 +22,12 @@ pub struct ClippedSurfaceRenderElement<R: NiriRenderer> {
|
|||||||
input_to_geo: Mat3,
|
input_to_geo: Mat3,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Clone)]
|
||||||
|
pub struct RoundedCornerDamage {
|
||||||
|
damage: ExtraDamage,
|
||||||
|
corner_radius: CornerRadius,
|
||||||
|
}
|
||||||
|
|
||||||
impl<R: NiriRenderer> ClippedSurfaceRenderElement<R> {
|
impl<R: NiriRenderer> ClippedSurfaceRenderElement<R> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
elem: WaylandSurfaceRenderElement<R>,
|
elem: WaylandSurfaceRenderElement<R>,
|
||||||
@@ -267,3 +274,23 @@ impl<'render> RenderElement<TtyRenderer<'render>>
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl RoundedCornerDamage {
|
||||||
|
pub fn set_size(&mut self, size: Size<i32, Logical>) {
|
||||||
|
self.damage.set_size(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_corner_radius(&mut self, corner_radius: CornerRadius) {
|
||||||
|
if self.corner_radius == corner_radius {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: make the damage granular.
|
||||||
|
self.corner_radius = corner_radius;
|
||||||
|
self.damage.damage_all();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn element(&self) -> ExtraDamage {
|
||||||
|
self.damage.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,75 @@
|
|||||||
|
use smithay::backend::renderer::element::{Element, Id, RenderElement};
|
||||||
|
use smithay::backend::renderer::utils::CommitCounter;
|
||||||
|
use smithay::backend::renderer::Renderer;
|
||||||
|
use smithay::utils::{Buffer, Logical, Physical, Point, Rectangle, Scale, Size};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct ExtraDamage {
|
||||||
|
id: Id,
|
||||||
|
commit: CommitCounter,
|
||||||
|
geometry: Rectangle<i32, Logical>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ExtraDamage {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
id: Id::new(),
|
||||||
|
commit: Default::default(),
|
||||||
|
geometry: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_size(&mut self, size: Size<i32, Logical>) {
|
||||||
|
if self.geometry.size == size {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.geometry.size = size;
|
||||||
|
self.commit.increment();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn damage_all(&mut self) {
|
||||||
|
self.commit.increment();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_location(mut self, location: Point<i32, Logical>) -> Self {
|
||||||
|
self.geometry.loc = location;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for ExtraDamage {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Element for ExtraDamage {
|
||||||
|
fn id(&self) -> &Id {
|
||||||
|
&self.id
|
||||||
|
}
|
||||||
|
|
||||||
|
fn current_commit(&self) -> CommitCounter {
|
||||||
|
self.commit
|
||||||
|
}
|
||||||
|
|
||||||
|
fn src(&self) -> Rectangle<f64, Buffer> {
|
||||||
|
Rectangle::from_loc_and_size((0., 0.), (1., 1.))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn geometry(&self, scale: Scale<f64>) -> Rectangle<i32, Physical> {
|
||||||
|
self.geometry.to_physical_precise_round(scale)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<R: Renderer> RenderElement<R> for ExtraDamage {
|
||||||
|
fn draw(
|
||||||
|
&self,
|
||||||
|
_frame: &mut <R as Renderer>::Frame<'_>,
|
||||||
|
_src: Rectangle<f64, Buffer>,
|
||||||
|
_dst: Rectangle<i32, Physical>,
|
||||||
|
_damage: &[Rectangle<i32, Physical>],
|
||||||
|
) -> Result<(), R::Error> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,6 +18,7 @@ use self::primary_gpu_texture::PrimaryGpuTextureRenderElement;
|
|||||||
|
|
||||||
pub mod border;
|
pub mod border;
|
||||||
pub mod clipped_surface;
|
pub mod clipped_surface;
|
||||||
|
pub mod damage;
|
||||||
pub mod offscreen;
|
pub mod offscreen;
|
||||||
pub mod primary_gpu_texture;
|
pub mod primary_gpu_texture;
|
||||||
pub mod render_elements;
|
pub mod render_elements;
|
||||||
|
|||||||
Reference in New Issue
Block a user