rework renderlayer to zindex solution
This commit is contained in:
parent
dea000921b
commit
957f1c522b
|
@ -269,6 +269,11 @@ impl LayerMap {
|
||||||
pub fn cleanup(&mut self) {
|
pub fn cleanup(&mut self) {
|
||||||
self.layers.retain(|layer| layer.alive())
|
self.layers.retain(|layer| layer.alive())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns layers count
|
||||||
|
pub fn len(&self) -> usize {
|
||||||
|
self.layers.len()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
|
|
|
@ -10,22 +10,22 @@ use std::{
|
||||||
};
|
};
|
||||||
use wayland_server::protocol::wl_surface::WlSurface;
|
use wayland_server::protocol::wl_surface::WlSurface;
|
||||||
|
|
||||||
/// Enum for indicating on with layer a render element schould be draw
|
/// Indicates default values for some zindexs inside smithay
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug)]
|
||||||
#[non_exhaustive]
|
#[repr(u8)]
|
||||||
pub enum RenderLayer {
|
pub enum RenderZindex {
|
||||||
/// Bellow every other elements
|
/// WlrLayer::Background default zindex
|
||||||
Bottom,
|
Background = 10,
|
||||||
/// Above WlrLayer::Background but bellow WlrLayer::Bottom
|
/// WlrLayer::Bottom default zindex
|
||||||
AboveBackground,
|
Bottom = 20,
|
||||||
/// Right before programs windows are draw
|
/// Not used yet?
|
||||||
BeforeWindows,
|
Shell = 30,
|
||||||
/// Right after programs windows are draw
|
/// Default zindex for Windows
|
||||||
AfterWindows,
|
Top = 40,
|
||||||
/// Above WlrLayer::Top but bellow WlrLayer::Overlay
|
/// Default Layer for RenderElements
|
||||||
BeforeOverlay,
|
Overlay = 50,
|
||||||
/// Above anything else
|
/// Default Layer for PopUps?
|
||||||
Top,
|
PopUp = 60,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Elements rendered by [`Space::render_output`] in addition to windows, layers and popups.
|
/// Elements rendered by [`Space::render_output`] in addition to windows, layers and popups.
|
||||||
|
@ -35,57 +35,6 @@ pub type DynamicRenderElements<R> =
|
||||||
pub(super) type SpaceElem<R> =
|
pub(super) type SpaceElem<R> =
|
||||||
dyn SpaceElement<R, <R as Renderer>::Frame, <R as Renderer>::Error, <R as Renderer>::TextureId>;
|
dyn SpaceElement<R, <R as Renderer>::Frame, <R as Renderer>::Error, <R as Renderer>::TextureId>;
|
||||||
|
|
||||||
/// Helper struct for iterating over diffrent layers of `DynamicRenderElements`
|
|
||||||
pub(super) struct DynamicRenderElementMap<'a, R: Renderer>(pub(super) &'a [DynamicRenderElements<R>]);
|
|
||||||
|
|
||||||
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<dyn Iterator<Item = &SpaceElem<R>> + 'a> {
|
|
||||||
self.iter_layer(RenderLayer::Bottom)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Iterate over `DynamicRenderElements with layer `RenderLayer::AboveBackground`
|
|
||||||
pub fn iter_above_background(&'a self) -> Box<dyn Iterator<Item = &SpaceElem<R>> + 'a> {
|
|
||||||
self.iter_layer(RenderLayer::AboveBackground)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Iterate over `DynamicRenderElements` with layer `RenderLayer::BeforeWindows`
|
|
||||||
pub fn iter_before_windows(&'a self) -> Box<dyn Iterator<Item = &SpaceElem<R>> + 'a> {
|
|
||||||
self.iter_layer(RenderLayer::BeforeWindows)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Iterate over `DynamicRenderElements` with layer `RenderLayer::AfterWindows`
|
|
||||||
pub fn iter_after_windows(&'a self) -> Box<dyn Iterator<Item = &SpaceElem<R>> + 'a> {
|
|
||||||
self.iter_layer(RenderLayer::AfterWindows)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Iterate over `DynamicRenderElements` with layer `RenderLayer::BeforeOverlay`
|
|
||||||
pub fn iter_before_overlay(&'a self) -> Box<dyn Iterator<Item = &SpaceElem<R>> + 'a> {
|
|
||||||
self.iter_layer(RenderLayer::BeforeOverlay)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Iterate over `DynamicRenderElements` with layer `RenderLayer::Top`
|
|
||||||
pub fn iter_top(&'a self) -> Box<dyn Iterator<Item = &SpaceElem<R>> + 'a> {
|
|
||||||
self.iter_layer(RenderLayer::Top)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Iterate over `DynamicRenderElements` with provided `layer`
|
|
||||||
pub fn iter_layer(&'a self, layer: RenderLayer) -> Box<dyn Iterator<Item = &SpaceElem<R>> + 'a> {
|
|
||||||
Box::new(
|
|
||||||
self.0
|
|
||||||
.iter()
|
|
||||||
.filter(move |c| c.layer() == layer)
|
|
||||||
.map(|c| c as &SpaceElem<R>),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Trait for custom elements to be rendered during [`Space::render_output`].
|
/// Trait for custom elements to be rendered during [`Space::render_output`].
|
||||||
pub trait RenderElement<R, F, E, T>
|
pub trait RenderElement<R, F, E, T>
|
||||||
where
|
where
|
||||||
|
@ -132,9 +81,9 @@ where
|
||||||
log: &slog::Logger,
|
log: &slog::Logger,
|
||||||
) -> Result<(), R::Error>;
|
) -> Result<(), R::Error>;
|
||||||
|
|
||||||
/// Returns they layer the elements schould be draw on, defaults to Top
|
/// Returns z_index of RenderElement, reverf too [`RenderZindex`] for default values
|
||||||
fn layer(&self) -> RenderLayer {
|
fn z_index(&self) -> u8 {
|
||||||
RenderLayer::Top
|
RenderZindex::Overlay as u8
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,6 +112,9 @@ where
|
||||||
damage: &[Rectangle<i32, Logical>],
|
damage: &[Rectangle<i32, Logical>],
|
||||||
log: &slog::Logger,
|
log: &slog::Logger,
|
||||||
) -> Result<(), R::Error>;
|
) -> Result<(), R::Error>;
|
||||||
|
fn z_index(&self) -> u8; //{
|
||||||
|
// 0
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R, F, E, T> SpaceElement<R, F, E, T> for Box<dyn RenderElement<R, F, E, T>>
|
impl<R, F, E, T> SpaceElement<R, F, E, T> for Box<dyn RenderElement<R, F, E, T>>
|
||||||
|
@ -196,6 +148,10 @@ where
|
||||||
) -> Result<(), R::Error> {
|
) -> Result<(), R::Error> {
|
||||||
(&**self as &dyn RenderElement<R, F, E, T>).draw(renderer, frame, scale, damage, log)
|
(&**self as &dyn RenderElement<R, F, E, T>).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
|
/// Generic helper for drawing [`WlSurface`]s and their subsurfaces
|
||||||
|
|
|
@ -5,7 +5,7 @@ use crate::{
|
||||||
space::{Space, SpaceElement},
|
space::{Space, SpaceElement},
|
||||||
},
|
},
|
||||||
utils::{Logical, Point, Rectangle},
|
utils::{Logical, Point, Rectangle},
|
||||||
wayland::output::Output,
|
wayland::{output::Output, shell::wlr_layer::Layer},
|
||||||
};
|
};
|
||||||
use std::{
|
use std::{
|
||||||
any::TypeId,
|
any::TypeId,
|
||||||
|
@ -13,6 +13,8 @@ use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use super::RenderZindex;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct LayerState {
|
pub struct LayerState {
|
||||||
pub drawn: bool,
|
pub drawn: bool,
|
||||||
|
@ -69,4 +71,19 @@ where
|
||||||
}
|
}
|
||||||
res
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,6 @@ use crate::{
|
||||||
TraversalAction,
|
TraversalAction,
|
||||||
},
|
},
|
||||||
output::Output,
|
output::Output,
|
||||||
shell::wlr_layer::Layer as WlrLayer,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use indexmap::{IndexMap, IndexSet};
|
use indexmap::{IndexMap, IndexSet};
|
||||||
|
@ -605,27 +604,18 @@ impl Space {
|
||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let custom_elements = DynamicRenderElementMap(custom_elements);
|
let mut render_elements: Vec<&SpaceElem<R>> =
|
||||||
|
Vec::with_capacity(custom_elements.len() + layer_map.len() + self.windows.len());
|
||||||
|
|
||||||
|
render_elements.append(&mut custom_elements.iter().map(|l| l as &SpaceElem<R>).collect());
|
||||||
|
render_elements.append(&mut self.windows.iter().map(|l| l as &SpaceElem<R>).collect());
|
||||||
|
render_elements.append(&mut layer_map.layers().map(|l| l as &SpaceElem<R>).collect());
|
||||||
|
|
||||||
|
render_elements.sort_by_key(|e| e.z_index());
|
||||||
|
|
||||||
// Then re-draw all windows & layers overlapping with a damage rect.
|
// Then re-draw all windows & layers overlapping with a damage rect.
|
||||||
|
|
||||||
for element in custom_elements
|
for element in render_elements {
|
||||||
.iter_bottom()
|
|
||||||
.chain(
|
|
||||||
layer_map
|
|
||||||
.layers_on(WlrLayer::Background)
|
|
||||||
.map(|l| l as &SpaceElem<R>),
|
|
||||||
)
|
|
||||||
.chain(custom_elements.iter_above_background())
|
|
||||||
.chain(layer_map.layers_on(WlrLayer::Bottom).map(|l| l as &SpaceElem<R>))
|
|
||||||
.chain(custom_elements.iter_before_windows())
|
|
||||||
.chain(self.windows.iter().map(|w| w as &SpaceElem<R>))
|
|
||||||
.chain(custom_elements.iter_after_windows())
|
|
||||||
.chain(layer_map.layers_on(WlrLayer::Top).map(|l| l as &SpaceElem<R>))
|
|
||||||
.chain(custom_elements.iter_before_overlay())
|
|
||||||
.chain(layer_map.layers_on(WlrLayer::Overlay).map(|l| l as &SpaceElem<R>))
|
|
||||||
.chain(custom_elements.iter_top())
|
|
||||||
{
|
|
||||||
let geo = element.geometry(self.id);
|
let geo = element.geometry(self.id);
|
||||||
if damage.iter().any(|d| d.overlaps(geo)) {
|
if damage.iter().any(|d| d.overlaps(geo)) {
|
||||||
let loc = element.location(self.id);
|
let loc = element.location(self.id);
|
||||||
|
|
|
@ -12,6 +12,8 @@ use crate::{
|
||||||
};
|
};
|
||||||
use std::any::TypeId;
|
use std::any::TypeId;
|
||||||
|
|
||||||
|
use super::RenderZindex;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct RenderPopup {
|
pub struct RenderPopup {
|
||||||
location: Point<i32, Logical>,
|
location: Point<i32, Logical>,
|
||||||
|
@ -126,4 +128,8 @@ where
|
||||||
// popups are special, we track them, but they render with their parents
|
// popups are special, we track them, but they render with their parents
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn z_index(&self) -> u8 {
|
||||||
|
RenderZindex::PopUp as u8
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,8 @@ use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use super::RenderZindex;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct WindowState {
|
pub struct WindowState {
|
||||||
pub location: Point<i32, Logical>,
|
pub location: Point<i32, Logical>,
|
||||||
|
@ -103,4 +105,8 @@ where
|
||||||
}
|
}
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn z_index(&self) -> u8 {
|
||||||
|
RenderZindex::Top as u8
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue