From b9ecc3c2d418e98fcb374040602abb7ce5f4047c Mon Sep 17 00:00:00 2001 From: dragonn Date: Tue, 18 Jan 2022 22:12:48 +0100 Subject: [PATCH 01/16] add layer definition to RenderElement --- src/desktop/space/element.rs | 22 ++++++++++++++++ src/desktop/space/mod.rs | 50 +++++++++++++++++++++++++++++++----- 2 files changed, 65 insertions(+), 7 deletions(-) diff --git a/src/desktop/space/element.rs b/src/desktop/space/element.rs index d162060..287337e 100644 --- a/src/desktop/space/element.rs +++ b/src/desktop/space/element.rs @@ -10,6 +10,23 @@ use std::{ }; use wayland_server::protocol::wl_surface::WlSurface; +/// Enum for indicating on with layer a render element schould be draw +#[derive(Debug, PartialEq, Eq)] +pub enum RenderLayer { + /// Bellow every other elements + Bottom, + /// Above WlrLayer::Background but bellow WlrLayer::Bottom + AboveBackground, + /// Right before programs windows are draw + BeforeWindows, + /// Right after programs windows are draw + AfterWindows, + /// Above WlrLayer::Top but bellow WlrLayer::Overlay + BeforeOverlay, + /// Above anything else + Top, +} + /// Trait for custom elements to be rendered during [`Space::render_output`]. pub trait RenderElement where @@ -55,6 +72,11 @@ where damage: &[Rectangle], log: &slog::Logger, ) -> Result<(), R::Error>; + + /// Returns they layer the elements schould be draw on, defaults to Top + fn layer(&self) -> RenderLayer { + RenderLayer::Top + } } pub(crate) trait SpaceElement diff --git a/src/desktop/space/mod.rs b/src/desktop/space/mod.rs index ed45ad9..2946570 100644 --- a/src/desktop/space/mod.rs +++ b/src/desktop/space/mod.rs @@ -501,6 +501,7 @@ impl Space { // This will hold all the damage we need for this rendering step let mut damage = Vec::>::new(); // First add damage for windows gone + for old_toplevel in state .last_state .iter() @@ -613,18 +614,53 @@ impl Space { // Then re-draw all windows & layers overlapping with a damage rect. - for element in layer_map - .layers_on(WlrLayer::Background) - .chain(layer_map.layers_on(WlrLayer::Bottom)) - .map(|l| l as &SpaceElem) + for element in custom_elements + .iter() + .filter(|c| c.layer() == RenderLayer::Bottom) + .map(|p| p as &SpaceElem) + .chain( + layer_map + .layers_on(WlrLayer::Background) + .map(|l| l as &SpaceElem) + .chain( + custom_elements + .iter() + .filter(|c| c.layer() == RenderLayer::AboveBackground) + .map(|c| c as &SpaceElem), + ) + .chain(layer_map.layers_on(WlrLayer::Bottom).map(|l| l as &SpaceElem)), + ) + .chain( + custom_elements + .iter() + .filter(|c| c.layer() == RenderLayer::BeforeWindows) + .map(|c| c as &SpaceElem), + ) .chain(self.windows.iter().map(|w| w as &SpaceElem)) + .chain( + custom_elements + .iter() + .filter(|c| c.layer() == RenderLayer::AfterWindows) + .map(|c| c as &SpaceElem), + ) .chain( layer_map .layers_on(WlrLayer::Top) - .chain(layer_map.layers_on(WlrLayer::Overlay)) - .map(|l| l as &SpaceElem), + .map(|l| l as &SpaceElem) + .chain( + custom_elements + .iter() + .filter(|c| c.layer() == RenderLayer::BeforeOverlay) + .map(|c| c as &SpaceElem), + ) + .chain(layer_map.layers_on(WlrLayer::Overlay).map(|l| l as &SpaceElem)), + ) + .chain( + custom_elements + .iter() + .filter(|c| c.layer() == RenderLayer::Top) + .map(|c| c as &SpaceElem), ) - .chain(custom_elements.iter().map(|c| c as &SpaceElem)) { let geo = element.geometry(self.id); if damage.iter().any(|d| d.overlaps(geo)) { From d7dfe2e3b691267231e9f3cf992cda05ef630bfc Mon Sep 17 00:00:00 2001 From: Mateusz Date: Wed, 19 Jan 2022 16:49:03 +0100 Subject: [PATCH 02/16] Move chain to upper chain in render loop Co-authored-by: Victoria Brekenfeld <4404502+Drakulix@users.noreply.github.com> --- src/desktop/space/mod.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/desktop/space/mod.rs b/src/desktop/space/mod.rs index 2946570..f6881e5 100644 --- a/src/desktop/space/mod.rs +++ b/src/desktop/space/mod.rs @@ -622,14 +622,14 @@ impl Space { layer_map .layers_on(WlrLayer::Background) .map(|l| l as &SpaceElem) - .chain( - custom_elements - .iter() - .filter(|c| c.layer() == RenderLayer::AboveBackground) - .map(|c| c as &SpaceElem), - ) - .chain(layer_map.layers_on(WlrLayer::Bottom).map(|l| l as &SpaceElem)), ) + .chain( + custom_elements + .iter() + .filter(|c| c.layer() == RenderLayer::AboveBackground) + .map(|c| c as &SpaceElem), + ) + .chain(layer_map.layers_on(WlrLayer::Bottom).map(|l| l as &SpaceElem)) .chain( custom_elements .iter() From 478fe6280828cfa603a84146234326b553a94f11 Mon Sep 17 00:00:00 2001 From: Mateusz Date: Wed, 19 Jan 2022 16:49:15 +0100 Subject: [PATCH 03/16] Move chain to upper chain in loop Co-authored-by: Victoria Brekenfeld <4404502+Drakulix@users.noreply.github.com> --- src/desktop/space/mod.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/desktop/space/mod.rs b/src/desktop/space/mod.rs index f6881e5..38a245c 100644 --- a/src/desktop/space/mod.rs +++ b/src/desktop/space/mod.rs @@ -647,14 +647,14 @@ impl Space { layer_map .layers_on(WlrLayer::Top) .map(|l| l as &SpaceElem) - .chain( - custom_elements - .iter() - .filter(|c| c.layer() == RenderLayer::BeforeOverlay) - .map(|c| c as &SpaceElem), - ) - .chain(layer_map.layers_on(WlrLayer::Overlay).map(|l| l as &SpaceElem)), ) + .chain( + custom_elements + .iter() + .filter(|c| c.layer() == RenderLayer::BeforeOverlay) + .map(|c| c as &SpaceElem), + ) + .chain(layer_map.layers_on(WlrLayer::Overlay).map(|l| l as &SpaceElem)) .chain( custom_elements .iter() From 3ae387e991b2c1f104819a747a0d6eace801e308 Mon Sep 17 00:00:00 2001 From: dragonn Date: Wed, 19 Jan 2022 17:35:30 +0100 Subject: [PATCH 04/16] DynamicRenderElementMap as a helper for iter on custom_elements --- src/desktop/space/mod.rs | 98 +++++++++++++++++++++++----------------- 1 file changed, 56 insertions(+), 42 deletions(-) diff --git a/src/desktop/space/mod.rs b/src/desktop/space/mod.rs index 38a245c..c193192 100644 --- a/src/desktop/space/mod.rs +++ b/src/desktop/space/mod.rs @@ -48,6 +48,52 @@ pub struct Space { pub type DynamicRenderElements = Box::Frame, ::Error, ::TextureId>>; +type SpaceElem = + dyn SpaceElement::Frame, ::Error, ::TextureId>; + +struct DynamicRenderElementMap<'a, R: Renderer>(&'a [DynamicRenderElements]); + +impl<'a, R> DynamicRenderElementMap<'a, R> +where + R: Renderer + ImportAll + 'static, + R::TextureId: 'static, + R::Error: 'static, + R::Frame: 'static, +{ + pub fn iter_bottom(&'a self) -> Box> + 'a> { + self.iter_layer(RenderLayer::Bottom) + } + + pub fn iter_above_background(&'a self) -> Box> + 'a> { + self.iter_layer(RenderLayer::AboveBackground) + } + + pub fn iter_before_windows(&'a self) -> Box> + 'a> { + self.iter_layer(RenderLayer::BeforeWindows) + } + + pub fn iter_after_windows(&'a self) -> Box> + 'a> { + self.iter_layer(RenderLayer::AfterWindows) + } + + pub fn iter_before_overlay(&'a self) -> Box> + 'a> { + self.iter_layer(RenderLayer::BeforeOverlay) + } + + pub fn iter_top(&'a self) -> Box> + 'a> { + self.iter_layer(RenderLayer::Top) + } + + pub fn iter_layer(&'a self, layer: RenderLayer) -> Box> + 'a> { + Box::new( + self.0 + .iter() + .filter(move |c| c.layer() == layer) + .map(|c| c as &SpaceElem), + ) + } +} + impl PartialEq for Space { fn eq(&self, other: &Space) -> bool { self.id == other.id @@ -474,9 +520,6 @@ impl Space { return Err(RenderError::UnmappedOutput); } - type SpaceElem = - dyn SpaceElement::Frame, ::Error, ::TextureId>; - let mut state = output_state(self.id, output); let output_size = output .current_mode() @@ -612,55 +655,26 @@ impl Space { .collect::>(), )?; + let custom_elements = DynamicRenderElementMap(custom_elements); + // Then re-draw all windows & layers overlapping with a damage rect. for element in custom_elements - .iter() - .filter(|c| c.layer() == RenderLayer::Bottom) - .map(|p| p as &SpaceElem) + .iter_bottom() .chain( layer_map .layers_on(WlrLayer::Background) - .map(|l| l as &SpaceElem) - ) - .chain( - custom_elements - .iter() - .filter(|c| c.layer() == RenderLayer::AboveBackground) - .map(|c| c as &SpaceElem), + .map(|l| l as &SpaceElem), ) + .chain(custom_elements.iter_above_background()) .chain(layer_map.layers_on(WlrLayer::Bottom).map(|l| l as &SpaceElem)) - .chain( - custom_elements - .iter() - .filter(|c| c.layer() == RenderLayer::BeforeWindows) - .map(|c| c as &SpaceElem), - ) + .chain(custom_elements.iter_before_windows()) .chain(self.windows.iter().map(|w| w as &SpaceElem)) - .chain( - custom_elements - .iter() - .filter(|c| c.layer() == RenderLayer::AfterWindows) - .map(|c| c as &SpaceElem), - ) - .chain( - layer_map - .layers_on(WlrLayer::Top) - .map(|l| l as &SpaceElem) - ) - .chain( - custom_elements - .iter() - .filter(|c| c.layer() == RenderLayer::BeforeOverlay) - .map(|c| c as &SpaceElem), - ) + .chain(custom_elements.iter_after_windows()) + .chain(layer_map.layers_on(WlrLayer::Top).map(|l| l as &SpaceElem)) + .chain(custom_elements.iter_before_overlay()) .chain(layer_map.layers_on(WlrLayer::Overlay).map(|l| l as &SpaceElem)) - .chain( - custom_elements - .iter() - .filter(|c| c.layer() == RenderLayer::Top) - .map(|c| c as &SpaceElem), - ) + .chain(custom_elements.iter_top()) { let geo = element.geometry(self.id); if damage.iter().any(|d| d.overlaps(geo)) { From 2b1e3894950af5c4cd66580079734effb4a81dc3 Mon Sep 17 00:00:00 2001 From: dragonn Date: Wed, 19 Jan 2022 21:12:54 +0100 Subject: [PATCH 05/16] move DynamicRenderElementMap and it's friends to elements.rs --- src/desktop/space/element.rs | 51 ++++++++++++++++++++++++++++++++++++ src/desktop/space/mod.rs | 50 ----------------------------------- 2 files changed, 51 insertions(+), 50 deletions(-) diff --git a/src/desktop/space/element.rs b/src/desktop/space/element.rs index 287337e..d623e6a 100644 --- a/src/desktop/space/element.rs +++ b/src/desktop/space/element.rs @@ -12,6 +12,7 @@ use wayland_server::protocol::wl_surface::WlSurface; /// Enum for indicating on with layer a render element schould be draw #[derive(Debug, PartialEq, Eq)] +#[non_exhaustive] pub enum RenderLayer { /// Bellow every other elements Bottom, @@ -27,6 +28,56 @@ pub enum RenderLayer { Top, } +/// Elements rendered by [`Space::render_output`] in addition to windows, layers and popups. +pub type DynamicRenderElements = + Box::Frame, ::Error, ::TextureId>>; + +pub(super) type SpaceElem = + dyn SpaceElement::Frame, ::Error, ::TextureId>; + +pub(super) struct DynamicRenderElementMap<'a, R: Renderer>(pub(super) &'a [DynamicRenderElements]); + +impl<'a, R> DynamicRenderElementMap<'a, R> +where + R: Renderer + ImportAll + 'static, + R::TextureId: 'static, + R::Error: 'static, + R::Frame: 'static, +{ + pub fn iter_bottom(&'a self) -> Box> + 'a> { + self.iter_layer(RenderLayer::Bottom) + } + + pub fn iter_above_background(&'a self) -> Box> + 'a> { + self.iter_layer(RenderLayer::AboveBackground) + } + + pub fn iter_before_windows(&'a self) -> Box> + 'a> { + self.iter_layer(RenderLayer::BeforeWindows) + } + + pub fn iter_after_windows(&'a self) -> Box> + 'a> { + self.iter_layer(RenderLayer::AfterWindows) + } + + pub fn iter_before_overlay(&'a self) -> Box> + 'a> { + self.iter_layer(RenderLayer::BeforeOverlay) + } + + pub fn iter_top(&'a self) -> Box> + 'a> { + self.iter_layer(RenderLayer::Top) + } + + pub fn iter_layer(&'a self, layer: RenderLayer) -> Box> + 'a> { + Box::new( + self.0 + .iter() + .filter(move |c| c.layer() == layer) + .map(|c| c as &SpaceElem), + ) + } +} + /// Trait for custom elements to be rendered during [`Space::render_output`]. pub trait RenderElement where diff --git a/src/desktop/space/mod.rs b/src/desktop/space/mod.rs index c193192..93b0ed9 100644 --- a/src/desktop/space/mod.rs +++ b/src/desktop/space/mod.rs @@ -44,56 +44,6 @@ pub struct Space { logger: ::slog::Logger, } -/// Elements rendered by [`Space::render_output`] in addition to windows, layers and popups. -pub type DynamicRenderElements = - Box::Frame, ::Error, ::TextureId>>; - -type SpaceElem = - dyn SpaceElement::Frame, ::Error, ::TextureId>; - -struct DynamicRenderElementMap<'a, R: Renderer>(&'a [DynamicRenderElements]); - -impl<'a, R> DynamicRenderElementMap<'a, R> -where - R: Renderer + ImportAll + 'static, - R::TextureId: 'static, - R::Error: 'static, - R::Frame: 'static, -{ - pub fn iter_bottom(&'a self) -> Box> + 'a> { - self.iter_layer(RenderLayer::Bottom) - } - - pub fn iter_above_background(&'a self) -> Box> + 'a> { - self.iter_layer(RenderLayer::AboveBackground) - } - - pub fn iter_before_windows(&'a self) -> Box> + 'a> { - self.iter_layer(RenderLayer::BeforeWindows) - } - - pub fn iter_after_windows(&'a self) -> Box> + 'a> { - self.iter_layer(RenderLayer::AfterWindows) - } - - pub fn iter_before_overlay(&'a self) -> Box> + 'a> { - self.iter_layer(RenderLayer::BeforeOverlay) - } - - pub fn iter_top(&'a self) -> Box> + 'a> { - self.iter_layer(RenderLayer::Top) - } - - pub fn iter_layer(&'a self, layer: RenderLayer) -> Box> + 'a> { - Box::new( - self.0 - .iter() - .filter(move |c| c.layer() == layer) - .map(|c| c as &SpaceElem), - ) - } -} - impl PartialEq for Space { fn eq(&self, other: &Space) -> bool { self.id == other.id From dea000921b897902c67bd4630fdb5eb72ffce948 Mon Sep 17 00:00:00 2001 From: dragonn Date: Wed, 19 Jan 2022 22:02:35 +0100 Subject: [PATCH 06/16] add comments to DynamicRenderElementMap --- src/desktop/space/element.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/desktop/space/element.rs b/src/desktop/space/element.rs index d623e6a..6752af9 100644 --- a/src/desktop/space/element.rs +++ b/src/desktop/space/element.rs @@ -35,6 +35,7 @@ pub type DynamicRenderElements = pub(super) type SpaceElem = dyn SpaceElement::Frame, ::Error, ::TextureId>; +/// Helper struct for iterating over diffrent layers of `DynamicRenderElements` pub(super) struct DynamicRenderElementMap<'a, R: Renderer>(pub(super) &'a [DynamicRenderElements]); impl<'a, R> DynamicRenderElementMap<'a, R> @@ -44,30 +45,37 @@ where R::Error: 'static, R::Frame: 'static, { + /// Iterate over `DynamicRenderElements` with layer `RenderLayer::Bottom` pub fn iter_bottom(&'a self) -> Box> + 'a> { self.iter_layer(RenderLayer::Bottom) } + /// Iterate over `DynamicRenderElements with layer `RenderLayer::AboveBackground` pub fn iter_above_background(&'a self) -> Box> + 'a> { self.iter_layer(RenderLayer::AboveBackground) } + /// Iterate over `DynamicRenderElements` with layer `RenderLayer::BeforeWindows` pub fn iter_before_windows(&'a self) -> Box> + 'a> { self.iter_layer(RenderLayer::BeforeWindows) } + /// Iterate over `DynamicRenderElements` with layer `RenderLayer::AfterWindows` pub fn iter_after_windows(&'a self) -> Box> + 'a> { self.iter_layer(RenderLayer::AfterWindows) } + /// Iterate over `DynamicRenderElements` with layer `RenderLayer::BeforeOverlay` pub fn iter_before_overlay(&'a self) -> Box> + 'a> { self.iter_layer(RenderLayer::BeforeOverlay) } + /// Iterate over `DynamicRenderElements` with layer `RenderLayer::Top` pub fn iter_top(&'a self) -> Box> + 'a> { self.iter_layer(RenderLayer::Top) } + /// Iterate over `DynamicRenderElements` with provided `layer` pub fn iter_layer(&'a self, layer: RenderLayer) -> Box> + 'a> { Box::new( self.0 From 957f1c522b5a486ce16c9b01b34dfa287ea3c45c Mon Sep 17 00:00:00 2001 From: dragonn Date: Thu, 20 Jan 2022 19:11:58 +0100 Subject: [PATCH 07/16] rework renderlayer to zindex solution --- src/desktop/layer.rs | 5 ++ src/desktop/space/element.rs | 96 ++++++++++-------------------------- src/desktop/space/layer.rs | 19 ++++++- src/desktop/space/mod.rs | 28 ++++------- src/desktop/space/popup.rs | 6 +++ src/desktop/space/window.rs | 6 +++ 6 files changed, 70 insertions(+), 90 deletions(-) diff --git a/src/desktop/layer.rs b/src/desktop/layer.rs index 1dc4b9a..b6e2c06 100644 --- a/src/desktop/layer.rs +++ b/src/desktop/layer.rs @@ -269,6 +269,11 @@ impl LayerMap { pub fn cleanup(&mut self) { self.layers.retain(|layer| layer.alive()) } + + /// Returns layers count + pub fn len(&self) -> usize { + self.layers.len() + } } #[derive(Debug, Default)] diff --git a/src/desktop/space/element.rs b/src/desktop/space/element.rs index 6752af9..4f915af 100644 --- a/src/desktop/space/element.rs +++ b/src/desktop/space/element.rs @@ -10,22 +10,22 @@ use std::{ }; use wayland_server::protocol::wl_surface::WlSurface; -/// Enum for indicating on with layer a render element schould be draw -#[derive(Debug, PartialEq, Eq)] -#[non_exhaustive] -pub enum RenderLayer { - /// Bellow every other elements - Bottom, - /// Above WlrLayer::Background but bellow WlrLayer::Bottom - AboveBackground, - /// Right before programs windows are draw - BeforeWindows, - /// Right after programs windows are draw - AfterWindows, - /// Above WlrLayer::Top but bellow WlrLayer::Overlay - BeforeOverlay, - /// Above anything else - Top, +/// Indicates default values for some zindexs inside smithay +#[derive(Debug)] +#[repr(u8)] +pub enum RenderZindex { + /// WlrLayer::Background default zindex + Background = 10, + /// WlrLayer::Bottom default zindex + Bottom = 20, + /// Not used yet? + Shell = 30, + /// Default zindex for Windows + Top = 40, + /// Default Layer for RenderElements + Overlay = 50, + /// Default Layer for PopUps? + PopUp = 60, } /// Elements rendered by [`Space::render_output`] in addition to windows, layers and popups. @@ -35,57 +35,6 @@ pub type DynamicRenderElements = pub(super) type SpaceElem = dyn SpaceElement::Frame, ::Error, ::TextureId>; -/// Helper struct for iterating over diffrent layers of `DynamicRenderElements` -pub(super) struct DynamicRenderElementMap<'a, R: Renderer>(pub(super) &'a [DynamicRenderElements]); - -impl<'a, R> DynamicRenderElementMap<'a, R> -where - R: Renderer + ImportAll + 'static, - R::TextureId: 'static, - R::Error: 'static, - R::Frame: 'static, -{ - /// Iterate over `DynamicRenderElements` with layer `RenderLayer::Bottom` - pub fn iter_bottom(&'a self) -> Box> + 'a> { - self.iter_layer(RenderLayer::Bottom) - } - - /// Iterate over `DynamicRenderElements with layer `RenderLayer::AboveBackground` - pub fn iter_above_background(&'a self) -> Box> + 'a> { - self.iter_layer(RenderLayer::AboveBackground) - } - - /// Iterate over `DynamicRenderElements` with layer `RenderLayer::BeforeWindows` - pub fn iter_before_windows(&'a self) -> Box> + 'a> { - self.iter_layer(RenderLayer::BeforeWindows) - } - - /// Iterate over `DynamicRenderElements` with layer `RenderLayer::AfterWindows` - pub fn iter_after_windows(&'a self) -> Box> + 'a> { - self.iter_layer(RenderLayer::AfterWindows) - } - - /// Iterate over `DynamicRenderElements` with layer `RenderLayer::BeforeOverlay` - pub fn iter_before_overlay(&'a self) -> Box> + 'a> { - self.iter_layer(RenderLayer::BeforeOverlay) - } - - /// Iterate over `DynamicRenderElements` with layer `RenderLayer::Top` - pub fn iter_top(&'a self) -> Box> + 'a> { - self.iter_layer(RenderLayer::Top) - } - - /// Iterate over `DynamicRenderElements` with provided `layer` - pub fn iter_layer(&'a self, layer: RenderLayer) -> Box> + 'a> { - Box::new( - self.0 - .iter() - .filter(move |c| c.layer() == layer) - .map(|c| c as &SpaceElem), - ) - } -} - /// Trait for custom elements to be rendered during [`Space::render_output`]. pub trait RenderElement where @@ -132,9 +81,9 @@ where log: &slog::Logger, ) -> Result<(), R::Error>; - /// Returns they layer the elements schould be draw on, defaults to Top - fn layer(&self) -> RenderLayer { - RenderLayer::Top + /// Returns z_index of RenderElement, reverf too [`RenderZindex`] for default values + fn z_index(&self) -> u8 { + RenderZindex::Overlay as u8 } } @@ -163,6 +112,9 @@ where damage: &[Rectangle], log: &slog::Logger, ) -> Result<(), R::Error>; + fn z_index(&self) -> u8; //{ + // 0 + //} } impl SpaceElement for Box> @@ -196,6 +148,10 @@ where ) -> Result<(), R::Error> { (&**self as &dyn RenderElement).draw(renderer, frame, scale, damage, log) } + + fn z_index(&self) -> u8 { + RenderElement::z_index(self.as_ref()) + } } /// Generic helper for drawing [`WlSurface`]s and their subsurfaces diff --git a/src/desktop/space/layer.rs b/src/desktop/space/layer.rs index 89a4799..e6f397e 100644 --- a/src/desktop/space/layer.rs +++ b/src/desktop/space/layer.rs @@ -5,7 +5,7 @@ use crate::{ space::{Space, SpaceElement}, }, utils::{Logical, Point, Rectangle}, - wayland::output::Output, + wayland::{output::Output, shell::wlr_layer::Layer}, }; use std::{ any::TypeId, @@ -13,6 +13,8 @@ use std::{ collections::HashMap, }; +use super::RenderZindex; + #[derive(Default)] pub struct LayerState { pub drawn: bool, @@ -69,4 +71,19 @@ where } res } + + fn z_index(&self) -> u8 { + if let Some(layer) = self.layer() { + let z_index = match layer { + Layer::Background => RenderZindex::Background, + Layer::Bottom => RenderZindex::Bottom, + Layer::Top => RenderZindex::Top, + Layer::Overlay => RenderZindex::Overlay, + }; + z_index as u8 + } else { + //TODO: what to do when layersurface doesn't have a layer? + 0 + } + } } diff --git a/src/desktop/space/mod.rs b/src/desktop/space/mod.rs index 93b0ed9..36e817c 100644 --- a/src/desktop/space/mod.rs +++ b/src/desktop/space/mod.rs @@ -14,7 +14,6 @@ use crate::{ TraversalAction, }, output::Output, - shell::wlr_layer::Layer as WlrLayer, }, }; use indexmap::{IndexMap, IndexSet}; @@ -605,27 +604,18 @@ impl Space { .collect::>(), )?; - let custom_elements = DynamicRenderElementMap(custom_elements); + let mut render_elements: Vec<&SpaceElem> = + Vec::with_capacity(custom_elements.len() + layer_map.len() + self.windows.len()); + + render_elements.append(&mut custom_elements.iter().map(|l| l as &SpaceElem).collect()); + render_elements.append(&mut self.windows.iter().map(|l| l as &SpaceElem).collect()); + render_elements.append(&mut layer_map.layers().map(|l| l as &SpaceElem).collect()); + + render_elements.sort_by_key(|e| e.z_index()); // Then re-draw all windows & layers overlapping with a damage rect. - for element in custom_elements - .iter_bottom() - .chain( - layer_map - .layers_on(WlrLayer::Background) - .map(|l| l as &SpaceElem), - ) - .chain(custom_elements.iter_above_background()) - .chain(layer_map.layers_on(WlrLayer::Bottom).map(|l| l as &SpaceElem)) - .chain(custom_elements.iter_before_windows()) - .chain(self.windows.iter().map(|w| w as &SpaceElem)) - .chain(custom_elements.iter_after_windows()) - .chain(layer_map.layers_on(WlrLayer::Top).map(|l| l as &SpaceElem)) - .chain(custom_elements.iter_before_overlay()) - .chain(layer_map.layers_on(WlrLayer::Overlay).map(|l| l as &SpaceElem)) - .chain(custom_elements.iter_top()) - { + for element in render_elements { let geo = element.geometry(self.id); if damage.iter().any(|d| d.overlaps(geo)) { let loc = element.location(self.id); diff --git a/src/desktop/space/popup.rs b/src/desktop/space/popup.rs index dbef156..6a0c423 100644 --- a/src/desktop/space/popup.rs +++ b/src/desktop/space/popup.rs @@ -12,6 +12,8 @@ use crate::{ }; use std::any::TypeId; +use super::RenderZindex; + #[derive(Debug)] pub struct RenderPopup { location: Point, @@ -126,4 +128,8 @@ where // popups are special, we track them, but they render with their parents Ok(()) } + + fn z_index(&self) -> u8 { + RenderZindex::PopUp as u8 + } } diff --git a/src/desktop/space/window.rs b/src/desktop/space/window.rs index f1ece6b..c000f04 100644 --- a/src/desktop/space/window.rs +++ b/src/desktop/space/window.rs @@ -13,6 +13,8 @@ use std::{ collections::HashMap, }; +use super::RenderZindex; + #[derive(Default)] pub struct WindowState { pub location: Point, @@ -103,4 +105,8 @@ where } res } + + fn z_index(&self) -> u8 { + RenderZindex::Top as u8 + } } From 53c6bf003f3e2d175ae788dd4e9fe7faa8e1fc00 Mon Sep 17 00:00:00 2001 From: dragonn Date: Thu, 20 Jan 2022 19:18:00 +0100 Subject: [PATCH 08/16] suppres clippy len_without_is_empty for LayerMap --- src/desktop/layer.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/desktop/layer.rs b/src/desktop/layer.rs index b6e2c06..fe63ed9 100644 --- a/src/desktop/layer.rs +++ b/src/desktop/layer.rs @@ -271,6 +271,7 @@ impl LayerMap { } /// Returns layers count + #[allow(clippy::len_without_is_empty)] //we don't need is_empty on that struct for now, mark as allow pub fn len(&self) -> usize { self.layers.len() } From 6477942122f439eca567e2b608c23bf2445788e6 Mon Sep 17 00:00:00 2001 From: dragonn Date: Thu, 20 Jan 2022 19:45:30 +0100 Subject: [PATCH 09/16] add extra derives to RenderZindex --- src/desktop/space/element.rs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/desktop/space/element.rs b/src/desktop/space/element.rs index 4f915af..93fdced 100644 --- a/src/desktop/space/element.rs +++ b/src/desktop/space/element.rs @@ -11,21 +11,23 @@ use std::{ use wayland_server::protocol::wl_surface::WlSurface; /// Indicates default values for some zindexs inside smithay -#[derive(Debug)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] #[repr(u8)] pub enum RenderZindex { /// WlrLayer::Background default zindex Background = 10, /// WlrLayer::Bottom default zindex Bottom = 20, - /// Not used yet? - Shell = 30, /// Default zindex for Windows - Top = 40, + Shell = 30, + /// Default zindex for Windows PopUps + PopUpsShell = 40, + /// WlrLayer::Top default zindex + Top = 50, /// Default Layer for RenderElements - Overlay = 50, - /// Default Layer for PopUps? - PopUp = 60, + Overlay = 80, + /// Default Layer for Overlay PopUp + PopUpsOverlay = 100, } /// Elements rendered by [`Space::render_output`] in addition to windows, layers and popups. From cbb2c1e54180cafc4eb6345a1c130acd202f5d38 Mon Sep 17 00:00:00 2001 From: dragonn Date: Thu, 20 Jan 2022 19:45:59 +0100 Subject: [PATCH 10/16] fine to return 0 when LayerSurface doesn't have layer --- src/desktop/space/layer.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/desktop/space/layer.rs b/src/desktop/space/layer.rs index e6f397e..93087dd 100644 --- a/src/desktop/space/layer.rs +++ b/src/desktop/space/layer.rs @@ -82,7 +82,6 @@ where }; z_index as u8 } else { - //TODO: what to do when layersurface doesn't have a layer? 0 } } From d7415e6fa9fb88e47dbb351edd76fb63d80aead9 Mon Sep 17 00:00:00 2001 From: dragonn Date: Thu, 20 Jan 2022 19:51:41 +0100 Subject: [PATCH 11/16] remove left over comment from default implemantion for z_index --- src/desktop/space/element.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/desktop/space/element.rs b/src/desktop/space/element.rs index 93fdced..52075a9 100644 --- a/src/desktop/space/element.rs +++ b/src/desktop/space/element.rs @@ -114,9 +114,7 @@ where damage: &[Rectangle], log: &slog::Logger, ) -> Result<(), R::Error>; - fn z_index(&self) -> u8; //{ - // 0 - //} + fn z_index(&self) -> u8; } impl SpaceElement for Box> From f0564ebad666b0740f8aa70bca61c9723e564890 Mon Sep 17 00:00:00 2001 From: dragonn Date: Thu, 20 Jan 2022 20:03:33 +0100 Subject: [PATCH 12/16] store parent_layer in RenderPopup for z_index implemantion --- src/desktop/space/popup.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/desktop/space/popup.rs b/src/desktop/space/popup.rs index 6a0c423..718d0d2 100644 --- a/src/desktop/space/popup.rs +++ b/src/desktop/space/popup.rs @@ -18,6 +18,7 @@ use super::RenderZindex; pub struct RenderPopup { location: Point, popup: PopupKind, + parent_layer: RenderZindex, } impl Window { @@ -41,6 +42,7 @@ impl Window { RenderPopup { location: offset, popup, + parent_layer: RenderZindex::Shell, } }) }) @@ -72,6 +74,7 @@ impl LayerSurface { RenderPopup { location: offset, popup, + parent_layer: RenderZindex::Overlay, } }) }) @@ -130,6 +133,10 @@ where } fn z_index(&self) -> u8 { - RenderZindex::PopUp as u8 + match self.parent_layer { + RenderZindex::Shell => RenderZindex::PopUpsShell as u8, + RenderZindex::Overlay => RenderZindex::PopUpsOverlay as u8, + _ => 0, //Maybe better panic here? Or return u8::MAX? + } } } From 97c831acbce033078136744bf245106e2f8f0b44 Mon Sep 17 00:00:00 2001 From: dragonn Date: Thu, 20 Jan 2022 20:04:05 +0100 Subject: [PATCH 13/16] rework damage tracking to render_elements and use extend --- src/desktop/space/mod.rs | 61 +++++++++++++++------------------------- 1 file changed, 22 insertions(+), 39 deletions(-) diff --git a/src/desktop/space/mod.rs b/src/desktop/space/mod.rs index 36e817c..401330a 100644 --- a/src/desktop/space/mod.rs +++ b/src/desktop/space/mod.rs @@ -490,6 +490,22 @@ impl Space { .flat_map(|l| l.popup_elements::(self.id)) .collect::>(); + let mut render_elements: Vec<&SpaceElem> = Vec::with_capacity( + custom_elements.len() + + layer_map.len() + + self.windows.len() + + window_popups.len() + + layer_popups.len(), + ); + + render_elements.extend(&mut custom_elements.iter().map(|l| l as &SpaceElem)); + render_elements.extend(&mut self.windows.iter().map(|l| l as &SpaceElem)); + render_elements.extend(&mut window_popups.iter().map(|l| l as &SpaceElem)); + render_elements.extend(&mut layer_map.layers().map(|l| l as &SpaceElem)); + render_elements.extend(&mut layer_popups.iter().map(|l| l as &SpaceElem)); + + render_elements.sort_by_key(|e| e.z_index()); + // This will hold all the damage we need for this rendering step let mut damage = Vec::>::new(); // First add damage for windows gone @@ -498,16 +514,7 @@ impl Space { .last_state .iter() .filter_map(|(id, geo)| { - if !self - .windows - .iter() - .map(|w| w as &SpaceElem) - .chain(window_popups.iter().map(|p| p as &SpaceElem)) - .chain(layer_map.layers().map(|l| l as &SpaceElem)) - .chain(layer_popups.iter().map(|p| p as &SpaceElem)) - .chain(custom_elements.iter().map(|c| c as &SpaceElem)) - .any(|e| ToplevelId::from(e) == *id) - { + if !render_elements.iter().any(|e| ToplevelId::from(*e) == *id) { Some(*geo) } else { None @@ -520,17 +527,9 @@ impl Space { } // lets iterate front to back and figure out, what new windows or unmoved windows we have - for element in self - .windows - .iter() - .map(|w| w as &SpaceElem) - .chain(window_popups.iter().map(|p| p as &SpaceElem)) - .chain(layer_map.layers().map(|l| l as &SpaceElem)) - .chain(layer_popups.iter().map(|p| p as &SpaceElem)) - .chain(custom_elements.iter().map(|c| c as &SpaceElem)) - { + for element in &render_elements { let geo = element.geometry(self.id); - let old_geo = state.last_state.get(&ToplevelId::from(element)).cloned(); + let old_geo = state.last_state.get(&ToplevelId::from(*element)).cloned(); // window was moved or resized if old_geo.map(|old_geo| old_geo != geo).unwrap_or(false) { @@ -603,19 +602,9 @@ impl Space { .map(|geo| geo.to_f64().to_physical(state.render_scale).to_i32_round()) .collect::>(), )?; - - let mut render_elements: Vec<&SpaceElem> = - Vec::with_capacity(custom_elements.len() + layer_map.len() + self.windows.len()); - - render_elements.append(&mut custom_elements.iter().map(|l| l as &SpaceElem).collect()); - render_elements.append(&mut self.windows.iter().map(|l| l as &SpaceElem).collect()); - render_elements.append(&mut layer_map.layers().map(|l| l as &SpaceElem).collect()); - - render_elements.sort_by_key(|e| e.z_index()); - // Then re-draw all windows & layers overlapping with a damage rect. - for element in render_elements { + for element in &render_elements { let geo = element.geometry(self.id); if damage.iter().any(|d| d.overlaps(geo)) { let loc = element.location(self.id); @@ -656,17 +645,11 @@ impl Space { } // If rendering was successful capture the state and add the damage - state.last_state = self - .windows + state.last_state = render_elements .iter() - .map(|w| w as &SpaceElem) - .chain(window_popups.iter().map(|p| p as &SpaceElem)) - .chain(layer_map.layers().map(|l| l as &SpaceElem)) - .chain(layer_popups.iter().map(|p| p as &SpaceElem)) - .chain(custom_elements.iter().map(|c| c as &SpaceElem)) .map(|elem| { let geo = elem.geometry(self.id); - (ToplevelId::from(elem), geo) + (ToplevelId::from(*elem), geo) }) .collect(); state.old_damage.push_front(new_damage.clone()); From 15c9e9adf0385e87997b6cca07a1e3fd7b84e2c1 Mon Sep 17 00:00:00 2001 From: dragonn Date: Thu, 20 Jan 2022 20:04:22 +0100 Subject: [PATCH 14/16] change default layer for Windows to Shell --- src/desktop/space/window.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/desktop/space/window.rs b/src/desktop/space/window.rs index c000f04..9b0c045 100644 --- a/src/desktop/space/window.rs +++ b/src/desktop/space/window.rs @@ -107,6 +107,6 @@ where } fn z_index(&self) -> u8 { - RenderZindex::Top as u8 + RenderZindex::Shell as u8 } } From 3f86c5b94d222bcaf403d1e3cd74ba044604ef1a Mon Sep 17 00:00:00 2001 From: dragonn Date: Thu, 20 Jan 2022 20:43:04 +0100 Subject: [PATCH 15/16] small reorder in RenderZindex and change z_index logic in popups --- src/desktop/space/element.rs | 10 +++++----- src/desktop/space/popup.rs | 26 ++++++++++++++++---------- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/src/desktop/space/element.rs b/src/desktop/space/element.rs index 52075a9..ebb7a7b 100644 --- a/src/desktop/space/element.rs +++ b/src/desktop/space/element.rs @@ -20,14 +20,14 @@ pub enum RenderZindex { Bottom = 20, /// Default zindex for Windows Shell = 30, - /// Default zindex for Windows PopUps - PopUpsShell = 40, /// WlrLayer::Top default zindex - Top = 50, + Top = 40, + /// Default zindex for Windows PopUps + Popups = 50, /// Default Layer for RenderElements - Overlay = 80, + Overlay = 60, /// Default Layer for Overlay PopUp - PopUpsOverlay = 100, + PopupsOverlay = 70, } /// Elements rendered by [`Space::render_output`] in addition to windows, layers and popups. diff --git a/src/desktop/space/popup.rs b/src/desktop/space/popup.rs index 718d0d2..dd8cc47 100644 --- a/src/desktop/space/popup.rs +++ b/src/desktop/space/popup.rs @@ -8,7 +8,7 @@ use crate::{ window::Window, }, utils::{Logical, Point, Rectangle}, - wayland::output::Output, + wayland::{output::Output, shell::wlr_layer::Layer}, }; use std::any::TypeId; @@ -18,7 +18,7 @@ use super::RenderZindex; pub struct RenderPopup { location: Point, popup: PopupKind, - parent_layer: RenderZindex, + z_index: u8, } impl Window { @@ -42,7 +42,7 @@ impl Window { RenderPopup { location: offset, popup, - parent_layer: RenderZindex::Shell, + z_index: RenderZindex::Popups as u8, } }) }) @@ -52,7 +52,7 @@ impl Window { } impl LayerSurface { - pub(super) fn popup_elements(&self, space_id: usize) -> impl Iterator + pub(super) fn popup_elements(&self, space_id: usize) -> impl Iterator + '_ where R: Renderer + ImportAll + 'static, R::TextureId: 'static, @@ -71,10 +71,20 @@ impl LayerSurface { .flatten() .map(move |(popup, location)| { let offset = loc + location - popup.geometry().loc; + let z_index = if let Some(layer) = self.layer() { + if layer == Layer::Overlay { + RenderZindex::PopupsOverlay as u8 + } else { + RenderZindex::Popups as u8 + } + } else { + 0 + }; + RenderPopup { location: offset, popup, - parent_layer: RenderZindex::Overlay, + z_index, } }) }) @@ -133,10 +143,6 @@ where } fn z_index(&self) -> u8 { - match self.parent_layer { - RenderZindex::Shell => RenderZindex::PopUpsShell as u8, - RenderZindex::Overlay => RenderZindex::PopUpsOverlay as u8, - _ => 0, //Maybe better panic here? Or return u8::MAX? - } + self.z_index } } From b11fef8a90c8a2d7a2144174fd1aeca2dfca3926 Mon Sep 17 00:00:00 2001 From: dragonn Date: Sun, 23 Jan 2022 19:58:11 +0100 Subject: [PATCH 16/16] remove not need &mut in render_elements extend --- src/desktop/space/mod.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/desktop/space/mod.rs b/src/desktop/space/mod.rs index 401330a..e35f0bf 100644 --- a/src/desktop/space/mod.rs +++ b/src/desktop/space/mod.rs @@ -498,11 +498,11 @@ impl Space { + layer_popups.len(), ); - render_elements.extend(&mut custom_elements.iter().map(|l| l as &SpaceElem)); - render_elements.extend(&mut self.windows.iter().map(|l| l as &SpaceElem)); - render_elements.extend(&mut window_popups.iter().map(|l| l as &SpaceElem)); - render_elements.extend(&mut layer_map.layers().map(|l| l as &SpaceElem)); - render_elements.extend(&mut layer_popups.iter().map(|l| l as &SpaceElem)); + render_elements.extend(custom_elements.iter().map(|l| l as &SpaceElem)); + render_elements.extend(self.windows.iter().map(|l| l as &SpaceElem)); + render_elements.extend(window_popups.iter().map(|l| l as &SpaceElem)); + render_elements.extend(layer_map.layers().map(|l| l as &SpaceElem)); + render_elements.extend(layer_popups.iter().map(|l| l as &SpaceElem)); render_elements.sort_by_key(|e| e.z_index());