diff --git a/src/backend/render/element.rs b/src/backend/render/element.rs index f0372606..aeff0fc0 100644 --- a/src/backend/render/element.rs +++ b/src/backend/render/element.rs @@ -18,6 +18,7 @@ where R: AsGlowRenderer + Renderer + ImportAll, ::TextureId: 'static, ::Frame: AsGles2Frame, + CosmicMappedRenderElement: RenderElement, { Workspace(WorkspaceRenderElement), Cursor(CursorRenderElement), @@ -31,6 +32,7 @@ where R: AsGlowRenderer + Renderer + ImportAll, ::TextureId: 'static, ::Frame: AsGles2Frame, + CosmicMappedRenderElement: RenderElement, { fn id(&self) -> &smithay::backend::renderer::element::Id { match self { @@ -209,6 +211,7 @@ where R: Renderer + ImportAll + AsGlowRenderer, ::TextureId: 'static, ::Frame: AsGles2Frame, + CosmicMappedRenderElement: RenderElement, { fn from(elem: WorkspaceRenderElement) -> Self { Self::Workspace(elem) @@ -220,6 +223,7 @@ where R: Renderer + ImportAll + AsGlowRenderer, ::TextureId: 'static, ::Frame: AsGles2Frame, + CosmicMappedRenderElement: RenderElement, { fn from(elem: CursorRenderElement) -> Self { Self::Cursor(elem) @@ -231,6 +235,7 @@ where R: Renderer + ImportAll + AsGlowRenderer, ::TextureId: 'static, ::Frame: AsGles2Frame, + CosmicMappedRenderElement: RenderElement, { fn from(elem: CosmicMappedRenderElement) -> Self { Self::MoveGrab(elem) @@ -243,6 +248,7 @@ where R: Renderer + ImportAll + AsGlowRenderer, ::TextureId: 'static, ::Frame: AsGles2Frame, + CosmicMappedRenderElement: RenderElement, { fn from(elem: TextureRenderElement) -> Self { Self::Egui(elem) diff --git a/src/backend/render/mod.rs b/src/backend/render/mod.rs index c3f2e96e..709bca1b 100644 --- a/src/backend/render/mod.rs +++ b/src/backend/render/mod.rs @@ -68,9 +68,10 @@ pub fn cursor_elements( mode: CursorMode, ) -> Vec where - R: Renderer + ImportAll + ImportMem, + R: Renderer + ImportAll + ImportMem + AsGlowRenderer, ::Frame: AsGles2Frame, ::TextureId: Clone + 'static, + CosmicMappedRenderElement: RenderElement, E: From> + From>, { let scale = output.current_scale().fractional_scale(); @@ -149,6 +150,7 @@ where ::TextureId: Clone + 'static, ::Error: From, CosmicElement: RenderElement, + CosmicMappedRenderElement: RenderElement, Source: Clone, { let handle = state.shell.workspaces.active(output).handle; @@ -195,6 +197,7 @@ where ::TextureId: Clone + 'static, ::Error: From, CosmicElement: RenderElement, + CosmicMappedRenderElement: RenderElement, Source: Clone, { #[cfg(feature = "debug")] diff --git a/src/shell/element/mod.rs b/src/shell/element/mod.rs index 890ac9cd..b2395d73 100644 --- a/src/shell/element/mod.rs +++ b/src/shell/element/mod.rs @@ -1,9 +1,25 @@ -use crate::{state::State, utils::prelude::SeatExt}; +use crate::{ + backend::render::{ + element::{AsGles2Frame, AsGlowRenderer, CosmicElement}, + GlMultiRenderer, + }, + state::State, + utils::prelude::SeatExt, +}; use id_tree::NodeId; use smithay::{ backend::{ input::KeyState, - renderer::{element::AsRenderElements, ImportAll, Renderer}, + renderer::{ + element::{ + texture::TextureRenderElement, AsRenderElements, Element, RenderElement, + UnderlyingStorage, + }, + gles2::Gles2Texture, + glow::GlowRenderer, + multigpu::Error as MultiError, + ImportAll, Renderer, + }, }, desktop::{space::SpaceElement, Kind, PopupManager, Window, WindowSurfaceType}, input::{ @@ -16,7 +32,7 @@ use smithay::{ wayland_protocols::xdg::shell::server::xdg_toplevel::State as XdgState, wayland_server::{backend::ObjectId, protocol::wl_surface::WlSurface}, }, - render_elements, space_elements, + space_elements, utils::{IsAlive, Logical, Physical, Point, Rectangle, Scale, Serial, Size}, wayland::{ compositor::{with_states, with_surface_tree_downward, TraversalAction}, @@ -26,6 +42,7 @@ use smithay::{ }; use std::{ collections::HashMap, + fmt, hash::Hash, sync::{Arc, Mutex}, }; @@ -35,6 +52,11 @@ pub use self::stack::CosmicStack; pub mod window; pub use self::window::CosmicWindow; +#[cfg(feature = "debug")] +use smithay::wayland::shell::xdg::XdgToplevelSurfaceData; +#[cfg(feature = "debug")] +use smithay_egui::EguiState; + use super::{focus::FocusDirection, layout::floating::ResizeState}; space_elements! { @@ -44,7 +66,7 @@ space_elements! { Stack=CosmicStack, } -#[derive(Debug, Clone)] +#[derive(Clone)] pub struct CosmicMapped { element: CosmicMappedInternal, @@ -56,6 +78,20 @@ pub struct CosmicMapped { //floating pub(super) last_geometry: Arc>>>, pub(super) resize_state: Arc>>, + + #[cfg(feature = "debug")] + debug: Arc>, +} + +impl fmt::Debug for CosmicMapped { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("CosmicMapped") + .field("element", &self.element) + .field("last_cursor_position", &self.last_cursor_position) + .field("tiling_node_id", &self.tiling_node_id) + .field("resize_state", &self.resize_state) + .finish() + } } impl PartialEq for CosmicMapped { @@ -239,8 +275,7 @@ impl CosmicMapped { Kind::Xdg(xdg) => { xdg.current_state().states.contains(XdgState::Resizing) || xdg.with_pending_state(|states| states.states.contains(XdgState::Resizing)) - } - // Kind::X11? + } // Kind::X11? } } @@ -387,8 +422,7 @@ impl CosmicMapped { Kind::Xdg(xdg) => { xdg.current_state().states.contains(XdgState::Activated) || xdg.with_pending_state(|states| states.states.contains(XdgState::Activated)) - } - // Kind::X11? + } // Kind::X11? } } @@ -687,6 +721,10 @@ impl From for CosmicMapped { tiling_node_id: Arc::new(Mutex::new(None)), last_geometry: Arc::new(Mutex::new(None)), resize_state: Arc::new(Mutex::new(None)), + #[cfg(feature = "debug")] + debug: Arc::new(Mutex::new(smithay_egui::EguiState::new( + Rectangle::from_loc_and_size((10, 10), (100, 100)), + ))), } } } @@ -699,20 +737,235 @@ impl From for CosmicMapped { tiling_node_id: Arc::new(Mutex::new(None)), last_geometry: Arc::new(Mutex::new(None)), resize_state: Arc::new(Mutex::new(None)), + #[cfg(feature = "debug")] + debug: Arc::new(Mutex::new(smithay_egui::EguiState::new( + Rectangle::from_loc_and_size((10, 10), (100, 100)), + ))), } } } -render_elements! { - pub CosmicMappedRenderElement where R: ImportAll; - Stack=self::stack::CosmicStackRenderElement, - Window=self::window::CosmicWindowRenderElement, +pub enum CosmicMappedRenderElement +where + R: AsGlowRenderer + Renderer + ImportAll, + ::TextureId: 'static, + ::Frame: AsGles2Frame, +{ + Stack(self::stack::CosmicStackRenderElement), + Window(self::window::CosmicWindowRenderElement), + #[cfg(feature = "debug")] + Egui(TextureRenderElement), +} + +impl Element for CosmicMappedRenderElement +where + R: AsGlowRenderer + Renderer + ImportAll, + ::TextureId: 'static, + ::Frame: AsGles2Frame, +{ + fn id(&self) -> &smithay::backend::renderer::element::Id { + match self { + CosmicMappedRenderElement::Stack(elem) => elem.id(), + CosmicMappedRenderElement::Window(elem) => elem.id(), + #[cfg(feature = "debug")] + CosmicMappedRenderElement::Egui(elem) => elem.id(), + } + } + + fn current_commit(&self) -> smithay::backend::renderer::utils::CommitCounter { + match self { + CosmicMappedRenderElement::Stack(elem) => elem.current_commit(), + CosmicMappedRenderElement::Window(elem) => elem.current_commit(), + #[cfg(feature = "debug")] + CosmicMappedRenderElement::Egui(elem) => elem.current_commit(), + } + } + + fn src(&self) -> Rectangle { + match self { + CosmicMappedRenderElement::Stack(elem) => elem.src(), + CosmicMappedRenderElement::Window(elem) => elem.src(), + #[cfg(feature = "debug")] + CosmicMappedRenderElement::Egui(elem) => elem.src(), + } + } + + fn geometry(&self, scale: Scale) -> Rectangle { + match self { + CosmicMappedRenderElement::Stack(elem) => elem.geometry(scale), + CosmicMappedRenderElement::Window(elem) => elem.geometry(scale), + #[cfg(feature = "debug")] + CosmicMappedRenderElement::Egui(elem) => elem.geometry(scale), + } + } + + fn location(&self, scale: Scale) -> Point { + match self { + CosmicMappedRenderElement::Stack(elem) => elem.location(scale), + CosmicMappedRenderElement::Window(elem) => elem.location(scale), + #[cfg(feature = "debug")] + CosmicMappedRenderElement::Egui(elem) => elem.location(scale), + } + } + + fn transform(&self) -> smithay::utils::Transform { + match self { + CosmicMappedRenderElement::Stack(elem) => elem.transform(), + CosmicMappedRenderElement::Window(elem) => elem.transform(), + #[cfg(feature = "debug")] + CosmicMappedRenderElement::Egui(elem) => elem.transform(), + } + } + + fn damage_since( + &self, + scale: Scale, + commit: Option, + ) -> Vec> { + match self { + CosmicMappedRenderElement::Stack(elem) => elem.damage_since(scale, commit), + CosmicMappedRenderElement::Window(elem) => elem.damage_since(scale, commit), + #[cfg(feature = "debug")] + CosmicMappedRenderElement::Egui(elem) => elem.damage_since(scale, commit), + } + } + + fn opaque_regions(&self, scale: Scale) -> Vec> { + match self { + CosmicMappedRenderElement::Stack(elem) => elem.opaque_regions(scale), + CosmicMappedRenderElement::Window(elem) => elem.opaque_regions(scale), + #[cfg(feature = "debug")] + CosmicMappedRenderElement::Egui(elem) => elem.opaque_regions(scale), + } + } +} + +impl RenderElement for CosmicMappedRenderElement { + fn draw( + &self, + renderer: &mut GlowRenderer, + frame: &mut ::Frame, + location: Point, + scale: Scale, + damage: &[Rectangle], + log: &slog::Logger, + ) -> Result<(), ::Error> { + match self { + CosmicMappedRenderElement::Stack(elem) => { + elem.draw(renderer, frame, location, scale, damage, log) + } + CosmicMappedRenderElement::Window(elem) => { + elem.draw(renderer, frame, location, scale, damage, log) + } + #[cfg(feature = "debug")] + CosmicMappedRenderElement::Egui(elem) => { + elem.draw(renderer, frame, location, scale, damage, log) + } + } + } + + fn underlying_storage( + &self, + renderer: &GlowRenderer, + ) -> Option> { + match self { + CosmicMappedRenderElement::Stack(elem) => elem.underlying_storage(renderer), + CosmicMappedRenderElement::Window(elem) => elem.underlying_storage(renderer), + #[cfg(feature = "debug")] + CosmicMappedRenderElement::Egui(elem) => elem.underlying_storage(renderer), + } + } +} + +impl<'a> RenderElement> for CosmicMappedRenderElement> { + fn draw( + &self, + renderer: &mut GlMultiRenderer<'a>, + frame: &mut as Renderer>::Frame, + location: Point, + scale: Scale, + damage: &[Rectangle], + log: &slog::Logger, + ) -> Result<(), as Renderer>::Error> { + match self { + CosmicMappedRenderElement::Stack(elem) => { + elem.draw(renderer, frame, location, scale, damage, log) + } + CosmicMappedRenderElement::Window(elem) => { + elem.draw(renderer, frame, location, scale, damage, log) + } + #[cfg(feature = "debug")] + CosmicMappedRenderElement::Egui(elem) => { + let glow_renderer = renderer.glow_renderer_mut(); + let gles2_frame = frame.gles2_frame_mut(); + elem.draw(glow_renderer, gles2_frame, location, scale, damage, log) + .map_err(|err| MultiError::Render(err)) + } + } + } + + fn underlying_storage( + &self, + renderer: &GlMultiRenderer<'a>, + ) -> Option>> { + match self { + CosmicMappedRenderElement::Stack(elem) => elem.underlying_storage(renderer), + CosmicMappedRenderElement::Window(elem) => elem.underlying_storage(renderer), + #[cfg(feature = "debug")] + CosmicMappedRenderElement::Egui(elem) => { + let glow_renderer = renderer.glow_renderer(); + match elem.underlying_storage(glow_renderer) { + Some(UnderlyingStorage::Wayland(buffer)) => { + Some(UnderlyingStorage::Wayland(buffer)) + } + _ => None, + } + } + } + } +} + +impl From> for CosmicMappedRenderElement +where + R: Renderer + ImportAll + AsGlowRenderer, + ::TextureId: 'static, + ::Frame: AsGles2Frame, + CosmicMappedRenderElement: RenderElement, +{ + fn from(elem: stack::CosmicStackRenderElement) -> Self { + CosmicMappedRenderElement::Stack(elem) + } +} +impl From> for CosmicMappedRenderElement +where + R: Renderer + ImportAll + AsGlowRenderer, + ::TextureId: 'static, + ::Frame: AsGles2Frame, + CosmicMappedRenderElement: RenderElement, +{ + fn from(elem: window::CosmicWindowRenderElement) -> Self { + CosmicMappedRenderElement::Window(elem) + } +} +#[cfg(feature = "debug")] +impl From> for CosmicMappedRenderElement +where + R: Renderer + ImportAll + AsGlowRenderer, + ::TextureId: 'static, + ::Frame: AsGles2Frame, + CosmicMappedRenderElement: RenderElement, +{ + fn from(elem: TextureRenderElement) -> Self { + CosmicMappedRenderElement::Egui(elem) + } } impl AsRenderElements for CosmicMapped where - R: Renderer + ImportAll, + R: Renderer + ImportAll + AsGlowRenderer, ::TextureId: 'static, + ::Frame: AsGles2Frame, + CosmicMappedRenderElement: RenderElement, { type RenderElement = CosmicMappedRenderElement; fn render_elements>( @@ -720,7 +973,7 @@ where location: Point, scale: Scale, ) -> Vec { - match &self.element { + let mut elements = match &self.element { CosmicMappedInternal::Stack(s) => AsRenderElements::::render_elements::< CosmicMappedRenderElement, >(s, location, scale), @@ -728,9 +981,121 @@ where CosmicMappedRenderElement, >(w, location, scale), _ => Vec::new(), + }; + + /* + #[cfg(feature = "debug")] + if !elements.is_empty() { + let window = self.active_window(); + let (app_id, title, min_size, max_size, size, states) = with_states(&window.kind().wl_surface(), |states| { + let attributes = states + .data_map + .get::() + .unwrap() + .lock() + .unwrap(); + (attributes.app_id.clone(), attributes.title.clone(), attributes.min_size.clone(), attributes.max_size.clone(), attributes.current.size.clone(), attributes.current.states.clone()) + }); + + let win_geo = self.geometry().size; + let area = { + let size = win_size.clamp((10, 10), (100, 100))}; + let offset = (win_size - (100, 100).into()) + .to_point() + .constain(Rectangle::from_loc_and_size((0, 0), (10, 10))); + Rectangle::from_loc_and_size(offset, size) + }; + + match self.debug.lock().unwrap().render( + |ui| { + egui::Frame::none() + .fill(Color32::DARK_GRAY) + .rounding(0.25) + .show(ui, |ui| { + ui.heading(title.as_deref().unwrap_or("")); + ui.label(app_id.as_deref().unwrap_or("")); + ui.horizontal(|ui| { + ui.label("States: "); + if states.contains(XdgState::Maximized) { + ui.label("🗖"); + } + if states.contains(XdgState::Fullscreen) { + ui.label("⬜") + } + if states.contains(XdgState::Activated) { + ui.label("🖱") + } + if states.contains(XdgState::Resizing) { + ui.label("↔") + } + if states.contains(XdgState::TiledLeft) { + ui.label("⏴") + } + if states.contains(XdgState::TiledRight) { + ui.label("⏵") + } + if states.contains(XdgState::TiledTop) { + ui.label("⏶") + } + if states.contains(XdgState::TiledBottom) { + ui.label("⏷") + } + }); + + let plot = Plot::new("Sizes") + .legend(Legend::default().position(Corner::RightBottom)) + .show_x(false) + .show_y(false) + .data_aspect(0.1); + plot.show(ui, |plot_ui| { + let center = ((max_size.w + 20) / 2, (max_size.h + 20) / 2); + let max_size_rect = Polygon::new(PlotPoints::new(vec![ + (10, 10), + (max_size.w + 10, 10), + (max_size.w + 10, max_size.h + 10), + (10, max_size.h + 10), + (10, 10), + ])); + plot_ui.polygon(max_size_rect.name(format!("{}", max_size))); + + if let Some(size) = size { + let size_rect = Polygon::new(PlotPoints::new(vec![ + (center.0 - size.w / 2, center.1 - size.h / 2), + (center.0 + size.w / 2, center.1 - size.w / 2), + (center.0 + size.w / 2, center.1 + size.w / 2), + (center.0 - size.w / 2, center.1 + size.w / 2), + (center.0 - size.w / 2, center.1 - size.w / 2), + ])); + plot_ui.polygon(size_rect.name(format!("{}", size))); + } + + let min_size_rect = Polygon::new(PlotPoints::new(vec![ + (center.0 - min_size.w / 2, center.1 - min_size.h / 2), + (center.0 + min_size.w / 2, center.1 - min_size.w / 2), + (center.0 + min_size.w / 2, center.1 + min_size.w / 2), + (center.0 - min_size.w / 2, center.1 + min_size.w / 2), + (center.0 - min_size.w / 2, center.1 - min_size.w / 2), + ])); + plot_ui.polygon(min_size_rect.name(format!("{}", min_size))); + }) + }); + }, + renderer, + area, + scale, + if self.last_cursor_position.lock().unwrap().values().any(|p| area.contains(p.to_i32_round())) { + 0.4 + } else { + 1.0 + }, + start_time, + ) { + Ok(element) => elements.push(element), + Err(err) => slog_scope::debug!("Error rendering debug overlay: {}", err), + }; } - .into_iter() - .map(C::from) - .collect() + */ + + elements.into_iter().map(C::from).collect() } } diff --git a/src/shell/layout/floating/grabs/moving.rs b/src/shell/layout/floating/grabs/moving.rs index a04cf043..4c12ae05 100644 --- a/src/shell/layout/floating/grabs/moving.rs +++ b/src/shell/layout/floating/grabs/moving.rs @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only use crate::{ + backend::render::element::{AsGles2Frame, AsGlowRenderer}, shell::{ element::{CosmicMapped, CosmicMappedRenderElement}, focus::target::{KeyboardFocusTarget, PointerFocusTarget}, @@ -9,7 +10,10 @@ use crate::{ }; use smithay::{ - backend::renderer::{element::AsRenderElements, ImportAll, Renderer}, + backend::renderer::{ + element::{AsRenderElements, RenderElement}, + ImportAll, Renderer, + }, desktop::space::SpaceElement, input::{ pointer::{ @@ -35,8 +39,10 @@ pub struct MoveGrabState { impl MoveGrabState { pub fn render(&self, seat: &Seat, output: &Output) -> Vec where - R: Renderer + ImportAll, + R: Renderer + ImportAll + AsGlowRenderer, ::TextureId: 'static, + ::Frame: AsGles2Frame, + CosmicMappedRenderElement: RenderElement, I: From>, { let cursor_at = seat.get_pointer().unwrap().current_location(); diff --git a/src/shell/layout/floating/mod.rs b/src/shell/layout/floating/mod.rs index 24fcc67f..e512ef6a 100644 --- a/src/shell/layout/floating/mod.rs +++ b/src/shell/layout/floating/mod.rs @@ -1,16 +1,16 @@ // SPDX-License-Identifier: GPL-3.0-only use smithay::{ - backend::renderer::{ImportAll, Renderer}, + backend::renderer::{element::RenderElement, ImportAll, Renderer}, desktop::{layer_map_for_output, space::SpaceElement, Space, Window}, input::{pointer::GrabStartData as PointerGrabStartData, Seat}, output::Output, - render_elements, utils::{Logical, Point, Rectangle, Serial}, }; use std::collections::HashMap; use crate::{ + backend::render::element::{AsGles2Frame, AsGlowRenderer}, shell::{ element::{CosmicMapped, CosmicMappedRenderElement}, grabs::ResizeEdge, @@ -295,23 +295,17 @@ impl FloatingLayout { pub fn render_output( &self, output: &Output, - ) -> Result>, OutputNotMapped> + ) -> Result>, OutputNotMapped> where - R: Renderer + ImportAll, + R: Renderer + ImportAll + AsGlowRenderer, ::TextureId: 'static, + ::Frame: AsGles2Frame, + CosmicMappedRenderElement: RenderElement, { let output_scale = output.current_scale().fractional_scale(); let output_geo = self.space.output_geometry(output).ok_or(OutputNotMapped)?; Ok(self .space - .render_elements_for_region::(&output_geo, output_scale) - .into_iter() - .map(FloatingRenderElement::from) - .collect()) + .render_elements_for_region::(&output_geo, output_scale)) } } - -render_elements! { - pub FloatingRenderElement where R: ImportAll; - Window=CosmicMappedRenderElement, -} diff --git a/src/shell/layout/tiling/mod.rs b/src/shell/layout/tiling/mod.rs index 3760bfd3..a1954490 100644 --- a/src/shell/layout/tiling/mod.rs +++ b/src/shell/layout/tiling/mod.rs @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only use crate::{ + backend::render::element::{AsGles2Frame, AsGlowRenderer}, shell::{ element::{CosmicMapped, CosmicMappedRenderElement}, focus::{ @@ -17,11 +18,13 @@ use crate::{ use id_tree::{InsertBehavior, MoveBehavior, Node, NodeId, NodeIdError, RemoveBehavior, Tree}; use smithay::{ - backend::renderer::{element::AsRenderElements, ImportAll, Renderer}, + backend::renderer::{ + element::{AsRenderElements, RenderElement}, + ImportAll, Renderer, + }, desktop::{layer_map_for_output, space::SpaceElement, PopupKind, Window}, input::{pointer::GrabStartData as PointerGrabStartData, Seat}, output::Output, - render_elements, utils::{IsAlive, Logical, Point, Rectangle, Scale, Serial}, }; use std::{borrow::Borrow, collections::HashMap, hash::Hash, sync::Arc}; @@ -1222,10 +1225,12 @@ impl TilingLayout { pub fn render_output( &self, output: &Output, - ) -> Result>, OutputNotMapped> + ) -> Result>, OutputNotMapped> where - R: Renderer + ImportAll, + R: Renderer + ImportAll + AsGlowRenderer, ::TextureId: 'static, + ::Frame: AsGles2Frame, + CosmicMappedRenderElement: RenderElement, { let output_scale = output.current_scale().fractional_scale(); @@ -1243,7 +1248,7 @@ impl TilingLayout { } }) .flat_map(|(mapped, loc)| { - AsRenderElements::::render_elements::>( + AsRenderElements::::render_elements::>( mapped, loc.to_physical_precise_round(output_scale) - mapped @@ -1256,8 +1261,3 @@ impl TilingLayout { .collect::>()) } } - -render_elements! { - pub TilingRenderElement where R: ImportAll; - Window=CosmicMappedRenderElement, -} diff --git a/src/shell/workspace.rs b/src/shell/workspace.rs index b9c0dbc3..95c0eba6 100644 --- a/src/shell/workspace.rs +++ b/src/shell/workspace.rs @@ -1,4 +1,5 @@ use crate::{ + backend::render::element::{AsGles2Frame, AsGlowRenderer}, shell::layout::{ floating::{FloatingLayout, MoveSurfaceGrab}, tiling::TilingLayout, @@ -17,7 +18,7 @@ use crate::{ use indexmap::IndexSet; use smithay::{ backend::renderer::{ - element::{surface::WaylandSurfaceRenderElement, AsRenderElements}, + element::{surface::WaylandSurfaceRenderElement, AsRenderElements, Element, RenderElement}, ImportAll, Renderer, }, desktop::{layer_map_for_output, space::SpaceElement, Kind, LayerSurface, Window}, @@ -27,7 +28,6 @@ use smithay::{ wayland_protocols::xdg::shell::server::xdg_toplevel::{self, ResizeEdge}, wayland_server::protocol::wl_surface::WlSurface, }, - render_elements, utils::{IsAlive, Logical, Point, Rectangle, Scale, Serial}, wayland::shell::wlr_layer::Layer, }; @@ -37,7 +37,7 @@ use super::{ element::CosmicMapped, focus::{FocusStack, FocusStackMut}, grabs::ResizeGrab, - layout::{floating::FloatingRenderElement, tiling::TilingRenderElement}, + CosmicMappedRenderElement, }; #[derive(Debug)] @@ -422,8 +422,10 @@ impl Workspace { output: &Output, ) -> Result>, OutputNotMapped> where - R: Renderer + ImportAll, + R: Renderer + ImportAll + AsGlowRenderer, ::TextureId: 'static, + ::Frame: AsGles2Frame, + CosmicMappedRenderElement: RenderElement, { let mut render_elements = Vec::new(); @@ -540,9 +542,140 @@ impl FocusStacks { pub struct OutputNotMapped; -render_elements! { - pub WorkspaceRenderElement where R: ImportAll; - Wayland=WaylandSurfaceRenderElement, - Floating=FloatingRenderElement, - Tiling=TilingRenderElement, +pub enum WorkspaceRenderElement +where + R: Renderer + ImportAll + AsGlowRenderer, + ::TextureId: 'static, + ::Frame: AsGles2Frame, +{ + Wayland(WaylandSurfaceRenderElement), + Window(CosmicMappedRenderElement), +} + +impl Element for WorkspaceRenderElement +where + R: Renderer + ImportAll + AsGlowRenderer, + ::TextureId: 'static, + ::Frame: AsGles2Frame, +{ + fn id(&self) -> &smithay::backend::renderer::element::Id { + match self { + WorkspaceRenderElement::Wayland(elem) => elem.id(), + WorkspaceRenderElement::Window(elem) => elem.id(), + } + } + + fn current_commit(&self) -> smithay::backend::renderer::utils::CommitCounter { + match self { + WorkspaceRenderElement::Wayland(elem) => elem.current_commit(), + WorkspaceRenderElement::Window(elem) => elem.current_commit(), + } + } + + fn src(&self) -> Rectangle { + match self { + WorkspaceRenderElement::Wayland(elem) => elem.src(), + WorkspaceRenderElement::Window(elem) => elem.src(), + } + } + + fn geometry(&self, scale: Scale) -> Rectangle { + match self { + WorkspaceRenderElement::Wayland(elem) => elem.geometry(scale), + WorkspaceRenderElement::Window(elem) => elem.geometry(scale), + } + } + + fn location(&self, scale: Scale) -> Point { + match self { + WorkspaceRenderElement::Wayland(elem) => elem.location(scale), + WorkspaceRenderElement::Window(elem) => elem.location(scale), + } + } + + fn transform(&self) -> smithay::utils::Transform { + match self { + WorkspaceRenderElement::Wayland(elem) => elem.transform(), + WorkspaceRenderElement::Window(elem) => elem.transform(), + } + } + + fn damage_since( + &self, + scale: Scale, + commit: Option, + ) -> Vec> { + match self { + WorkspaceRenderElement::Wayland(elem) => elem.damage_since(scale, commit), + WorkspaceRenderElement::Window(elem) => elem.damage_since(scale, commit), + } + } + + fn opaque_regions(&self, scale: Scale) -> Vec> { + match self { + WorkspaceRenderElement::Wayland(elem) => elem.opaque_regions(scale), + WorkspaceRenderElement::Window(elem) => elem.opaque_regions(scale), + } + } +} + +impl RenderElement for WorkspaceRenderElement +where + R: Renderer + ImportAll + AsGlowRenderer, + ::TextureId: 'static, + ::Frame: AsGles2Frame, + CosmicMappedRenderElement: RenderElement, +{ + fn draw( + &self, + renderer: &mut R, + frame: &mut ::Frame, + location: Point, + scale: Scale, + damage: &[Rectangle], + log: &slog::Logger, + ) -> Result<(), ::Error> { + match self { + WorkspaceRenderElement::Wayland(elem) => { + elem.draw(renderer, frame, location, scale, damage, log) + } + WorkspaceRenderElement::Window(elem) => { + elem.draw(renderer, frame, location, scale, damage, log) + } + } + } + + fn underlying_storage( + &self, + renderer: &R, + ) -> Option> { + match self { + WorkspaceRenderElement::Wayland(elem) => elem.underlying_storage(renderer), + WorkspaceRenderElement::Window(elem) => elem.underlying_storage(renderer), + } + } +} + +impl From for WorkspaceRenderElement +where + R: Renderer + ImportAll + AsGlowRenderer, + ::TextureId: 'static, + ::Frame: AsGles2Frame, + CosmicMappedRenderElement: RenderElement, +{ + fn from(elem: WaylandSurfaceRenderElement) -> Self { + WorkspaceRenderElement::Wayland(elem) + } +} + +impl From> for WorkspaceRenderElement +where + R: Renderer + ImportAll + AsGlowRenderer, + ::TextureId: 'static, + ::Frame: AsGles2Frame, + CosmicMappedRenderElement: RenderElement, +{ + fn from(elem: CosmicMappedRenderElement) -> Self { + WorkspaceRenderElement::Window(elem) + } }