From c3ecbeee3b062e1dbf4240de204513bf4ee6f881 Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Wed, 20 Dec 2023 21:15:53 +0000 Subject: [PATCH] render: Fix OR window and sticky X11 windows stacking order --- src/backend/render/mod.rs | 58 +++++++++++++++++++++++++++++++++++---- src/shell/workspace.rs | 43 ++--------------------------- 2 files changed, 55 insertions(+), 46 deletions(-) diff --git a/src/backend/render/mod.rs b/src/backend/render/mod.rs index ee5838df..0cc0aeda 100644 --- a/src/backend/render/mod.rs +++ b/src/backend/render/mod.rs @@ -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::::render_elements::>( + 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::( 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::( 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) diff --git a/src/shell/workspace.rs b/src/shell/workspace.rs index 98296514..098c51c9 100644 --- a/src/shell/workspace.rs +++ b/src/shell/workspace.rs @@ -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>, overview: (OverviewMode, Option<(SwapIndicator, Option<&Tree>)>), 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::::render_elements::>( - 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)) } }