Skip to content

Commit e16071f

Browse files
committed
config: Move key binding code to a seperate file
1 parent 3df9f4b commit e16071f

File tree

2 files changed

+301
-277
lines changed

2 files changed

+301
-277
lines changed

src/config/key_bindings.rs

Lines changed: 295 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,295 @@
1+
// SPDX-License-Identifier: GPL-3.0-only
2+
3+
use crate::shell::{
4+
focus::FocusDirection, grabs::ResizeEdge, layout::tiling::Direction, ResizeDirection,
5+
};
6+
use serde::Deserialize;
7+
use smithay::{
8+
backend::input::KeyState,
9+
input::keyboard::{keysyms as KeySyms, xkb::keysym_get_name, ModifiersState},
10+
};
11+
use std::collections::HashMap;
12+
13+
use super::{types::*, WorkspaceLayout};
14+
15+
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
16+
pub enum KeyModifier {
17+
Ctrl,
18+
Alt,
19+
Shift,
20+
Super,
21+
}
22+
23+
#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
24+
pub struct KeyModifiers {
25+
pub ctrl: bool,
26+
pub alt: bool,
27+
pub shift: bool,
28+
pub logo: bool,
29+
}
30+
31+
impl PartialEq<ModifiersState> for KeyModifiers {
32+
fn eq(&self, other: &ModifiersState) -> bool {
33+
self.ctrl == other.ctrl
34+
&& self.alt == other.alt
35+
&& self.shift == other.shift
36+
&& self.logo == other.logo
37+
}
38+
}
39+
40+
impl Into<KeyModifiers> for ModifiersState {
41+
fn into(self) -> KeyModifiers {
42+
KeyModifiers {
43+
ctrl: self.ctrl,
44+
alt: self.alt,
45+
shift: self.shift,
46+
logo: self.logo,
47+
}
48+
}
49+
}
50+
51+
impl std::ops::AddAssign<KeyModifier> for KeyModifiers {
52+
fn add_assign(&mut self, rhs: KeyModifier) {
53+
match rhs {
54+
KeyModifier::Ctrl => self.ctrl = true,
55+
KeyModifier::Alt => self.alt = true,
56+
KeyModifier::Shift => self.shift = true,
57+
KeyModifier::Super => self.logo = true,
58+
};
59+
}
60+
}
61+
62+
impl std::ops::BitOr for KeyModifier {
63+
type Output = KeyModifiers;
64+
65+
fn bitor(self, rhs: KeyModifier) -> Self::Output {
66+
let mut modifiers = self.into();
67+
modifiers += rhs;
68+
modifiers
69+
}
70+
}
71+
72+
impl Into<KeyModifiers> for KeyModifier {
73+
fn into(self) -> KeyModifiers {
74+
let mut modifiers = KeyModifiers {
75+
ctrl: false,
76+
alt: false,
77+
shift: false,
78+
logo: false,
79+
};
80+
modifiers += self;
81+
modifiers
82+
}
83+
}
84+
85+
/// Describtion of a key combination that might be
86+
/// handled by the compositor.
87+
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Hash)]
88+
#[serde(deny_unknown_fields)]
89+
pub struct KeyPattern {
90+
/// What modifiers are expected to be pressed alongside the key
91+
#[serde(deserialize_with = "deserialize_KeyModifiers")]
92+
pub modifiers: KeyModifiers,
93+
/// The actual key, that was pressed
94+
#[serde(deserialize_with = "deserialize_Keysym")]
95+
pub key: u32,
96+
}
97+
98+
impl KeyPattern {
99+
pub fn new(modifiers: impl Into<KeyModifiers>, key: u32) -> KeyPattern {
100+
KeyPattern {
101+
modifiers: modifiers.into(),
102+
key,
103+
}
104+
}
105+
}
106+
107+
impl ToString for KeyPattern {
108+
fn to_string(&self) -> String {
109+
let mut result = String::new();
110+
if self.modifiers.logo {
111+
result += "Super+";
112+
}
113+
if self.modifiers.ctrl {
114+
result += "Ctrl+";
115+
}
116+
if self.modifiers.alt {
117+
result += "Alt+";
118+
}
119+
if self.modifiers.shift {
120+
result += "Shift+";
121+
}
122+
result += &keysym_get_name(self.key);
123+
result
124+
}
125+
}
126+
127+
#[derive(Debug, Deserialize, Clone, PartialEq, Eq)]
128+
pub enum Action {
129+
Terminate,
130+
Debug,
131+
Close,
132+
133+
Workspace(u8),
134+
NextWorkspace,
135+
PreviousWorkspace,
136+
LastWorkspace,
137+
MoveToWorkspace(u8),
138+
MoveToNextWorkspace,
139+
MoveToPreviousWorkspace,
140+
MoveToLastWorkspace,
141+
SendToWorkspace(u8),
142+
SendToNextWorkspace,
143+
SendToPreviousWorkspace,
144+
SendToLastWorkspace,
145+
146+
NextOutput,
147+
PreviousOutput,
148+
MoveToNextOutput,
149+
MoveToPreviousOutput,
150+
SendToNextOutput,
151+
SendToPreviousOutput,
152+
153+
Focus(FocusDirection),
154+
Move(Direction),
155+
156+
ToggleOrientation,
157+
Orientation(crate::shell::layout::Orientation),
158+
159+
ToggleStacking,
160+
161+
ToggleTiling,
162+
ToggleWindowFloating,
163+
164+
Resizing(ResizeDirection),
165+
#[serde(skip)]
166+
_ResizingInternal(ResizeDirection, ResizeEdge, KeyState),
167+
Maximize,
168+
Spawn(String),
169+
}
170+
171+
fn insert_binding(
172+
key_bindings: &mut HashMap<KeyPattern, Action>,
173+
modifiers: KeyModifiers,
174+
keys: impl Iterator<Item = u32>,
175+
action: Action,
176+
) {
177+
if !key_bindings.values().any(|a| a == &action) {
178+
for key in keys {
179+
let pattern = KeyPattern {
180+
modifiers: modifiers.clone(),
181+
key,
182+
};
183+
if !key_bindings.contains_key(&pattern) {
184+
key_bindings.insert(pattern, action.clone());
185+
}
186+
}
187+
}
188+
}
189+
190+
pub fn add_default_bindings(
191+
key_bindings: &mut HashMap<KeyPattern, Action>,
192+
workspace_layout: WorkspaceLayout,
193+
) {
194+
let (workspace_previous, workspace_next, output_previous, output_next) = match workspace_layout
195+
{
196+
WorkspaceLayout::Horizontal => (
197+
[KeySyms::KEY_Left, KeySyms::KEY_h],
198+
[KeySyms::KEY_Right, KeySyms::KEY_j],
199+
[KeySyms::KEY_Up, KeySyms::KEY_k],
200+
[KeySyms::KEY_Down, KeySyms::KEY_j],
201+
),
202+
WorkspaceLayout::Vertical => (
203+
[KeySyms::KEY_Up, KeySyms::KEY_k],
204+
[KeySyms::KEY_Down, KeySyms::KEY_j],
205+
[KeySyms::KEY_Left, KeySyms::KEY_h],
206+
[KeySyms::KEY_Right, KeySyms::KEY_j],
207+
),
208+
};
209+
210+
insert_binding(
211+
key_bindings,
212+
KeyModifiers {
213+
logo: true,
214+
ctrl: true,
215+
..Default::default()
216+
},
217+
workspace_previous.iter().copied(),
218+
Action::PreviousWorkspace,
219+
);
220+
insert_binding(
221+
key_bindings,
222+
KeyModifiers {
223+
logo: true,
224+
ctrl: true,
225+
..Default::default()
226+
},
227+
workspace_next.iter().copied(),
228+
Action::NextWorkspace,
229+
);
230+
insert_binding(
231+
key_bindings,
232+
KeyModifiers {
233+
logo: true,
234+
ctrl: true,
235+
shift: true,
236+
..Default::default()
237+
},
238+
workspace_previous.iter().copied(),
239+
Action::MoveToPreviousWorkspace,
240+
);
241+
insert_binding(
242+
key_bindings,
243+
KeyModifiers {
244+
logo: true,
245+
ctrl: true,
246+
shift: true,
247+
..Default::default()
248+
},
249+
workspace_next.iter().copied(),
250+
Action::MoveToNextWorkspace,
251+
);
252+
253+
insert_binding(
254+
key_bindings,
255+
KeyModifiers {
256+
logo: true,
257+
ctrl: true,
258+
..Default::default()
259+
},
260+
output_previous.iter().copied(),
261+
Action::PreviousOutput,
262+
);
263+
insert_binding(
264+
key_bindings,
265+
KeyModifiers {
266+
logo: true,
267+
ctrl: true,
268+
..Default::default()
269+
},
270+
output_next.iter().copied(),
271+
Action::NextOutput,
272+
);
273+
insert_binding(
274+
key_bindings,
275+
KeyModifiers {
276+
logo: true,
277+
ctrl: true,
278+
shift: true,
279+
..Default::default()
280+
},
281+
output_previous.iter().copied(),
282+
Action::MoveToPreviousOutput,
283+
);
284+
insert_binding(
285+
key_bindings,
286+
KeyModifiers {
287+
logo: true,
288+
ctrl: true,
289+
shift: true,
290+
..Default::default()
291+
},
292+
output_next.iter().copied(),
293+
Action::MoveToNextOutput,
294+
);
295+
}

0 commit comments

Comments
 (0)