gtk4_layer_shell/lib.rs
1#![cfg_attr(docsrs, feature(doc_cfg))]
2#![deny(warnings)]
3#![allow(rustdoc::redundant_explicit_links)]
4
5#[allow(unused_imports)]
6#[allow(clippy::single_component_path_imports)]
7use gtk; // Required for the documentation to build without warnings
8
9use glib::translate::{FromGlib, TryFromGlib};
10use gtk::prelude::IsA;
11use gtk4_layer_shell_sys as ffi;
12
13impl TryFromGlib<ffi::GtkLayerShellLayer> for Layer {
14 type Error = glib::translate::GlibNoneError;
15
16 unsafe fn try_from_glib(value: ffi::GtkLayerShellLayer) -> Result<Self, Self::Error> {
17 let layer = unsafe { Self::from_glib(value) };
18 // If we got an unknown variant, return an error; otherwise, return the value.
19 match layer {
20 Layer::__Unknown(_) => Err(glib::translate::GlibNoneError),
21 _ => Ok(layer),
22 }
23 }
24}
25
26macro_rules! assert_initialized_main_thread {
27 () => {
28 if !::gtk::is_initialized_main_thread() {
29 if ::gtk::is_initialized() {
30 panic!("GTK may only be used from the main thread.");
31 } else {
32 panic!("GTK has not been initialized. Call `gtk::init` first.");
33 }
34 }
35 };
36}
37
38/// No-op.
39macro_rules! skip_assert_initialized {
40 () => {};
41}
42
43mod auto;
44pub use auto::{
45 functions::is_supported, functions::major_version, functions::micro_version,
46 functions::minor_version, functions::protocol_version, Edge, KeyboardMode, Layer,
47};
48
49mod manual;
50pub use manual::*;
51
52pub trait LayerShell: IsA<gtk::Window> {
53 /// When auto exclusive zone is enabled, exclusive zone is automatically set to the
54 /// size of the `window` + relevant margin. To disable auto exclusive zone, just set the
55 /// exclusive zone to 0 or any other fixed value.
56 ///
57 /// NOTE: you can control the auto exclusive zone by changing the margin on the non-anchored
58 /// edge. This behavior is specific to gtk-layer-shell and not part of the underlying protocol
59 /// ## `window`
60 /// A layer surface.
61 #[doc(alias = "gtk_layer_auto_exclusive_zone_enable")]
62 fn auto_exclusive_zone_enable(&self) {
63 crate::auto::functions::auto_exclusive_zone_enable(self);
64 }
65
66 /// ## `window`
67 /// A layer surface.
68 ///
69 /// # Returns
70 ///
71 /// if the surface's exclusive zone is set to change based on the window's size
72 #[doc(alias = "gtk_layer_auto_exclusive_zone_is_enabled")]
73 fn auto_exclusive_zone_is_enabled(&self) -> bool {
74 crate::auto::functions::auto_exclusive_zone_is_enabled(self)
75 }
76
77 /// ## `window`
78 /// A layer surface.
79 /// ## `edge`
80 /// the edge to which the surface may or may not be anchored
81 ///
82 /// # Returns
83 ///
84 /// if this surface is anchored to the given edge.
85 #[doc(alias = "gtk_layer_get_anchor")]
86 #[doc(alias = "get_anchor")]
87 fn is_anchor(&self, edge: Edge) -> bool {
88 crate::auto::functions::is_anchor(self, edge)
89 }
90
91 /// ## `window`
92 /// A layer surface.
93 ///
94 /// # Returns
95 ///
96 /// the window's exclusive zone (which may have been set manually or automatically)
97 #[doc(alias = "gtk_layer_get_exclusive_zone")]
98 #[doc(alias = "get_exclusive_zone")]
99 fn exclusive_zone(&self) -> i32 {
100 crate::auto::functions::exclusive_zone(self)
101 }
102
103 /// ## `window`
104 /// A layer surface.
105 ///
106 /// # Returns
107 ///
108 /// current keyboard interactivity mode for `window`.
109 #[doc(alias = "gtk_layer_get_keyboard_mode")]
110 #[doc(alias = "get_keyboard_mode")]
111 fn keyboard_mode(&self) -> KeyboardMode {
112 crate::auto::functions::keyboard_mode(self)
113 }
114
115 /// ## `window`
116 /// A layer surface.
117 ///
118 /// # Returns
119 ///
120 /// the current layer.
121 #[doc(alias = "gtk_layer_get_layer")]
122 #[doc(alias = "get_layer")]
123 fn layer(&self) -> Option<Layer> {
124 crate::auto::functions::layer(self)
125 }
126
127 /// ## `window`
128 /// A layer surface.
129 /// ## `edge`
130 /// the margin edge to get
131 ///
132 /// # Returns
133 ///
134 /// the size of the margin for the given edge.
135 #[doc(alias = "gtk_layer_get_margin")]
136 #[doc(alias = "get_margin")]
137 fn margin(&self, edge: Edge) -> i32 {
138 crate::auto::functions::margin(self, edge)
139 }
140
141 /// NOTE: To get which monitor the surface is actually on, use
142 /// `gdk_display_get_monitor_at_window()`.
143 /// ## `window`
144 /// A layer surface.
145 ///
146 /// # Returns
147 ///
148 /// the monitor this surface will/has requested to be on, can be [`None`].
149 #[doc(alias = "gtk_layer_get_monitor")]
150 #[doc(alias = "get_monitor")]
151 fn monitor(&self) -> Option<gdk::Monitor> {
152 crate::auto::functions::monitor(self)
153 }
154
155 /// NOTE: this function does not return ownership of the string. Do not free the returned string.
156 /// Future calls into the library may invalidate the returned string.
157 /// ## `window`
158 /// A layer surface.
159 ///
160 /// # Returns
161 ///
162 /// a reference to the namespace property. If namespace is unset, returns the
163 /// default namespace ("gtk-layer-shell"). Never returns [`None`].
164 #[doc(alias = "gtk_layer_get_namespace")]
165 #[doc(alias = "get_namespace")]
166 fn namespace(&self) -> Option<glib::GString> {
167 crate::auto::functions::namespace(self)
168 }
169
170 /// Set the `window` up to be a layer surface once it is mapped. this must be called before
171 /// the `window` is realized.
172 /// ## `window`
173 /// A [`gtk::Window`][crate::gtk::Window] to be turned into a layer surface.
174 #[doc(alias = "init_for_window")]
175 #[doc(alias = "gtk_layer_init_for_window")]
176 fn init_layer_shell(&self) {
177 crate::auto::functions::init_for_window(self);
178 }
179
180 /// ## `window`
181 /// A [`gtk::Window`][crate::gtk::Window] that may or may not have a layer surface.
182 ///
183 /// # Returns
184 ///
185 /// if `window` has been initialized as a layer surface.
186 #[doc(alias = "gtk_layer_is_layer_window")]
187 fn is_layer_window(&self) -> bool {
188 crate::auto::functions::is_layer_window(self)
189 }
190
191 /// Set whether `window` should be anchored to `edge`.
192 /// - If two perpendicular edges are anchored, the surface with be anchored to that corner
193 /// - If two opposite edges are anchored, the window will be stretched across the screen in that direction
194 ///
195 /// Default is [`false`] for each [`Edge`][crate::Edge]
196 /// ## `window`
197 /// A layer surface.
198 /// ## `edge`
199 /// A [`Edge`][crate::Edge] this layer surface may be anchored to.
200 /// ## `anchor_to_edge`
201 /// Whether or not to anchor this layer surface to `edge`.
202 #[doc(alias = "gtk_layer_set_anchor")]
203 fn set_anchor(&self, edge: Edge, anchor_to_edge: bool) {
204 crate::auto::functions::set_anchor(self, edge, anchor_to_edge);
205 }
206
207 /// Has no effect unless the surface is anchored to an edge. Requests that the compositor
208 /// does not place other surfaces within the given exclusive zone of the anchored edge.
209 /// For example, a panel can request to not be covered by maximized windows. See
210 /// wlr-layer-shell-unstable-v1.xml for details.
211 ///
212 /// Default is 0
213 /// ## `window`
214 /// A layer surface.
215 /// ## `exclusive_zone`
216 /// The size of the exclusive zone.
217 #[doc(alias = "gtk_layer_set_exclusive_zone")]
218 fn set_exclusive_zone(&self, exclusive_zone: i32) {
219 crate::auto::functions::set_exclusive_zone(self, exclusive_zone);
220 }
221
222 /// Sets if/when `window` should receive keyboard events from the compositor, see
223 /// GtkLayerShellKeyboardMode for details.
224 ///
225 /// Default is [`KeyboardMode::None`][crate::KeyboardMode::None]
226 /// ## `window`
227 /// A layer surface.
228 /// ## `mode`
229 /// The type of keyboard interactivity requested.
230 #[doc(alias = "gtk_layer_set_keyboard_mode")]
231 fn set_keyboard_mode(&self, mode: KeyboardMode) {
232 crate::auto::functions::set_keyboard_mode(self, mode);
233 }
234
235 /// Set the "layer" on which the surface appears (controls if it is over top of or below other surfaces). The layer may
236 /// be changed on-the-fly in the current version of the layer shell protocol, but on compositors that only support an
237 /// older version the `window` is remapped so the change can take effect.
238 ///
239 /// Default is [`Layer::Top`][crate::Layer::Top]
240 /// ## `window`
241 /// A layer surface.
242 /// ## `layer`
243 /// The layer on which this surface appears.
244 #[doc(alias = "gtk_layer_set_layer")]
245 fn set_layer(&self, layer: Layer) {
246 crate::auto::functions::set_layer(self, layer);
247 }
248
249 /// Set the margin for a specific `edge` of a `window`. Effects both surface's distance from
250 /// the edge and its exclusive zone size (if auto exclusive zone enabled).
251 ///
252 /// Default is 0 for each [`Edge`][crate::Edge]
253 /// ## `window`
254 /// A layer surface.
255 /// ## `edge`
256 /// The [`Edge`][crate::Edge] for which to set the margin.
257 /// ## `margin_size`
258 /// The margin for `edge` to be set.
259 #[doc(alias = "gtk_layer_set_margin")]
260 fn set_margin(&self, edge: Edge, margin_size: i32) {
261 crate::auto::functions::set_margin(self, edge, margin_size);
262 }
263
264 /// Set the output for the window to be placed on, or [`None`] to let the compositor choose.
265 /// If the window is currently mapped, it will get remapped so the change can take effect.
266 ///
267 /// Default is [`None`]
268 /// ## `window`
269 /// A layer surface.
270 /// ## `monitor`
271 /// The output this layer surface will be placed on ([`None`] to let the compositor decide).
272 #[doc(alias = "gtk_layer_set_monitor")]
273 fn set_monitor(&self, monitor: Option<&gdk::Monitor>) {
274 crate::auto::functions::set_monitor(self, monitor);
275 }
276
277 /// Set the "namespace" of the surface.
278 ///
279 /// No one is quite sure what this is for, but it probably should be something generic
280 /// ("panel", "osk", etc). The `name_space` string is copied, and caller maintains
281 /// ownership of original. If the window is currently mapped, it will get remapped so
282 /// the change can take effect.
283 ///
284 /// Default is "gtk-layer-shell" (which will be used if set to [`None`])
285 /// ## `window`
286 /// A layer surface.
287 /// ## `name_space`
288 /// The namespace of this layer surface.
289 #[doc(alias = "gtk_layer_set_namespace")]
290 fn set_namespace(&self, name_space: Option<&str>) {
291 crate::auto::functions::set_namespace(self, name_space);
292 }
293
294 /// ## `window`
295 /// A layer surface.
296 ///
297 /// # Returns
298 ///
299 /// The underlying layer surface Wayland object
300 ///
301 #[doc(alias = "gtk_layer_get_zwlr_layer_surface_v1")]
302 #[doc(alias = "get_zwlr_layer_surface_v1")]
303 fn zwlr_layer_surface_v1(&self) -> Option<*mut ffi::zwlr_layer_surface_v1> {
304 zwlr_layer_surface_v1(self)
305 }
306}
307
308// The default implementation is always fine
309impl<T: IsA<gtk::Window>> LayerShell for T {}