shell: Fix render order regarding popups

This commit is contained in:
Victoria Brekenfeld 2023-07-13 17:19:29 +02:00
parent a308997fd4
commit c7d4fa5d53
9 changed files with 676 additions and 544 deletions

View file

@ -46,8 +46,9 @@ use smithay::{
buffer_dimensions, buffer_dimensions,
damage::{Error as RenderError, OutputDamageTracker, OutputNoMode, RenderOutputResult}, damage::{Error as RenderError, OutputDamageTracker, OutputNoMode, RenderOutputResult},
element::{ element::{
surface::render_elements_from_surface_tree,
utils::{Relocate, RelocateRenderElement}, utils::{Relocate, RelocateRenderElement},
AsRenderElements, Element, Id, RenderElement, Element, Id, RenderElement,
}, },
gles::{ gles::{
element::PixelShaderElement, GlesError, GlesPixelProgram, GlesRenderer, Uniform, element::PixelShaderElement, GlesError, GlesPixelProgram, GlesRenderer, Uniform,
@ -59,7 +60,7 @@ use smithay::{
Bind, Blit, ExportMem, ImportAll, ImportMem, Offscreen, Renderer, TextureFilter, Bind, Blit, ExportMem, ImportAll, ImportMem, Offscreen, Renderer, TextureFilter,
}, },
}, },
desktop::layer_map_for_output, desktop::{layer_map_for_output, PopupManager},
output::Output, output::Output,
utils::{IsAlive, Logical, Point, Rectangle, Scale}, utils::{IsAlive, Logical, Point, Rectangle, Scale},
wayland::{ wayland::{
@ -495,14 +496,23 @@ where
.shell .shell
.space_for_handle(&current.0) .space_for_handle(&current.0)
.ok_or(OutputNoMode)?; .ok_or(OutputNoMode)?;
let has_fullscreen = workspace.fullscreen.contains_key(output);
// foreground layers are static let has_fullscreen = workspace.fullscreen.contains_key(output);
elements.extend( let (overlay_elements, overlay_popups) =
foreground_layer_elements(renderer, output, has_fullscreen, exclude_workspace_overview) split_layer_elements(renderer, output, Layer::Overlay, exclude_workspace_overview);
.into_iter()
.map(Into::into), // overlay is above everything
); elements.extend(overlay_popups.into_iter().map(Into::into));
elements.extend(overlay_elements.into_iter().map(Into::into));
let mut window_elements = if has_fullscreen {
let (top_elements, top_popups) =
split_layer_elements(renderer, output, Layer::Top, exclude_workspace_overview);
elements.extend(top_popups.into_iter().map(Into::into));
top_elements.into_iter().map(Into::into).collect()
} else {
Vec::new()
};
let offset = match previous.as_ref() { let offset = match previous.as_ref() {
Some((previous, previous_idx, start)) => { Some((previous, previous_idx, start)) => {
@ -534,40 +544,49 @@ where
} }
}); });
elements.extend( let (w_elements, p_elements) = workspace
workspace .render_output::<R>(
.render_output::<R>( renderer,
renderer, output,
output, &state.shell.override_redirect_windows,
&state.shell.override_redirect_windows, state.xwayland_state.as_mut(),
state.xwayland_state.as_mut(), (!move_active && is_active_space).then_some(&last_active_seat),
(!move_active && is_active_space).then_some(&last_active_seat), overview.clone(),
overview.clone(), resize_indicator.clone(),
resize_indicator.clone(), state.config.static_conf.active_hint,
state.config.static_conf.active_hint, )
) .map_err(|_| OutputNoMode)?;
.map_err(|_| OutputNoMode)? elements.extend(p_elements.into_iter().map(|p_element| {
.into_iter() CosmicElement::Workspace(RelocateRenderElement::from_element(
.map(|w_element| { p_element,
CosmicElement::Workspace(RelocateRenderElement::from_element( offset.to_physical_precise_round(output_scale),
w_element, Relocate::Relative,
offset.to_physical_precise_round(output_scale), ))
Relocate::Relative, }));
)) window_elements.extend(w_elements.into_iter().map(|w_element| {
}), CosmicElement::Workspace(RelocateRenderElement::from_element(
); w_element,
offset.to_physical_precise_round(output_scale),
Relocate::Relative,
))
}));
elements.extend( let (w_elements, p_elements) =
background_layer_elements(renderer, output, exclude_workspace_overview) background_layer_elements(renderer, output, exclude_workspace_overview);
.into_iter() elements.extend(p_elements.into_iter().map(|p_element| {
.map(|w_element| { CosmicElement::Workspace(RelocateRenderElement::from_element(
CosmicElement::Workspace(RelocateRenderElement::from_element( p_element,
w_element, offset.to_physical_precise_round(output_scale),
offset.to_physical_precise_round(output_scale), Relocate::Relative,
Relocate::Relative, ))
)) }));
}), window_elements.extend(w_elements.into_iter().map(|w_element| {
); CosmicElement::Workspace(RelocateRenderElement::from_element(
w_element,
offset.to_physical_precise_round(output_scale),
Relocate::Relative,
))
}));
Point::<i32, Logical>::from(match (layout, *previous_idx < current.1) { Point::<i32, Logical>::from(match (layout, *previous_idx < current.1) {
(WorkspaceLayout::Vertical, true) => (0, output_size.h + offset.y), (WorkspaceLayout::Vertical, true) => (0, output_size.h + offset.y),
@ -581,51 +600,66 @@ where
let is_active_space = workspace.outputs().any(|o| o == &active_output); let is_active_space = workspace.outputs().any(|o| o == &active_output);
elements.extend( let (w_elements, p_elements) = workspace
workspace .render_output::<R>(
.render_output::<R>( renderer,
renderer, output,
output, &state.shell.override_redirect_windows,
&state.shell.override_redirect_windows, state.xwayland_state.as_mut(),
state.xwayland_state.as_mut(), (!move_active && is_active_space).then_some(&last_active_seat),
(!move_active && is_active_space).then_some(&last_active_seat), overview,
overview, resize_indicator,
resize_indicator, state.config.static_conf.active_hint,
state.config.static_conf.active_hint, )
) .map_err(|_| OutputNoMode)?;
.map_err(|_| OutputNoMode)? elements.extend(p_elements.into_iter().map(|p_element| {
.into_iter() CosmicElement::Workspace(RelocateRenderElement::from_element(
.map(|w_element| { p_element,
CosmicElement::Workspace(RelocateRenderElement::from_element( offset.to_physical_precise_round(output_scale),
w_element, Relocate::Relative,
offset.to_physical_precise_round(output_scale), ))
Relocate::Relative, }));
)) window_elements.extend(w_elements.into_iter().map(|w_element| {
}), CosmicElement::Workspace(RelocateRenderElement::from_element(
); w_element,
offset.to_physical_precise_round(output_scale),
Relocate::Relative,
))
}));
elements.extend( let (w_elements, p_elements) =
background_layer_elements(renderer, output, exclude_workspace_overview) background_layer_elements(renderer, output, exclude_workspace_overview);
.into_iter()
.map(|w_element| { elements.extend(p_elements.into_iter().map(|p_element| {
CosmicElement::Workspace(RelocateRenderElement::from_element( CosmicElement::Workspace(RelocateRenderElement::from_element(
w_element, p_element,
offset.to_physical_precise_round(output_scale), offset.to_physical_precise_round(output_scale),
Relocate::Relative, Relocate::Relative,
)) ))
}), }));
);
window_elements.extend(w_elements.into_iter().map(|w_element| {
CosmicElement::Workspace(RelocateRenderElement::from_element(
w_element,
offset.to_physical_precise_round(output_scale),
Relocate::Relative,
))
}));
elements.extend(window_elements);
Ok(elements) Ok(elements)
} }
// bottom and background layer surfaces pub fn split_layer_elements<R>(
pub fn foreground_layer_elements<R>(
renderer: &mut R, renderer: &mut R,
output: &Output, output: &Output,
has_fullscreen: bool, layer: Layer,
exclude_workspace_overview: bool, exclude_workspace_overview: bool,
) -> Vec<WorkspaceRenderElement<R>> ) -> (
Vec<WorkspaceRenderElement<R>>,
Vec<WorkspaceRenderElement<R>>,
)
where where
R: Renderer + ImportAll + ImportMem + AsGlowRenderer, R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
<R as Renderer>::TextureId: Clone + 'static, <R as Renderer>::TextureId: Clone + 'static,
@ -636,32 +670,46 @@ where
let layer_map = layer_map_for_output(output); let layer_map = layer_map_for_output(output);
let output_scale = output.current_scale().fractional_scale(); let output_scale = output.current_scale().fractional_scale();
let mut popup_elements = Vec::new();
let mut layer_elements = Vec::new();
layer_map layer_map
.layers() .layers_on(layer)
.rev() .rev()
.filter(|s| !(exclude_workspace_overview && s.namespace() == WORKSPACE_OVERVIEW_NAMESPACE)) .filter(|s| !(exclude_workspace_overview && s.namespace() == WORKSPACE_OVERVIEW_NAMESPACE))
.filter(|s| {
if has_fullscreen {
matches!(s.layer(), Layer::Overlay)
} else {
matches!(s.layer(), Layer::Top | Layer::Overlay)
}
})
.filter_map(|surface| { .filter_map(|surface| {
layer_map layer_map
.layer_geometry(surface) .layer_geometry(surface)
.map(|geo| (geo.loc, surface)) .map(|geo| (geo.loc, surface))
}) })
.flat_map(|(loc, surface)| { .for_each(|(location, surface)| {
AsRenderElements::<R>::render_elements::<WorkspaceRenderElement<R>>( let location = location.to_physical_precise_round(output_scale);
surface, let surface = surface.wl_surface();
renderer, let scale = Scale::from(output_scale);
loc.to_physical_precise_round(output_scale),
Scale::from(output_scale), popup_elements.extend(PopupManager::popups_for_surface(surface).flat_map(
1.0, |(popup, popup_offset)| {
) let offset = (popup_offset - popup.geometry().loc)
}) .to_f64()
.collect() .to_physical(scale)
.to_i32_round();
render_elements_from_surface_tree(
renderer,
popup.wl_surface(),
location + offset,
scale,
1.0,
)
},
));
layer_elements.extend(render_elements_from_surface_tree(
renderer, surface, location, scale, 1.0,
));
});
(layer_elements, popup_elements)
} }
// bottom and background layer surfaces // bottom and background layer surfaces
@ -669,7 +717,10 @@ pub fn background_layer_elements<R>(
renderer: &mut R, renderer: &mut R,
output: &Output, output: &Output,
exclude_workspace_overview: bool, exclude_workspace_overview: bool,
) -> Vec<WorkspaceRenderElement<R>> ) -> (
Vec<WorkspaceRenderElement<R>>,
Vec<WorkspaceRenderElement<R>>,
)
where where
R: Renderer + ImportAll + ImportMem + AsGlowRenderer, R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
<R as Renderer>::TextureId: Clone + 'static, <R as Renderer>::TextureId: Clone + 'static,
@ -677,29 +728,17 @@ where
CosmicMappedRenderElement<R>: RenderElement<R>, CosmicMappedRenderElement<R>: RenderElement<R>,
WorkspaceRenderElement<R>: RenderElement<R>, WorkspaceRenderElement<R>: RenderElement<R>,
{ {
let layer_map = layer_map_for_output(output); let (mut layer_elements, mut popup_elements) =
let output_scale = output.current_scale().fractional_scale(); split_layer_elements(renderer, output, Layer::Bottom, exclude_workspace_overview);
let more = split_layer_elements(
layer_map renderer,
.layers() output,
.rev() Layer::Background,
.filter(|s| !(exclude_workspace_overview && s.namespace() == WORKSPACE_OVERVIEW_NAMESPACE)) exclude_workspace_overview,
.filter(|s| matches!(s.layer(), Layer::Background | Layer::Bottom)) );
.filter_map(|surface| { layer_elements.extend(more.0);
layer_map popup_elements.extend(more.1);
.layer_geometry(surface) (layer_elements, popup_elements)
.map(|geo| (geo.loc, surface))
})
.flat_map(|(loc, surface)| {
AsRenderElements::<R>::render_elements::<WorkspaceRenderElement<R>>(
surface,
renderer,
loc.to_physical_precise_round(output_scale),
Scale::from(output_scale),
1.0,
)
})
.collect()
} }
pub fn render_output<R, Target, OffTarget, Source>( pub fn render_output<R, Target, OffTarget, Source>(

View file

@ -14,7 +14,7 @@ use smithay::{
renderer::{ renderer::{
element::{ element::{
utils::{CropRenderElement, RelocateRenderElement, RescaleRenderElement}, utils::{CropRenderElement, RelocateRenderElement, RescaleRenderElement},
AsRenderElements, Element, RenderElement, UnderlyingStorage, Element, RenderElement, UnderlyingStorage,
}, },
gles::element::PixelShaderElement, gles::element::PixelShaderElement,
glow::GlowRenderer, glow::GlowRenderer,
@ -550,6 +550,206 @@ impl CosmicMapped {
debug.take(); debug.take();
} }
} }
pub fn split_render_elements<R, C>(
&self,
renderer: &mut R,
location: smithay::utils::Point<i32, smithay::utils::Physical>,
scale: smithay::utils::Scale<f64>,
alpha: f32,
) -> (Vec<C>, Vec<C>)
where
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
<R as Renderer>::TextureId: 'static,
CosmicMappedRenderElement<R>: RenderElement<R>,
C: From<CosmicMappedRenderElement<R>>,
{
#[cfg(feature = "debug")]
let mut debug_elements = if let Some(debug) = self.debug.lock().unwrap().as_mut() {
let window = self.active_window();
let window_geo = window.geometry();
let (min_size, max_size, size) =
(window.min_size(), window.max_size(), window.geometry().size);
let area = Rectangle::<i32, Logical>::from_loc_and_size(
location.to_f64().to_logical(scale).to_i32_round(),
self.bbox().size,
);
let glow_renderer = renderer.glow_renderer_mut();
match debug.render(
|ctx| {
egui::Area::new("window")
.anchor(
egui::Align2::RIGHT_TOP,
[
-window_geo.loc.x as f32 - 10.0,
window_geo.loc.y as f32 - 10.0,
],
)
.show(ctx, |ui| {
egui::Frame::none()
.fill(egui::Color32::BLACK)
.rounding(5.0)
.inner_margin(10.0)
.show(ui, |ui| {
ui.heading(window.title());
ui.horizontal(|ui| {
ui.label("App ID: ");
ui.label(window.app_id());
});
ui.label(match window {
CosmicSurface::Wayland(_) => "Protocol: Wayland",
CosmicSurface::X11(_) => "Protocol: X11",
_ => unreachable!(),
});
ui.horizontal(|ui| {
ui.label("States: ");
if window.is_maximized() {
ui.label("🗖");
}
if window.is_fullscreen() {
ui.label("");
}
if window.is_activated() {
ui.label("🖱");
}
if window.is_resizing().is_some() {
ui.label("");
}
});
let plot = Plot::new("Sizes")
.legend(Legend::default().position(Corner::RightBottom))
.data_aspect(1.0)
.view_aspect(1.0)
.show_x(false)
.show_y(false)
.width(200.0)
.height(200.0);
plot.show(ui, |plot_ui| {
let center = if let Some(max_size) = max_size {
((max_size.w + 20) / 2, (max_size.h + 20) / 2)
} else {
(100, 100)
};
if let Some(max_size) = max_size {
let max_size_rect =
Polygon::new(PlotPoints::new(vec![
[10.0, 10.0],
[max_size.w as f64 + 10.0, 10.0],
[
max_size.w as f64 + 10.0,
max_size.h as f64 + 10.0,
],
[10.0, max_size.h as f64 + 10.0],
[10.0, 10.0],
]));
plot_ui.polygon(
max_size_rect
.name(format!("{}x{}", max_size.w, max_size.h)),
);
}
let size_rect = Polygon::new(PlotPoints::new(vec![
[
(center.0 - size.w / 2) as f64,
(center.1 - size.h / 2) as f64,
],
[
(center.0 + size.w / 2) as f64,
(center.1 - size.h / 2) as f64,
],
[
(center.0 + size.w / 2) as f64,
(center.1 + size.h / 2) as f64,
],
[
(center.0 - size.w / 2) as f64,
(center.1 + size.h / 2) as f64,
],
[
(center.0 - size.w / 2) as f64,
(center.1 - size.h / 2) as f64,
],
]));
plot_ui.polygon(
size_rect.name(format!("{}x{}", size.w, size.h)),
);
if let Some(min_size) = min_size {
let min_size_rect =
Polygon::new(PlotPoints::new(vec![
[
(center.0 - min_size.w / 2) as f64,
(center.1 - min_size.h / 2) as f64,
],
[
(center.0 + min_size.w / 2) as f64,
(center.1 - min_size.h / 2) as f64,
],
[
(center.0 + min_size.w / 2) as f64,
(center.1 + min_size.h / 2) as f64,
],
[
(center.0 - min_size.w / 2) as f64,
(center.1 + min_size.h / 2) as f64,
],
[
(center.0 - min_size.w / 2) as f64,
(center.1 - min_size.h / 2) as f64,
],
]));
plot_ui.polygon(
min_size_rect
.name(format!("{}x{}", min_size.w, min_size.h)),
);
}
})
})
});
},
glow_renderer,
area,
scale.x,
0.8,
) {
Ok(element) => vec![element.into()],
Err(err) => {
debug!(?err, "Error rendering debug overlay.");
Vec::new()
}
}
} else {
Vec::new()
};
#[cfg(not(feature = "debug"))]
let debug_elements = Vec::new();
#[cfg_attr(not(feature = "debug"), allow(unused_mut))]
let (window_elements, popup_elements) = match &self.element {
CosmicMappedInternal::Stack(s) => s
.split_render_elements::<R, CosmicMappedRenderElement<R>>(
renderer, location, scale, alpha,
),
CosmicMappedInternal::Window(w) => w
.split_render_elements::<R, CosmicMappedRenderElement<R>>(
renderer, location, scale, alpha,
),
_ => unreachable!(),
};
(
debug_elements
.into_iter()
.map(C::from)
.chain(window_elements.into_iter().map(C::from))
.collect(),
popup_elements.into_iter().map(C::from).collect(),
)
}
} }
impl IsAlive for CosmicMapped { impl IsAlive for CosmicMapped {
@ -1026,200 +1226,3 @@ where
CosmicMappedRenderElement::Egui(elem) CosmicMappedRenderElement::Egui(elem)
} }
} }
impl<R> AsRenderElements<R> for CosmicMapped
where
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
<R as Renderer>::TextureId: 'static,
CosmicMappedRenderElement<R>: RenderElement<R>,
{
type RenderElement = CosmicMappedRenderElement<R>;
fn render_elements<C: From<Self::RenderElement>>(
&self,
renderer: &mut R,
location: Point<i32, Physical>,
scale: Scale<f64>,
alpha: f32,
) -> Vec<C> {
#[cfg(feature = "debug")]
let mut elements = if let Some(debug) = self.debug.lock().unwrap().as_mut() {
let window = self.active_window();
let window_geo = window.geometry();
let (min_size, max_size, size) =
(window.min_size(), window.max_size(), window.geometry().size);
let area = Rectangle::<i32, Logical>::from_loc_and_size(
location.to_f64().to_logical(scale).to_i32_round(),
self.bbox().size,
);
let glow_renderer = renderer.glow_renderer_mut();
match debug.render(
|ctx| {
egui::Area::new("window")
.anchor(
egui::Align2::RIGHT_TOP,
[
-window_geo.loc.x as f32 - 10.0,
window_geo.loc.y as f32 - 10.0,
],
)
.show(ctx, |ui| {
egui::Frame::none()
.fill(egui::Color32::BLACK)
.rounding(5.0)
.inner_margin(10.0)
.show(ui, |ui| {
ui.heading(window.title());
ui.horizontal(|ui| {
ui.label("App ID: ");
ui.label(window.app_id());
});
ui.label(match window {
CosmicSurface::Wayland(_) => "Protocol: Wayland",
CosmicSurface::X11(_) => "Protocol: X11",
_ => unreachable!(),
});
ui.horizontal(|ui| {
ui.label("States: ");
if window.is_maximized() {
ui.label("🗖");
}
if window.is_fullscreen() {
ui.label("");
}
if window.is_activated() {
ui.label("🖱");
}
if window.is_resizing().is_some() {
ui.label("");
}
});
let plot = Plot::new("Sizes")
.legend(Legend::default().position(Corner::RightBottom))
.data_aspect(1.0)
.view_aspect(1.0)
.show_x(false)
.show_y(false)
.width(200.0)
.height(200.0);
plot.show(ui, |plot_ui| {
let center = if let Some(max_size) = max_size {
((max_size.w + 20) / 2, (max_size.h + 20) / 2)
} else {
(100, 100)
};
if let Some(max_size) = max_size {
let max_size_rect =
Polygon::new(PlotPoints::new(vec![
[10.0, 10.0],
[max_size.w as f64 + 10.0, 10.0],
[
max_size.w as f64 + 10.0,
max_size.h as f64 + 10.0,
],
[10.0, max_size.h as f64 + 10.0],
[10.0, 10.0],
]));
plot_ui.polygon(
max_size_rect
.name(format!("{}x{}", max_size.w, max_size.h)),
);
}
let size_rect = Polygon::new(PlotPoints::new(vec![
[
(center.0 - size.w / 2) as f64,
(center.1 - size.h / 2) as f64,
],
[
(center.0 + size.w / 2) as f64,
(center.1 - size.h / 2) as f64,
],
[
(center.0 + size.w / 2) as f64,
(center.1 + size.h / 2) as f64,
],
[
(center.0 - size.w / 2) as f64,
(center.1 + size.h / 2) as f64,
],
[
(center.0 - size.w / 2) as f64,
(center.1 - size.h / 2) as f64,
],
]));
plot_ui.polygon(
size_rect.name(format!("{}x{}", size.w, size.h)),
);
if let Some(min_size) = min_size {
let min_size_rect =
Polygon::new(PlotPoints::new(vec![
[
(center.0 - min_size.w / 2) as f64,
(center.1 - min_size.h / 2) as f64,
],
[
(center.0 + min_size.w / 2) as f64,
(center.1 - min_size.h / 2) as f64,
],
[
(center.0 + min_size.w / 2) as f64,
(center.1 + min_size.h / 2) as f64,
],
[
(center.0 - min_size.w / 2) as f64,
(center.1 + min_size.h / 2) as f64,
],
[
(center.0 - min_size.w / 2) as f64,
(center.1 - min_size.h / 2) as f64,
],
]));
plot_ui.polygon(
min_size_rect
.name(format!("{}x{}", min_size.w, min_size.h)),
);
}
})
})
});
},
glow_renderer,
area,
scale.x,
0.8,
) {
Ok(element) => vec![element.into()],
Err(err) => {
debug!(?err, "Error rendering debug overlay.");
Vec::new()
}
}
} else {
Vec::new()
};
#[cfg(not(feature = "debug"))]
let mut elements = Vec::new();
#[cfg_attr(not(feature = "debug"), allow(unused_mut))]
match &self.element {
CosmicMappedInternal::Stack(s) => {
elements.extend(AsRenderElements::<R>::render_elements::<
CosmicMappedRenderElement<R>,
>(s, renderer, location, scale, alpha))
}
CosmicMappedInternal::Window(w) => {
elements.extend(AsRenderElements::<R>::render_elements::<
CosmicMappedRenderElement<R>,
>(w, renderer, location, scale, alpha))
}
_ => {}
};
elements.into_iter().map(C::from).collect()
}
}

View file

@ -36,7 +36,7 @@ use smithay::{
}, },
output::Output, output::Output,
render_elements, render_elements,
utils::{IsAlive, Logical, Physical, Point, Rectangle, Scale, Serial, Size}, utils::{IsAlive, Logical, Point, Rectangle, Serial, Size},
wayland::seat::WaylandFocus, wayland::seat::WaylandFocus,
}; };
use std::{ use std::{
@ -462,6 +462,50 @@ impl CosmicStack {
pub(super) fn loop_handle(&self) -> LoopHandle<'static, crate::state::Data> { pub(super) fn loop_handle(&self) -> LoopHandle<'static, crate::state::Data> {
self.0.loop_handle() self.0.loop_handle()
} }
pub fn split_render_elements<R, C>(
&self,
renderer: &mut R,
location: smithay::utils::Point<i32, smithay::utils::Physical>,
scale: smithay::utils::Scale<f64>,
alpha: f32,
) -> (Vec<C>, Vec<C>)
where
R: Renderer + ImportAll + ImportMem,
<R as Renderer>::TextureId: 'static,
C: From<CosmicStackRenderElement<R>>,
{
let stack_loc = location
+ self
.0
.with_program(|p| {
p.windows.lock().unwrap()[p.active.load(Ordering::SeqCst)]
.geometry()
.loc
})
.to_physical_precise_round(scale);
let window_loc = location + Point::from((0, (TAB_HEIGHT as f64 * scale.y) as i32));
let elements = AsRenderElements::<R>::render_elements::<CosmicStackRenderElement<R>>(
&self.0, renderer, stack_loc, scale, alpha,
);
let (window_elements, popup_elements) = self.0.with_program(|p| {
p.windows.lock().unwrap()[p.active.load(Ordering::SeqCst)]
.split_render_elements::<R, CosmicStackRenderElement<R>>(
renderer, window_loc, scale, alpha,
)
});
(
elements
.into_iter()
.map(C::from)
.chain(window_elements.into_iter().map(C::from))
.collect(),
popup_elements.into_iter().map(C::from).collect(),
)
}
} }
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
@ -1061,45 +1105,3 @@ render_elements! {
Header = MemoryRenderBufferRenderElement<R>, Header = MemoryRenderBufferRenderElement<R>,
Window = WaylandSurfaceRenderElement<R>, Window = WaylandSurfaceRenderElement<R>,
} }
impl<R> AsRenderElements<R> for CosmicStack
where
R: Renderer + ImportAll + ImportMem,
<R as Renderer>::TextureId: 'static,
{
type RenderElement = CosmicStackRenderElement<R>;
fn render_elements<C: From<Self::RenderElement>>(
&self,
renderer: &mut R,
location: Point<i32, Physical>,
scale: Scale<f64>,
alpha: f32,
) -> Vec<C> {
let stack_loc = location
+ self
.0
.with_program(|p| {
p.windows.lock().unwrap()[p.active.load(Ordering::SeqCst)]
.geometry()
.loc
})
.to_physical_precise_round(scale);
let window_loc = location + Point::from((0, (TAB_HEIGHT as f64 * scale.y) as i32));
let mut elements = AsRenderElements::<R>::render_elements::<CosmicStackRenderElement<R>>(
&self.0, renderer, stack_loc, scale, alpha,
);
elements.extend(self.0.with_program(|p| {
AsRenderElements::<R>::render_elements::<CosmicStackRenderElement<R>>(
&p.windows.lock().unwrap()[p.active.load(Ordering::SeqCst)],
renderer,
window_loc,
scale,
alpha,
)
}));
elements.into_iter().map(C::from).collect()
}
}

View file

@ -3,8 +3,9 @@ use std::time::Duration;
use smithay::{ use smithay::{
backend::renderer::{ backend::renderer::{
element::{ element::{
surface::WaylandSurfaceRenderElement, utils::select_dmabuf_feedback, AsRenderElements, surface::{render_elements_from_surface_tree, WaylandSurfaceRenderElement},
RenderElementStates, utils::select_dmabuf_feedback,
AsRenderElements, RenderElementStates,
}, },
ImportAll, Renderer, ImportAll, Renderer,
}, },
@ -14,7 +15,7 @@ use smithay::{
take_presentation_feedback_surface_tree, with_surfaces_surface_tree, take_presentation_feedback_surface_tree, with_surfaces_surface_tree,
OutputPresentationFeedback, OutputPresentationFeedback,
}, },
Window, PopupManager, Window,
}, },
input::{keyboard::KeyboardTarget, pointer::PointerTarget}, input::{keyboard::KeyboardTarget, pointer::PointerTarget},
output::Output, output::Output,
@ -591,6 +592,50 @@ impl CosmicSurface {
_ => unreachable!(), _ => unreachable!(),
} }
} }
pub fn split_render_elements<R, C>(
&self,
renderer: &mut R,
location: smithay::utils::Point<i32, smithay::utils::Physical>,
scale: smithay::utils::Scale<f64>,
alpha: f32,
) -> (Vec<C>, Vec<C>)
where
R: Renderer + ImportAll,
<R as Renderer>::TextureId: 'static,
C: From<WaylandSurfaceRenderElement<R>>,
{
match self {
CosmicSurface::Wayland(window) => {
let surface = window.toplevel().wl_surface();
let popup_render_elements = PopupManager::popups_for_surface(surface)
.flat_map(|(popup, popup_offset)| {
let offset = (window.geometry().loc + popup_offset - popup.geometry().loc)
.to_physical_precise_round(scale);
render_elements_from_surface_tree(
renderer,
popup.wl_surface(),
location + offset,
scale,
alpha,
)
})
.collect();
let window_render_elements =
render_elements_from_surface_tree(renderer, surface, location, scale, alpha);
(window_render_elements, popup_render_elements)
}
CosmicSurface::X11(surface) => (
surface.render_elements(renderer, location, scale, alpha),
Vec::new(),
),
_ => unreachable!(),
}
}
} }
impl KeyboardTarget<crate::state::State> for CosmicSurface { impl KeyboardTarget<crate::state::State> for CosmicSurface {
@ -761,6 +806,15 @@ impl WaylandFocus for CosmicSurface {
} }
} }
impl X11Relatable for CosmicSurface {
fn is_window(&self, window: &X11Surface) -> bool {
match self {
CosmicSurface::X11(surface) => surface == window,
_ => false,
}
}
}
impl<R> AsRenderElements<R> for CosmicSurface impl<R> AsRenderElements<R> for CosmicSurface
where where
R: Renderer + ImportAll, R: Renderer + ImportAll,
@ -786,12 +840,3 @@ where
} }
} }
} }
impl X11Relatable for CosmicSurface {
fn is_window(&self, window: &X11Surface) -> bool {
match self {
CosmicSurface::X11(surface) => surface == window,
_ => false,
}
}
}

View file

@ -29,9 +29,7 @@ use smithay::{
}, },
output::Output, output::Output,
render_elements, render_elements,
utils::{ utils::{Buffer as BufferCoords, IsAlive, Logical, Point, Rectangle, Serial, Size},
Buffer as BufferCoords, IsAlive, Logical, Physical, Point, Rectangle, Scale, Serial, Size,
},
wayland::seat::WaylandFocus, wayland::seat::WaylandFocus,
}; };
use std::{ use std::{
@ -164,6 +162,50 @@ impl CosmicWindow {
pub(super) fn loop_handle(&self) -> LoopHandle<'static, crate::state::Data> { pub(super) fn loop_handle(&self) -> LoopHandle<'static, crate::state::Data> {
self.0.loop_handle() self.0.loop_handle()
} }
pub fn split_render_elements<R, C>(
&self,
renderer: &mut R,
location: smithay::utils::Point<i32, smithay::utils::Physical>,
scale: smithay::utils::Scale<f64>,
alpha: f32,
) -> (Vec<C>, Vec<C>)
where
R: Renderer + ImportAll + ImportMem,
<R as Renderer>::TextureId: 'static,
C: From<CosmicWindowRenderElement<R>>,
{
let has_ssd = self.0.with_program(|p| p.has_ssd(false));
let window_loc = if has_ssd {
location + Point::from((0, (SSD_HEIGHT as f64 * scale.y) as i32))
} else {
location
};
let (mut window_elements, popup_elements) = self.0.with_program(|p| {
p.window
.split_render_elements::<R, CosmicWindowRenderElement<R>>(
renderer, window_loc, scale, alpha,
)
});
if has_ssd {
let ssd_loc = location
+ self
.0
.with_program(|p| p.window.geometry().loc)
.to_physical_precise_round(scale);
window_elements.extend(AsRenderElements::<R>::render_elements::<
CosmicWindowRenderElement<R>,
>(&self.0, renderer, ssd_loc, scale, alpha))
}
(
window_elements.into_iter().map(C::from).collect(),
popup_elements.into_iter().map(C::from).collect(),
)
}
} }
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
@ -555,44 +597,3 @@ render_elements! {
Header = MemoryRenderBufferRenderElement<R>, Header = MemoryRenderBufferRenderElement<R>,
Window = WaylandSurfaceRenderElement<R>, Window = WaylandSurfaceRenderElement<R>,
} }
impl<R> AsRenderElements<R> for CosmicWindow
where
R: Renderer + ImportAll + ImportMem,
<R as Renderer>::TextureId: 'static,
{
type RenderElement = CosmicWindowRenderElement<R>;
fn render_elements<C: From<Self::RenderElement>>(
&self,
renderer: &mut R,
location: Point<i32, Physical>,
scale: Scale<f64>,
alpha: f32,
) -> Vec<C> {
let has_ssd = self.0.with_program(|p| p.has_ssd(false));
let window_loc = if has_ssd {
location + Point::from((0, (SSD_HEIGHT as f64 * scale.y) as i32))
} else {
location
};
let mut elements = self.0.with_program(|p| {
AsRenderElements::<R>::render_elements::<CosmicWindowRenderElement<R>>(
&p.window, renderer, window_loc, scale, alpha,
)
});
if has_ssd {
let ssd_loc = location
+ self
.0
.with_program(|p| p.window.geometry().loc)
.to_physical_precise_round(scale);
elements.extend(AsRenderElements::<R>::render_elements::<
CosmicWindowRenderElement<R>,
>(&self.0, renderer, ssd_loc, scale, alpha))
}
elements.into_iter().map(C::from).collect()
}
}

View file

@ -11,10 +11,7 @@ use crate::{
}; };
use smithay::{ use smithay::{
backend::renderer::{ backend::renderer::{element::RenderElement, ImportAll, ImportMem, Renderer},
element::{AsRenderElements, RenderElement},
ImportAll, ImportMem, Renderer,
},
desktop::space::SpaceElement, desktop::space::SpaceElement,
input::{ input::{
pointer::{ pointer::{
@ -60,9 +57,8 @@ impl MoveGrabState {
let scale = output.current_scale().fractional_scale().into(); let scale = output.current_scale().fractional_scale().into();
let render_location = cursor_at.to_i32_round() - output.geometry().loc + self.window_offset; let render_location = cursor_at.to_i32_round() - output.geometry().loc + self.window_offset;
let mut elements: Vec<I> = Vec::new(); let focus_element = if self.indicator_thickness > 0 {
if self.indicator_thickness > 0 { Some(
elements.push(
CosmicMappedRenderElement::from(IndicatorShader::focus_element( CosmicMappedRenderElement::from(IndicatorShader::focus_element(
renderer, renderer,
self.window.clone(), self.window.clone(),
@ -71,16 +67,23 @@ impl MoveGrabState {
1.0, 1.0,
)) ))
.into(), .into(),
); )
} } else {
elements.extend(AsRenderElements::<R>::render_elements::<I>( None
&self.window, };
let (window_elements, popup_elements) = self.window.split_render_elements::<R, I>(
renderer, renderer,
(render_location - self.window.geometry().loc).to_physical_precise_round(scale), (render_location - self.window.geometry().loc).to_physical_precise_round(scale),
scale, scale,
1.0, 1.0,
)); );
elements
popup_elements
.into_iter()
.chain(focus_element)
.chain(window_elements)
.collect()
} }
pub fn send_frames( pub fn send_frames(

View file

@ -438,7 +438,10 @@ impl FloatingLayout {
mut resize_indicator: Option<(ResizeMode, ResizeIndicator)>, mut resize_indicator: Option<(ResizeMode, ResizeIndicator)>,
indicator_thickness: u8, indicator_thickness: u8,
alpha: f32, alpha: f32,
) -> Vec<CosmicMappedRenderElement<R>> ) -> (
Vec<CosmicMappedRenderElement<R>>,
Vec<CosmicMappedRenderElement<R>>,
)
where where
R: Renderer + ImportAll + ImportMem + AsGlowRenderer, R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
<R as Renderer>::TextureId: 'static, <R as Renderer>::TextureId: 'static,
@ -452,25 +455,49 @@ impl FloatingLayout {
let output_scale = output.current_scale().fractional_scale(); let output_scale = output.current_scale().fractional_scale();
let output_geo = self.space.output_geometry(output).unwrap(); let output_geo = self.space.output_geometry(output).unwrap();
let mut window_elements = Vec::new();
let mut popup_elements = Vec::new();
self.space self.space
.elements_for_output(output) .elements_for_output(output)
.rev() .rev()
.flat_map(|elem| { .for_each(|elem| {
let render_location = self.space.element_location(elem).unwrap() let render_location = self.space.element_location(elem).unwrap()
- output_geo.loc - output_geo.loc
- elem.geometry().loc; - elem.geometry().loc;
let mut elements = elem.render_elements( let (w_elements, p_elements) = elem.split_render_elements(
renderer, renderer,
render_location.to_physical_precise_round(output_scale), render_location.to_physical_precise_round(output_scale),
output_scale.into(), output_scale.into(),
alpha, alpha,
); );
if focused == Some(elem) { if focused == Some(elem) {
let mut indicator_geometry = Rectangle::from_loc_and_size( let mut indicator_geometry = Rectangle::from_loc_and_size(
self.space.element_location(elem).unwrap() - output_geo.loc, self.space.element_location(elem).unwrap() - output_geo.loc,
elem.geometry().size, elem.geometry().size,
); );
if let Some((mode, resize)) = resize_indicator.as_mut() {
indicator_geometry.loc -= (18, 18).into();
indicator_geometry.size += (36, 36).into();
resize.resize(indicator_geometry.size);
resize.output_enter(output, output_geo);
window_elements.extend(
resize
.render_elements::<CosmicWindowRenderElement<R>>(
renderer,
indicator_geometry
.loc
.to_physical_precise_round(output_scale),
output_scale.into(),
alpha * mode.alpha().unwrap_or(1.0),
)
.into_iter()
.map(CosmicMappedRenderElement::Window),
);
}
if indicator_thickness > 0 { if indicator_thickness > 0 {
let element = IndicatorShader::focus_element( let element = IndicatorShader::focus_element(
renderer, renderer,
@ -479,31 +506,14 @@ impl FloatingLayout {
indicator_thickness, indicator_thickness,
alpha, alpha,
); );
elements.insert(0, element.into()); window_elements.push(element.into());
}
if let Some((mode, resize)) = resize_indicator.as_mut() {
indicator_geometry.loc -= (18, 18).into();
indicator_geometry.size += (36, 36).into();
resize.resize(indicator_geometry.size);
resize.output_enter(output, output_geo);
elements = resize
.render_elements::<CosmicWindowRenderElement<R>>(
renderer,
indicator_geometry
.loc
.to_physical_precise_round(output_scale),
output_scale.into(),
alpha * mode.alpha().unwrap_or(1.0),
)
.into_iter()
.map(CosmicMappedRenderElement::Window)
.chain(elements.into_iter())
.collect();
} }
} }
elements
}) window_elements.extend(w_elements);
.collect() popup_elements.extend(p_elements);
});
(window_elements, popup_elements)
} }
} }

View file

@ -1974,7 +1974,13 @@ impl TilingLayout {
overview: OverviewMode, overview: OverviewMode,
resize_indicator: Option<(ResizeMode, ResizeIndicator)>, resize_indicator: Option<(ResizeMode, ResizeIndicator)>,
indicator_thickness: u8, indicator_thickness: u8,
) -> Result<Vec<CosmicMappedRenderElement<R>>, OutputNotMapped> ) -> Result<
(
Vec<CosmicMappedRenderElement<R>>,
Vec<CosmicMappedRenderElement<R>>,
),
OutputNotMapped,
>
where where
R: Renderer + ImportAll + ImportMem + AsGlowRenderer, R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
<R as Renderer>::TextureId: 'static, <R as Renderer>::TextureId: 'static,
@ -2014,7 +2020,8 @@ impl TilingLayout {
}; };
let draw_groups = overview.alpha(); let draw_groups = overview.alpha();
let mut elements = Vec::new(); let mut window_elements = Vec::new();
let mut popup_elements = Vec::new();
// all gone windows and fade them out // all gone windows and fade them out
let old_geometries = if let Some(reference_tree) = reference_tree.as_ref() { let old_geometries = if let Some(reference_tree) = reference_tree.as_ref() {
@ -2034,14 +2041,16 @@ impl TilingLayout {
.unzip(); .unzip();
// all old windows we want to fade out // all old windows we want to fade out
elements.extend(render_old_tree( let (w_elements, p_elements) = render_old_tree(
reference_tree, reference_tree,
target_tree, target_tree,
renderer, renderer,
geometries.clone(), geometries.clone(),
output_scale, output_scale,
percentage, percentage,
)); );
window_elements.extend(w_elements);
popup_elements.extend(p_elements);
geometries geometries
} else { } else {
@ -2063,7 +2072,7 @@ impl TilingLayout {
.unzip(); .unzip();
// all alive windows // all alive windows
elements.extend(render_new_tree( let (w_elements, p_elements) = render_new_tree(
target_tree, target_tree,
reference_tree, reference_tree,
renderer, renderer,
@ -2083,14 +2092,16 @@ impl TilingLayout {
indicator_thickness indicator_thickness
}, },
resize_indicator, resize_indicator,
)); );
window_elements.extend(w_elements);
popup_elements.extend(p_elements);
// tiling hints // tiling hints
if let Some(group_elements) = group_elements { if let Some(group_elements) = group_elements {
elements.extend(group_elements); window_elements.extend(group_elements);
} }
Ok(elements) Ok((window_elements, popup_elements))
} }
} }
@ -2340,7 +2351,10 @@ fn render_old_tree<R>(
geometries: Option<HashMap<NodeId, Rectangle<i32, Logical>>>, geometries: Option<HashMap<NodeId, Rectangle<i32, Logical>>>,
output_scale: f64, output_scale: f64,
percentage: f32, percentage: f32,
) -> Vec<CosmicMappedRenderElement<R>> ) -> (
Vec<CosmicMappedRenderElement<R>>,
Vec<CosmicMappedRenderElement<R>>,
)
where where
R: Renderer + ImportAll + ImportMem + AsGlowRenderer, R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
<R as Renderer>::TextureId: 'static, <R as Renderer>::TextureId: 'static,
@ -2348,6 +2362,9 @@ where
CosmicWindowRenderElement<R>: RenderElement<R>, CosmicWindowRenderElement<R>: RenderElement<R>,
CosmicStackRenderElement<R>: RenderElement<R>, CosmicStackRenderElement<R>: RenderElement<R>,
{ {
let mut window_elements = Vec::new();
let mut popup_elements = Vec::new();
if let Some(root) = reference_tree.root_node_id() { if let Some(root) = reference_tree.root_node_id() {
let geometries = geometries.unwrap_or_default(); let geometries = geometries.unwrap_or_default();
reference_tree reference_tree
@ -2374,7 +2391,7 @@ where
true true
} }
}) })
.flat_map(|(mapped, original_geo, scaled_geo)| { .for_each(|(mapped, original_geo, scaled_geo)| {
let (scale, offset) = scaled_geo let (scale, offset) = scaled_geo
.map(|adapted_geo| scale_to_center(&original_geo, adapted_geo)) .map(|adapted_geo| scale_to_center(&original_geo, adapted_geo))
.unwrap_or_else(|| (1.0.into(), (0, 0).into())); .unwrap_or_else(|| (1.0.into(), (0, 0).into()));
@ -2396,15 +2413,16 @@ where
.geometry() .geometry()
.loc .loc
.to_physical_precise_round(output_scale); .to_physical_precise_round(output_scale);
AsRenderElements::<R>::render_elements::<CosmicMappedRenderElement<R>>(
mapped, let (w_elements, p_elements) = mapped
renderer, .split_render_elements::<R, CosmicMappedRenderElement<R>>(
original_location, renderer,
Scale::from(output_scale), original_location,
1.0 - percentage, Scale::from(output_scale),
) 1.0 - percentage,
.into_iter() );
.flat_map(|element| match element {
window_elements.extend(w_elements.into_iter().flat_map(|element| match element {
CosmicMappedRenderElement::Stack(elem) => { CosmicMappedRenderElement::Stack(elem) => {
Some(CosmicMappedRenderElement::TiledStack({ Some(CosmicMappedRenderElement::TiledStack({
let cropped = CropRenderElement::from_element( let cropped = CropRenderElement::from_element(
@ -2448,13 +2466,12 @@ where
})) }))
} }
x => Some(x), x => Some(x),
}) }));
.collect::<Vec<_>>() popup_elements.extend(p_elements);
}) });
.collect()
} else {
Vec::new()
} }
(window_elements, popup_elements)
} }
fn render_new_tree<R>( fn render_new_tree<R>(
@ -2468,7 +2485,10 @@ fn render_new_tree<R>(
percentage: f32, percentage: f32,
indicator_thickness: u8, indicator_thickness: u8,
mut resize_indicator: Option<(ResizeMode, ResizeIndicator)>, mut resize_indicator: Option<(ResizeMode, ResizeIndicator)>,
) -> Vec<CosmicMappedRenderElement<R>> ) -> (
Vec<CosmicMappedRenderElement<R>>,
Vec<CosmicMappedRenderElement<R>>,
)
where where
R: Renderer + ImportAll + ImportMem + AsGlowRenderer, R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
<R as Renderer>::TextureId: 'static, <R as Renderer>::TextureId: 'static,
@ -2491,6 +2511,9 @@ where
}) })
.map(|(id, _)| id); .map(|(id, _)| id);
let mut window_elements = Vec::new();
let mut popup_elements = Vec::new();
let mut group_backdrop = None; let mut group_backdrop = None;
let mut indicator = None; let mut indicator = None;
let mut resize_elements = None; let mut resize_elements = None;
@ -2501,10 +2524,10 @@ where
if let Some(root) = target_tree.root_node_id() { if let Some(root) = target_tree.root_node_id() {
let old_geometries = old_geometries.unwrap_or_default(); let old_geometries = old_geometries.unwrap_or_default();
let geometries = geometries.unwrap_or_default(); let geometries = geometries.unwrap_or_default();
let elements: Vec<CosmicMappedRenderElement<R>> = target_tree target_tree
.traverse_pre_order_ids(root) .traverse_pre_order_ids(root)
.unwrap() .unwrap()
.flat_map(|node_id| { .for_each(|node_id| {
let data = target_tree.get(&node_id).unwrap().data(); let data = target_tree.get(&node_id).unwrap().data();
let (original_geo, scaled_geo) = (data.geometry(), geometries.get(&node_id)); let (original_geo, scaled_geo) = (data.geometry(), geometries.get(&node_id));
@ -2589,8 +2612,6 @@ where
(new_geo, percentage) (new_geo, percentage)
}; };
let mut elements = Vec::new();
if focused.as_ref() == Some(&node_id) { if focused.as_ref() == Some(&node_id) {
if indicator_thickness > 0 || data.is_group() { if indicator_thickness > 0 || data.is_group() {
let mut geo = geo.clone(); let mut geo = geo.clone();
@ -2668,16 +2689,16 @@ where
let original_location = (original_geo.loc - mapped.geometry().loc) let original_location = (original_geo.loc - mapped.geometry().loc)
.to_physical_precise_round(output_scale); .to_physical_precise_round(output_scale);
elements.extend( let (w_elements, p_elements) = mapped
AsRenderElements::<R>::render_elements::<CosmicMappedRenderElement<R>>( .split_render_elements::<R, CosmicMappedRenderElement<R>>(
mapped,
renderer, renderer,
original_location, original_location,
Scale::from(output_scale), Scale::from(output_scale),
alpha, alpha,
) );
.into_iter()
.flat_map(|element| match element { window_elements.extend(w_elements.into_iter().flat_map(
|element| match element {
CosmicMappedRenderElement::Stack(elem) => { CosmicMappedRenderElement::Stack(elem) => {
Some(CosmicMappedRenderElement::TiledStack({ Some(CosmicMappedRenderElement::TiledStack({
let cropped = CropRenderElement::from_element( let cropped = CropRenderElement::from_element(
@ -2721,24 +2742,22 @@ where
})) }))
} }
x => Some(x), x => Some(x),
}), },
); ));
popup_elements.extend(p_elements)
} }
});
elements window_elements = resize_elements
})
.collect();
resize_elements
.into_iter() .into_iter()
.flatten() .flatten()
.chain(indicator.into_iter().map(Into::into)) .chain(indicator.into_iter().map(Into::into))
.chain(elements) .chain(window_elements)
.chain(group_backdrop.into_iter().map(Into::into)) .chain(group_backdrop.into_iter().map(Into::into))
.collect() .collect();
} else {
Vec::new()
} }
(window_elements, popup_elements)
} }
fn scale_to_center( fn scale_to_center(

View file

@ -493,7 +493,13 @@ impl Workspace {
overview: OverviewMode, overview: OverviewMode,
resize_indicator: Option<(ResizeMode, ResizeIndicator)>, resize_indicator: Option<(ResizeMode, ResizeIndicator)>,
indicator_thickness: u8, indicator_thickness: u8,
) -> Result<Vec<WorkspaceRenderElement<R>>, OutputNotMapped> ) -> Result<
(
Vec<WorkspaceRenderElement<R>>,
Vec<WorkspaceRenderElement<R>>,
),
OutputNotMapped,
>
where where
R: Renderer + ImportAll + ImportMem + AsGlowRenderer, R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
<R as Renderer>::TextureId: 'static, <R as Renderer>::TextureId: 'static,
@ -505,14 +511,15 @@ impl Workspace {
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
puffin::profile_function!(); puffin::profile_function!();
let mut render_elements = Vec::new(); let mut window_elements = Vec::new();
let mut popup_elements = Vec::new();
let output_scale = output.current_scale().fractional_scale(); let output_scale = output.current_scale().fractional_scale();
let layer_map = layer_map_for_output(output); let layer_map = layer_map_for_output(output);
let zone = layer_map.non_exclusive_zone(); let zone = layer_map.non_exclusive_zone();
if let Some(fullscreen) = self.fullscreen.get(output) { if let Some(fullscreen) = self.fullscreen.get(output) {
render_elements.extend( popup_elements.extend(
override_redirect_windows override_redirect_windows
.iter() .iter()
.filter(|or| or.geometry().intersection(output.geometry()).is_some()) .filter(|or| or.geometry().intersection(output.geometry()).is_some())
@ -529,7 +536,7 @@ impl Workspace {
); );
// fullscreen window // fullscreen window
render_elements.extend(AsRenderElements::<R>::render_elements::< window_elements.extend(AsRenderElements::<R>::render_elements::<
WorkspaceRenderElement<R>, WorkspaceRenderElement<R>,
>( >(
fullscreen, fullscreen,
@ -540,9 +547,13 @@ impl Workspace {
)); ));
if let Some(xwm) = xwm_state.and_then(|state| state.xwm.as_mut()) { if let Some(xwm) = xwm_state.and_then(|state| state.xwm.as_mut()) {
if let Err(err) = if let Err(err) = xwm.update_stacking_order_upwards(
xwm.update_stacking_order_upwards(render_elements.iter().rev().map(|e| e.id())) popup_elements
{ .iter()
.rev()
.map(|e| e.id())
.chain(window_elements.iter().rev().map(|e| e.id())),
) {
warn!( warn!(
wm_id = ?xwm.id(), wm_id = ?xwm.id(),
?err, ?err,
@ -556,7 +567,7 @@ impl Workspace {
// - resizing in tiling // - resizing in tiling
// OR windows above all // OR windows above all
render_elements.extend( popup_elements.extend(
override_redirect_windows override_redirect_windows
.iter() .iter()
.filter(|or| or.geometry().intersection(output.geometry()).is_some()) .filter(|or| or.geometry().intersection(output.geometry()).is_some())
@ -592,40 +603,39 @@ impl Workspace {
} }
OverviewMode::None => 1.0, OverviewMode::None => 1.0,
}; };
render_elements.extend(
self.floating_layer let (w_elements, p_elements) = self.floating_layer.render_output::<R>(
.render_output::<R>( renderer,
renderer, output,
output, focused.as_ref(),
focused.as_ref(), resize_indicator.clone(),
resize_indicator.clone(), indicator_thickness,
indicator_thickness, alpha,
alpha,
)
.into_iter()
.map(WorkspaceRenderElement::from),
); );
popup_elements.extend(p_elements.into_iter().map(WorkspaceRenderElement::from));
window_elements.extend(w_elements.into_iter().map(WorkspaceRenderElement::from));
//tiling surfaces //tiling surfaces
render_elements.extend( let (w_elements, p_elements) = self.tiling_layer.render_output::<R>(
self.tiling_layer renderer,
.render_output::<R>( output,
renderer, draw_focus_indicator,
output, layer_map.non_exclusive_zone(),
draw_focus_indicator, overview.clone(),
layer_map.non_exclusive_zone(), resize_indicator,
overview.clone(), indicator_thickness,
resize_indicator, )?;
indicator_thickness, popup_elements.extend(p_elements.into_iter().map(WorkspaceRenderElement::from));
)? window_elements.extend(w_elements.into_iter().map(WorkspaceRenderElement::from));
.into_iter()
.map(WorkspaceRenderElement::from),
);
if let Some(xwm) = xwm_state.and_then(|state| state.xwm.as_mut()) { if let Some(xwm) = xwm_state.and_then(|state| state.xwm.as_mut()) {
if let Err(err) = if let Err(err) = xwm.update_stacking_order_upwards(
xwm.update_stacking_order_upwards(render_elements.iter().rev().map(|e| e.id())) popup_elements
{ .iter()
.rev()
.map(|e| e.id())
.chain(window_elements.iter().rev().map(|e| e.id())),
) {
warn!( warn!(
wm_id = ?xwm.id(), wm_id = ?xwm.id(),
?err, ?err,
@ -647,7 +657,7 @@ impl Workspace {
}; };
if let Some(alpha) = alpha { if let Some(alpha) = alpha {
render_elements.push( window_elements.push(
Into::<CosmicMappedRenderElement<R>>::into(BackdropShader::element( Into::<CosmicMappedRenderElement<R>>::into(BackdropShader::element(
renderer, renderer,
self.backdrop_id.clone(), self.backdrop_id.clone(),
@ -661,7 +671,7 @@ impl Workspace {
} }
} }
Ok(render_elements) Ok((window_elements, popup_elements))
} }
} }