render: Fix OR window and sticky X11 windows stacking order

This commit is contained in:
Victoria Brekenfeld 2023-12-20 21:15:53 +00:00 committed by Victoria Brekenfeld
parent f928f80f09
commit c3ecbeee3b
2 changed files with 55 additions and 46 deletions

View file

@ -47,7 +47,7 @@ use smithay::{
element::{
surface::{render_elements_from_surface_tree, WaylandSurfaceRenderElement},
utils::{Relocate, RelocateRenderElement},
Element, Id, Kind, RenderElement,
AsRenderElements, Element, Id, Kind, RenderElement,
},
gles::{
element::PixelShaderElement, GlesError, GlesPixelProgram, GlesRenderer, Uniform,
@ -580,6 +580,40 @@ where
let active_hint = theme.active_hint as u8;
// overlay redirect windows
// they need to be over sticky windows, because they could be popups of sticky windows,
// and we can't differenciate that.
elements.extend(
state
.shell
.override_redirect_windows
.iter()
.filter(|or| {
(*or)
.geometry()
.as_global()
.intersection(workspace.output.geometry())
.is_some()
})
.flat_map(|or| {
AsRenderElements::<R>::render_elements::<WorkspaceRenderElement<R>>(
or,
renderer,
(or.geometry().loc - workspace.output.geometry().loc.as_logical())
.to_physical_precise_round(output_scale),
Scale::from(output_scale),
1.0,
)
})
.map(|p_element| {
CosmicElement::Workspace(RelocateRenderElement::from_element(
p_element,
(0, 0),
Relocate::Relative,
))
}),
);
// sticky windows
if !has_fullscreen {
let alpha = match &overview.0 {
@ -663,8 +697,6 @@ where
let (w_elements, p_elements) = workspace
.render::<R>(
renderer,
&state.shell.override_redirect_windows,
state.shell.xwayland_state.as_mut(),
(!move_active && is_active_space).then_some(&last_active_seat),
overview.clone(),
resize_indicator.clone(),
@ -719,8 +751,6 @@ where
let (w_elements, p_elements) = workspace
.render::<R>(
renderer,
&state.shell.override_redirect_windows,
state.shell.xwayland_state.as_mut(),
(!move_active && is_active_space).then_some(&last_active_seat),
overview,
resize_indicator,
@ -764,6 +794,24 @@ where
}));
}
if let Some(xwm) = state
.shell
.xwayland_state
.as_mut()
.and_then(|state| state.xwm.as_mut())
{
// we don't include the popup elements, which contain the OR windows, because we are not supposed to restack them
if let Err(err) =
xwm.update_stacking_order_upwards(window_elements.iter().rev().map(|e| e.id()))
{
warn!(
wm_id = ?xwm.id(),
?err,
"Failed to update Xwm stacking order.",
);
}
}
elements.extend(window_elements);
Ok(elements)

View file

@ -17,7 +17,6 @@ use crate::{
workspace::WorkspaceHandle,
},
},
xwayland::XWaylandState,
};
use cosmic::theme::CosmicTheme;
@ -28,7 +27,7 @@ use smithay::{
backend::renderer::{
element::{
surface::WaylandSurfaceRenderElement, texture::TextureRenderElement,
utils::RescaleRenderElement, AsRenderElements, Element, Id, RenderElement,
utils::RescaleRenderElement, Element, Id, RenderElement,
},
gles::{GlesError, GlesTexture},
glow::{GlowFrame, GlowRenderer},
@ -47,7 +46,7 @@ use smithay::{
seat::WaylandFocus,
xdg_activation::{XdgActivationState, XdgActivationToken},
},
xwayland::{X11Surface, X11Wm},
xwayland::X11Wm,
};
use std::{
collections::{HashMap, HashSet, VecDeque},
@ -57,7 +56,6 @@ use std::{
},
time::{Duration, Instant},
};
use tracing::warn;
use wayland_backend::server::ClientId;
use super::{
@ -794,8 +792,6 @@ impl Workspace {
pub fn render<'a, R>(
&self,
renderer: &mut R,
override_redirect_windows: &[X11Surface],
xwm_state: Option<&'a mut XWaylandState>,
draw_focus_indicator: Option<&Seat<State>>,
overview: (OverviewMode, Option<(SwapIndicator, Option<&Tree<Data>>)>),
resize_indicator: Option<(ResizeMode, ResizeIndicator)>,
@ -828,29 +824,6 @@ impl Workspace {
layer_map.non_exclusive_zone().as_local()
};
// OR windows above all
popup_elements.extend(
override_redirect_windows
.iter()
.filter(|or| {
(*or)
.geometry()
.as_global()
.intersection(self.output.geometry())
.is_some()
})
.flat_map(|or| {
AsRenderElements::<R>::render_elements::<WorkspaceRenderElement<R>>(
or,
renderer,
(or.geometry().loc - self.output.geometry().loc.as_logical())
.to_physical_precise_round(output_scale),
Scale::from(output_scale),
1.0,
)
}),
);
if let Some(fullscreen) = self.fullscreen.as_ref() {
// fullscreen window
let bbox = fullscreen.surface.bbox().as_local();
@ -1022,18 +995,6 @@ impl Workspace {
}
}
if let Some(xwm) = xwm_state.and_then(|state| state.xwm.as_mut()) {
if let Err(err) =
xwm.update_stacking_order_upwards(window_elements.iter().rev().map(|e| e.id()))
{
warn!(
wm_id = ?xwm.id(),
?err,
"Failed to update Xwm stacking order.",
);
}
}
Ok((window_elements, popup_elements))
}
}