Skip to main content

jay_config/
input.rs

1//! Tools for configuring input devices.
2
3pub mod acceleration;
4pub mod capability;
5pub mod clickmethod;
6pub mod input_event_codes;
7pub mod scrollmethod;
8
9use crate::_private::DEFAULT_SEAT_NAME;
10use crate::_private::ipc::WorkspaceSource;
11use crate::Axis;
12use crate::ContainerTarget;
13use crate::Direction;
14use crate::ModifiedKeySym;
15use crate::RelativeAxis;
16use crate::Workspace;
17use crate::input::acceleration::AccelProfile;
18use crate::input::capability::Capability;
19use crate::input::clickmethod::ClickMethod;
20use crate::input::scrollmethod::ScrollMethod;
21use crate::keyboard::Keymap;
22use crate::keyboard::mods::Modifiers;
23use crate::keyboard::syms::KeySym;
24use crate::video::Connector;
25use crate::window::Window;
26use jay_proc::PrivateEnum;
27use serde::Deserialize;
28use serde::Serialize;
29use std::time::Duration;
30
31/// An input device.
32#[derive(Serialize, Deserialize, Copy, Clone, Debug, Hash, Eq, PartialEq)]
33pub struct InputDevice(pub u64);
34
35impl InputDevice {
36    /// Assigns the input device to a seat.
37    pub fn set_seat(self, seat: Seat) {
38        get!().set_seat(self, seat)
39    }
40
41    /// Sets the keymap of the device.
42    ///
43    /// This overrides the keymap set for the seat. The keymap becomes active when a key
44    /// on the device is pressed.
45    ///
46    /// Setting the invalid keymap reverts to the seat keymap.
47    pub fn set_keymap(self, keymap: Keymap) {
48        get!().set_device_keymap(self, keymap)
49    }
50
51    /// Returns whether the device has the specified capability.
52    pub fn has_capability(self, cap: Capability) -> bool {
53        get!(false).has_capability(self, cap)
54    }
55
56    /// Sets the device to be left handed.
57    ///
58    /// This has the effect of swapping the left and right mouse button. See the libinput
59    /// documentation for more details.
60    pub fn set_left_handed(self, left_handed: bool) {
61        get!().set_left_handed(self, left_handed);
62    }
63
64    /// Sets the acceleration profile of the device.
65    ///
66    /// This corresponds to the libinput setting of the same name.
67    pub fn set_accel_profile(self, profile: AccelProfile) {
68        get!().set_accel_profile(self, profile);
69    }
70
71    /// Sets the acceleration speed of the device.
72    ///
73    /// This corresponds to the libinput setting of the same name.
74    pub fn set_accel_speed(self, speed: f64) {
75        get!().set_accel_speed(self, speed);
76    }
77
78    /// Sets the transformation matrix of the device.
79    ///
80    /// This is not a libinput setting but a setting of the compositor. It currently affects
81    /// relative mouse motions in that the matrix is applied to the motion. To reduce the mouse
82    /// speed to 35%, use the following matrix:
83    ///
84    /// ```text
85    /// [
86    ///     [0.35, 1.0],
87    ///     [1.0, 0.35],
88    /// ]
89    /// ```
90    ///
91    /// This might give you better results than using `set_accel_profile` and `set_accel_speed`.
92    pub fn set_transform_matrix(self, matrix: [[f64; 2]; 2]) {
93        get!().set_transform_matrix(self, matrix);
94    }
95
96    /// Sets the calibration matrix of the device.
97    ///
98    /// This corresponds to the libinput setting of the same name.
99    pub fn set_calibration_matrix(self, matrix: [[f32; 3]; 2]) {
100        get!().set_calibration_matrix(self, matrix);
101    }
102
103    /// Returns the name of the device.
104    pub fn name(self) -> String {
105        get!(String::new()).device_name(self)
106    }
107
108    /// Sets how many pixel to scroll per scroll wheel dedent.
109    ///
110    /// Default: `15.0`
111    ///
112    /// This setting has no effect on non-wheel input such as touchpads.
113    ///
114    /// Some mouse wheels support high-resolution scrolling without discrete steps. In
115    /// this case a value proportional to this setting will be used.
116    pub fn set_px_per_wheel_scroll(self, px: f64) {
117        get!().set_px_per_wheel_scroll(self, px);
118    }
119
120    /// Sets a multiplier for pixel scroll events.
121    ///
122    /// Default: `1.0`
123    ///
124    /// This setting has no effect on scroll events created by a scroll wheel.
125    pub fn set_px_scroll_multiplier(self, mul: f64) {
126        get!().set_px_scroll_multiplier(self, mul);
127    }
128
129    /// Sets whether tap-to-click is enabled for this device.
130    ///
131    /// See <https://wayland.freedesktop.org/libinput/doc/latest/tapping.html>
132    pub fn set_tap_enabled(self, enabled: bool) {
133        get!().set_input_tap_enabled(self, enabled);
134    }
135
136    /// Sets whether tap-and-drag is enabled for this device.
137    ///
138    /// See <https://wayland.freedesktop.org/libinput/doc/latest/tapping.html>
139    pub fn set_drag_enabled(self, enabled: bool) {
140        get!().set_input_drag_enabled(self, enabled);
141    }
142
143    /// Sets whether drag lock is enabled for this device.
144    ///
145    /// See <https://wayland.freedesktop.org/libinput/doc/latest/tapping.html>
146    pub fn set_drag_lock_enabled(self, enabled: bool) {
147        get!().set_input_drag_lock_enabled(self, enabled);
148    }
149
150    /// Sets whether natural scrolling is enabled for this device.
151    ///
152    /// See <https://wayland.freedesktop.org/libinput/doc/latest/scrolling.html>
153    pub fn set_natural_scrolling_enabled(self, enabled: bool) {
154        get!().set_input_natural_scrolling_enabled(self, enabled);
155    }
156
157    /// Sets the click method of the device.
158    ///
159    /// See <https://wayland.freedesktop.org/libinput/doc/latest/configuration.html#click-method>
160    pub fn set_click_method(self, method: ClickMethod) {
161        get!().set_input_click_method(self, method);
162    }
163
164    /// Sets whether middle button emulation is enabled for this device.
165    ///
166    /// See <https://wayland.freedesktop.org/libinput/doc/latest/configuration.html#middle-button-emulation>
167    pub fn set_middle_button_emulation_enabled(self, enabled: bool) {
168        get!().set_input_middle_button_emulation_enabled(self, enabled);
169    }
170
171    /// Sets the scroll method of the device.
172    ///
173    /// See <https://wayland.freedesktop.org/libinput/doc/latest/scrolling.html>
174    pub fn set_scroll_method(self, method: ScrollMethod) {
175        get!().set_input_scroll_method(self, method);
176    }
177
178    /// Sets the scroll button of the device.
179    ///
180    /// See <https://wayland.freedesktop.org/libinput/doc/latest/scrolling.html>
181    pub fn set_scroll_button(self, button: InputEventCode) {
182        get!().set_input_scroll_button(self, button);
183    }
184
185    /// Sets whether scroll button locking is enabled for the device.
186    ///
187    /// See <https://wayland.freedesktop.org/libinput/doc/latest/scrolling.html>
188    pub fn set_scroll_button_lock(self, enabled: bool) {
189        get!().set_input_scroll_button_lock(self, enabled);
190    }
191
192    /// Returns the syspath of this device.
193    ///
194    /// E.g. `/sys/devices/pci0000:00/0000:00:08.1/0000:14:00.4/usb5/5-1/5-1.1/5-1.1.3/5-1.1.3:1.0`.
195    pub fn syspath(self) -> String {
196        get!(String::new()).input_device_syspath(self)
197    }
198
199    /// Returns the devnode of this device.
200    ///
201    /// E.g. `/dev/input/event7`.
202    pub fn devnode(self) -> String {
203        get!(String::new()).input_device_devnode(self)
204    }
205
206    /// Sets a callback that will be run if this device triggers a switch event.
207    pub fn on_switch_event<F: FnMut(SwitchEvent) + 'static>(self, f: F) {
208        get!().on_switch_event(self, f)
209    }
210
211    /// Maps this input device to a connector.
212    ///
213    /// The connector should be connected.
214    ///
215    /// This should be used for touch screens and graphics tablets.
216    pub fn set_connector(self, connector: Connector) {
217        get!().set_input_device_connector(self, connector);
218    }
219
220    /// Removes the mapping of this device to a connector.
221    pub fn remove_mapping(self) {
222        get!().remove_input_mapping(self);
223    }
224}
225
226/// A direction in a timeline.
227#[derive(Serialize, Deserialize, Copy, Clone, Debug, Hash, Eq, PartialEq)]
228pub enum Timeline {
229    Older,
230    Newer,
231}
232
233/// A direction for layer traversal.
234#[derive(Serialize, Deserialize, Copy, Clone, Debug, Hash, Eq, PartialEq)]
235pub enum LayerDirection {
236    Below,
237    Above,
238}
239
240/// A seat.
241#[derive(Serialize, Deserialize, Copy, Clone, Debug, Hash, Eq, PartialEq)]
242pub struct Seat(pub u64);
243
244impl Seat {
245    pub const INVALID: Self = Self(0);
246
247    /// Returns whether the seat is invalid.
248    pub fn is_invalid(self) -> bool {
249        self == Self::INVALID
250    }
251
252    #[doc(hidden)]
253    pub fn raw(self) -> u64 {
254        self.0
255    }
256
257    #[doc(hidden)]
258    pub fn from_raw(raw: u64) -> Self {
259        Self(raw)
260    }
261
262    /// Sets whether this seat's cursor uses the hardware cursor if available.
263    ///
264    /// Only one seat at a time can use the hardware cursor. Setting this to `true` for a
265    /// seat automatically unsets it for all other seats.
266    ///
267    /// By default, the first created seat uses the hardware cursor.
268    pub fn use_hardware_cursor(self, use_hardware_cursor: bool) {
269        get!().set_use_hardware_cursor(self, use_hardware_cursor);
270    }
271
272    /// Sets the size of the cursor theme.
273    ///
274    /// Default: 16.
275    pub fn set_cursor_size(self, size: i32) {
276        get!().set_cursor_size(self, size)
277    }
278
279    /// Creates a compositor-wide hotkey.
280    ///
281    /// The closure is invoked when the user presses the last key of the modified keysym.
282    /// Note that the keysym is calculated without modifiers applied. To perform an action
283    /// when `SHIFT+k` is pressed, use `SHIFT | SYM_k` not `SHIFT | SYM_K`.
284    ///
285    /// CapsLock and NumLock are ignored during modifier evaluation. Therefore, bindings
286    /// containing these modifiers will never be invoked.
287    pub fn bind<T: Into<ModifiedKeySym>, F: FnMut() + 'static>(self, mod_sym: T, f: F) {
288        self.bind_masked(Modifiers(!0), mod_sym, f)
289    }
290
291    /// Creates a compositor-wide hotkey while ignoring some modifiers.
292    ///
293    /// This is similar to `bind` except that only the masked modifiers are considered.
294    ///
295    /// For example, if this function is invoked with `mod_mask = Modifiers::NONE` and
296    /// `mod_sym = SYM_XF86AudioRaiseVolume`, then the callback will be invoked whenever
297    /// `SYM_XF86AudioRaiseVolume` is pressed. Even if the user is simultaneously holding
298    /// the shift key which would otherwise prevent the callback from taking effect.
299    ///
300    /// For example, if this function is invoked with `mod_mask = CTRL | SHIFT` and
301    /// `mod_sym = CTRL | SYM_x`, then the callback will be invoked whenever the user
302    /// presses `ctrl+x` without pressing the shift key. Even if the user is
303    /// simultaneously holding the alt key.
304    ///
305    /// If `mod_sym` contains any modifiers, then these modifiers are automatically added
306    /// to the mask. The synthetic `RELEASE` modifier is always added to the mask.
307    pub fn bind_masked<T: Into<ModifiedKeySym>, F: FnMut() + 'static>(
308        self,
309        mod_mask: Modifiers,
310        mod_sym: T,
311        f: F,
312    ) {
313        get!().bind_masked(self, mod_mask, mod_sym.into(), f)
314    }
315
316    /// Configures whether the given bind repeats.
317    ///
318    /// The default is `false`.
319    ///
320    /// Binding resets the value to the default.
321    pub fn set_repeat_bind<T: Into<ModifiedKeySym>>(self, mod_sym: T, repeat: bool) {
322        get!().set_repeat_bind(self, mod_sym.into(), repeat);
323    }
324
325    /// Configures whether the given bind executes even if the screen is locked.
326    ///
327    /// The default is `false`.
328    ///
329    /// Binding resets the value to the default.
330    pub fn set_bind_allow_locked<T: Into<ModifiedKeySym>>(self, mod_sym: T, locked: bool) {
331        get!().set_bind_locked(self, mod_sym.into(), locked);
332    }
333
334    /// Registers a callback to be executed when the currently pressed key is released.
335    ///
336    /// This should only be called in callbacks for key-press binds.
337    ///
338    /// The callback will be executed once when the key is released regardless of any
339    /// modifiers.
340    pub fn latch<F: FnOnce() + 'static>(self, f: F) {
341        get!().latch(self, f)
342    }
343
344    /// Unbinds a hotkey.
345    pub fn unbind<T: Into<ModifiedKeySym>>(self, mod_sym: T) {
346        get!().unbind(self, mod_sym.into())
347    }
348
349    /// Moves the focus in the focus history.
350    pub fn focus_history(self, timeline: Timeline) {
351        get!().seat_focus_history(self, timeline)
352    }
353
354    /// Configures whether the focus history only includes visible windows.
355    ///
356    /// If this is `false`, then hidden windows will be made visible before moving the
357    /// focus to them.
358    ///
359    /// The default is `false`.
360    pub fn focus_history_set_only_visible(self, only_visible: bool) {
361        get!().seat_focus_history_set_only_visible(self, only_visible)
362    }
363
364    /// Configures whether the focus history only includes windows on the same workspace
365    /// as the currently focused window.
366    ///
367    /// The default is `false`.
368    pub fn focus_history_set_same_workspace(self, same_workspace: bool) {
369        get!().seat_focus_history_set_same_workspace(self, same_workspace)
370    }
371
372    /// Moves the keyboard focus of the seat to the layer above or below the current
373    /// layer.
374    pub fn focus_layer_rel(self, direction: LayerDirection) {
375        get!().seat_focus_layer_rel(self, direction)
376    }
377
378    /// Moves the keyboard focus to the tile layer.
379    pub fn focus_tiles(self) {
380        get!().seat_focus_tiles(self)
381    }
382
383    /// Moves the keyboard focus of the seat in the specified direction.
384    pub fn focus(self, direction: Direction) {
385        get!().seat_focus(self, direction)
386    }
387
388    /// Moves the focused window in the specified direction.
389    pub fn move_(self, direction: Direction) {
390        get!().seat_move(self, direction)
391    }
392
393    /// Sets the keymap of the seat.
394    pub fn set_keymap(self, keymap: Keymap) {
395        get!().seat_set_keymap(self, keymap)
396    }
397
398    /// Returns the repeat rate of the seat.
399    ///
400    /// The returned tuple is `(rate, delay)` where `rate` is the number of times keys repeat per second
401    /// and `delay` is the time after the button press after which keys start repeating.
402    pub fn repeat_rate(self) -> (i32, i32) {
403        get!((25, 250)).seat_get_repeat_rate(self)
404    }
405
406    /// Sets the repeat rate of the seat.
407    pub fn set_repeat_rate(self, rate: i32, delay: i32) {
408        get!().seat_set_repeat_rate(self, rate, delay)
409    }
410
411    /// Returns whether the parent-container of the currently focused window is in mono-mode.
412    pub fn mono(self) -> bool {
413        get!(false).seat_mono(self)
414    }
415
416    /// Sets whether the parent-container of the currently focused window is in mono-mode.
417    pub fn set_mono(self, mono: bool) {
418        get!().set_seat_mono(self, mono)
419    }
420
421    /// Toggles whether the parent-container of the currently focused window is in mono-mode.
422    pub fn toggle_mono(self) {
423        self.set_mono(!self.mono());
424    }
425
426    /// Returns the split axis of the parent-container of the currently focused window.
427    pub fn split(self) -> Axis {
428        get!(Axis::Horizontal).seat_split(self)
429    }
430
431    /// Sets the split axis of the parent-container of the currently focused window.
432    pub fn set_split(self, axis: Axis) {
433        get!().set_seat_split(self, axis)
434    }
435
436    /// Toggles the split axis of the parent-container of the currently focused window.
437    pub fn toggle_split(self) {
438        self.set_split(self.split().other());
439    }
440
441    /// Returns whether the target container of the currently focused window is in
442    /// mono-mode.
443    pub fn container_mono(self, target: ContainerTarget) -> bool {
444        get!(false).seat_container_mono(self, target.to_private())
445    }
446
447    /// Sets whether the target container of the currently focused window is in mono-mode.
448    pub fn set_container_mono(self, target: ContainerTarget, mono: bool) {
449        get!().set_seat_container_mono(self, target.to_private(), mono)
450    }
451
452    /// Toggles whether the target container of the currently focused window is in
453    /// mono-mode.
454    pub fn toggle_container_mono(self, target: ContainerTarget) {
455        self.set_container_mono(target, !self.container_mono(target));
456    }
457
458    /// Returns the split axis of the target container of the currently focused window.
459    pub fn container_split(self, target: ContainerTarget) -> Axis {
460        get!(Axis::Horizontal).seat_container_split(self, target.to_private())
461    }
462
463    /// Sets the split axis of the target container of the currently focused window.
464    pub fn set_container_split(self, target: ContainerTarget, axis: Axis) {
465        get!().set_seat_container_split(self, target.to_private(), axis)
466    }
467
468    /// Toggles the split axis of the target container of the currently focused window.
469    pub fn toggle_container_split(self, target: ContainerTarget) {
470        self.set_container_split(target, self.container_split(target).other());
471    }
472
473    /// Sets the split axis of the target container of the currently focused window
474    /// relative to the dimensions of that container.
475    pub fn set_container_split_relative(self, target: ContainerTarget, axis: RelativeAxis) {
476        get!().set_seat_container_split_relative(self, target.to_private(), axis.to_private())
477    }
478
479    /// Returns the input devices assigned to this seat.
480    pub fn input_devices(self) -> Vec<InputDevice> {
481        get!().get_input_devices(Some(self))
482    }
483
484    /// Creates a new container with the specified split in place of the currently focused window.
485    ///
486    /// If the window is the only child of its container and
487    /// [`set_split_reuses_container`](crate::set_split_reuses_container) is enabled, the
488    /// split axis of that container is changed instead.
489    pub fn create_split(self, axis: Axis) {
490        get!().create_seat_split(self, axis);
491    }
492
493    /// Creates a new container in place of the currently focused window with a split
494    /// relative to the dimensions of that window.
495    ///
496    /// If the window is the only child of its container and
497    /// [`set_split_reuses_container`](crate::set_split_reuses_container) is enabled, the
498    /// split axis of that container is changed instead.
499    pub fn create_split_relative(self, axis: RelativeAxis) {
500        get!().create_seat_split_relative(self, axis.to_private());
501    }
502
503    /// Focuses the parent node of the currently focused window.
504    pub fn focus_parent(self) {
505        get!().focus_seat_parent(self);
506    }
507
508    /// Requests the currently focused window to be closed.
509    pub fn close(self) {
510        get!().seat_close(self);
511    }
512
513    /// Returns whether the currently focused window is floating.
514    pub fn get_floating(self) -> bool {
515        get!().get_seat_floating(self)
516    }
517    /// Sets whether the currently focused window is floating.
518    pub fn set_floating(self, floating: bool) {
519        get!().set_seat_floating(self, floating);
520    }
521
522    /// Toggles whether the currently focused window is floating.
523    ///
524    /// You can do the same by double-clicking on the header.
525    pub fn toggle_floating(self) {
526        get!().toggle_seat_floating(self);
527    }
528
529    /// Returns the workspace that is currently active on the output that contains the seat's
530    /// cursor.
531    ///
532    /// If no such workspace exists, `exists` returns `false` for the returned workspace.
533    pub fn get_workspace(self) -> Workspace {
534        get!(Workspace(0)).get_seat_cursor_workspace(self)
535    }
536
537    /// Returns the workspace that is currently active on the output that contains the seat's
538    /// keyboard focus.
539    ///
540    /// If no such workspace exists, `exists` returns `false` for the returned workspace.
541    pub fn get_keyboard_workspace(self) -> Workspace {
542        get!(Workspace(0)).get_seat_keyboard_workspace(self)
543    }
544
545    /// Shows the workspace and sets the keyboard focus of the seat to that workspace.
546    ///
547    /// If the workspace doesn't currently exist, it is created on the output that contains the
548    /// seat's cursor.
549    ///
550    /// See also [`Workspace::show`].
551    pub fn show_workspace(self, workspace: Workspace) {
552        get!().show_workspace(self, workspace)
553    }
554
555    /// Shows the workspace and sets the keyboard focus of the seat to that workspace.
556    ///
557    /// If the workspace doesn't currently exist and the connector is connected, the
558    /// workspace is created on the given connector. If the connector is not connected,
559    /// the workspace is created on the output that contains the seat's cursor.
560    ///
561    /// See also [`Workspace::show`].
562    pub fn show_workspace_on(self, workspace: Workspace, connector: Connector) {
563        get!().show_workspace_on(self, workspace, connector)
564    }
565
566    /// Moves the currently focused window to the workspace.
567    pub fn set_workspace(self, workspace: Workspace) {
568        get!().set_seat_workspace(self, workspace)
569    }
570
571    /// Toggles whether the currently focused window is fullscreen.
572    pub fn toggle_fullscreen(self) {
573        let c = get!();
574        c.set_seat_fullscreen(self, !c.get_seat_fullscreen(self));
575    }
576    /// Returns whether the currently focused window is fullscreen.
577    pub fn fullscreen(self) -> bool {
578        get!(false).get_seat_fullscreen(self)
579    }
580
581    /// Sets whether the currently focused window is fullscreen.
582    pub fn set_fullscreen(self, fullscreen: bool) {
583        get!().set_seat_fullscreen(self, fullscreen)
584    }
585
586    /// Disables the currently active pointer constraint on this seat.
587    pub fn disable_pointer_constraint(self) {
588        get!().disable_pointer_constraint(self)
589    }
590
591    /// Moves the currently focused workspace to another output.
592    pub fn move_to_output(self, connector: Connector) {
593        get!().move_to_output(WorkspaceSource::Seat(self), connector);
594    }
595
596    /// Set whether the current key event is forwarded to the focused client.
597    ///
598    /// This only has an effect if called from a keyboard shortcut.
599    ///
600    /// By default, release events are forwarded and press events are consumed. Note that
601    /// consuming release events can cause clients to get stuck in the pressed state.
602    pub fn set_forward(self, forward: bool) {
603        get!().set_forward(self, forward);
604    }
605
606    /// This is a shorthand for `set_forward(true)`.
607    pub fn forward(self) {
608        self.set_forward(true)
609    }
610
611    /// This is a shorthand for `set_forward(false)`.
612    pub fn consume(self) {
613        self.set_forward(false)
614    }
615
616    /// Sets the focus-follows-mouse mode.
617    pub fn set_focus_follows_mouse_mode(self, mode: FocusFollowsMouseMode) {
618        get!().set_focus_follows_mouse_mode(self, mode);
619    }
620
621    /// Sets the fallback output mode.
622    ///
623    /// The default is `Cursor`.
624    pub fn set_fallback_output_mode(self, mode: FallbackOutputMode) {
625        get!().set_fallback_output_mode(self, mode.to_private());
626    }
627
628    /// Enables or disable window management mode.
629    ///
630    /// In window management mode, floating windows can be moved by pressing the left
631    /// mouse button and all windows can be resize by pressing the right mouse button.
632    pub fn set_window_management_enabled(self, enabled: bool) {
633        get!().set_window_management_enabled(self, enabled);
634    }
635
636    /// Sets a key that enables window management mode while pressed.
637    ///
638    /// This is a shorthand for
639    ///
640    /// ```rust,ignore
641    /// self.bind(mod_sym, move || {
642    ///     self.set_window_management_enabled(true);
643    ///     self.forward();
644    ///     self.latch(move || {
645    ///         self.set_window_management_enabled(false);
646    ///     });
647    /// });
648    /// ```
649    pub fn set_window_management_key<T: Into<ModifiedKeySym>>(self, mod_sym: T) {
650        self.bind(mod_sym, move || {
651            self.set_window_management_enabled(true);
652            self.forward();
653            self.latch(move || {
654                self.set_window_management_enabled(false);
655            });
656        });
657    }
658
659    /// Gets whether the currently focused window is pinned.
660    ///
661    /// If a floating window is pinned, it will stay visible even when switching to a
662    /// different workspace.
663    pub fn float_pinned(self) -> bool {
664        get!().get_pinned(self)
665    }
666
667    /// Sets whether the currently focused window is pinned.
668    pub fn set_float_pinned(self, pinned: bool) {
669        get!().set_pinned(self, pinned);
670    }
671
672    /// Toggles whether the currently focused window is pinned.
673    pub fn toggle_float_pinned(self) {
674        self.set_float_pinned(!self.float_pinned());
675    }
676
677    /// Returns the focused window.
678    ///
679    /// If no window is focused, [`Window::exists`] returns false.
680    pub fn window(self) -> Window {
681        get!(Window(0)).get_seat_keyboard_window(self)
682    }
683
684    /// Puts the keyboard focus on the window.
685    ///
686    /// This has no effect if the window is not visible.
687    pub fn focus_window(self, window: Window) {
688        get!().focus_window(self, window)
689    }
690
691    /// Sets the key that can be used to revert the pointer to the default state.
692    ///
693    /// Pressing this key cancels any grabs, drags, selections, etc.
694    ///
695    /// The default is `SYM_Escape`. Setting this to `SYM_NoSymbol` effectively disables
696    /// this functionality.
697    pub fn set_pointer_revert_key(self, sym: KeySym) {
698        get!().set_pointer_revert_key(self, sym);
699    }
700
701    /// Creates a mark for the currently focused window.
702    ///
703    /// `kc` should be an evdev keycode. If `kc` is none, then the keycode will be
704    /// inferred from the next key press. Pressing escape during this interactive
705    /// selection aborts the process.
706    ///
707    /// Currently very few `u32` are valid keycodes. Large numbers can therefore be used
708    /// to create marks that do not correspond to a key. However, `kc` should always be
709    /// less than `u32::MAX - 8`.
710    pub fn create_mark(self, kc: Option<u32>) {
711        get!().seat_create_mark(self, kc);
712    }
713
714    /// Moves the keyboard focus to a window identified by a mark.
715    ///
716    /// See [`Seat::create_mark`] for information about the `kc` parameter.
717    pub fn jump_to_mark(self, kc: Option<u32>) {
718        get!().seat_jump_to_mark(self, kc);
719    }
720
721    /// Copies a mark from one keycode to another.
722    ///
723    /// If the `src` keycode identifies a mark before this function is called, the `dst`
724    /// keycode will identify the same mark afterwards.
725    pub fn copy_mark(self, src: u32, dst: u32) {
726        get!().seat_copy_mark(self, src, dst);
727    }
728
729    /// Sets whether the simple, XCompose based input method is enabled.
730    ///
731    /// Regardless of this setting, this input method is not used if an external input
732    /// method is running.
733    ///
734    /// The default is `true`.
735    pub fn set_simple_im_enabled(self, enabled: bool) {
736        get!().seat_set_simple_im_enabled(self, enabled);
737    }
738
739    /// Returns whether the simple, XCompose based input method is enabled.
740    pub fn simple_im_enabled(self) -> bool {
741        get!(true).seat_get_simple_im_enabled(self)
742    }
743
744    /// Toggles whether the simple, XCompose based input method is enabled.
745    pub fn toggle_simple_im_enabled(self) {
746        let get = get!();
747        get.seat_set_simple_im_enabled(self, !get.seat_get_simple_im_enabled(self));
748    }
749
750    /// Reloads the simple, XCompose based input method.
751    ///
752    /// This is useful if you change the XCompose files after starting the compositor.
753    pub fn reload_simple_im(self) {
754        get!().seat_reload_simple_im(self);
755    }
756
757    /// Enables Unicode input in the simple, XCompose based input method.
758    ///
759    /// This has no effect if the simple IM is not currently active.
760    pub fn enable_unicode_input(self) {
761        get!().seat_enable_unicode_input(self);
762    }
763
764    /// Warps the cursor to the center of the currently focused window.
765    pub fn warp_mouse_to_focus(self) {
766        get!().seat_warp_mouse_to_focus(self)
767    }
768
769    /// Resizes the focused window.
770    pub fn resize(self, dx1: i32, dy1: i32, dx2: i32, dy2: i32) {
771        self.window().resize(dx1, dy1, dx2, dy2);
772    }
773
774    /// Sets whether the cursor should automatically move to the center of a window
775    /// when focus changes via keyboard commands (move-left, focus-right, show-workspace, etc.).
776    ///
777    /// The default is `false`.
778    #[deprecated = "This setting is unstable and might be removed in the future"]
779    pub fn unstable_set_mouse_follows_focus(self, enabled: bool) {
780        get!().seat_set_mouse_follows_focus(self, enabled)
781    }
782
783    /// Returns the output that contains the seat's cursor.
784    ///
785    /// If no such connector exists, `exists` returns `false` for the returned connector.
786    pub fn get_cursor_connector(self) -> Connector {
787        get!(Connector(0)).get_seat_cursor_connector(self)
788    }
789
790    /// Returns the output that contains the seat's keyboard focus.
791    ///
792    /// If no such connector exists, `exists` returns `false` for the returned connector.
793    pub fn get_keyboard_connector(self) -> Connector {
794        get!(Connector(0)).get_seat_keyboard_connector(self)
795    }
796}
797
798/// A focus-follows-mouse mode.
799#[derive(Serialize, Deserialize, Copy, Clone, Debug, Hash, Eq, PartialEq)]
800pub enum FocusFollowsMouseMode {
801    /// When the mouse moves and enters a toplevel, that toplevel gets the keyboard focus.
802    True,
803    /// The keyboard focus changes only when clicking on a window or the previously
804    /// focused window becomes invisible.
805    False,
806}
807
808/// Defines which output is used when no particular output is specified.
809///
810/// This configures where to place a newly opened window or workspace, what window to focus when a
811/// window is closed, which workspace is moved with [`Seat::move_to_output`], and similar actions.
812#[derive(Serialize, Deserialize, Copy, Clone, Debug, Hash, Eq, PartialEq, PrivateEnum)]
813#[non_exhaustive]
814pub enum FallbackOutputMode {
815    /// Use the output the cursor is on.
816    Cursor,
817    /// Use the output the focus is on (highlighted window).
818    Focus,
819}
820
821/// Returns all seats.
822pub fn get_seats() -> Vec<Seat> {
823    get!().seats()
824}
825
826/// Returns all input devices.
827pub fn input_devices() -> Vec<InputDevice> {
828    get!().get_input_devices(None)
829}
830
831/// Returns or creates a seat.
832///
833/// Seats are identified by their name. If no seat with the name exists, a new seat will be created.
834///
835/// NOTE: You should prefer [`get_default_seat`] instead. Most applications cannot handle more than
836/// one seat and will only process input from one of the seats.
837pub fn get_seat(name: &str) -> Seat {
838    get!(Seat(0)).get_seat(name)
839}
840
841/// Returns or creates the default seat.
842///
843/// This is equivalent to `get_seat("default")`.
844pub fn get_default_seat() -> Seat {
845    get_seat(DEFAULT_SEAT_NAME)
846}
847
848/// Sets a closure to run when a new seat has been created.
849pub fn on_new_seat<F: FnMut(Seat) + 'static>(f: F) {
850    get!().on_new_seat(f)
851}
852
853/// Sets a closure to run when a new input device has been added.
854pub fn on_new_input_device<F: FnMut(InputDevice) + 'static>(f: F) {
855    get!().on_new_input_device(f)
856}
857
858/// Sets a closure to run when an input device has been removed.
859pub fn on_input_device_removed<F: FnMut(InputDevice) + 'static>(f: F) {
860    get!().on_input_device_removed(f)
861}
862
863/// Sets the maximum time between two clicks to be registered as a double click by the
864/// compositor.
865///
866/// This only affects interactions with the compositor UI and has no effect on
867/// applications.
868///
869/// The default is 400 ms.
870pub fn set_double_click_time(duration: Duration) {
871    let usec = duration.as_micros().min(u64::MAX as u128);
872    get!().set_double_click_interval(usec as u64)
873}
874
875/// Sets the maximum distance between two clicks to be registered as a double click by the
876/// compositor.
877///
878/// This only affects interactions with the compositor UI and has no effect on
879/// applications.
880///
881/// Setting a negative distance disables double clicks.
882///
883/// The default is 5.
884pub fn set_double_click_distance(distance: i32) {
885    get!().set_double_click_distance(distance)
886}
887
888/// Disables the creation of a default seat.
889///
890/// Unless this function is called at startup of the compositor, a seat called `default`
891/// will automatically be created.
892///
893/// When a new input device is attached and a seat called `default` exists, the input
894/// device is initially attached to this seat.
895pub fn disable_default_seat() {
896    get!().disable_default_seat();
897}
898
899/// An event generated by a switch.
900#[derive(Serialize, Deserialize, Copy, Clone, Debug, Hash, Eq, PartialEq)]
901pub enum SwitchEvent {
902    /// The lid of the device (usually a laptop) has been opened.
903    ///
904    /// This is the default state.
905    LidOpened,
906    /// The lid of the device (usually a laptop) has been closed.
907    ///
908    /// If the device is already in this state when the device is discovered, a synthetic
909    /// event of this kind is generated.
910    LidClosed,
911    /// The device has been converted from tablet to laptop mode.
912    ///
913    /// This is the default state.
914    ConvertedToLaptop,
915    /// The device has been converted from laptop to tablet mode.
916    ///
917    /// If the device is already in this state when the device is discovered, a synthetic
918    /// event of this kind is generated.
919    ConvertedToTablet,
920}
921
922/// Enables or disables the unauthenticated libei socket.
923///
924/// Even if the socket is disabled, application can still request access via the portal.
925///
926/// The default is `false`.
927pub fn set_libei_socket_enabled(enabled: bool) {
928    get!().set_ei_socket_enabled(enabled);
929}
930
931#[derive(Serialize, Deserialize, Copy, Clone, Debug, Hash, Eq, PartialEq)]
932pub struct InputEventCode(pub u32);
933
934impl InputEventCode {
935    pub const NONE: Self = Self(0);
936}