wayland: add prefer_csd attribute

This commit is contained in:
Timon 2025-10-24 12:35:51 +00:00 committed by GitHub
parent 42d256e926
commit bd6fef1d80
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 29 additions and 8 deletions

View file

@ -98,6 +98,7 @@ pub(crate) struct ApplicationName {
pub struct WindowAttributesWayland { pub struct WindowAttributesWayland {
pub(crate) name: Option<ApplicationName>, pub(crate) name: Option<ApplicationName>,
pub(crate) activation_token: Option<ActivationToken>, pub(crate) activation_token: Option<ActivationToken>,
pub(crate) prefer_csd: bool,
} }
impl WindowAttributesWayland { impl WindowAttributesWayland {
@ -119,6 +120,18 @@ impl WindowAttributesWayland {
self.activation_token = Some(token); self.activation_token = Some(token);
self 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 { impl PlatformWindowAttributes for WindowAttributesWayland {

View file

@ -106,6 +106,12 @@ impl Window {
let window = let window =
state.xdg_shell.create_window(surface.clone(), default_decorations, &queue_handle); 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::<WindowAttributesWayland>().ok())
.unwrap_or_default();
let mut window_state = WindowState::new( let mut window_state = WindowState::new(
event_loop_window_target.handle.clone(), event_loop_window_target.handle.clone(),
&event_loop_window_target.queue_handle, &event_loop_window_target.queue_handle,
@ -113,6 +119,7 @@ impl Window {
size, size,
window.clone(), window.clone(),
attributes.preferred_theme, attributes.preferred_theme,
prefer_csd,
); );
window_state.set_window_icon(attributes.window_icon); window_state.set_window_icon(attributes.window_icon);
@ -125,13 +132,6 @@ impl Window {
// Set the decorations hint. // Set the decorations hint.
window_state.set_decorate(attributes.decorations); window_state.set_decorate(attributes.decorations);
let (app_name, activation_token) =
match attributes.platform.take().and_then(|p| p.cast::<WindowAttributesWayland>().ok())
{
Some(attrs) => (attrs.name, attrs.activation_token),
None => (None, None),
};
// Set the app_id. // Set the app_id.
if let Some(name) = app_name.map(|name| name.general) { if let Some(name) = app_name.map(|name| name.general) {
window.set_app_id(name); window.set_app_id(name);

View file

@ -134,6 +134,9 @@ pub struct WindowState {
/// Whether we should decorate the frame. /// Whether we should decorate the frame.
decorate: bool, decorate: bool,
/// Whether we should tell the compositor that we prefer drawing decorations ourself.
prefer_csd: bool,
/// Min size. /// Min size.
min_surface_size: LogicalSize<u32>, min_surface_size: LogicalSize<u32>,
max_surface_size: Option<LogicalSize<u32>>, max_surface_size: Option<LogicalSize<u32>>,
@ -180,6 +183,7 @@ impl WindowState {
initial_size: Size, initial_size: Size,
window: Window, window: Window,
theme: Option<Theme>, theme: Option<Theme>,
prefer_csd: bool,
) -> Self { ) -> Self {
let compositor = winit_state.compositor_state.clone(); let compositor = winit_state.compositor_state.clone();
let pointer_constraints = winit_state.pointer_constraints.clone(); let pointer_constraints = winit_state.pointer_constraints.clone();
@ -209,6 +213,7 @@ impl WindowState {
selected_cursor: Default::default(), selected_cursor: Default::default(),
cursor_visible: true, cursor_visible: true,
decorate: true, decorate: true,
prefer_csd,
fractional_scale, fractional_scale,
frame: None, frame: None,
frame_callback_state: FrameCallbackState::None, frame_callback_state: FrameCallbackState::None,
@ -955,7 +960,7 @@ impl WindowState {
/// Whether show or hide client side decorations. /// Whether show or hide client side decorations.
#[inline] #[inline]
pub fn set_decorate(&mut self, decorate: bool) { pub fn set_decorate(&mut self, decorate: bool) {
if decorate == self.decorate { if decorate == self.decorate && !self.prefer_csd {
return; return;
} }
@ -966,6 +971,9 @@ impl WindowState {
// To disable decorations we should request client and hide the frame. // To disable decorations we should request client and hide the frame.
self.window.request_decoration_mode(Some(DecorationMode::Client)) 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)), _ if self.decorate => self.window.request_decoration_mode(Some(DecorationMode::Server)),
_ => (), _ => (),
} }