gpui/platform/layer_shell.rs
1use bitflags::bitflags;
2use thiserror::Error;
3
4use crate::{Pixels, util::FluentBuilder};
5
6/// The layer the surface is rendered on. Multiple surfaces can share a layer, and ordering within
7/// a single layer is undefined.
8#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
9pub enum Layer {
10 /// The background layer, typically used for wallpapers.
11 Background,
12
13 /// The bottom layer.
14 Bottom,
15
16 /// The top layer, typically used for fullscreen windows.
17 Top,
18
19 /// The overlay layer, used for surfaces that should always be on top.
20 #[default]
21 Overlay,
22}
23
24bitflags! {
25 /// Screen anchor point for layer_shell surfaces. These can be used in any combination, e.g.
26 /// specifying `Anchor::LEFT | Anchor::RIGHT` will stretch the surface across the width of the
27 /// screen.
28 #[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
29 pub struct Anchor: u32 {
30 /// Anchor to the top edge of the screen.
31 const TOP = 1;
32 /// Anchor to the bottom edge of the screen.
33 const BOTTOM = 2;
34 /// Anchor to the left edge of the screen.
35 const LEFT = 4;
36 /// Anchor to the right edge of the screen.
37 const RIGHT = 8;
38 }
39}
40
41/// Keyboard interactivity mode for the layer_shell surfaces.
42#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
43pub enum KeyboardInteractivity {
44 /// No keyboard inputs will be delivered to the surface and it won't be able to receive
45 /// keyboard focus.
46 None,
47
48 /// The surface will receive exclusive keyboard focus as long as it is above the shell surface
49 /// layer, and no other layer_shell surfaces are above it.
50 Exclusive,
51
52 /// The surface can be focused similarly to a normal window.
53 #[default]
54 OnDemand,
55}
56
57/// Configures a Wayland layer-shell surface, such as a panel, dock, or wallpaper.
58///
59/// Set this on [`WindowKind::LayerShell`](crate::WindowKind::LayerShell) when you open a window.
60/// Chain setters on [`LayerShellOptions::default`] to configure the surface. Pass `None` to
61/// clear the exclusive zone, exclusive edge, or margins.
62///
63/// The compositor applies the namespace, layer, anchor and margins. Opening the window fails
64/// with [`LayerShellNotSupportedError`] when the compositor doesn't support the layer-shell
65/// protocol. Layer shell exists only on Wayland, so this module is available only on Linux
66/// builds with the `wayland` feature.
67///
68/// # Examples
69///
70/// ```
71/// # #[cfg(all(target_os = "linux", feature = "wayland"))]
72/// # fn main() {
73/// use gpui::{
74/// layer_shell::{Anchor, KeyboardInteractivity, Layer, LayerShellOptions},
75/// px,
76/// };
77///
78/// // A 40 px bar along the bottom edge, stretched across the screen.
79/// let options = LayerShellOptions::default()
80/// .namespace("panel")
81/// .layer(Layer::Top)
82/// .anchor(Anchor::LEFT | Anchor::RIGHT | Anchor::BOTTOM)
83/// .exclusive_zone(px(40.0))
84/// .keyboard_interactivity(KeyboardInteractivity::None);
85///
86/// assert_eq!(options.namespace, "panel");
87/// assert_eq!(options.layer, Layer::Top);
88/// assert_eq!(options.exclusive_zone, Some(px(40.0)));
89/// # }
90/// # #[cfg(not(all(target_os = "linux", feature = "wayland")))]
91/// # fn main() {}
92/// ```
93#[derive(Clone, Debug, Default, PartialEq, Eq, derive_setters::Setters)]
94#[setters(into)]
95pub struct LayerShellOptions {
96 /// The namespace for the surface, mostly used by compositors to apply rules, can not be
97 /// changed after the surface is created.
98 pub namespace: String,
99 /// The layer the surface is rendered on.
100 pub layer: Layer,
101 /// The anchor point of the surface.
102 pub anchor: Anchor,
103 /// Requests that the compositor avoids occluding an area with other surfaces.
104 pub exclusive_zone: Option<Pixels>,
105 /// The anchor point of the exclusive zone, will be determined using the anchor if left
106 /// unspecified.
107 pub exclusive_edge: Option<Anchor>,
108 /// Margins between the surface and its anchor point(s).
109 /// Specified in CSS order: top, right, bottom, left.
110 pub margin: Option<(Pixels, Pixels, Pixels, Pixels)>,
111 /// How keyboard events should be delivered to the surface.
112 pub keyboard_interactivity: KeyboardInteractivity,
113}
114
115impl FluentBuilder for LayerShellOptions {}
116
117/// An error indicating that an action failed because the compositor doesn't support the required
118/// layer_shell protocol.
119#[derive(Debug, Error)]
120#[error("Compositor doesn't support zwlr_layer_shell_v1")]
121pub struct LayerShellNotSupportedError;