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.
This commit is contained in:
Kirill Chibisov 2023-06-25 14:12:12 +04:00 committed by GitHub
parent bc216b8f67
commit 059abb06fc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 43 additions and 7 deletions

View file

@ -105,11 +105,18 @@ impl Window {
.map(|size| size.to_logical::<u32>(1.)) .map(|size| size.to_logical::<u32>(1.))
.unwrap_or((800, 600).into()); .unwrap_or((800, 600).into());
let window = state.xdg_shell.create_window( // We prefer server side decorations, however to not have decorations we ask for client
surface.clone(), // side decorations instead.
WindowDecorations::ServerDefault, let default_decorations = if attributes.decorations {
&queue_handle, WindowDecorations::RequestServer
); } else {
WindowDecorations::RequestClient
};
let window =
state
.xdg_shell
.create_window(surface.clone(), default_decorations, &queue_handle);
let mut window_state = WindowState::new( let mut window_state = WindowState::new(
event_loop_window_target.connection.clone(), event_loop_window_target.connection.clone(),
@ -123,6 +130,9 @@ impl Window {
// Set transparency hint. // Set transparency hint.
window_state.set_transparent(attributes.transparent); window_state.set_transparent(attributes.transparent);
// Set the decorations hint.
window_state.set_decorate(attributes.decorations);
// Set the app_id. // Set the app_id.
if let Some(name) = platform_attributes.name.map(|name| name.general) { if let Some(name) = platform_attributes.name.map(|name| name.general) {
window.set_app_id(name); window.set_app_id(name);

View file

@ -113,6 +113,9 @@ pub struct WindowState {
/// Whether the CSD fail to create, so we don't try to create them on each iteration. /// Whether the CSD fail to create, so we don't try to create them on each iteration.
csd_fails: bool, csd_fails: bool,
/// Whether we should decorate the frame.
decorate: bool,
/// Min size. /// Min size.
min_inner_size: LogicalSize<u32>, min_inner_size: LogicalSize<u32>,
max_inner_size: Option<LogicalSize<u32>>, max_inner_size: Option<LogicalSize<u32>>,
@ -180,8 +183,8 @@ impl WindowState {
) { ) {
Ok(mut frame) => { Ok(mut frame) => {
frame.set_title(&self.title); frame.set_title(&self.title);
// Ensure that the frame is not hidden. // Hide the frame if we were asked to not decorate.
frame.set_hidden(false); frame.set_hidden(!self.decorate);
self.frame = Some(frame); self.frame = Some(frame);
} }
Err(err) => { Err(err) => {
@ -391,6 +394,7 @@ impl WindowState {
connection, connection,
theme, theme,
csd_fails: false, csd_fails: false,
decorate: true,
cursor_grab_mode: GrabState::new(), cursor_grab_mode: GrabState::new(),
cursor_icon: CursorIcon::Default, cursor_icon: CursorIcon::Default,
cursor_visible: true, cursor_visible: true,
@ -706,6 +710,28 @@ 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 {
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() { if let Some(frame) = self.frame.as_mut() {
frame.set_hidden(!decorate); frame.set_hidden(!decorate);
// Force the resize. // Force the resize.