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