From 94fecec9cb4a13a677765c2a092b629e8083ea81 Mon Sep 17 00:00:00 2001 From: Ian Douglas Scott Date: Tue, 9 Jul 2024 15:21:16 -0700 Subject: [PATCH] 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. --- src/backend/render/mod.rs | 329 +++++++++++++++---------------- src/shell/element/mod.rs | 43 ++-- src/shell/element/stack.rs | 41 ++-- src/shell/element/surface.rs | 20 +- src/shell/element/window.rs | 39 ++-- src/shell/grabs/moving.rs | 11 +- src/shell/layout/floating/mod.rs | 25 ++- src/shell/layout/tiling/mod.rs | 175 ++++++++-------- src/shell/workspace.rs | 70 +++---- 9 files changed, 374 insertions(+), 379 deletions(-) diff --git a/src/backend/render/mod.rs b/src/backend/render/mod.rs index 0792fc8c..47bfe309 100644 --- a/src/backend/render/mod.rs +++ b/src/backend/render/mod.rs @@ -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 { + pub w_elements: Vec, + pub p_elements: Vec, +} + +impl Default for SplitRenderElements { + fn default() -> Self { + Self { + w_elements: Vec::new(), + p_elements: Vec::new(), + } + } +} + +impl SplitRenderElements { + 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 E>(&mut self, other: SplitRenderElements, 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 { + self.p_elements.extend(self.w_elements); + self.p_elements + } +} + +impl SplitRenderElements> +where + R: Renderer + ImportAll + ImportMem + AsGlowRenderer, + CosmicMappedRenderElement: RenderElement, +{ + fn extend_from_workspace_elements>>( + &mut self, + other: SplitRenderElements, + offset: Point, + ) { + self.extend_map(other, |element| { + CosmicElement::Workspace(RelocateRenderElement::from_element( + element.into(), + offset, + Relocate::Relative, + )) + }) + } +} + #[profiling::function] pub fn workspace_elements( _gpu: Option<&DrmNode>, @@ -484,6 +538,8 @@ where CosmicMappedRenderElement: RenderElement, WorkspaceRenderElement: RenderElement, { + let mut elements = SplitRenderElements::default(); + let theme = shell.read().unwrap().theme().clone(); let seats = shell .read() @@ -493,7 +549,7 @@ where .cloned() .collect::>(); - 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::( - 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::( + 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::::from(match (layout, *previous_idx < current.1) { @@ -783,55 +800,28 @@ where None => (0, 0).into(), }; - let (w_elements, p_elements) = workspace - .render::( - 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::( + 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( @@ -839,10 +829,7 @@ pub fn split_layer_elements( output: &Output, layer: Layer, exclude_workspace_overview: bool, -) -> ( - Vec>, - Vec>, -) +) -> SplitRenderElements> where R: Renderer + ImportAll + ImportMem + AsGlowRenderer, ::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( renderer: &mut R, output: &Output, exclude_workspace_overview: bool, -) -> ( - Vec>, - Vec>, -) +) -> SplitRenderElements> where R: Renderer + ImportAll + ImportMem + AsGlowRenderer, ::TextureId: Clone + 'static, @@ -917,17 +904,15 @@ where CosmicMappedRenderElement: RenderElement, WorkspaceRenderElement: RenderElement, { - 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( diff --git a/src/shell/element/mod.rs b/src/shell/element/mod.rs index 231f633a..94cb702e 100644 --- a/src/shell/element/mod.rs +++ b/src/shell/element/mod.rs @@ -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, scale: smithay::utils::Scale, alpha: f32, - ) -> (Vec, Vec) + ) -> SplitRenderElements where R: Renderer + ImportAll + ImportMem + AsGlowRenderer, ::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::>( - renderer, location, scale, alpha, - ), - CosmicMappedInternal::Window(w) => w - .split_render_elements::>( - 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::>( + renderer, location, scale, alpha, + ), + CosmicMappedInternal::Window(w) => w + .split_render_elements::>( + renderer, location, scale, alpha, + ), + _ => unreachable!(), + }, + C::from, + ); + + elements } pub(crate) fn update_theme(&self, theme: cosmic::Theme) { diff --git a/src/shell/element/stack.rs b/src/shell/element/stack.rs index 107179a3..8489365b 100644 --- a/src/shell/element/stack.rs +++ b/src/shell/element/stack.rs @@ -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, scale: Scale, alpha: f32, - ) -> (Vec, Vec) + ) -> SplitRenderElements where R: Renderer + ImportAll + ImportMem, ::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::::render_elements::>( + let w_elements = AsRenderElements::::render_elements::>( &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::>( + 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::>( 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) { diff --git a/src/shell/element/surface.rs b/src/shell/element/surface.rs index 5c18870a..a870d8e4 100644 --- a/src/shell/element/surface.rs +++ b/src/shell/element/surface.rs @@ -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, scale: smithay::utils::Scale, alpha: f32, - ) -> (Vec, Vec) + ) -> SplitRenderElements where R: Renderer + ImportAll, ::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(), + }, } } diff --git a/src/shell/element/window.rs b/src/shell/element/window.rs index 5917a78d..706784fd 100644 --- a/src/shell/element/window.rs +++ b/src/shell/element/window.rs @@ -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, scale: smithay::utils::Scale, alpha: f32, - ) -> (Vec, Vec) + ) -> SplitRenderElements where R: Renderer + ImportAll + ImportMem, ::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::>( - renderer, window_loc, scale, alpha, - ) - }); + let mut elements = SplitRenderElements::default(); + + elements.extend_map( + self.0.with_program(|p| { + p.window + .split_render_elements::>( + 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::::render_elements::< - CosmicWindowRenderElement, - >(&self.0, renderer, ssd_loc, scale, alpha)) + elements.w_elements.extend( + AsRenderElements::::render_elements::>( + &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) { diff --git a/src/shell/grabs/moving.rs b/src/shell/grabs/moving.rs index 0cbe400f..b4a0bac0 100644 --- a/src/shell/grabs/moving.rs +++ b/src/shell/grabs/moving.rs @@ -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::>( 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( diff --git a/src/shell/layout/floating/mod.rs b/src/shell/layout/floating/mod.rs index 1c184a30..c0ff2ad2 100644 --- a/src/shell/layout/floating/mod.rs +++ b/src/shell/layout/floating/mod.rs @@ -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>, - Vec>, - ) + ) -> SplitRenderElements> where R: Renderer + ImportAll + ImportMem + AsGlowRenderer, ::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::>( 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) { diff --git a/src/shell/layout/tiling/mod.rs b/src/shell/layout/tiling/mod.rs index 3d143089..595a9ebe 100644 --- a/src/shell/layout/tiling/mod.rs +++ b/src/shell/layout/tiling/mod.rs @@ -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>, - Vec>, - ), - OutputNotMapped, - > + ) -> Result>, OutputNotMapped> where R: Renderer + ImportAll + ImportMem + AsGlowRenderer, ::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( indicator_thickness: u8, is_swap_mode: bool, theme: &cosmic::theme::CosmicTheme, -) -> ( - Vec>, - Vec>, -) +) -> SplitRenderElements> where R: Renderer + ImportAll + ImportMem + AsGlowRenderer, ::TextureId: Send + Clone + 'static, @@ -4709,8 +4695,7 @@ where CosmicStackRenderElement: RenderElement, { 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::>( - 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::>( + 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( @@ -4857,10 +4848,7 @@ fn render_new_tree( swapping_stack_surface_id: &Id, placeholder_id: &Id, theme: &cosmic::theme::CosmicTheme, -) -> ( - Vec>, - Vec>, -) +) -> SplitRenderElements> where R: Renderer + ImportAll + ImportMem + AsGlowRenderer, ::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::>( - 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::>( + 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( diff --git a/src/shell/workspace.rs b/src/shell/workspace.rs index 804a29df..4ec42b41 100644 --- a/src/shell/workspace.rs +++ b/src/shell/workspace.rs @@ -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>, - Vec>, - ), - OutputNotMapped, - > + ) -> Result>, OutputNotMapped> where R: Renderer + ImportAll + ImportMem + AsGlowRenderer, ::TextureId: Send + Clone + 'static, @@ -1020,8 +1014,7 @@ impl Workspace { CosmicStackRenderElement: RenderElement, WorkspaceRenderElement: RenderElement, { - 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::>( 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::( - renderer, - focused.as_ref(), - resize_indicator.clone(), - indicator_thickness, - alpha, - theme, + elements.extend_map( + self.floating_layer.render::( + 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::( - 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::( + 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::>::into(BackdropShader::element( renderer, self.backdrop_id.clone(), @@ -1205,7 +1205,7 @@ impl Workspace { } } - Ok((window_elements, popup_elements)) + Ok(elements) } }