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)) {