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>
88 lines
3.0 KiB
Rust
88 lines
3.0 KiB
Rust
fn main() {
|
|
#[cfg(all(target_os = "linux", feature = "wayland"))]
|
|
example::main();
|
|
|
|
#[cfg(not(all(target_os = "linux", feature = "wayland")))]
|
|
panic!("This example requires the `wayland` feature and a linux system.");
|
|
}
|
|
|
|
#[cfg(all(target_os = "linux", feature = "wayland"))]
|
|
mod example {
|
|
use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
|
|
|
use gpui::{
|
|
App, Application, Bounds, Context, FontWeight, Size, Window, WindowBackgroundAppearance,
|
|
WindowBounds, WindowKind, WindowOptions, div, layer_shell::*, point, prelude::*, px, rems,
|
|
rgba, white,
|
|
};
|
|
|
|
struct LayerShellExample;
|
|
|
|
impl LayerShellExample {
|
|
fn new(cx: &mut Context<Self>) -> Self {
|
|
cx.spawn(async move |this, cx| {
|
|
loop {
|
|
let _ = this.update(cx, |_, cx| cx.notify());
|
|
cx.background_executor()
|
|
.timer(Duration::from_millis(500))
|
|
.await;
|
|
}
|
|
})
|
|
.detach();
|
|
|
|
LayerShellExample
|
|
}
|
|
}
|
|
|
|
impl Render for LayerShellExample {
|
|
fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
|
|
let now = SystemTime::now()
|
|
.duration_since(UNIX_EPOCH)
|
|
.unwrap()
|
|
.as_secs();
|
|
|
|
let hours = (now / 3600) % 24;
|
|
let minutes = (now / 60) % 60;
|
|
let seconds = now % 60;
|
|
|
|
div()
|
|
.size_full()
|
|
.flex()
|
|
.items_center()
|
|
.justify_center()
|
|
.text_size(rems(4.5))
|
|
.font_weight(FontWeight::EXTRA_BOLD)
|
|
.text_color(white())
|
|
.bg(rgba(0x0000044))
|
|
.rounded_xl()
|
|
.child(format!("{:02}:{:02}:{:02}", hours, minutes, seconds))
|
|
}
|
|
}
|
|
|
|
pub fn main() {
|
|
Application::new().run(|cx: &mut App| {
|
|
cx.open_window(
|
|
WindowOptions {
|
|
titlebar: None,
|
|
window_bounds: Some(WindowBounds::Windowed(Bounds {
|
|
origin: point(px(0.), px(0.)),
|
|
size: Size::new(px(500.), px(200.)),
|
|
})),
|
|
app_id: Some("gpui-layer-shell-example".to_string()),
|
|
window_background: WindowBackgroundAppearance::Transparent,
|
|
kind: WindowKind::LayerShell(LayerShellOptions {
|
|
namespace: "gpui".to_string(),
|
|
anchor: Anchor::LEFT | Anchor::RIGHT | Anchor::BOTTOM,
|
|
margin: Some((px(0.), px(0.), px(40.), px(0.))),
|
|
keyboard_interactivity: KeyboardInteractivity::None,
|
|
..Default::default()
|
|
}),
|
|
..Default::default()
|
|
},
|
|
|_, cx| cx.new(LayerShellExample::new),
|
|
)
|
|
.unwrap();
|
|
});
|
|
}
|
|
}
|