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