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

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

View file

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

View file

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