render: Use NamespaceElements to fix blurred lower layer-shell surfaces

This commit is contained in:
Victoria Brekenfeld 2026-03-06 17:19:12 +01:00 committed by Victoria Brekenfeld
parent a9bf89d8b2
commit eb41b076ed
6 changed files with 134 additions and 45 deletions

View file

@ -55,7 +55,7 @@ use smithay::{
Color32F, Offscreen, Texture, TextureFilter, Color32F, Offscreen, Texture, TextureFilter,
damage::{Error as RenderError, OutputDamageTracker, RenderOutputResult}, damage::{Error as RenderError, OutputDamageTracker, RenderOutputResult},
element::{ element::{
Element, Id, Kind, RenderElement, WeakId, Element, Id, Kind, NamespacedElement, RenderElement, WeakId,
texture::{TextureRenderBuffer, TextureRenderElement}, texture::{TextureRenderBuffer, TextureRenderElement},
utils::{ utils::{
ConstrainAlign, ConstrainScaleBehavior, CropRenderElement, Relocate, ConstrainAlign, ConstrainScaleBehavior, CropRenderElement, Relocate,
@ -825,7 +825,10 @@ where
}) })
} }
Stage::LayerPopup { Stage::LayerPopup {
popup, location, .. popup,
location,
workspace_idx,
..
} => { } => {
let mut geometry = popup.geometry().as_global(); let mut geometry = popup.geometry().as_global();
geometry.loc += location; geometry.loc += location;
@ -843,11 +846,20 @@ where
false, false,
[0; 4], [0; 4],
FRAME_TIME_FILTER, FRAME_TIME_FILTER,
&mut |elem| elements.extend(crop_to_output(elem.into()).map(Into::into)), &mut |elem| {
elements.extend(
crop_to_output(NamespacedElement::new(elem, workspace_idx).into())
.map(Into::into),
)
},
None, None,
) )
} }
Stage::LayerSurface { layer, location } => { Stage::LayerSurface {
layer,
location,
workspace_idx,
} => {
let mut geometry = layer.geometry().as_global(); let mut geometry = layer.geometry().as_global();
geometry.loc += location; geometry.loc += location;
@ -864,7 +876,12 @@ where
false, false,
[0; 4], [0; 4],
FRAME_TIME_FILTER, FRAME_TIME_FILTER,
&mut |elem| elements.extend(crop_to_output(elem.into()).map(Into::into)), &mut |elem| {
elements.extend(
crop_to_output(NamespacedElement::new(elem, workspace_idx).into())
.map(Into::into),
)
},
None, None,
); );
} }

View file

@ -2132,6 +2132,7 @@ impl State {
layer, layer,
popup, popup,
location, location,
..
} => { } => {
if layer.can_receive_keyboard_focus() { if layer.can_receive_keyboard_focus() {
let surface = popup.wl_surface(); let surface = popup.wl_surface();
@ -2149,7 +2150,9 @@ impl State {
} }
} }
} }
Stage::LayerSurface { layer, location } => { Stage::LayerSurface {
layer, location, ..
} => {
if under_from_surface_tree( if under_from_surface_tree(
layer.wl_surface(), layer.wl_surface(),
global_pos.as_logical(), global_pos.as_logical(),
@ -2301,7 +2304,9 @@ impl State {
)))); ))));
} }
} }
Stage::LayerSurface { layer, location } => { Stage::LayerSurface {
layer, location, ..
} => {
let surface = layer.wl_surface(); let surface = layer.wl_surface();
if let Some((surface, surface_loc)) = under_from_surface_tree( if let Some((surface, surface_loc)) = under_from_surface_tree(
surface, surface,

View file

@ -32,10 +32,12 @@ pub enum Stage<'a> {
layer: LayerSurface, layer: LayerSurface,
popup: &'a PopupKind, popup: &'a PopupKind,
location: Point<i32, Global>, location: Point<i32, Global>,
workspace_idx: usize,
}, },
LayerSurface { LayerSurface {
layer: LayerSurface, layer: LayerSurface,
location: Point<i32, Global>, location: Point<i32, Global>,
workspace_idx: usize,
}, },
OverrideRedirect { OverrideRedirect {
surface: &'a X11Surface, surface: &'a X11Surface,
@ -95,10 +97,15 @@ fn render_input_order_internal<R: 'static>(
layer, layer,
popup: &popup, popup: &popup,
location, location,
workspace_idx: current.1,
})?; })?;
} }
for (layer, location) in layer_surfaces(output, Layer::Overlay, element_filter) { for (layer, location) in layer_surfaces(output, Layer::Overlay, element_filter) {
callback(Stage::LayerSurface { layer, location })?; callback(Stage::LayerSurface {
layer,
location,
workspace_idx: current.1,
})?;
} }
// calculate a bunch of stuff for workspace transitions // calculate a bunch of stuff for workspace transitions
@ -187,7 +194,7 @@ fn render_input_order_internal<R: 'static>(
}); });
( (
Some((previous, has_fullscreen, offset)), Some((previous, previous_idx, has_fullscreen, offset)),
Point::<i32, Logical>::from(match (layout, forward) { Point::<i32, Logical>::from(match (layout, forward) {
(WorkspaceLayout::Vertical, true) => (0, output_size.h + offset.y), (WorkspaceLayout::Vertical, true) => (0, output_size.h + offset.y),
(WorkspaceLayout::Vertical, false) => (0, -(output_size.h - offset.y)), (WorkspaceLayout::Vertical, false) => (0, -(output_size.h - offset.y)),
@ -206,6 +213,7 @@ fn render_input_order_internal<R: 'static>(
layer, layer,
popup: &popup, popup: &popup,
location, location,
workspace_idx: current.1,
})?; })?;
} }
} }
@ -236,7 +244,7 @@ fn render_input_order_internal<R: 'static>(
if element_filter != ElementFilter::LayerShellOnly { if element_filter != ElementFilter::LayerShellOnly {
// previous workspace popups // previous workspace popups
if let Some((previous_handle, _, offset)) = previous.as_ref() { if let Some((previous_handle, _, _, offset)) = previous.as_ref() {
let Some(workspace) = shell.workspaces.space_for_handle(previous_handle) else { let Some(workspace) = shell.workspaces.space_for_handle(previous_handle) else {
return ControlFlow::Break(Err(OutputNoMode)); return ControlFlow::Break(Err(OutputNoMode));
}; };
@ -265,11 +273,12 @@ fn render_input_order_internal<R: 'static>(
layer, layer,
popup: &popup, popup: &popup,
location, location,
workspace_idx: current.1,
})?; })?;
} }
} }
if let Some((_, has_fullscreen, offset)) = previous.as_ref() if let Some((_, idx, has_fullscreen, offset)) = previous.as_ref()
&& !has_fullscreen && !has_fullscreen
{ {
// previous bottom layer popups // previous bottom layer popups
@ -278,6 +287,7 @@ fn render_input_order_internal<R: 'static>(
layer, layer,
popup: &popup, popup: &popup,
location: location + offset.as_global(), location: location + offset.as_global(),
workspace_idx: **idx,
})?; })?;
} }
} }
@ -289,11 +299,12 @@ fn render_input_order_internal<R: 'static>(
layer, layer,
popup: &popup, popup: &popup,
location, location,
workspace_idx: current.1,
})?; })?;
} }
} }
if let Some((_, has_fullscreen, offset)) = previous.as_ref() if let Some((_, idx, has_fullscreen, offset)) = previous.as_ref()
&& !has_fullscreen && !has_fullscreen
{ {
// previous background layer popups // previous background layer popups
@ -302,6 +313,7 @@ fn render_input_order_internal<R: 'static>(
layer, layer,
popup: &popup, popup: &popup,
location: location + offset.as_global(), location: location + offset.as_global(),
workspace_idx: **idx,
})?; })?;
} }
} }
@ -309,7 +321,11 @@ fn render_input_order_internal<R: 'static>(
if !has_focused_fullscreen { if !has_focused_fullscreen {
// top-layer shell // top-layer shell
for (layer, location) in layer_surfaces(output, Layer::Top, element_filter) { for (layer, location) in layer_surfaces(output, Layer::Top, element_filter) {
callback(Stage::LayerSurface { layer, location })?; callback(Stage::LayerSurface {
layer,
location,
workspace_idx: current.1,
})?;
} }
} }
@ -326,7 +342,7 @@ fn render_input_order_internal<R: 'static>(
})?; })?;
// previous workspace windows // previous workspace windows
if let Some((previous_handle, _, offset)) = previous.as_ref() { if let Some((previous_handle, _, _, offset)) = previous.as_ref() {
let Some(workspace) = shell.workspaces.space_for_handle(previous_handle) else { let Some(workspace) = shell.workspaces.space_for_handle(previous_handle) else {
return ControlFlow::Break(Err(OutputNoMode)); return ControlFlow::Break(Err(OutputNoMode));
}; };
@ -341,17 +357,25 @@ fn render_input_order_internal<R: 'static>(
// bottom layer // bottom layer
for (layer, mut location) in layer_surfaces(output, Layer::Bottom, element_filter) { for (layer, mut location) in layer_surfaces(output, Layer::Bottom, element_filter) {
location += current_offset.as_global(); location += current_offset.as_global();
callback(Stage::LayerSurface { layer, location })?; callback(Stage::LayerSurface {
layer,
location,
workspace_idx: current.1,
})?;
} }
} }
if let Some((_, has_fullscreen, offset)) = previous.as_ref() if let Some((_, idx, has_fullscreen, offset)) = previous.as_ref()
&& !has_fullscreen && !has_fullscreen
{ {
// previous bottom layer // previous bottom layer
for (layer, mut location) in layer_surfaces(output, Layer::Bottom, element_filter) { for (layer, mut location) in layer_surfaces(output, Layer::Bottom, element_filter) {
location += offset.as_global(); location += offset.as_global();
callback(Stage::LayerSurface { layer, location })?; callback(Stage::LayerSurface {
layer,
location,
workspace_idx: **idx,
})?;
} }
} }
@ -359,17 +383,25 @@ fn render_input_order_internal<R: 'static>(
// background layer // background layer
for (layer, mut location) in layer_surfaces(output, Layer::Background, element_filter) { for (layer, mut location) in layer_surfaces(output, Layer::Background, element_filter) {
location += current_offset.as_global(); location += current_offset.as_global();
callback(Stage::LayerSurface { layer, location })?; callback(Stage::LayerSurface {
layer,
location,
workspace_idx: current.1,
})?;
} }
} }
if let Some((_, has_fullscreen, offset)) = previous.as_ref() if let Some((_, idx, has_fullscreen, offset)) = previous.as_ref()
&& !has_fullscreen && !has_fullscreen
{ {
// previous background layer // previous background layer
for (layer, mut location) in layer_surfaces(output, Layer::Background, element_filter) { for (layer, mut location) in layer_surfaces(output, Layer::Background, element_filter) {
location += offset.as_global(); location += offset.as_global();
callback(Stage::LayerSurface { layer, location })?; callback(Stage::LayerSurface {
layer,
location,
workspace_idx: **idx,
})?;
} }
} }

View file

@ -5038,13 +5038,14 @@ impl Shell {
let map = smithay::desktop::layer_map_for_output(output); let map = smithay::desktop::layer_map_for_output(output);
for layer_surface in map.layers() { for layer_surface in map.layers() {
let namespace = self.workspaces.active_num(output).1;
layer_surface.take_presentation_feedback( layer_surface.take_presentation_feedback(
&mut output_presentation_feedback, &mut output_presentation_feedback,
surface_primary_scanout_output, surface_primary_scanout_output,
|surface, _| { |surface, _| {
surface_presentation_feedback_flags_from_states( surface_presentation_feedback_flags_from_states(
surface, surface,
None, Some(namespace),
render_element_states, render_element_states,
) )
}, },

View file

@ -31,7 +31,7 @@ use indexmap::IndexSet;
use keyframe::{ease, functions::EaseInOutCubic}; use keyframe::{ease, functions::EaseInOutCubic};
use smallvec::SmallVec; use smallvec::SmallVec;
use smithay::backend::drm::DrmNode; use smithay::backend::drm::DrmNode;
use smithay::backend::renderer::element::Kind; use smithay::backend::renderer::element::{Kind, NamespacedElement};
use smithay::output::WeakOutput; use smithay::output::WeakOutput;
use smithay::utils::user_data::UserDataMap; use smithay::utils::user_data::UserDataMap;
use smithay::{ use smithay::{
@ -1974,6 +1974,7 @@ where
R::TextureId: 'static, R::TextureId: 'static,
{ {
OverrideRedirect(SurfaceRenderElement<R>), OverrideRedirect(SurfaceRenderElement<R>),
LowerLayerShell(NamespacedElement<SurfaceRenderElement<R>>),
Fullscreen(RescaleRenderElement<CosmicWindowRenderElement<R>>), Fullscreen(RescaleRenderElement<CosmicWindowRenderElement<R>>),
FullscreenPopup(CosmicWindowRenderElement<R>), FullscreenPopup(CosmicWindowRenderElement<R>),
Window(CosmicMappedRenderElement<R>), Window(CosmicMappedRenderElement<R>),
@ -1988,6 +1989,7 @@ where
fn id(&self) -> &smithay::backend::renderer::element::Id { fn id(&self) -> &smithay::backend::renderer::element::Id {
match self { match self {
WorkspaceRenderElement::OverrideRedirect(elem) => elem.id(), WorkspaceRenderElement::OverrideRedirect(elem) => elem.id(),
WorkspaceRenderElement::LowerLayerShell(elem) => elem.id(),
WorkspaceRenderElement::Fullscreen(elem) => elem.id(), WorkspaceRenderElement::Fullscreen(elem) => elem.id(),
WorkspaceRenderElement::FullscreenPopup(elem) => elem.id(), WorkspaceRenderElement::FullscreenPopup(elem) => elem.id(),
WorkspaceRenderElement::Window(elem) => elem.id(), WorkspaceRenderElement::Window(elem) => elem.id(),
@ -1998,6 +2000,7 @@ where
fn current_commit(&self) -> smithay::backend::renderer::utils::CommitCounter { fn current_commit(&self) -> smithay::backend::renderer::utils::CommitCounter {
match self { match self {
WorkspaceRenderElement::OverrideRedirect(elem) => elem.current_commit(), WorkspaceRenderElement::OverrideRedirect(elem) => elem.current_commit(),
WorkspaceRenderElement::LowerLayerShell(elem) => elem.current_commit(),
WorkspaceRenderElement::Fullscreen(elem) => elem.current_commit(), WorkspaceRenderElement::Fullscreen(elem) => elem.current_commit(),
WorkspaceRenderElement::FullscreenPopup(elem) => elem.current_commit(), WorkspaceRenderElement::FullscreenPopup(elem) => elem.current_commit(),
WorkspaceRenderElement::Window(elem) => elem.current_commit(), WorkspaceRenderElement::Window(elem) => elem.current_commit(),
@ -2008,6 +2011,7 @@ where
fn src(&self) -> Rectangle<f64, smithay::utils::Buffer> { fn src(&self) -> Rectangle<f64, smithay::utils::Buffer> {
match self { match self {
WorkspaceRenderElement::OverrideRedirect(elem) => elem.src(), WorkspaceRenderElement::OverrideRedirect(elem) => elem.src(),
WorkspaceRenderElement::LowerLayerShell(elem) => elem.src(),
WorkspaceRenderElement::Fullscreen(elem) => elem.src(), WorkspaceRenderElement::Fullscreen(elem) => elem.src(),
WorkspaceRenderElement::FullscreenPopup(elem) => elem.src(), WorkspaceRenderElement::FullscreenPopup(elem) => elem.src(),
WorkspaceRenderElement::Window(elem) => elem.src(), WorkspaceRenderElement::Window(elem) => elem.src(),
@ -2018,6 +2022,7 @@ where
fn geometry(&self, scale: Scale<f64>) -> Rectangle<i32, smithay::utils::Physical> { fn geometry(&self, scale: Scale<f64>) -> Rectangle<i32, smithay::utils::Physical> {
match self { match self {
WorkspaceRenderElement::OverrideRedirect(elem) => elem.geometry(scale), WorkspaceRenderElement::OverrideRedirect(elem) => elem.geometry(scale),
WorkspaceRenderElement::LowerLayerShell(elem) => elem.geometry(scale),
WorkspaceRenderElement::Fullscreen(elem) => elem.geometry(scale), WorkspaceRenderElement::Fullscreen(elem) => elem.geometry(scale),
WorkspaceRenderElement::FullscreenPopup(elem) => elem.geometry(scale), WorkspaceRenderElement::FullscreenPopup(elem) => elem.geometry(scale),
WorkspaceRenderElement::Window(elem) => elem.geometry(scale), WorkspaceRenderElement::Window(elem) => elem.geometry(scale),
@ -2028,6 +2033,7 @@ where
fn location(&self, scale: Scale<f64>) -> Point<i32, smithay::utils::Physical> { fn location(&self, scale: Scale<f64>) -> Point<i32, smithay::utils::Physical> {
match self { match self {
WorkspaceRenderElement::OverrideRedirect(elem) => elem.location(scale), WorkspaceRenderElement::OverrideRedirect(elem) => elem.location(scale),
WorkspaceRenderElement::LowerLayerShell(elem) => elem.location(scale),
WorkspaceRenderElement::Fullscreen(elem) => elem.location(scale), WorkspaceRenderElement::Fullscreen(elem) => elem.location(scale),
WorkspaceRenderElement::FullscreenPopup(elem) => elem.location(scale), WorkspaceRenderElement::FullscreenPopup(elem) => elem.location(scale),
WorkspaceRenderElement::Window(elem) => elem.location(scale), WorkspaceRenderElement::Window(elem) => elem.location(scale),
@ -2038,6 +2044,7 @@ where
fn transform(&self) -> smithay::utils::Transform { fn transform(&self) -> smithay::utils::Transform {
match self { match self {
WorkspaceRenderElement::OverrideRedirect(elem) => elem.transform(), WorkspaceRenderElement::OverrideRedirect(elem) => elem.transform(),
WorkspaceRenderElement::LowerLayerShell(elem) => elem.transform(),
WorkspaceRenderElement::Fullscreen(elem) => elem.transform(), WorkspaceRenderElement::Fullscreen(elem) => elem.transform(),
WorkspaceRenderElement::FullscreenPopup(elem) => elem.transform(), WorkspaceRenderElement::FullscreenPopup(elem) => elem.transform(),
WorkspaceRenderElement::Window(elem) => elem.transform(), WorkspaceRenderElement::Window(elem) => elem.transform(),
@ -2052,6 +2059,7 @@ where
) -> DamageSet<i32, smithay::utils::Physical> { ) -> DamageSet<i32, smithay::utils::Physical> {
match self { match self {
WorkspaceRenderElement::OverrideRedirect(elem) => elem.damage_since(scale, commit), WorkspaceRenderElement::OverrideRedirect(elem) => elem.damage_since(scale, commit),
WorkspaceRenderElement::LowerLayerShell(elem) => elem.damage_since(scale, commit),
WorkspaceRenderElement::Fullscreen(elem) => elem.damage_since(scale, commit), WorkspaceRenderElement::Fullscreen(elem) => elem.damage_since(scale, commit),
WorkspaceRenderElement::FullscreenPopup(elem) => elem.damage_since(scale, commit), WorkspaceRenderElement::FullscreenPopup(elem) => elem.damage_since(scale, commit),
WorkspaceRenderElement::Window(elem) => elem.damage_since(scale, commit), WorkspaceRenderElement::Window(elem) => elem.damage_since(scale, commit),
@ -2062,6 +2070,7 @@ where
fn opaque_regions(&self, scale: Scale<f64>) -> OpaqueRegions<i32, smithay::utils::Physical> { fn opaque_regions(&self, scale: Scale<f64>) -> OpaqueRegions<i32, smithay::utils::Physical> {
match self { match self {
WorkspaceRenderElement::OverrideRedirect(elem) => elem.opaque_regions(scale), WorkspaceRenderElement::OverrideRedirect(elem) => elem.opaque_regions(scale),
WorkspaceRenderElement::LowerLayerShell(elem) => elem.opaque_regions(scale),
WorkspaceRenderElement::Fullscreen(elem) => elem.opaque_regions(scale), WorkspaceRenderElement::Fullscreen(elem) => elem.opaque_regions(scale),
WorkspaceRenderElement::FullscreenPopup(elem) => elem.opaque_regions(scale), WorkspaceRenderElement::FullscreenPopup(elem) => elem.opaque_regions(scale),
WorkspaceRenderElement::Window(elem) => elem.opaque_regions(scale), WorkspaceRenderElement::Window(elem) => elem.opaque_regions(scale),
@ -2072,6 +2081,7 @@ where
fn alpha(&self) -> f32 { fn alpha(&self) -> f32 {
match self { match self {
WorkspaceRenderElement::OverrideRedirect(elem) => elem.alpha(), WorkspaceRenderElement::OverrideRedirect(elem) => elem.alpha(),
WorkspaceRenderElement::LowerLayerShell(elem) => elem.alpha(),
WorkspaceRenderElement::Fullscreen(elem) => elem.alpha(), WorkspaceRenderElement::Fullscreen(elem) => elem.alpha(),
WorkspaceRenderElement::FullscreenPopup(elem) => elem.alpha(), WorkspaceRenderElement::FullscreenPopup(elem) => elem.alpha(),
WorkspaceRenderElement::Window(elem) => elem.alpha(), WorkspaceRenderElement::Window(elem) => elem.alpha(),
@ -2082,6 +2092,7 @@ where
fn kind(&self) -> Kind { fn kind(&self) -> Kind {
match self { match self {
WorkspaceRenderElement::OverrideRedirect(elem) => elem.kind(), WorkspaceRenderElement::OverrideRedirect(elem) => elem.kind(),
WorkspaceRenderElement::LowerLayerShell(elem) => elem.kind(),
WorkspaceRenderElement::Fullscreen(elem) => elem.kind(), WorkspaceRenderElement::Fullscreen(elem) => elem.kind(),
WorkspaceRenderElement::FullscreenPopup(elem) => elem.kind(), WorkspaceRenderElement::FullscreenPopup(elem) => elem.kind(),
WorkspaceRenderElement::Window(elem) => elem.kind(), WorkspaceRenderElement::Window(elem) => elem.kind(),
@ -2092,6 +2103,7 @@ where
fn is_framebuffer_effect(&self) -> bool { fn is_framebuffer_effect(&self) -> bool {
match self { match self {
WorkspaceRenderElement::OverrideRedirect(elem) => elem.is_framebuffer_effect(), WorkspaceRenderElement::OverrideRedirect(elem) => elem.is_framebuffer_effect(),
WorkspaceRenderElement::LowerLayerShell(elem) => elem.is_framebuffer_effect(),
WorkspaceRenderElement::Fullscreen(elem) => elem.is_framebuffer_effect(), WorkspaceRenderElement::Fullscreen(elem) => elem.is_framebuffer_effect(),
WorkspaceRenderElement::FullscreenPopup(elem) => elem.is_framebuffer_effect(), WorkspaceRenderElement::FullscreenPopup(elem) => elem.is_framebuffer_effect(),
WorkspaceRenderElement::Window(elem) => elem.is_framebuffer_effect(), WorkspaceRenderElement::Window(elem) => elem.is_framebuffer_effect(),
@ -2118,6 +2130,9 @@ where
WorkspaceRenderElement::OverrideRedirect(elem) => { WorkspaceRenderElement::OverrideRedirect(elem) => {
elem.draw(frame, src, dst, damage, opaque_regions, cache) elem.draw(frame, src, dst, damage, opaque_regions, cache)
} }
WorkspaceRenderElement::LowerLayerShell(elem) => {
elem.draw(frame, src, dst, damage, opaque_regions, cache)
}
WorkspaceRenderElement::Fullscreen(elem) => { WorkspaceRenderElement::Fullscreen(elem) => {
elem.draw(frame, src, dst, damage, opaque_regions, cache) elem.draw(frame, src, dst, damage, opaque_regions, cache)
} }
@ -2146,6 +2161,7 @@ where
) -> Option<smithay::backend::renderer::element::UnderlyingStorage<'_>> { ) -> Option<smithay::backend::renderer::element::UnderlyingStorage<'_>> {
match self { match self {
WorkspaceRenderElement::OverrideRedirect(elem) => elem.underlying_storage(renderer), WorkspaceRenderElement::OverrideRedirect(elem) => elem.underlying_storage(renderer),
WorkspaceRenderElement::LowerLayerShell(elem) => elem.underlying_storage(renderer),
WorkspaceRenderElement::Fullscreen(elem) => elem.underlying_storage(renderer), WorkspaceRenderElement::Fullscreen(elem) => elem.underlying_storage(renderer),
WorkspaceRenderElement::FullscreenPopup(elem) => elem.underlying_storage(renderer), WorkspaceRenderElement::FullscreenPopup(elem) => elem.underlying_storage(renderer),
WorkspaceRenderElement::Window(elem) => elem.underlying_storage(renderer), WorkspaceRenderElement::Window(elem) => elem.underlying_storage(renderer),
@ -2166,6 +2182,9 @@ where
WorkspaceRenderElement::OverrideRedirect(elem) => { WorkspaceRenderElement::OverrideRedirect(elem) => {
elem.capture_framebuffer(frame, src, dst, cache) elem.capture_framebuffer(frame, src, dst, cache)
} }
WorkspaceRenderElement::LowerLayerShell(elem) => {
elem.capture_framebuffer(frame, src, dst, cache)
}
WorkspaceRenderElement::Fullscreen(elem) => { WorkspaceRenderElement::Fullscreen(elem) => {
elem.capture_framebuffer(frame, src, dst, cache) elem.capture_framebuffer(frame, src, dst, cache)
} }
@ -2222,6 +2241,17 @@ where
} }
} }
impl<R> From<NamespacedElement<SurfaceRenderElement<R>>> for WorkspaceRenderElement<R>
where
R: AsGlowRenderer,
R::TextureId: 'static,
CosmicMappedRenderElement<R>: RenderElement<R>,
{
fn from(elem: NamespacedElement<SurfaceRenderElement<R>>) -> Self {
WorkspaceRenderElement::LowerLayerShell(elem)
}
}
impl<R> From<CosmicMappedRenderElement<R>> for WorkspaceRenderElement<R> impl<R> From<CosmicMappedRenderElement<R>> for WorkspaceRenderElement<R>
where where
R: AsGlowRenderer, R: AsGlowRenderer,

View file

@ -939,19 +939,22 @@ impl Common {
render_element_states: &RenderElementStates, render_element_states: &RenderElementStates,
) { ) {
let shell = self.shell.read(); let shell = self.shell.read();
let processor = |surface: &WlSurface, states: &SurfaceData| { let processor = |namespace: Option<usize>| {
let primary_scanout_output = update_surface_primary_scanout_output( move |surface: &WlSurface, states: &SurfaceData| {
surface, let primary_scanout_output = update_surface_primary_scanout_output(
output, surface,
states, output,
None, states,
render_element_states, namespace,
primary_scanout_output_compare, render_element_states,
); primary_scanout_output_compare,
if let Some(output) = primary_scanout_output { );
with_fractional_scale(states, |fraction_scale| { if let Some(output) = primary_scanout_output {
fraction_scale.set_preferred_scale(output.current_scale().fractional_scale()); with_fractional_scale(states, |fraction_scale| {
}); fraction_scale
.set_preferred_scale(output.current_scale().fractional_scale());
});
}
} }
}; };
@ -959,7 +962,7 @@ impl Common {
if let Some(session_lock) = shell.session_lock.as_ref() if let Some(session_lock) = shell.session_lock.as_ref()
&& let Some(lock_surface) = session_lock.surfaces.get(output) && let Some(lock_surface) = session_lock.surfaces.get(output)
{ {
with_surfaces_surface_tree(lock_surface.wl_surface(), processor) with_surfaces_surface_tree(lock_surface.wl_surface(), processor(None))
} }
for seat in shell for seat in shell
@ -971,7 +974,7 @@ impl Common {
// cursor ... // cursor ...
if let CursorImageStatus::Surface(wl_surface) = cursor_status { if let CursorImageStatus::Surface(wl_surface) = cursor_status {
with_surfaces_surface_tree(&wl_surface, processor); with_surfaces_surface_tree(&wl_surface, processor(None));
} }
// grabs // grabs
@ -979,12 +982,12 @@ impl Common {
&& let Some(grab_state) = move_grab.lock().unwrap().as_ref() && let Some(grab_state) = move_grab.lock().unwrap().as_ref()
{ {
for (window, _) in grab_state.element().windows() { for (window, _) in grab_state.element().windows() {
window.with_surfaces(processor); window.with_surfaces(processor(None));
} }
} }
if let Some(icon) = get_dnd_icon(seat) { if let Some(icon) = get_dnd_icon(seat) {
with_surfaces_surface_tree(&icon.surface, processor); with_surfaces_surface_tree(&icon.surface, processor(None));
} }
} }
@ -992,7 +995,7 @@ impl Common {
for set in shell.workspaces.sets.values() { for set in shell.workspaces.sets.values() {
set.sticky_layer.mapped().for_each(|mapped| { set.sticky_layer.mapped().for_each(|mapped| {
for (window, _) in mapped.windows() { for (window, _) in mapped.windows() {
window.with_surfaces(processor); window.with_surfaces(processor(None));
} }
}); });
} }
@ -1000,16 +1003,16 @@ impl Common {
// normal windows // normal windows
for space in shell.workspaces.spaces() { for space in shell.workspaces.spaces() {
if let Some(fs) = space.get_fullscreen(shell.seats.last_active()) { if let Some(fs) = space.get_fullscreen(shell.seats.last_active()) {
fs.surface.with_surfaces(processor); fs.surface.with_surfaces(processor(None));
} }
space.mapped().for_each(|mapped| { space.mapped().for_each(|mapped| {
for (window, _) in mapped.windows() { for (window, _) in mapped.windows() {
window.with_surfaces(processor); window.with_surfaces(processor(None));
} }
}); });
space.minimized_windows.iter().for_each(|m| { space.minimized_windows.iter().for_each(|m| {
for window in m.windows() { for window in m.windows() {
window.with_surfaces(processor); window.with_surfaces(processor(None));
} }
}) })
} }
@ -1017,15 +1020,16 @@ impl Common {
// OR windows // OR windows
shell.override_redirect_windows.iter().for_each(|or| { shell.override_redirect_windows.iter().for_each(|or| {
if let Some(wl_surface) = or.wl_surface() { if let Some(wl_surface) = or.wl_surface() {
with_surfaces_surface_tree(&wl_surface, processor); with_surfaces_surface_tree(&wl_surface, processor(None));
} }
}); });
// layer surfaces // layer surfaces
for o in shell.outputs() { for o in shell.outputs() {
let namespace = shell.workspaces.active_num(o).1;
let map = smithay::desktop::layer_map_for_output(o); let map = smithay::desktop::layer_map_for_output(o);
for layer_surface in map.layers() { for layer_surface in map.layers() {
layer_surface.with_surfaces(processor); layer_surface.with_surfaces(processor(Some(namespace)));
} }
} }
} }