diff --git a/src/shell/element/mod.rs b/src/shell/element/mod.rs index 02aaf2c4..64e33588 100644 --- a/src/shell/element/mod.rs +++ b/src/shell/element/mod.rs @@ -505,6 +505,8 @@ impl CosmicMapped { outputs: impl Iterator)>, ) { let handle = self.loop_handle(); + surface.try_force_undecorated(false); + surface.set_tiled(false); let window = CosmicWindow::new(surface, handle); if let Some(geo) = self.last_geometry.lock().unwrap().clone() { diff --git a/src/shell/element/surface.rs b/src/shell/element/surface.rs index d9d1df60..ec29685c 100644 --- a/src/shell/element/surface.rs +++ b/src/shell/element/surface.rs @@ -1,4 +1,4 @@ -use std::{cell::RefCell, time::Duration}; +use std::time::Duration; use smithay::{ backend::renderer::{ @@ -38,7 +38,7 @@ use smithay::{ xwayland::{xwm::X11Relatable, X11Surface}, }; -use crate::state::SurfaceDmabufFeedback; +use crate::{state::SurfaceDmabufFeedback, wayland::handlers::decoration::PreferredDecorationMode}; space_elements! { #[derive(Debug, Clone, PartialEq)] @@ -195,22 +195,14 @@ impl CosmicSurface { if enable { let previous_decoration_state = window.toplevel().current_state().decoration_mode.clone(); - window - .user_data() - .insert_if_missing(|| RefCell::new(Option::::None)); - *window - .user_data() - .get::>>() - .unwrap() - .borrow_mut() = previous_decoration_state; + if PreferredDecorationMode::is_unset(window) { + PreferredDecorationMode::update(window, previous_decoration_state); + } window.toplevel().with_pending_state(|pending| { pending.decoration_mode = Some(DecorationMode::ServerSide); }); } else { - let previous_mode = window - .user_data() - .get::>>() - .and_then(|m| m.borrow().clone()); + let previous_mode = PreferredDecorationMode::mode(window); window.toplevel().with_pending_state(|pending| { pending.decoration_mode = previous_mode; }); diff --git a/src/shell/layout/tiling/mod.rs b/src/shell/layout/tiling/mod.rs index 1c07ba03..608c0e02 100644 --- a/src/shell/layout/tiling/mod.rs +++ b/src/shell/layout/tiling/mod.rs @@ -1217,6 +1217,8 @@ impl TilingLayout { // map the rest for other in surfaces { + other.try_force_undecorated(false); + other.set_tiled(false); let window = CosmicMapped::from(CosmicWindow::new(other, handle.clone())); window.output_enter(&output, window.bbox()); diff --git a/src/wayland/handlers/decoration.rs b/src/wayland/handlers/decoration.rs index d637dfa2..151e0890 100644 --- a/src/wayland/handlers/decoration.rs +++ b/src/wayland/handlers/decoration.rs @@ -1,5 +1,8 @@ +use std::cell::RefCell; + use smithay::{ delegate_kde_decoration, delegate_xdg_decoration, + desktop::Window, reexports::{ wayland_protocols::xdg::decoration::zv1::server::zxdg_toplevel_decoration_v1::Mode as XdgMode, wayland_protocols_misc::server_decoration::server::org_kde_kwin_server_decoration::{ @@ -22,6 +25,38 @@ use crate::{ state::State, }; +pub struct PreferredDecorationMode(RefCell>); + +impl PreferredDecorationMode { + pub fn is_unset(window: &Window) -> bool { + window + .user_data() + .get::() + .is_none() + } + + pub fn mode(window: &Window) -> Option { + let user_data = window.user_data(); + user_data.insert_if_missing(|| PreferredDecorationMode(RefCell::new(None))); + user_data + .get::() + .unwrap() + .0 + .borrow() + .clone() + } + + pub fn update(window: &Window, update: Option) { + let user_data = window.user_data(); + user_data.insert_if_missing(|| PreferredDecorationMode(RefCell::new(None))); + *user_data + .get::() + .unwrap() + .0 + .borrow_mut() = update; + } +} + impl State { pub fn new_decoration(mapped: &CosmicMapped, surface: &WlSurface) -> KdeMode { if mapped.is_stack() { @@ -54,6 +89,7 @@ impl State { .windows() .find(|(window, _)| window.wl_surface().as_ref() == Some(surface)) { + PreferredDecorationMode::update(&window, Some(mode)); window.toplevel().with_pending_state(|state| { state.decoration_mode = Some(mode); }); @@ -66,6 +102,7 @@ impl State { .windows() .find(|(window, _)| window.wl_surface().as_ref() == Some(surface)) { + PreferredDecorationMode::update(&window, None); window.toplevel().with_pending_state(|state| { state.decoration_mode = None; });