leftwm_core/utils/
modmask_lookup.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
use bitflags::bitflags;
use serde::{de::Visitor, Deserialize, Serialize};

bitflags! {
    /// Represents the state of modifier keys
    #[derive(Clone, Debug, PartialEq, Eq)]
    pub struct ModMask: u16 {
        /// Used as the zero value
        const Zero = 0;
        const Any = 1;
        const Shift = 1 << 1;
        const Control = 1 << 2;
        /// Mod1
        const Alt = 1 << 3;
        /// Mod2
        const NumLock = 1 << 4;
        const Mod3 = 1 << 5;
        /// Mod4
        const Super = 1 << 6;
        const Mod5 = 1 << 7;
    }
}

/// Representation of mouse buttons
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq)]
pub enum Button {
    /// no buttons pressed
    None,
    /// Main button (left click for right-handed)
    /// Button1
    Main,
    /// Middle button (pressing the scroll wheel)
    /// Button2
    Middle,
    /// Secondary button (right click for right-handed)
    /// Button3
    Secondary,
    /// Scroll wheel up
    /// Button4
    ScrollUp,
    /// Scroll wheel down
    /// Button5
    ScrollDown,
}

impl From<u8> for Button {
    fn from(value: u8) -> Self {
        match value {
            1 => Self::Main,
            2 => Self::Middle,
            3 => Self::Secondary,
            4 => Self::ScrollUp,
            5 => Self::ScrollDown,
            _ => Self::None,
        }
    }
}

impl From<Button> for u8 {
    fn from(value: Button) -> Self {
        match value {
            Button::None => 0,
            Button::Main => 1,
            Button::Middle => 2,
            Button::Secondary => 3,
            Button::ScrollUp => 4,
            Button::ScrollDown => 5,
        }
    }
}

#[must_use]
pub fn into_modmask(keys: &[String]) -> ModMask {
    let mut mask = ModMask::Zero;
    for s in keys {
        mask |= into_mod(s);
    }
    // clean the mask
    mask.remove(ModMask::NumLock);
    mask.intersection(
        ModMask::Shift
            | ModMask::Control
            | ModMask::Alt
            | ModMask::Mod3
            | ModMask::Super
            | ModMask::Mod5,
    )
}

#[must_use]
pub fn into_mod(key: &str) -> ModMask {
    match key {
        "None" => ModMask::Any,
        "Shift" => ModMask::Shift,
        "Control" => ModMask::Control,
        "Mod1" | "Alt" => ModMask::Alt,
        // NOTE: we are ignoring the state of Numlock
        // this is left here as a reminder
        // "Mod2" | "NumLock" => ModMask::NumLock,
        "Mod3" => ModMask::Mod3,
        "Mod4" | "Super" => ModMask::Super,
        "Mod5" => ModMask::Mod5,
        _ => ModMask::Zero,
    }
}

// serde impls (derive is not working with the bitflags macro)

impl Serialize for ModMask {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        serializer.serialize_u16(self.bits())
    }
}

impl<'de> Deserialize<'de> for ModMask {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        struct ModmaskVisitor;

        impl<'de> Visitor<'de> for ModmaskVisitor {
            type Value = ModMask;

            fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
                formatter.write_str("a bitfield on 8 bits")
            }

            fn visit_u8<E>(self, v: u8) -> Result<Self::Value, E>
            where
                E: serde::de::Error,
            {
                Ok(ModMask::from_bits_retain(u16::from(v)))
            }

            fn visit_u16<E>(self, v: u16) -> Result<Self::Value, E>
            where
                E: serde::de::Error,
            {
                Ok(ModMask::from_bits_retain(v))
            }
        }

        deserializer.deserialize_u16(ModmaskVisitor)
    }
}