gpui: Fall back to client-side decorations on Wayland if SSD not supported (#39313)

It is optional for Wayland servers to support server-side decorations.
In particular, GNOME chooses to not implement SSD
(https://gitlab.gnome.org/GNOME/mutter/-/issues/217). So, even if the
application requests SSD, it must draw client-side decorations unless
the application receives a response from the server confirming the
request for SSD.

Before, when the user requested SSD for Zed, but the Wayland server did
not support it, there were no server-side decorations (window titlebar)
drawn, but Zed did not draw the window minimize, maximize, and close
buttons either. This fixes Zed so it always draws the window control
buttons if the Wayland server does not support SSD.

Before on GNOME Wayland with SSD requested:
<img width="3840" height="2160" alt="image"
src="https://github.com/user-attachments/assets/68a6d853-623d-401f-8e7f-21d4dea00543"
/>

After on GNOME Wayland with SSD requested:
<img width="3840" height="2160" alt="image"
src="https://github.com/user-attachments/assets/b258ae8b-fe0e-4ba2-a541-ef6f2c38f788"
/>


Release Notes:

- Fixed window control buttons not showing in GNOME Wayland when SSD
requested
This commit is contained in:
Be
2025-11-21 19:55:44 +00:00
committed by GitHub
parent e76b485de3
commit a04b3d80c8
@@ -1270,10 +1270,21 @@ impl PlatformWindow for WaylandWindow {
fn request_decorations(&self, decorations: WindowDecorations) {
let mut state = self.borrow_mut();
state.decorations = decorations;
if let Some(decoration) = state.surface_state.decoration() {
decoration.set_mode(decorations.to_xdg());
update_window(state);
match state.surface_state.decoration().as_ref() {
Some(decoration) => {
decoration.set_mode(decorations.to_xdg());
state.decorations = decorations;
update_window(state);
}
None => {
if matches!(decorations, WindowDecorations::Server) {
log::info!(
"Server-side decorations requested, but the Wayland server does not support them. Falling back to client-side decorations."
);
}
state.decorations = WindowDecorations::Client;
update_window(state);
}
}
}