gpui: Implement support for wlr layer shell (#35610)

This reintroduces `layer_shell` support after #32651 was reverted. On
top of that, it allows setting options for the created surface,
restricts the enum variant to the `wayland` feature, and adds an example
that renders a clock widget using the protocol.

I've renamed the `WindowKind` variant to `LayerShell` from `Overlay`,
since the protocol can also be used to render wallpapers and such, which
doesn't really fit with the word.

Things I'm still unsure of:
- We need to get the layer options types to the user somehow, but
nothing from the `platform::linux` crate was exported, I'm assuming
intentionally. I've kept the types inside the module (instead of doing
`pub use layer_shell::*` to not pollute the global namespace with
generic words like `Anchor` or `Layer` Let me know if you want to do
this differently.
- I've added the options to the `WindowKind` variant. That's the only
clean way I see to supply them when the window is created. This makes
the kind no longer implement `Copy`.
- The options don't have setter methods yet and can only be defined on
window creation. We'd have to make fallible functions for setting them,
which only work if the underlying surface is a `layer_shell` surface.
That feels un-rust-y.

CC @zeroeightysix  
Thanks to @wuliuqii, whose layer-shell implementation I've also looked
at while putting this together.

Release Notes:

- Add support for the `layer_shell` protocol on wayland

---------

Co-authored-by: Ridan Vandenbergh <ridanvandenbergh@gmail.com>
This commit is contained in:
Hilmar Wiegand
2025-10-29 11:32:01 -04:00
committed by GitHub
co-authored by Ridan Vandenbergh
parent 19099e808c
commit b92664c52d
9 changed files with 541 additions and 82 deletions
+18 -10
View File
@@ -82,6 +82,9 @@ pub(crate) use test::*;
#[cfg(target_os = "windows")]
pub(crate) use windows::*;
#[cfg(all(target_os = "linux", feature = "wayland"))]
pub use linux::layer_shell;
#[cfg(any(test, feature = "test-support"))]
pub use test::{TestDispatcher, TestScreenCaptureSource, TestScreenCaptureStream};
@@ -120,6 +123,15 @@ pub(crate) fn current_platform(headless: bool) -> Rc<dyn Platform> {
}
}
#[cfg(target_os = "windows")]
pub(crate) fn current_platform(_headless: bool) -> Rc<dyn Platform> {
Rc::new(
WindowsPlatform::new()
.inspect_err(|err| show_error("Failed to launch", err.to_string()))
.unwrap(),
)
}
/// Return which compositor we're guessing we'll use.
/// Does not attempt to connect to the given compositor
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
@@ -151,15 +163,6 @@ pub fn guess_compositor() -> &'static str {
}
}
#[cfg(target_os = "windows")]
pub(crate) fn current_platform(_headless: bool) -> Rc<dyn Platform> {
Rc::new(
WindowsPlatform::new()
.inspect_err(|err| show_error("Failed to launch", err.to_string()))
.unwrap(),
)
}
pub(crate) trait Platform: 'static {
fn background_executor(&self) -> BackgroundExecutor;
fn foreground_executor(&self) -> ForegroundExecutor;
@@ -1293,7 +1296,7 @@ pub struct TitlebarOptions {
}
/// The kind of window to create
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum WindowKind {
/// A normal application window
Normal,
@@ -1304,6 +1307,11 @@ pub enum WindowKind {
/// A floating window that appears on top of its parent window
Floating,
/// A Wayland LayerShell window, used to draw overlays or backgrounds for applications such as
/// docks, notifications or wallpapers.
#[cfg(all(target_os = "linux", feature = "wayland"))]
LayerShell(layer_shell::LayerShellOptions),
}
/// The appearance of the window, as defined by the operating system.