diff --git a/Cargo.lock b/Cargo.lock index e6380cc9..16536072 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -866,6 +866,7 @@ dependencies = [ "sanitize-filename", "serde", "serde_json", + "smallvec", "smithay", "smithay-egui", "thiserror 2.0.18", @@ -4923,7 +4924,7 @@ checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "smithay" version = "0.7.0" -source = "git+https://github.com/smithay/smithay.git?rev=e84a4ca#e84a4ca82d58d783839083bd48c4ab120715c4b6" +source = "git+https://github.com/smithay/smithay.git?rev=f6d1070#f6d10709db2bb68c46b9c128a4163d035356572c" dependencies = [ "aliasable", "appendlist", diff --git a/Cargo.toml b/Cargo.toml index f5e69fab..08c158c0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -83,6 +83,7 @@ logind-zbus = { version = "5.3.2", optional = true } futures-executor = { version = "0.3.32", features = ["thread-pool"] } futures-util = "0.3.32" cgmath = "0.18.0" +smallvec = "1.15.1" [dependencies.id_tree] branch = "feature/copy_clone" @@ -142,4 +143,4 @@ cosmic-protocols = { git = "https://github.com/pop-os//cosmic-protocols", branch cosmic-client-toolkit = { git = "https://github.com/pop-os//cosmic-protocols", branch = "main" } [patch.crates-io] -smithay = { git = "https://github.com/smithay/smithay.git", rev = "e84a4ca" } +smithay = { git = "https://github.com/smithay/smithay.git", rev = "f6d1070" } diff --git a/src/backend/render/clipped_surface.rs b/src/backend/render/clipped_surface.rs index 189312f2..8705051e 100644 --- a/src/backend/render/clipped_surface.rs +++ b/src/backend/render/clipped_surface.rs @@ -3,15 +3,19 @@ use std::borrow::{Borrow, BorrowMut}; use cgmath::{Matrix3, Vector2}; -use smithay::backend::renderer::{ - ImportAll, ImportMem, Renderer, - element::{ - Element, Id, Kind, RenderElement, UnderlyingStorage, surface::WaylandSurfaceRenderElement, - }, - gles::{GlesFrame, GlesRenderer, GlesTexProgram, Uniform, UniformValue}, - utils::{CommitCounter, DamageSet, OpaqueRegions}, -}; use smithay::utils::{Buffer, Logical, Physical, Point, Rectangle, Scale, Size, Transform}; +use smithay::{ + backend::renderer::{ + ImportAll, ImportMem, Renderer, + element::{ + Element, Id, Kind, RenderElement, UnderlyingStorage, + surface::WaylandSurfaceRenderElement, + }, + gles::{GlesFrame, GlesRenderer, GlesTexProgram, Uniform, UniformValue}, + utils::{CommitCounter, DamageSet, OpaqueRegions}, + }, + utils::user_data::UserDataMap, +}; use crate::backend::render::element::AsGlowRenderer; @@ -253,10 +257,12 @@ where dst: Rectangle, damage: &[Rectangle], opaque_regions: &[Rectangle], + cache: Option<&UserDataMap>, ) -> Result<(), R::Error> { BorrowMut::::borrow_mut(::glow_frame_mut(frame)) .override_default_tex_program(self.program.clone(), self.uniforms.clone()); - self.inner.draw(frame, src, dst, damage, opaque_regions)?; + self.inner + .draw(frame, src, dst, damage, opaque_regions, cache)?; BorrowMut::::borrow_mut(::glow_frame_mut(frame)) .clear_tex_program_override(); Ok(()) diff --git a/src/backend/render/element.rs b/src/backend/render/element.rs index 5f75725f..496702d0 100644 --- a/src/backend/render/element.rs +++ b/src/backend/render/element.rs @@ -18,7 +18,9 @@ use smithay::{ utils::{CommitCounter, DamageSet, OpaqueRegions}, }, }, - utils::{Buffer as BufferCoords, Logical, Physical, Point, Rectangle, Scale}, + utils::{ + Buffer as BufferCoords, Logical, Physical, Point, Rectangle, Scale, user_data::UserDataMap, + }, }; use super::{GlMultiRenderer, cursor::CursorRenderElement}; @@ -182,6 +184,19 @@ where CosmicElement::Egui(elem) => elem.kind(), } } + + fn is_framebuffer_effect(&self) -> bool { + match self { + CosmicElement::Workspace(elem) => elem.is_framebuffer_effect(), + CosmicElement::Cursor(elem) => elem.is_framebuffer_effect(), + CosmicElement::Dnd(elem) => elem.is_framebuffer_effect(), + CosmicElement::MoveGrab(elem) => elem.is_framebuffer_effect(), + CosmicElement::Postprocess(elem) => elem.is_framebuffer_effect(), + CosmicElement::Zoom(elem) => elem.is_framebuffer_effect(), + #[cfg(feature = "debug")] + CosmicElement::Egui(elem) => elem.is_framebuffer_effect(), + } + } } impl RenderElement for CosmicElement @@ -198,12 +213,19 @@ where dst: Rectangle, damage: &[Rectangle], opaque_regions: &[Rectangle], + cache: Option<&UserDataMap>, ) -> Result<(), R::Error> { match self { - CosmicElement::Workspace(elem) => elem.draw(frame, src, dst, damage, opaque_regions), - CosmicElement::Cursor(elem) => elem.draw(frame, src, dst, damage, opaque_regions), - CosmicElement::Dnd(elem) => elem.draw(frame, src, dst, damage, opaque_regions), - CosmicElement::MoveGrab(elem) => elem.draw(frame, src, dst, damage, opaque_regions), + CosmicElement::Workspace(elem) => { + elem.draw(frame, src, dst, damage, opaque_regions, cache) + } + CosmicElement::Cursor(elem) => { + elem.draw(frame, src, dst, damage, opaque_regions, cache) + } + CosmicElement::Dnd(elem) => elem.draw(frame, src, dst, damage, opaque_regions, cache), + CosmicElement::MoveGrab(elem) => { + elem.draw(frame, src, dst, damage, opaque_regions, cache) + } CosmicElement::Postprocess(elem) => { let glow_frame = R::glow_frame_mut(frame); RenderElement::::draw( @@ -213,10 +235,11 @@ where dst, damage, opaque_regions, + cache, ) .map_err(FromGlesError::from_gles_error) } - CosmicElement::Zoom(elem) => elem.draw(frame, src, dst, damage, opaque_regions), + CosmicElement::Zoom(elem) => elem.draw(frame, src, dst, damage, opaque_regions, cache), #[cfg(feature = "debug")] CosmicElement::Egui(elem) => { let glow_frame = R::glow_frame_mut(frame); @@ -227,6 +250,7 @@ where dst, damage, opaque_regions, + cache, ) .map_err(FromGlesError::from_gles_error) } @@ -251,6 +275,37 @@ where } } } + + fn capture_framebuffer( + &self, + frame: &mut ::Frame<'_, '_>, + src: Rectangle, + dst: Rectangle, + cache: &UserDataMap, + ) -> Result<(), ::Error> { + match self { + CosmicElement::Workspace(elem) => elem.capture_framebuffer(frame, src, dst, cache), + CosmicElement::Cursor(elem) => elem.capture_framebuffer(frame, src, dst, cache), + CosmicElement::Dnd(elem) => elem.capture_framebuffer(frame, src, dst, cache), + CosmicElement::MoveGrab(elem) => elem.capture_framebuffer(frame, src, dst, cache), + CosmicElement::Postprocess(elem) => { + let glow_frame = R::glow_frame_mut(frame); + RenderElement::::capture_framebuffer( + elem, glow_frame, src, dst, cache, + ) + .map_err(FromGlesError::from_gles_error) + } + CosmicElement::Zoom(elem) => elem.capture_framebuffer(frame, src, dst, cache), + #[cfg(feature = "debug")] + CosmicElement::Egui(elem) => { + let glow_frame = R::glow_frame_mut(frame); + RenderElement::::capture_framebuffer( + elem, glow_frame, src, dst, cache, + ) + .map_err(FromGlesError::from_gles_error) + } + } + } } impl From>>> @@ -398,6 +453,7 @@ impl RenderElement for DamageElement { _dst: Rectangle, _damage: &[Rectangle], _opaque_regions: &[Rectangle], + _cache: Option<&UserDataMap>, ) -> Result<(), R::Error> { Ok(()) } diff --git a/src/shell/element/mod.rs b/src/shell/element/mod.rs index 2e6e205b..7f3859ee 100644 --- a/src/shell/element/mod.rs +++ b/src/shell/element/mod.rs @@ -11,7 +11,7 @@ use smithay::{ input::KeyState, renderer::{ element::{ - Element, RenderElement, UnderlyingStorage, + Element, Kind, RenderElement, UnderlyingStorage, memory::MemoryRenderBufferRenderElement, utils::{CropRenderElement, RelocateRenderElement, RescaleRenderElement}, }, @@ -30,6 +30,7 @@ use smithay::{ space_elements, utils::{ Buffer as BufferCoords, IsAlive, Logical, Physical, Point, Rectangle, Scale, Serial, Size, + user_data::UserDataMap, }, wayland::seat::WaylandFocus, xwayland::{X11Surface, xwm::X11Relatable}, @@ -1282,6 +1283,44 @@ where CosmicMappedRenderElement::Egui(elem) => elem.alpha(), } } + + fn kind(&self) -> Kind { + match self { + CosmicMappedRenderElement::Stack(elem) => elem.kind(), + CosmicMappedRenderElement::Window(elem) => elem.kind(), + CosmicMappedRenderElement::TiledStack(elem) => elem.kind(), + CosmicMappedRenderElement::TiledWindow(elem) => elem.kind(), + CosmicMappedRenderElement::TiledOverlay(elem) => elem.kind(), + CosmicMappedRenderElement::MovingStack(elem) => elem.kind(), + CosmicMappedRenderElement::MovingWindow(elem) => elem.kind(), + CosmicMappedRenderElement::GrabbedStack(elem) => elem.kind(), + CosmicMappedRenderElement::GrabbedWindow(elem) => elem.kind(), + CosmicMappedRenderElement::FocusIndicator(elem) => elem.kind(), + CosmicMappedRenderElement::Overlay(elem) => elem.kind(), + CosmicMappedRenderElement::StackHoverIndicator(elem) => elem.kind(), + #[cfg(feature = "debug")] + CosmicMappedRenderElement::Egui(elem) => elem.kind(), + } + } + + fn is_framebuffer_effect(&self) -> bool { + match self { + CosmicMappedRenderElement::Stack(elem) => elem.is_framebuffer_effect(), + CosmicMappedRenderElement::Window(elem) => elem.is_framebuffer_effect(), + CosmicMappedRenderElement::TiledStack(elem) => elem.is_framebuffer_effect(), + CosmicMappedRenderElement::TiledWindow(elem) => elem.is_framebuffer_effect(), + CosmicMappedRenderElement::TiledOverlay(elem) => elem.is_framebuffer_effect(), + CosmicMappedRenderElement::MovingStack(elem) => elem.is_framebuffer_effect(), + CosmicMappedRenderElement::MovingWindow(elem) => elem.is_framebuffer_effect(), + CosmicMappedRenderElement::GrabbedStack(elem) => elem.is_framebuffer_effect(), + CosmicMappedRenderElement::GrabbedWindow(elem) => elem.is_framebuffer_effect(), + CosmicMappedRenderElement::FocusIndicator(elem) => elem.is_framebuffer_effect(), + CosmicMappedRenderElement::Overlay(elem) => elem.is_framebuffer_effect(), + CosmicMappedRenderElement::StackHoverIndicator(elem) => elem.is_framebuffer_effect(), + #[cfg(feature = "debug")] + CosmicMappedRenderElement::Egui(elem) => elem.is_framebuffer_effect(), + } + } } impl RenderElement for CosmicMappedRenderElement @@ -1297,19 +1336,20 @@ where dst: Rectangle, damage: &[Rectangle], opaque_regions: &[Rectangle], + cache: Option<&UserDataMap>, ) -> Result<(), R::Error> { match self { CosmicMappedRenderElement::Stack(elem) => { - elem.draw(frame, src, dst, damage, opaque_regions) + elem.draw(frame, src, dst, damage, opaque_regions, cache) } CosmicMappedRenderElement::Window(elem) => { - elem.draw(frame, src, dst, damage, opaque_regions) + elem.draw(frame, src, dst, damage, opaque_regions, cache) } CosmicMappedRenderElement::TiledStack(elem) => { - elem.draw(frame, src, dst, damage, opaque_regions) + elem.draw(frame, src, dst, damage, opaque_regions, cache) } CosmicMappedRenderElement::TiledWindow(elem) => { - elem.draw(frame, src, dst, damage, opaque_regions) + elem.draw(frame, src, dst, damage, opaque_regions, cache) } CosmicMappedRenderElement::TiledOverlay(elem) => RenderElement::::draw( elem, @@ -1318,19 +1358,20 @@ where dst, damage, opaque_regions, + cache, ) .map_err(FromGlesError::from_gles_error), CosmicMappedRenderElement::MovingStack(elem) => { - elem.draw(frame, src, dst, damage, opaque_regions) + elem.draw(frame, src, dst, damage, opaque_regions, cache) } CosmicMappedRenderElement::MovingWindow(elem) => { - elem.draw(frame, src, dst, damage, opaque_regions) + elem.draw(frame, src, dst, damage, opaque_regions, cache) } CosmicMappedRenderElement::GrabbedStack(elem) => { - elem.draw(frame, src, dst, damage, opaque_regions) + elem.draw(frame, src, dst, damage, opaque_regions, cache) } CosmicMappedRenderElement::GrabbedWindow(elem) => { - elem.draw(frame, src, dst, damage, opaque_regions) + elem.draw(frame, src, dst, damage, opaque_regions, cache) } CosmicMappedRenderElement::FocusIndicator(elem) => RenderElement::::draw( elem, @@ -1339,6 +1380,7 @@ where dst, damage, opaque_regions, + cache, ) .map_err(FromGlesError::from_gles_error), CosmicMappedRenderElement::Overlay(elem) => RenderElement::::draw( @@ -1348,10 +1390,11 @@ where dst, damage, opaque_regions, + cache, ) .map_err(FromGlesError::from_gles_error), CosmicMappedRenderElement::StackHoverIndicator(elem) => { - elem.draw(frame, src, dst, damage, opaque_regions) + elem.draw(frame, src, dst, damage, opaque_regions, cache) } #[cfg(feature = "debug")] CosmicMappedRenderElement::Egui(elem) => { @@ -1363,6 +1406,7 @@ where dst, damage, opaque_regions, + cache, ) .map_err(FromGlesError::from_gles_error) } @@ -1398,6 +1442,82 @@ where } } } + + fn capture_framebuffer( + &self, + frame: &mut R::Frame<'_, '_>, + src: Rectangle, + dst: Rectangle, + cache: &UserDataMap, + ) -> Result<(), R::Error> { + match self { + CosmicMappedRenderElement::Stack(elem) => { + elem.capture_framebuffer(frame, src, dst, cache) + } + CosmicMappedRenderElement::Window(elem) => { + elem.capture_framebuffer(frame, src, dst, cache) + } + CosmicMappedRenderElement::TiledStack(elem) => { + elem.capture_framebuffer(frame, src, dst, cache) + } + CosmicMappedRenderElement::TiledWindow(elem) => { + elem.capture_framebuffer(frame, src, dst, cache) + } + CosmicMappedRenderElement::TiledOverlay(elem) => { + RenderElement::::capture_framebuffer( + elem, + R::glow_frame_mut(frame), + src, + dst, + cache, + ) + .map_err(FromGlesError::from_gles_error) + } + CosmicMappedRenderElement::MovingStack(elem) => { + elem.capture_framebuffer(frame, src, dst, cache) + } + CosmicMappedRenderElement::MovingWindow(elem) => { + elem.capture_framebuffer(frame, src, dst, cache) + } + CosmicMappedRenderElement::GrabbedStack(elem) => { + elem.capture_framebuffer(frame, src, dst, cache) + } + CosmicMappedRenderElement::GrabbedWindow(elem) => { + elem.capture_framebuffer(frame, src, dst, cache) + } + CosmicMappedRenderElement::FocusIndicator(elem) => { + RenderElement::::capture_framebuffer( + elem, + R::glow_frame_mut(frame), + src, + dst, + cache, + ) + .map_err(FromGlesError::from_gles_error) + } + CosmicMappedRenderElement::Overlay(elem) => { + RenderElement::::capture_framebuffer( + elem, + R::glow_frame_mut(frame), + src, + dst, + cache, + ) + .map_err(FromGlesError::from_gles_error) + } + CosmicMappedRenderElement::StackHoverIndicator(elem) => { + elem.capture_framebuffer(frame, src, dst, cache) + } + #[cfg(feature = "debug")] + CosmicMappedRenderElement::Egui(elem) => { + let glow_frame = R::glow_frame_mut(frame); + RenderElement::::capture_framebuffer( + elem, glow_frame, src, dst, cache, + ) + .map_err(FromGlesError::from_gles_error) + } + } + } } impl From> for CosmicMappedRenderElement diff --git a/src/shell/element/stack.rs b/src/shell/element/stack.rs index 7e0cb4ac..d2f9c949 100644 --- a/src/shell/element/stack.rs +++ b/src/shell/element/stack.rs @@ -67,7 +67,10 @@ use smithay::{ }, output::Output, reexports::wayland_server::protocol::wl_surface::WlSurface, - utils::{Buffer, IsAlive, Logical, Physical, Point, Rectangle, Scale, Serial, Size, Transform}, + utils::{ + Buffer, IsAlive, Logical, Physical, Point, Rectangle, Scale, Serial, Size, Transform, + user_data::UserDataMap, + }, wayland::seat::WaylandFocus, }; use std::{ @@ -1995,6 +1998,16 @@ where CosmicStackRenderElement::Clipped(elem) => elem.kind(), } } + + fn is_framebuffer_effect(&self) -> bool { + match self { + CosmicStackRenderElement::Header(elem) => elem.is_framebuffer_effect(), + CosmicStackRenderElement::Shadow(elem) => elem.is_framebuffer_effect(), + CosmicStackRenderElement::Border(elem) => elem.is_framebuffer_effect(), + CosmicStackRenderElement::Window(elem) => elem.is_framebuffer_effect(), + CosmicStackRenderElement::Clipped(elem) => elem.is_framebuffer_effect(), + } + } } impl RenderElement for CosmicStackRenderElement @@ -2010,10 +2023,11 @@ where dst: Rectangle, damage: &[Rectangle], opaque_regions: &[Rectangle], + cache: Option<&UserDataMap>, ) -> Result<(), ::Error> { match self { CosmicStackRenderElement::Header(elem) => { - elem.draw(frame, src, dst, damage, opaque_regions) + elem.draw(frame, src, dst, damage, opaque_regions, cache) } CosmicStackRenderElement::Shadow(elem) | CosmicStackRenderElement::Border(elem) => { RenderElement::::draw( @@ -2023,14 +2037,15 @@ where dst, damage, opaque_regions, + cache, ) .map_err(FromGlesError::from_gles_error) } CosmicStackRenderElement::Window(elem) => { - elem.draw(frame, src, dst, damage, opaque_regions) + elem.draw(frame, src, dst, damage, opaque_regions, cache) } CosmicStackRenderElement::Clipped(elem) => { - elem.draw(frame, src, dst, damage, opaque_regions) + elem.draw(frame, src, dst, damage, opaque_regions, cache) } } } @@ -2045,4 +2060,34 @@ where CosmicStackRenderElement::Clipped(elem) => elem.underlying_storage(renderer), } } + + fn capture_framebuffer( + &self, + frame: &mut R::Frame<'_, '_>, + src: Rectangle, + dst: Rectangle, + cache: &UserDataMap, + ) -> Result<(), ::Error> { + match self { + CosmicStackRenderElement::Header(elem) => { + elem.capture_framebuffer(frame, src, dst, cache) + } + CosmicStackRenderElement::Shadow(elem) | CosmicStackRenderElement::Border(elem) => { + RenderElement::::capture_framebuffer( + elem, + R::glow_frame_mut(frame), + src, + dst, + cache, + ) + .map_err(FromGlesError::from_gles_error) + } + CosmicStackRenderElement::Window(elem) => { + elem.capture_framebuffer(frame, src, dst, cache) + } + CosmicStackRenderElement::Clipped(elem) => { + elem.capture_framebuffer(frame, src, dst, cache) + } + } + } } diff --git a/src/shell/element/window.rs b/src/shell/element/window.rs index 00d1b5e4..32ca4d33 100644 --- a/src/shell/element/window.rs +++ b/src/shell/element/window.rs @@ -53,7 +53,10 @@ use smithay::{ }, output::Output, reexports::wayland_server::protocol::wl_surface::WlSurface, - utils::{Buffer, IsAlive, Logical, Physical, Point, Rectangle, Scale, Serial, Size, Transform}, + utils::{ + Buffer, IsAlive, Logical, Physical, Point, Rectangle, Scale, Serial, Size, Transform, + user_data::UserDataMap, + }, wayland::seat::WaylandFocus, }; use std::{ @@ -1366,6 +1369,16 @@ where CosmicWindowRenderElement::Clipped(elem) => elem.kind(), } } + + fn is_framebuffer_effect(&self) -> bool { + match self { + CosmicWindowRenderElement::Header(elem) => elem.is_framebuffer_effect(), + CosmicWindowRenderElement::Shadow(elem) => elem.is_framebuffer_effect(), + CosmicWindowRenderElement::Border(elem) => elem.is_framebuffer_effect(), + CosmicWindowRenderElement::Window(elem) => elem.is_framebuffer_effect(), + CosmicWindowRenderElement::Clipped(elem) => elem.is_framebuffer_effect(), + } + } } impl RenderElement for CosmicWindowRenderElement @@ -1381,10 +1394,11 @@ where dst: Rectangle, damage: &[Rectangle], opaque_regions: &[Rectangle], + cache: Option<&UserDataMap>, ) -> Result<(), ::Error> { match self { CosmicWindowRenderElement::Header(elem) => { - elem.draw(frame, src, dst, damage, opaque_regions) + elem.draw(frame, src, dst, damage, opaque_regions, cache) } CosmicWindowRenderElement::Shadow(elem) | CosmicWindowRenderElement::Border(elem) => { RenderElement::::draw( @@ -1394,14 +1408,15 @@ where dst, damage, opaque_regions, + cache, ) .map_err(FromGlesError::from_gles_error) } CosmicWindowRenderElement::Window(elem) => { - elem.draw(frame, src, dst, damage, opaque_regions) + elem.draw(frame, src, dst, damage, opaque_regions, cache) } CosmicWindowRenderElement::Clipped(elem) => { - elem.draw(frame, src, dst, damage, opaque_regions) + elem.draw(frame, src, dst, damage, opaque_regions, cache) } } } @@ -1416,4 +1431,34 @@ where CosmicWindowRenderElement::Clipped(elem) => elem.underlying_storage(renderer), } } + + fn capture_framebuffer( + &self, + frame: &mut ::Frame<'_, '_>, + src: Rectangle, + dst: Rectangle, + cache: &UserDataMap, + ) -> Result<(), ::Error> { + match self { + CosmicWindowRenderElement::Header(elem) => { + elem.capture_framebuffer(frame, src, dst, cache) + } + CosmicWindowRenderElement::Shadow(elem) | CosmicWindowRenderElement::Border(elem) => { + RenderElement::::capture_framebuffer( + elem, + R::glow_frame_mut(frame), + src, + dst, + cache, + ) + .map_err(FromGlesError::from_gles_error) + } + CosmicWindowRenderElement::Window(elem) => { + elem.capture_framebuffer(frame, src, dst, cache) + } + CosmicWindowRenderElement::Clipped(elem) => { + elem.capture_framebuffer(frame, src, dst, cache) + } + } + } } diff --git a/src/shell/mod.rs b/src/shell/mod.rs index f9cfe5fe..4dde0f82 100644 --- a/src/shell/mod.rs +++ b/src/shell/mod.rs @@ -4859,6 +4859,7 @@ impl Shell { |surface, _| { surface_presentation_feedback_flags_from_states( surface, + None, render_element_states, ) }, @@ -4875,6 +4876,7 @@ impl Shell { |surface, _| { surface_presentation_feedback_flags_from_states( surface, + None, render_element_states, ) }, @@ -4888,7 +4890,11 @@ impl Shell { &mut output_presentation_feedback, surface_primary_scanout_output, |surface, _| { - surface_presentation_feedback_flags_from_states(surface, render_element_states) + surface_presentation_feedback_flags_from_states( + surface, + None, + render_element_states, + ) }, ); } diff --git a/src/shell/workspace.rs b/src/shell/workspace.rs index 5a535145..1be2c2ae 100644 --- a/src/shell/workspace.rs +++ b/src/shell/workspace.rs @@ -31,7 +31,9 @@ use cosmic_protocols::workspace::v2::server::zcosmic_workspace_handle_v2::Tiling use id_tree::Tree; use indexmap::IndexSet; use keyframe::{ease, functions::EaseInOutCubic}; +use smithay::backend::renderer::element::Kind; use smithay::output::WeakOutput; +use smithay::utils::user_data::UserDataMap; use smithay::{ backend::renderer::{ element::{ @@ -1987,6 +1989,26 @@ where WorkspaceRenderElement::Backdrop(elem) => elem.alpha(), } } + + fn kind(&self) -> Kind { + match self { + WorkspaceRenderElement::OverrideRedirect(elem) => elem.kind(), + WorkspaceRenderElement::Fullscreen(elem) => elem.kind(), + WorkspaceRenderElement::FullscreenPopup(elem) => elem.kind(), + WorkspaceRenderElement::Window(elem) => elem.kind(), + WorkspaceRenderElement::Backdrop(elem) => elem.kind(), + } + } + + fn is_framebuffer_effect(&self) -> bool { + match self { + WorkspaceRenderElement::OverrideRedirect(elem) => elem.is_framebuffer_effect(), + WorkspaceRenderElement::Fullscreen(elem) => elem.is_framebuffer_effect(), + WorkspaceRenderElement::FullscreenPopup(elem) => elem.is_framebuffer_effect(), + WorkspaceRenderElement::Window(elem) => elem.is_framebuffer_effect(), + WorkspaceRenderElement::Backdrop(elem) => elem.is_framebuffer_effect(), + } + } } impl RenderElement for WorkspaceRenderElement @@ -2002,19 +2024,20 @@ where dst: Rectangle, damage: &[Rectangle], opaque_regions: &[Rectangle], + cache: Option<&UserDataMap>, ) -> Result<(), R::Error> { match self { WorkspaceRenderElement::OverrideRedirect(elem) => { - elem.draw(frame, src, dst, damage, opaque_regions) + elem.draw(frame, src, dst, damage, opaque_regions, cache) } WorkspaceRenderElement::Fullscreen(elem) => { - elem.draw(frame, src, dst, damage, opaque_regions) + elem.draw(frame, src, dst, damage, opaque_regions, cache) } WorkspaceRenderElement::FullscreenPopup(elem) => { - elem.draw(frame, src, dst, damage, opaque_regions) + elem.draw(frame, src, dst, damage, opaque_regions, cache) } WorkspaceRenderElement::Window(elem) => { - elem.draw(frame, src, dst, damage, opaque_regions) + elem.draw(frame, src, dst, damage, opaque_regions, cache) } WorkspaceRenderElement::Backdrop(elem) => RenderElement::::draw( elem, @@ -2023,6 +2046,7 @@ where dst, damage, opaque_regions, + cache, ) .map_err(FromGlesError::from_gles_error), } @@ -2042,6 +2066,39 @@ where } } } + + fn capture_framebuffer( + &self, + frame: &mut R::Frame<'_, '_>, + src: Rectangle, + dst: Rectangle, + cache: &UserDataMap, + ) -> Result<(), R::Error> { + match self { + WorkspaceRenderElement::OverrideRedirect(elem) => { + elem.capture_framebuffer(frame, src, dst, cache) + } + WorkspaceRenderElement::Fullscreen(elem) => { + elem.capture_framebuffer(frame, src, dst, cache) + } + WorkspaceRenderElement::FullscreenPopup(elem) => { + elem.capture_framebuffer(frame, src, dst, cache) + } + WorkspaceRenderElement::Window(elem) => { + elem.capture_framebuffer(frame, src, dst, cache) + } + WorkspaceRenderElement::Backdrop(elem) => { + RenderElement::::capture_framebuffer( + elem, + R::glow_frame_mut(frame), + src, + dst, + cache, + ) + .map_err(FromGlesError::from_gles_error) + } + } + } } impl From>> for WorkspaceRenderElement diff --git a/src/state.rs b/src/state.rs index 81e16e4e..21dfcef0 100644 --- a/src/state.rs +++ b/src/state.rs @@ -940,6 +940,7 @@ impl Common { surface, output, states, + None, render_element_states, primary_scanout_output_compare, );