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 {}