Merge pull request #473 from dragonnn/render_layers
Add layer definition to RenderElement
This commit is contained in:
commit
8558253b13
|
@ -332,6 +332,12 @@ impl LayerMap {
|
||||||
self.layers.retain(|layer| layer.alive());
|
self.layers.retain(|layer| layer.alive());
|
||||||
self.surfaces.retain(|s| s.as_ref().is_alive());
|
self.surfaces.retain(|s| s.as_ref().is_alive());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 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()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
|
|
|
@ -10,6 +10,33 @@ use std::{
|
||||||
};
|
};
|
||||||
use wayland_server::protocol::wl_surface::WlSurface;
|
use wayland_server::protocol::wl_surface::WlSurface;
|
||||||
|
|
||||||
|
/// Indicates default values for some zindexs inside smithay
|
||||||
|
#[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,
|
||||||
|
/// Default zindex for Windows
|
||||||
|
Shell = 30,
|
||||||
|
/// WlrLayer::Top default zindex
|
||||||
|
Top = 40,
|
||||||
|
/// Default zindex for Windows PopUps
|
||||||
|
Popups = 50,
|
||||||
|
/// Default Layer for RenderElements
|
||||||
|
Overlay = 60,
|
||||||
|
/// Default Layer for Overlay PopUp
|
||||||
|
PopupsOverlay = 70,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Elements rendered by [`Space::render_output`] in addition to windows, layers and popups.
|
||||||
|
pub type DynamicRenderElements<R> =
|
||||||
|
Box<dyn RenderElement<R, <R as Renderer>::Frame, <R as Renderer>::Error, <R as Renderer>::TextureId>>;
|
||||||
|
|
||||||
|
pub(super) type SpaceElem<R> =
|
||||||
|
dyn SpaceElement<R, <R as Renderer>::Frame, <R as Renderer>::Error, <R as Renderer>::TextureId>;
|
||||||
|
|
||||||
/// 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
|
||||||
|
@ -58,6 +85,11 @@ where
|
||||||
damage: &[Rectangle<i32, Logical>],
|
damage: &[Rectangle<i32, Logical>],
|
||||||
log: &slog::Logger,
|
log: &slog::Logger,
|
||||||
) -> Result<(), R::Error>;
|
) -> Result<(), R::Error>;
|
||||||
|
|
||||||
|
/// Returns z_index of RenderElement, reverf too [`RenderZindex`] for default values
|
||||||
|
fn z_index(&self) -> u8 {
|
||||||
|
RenderZindex::Overlay as u8
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) trait SpaceElement<R, F, E, T>
|
pub(crate) trait SpaceElement<R, F, E, T>
|
||||||
|
@ -85,6 +117,7 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
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>>
|
||||||
|
@ -118,6 +151,10 @@ where
|
||||||
) -> Result<(), R::Error> {
|
) -> Result<(), R::Error> {
|
||||||
(&**self as &dyn RenderElement<R, F, E, T>).draw(renderer, frame, scale, location, damage, log)
|
(&**self as &dyn RenderElement<R, F, E, T>).draw(renderer, frame, scale, location, 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,18 @@ 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 {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,6 @@ use crate::{
|
||||||
wayland::{
|
wayland::{
|
||||||
compositor::{get_parent, is_sync_subsurface},
|
compositor::{get_parent, is_sync_subsurface},
|
||||||
output::Output,
|
output::Output,
|
||||||
shell::wlr_layer::Layer as WlrLayer,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use indexmap::{IndexMap, IndexSet};
|
use indexmap::{IndexMap, IndexSet};
|
||||||
|
@ -43,10 +42,6 @@ pub struct Space {
|
||||||
logger: ::slog::Logger,
|
logger: ::slog::Logger,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Elements rendered by [`Space::render_output`] in addition to windows, layers and popups.
|
|
||||||
pub type DynamicRenderElements<R> =
|
|
||||||
Box<dyn RenderElement<R, <R as Renderer>::Frame, <R as Renderer>::Error, <R as Renderer>::TextureId>>;
|
|
||||||
|
|
||||||
impl PartialEq for Space {
|
impl PartialEq for Space {
|
||||||
fn eq(&self, other: &Space) -> bool {
|
fn eq(&self, other: &Space) -> bool {
|
||||||
self.id == other.id
|
self.id == other.id
|
||||||
|
@ -415,9 +410,6 @@ impl Space {
|
||||||
return Err(RenderError::UnmappedOutput);
|
return Err(RenderError::UnmappedOutput);
|
||||||
}
|
}
|
||||||
|
|
||||||
type SpaceElem<R> =
|
|
||||||
dyn SpaceElement<R, <R as Renderer>::Frame, <R as Renderer>::Error, <R as Renderer>::TextureId>;
|
|
||||||
|
|
||||||
let mut state = output_state(self.id, output);
|
let mut state = output_state(self.id, output);
|
||||||
let output_size = output
|
let output_size = output
|
||||||
.current_mode()
|
.current_mode()
|
||||||
|
@ -439,23 +431,31 @@ impl Space {
|
||||||
.flat_map(|l| l.popup_elements::<R>(self.id))
|
.flat_map(|l| l.popup_elements::<R>(self.id))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let mut render_elements: Vec<&SpaceElem<R>> = Vec::with_capacity(
|
||||||
|
custom_elements.len()
|
||||||
|
+ layer_map.len()
|
||||||
|
+ self.windows.len()
|
||||||
|
+ window_popups.len()
|
||||||
|
+ layer_popups.len(),
|
||||||
|
);
|
||||||
|
|
||||||
|
render_elements.extend(custom_elements.iter().map(|l| l as &SpaceElem<R>));
|
||||||
|
render_elements.extend(self.windows.iter().map(|l| l as &SpaceElem<R>));
|
||||||
|
render_elements.extend(window_popups.iter().map(|l| l as &SpaceElem<R>));
|
||||||
|
render_elements.extend(layer_map.layers().map(|l| l as &SpaceElem<R>));
|
||||||
|
render_elements.extend(layer_popups.iter().map(|l| l as &SpaceElem<R>));
|
||||||
|
|
||||||
|
render_elements.sort_by_key(|e| e.z_index());
|
||||||
|
|
||||||
// This will hold all the damage we need for this rendering step
|
// This will hold all the damage we need for this rendering step
|
||||||
let mut damage = Vec::<Rectangle<i32, Logical>>::new();
|
let mut damage = Vec::<Rectangle<i32, Logical>>::new();
|
||||||
// First add damage for windows gone
|
// First add damage for windows gone
|
||||||
|
|
||||||
for old_toplevel in state
|
for old_toplevel in state
|
||||||
.last_state
|
.last_state
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|(id, geo)| {
|
.filter_map(|(id, geo)| {
|
||||||
if !self
|
if !render_elements.iter().any(|e| ToplevelId::from(*e) == *id) {
|
||||||
.windows
|
|
||||||
.iter()
|
|
||||||
.map(|w| w as &SpaceElem<R>)
|
|
||||||
.chain(window_popups.iter().map(|p| p as &SpaceElem<R>))
|
|
||||||
.chain(layer_map.layers().map(|l| l as &SpaceElem<R>))
|
|
||||||
.chain(layer_popups.iter().map(|p| p as &SpaceElem<R>))
|
|
||||||
.chain(custom_elements.iter().map(|c| c as &SpaceElem<R>))
|
|
||||||
.any(|e| ToplevelId::from(e) == *id)
|
|
||||||
{
|
|
||||||
Some(*geo)
|
Some(*geo)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -468,17 +468,9 @@ impl Space {
|
||||||
}
|
}
|
||||||
|
|
||||||
// lets iterate front to back and figure out, what new windows or unmoved windows we have
|
// lets iterate front to back and figure out, what new windows or unmoved windows we have
|
||||||
for element in self
|
for element in &render_elements {
|
||||||
.windows
|
|
||||||
.iter()
|
|
||||||
.map(|w| w as &SpaceElem<R>)
|
|
||||||
.chain(window_popups.iter().map(|p| p as &SpaceElem<R>))
|
|
||||||
.chain(layer_map.layers().map(|l| l as &SpaceElem<R>))
|
|
||||||
.chain(layer_popups.iter().map(|p| p as &SpaceElem<R>))
|
|
||||||
.chain(custom_elements.iter().map(|c| c as &SpaceElem<R>))
|
|
||||||
{
|
|
||||||
let geo = element.geometry(self.id);
|
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
|
// window was moved or resized
|
||||||
if old_geo.map(|old_geo| old_geo != geo).unwrap_or(false) {
|
if old_geo.map(|old_geo| old_geo != geo).unwrap_or(false) {
|
||||||
|
@ -551,22 +543,9 @@ impl Space {
|
||||||
.map(|geo| geo.to_f64().to_physical(state.render_scale).to_i32_round())
|
.map(|geo| geo.to_f64().to_physical(state.render_scale).to_i32_round())
|
||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// 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 layer_map
|
for element in &render_elements {
|
||||||
.layers_on(WlrLayer::Background)
|
|
||||||
.chain(layer_map.layers_on(WlrLayer::Bottom))
|
|
||||||
.map(|l| l as &SpaceElem<R>)
|
|
||||||
.chain(self.windows.iter().map(|w| w as &SpaceElem<R>))
|
|
||||||
.chain(
|
|
||||||
layer_map
|
|
||||||
.layers_on(WlrLayer::Top)
|
|
||||||
.chain(layer_map.layers_on(WlrLayer::Overlay))
|
|
||||||
.map(|l| l as &SpaceElem<R>),
|
|
||||||
)
|
|
||||||
.chain(custom_elements.iter().map(|c| c as &SpaceElem<R>))
|
|
||||||
{
|
|
||||||
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);
|
||||||
|
@ -607,17 +586,11 @@ impl Space {
|
||||||
}
|
}
|
||||||
|
|
||||||
// If rendering was successful capture the state and add the damage
|
// If rendering was successful capture the state and add the damage
|
||||||
state.last_state = self
|
state.last_state = render_elements
|
||||||
.windows
|
|
||||||
.iter()
|
.iter()
|
||||||
.map(|w| w as &SpaceElem<R>)
|
|
||||||
.chain(window_popups.iter().map(|p| p as &SpaceElem<R>))
|
|
||||||
.chain(layer_map.layers().map(|l| l as &SpaceElem<R>))
|
|
||||||
.chain(layer_popups.iter().map(|p| p as &SpaceElem<R>))
|
|
||||||
.chain(custom_elements.iter().map(|c| c as &SpaceElem<R>))
|
|
||||||
.map(|elem| {
|
.map(|elem| {
|
||||||
let geo = elem.geometry(self.id);
|
let geo = elem.geometry(self.id);
|
||||||
(ToplevelId::from(elem), geo)
|
(ToplevelId::from(*elem), geo)
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
state.old_damage.push_front(new_damage.clone());
|
state.old_damage.push_front(new_damage.clone());
|
||||||
|
|
|
@ -8,14 +8,17 @@ use crate::{
|
||||||
window::Window,
|
window::Window,
|
||||||
},
|
},
|
||||||
utils::{Logical, Point, Rectangle},
|
utils::{Logical, Point, Rectangle},
|
||||||
wayland::output::Output,
|
wayland::{output::Output, shell::wlr_layer::Layer},
|
||||||
};
|
};
|
||||||
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>,
|
||||||
popup: PopupKind,
|
popup: PopupKind,
|
||||||
|
z_index: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Window {
|
impl Window {
|
||||||
|
@ -39,6 +42,7 @@ impl Window {
|
||||||
RenderPopup {
|
RenderPopup {
|
||||||
location: offset,
|
location: offset,
|
||||||
popup,
|
popup,
|
||||||
|
z_index: RenderZindex::Popups as u8,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -48,7 +52,7 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LayerSurface {
|
impl LayerSurface {
|
||||||
pub(super) fn popup_elements<R>(&self, space_id: usize) -> impl Iterator<Item = RenderPopup>
|
pub(super) fn popup_elements<R>(&self, space_id: usize) -> impl Iterator<Item = RenderPopup> + '_
|
||||||
where
|
where
|
||||||
R: Renderer + ImportAll + 'static,
|
R: Renderer + ImportAll + 'static,
|
||||||
R::TextureId: 'static,
|
R::TextureId: 'static,
|
||||||
|
@ -67,9 +71,20 @@ impl LayerSurface {
|
||||||
.flatten()
|
.flatten()
|
||||||
.map(move |(popup, location)| {
|
.map(move |(popup, location)| {
|
||||||
let offset = loc + location - popup.geometry().loc;
|
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 {
|
RenderPopup {
|
||||||
location: offset,
|
location: offset,
|
||||||
popup,
|
popup,
|
||||||
|
z_index,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -126,4 +141,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 {
|
||||||
|
self.z_index
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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::Shell as u8
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue