diff --git a/winit-wayland/src/lib.rs b/winit-wayland/src/lib.rs index d13b3064..b34dedad 100644 --- a/winit-wayland/src/lib.rs +++ b/winit-wayland/src/lib.rs @@ -98,6 +98,7 @@ pub(crate) struct ApplicationName { pub struct WindowAttributesWayland { pub(crate) name: Option, pub(crate) activation_token: Option, + pub(crate) prefer_csd: bool, } impl WindowAttributesWayland { @@ -119,6 +120,18 @@ impl WindowAttributesWayland { self.activation_token = Some(token); self } + + /// Builds the window with a given preference for client-side decorations. + /// + /// When set to `true`, the window will tell the compositor that it prefers + /// client-side decorations, even if server-side decorations are available. + /// When set to `false` (the default), the window will indicate a preference + /// for server-side decorations. + #[inline] + pub fn with_prefer_csd(mut self, prefer_csd: bool) -> Self { + self.prefer_csd = prefer_csd; + self + } } impl PlatformWindowAttributes for WindowAttributesWayland { diff --git a/winit-wayland/src/window/mod.rs b/winit-wayland/src/window/mod.rs index b3bdaa71..37021bb0 100644 --- a/winit-wayland/src/window/mod.rs +++ b/winit-wayland/src/window/mod.rs @@ -106,6 +106,12 @@ impl Window { let window = state.xdg_shell.create_window(surface.clone(), default_decorations, &queue_handle); + let WindowAttributesWayland { name: app_name, activation_token, prefer_csd } = *attributes + .platform + .take() + .and_then(|p| p.cast::().ok()) + .unwrap_or_default(); + let mut window_state = WindowState::new( event_loop_window_target.handle.clone(), &event_loop_window_target.queue_handle, @@ -113,6 +119,7 @@ impl Window { size, window.clone(), attributes.preferred_theme, + prefer_csd, ); window_state.set_window_icon(attributes.window_icon); @@ -125,13 +132,6 @@ impl Window { // Set the decorations hint. window_state.set_decorate(attributes.decorations); - let (app_name, activation_token) = - match attributes.platform.take().and_then(|p| p.cast::().ok()) - { - Some(attrs) => (attrs.name, attrs.activation_token), - None => (None, None), - }; - // Set the app_id. if let Some(name) = app_name.map(|name| name.general) { window.set_app_id(name); diff --git a/winit-wayland/src/window/state.rs b/winit-wayland/src/window/state.rs index 8e3f52da..86711bdd 100644 --- a/winit-wayland/src/window/state.rs +++ b/winit-wayland/src/window/state.rs @@ -134,6 +134,9 @@ pub struct WindowState { /// Whether we should decorate the frame. decorate: bool, + /// Whether we should tell the compositor that we prefer drawing decorations ourself. + prefer_csd: bool, + /// Min size. min_surface_size: LogicalSize, max_surface_size: Option>, @@ -180,6 +183,7 @@ impl WindowState { initial_size: Size, window: Window, theme: Option, + prefer_csd: bool, ) -> Self { let compositor = winit_state.compositor_state.clone(); let pointer_constraints = winit_state.pointer_constraints.clone(); @@ -209,6 +213,7 @@ impl WindowState { selected_cursor: Default::default(), cursor_visible: true, decorate: true, + prefer_csd, fractional_scale, frame: None, frame_callback_state: FrameCallbackState::None, @@ -955,7 +960,7 @@ impl WindowState { /// Whether show or hide client side decorations. #[inline] pub fn set_decorate(&mut self, decorate: bool) { - if decorate == self.decorate { + if decorate == self.decorate && !self.prefer_csd { return; } @@ -966,6 +971,9 @@ impl WindowState { // To disable decorations we should request client and hide the frame. self.window.request_decoration_mode(Some(DecorationMode::Client)) }, + _ if self.decorate && self.prefer_csd => { + self.window.request_decoration_mode(Some(DecorationMode::Client)) + }, _ if self.decorate => self.window.request_decoration_mode(Some(DecorationMode::Server)), _ => (), }