jay_config/keyboard/
mod.rs

1//! Tools affecting the keyboard behavior.
2
3use {
4    crate::keyboard::{mods::Modifiers, syms::KeySym},
5    serde::{Deserialize, Serialize},
6    std::ops::{BitOr, BitOrAssign},
7};
8
9pub mod mods;
10pub mod syms;
11
12/// A keysym with zero or more modifiers
13#[derive(Serialize, Deserialize, Copy, Clone, Eq, PartialEq, Hash, Debug)]
14pub struct ModifiedKeySym {
15    pub mods: Modifiers,
16    pub sym: KeySym,
17}
18
19impl From<KeySym> for ModifiedKeySym {
20    fn from(sym: KeySym) -> Self {
21        Self {
22            mods: Modifiers(0),
23            sym,
24        }
25    }
26}
27
28impl BitOr<Modifiers> for ModifiedKeySym {
29    type Output = ModifiedKeySym;
30
31    fn bitor(self, rhs: Modifiers) -> Self::Output {
32        ModifiedKeySym {
33            mods: self.mods | rhs,
34            sym: self.sym,
35        }
36    }
37}
38
39impl BitOrAssign<Modifiers> for ModifiedKeySym {
40    fn bitor_assign(&mut self, rhs: Modifiers) {
41        self.mods |= rhs;
42    }
43}
44
45/// A keymap.
46#[derive(Serialize, Deserialize, Copy, Clone, Debug, Eq, PartialEq, Hash)]
47pub struct Keymap(pub u64);
48
49impl Keymap {
50    /// The invalid keymap.
51    pub const INVALID: Self = Self(0);
52
53    /// Returns whether this keymap is valid.
54    pub fn is_valid(self) -> bool {
55        self != Self::INVALID
56    }
57
58    /// Returns whether this keymap is invalid.
59    pub fn is_invalid(self) -> bool {
60        self == Self::INVALID
61    }
62
63    /// Destroys this reference to the keymap.
64    ///
65    /// Seats that are currently using this keymap are unaffected.
66    pub fn destroy(self) {
67        if self.is_valid() {
68            get!().destroy_keymap(self);
69        }
70    }
71}
72
73/// Parses a keymap.
74///
75/// The returned keymap can later be used to set the keymap of a seat. If the keymap cannot
76/// be parsed, returns an invalid keymap. Trying to set a seat's keymap to an invalid keymap
77/// has no effect.
78///
79/// A simple keymap looks as follows:
80///
81/// ```text
82/// xkb_keymap {
83///     xkb_keycodes  { include "evdev+aliases(qwerty)" };
84///     xkb_types     { include "complete" };
85///     xkb_compat    { include "complete" };
86///     xkb_symbols   { include "pc+inet(evdev)+us(basic)" };
87/// };
88/// ```
89///
90/// To use a programmer Dvorak, replace the corresponding line by
91///
92/// ```text
93///     xkb_symbols   { include "pc+inet(evdev)+us(dvp)" };
94/// ```
95///
96/// To use a German keymap, replace the corresponding line by
97///
98/// ```text
99///     xkb_symbols   { include "pc+inet(evdev)+de(basic)" };
100/// ```
101///
102/// You can also use a completely custom keymap that doesn't use any includes. See the
103/// [default][default] Jay keymap for an example.
104///
105/// General information about the keymap format can be found in the [arch wiki][wiki].
106///
107/// [default]: https://github.com/mahkoh/jay/tree/master/src/keymap.xkb
108/// [wiki]: https://wiki.archlinux.org/title/X_keyboard_extension
109pub fn parse_keymap(keymap: &str) -> Keymap {
110    get!(Keymap::INVALID).parse_keymap(keymap)
111}