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