From 059abb06fc7c1e072a986648e3df9ca9925a4355 Mon Sep 17 00:00:00 2001 From: Kirill Chibisov Date: Sun, 25 Jun 2023 14:12:12 +0400 Subject: [PATCH] On Wayland, handle `none` decorations During the migration some logic wrt `none` decorations was lost along the way, however we also now try to ask for client side decorations if the user wants to disable server side decorations. Fixes #2902. --- src/platform_impl/linux/wayland/window/mod.rs | 20 +++++++++---- .../linux/wayland/window/state.rs | 30 +++++++++++++++++-- 2 files changed, 43 insertions(+), 7 deletions(-) diff --git a/src/platform_impl/linux/wayland/window/mod.rs b/src/platform_impl/linux/wayland/window/mod.rs index f6eb476c5c..74f6370d1e 100644 --- a/src/platform_impl/linux/wayland/window/mod.rs +++ b/src/platform_impl/linux/wayland/window/mod.rs @@ -105,11 +105,18 @@ impl Window { .map(|size| size.to_logical::(1.)) .unwrap_or((800, 600).into()); - let window = state.xdg_shell.create_window( - surface.clone(), - WindowDecorations::ServerDefault, - &queue_handle, - ); + // We prefer server side decorations, however to not have decorations we ask for client + // side decorations instead. + let default_decorations = if attributes.decorations { + WindowDecorations::RequestServer + } else { + WindowDecorations::RequestClient + }; + + let window = + state + .xdg_shell + .create_window(surface.clone(), default_decorations, &queue_handle); let mut window_state = WindowState::new( event_loop_window_target.connection.clone(), @@ -123,6 +130,9 @@ impl Window { // Set transparency hint. window_state.set_transparent(attributes.transparent); + // Set the decorations hint. + window_state.set_decorate(attributes.decorations); + // Set the app_id. if let Some(name) = platform_attributes.name.map(|name| name.general) { window.set_app_id(name); diff --git a/src/platform_impl/linux/wayland/window/state.rs b/src/platform_impl/linux/wayland/window/state.rs index 5f1ee11259..e67e16528f 100644 --- a/src/platform_impl/linux/wayland/window/state.rs +++ b/src/platform_impl/linux/wayland/window/state.rs @@ -113,6 +113,9 @@ pub struct WindowState { /// Whether the CSD fail to create, so we don't try to create them on each iteration. csd_fails: bool, + /// Whether we should decorate the frame. + decorate: bool, + /// Min size. min_inner_size: LogicalSize, max_inner_size: Option>, @@ -180,8 +183,8 @@ impl WindowState { ) { Ok(mut frame) => { frame.set_title(&self.title); - // Ensure that the frame is not hidden. - frame.set_hidden(false); + // Hide the frame if we were asked to not decorate. + frame.set_hidden(!self.decorate); self.frame = Some(frame); } Err(err) => { @@ -391,6 +394,7 @@ impl WindowState { connection, theme, csd_fails: false, + decorate: true, cursor_grab_mode: GrabState::new(), cursor_icon: CursorIcon::Default, cursor_visible: true, @@ -706,6 +710,28 @@ impl WindowState { /// Whether show or hide client side decorations. #[inline] pub fn set_decorate(&mut self, decorate: bool) { + if decorate == self.decorate { + return; + } + + self.decorate = decorate; + + match self + .last_configure + .as_ref() + .map(|configure| configure.decoration_mode) + { + Some(DecorationMode::Server) if !self.decorate => { + // To disable decorations we should request client and hide the frame. + self.window + .request_decoration_mode(Some(DecorationMode::Client)) + } + _ if self.decorate => self + .window + .request_decoration_mode(Some(DecorationMode::Server)), + _ => (), + } + if let Some(frame) = self.frame.as_mut() { frame.set_hidden(!decorate); // Force the resize.