diff --git a/src/backend/render/mod.rs b/src/backend/render/mod.rs index f737afe1..a22289f4 100644 --- a/src/backend/render/mod.rs +++ b/src/backend/render/mod.rs @@ -55,7 +55,7 @@ use smithay::{ Color32F, Offscreen, Texture, TextureFilter, damage::{Error as RenderError, OutputDamageTracker, RenderOutputResult}, element::{ - Element, Id, Kind, RenderElement, WeakId, + Element, Id, Kind, NamespacedElement, RenderElement, WeakId, texture::{TextureRenderBuffer, TextureRenderElement}, utils::{ ConstrainAlign, ConstrainScaleBehavior, CropRenderElement, Relocate, @@ -825,7 +825,10 @@ where }) } Stage::LayerPopup { - popup, location, .. + popup, + location, + workspace_idx, + .. } => { let mut geometry = popup.geometry().as_global(); geometry.loc += location; @@ -843,11 +846,20 @@ where false, [0; 4], 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, ) } - Stage::LayerSurface { layer, location } => { + Stage::LayerSurface { + layer, + location, + workspace_idx, + } => { let mut geometry = layer.geometry().as_global(); geometry.loc += location; @@ -864,7 +876,12 @@ where false, [0; 4], 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, ); } diff --git a/src/input/mod.rs b/src/input/mod.rs index da3014ae..69b5064c 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -2132,6 +2132,7 @@ impl State { layer, popup, location, + .. } => { if layer.can_receive_keyboard_focus() { let surface = popup.wl_surface(); @@ -2149,7 +2150,9 @@ impl State { } } } - Stage::LayerSurface { layer, location } => { + Stage::LayerSurface { + layer, location, .. + } => { if under_from_surface_tree( layer.wl_surface(), global_pos.as_logical(), @@ -2301,7 +2304,9 @@ impl State { )))); } } - Stage::LayerSurface { layer, location } => { + Stage::LayerSurface { + layer, location, .. + } => { let surface = layer.wl_surface(); if let Some((surface, surface_loc)) = under_from_surface_tree( surface, diff --git a/src/shell/focus/order.rs b/src/shell/focus/order.rs index d02b310e..fb904c01 100644 --- a/src/shell/focus/order.rs +++ b/src/shell/focus/order.rs @@ -32,10 +32,12 @@ pub enum Stage<'a> { layer: LayerSurface, popup: &'a PopupKind, location: Point, + workspace_idx: usize, }, LayerSurface { layer: LayerSurface, location: Point, + workspace_idx: usize, }, OverrideRedirect { surface: &'a X11Surface, @@ -95,10 +97,15 @@ fn render_input_order_internal( layer, popup: &popup, location, + workspace_idx: current.1, })?; } 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 @@ -187,7 +194,7 @@ fn render_input_order_internal( }); ( - Some((previous, has_fullscreen, offset)), + Some((previous, previous_idx, has_fullscreen, offset)), Point::::from(match (layout, forward) { (WorkspaceLayout::Vertical, true) => (0, output_size.h + offset.y), (WorkspaceLayout::Vertical, false) => (0, -(output_size.h - offset.y)), @@ -206,6 +213,7 @@ fn render_input_order_internal( layer, popup: &popup, location, + workspace_idx: current.1, })?; } } @@ -236,7 +244,7 @@ fn render_input_order_internal( if element_filter != ElementFilter::LayerShellOnly { // 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 { return ControlFlow::Break(Err(OutputNoMode)); }; @@ -265,11 +273,12 @@ fn render_input_order_internal( layer, popup: &popup, 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 { // previous bottom layer popups @@ -278,6 +287,7 @@ fn render_input_order_internal( layer, popup: &popup, location: location + offset.as_global(), + workspace_idx: **idx, })?; } } @@ -289,11 +299,12 @@ fn render_input_order_internal( layer, popup: &popup, 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 { // previous background layer popups @@ -302,6 +313,7 @@ fn render_input_order_internal( layer, popup: &popup, location: location + offset.as_global(), + workspace_idx: **idx, })?; } } @@ -309,7 +321,11 @@ fn render_input_order_internal( if !has_focused_fullscreen { // top-layer shell 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( })?; // 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 { return ControlFlow::Break(Err(OutputNoMode)); }; @@ -341,17 +357,25 @@ fn render_input_order_internal( // bottom layer for (layer, mut location) in layer_surfaces(output, Layer::Bottom, element_filter) { 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 { // previous bottom layer for (layer, mut location) in layer_surfaces(output, Layer::Bottom, element_filter) { 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( // background layer for (layer, mut location) in layer_surfaces(output, Layer::Background, element_filter) { 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 { // previous background layer for (layer, mut location) in layer_surfaces(output, Layer::Background, element_filter) { location += offset.as_global(); - callback(Stage::LayerSurface { layer, location })?; + callback(Stage::LayerSurface { + layer, + location, + workspace_idx: **idx, + })?; } } diff --git a/src/shell/mod.rs b/src/shell/mod.rs index 60b3d1e1..b4559dce 100644 --- a/src/shell/mod.rs +++ b/src/shell/mod.rs @@ -5038,13 +5038,14 @@ impl Shell { let map = smithay::desktop::layer_map_for_output(output); for layer_surface in map.layers() { + let namespace = self.workspaces.active_num(output).1; layer_surface.take_presentation_feedback( &mut output_presentation_feedback, surface_primary_scanout_output, |surface, _| { surface_presentation_feedback_flags_from_states( surface, - None, + Some(namespace), render_element_states, ) }, diff --git a/src/shell/workspace.rs b/src/shell/workspace.rs index 6407935d..b8b104c5 100644 --- a/src/shell/workspace.rs +++ b/src/shell/workspace.rs @@ -31,7 +31,7 @@ use indexmap::IndexSet; use keyframe::{ease, functions::EaseInOutCubic}; use smallvec::SmallVec; use smithay::backend::drm::DrmNode; -use smithay::backend::renderer::element::Kind; +use smithay::backend::renderer::element::{Kind, NamespacedElement}; use smithay::output::WeakOutput; use smithay::utils::user_data::UserDataMap; use smithay::{ @@ -1974,6 +1974,7 @@ where R::TextureId: 'static, { OverrideRedirect(SurfaceRenderElement), + LowerLayerShell(NamespacedElement>), Fullscreen(RescaleRenderElement>), FullscreenPopup(CosmicWindowRenderElement), Window(CosmicMappedRenderElement), @@ -1988,6 +1989,7 @@ where fn id(&self) -> &smithay::backend::renderer::element::Id { match self { WorkspaceRenderElement::OverrideRedirect(elem) => elem.id(), + WorkspaceRenderElement::LowerLayerShell(elem) => elem.id(), WorkspaceRenderElement::Fullscreen(elem) => elem.id(), WorkspaceRenderElement::FullscreenPopup(elem) => elem.id(), WorkspaceRenderElement::Window(elem) => elem.id(), @@ -1998,6 +2000,7 @@ where fn current_commit(&self) -> smithay::backend::renderer::utils::CommitCounter { match self { WorkspaceRenderElement::OverrideRedirect(elem) => elem.current_commit(), + WorkspaceRenderElement::LowerLayerShell(elem) => elem.current_commit(), WorkspaceRenderElement::Fullscreen(elem) => elem.current_commit(), WorkspaceRenderElement::FullscreenPopup(elem) => elem.current_commit(), WorkspaceRenderElement::Window(elem) => elem.current_commit(), @@ -2008,6 +2011,7 @@ where fn src(&self) -> Rectangle { match self { WorkspaceRenderElement::OverrideRedirect(elem) => elem.src(), + WorkspaceRenderElement::LowerLayerShell(elem) => elem.src(), WorkspaceRenderElement::Fullscreen(elem) => elem.src(), WorkspaceRenderElement::FullscreenPopup(elem) => elem.src(), WorkspaceRenderElement::Window(elem) => elem.src(), @@ -2018,6 +2022,7 @@ where fn geometry(&self, scale: Scale) -> Rectangle { match self { WorkspaceRenderElement::OverrideRedirect(elem) => elem.geometry(scale), + WorkspaceRenderElement::LowerLayerShell(elem) => elem.geometry(scale), WorkspaceRenderElement::Fullscreen(elem) => elem.geometry(scale), WorkspaceRenderElement::FullscreenPopup(elem) => elem.geometry(scale), WorkspaceRenderElement::Window(elem) => elem.geometry(scale), @@ -2028,6 +2033,7 @@ where fn location(&self, scale: Scale) -> Point { match self { WorkspaceRenderElement::OverrideRedirect(elem) => elem.location(scale), + WorkspaceRenderElement::LowerLayerShell(elem) => elem.location(scale), WorkspaceRenderElement::Fullscreen(elem) => elem.location(scale), WorkspaceRenderElement::FullscreenPopup(elem) => elem.location(scale), WorkspaceRenderElement::Window(elem) => elem.location(scale), @@ -2038,6 +2044,7 @@ where fn transform(&self) -> smithay::utils::Transform { match self { WorkspaceRenderElement::OverrideRedirect(elem) => elem.transform(), + WorkspaceRenderElement::LowerLayerShell(elem) => elem.transform(), WorkspaceRenderElement::Fullscreen(elem) => elem.transform(), WorkspaceRenderElement::FullscreenPopup(elem) => elem.transform(), WorkspaceRenderElement::Window(elem) => elem.transform(), @@ -2052,6 +2059,7 @@ where ) -> DamageSet { match self { 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::FullscreenPopup(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) -> OpaqueRegions { match self { WorkspaceRenderElement::OverrideRedirect(elem) => elem.opaque_regions(scale), + WorkspaceRenderElement::LowerLayerShell(elem) => elem.opaque_regions(scale), WorkspaceRenderElement::Fullscreen(elem) => elem.opaque_regions(scale), WorkspaceRenderElement::FullscreenPopup(elem) => elem.opaque_regions(scale), WorkspaceRenderElement::Window(elem) => elem.opaque_regions(scale), @@ -2072,6 +2081,7 @@ where fn alpha(&self) -> f32 { match self { WorkspaceRenderElement::OverrideRedirect(elem) => elem.alpha(), + WorkspaceRenderElement::LowerLayerShell(elem) => elem.alpha(), WorkspaceRenderElement::Fullscreen(elem) => elem.alpha(), WorkspaceRenderElement::FullscreenPopup(elem) => elem.alpha(), WorkspaceRenderElement::Window(elem) => elem.alpha(), @@ -2082,6 +2092,7 @@ where fn kind(&self) -> Kind { match self { WorkspaceRenderElement::OverrideRedirect(elem) => elem.kind(), + WorkspaceRenderElement::LowerLayerShell(elem) => elem.kind(), WorkspaceRenderElement::Fullscreen(elem) => elem.kind(), WorkspaceRenderElement::FullscreenPopup(elem) => elem.kind(), WorkspaceRenderElement::Window(elem) => elem.kind(), @@ -2092,6 +2103,7 @@ where fn is_framebuffer_effect(&self) -> bool { match self { WorkspaceRenderElement::OverrideRedirect(elem) => elem.is_framebuffer_effect(), + WorkspaceRenderElement::LowerLayerShell(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(), @@ -2118,6 +2130,9 @@ where WorkspaceRenderElement::OverrideRedirect(elem) => { elem.draw(frame, src, dst, damage, opaque_regions, cache) } + WorkspaceRenderElement::LowerLayerShell(elem) => { + elem.draw(frame, src, dst, damage, opaque_regions, cache) + } WorkspaceRenderElement::Fullscreen(elem) => { elem.draw(frame, src, dst, damage, opaque_regions, cache) } @@ -2146,6 +2161,7 @@ where ) -> Option> { match self { WorkspaceRenderElement::OverrideRedirect(elem) => elem.underlying_storage(renderer), + WorkspaceRenderElement::LowerLayerShell(elem) => elem.underlying_storage(renderer), WorkspaceRenderElement::Fullscreen(elem) => elem.underlying_storage(renderer), WorkspaceRenderElement::FullscreenPopup(elem) => elem.underlying_storage(renderer), WorkspaceRenderElement::Window(elem) => elem.underlying_storage(renderer), @@ -2166,6 +2182,9 @@ where WorkspaceRenderElement::OverrideRedirect(elem) => { elem.capture_framebuffer(frame, src, dst, cache) } + WorkspaceRenderElement::LowerLayerShell(elem) => { + elem.capture_framebuffer(frame, src, dst, cache) + } WorkspaceRenderElement::Fullscreen(elem) => { elem.capture_framebuffer(frame, src, dst, cache) } @@ -2222,6 +2241,17 @@ where } } +impl From>> for WorkspaceRenderElement +where + R: AsGlowRenderer, + R::TextureId: 'static, + CosmicMappedRenderElement: RenderElement, +{ + fn from(elem: NamespacedElement>) -> Self { + WorkspaceRenderElement::LowerLayerShell(elem) + } +} + impl From> for WorkspaceRenderElement where R: AsGlowRenderer, diff --git a/src/state.rs b/src/state.rs index f377010c..cf66aeaa 100644 --- a/src/state.rs +++ b/src/state.rs @@ -939,19 +939,22 @@ impl Common { render_element_states: &RenderElementStates, ) { let shell = self.shell.read(); - let processor = |surface: &WlSurface, states: &SurfaceData| { - let primary_scanout_output = update_surface_primary_scanout_output( - surface, - output, - states, - None, - render_element_states, - primary_scanout_output_compare, - ); - if let Some(output) = primary_scanout_output { - with_fractional_scale(states, |fraction_scale| { - fraction_scale.set_preferred_scale(output.current_scale().fractional_scale()); - }); + let processor = |namespace: Option| { + move |surface: &WlSurface, states: &SurfaceData| { + let primary_scanout_output = update_surface_primary_scanout_output( + surface, + output, + states, + namespace, + render_element_states, + primary_scanout_output_compare, + ); + if let Some(output) = primary_scanout_output { + 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() && 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 @@ -971,7 +974,7 @@ impl Common { // cursor ... if let CursorImageStatus::Surface(wl_surface) = cursor_status { - with_surfaces_surface_tree(&wl_surface, processor); + with_surfaces_surface_tree(&wl_surface, processor(None)); } // grabs @@ -979,12 +982,12 @@ impl Common { && let Some(grab_state) = move_grab.lock().unwrap().as_ref() { for (window, _) in grab_state.element().windows() { - window.with_surfaces(processor); + window.with_surfaces(processor(None)); } } 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() { set.sticky_layer.mapped().for_each(|mapped| { for (window, _) in mapped.windows() { - window.with_surfaces(processor); + window.with_surfaces(processor(None)); } }); } @@ -1000,16 +1003,16 @@ impl Common { // normal windows for space in shell.workspaces.spaces() { 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| { for (window, _) in mapped.windows() { - window.with_surfaces(processor); + window.with_surfaces(processor(None)); } }); space.minimized_windows.iter().for_each(|m| { for window in m.windows() { - window.with_surfaces(processor); + window.with_surfaces(processor(None)); } }) } @@ -1017,15 +1020,16 @@ impl Common { // OR windows shell.override_redirect_windows.iter().for_each(|or| { 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 for o in shell.outputs() { + let namespace = shell.workspaces.active_num(o).1; let map = smithay::desktop::layer_map_for_output(o); for layer_surface in map.layers() { - layer_surface.with_surfaces(processor); + layer_surface.with_surfaces(processor(Some(namespace))); } } }