Add a SplitRenderElements type, with useful methods

`(w_elements, p_elements)` tuples are used in a bunch of places. A
struct with named fields is generally an improvement just due to the
fact the order is non-obvious.

But we can also add methods. In particular,
`extend_from_workspace_elements` abstracts out some of the more
redundant code in `workspace_elements`.

It would be nice to avoid allocation everywhere, but iterators would
complicate lifetimes, run into issues with needing multiple mutable
borrows to things like the `Renderer`, and be awkward in certain
functions without generator syntax. In any case, cosmic-comp already
relies on allocating vectors here.

If this abstraction is commonly useful in compositors, perhaps it could
be moved to Smithay.
This commit is contained in:
Ian Douglas Scott 2024-07-09 15:21:16 -07:00 committed by Victoria Brekenfeld
parent c506d94ac8
commit 94fecec9cb
9 changed files with 374 additions and 379 deletions

View file

@ -58,7 +58,7 @@ use smithay::{
desktop::{layer_map_for_output, PopupManager},
input::Seat,
output::{Output, OutputNoMode},
utils::{IsAlive, Logical, Monotonic, Point, Rectangle, Scale, Time, Transform},
utils::{IsAlive, Logical, Monotonic, Physical, Point, Rectangle, Scale, Time, Transform},
wayland::{
dmabuf::get_dmabuf,
shell::wlr_layer::Layer,
@ -464,6 +464,60 @@ where
#[cfg(not(feature = "debug"))]
pub type EguiState = ();
#[derive(Clone, Debug)]
pub struct SplitRenderElements<E> {
pub w_elements: Vec<E>,
pub p_elements: Vec<E>,
}
impl<E> Default for SplitRenderElements<E> {
fn default() -> Self {
Self {
w_elements: Vec::new(),
p_elements: Vec::new(),
}
}
}
impl<E> SplitRenderElements<E> {
pub fn extend(&mut self, other: Self) {
self.w_elements.extend(other.w_elements);
self.p_elements.extend(other.p_elements);
}
pub fn extend_map<E2, F: FnMut(E2) -> E>(&mut self, other: SplitRenderElements<E2>, mut f: F) {
self.w_elements
.extend(other.w_elements.into_iter().map(&mut f));
self.p_elements
.extend(other.p_elements.into_iter().map(&mut f));
}
pub fn join(mut self) -> Vec<E> {
self.p_elements.extend(self.w_elements);
self.p_elements
}
}
impl<R> SplitRenderElements<CosmicElement<R>>
where
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
CosmicMappedRenderElement<R>: RenderElement<R>,
{
fn extend_from_workspace_elements<E: Into<WorkspaceRenderElement<R>>>(
&mut self,
other: SplitRenderElements<E>,
offset: Point<i32, Physical>,
) {
self.extend_map(other, |element| {
CosmicElement::Workspace(RelocateRenderElement::from_element(
element.into(),
offset,
Relocate::Relative,
))
})
}
}
#[profiling::function]
pub fn workspace_elements<R>(
_gpu: Option<&DrmNode>,
@ -484,6 +538,8 @@ where
CosmicMappedRenderElement<R>: RenderElement<R>,
WorkspaceRenderElement<R>: RenderElement<R>,
{
let mut elements = SplitRenderElements::default();
let theme = shell.read().unwrap().theme().clone();
let seats = shell
.read()
@ -493,7 +549,7 @@ where
.cloned()
.collect::<Vec<_>>();
let mut elements = cursor_elements(
elements.p_elements.extend(cursor_elements(
renderer,
seats.iter(),
&theme,
@ -501,7 +557,7 @@ where
output,
cursor_mode,
exclude_workspace_overview,
);
));
#[cfg(feature = "debug")]
{
@ -525,7 +581,7 @@ where
)
.map_err(FromGlesError::from_gles_error)
.map_err(RenderError::Rendering)?;
elements.push(fps_overlay.into());
elements.p_elements.push(fps_overlay.into());
}
}
@ -533,12 +589,12 @@ where
// If session locked, only show session lock surfaces
if let Some(session_lock) = &shell.session_lock {
elements.extend(
elements.p_elements.extend(
session_lock_elements(renderer, output, session_lock)
.into_iter()
.map(|x| WorkspaceRenderElement::from(x).into()),
);
return Ok(elements);
return Ok(elements.join());
}
let theme = theme.cosmic();
@ -586,20 +642,22 @@ where
.as_ref()
.filter(|f| !f.is_animating())
.is_some();
let (overlay_elements, overlay_popups) =
let overlay_elements =
split_layer_elements(renderer, output, Layer::Overlay, exclude_workspace_overview);
// overlay is above everything
elements.extend(overlay_popups.into_iter().map(Into::into));
elements.extend(overlay_elements.into_iter().map(Into::into));
elements
.p_elements
.extend(overlay_elements.p_elements.into_iter().map(Into::into));
elements
.p_elements
.extend(overlay_elements.w_elements.into_iter().map(Into::into));
let mut window_elements = if !has_fullscreen {
let (top_elements, top_popups) =
split_layer_elements(renderer, output, Layer::Top, exclude_workspace_overview);
elements.extend(top_popups.into_iter().map(Into::into));
top_elements.into_iter().map(Into::into).collect()
} else {
Vec::new()
if !has_fullscreen {
elements.extend_from_workspace_elements(
split_layer_elements(renderer, output, Layer::Top, exclude_workspace_overview),
(0, 0).into(),
);
};
let active_hint = if shell.active_hint {
@ -611,7 +669,7 @@ where
// overlay redirect windows
// they need to be over sticky windows, because they could be popups of sticky windows,
// and we can't differenciate that.
elements.extend(
elements.p_elements.extend(
shell
.override_redirect_windows
.iter()
@ -632,13 +690,7 @@ where
1.0,
)
})
.map(|p_element| {
CosmicElement::Workspace(RelocateRenderElement::from_element(
p_element,
(0, 0),
Relocate::Relative,
))
}),
.map(|p_element| p_element.into()),
);
// sticky windows
@ -665,29 +717,17 @@ where
.then_some(last_active_seat)
.map(|seat| workspace.focus_stack.get(seat));
let (w_elements, p_elements) = set.sticky_layer.render(
renderer,
current_focus.as_ref().and_then(|stack| stack.last()),
resize_indicator.clone(),
active_hint,
alpha,
theme,
elements.extend_from_workspace_elements(
set.sticky_layer.render(
renderer,
current_focus.as_ref().and_then(|stack| stack.last()),
resize_indicator.clone(),
active_hint,
alpha,
theme,
),
(0, 0).into(),
);
elements.extend(p_elements.into_iter().map(|p_element| {
CosmicElement::Workspace(RelocateRenderElement::from_element(
WorkspaceRenderElement::Window(p_element),
(0, 0),
Relocate::Relative,
))
}));
window_elements.extend(w_elements.into_iter().map(|w_element| {
CosmicElement::Workspace(RelocateRenderElement::from_element(
WorkspaceRenderElement::Window(w_element),
(0, 0),
Relocate::Relative,
))
}));
}
let offset = match previous.as_ref() {
@ -729,48 +769,25 @@ where
}
});
let (w_elements, p_elements) = workspace
.render::<R>(
renderer,
(!move_active && is_active_space).then_some(last_active_seat),
overview.clone(),
resize_indicator.clone(),
active_hint,
theme,
)
.map_err(|_| OutputNoMode)?;
elements.extend(p_elements.into_iter().map(|p_element| {
CosmicElement::Workspace(RelocateRenderElement::from_element(
p_element,
offset.to_physical_precise_round(output_scale),
Relocate::Relative,
))
}));
window_elements.extend(w_elements.into_iter().map(|w_element| {
CosmicElement::Workspace(RelocateRenderElement::from_element(
w_element,
offset.to_physical_precise_round(output_scale),
Relocate::Relative,
))
}));
elements.extend_from_workspace_elements(
workspace
.render::<R>(
renderer,
(!move_active && is_active_space).then_some(last_active_seat),
overview.clone(),
resize_indicator.clone(),
active_hint,
theme,
)
.map_err(|_| OutputNoMode)?,
offset.to_physical_precise_round(output_scale),
);
if !has_fullscreen {
let (w_elements, p_elements) =
background_layer_elements(renderer, output, exclude_workspace_overview);
elements.extend(p_elements.into_iter().map(|p_element| {
CosmicElement::Workspace(RelocateRenderElement::from_element(
p_element,
offset.to_physical_precise_round(output_scale),
Relocate::Relative,
))
}));
window_elements.extend(w_elements.into_iter().map(|w_element| {
CosmicElement::Workspace(RelocateRenderElement::from_element(
w_element,
offset.to_physical_precise_round(output_scale),
Relocate::Relative,
))
}));
elements.extend_from_workspace_elements(
background_layer_elements(renderer, output, exclude_workspace_overview),
offset.to_physical_precise_round(output_scale),
);
}
Point::<i32, Logical>::from(match (layout, *previous_idx < current.1) {
@ -783,55 +800,28 @@ where
None => (0, 0).into(),
};
let (w_elements, p_elements) = workspace
.render::<R>(
renderer,
(!move_active && is_active_space).then_some(&last_active_seat),
overview,
resize_indicator,
active_hint,
theme,
)
.map_err(|_| OutputNoMode)?;
elements.extend(p_elements.into_iter().map(|p_element| {
CosmicElement::Workspace(RelocateRenderElement::from_element(
p_element,
offset.to_physical_precise_round(output_scale),
Relocate::Relative,
))
}));
window_elements.extend(w_elements.into_iter().map(|w_element| {
CosmicElement::Workspace(RelocateRenderElement::from_element(
w_element,
offset.to_physical_precise_round(output_scale),
Relocate::Relative,
))
}));
elements.extend_from_workspace_elements(
workspace
.render::<R>(
renderer,
(!move_active && is_active_space).then_some(&last_active_seat),
overview,
resize_indicator,
active_hint,
theme,
)
.map_err(|_| OutputNoMode)?,
offset.to_physical_precise_round(output_scale),
);
if !has_fullscreen {
let (w_elements, p_elements) =
background_layer_elements(renderer, output, exclude_workspace_overview);
elements.extend(p_elements.into_iter().map(|p_element| {
CosmicElement::Workspace(RelocateRenderElement::from_element(
p_element,
offset.to_physical_precise_round(output_scale),
Relocate::Relative,
))
}));
window_elements.extend(w_elements.into_iter().map(|w_element| {
CosmicElement::Workspace(RelocateRenderElement::from_element(
w_element,
offset.to_physical_precise_round(output_scale),
Relocate::Relative,
))
}));
elements.extend_from_workspace_elements(
background_layer_elements(renderer, output, exclude_workspace_overview),
offset.to_physical_precise_round(output_scale),
);
}
elements.extend(window_elements);
Ok(elements)
Ok(elements.join())
}
pub fn split_layer_elements<R>(
@ -839,10 +829,7 @@ pub fn split_layer_elements<R>(
output: &Output,
layer: Layer,
exclude_workspace_overview: bool,
) -> (
Vec<WorkspaceRenderElement<R>>,
Vec<WorkspaceRenderElement<R>>,
)
) -> SplitRenderElements<WorkspaceRenderElement<R>>
where
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
<R as Renderer>::TextureId: Clone + 'static,
@ -853,8 +840,7 @@ where
let layer_map = layer_map_for_output(output);
let output_scale = output.current_scale().fractional_scale();
let mut popup_elements = Vec::new();
let mut layer_elements = Vec::new();
let mut elements = SplitRenderElements::default();
layer_map
.layers_on(layer)
@ -870,35 +856,39 @@ where
let surface = surface.wl_surface();
let scale = Scale::from(output_scale);
popup_elements.extend(PopupManager::popups_for_surface(surface).flat_map(
|(popup, popup_offset)| {
let offset = (popup_offset - popup.geometry().loc)
.to_f64()
.to_physical(scale)
.to_i32_round();
elements
.p_elements
.extend(PopupManager::popups_for_surface(surface).flat_map(
|(popup, popup_offset)| {
let offset = (popup_offset - popup.geometry().loc)
.to_f64()
.to_physical(scale)
.to_i32_round();
render_elements_from_surface_tree(
renderer,
popup.wl_surface(),
location + offset,
scale,
1.0,
Kind::Unspecified,
)
},
));
render_elements_from_surface_tree(
renderer,
popup.wl_surface(),
location + offset,
scale,
1.0,
Kind::Unspecified,
)
},
));
layer_elements.extend(render_elements_from_surface_tree(
renderer,
surface,
location,
scale,
1.0,
Kind::Unspecified,
));
elements
.w_elements
.extend(render_elements_from_surface_tree(
renderer,
surface,
location,
scale,
1.0,
Kind::Unspecified,
));
});
(layer_elements, popup_elements)
elements
}
// bottom and background layer surfaces
@ -906,10 +896,7 @@ pub fn background_layer_elements<R>(
renderer: &mut R,
output: &Output,
exclude_workspace_overview: bool,
) -> (
Vec<WorkspaceRenderElement<R>>,
Vec<WorkspaceRenderElement<R>>,
)
) -> SplitRenderElements<WorkspaceRenderElement<R>>
where
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
<R as Renderer>::TextureId: Clone + 'static,
@ -917,17 +904,15 @@ where
CosmicMappedRenderElement<R>: RenderElement<R>,
WorkspaceRenderElement<R>: RenderElement<R>,
{
let (mut layer_elements, mut popup_elements) =
let mut elements =
split_layer_elements(renderer, output, Layer::Bottom, exclude_workspace_overview);
let more = split_layer_elements(
elements.extend(split_layer_elements(
renderer,
output,
Layer::Background,
exclude_workspace_overview,
);
layer_elements.extend(more.0);
popup_elements.extend(more.1);
(layer_elements, popup_elements)
));
elements
}
fn session_lock_elements<R>(

View file

@ -1,7 +1,7 @@
use crate::{
backend::render::{
element::{AsGlowFrame, AsGlowRenderer},
GlMultiError, GlMultiFrame, GlMultiRenderer,
GlMultiError, GlMultiFrame, GlMultiRenderer, SplitRenderElements,
},
state::State,
utils::{iced::IcedElementInternal, prelude::*},
@ -663,7 +663,7 @@ impl CosmicMapped {
location: smithay::utils::Point<i32, smithay::utils::Physical>,
scale: smithay::utils::Scale<f64>,
alpha: f32,
) -> (Vec<C>, Vec<C>)
) -> SplitRenderElements<C>
where
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
<R as Renderer>::TextureId: Send + Clone + 'static,
@ -842,27 +842,28 @@ impl CosmicMapped {
#[cfg(not(feature = "debug"))]
let debug_elements = Vec::new();
#[cfg_attr(not(feature = "debug"), allow(unused_mut))]
let (window_elements, popup_elements) = match &self.element {
CosmicMappedInternal::Stack(s) => s
.split_render_elements::<R, CosmicMappedRenderElement<R>>(
renderer, location, scale, alpha,
),
CosmicMappedInternal::Window(w) => w
.split_render_elements::<R, CosmicMappedRenderElement<R>>(
renderer, location, scale, alpha,
),
_ => unreachable!(),
let mut elements = SplitRenderElements {
w_elements: debug_elements,
p_elements: Vec::new(),
};
(
debug_elements
.into_iter()
.map(C::from)
.chain(window_elements.into_iter().map(C::from))
.collect(),
popup_elements.into_iter().map(C::from).collect(),
)
#[cfg_attr(not(feature = "debug"), allow(unused_mut))]
elements.extend_map(
match &self.element {
CosmicMappedInternal::Stack(s) => s
.split_render_elements::<R, CosmicMappedRenderElement<R>>(
renderer, location, scale, alpha,
),
CosmicMappedInternal::Window(w) => w
.split_render_elements::<R, CosmicMappedRenderElement<R>>(
renderer, location, scale, alpha,
),
_ => unreachable!(),
},
C::from,
);
elements
}
pub(crate) fn update_theme(&self, theme: cosmic::Theme) {

View file

@ -1,6 +1,9 @@
use super::{surface::RESIZE_BORDER, window::Focus, CosmicSurface};
use crate::{
backend::render::cursor::{CursorShape, CursorState},
backend::render::{
cursor::{CursorShape, CursorState},
SplitRenderElements,
},
shell::{
focus::target::PointerFocusTarget,
grabs::{ReleaseMode, ResizeEdge},
@ -547,7 +550,7 @@ impl CosmicStack {
location: Point<i32, Physical>,
scale: Scale<f64>,
alpha: f32,
) -> (Vec<C>, Vec<C>)
) -> SplitRenderElements<C>
where
R: Renderer + ImportAll + ImportMem,
<R as Renderer>::TextureId: Send + Clone + 'static,
@ -564,30 +567,28 @@ impl CosmicStack {
let stack_loc = location + offset;
let window_loc = location + Point::from((0, (TAB_HEIGHT as f64 * scale.y) as i32));
let elements = AsRenderElements::<R>::render_elements::<CosmicStackRenderElement<R>>(
let w_elements = AsRenderElements::<R>::render_elements::<CosmicStackRenderElement<R>>(
&self.0, renderer, stack_loc, scale, alpha,
);
let (window_elements, popup_elements) = self.0.with_program(|p| {
let windows = p.windows.lock().unwrap();
let active = p.active.load(Ordering::SeqCst);
let mut elements = SplitRenderElements {
w_elements: w_elements.into_iter().map(C::from).collect(),
p_elements: Vec::new(),
};
let (window_elements, popup_elements) = windows[active]
.split_render_elements::<R, CosmicStackRenderElement<R>>(
elements.extend_map(
self.0.with_program(|p| {
let windows = p.windows.lock().unwrap();
let active = p.active.load(Ordering::SeqCst);
windows[active].split_render_elements::<R, CosmicStackRenderElement<R>>(
renderer, window_loc, scale, alpha,
);
)
}),
C::from,
);
(window_elements, popup_elements)
});
(
elements
.into_iter()
.map(C::from)
.chain(window_elements.into_iter().map(C::from))
.collect(),
popup_elements.into_iter().map(C::from).collect(),
)
elements
}
pub(crate) fn set_theme(&self, theme: cosmic::Theme) {

View file

@ -42,6 +42,7 @@ use smithay::{
};
use crate::{
backend::render::SplitRenderElements,
state::{State, SurfaceDmabufFeedback},
utils::prelude::*,
wayland::handlers::decoration::PreferredDecorationMode,
@ -563,7 +564,7 @@ impl CosmicSurface {
location: smithay::utils::Point<i32, smithay::utils::Physical>,
scale: smithay::utils::Scale<f64>,
alpha: f32,
) -> (Vec<C>, Vec<C>)
) -> SplitRenderElements<C>
where
R: Renderer + ImportAll,
<R as Renderer>::TextureId: Clone + 'static,
@ -573,7 +574,7 @@ impl CosmicSurface {
WindowSurface::Wayland(toplevel) => {
let surface = toplevel.wl_surface();
let popup_render_elements = PopupManager::popups_for_surface(surface)
let p_elements = PopupManager::popups_for_surface(surface)
.flat_map(|(popup, popup_offset)| {
let offset = (self.0.geometry().loc + popup_offset - popup.geometry().loc)
.to_physical_precise_round(scale);
@ -589,7 +590,7 @@ impl CosmicSurface {
})
.collect();
let window_render_elements = render_elements_from_surface_tree(
let w_elements = render_elements_from_surface_tree(
renderer,
surface,
location,
@ -598,12 +599,15 @@ impl CosmicSurface {
element::Kind::Unspecified,
);
(window_render_elements, popup_render_elements)
SplitRenderElements {
w_elements,
p_elements,
}
}
WindowSurface::X11(surface) => (
surface.render_elements(renderer, location, scale, alpha),
Vec::new(),
),
WindowSurface::X11(surface) => SplitRenderElements {
w_elements: surface.render_elements(renderer, location, scale, alpha),
p_elements: Vec::new(),
},
}
}

View file

@ -1,5 +1,8 @@
use crate::{
backend::render::cursor::{CursorShape, CursorState},
backend::render::{
cursor::{CursorShape, CursorState},
SplitRenderElements,
},
shell::{
focus::target::PointerFocusTarget,
grabs::{ReleaseMode, ResizeEdge},
@ -317,7 +320,7 @@ impl CosmicWindow {
location: smithay::utils::Point<i32, smithay::utils::Physical>,
scale: smithay::utils::Scale<f64>,
alpha: f32,
) -> (Vec<C>, Vec<C>)
) -> SplitRenderElements<C>
where
R: Renderer + ImportAll + ImportMem,
<R as Renderer>::TextureId: Send + Clone + 'static,
@ -331,12 +334,17 @@ impl CosmicWindow {
location
};
let (mut window_elements, popup_elements) = self.0.with_program(|p| {
p.window
.split_render_elements::<R, CosmicWindowRenderElement<R>>(
renderer, window_loc, scale, alpha,
)
});
let mut elements = SplitRenderElements::default();
elements.extend_map(
self.0.with_program(|p| {
p.window
.split_render_elements::<R, CosmicWindowRenderElement<R>>(
renderer, window_loc, scale, alpha,
)
}),
C::from,
);
if has_ssd {
let ssd_loc = location
@ -344,15 +352,16 @@ impl CosmicWindow {
.0
.with_program(|p| p.window.geometry().loc)
.to_physical_precise_round(scale);
window_elements.extend(AsRenderElements::<R>::render_elements::<
CosmicWindowRenderElement<R>,
>(&self.0, renderer, ssd_loc, scale, alpha))
elements.w_elements.extend(
AsRenderElements::<R>::render_elements::<CosmicWindowRenderElement<R>>(
&self.0, renderer, ssd_loc, scale, alpha,
)
.into_iter()
.map(C::from),
)
}
(
window_elements.into_iter().map(C::from).collect(),
popup_elements.into_iter().map(C::from).collect(),
)
elements
}
pub(crate) fn set_theme(&self, theme: cosmic::Theme) {

View file

@ -4,7 +4,7 @@ use crate::{
backend::render::{
cursor::{CursorShape, CursorState},
element::AsGlowRenderer,
BackdropShader, IndicatorShader, Key, Usage,
BackdropShader, IndicatorShader, Key, SplitRenderElements, Usage,
},
shell::{
element::{
@ -182,7 +182,10 @@ impl MoveGrabState {
_ => vec![],
};
let (window_elements, popup_elements) = self
let SplitRenderElements {
w_elements,
p_elements,
} = self
.window
.split_render_elements::<R, CosmicMappedRenderElement<R>>(
renderer,
@ -202,9 +205,9 @@ impl MoveGrabState {
1.0,
)
})
.chain(popup_elements)
.chain(p_elements)
.chain(focus_element)
.chain(window_elements.into_iter().map(|elem| match elem {
.chain(w_elements.into_iter().map(|elem| match elem {
CosmicMappedRenderElement::Stack(stack) => {
CosmicMappedRenderElement::GrabbedStack(
RescaleRenderElement::from_element(

View file

@ -24,7 +24,7 @@ use smithay::{
};
use crate::{
backend::render::{element::AsGlowRenderer, IndicatorShader, Key, Usage},
backend::render::{element::AsGlowRenderer, IndicatorShader, Key, SplitRenderElements, Usage},
shell::{
element::{
resize_indicator::ResizeIndicator,
@ -1270,10 +1270,7 @@ impl FloatingLayout {
indicator_thickness: u8,
alpha: f32,
theme: &cosmic::theme::CosmicTheme,
) -> (
Vec<CosmicMappedRenderElement<R>>,
Vec<CosmicMappedRenderElement<R>>,
)
) -> SplitRenderElements<CosmicMappedRenderElement<R>>
where
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
<R as Renderer>::TextureId: Send + Clone + 'static,
@ -1288,8 +1285,7 @@ impl FloatingLayout {
};
let output_scale = output.current_scale().fractional_scale();
let mut window_elements = Vec::new();
let mut popup_elements = Vec::new();
let mut elements = SplitRenderElements::default();
for elem in self
.animations
@ -1305,7 +1301,10 @@ impl FloatingLayout {
.unwrap_or_else(|| (self.space.element_geometry(elem).unwrap().as_local(), alpha));
let render_location = geometry.loc - elem.geometry().loc.as_local();
let (mut w_elements, p_elements) = elem.split_render_elements(
let SplitRenderElements {
mut w_elements,
p_elements,
} = elem.split_render_elements(
renderer,
render_location
.as_logical()
@ -1388,7 +1387,7 @@ impl FloatingLayout {
resize.resize(resize_geometry.size.as_logical());
resize.output_enter(output, Rectangle::default() /* unused */);
window_elements.extend(
elements.w_elements.extend(
resize
.render_elements::<CosmicWindowRenderElement<R>>(
renderer,
@ -1420,15 +1419,15 @@ impl FloatingLayout {
active_window_hint.blue,
],
);
window_elements.push(element.into());
elements.w_elements.push(element.into());
}
}
window_elements.extend(w_elements);
popup_elements.extend(p_elements);
elements.w_elements.extend(w_elements);
elements.p_elements.extend(p_elements);
}
(window_elements, popup_elements)
elements
}
fn gaps(&self) -> (i32, i32) {

View file

@ -2,8 +2,8 @@
use crate::{
backend::render::{
element::AsGlowRenderer, BackdropShader, IndicatorShader, Key, Usage, ACTIVE_GROUP_COLOR,
GROUP_COLOR,
element::AsGlowRenderer, BackdropShader, IndicatorShader, Key, SplitRenderElements, Usage,
ACTIVE_GROUP_COLOR, GROUP_COLOR,
},
shell::{
element::{
@ -3849,13 +3849,7 @@ impl TilingLayout {
resize_indicator: Option<(ResizeMode, ResizeIndicator)>,
indicator_thickness: u8,
theme: &cosmic::theme::CosmicTheme,
) -> Result<
(
Vec<CosmicMappedRenderElement<R>>,
Vec<CosmicMappedRenderElement<R>>,
),
OutputNotMapped,
>
) -> Result<SplitRenderElements<CosmicMappedRenderElement<R>>, OutputNotMapped>
where
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
<R as Renderer>::TextureId: Send + Clone + 'static,
@ -3888,8 +3882,7 @@ impl TilingLayout {
};
let draw_groups = overview.0.alpha();
let mut window_elements = Vec::new();
let mut popup_elements = Vec::new();
let mut elements = SplitRenderElements::default();
let is_overview = !matches!(overview.0, OverviewMode::None);
let is_mouse_tiling = (matches!(overview.0.trigger(), Some(Trigger::Pointer(_))))
@ -3924,7 +3917,7 @@ impl TilingLayout {
.unzip();
// all old windows we want to fade out
let (w_elements, p_elements) = render_old_tree(
elements.extend(render_old_tree(
reference_tree,
target_tree,
renderer,
@ -3934,9 +3927,7 @@ impl TilingLayout {
indicator_thickness,
swap_desc.is_some(),
theme,
);
window_elements.extend(w_elements);
popup_elements.extend(p_elements);
));
geometries
} else {
@ -3964,7 +3955,7 @@ impl TilingLayout {
.unzip();
// all alive windows
let (w_elements, p_elements) = render_new_tree(
elements.extend(render_new_tree(
target_tree,
reference_tree,
renderer,
@ -3992,16 +3983,14 @@ impl TilingLayout {
&self.swapping_stack_surface_id,
&self.placeholder_id,
theme,
);
window_elements.extend(w_elements);
popup_elements.extend(p_elements);
));
// tiling hints
if let Some(group_elements) = group_elements {
window_elements.extend(group_elements);
elements.w_elements.extend(group_elements);
}
Ok((window_elements, popup_elements))
Ok(elements)
}
fn gaps(&self) -> (i32, i32) {
@ -4697,10 +4686,7 @@ fn render_old_tree<R>(
indicator_thickness: u8,
is_swap_mode: bool,
theme: &cosmic::theme::CosmicTheme,
) -> (
Vec<CosmicMappedRenderElement<R>>,
Vec<CosmicMappedRenderElement<R>>,
)
) -> SplitRenderElements<CosmicMappedRenderElement<R>>
where
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
<R as Renderer>::TextureId: Send + Clone + 'static,
@ -4709,8 +4695,7 @@ where
CosmicStackRenderElement<R>: RenderElement<R>,
{
let window_hint = crate::theme::active_window_hint(theme);
let mut window_elements = Vec::new();
let mut popup_elements = Vec::new();
let mut elements = SplitRenderElements::default();
if let Some(root) = reference_tree.root_node_id() {
let geometries = geometries.unwrap_or_default();
@ -4780,62 +4765,68 @@ where
};
let elem_geometry = mapped.geometry().to_physical_precise_round(output_scale);
let (w_elements, p_elements) = mapped
.split_render_elements::<R, CosmicMappedRenderElement<R>>(
renderer,
geo.loc.as_logical().to_physical_precise_round(output_scale)
- elem_geometry.loc,
Scale::from(output_scale),
alpha,
);
let SplitRenderElements {
w_elements,
p_elements,
} = mapped.split_render_elements::<R, CosmicMappedRenderElement<R>>(
renderer,
geo.loc.as_logical().to_physical_precise_round(output_scale)
- elem_geometry.loc,
Scale::from(output_scale),
alpha,
);
window_elements.extend(w_elements.into_iter().flat_map(|element| {
match element {
CosmicMappedRenderElement::Stack(elem) => constrain_render_elements(
std::iter::once(elem),
geo.loc.as_logical().to_physical_precise_round(output_scale)
- elem_geometry.loc,
geo.as_logical().to_physical_precise_round(output_scale),
elem_geometry,
ConstrainScaleBehavior::Stretch,
ConstrainAlign::CENTER,
output_scale,
)
.next()
.map(CosmicMappedRenderElement::TiledStack),
CosmicMappedRenderElement::Window(elem) => constrain_render_elements(
std::iter::once(elem),
geo.loc.as_logical().to_physical_precise_round(output_scale)
- elem_geometry.loc,
geo.as_logical().to_physical_precise_round(output_scale),
elem_geometry,
ConstrainScaleBehavior::Stretch,
ConstrainAlign::CENTER,
output_scale,
)
.next()
.map(CosmicMappedRenderElement::TiledWindow),
x => Some(x),
}
}));
elements
.w_elements
.extend(w_elements.into_iter().flat_map(|element| {
match element {
CosmicMappedRenderElement::Stack(elem) => constrain_render_elements(
std::iter::once(elem),
geo.loc.as_logical().to_physical_precise_round(output_scale)
- elem_geometry.loc,
geo.as_logical().to_physical_precise_round(output_scale),
elem_geometry,
ConstrainScaleBehavior::Stretch,
ConstrainAlign::CENTER,
output_scale,
)
.next()
.map(CosmicMappedRenderElement::TiledStack),
CosmicMappedRenderElement::Window(elem) => constrain_render_elements(
std::iter::once(elem),
geo.loc.as_logical().to_physical_precise_round(output_scale)
- elem_geometry.loc,
geo.as_logical().to_physical_precise_round(output_scale),
elem_geometry,
ConstrainScaleBehavior::Stretch,
ConstrainAlign::CENTER,
output_scale,
)
.next()
.map(CosmicMappedRenderElement::TiledWindow),
x => Some(x),
}
}));
if minimize_geo.is_some() && indicator_thickness > 0 {
window_elements.push(CosmicMappedRenderElement::FocusIndicator(
IndicatorShader::focus_element(
renderer,
Key::Window(Usage::FocusIndicator, mapped.clone().key()),
geo,
indicator_thickness,
output_scale,
alpha,
[window_hint.red, window_hint.green, window_hint.blue],
),
));
elements
.w_elements
.push(CosmicMappedRenderElement::FocusIndicator(
IndicatorShader::focus_element(
renderer,
Key::Window(Usage::FocusIndicator, mapped.clone().key()),
geo,
indicator_thickness,
output_scale,
alpha,
[window_hint.red, window_hint.green, window_hint.blue],
),
));
}
popup_elements.extend(p_elements);
elements.p_elements.extend(p_elements);
});
}
(window_elements, popup_elements)
elements
}
fn render_new_tree<R>(
@ -4857,10 +4848,7 @@ fn render_new_tree<R>(
swapping_stack_surface_id: &Id,
placeholder_id: &Id,
theme: &cosmic::theme::CosmicTheme,
) -> (
Vec<CosmicMappedRenderElement<R>>,
Vec<CosmicMappedRenderElement<R>>,
)
) -> SplitRenderElements<CosmicMappedRenderElement<R>>
where
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
<R as Renderer>::TextureId: Send + Clone + 'static,
@ -5249,15 +5237,17 @@ where
if let Data::Mapped { mapped, .. } = data {
let elem_geometry = mapped.geometry().to_physical_precise_round(output_scale);
let (mut w_elements, p_elements) = mapped
.split_render_elements::<R, CosmicMappedRenderElement<R>>(
renderer,
//original_location,
geo.loc.as_logical().to_physical_precise_round(output_scale)
- elem_geometry.loc,
Scale::from(output_scale),
alpha,
);
let SplitRenderElements {
mut w_elements,
p_elements,
} = mapped.split_render_elements::<R, CosmicMappedRenderElement<R>>(
renderer,
//original_location,
geo.loc.as_logical().to_physical_precise_round(output_scale)
- elem_geometry.loc,
Scale::from(output_scale),
alpha,
);
if swap_desc
.as_ref()
.filter(|swap_desc| swap_desc.node == node_id)
@ -5376,7 +5366,10 @@ where
.chain(group_backdrop.into_iter().map(Into::into))
.collect();
(window_elements, popup_elements)
SplitRenderElements {
w_elements: window_elements,
p_elements: popup_elements,
}
}
fn scale_to_center<C>(

View file

@ -1,7 +1,7 @@
use crate::{
backend::render::{
element::{AsGlowFrame, AsGlowRenderer},
BackdropShader, GlMultiError, GlMultiFrame, GlMultiRenderer,
BackdropShader, GlMultiError, GlMultiFrame, GlMultiRenderer, SplitRenderElements,
},
shell::{
layout::{floating::FloatingLayout, tiling::TilingLayout},
@ -1005,13 +1005,7 @@ impl Workspace {
resize_indicator: Option<(ResizeMode, ResizeIndicator)>,
indicator_thickness: u8,
theme: &CosmicTheme,
) -> Result<
(
Vec<WorkspaceRenderElement<R>>,
Vec<WorkspaceRenderElement<R>>,
),
OutputNotMapped,
>
) -> Result<SplitRenderElements<WorkspaceRenderElement<R>>, OutputNotMapped>
where
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
<R as Renderer>::TextureId: Send + Clone + 'static,
@ -1020,8 +1014,7 @@ impl Workspace {
CosmicStackRenderElement<R>: RenderElement<R>,
WorkspaceRenderElement<R>: RenderElement<R>,
{
let mut window_elements = Vec::new();
let mut popup_elements = Vec::new();
let mut elements = SplitRenderElements::default();
let output_scale = self.output.current_scale().fractional_scale();
let zone = {
@ -1104,7 +1097,10 @@ impl Workspace {
y: target_geo.size.h as f64 / bbox.size.h as f64,
};
let (w_elements, p_elements) = fullscreen
let SplitRenderElements {
w_elements,
p_elements,
} = fullscreen
.surface
.split_render_elements::<R, CosmicWindowRenderElement<R>>(
renderer,
@ -1112,13 +1108,15 @@ impl Workspace {
output_scale.into(),
alpha,
);
window_elements.extend(
elements.w_elements.extend(
w_elements
.into_iter()
.map(|elem| RescaleRenderElement::from_element(elem, render_loc, scale))
.map(Into::into),
);
popup_elements.extend(p_elements.into_iter().map(Into::into));
elements
.p_elements
.extend(p_elements.into_iter().map(Into::into))
}
if self
@ -1150,16 +1148,17 @@ impl Workspace {
OverviewMode::None => 1.0,
};
let (w_elements, p_elements) = self.floating_layer.render::<R>(
renderer,
focused.as_ref(),
resize_indicator.clone(),
indicator_thickness,
alpha,
theme,
elements.extend_map(
self.floating_layer.render::<R>(
renderer,
focused.as_ref(),
resize_indicator.clone(),
indicator_thickness,
alpha,
theme,
),
WorkspaceRenderElement::from,
);
popup_elements.extend(p_elements.into_iter().map(WorkspaceRenderElement::from));
window_elements.extend(w_elements.into_iter().map(WorkspaceRenderElement::from));
let alpha = match &overview.0 {
OverviewMode::Started(_, start) => Some(
@ -1175,20 +1174,21 @@ impl Workspace {
};
//tiling surfaces
let (w_elements, p_elements) = self.tiling_layer.render::<R>(
renderer,
draw_focus_indicator,
zone,
overview,
resize_indicator,
indicator_thickness,
theme,
)?;
popup_elements.extend(p_elements.into_iter().map(WorkspaceRenderElement::from));
window_elements.extend(w_elements.into_iter().map(WorkspaceRenderElement::from));
elements.extend_map(
self.tiling_layer.render::<R>(
renderer,
draw_focus_indicator,
zone,
overview,
resize_indicator,
indicator_thickness,
theme,
)?,
WorkspaceRenderElement::from,
);
if let Some(alpha) = alpha {
window_elements.push(
elements.w_elements.push(
Into::<CosmicMappedRenderElement<R>>::into(BackdropShader::element(
renderer,
self.backdrop_id.clone(),
@ -1205,7 +1205,7 @@ impl Workspace {
}
}
Ok((window_elements, popup_elements))
Ok(elements)
}
}