1use serde::Serialize;
30
31#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
46pub enum Modifier {
47 Alt,
49 AltLeft,
51 AltRight,
53 Shift,
55 ShiftLeft,
57 ShiftRight,
59 Sym,
61 Function,
63 Ctrl,
65 CtrlLeft,
67 CtrlRight,
69 Meta,
72 MetaLeft,
74 MetaRight,
76 CapsLock,
78 NumLock,
80 ScrollLock,
82 Primary,
86}
87
88impl Modifier {
89 pub fn as_str(self) -> &'static str {
91 match self {
92 Self::Alt => "alt",
93 Self::AltLeft => "alt_left",
94 Self::AltRight => "alt_right",
95 Self::Shift => "shift",
96 Self::ShiftLeft => "shift_left",
97 Self::ShiftRight => "shift_right",
98 Self::Sym => "sym",
99 Self::Function => "function",
100 Self::Ctrl => "ctrl",
101 Self::CtrlLeft => "ctrl_left",
102 Self::CtrlRight => "ctrl_right",
103 Self::Meta => "meta",
104 Self::MetaLeft => "meta_left",
105 Self::MetaRight => "meta_right",
106 Self::CapsLock => "caps_lock",
107 Self::NumLock => "num_lock",
108 Self::ScrollLock => "scroll_lock",
109 Self::Primary => "primary",
110 }
111 }
112}
113
114impl Serialize for Modifier {
115 fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
116 s.serialize_str(self.as_str())
117 }
118}
119
120#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
128pub enum BindingAction {
129 #[default]
131 Down,
132 Up,
134 Repeat,
136}
137
138impl BindingAction {
139 pub fn as_str(self) -> &'static str {
141 match self {
142 Self::Down => "down",
143 Self::Up => "up",
144 Self::Repeat => "repeat",
145 }
146 }
147}
148
149impl Serialize for BindingAction {
150 fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
151 s.serialize_str(self.as_str())
152 }
153}
154
155#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
166pub struct Key(pub String);
167
168impl Key {
169 pub fn new(name: impl Into<String>) -> Self {
171 Self(name.into())
172 }
173}
174
175impl<S: Into<String>> From<S> for Key {
176 fn from(s: S) -> Self {
177 Self(s.into())
178 }
179}
180
181impl Serialize for Key {
182 fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
183 s.serialize_str(&self.0)
184 }
185}
186
187#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, Serialize)]
191#[serde(rename_all = "snake_case")]
192pub enum Handedness {
193 #[default]
194 Right,
195 Left,
196}
197
198#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, Serialize)]
202#[serde(rename_all = "snake_case")]
203pub enum PointerAcceleration {
204 Adaptive,
205 #[default]
206 None,
207}
208
209#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, Serialize)]
213#[serde(rename_all = "snake_case")]
214pub enum CursorFocusMode {
215 #[default]
216 Hover,
217 Click,
218}
219
220#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, Serialize)]
224#[serde(rename_all = "snake_case")]
225pub enum TouchpadClickMode {
226 #[default]
227 None,
228 AreaToClick,
229 FingerCount,
230}
231
232#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, Serialize)]
236#[serde(rename_all = "snake_case")]
237pub enum TouchpadScrollMode {
238 #[default]
239 None,
240 TwoFingerScroll,
241 EdgeScroll,
242 ButtonDownScroll,
243}
244
245#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, Serialize)]
249#[serde(rename_all = "snake_case")]
250pub enum AnimationPartType {
251 #[default]
252 Disabled,
253 Slide,
254 Grow,
255 Shrink,
256 Fade,
257}
258
259#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, Serialize)]
263#[serde(rename_all = "snake_case")]
264pub enum EasingFunction {
265 #[default]
266 Linear,
267 EaseInSine,
268 EaseOutSine,
269 EaseInOutSine,
270 EaseInQuad,
271 EaseOutQuad,
272 EaseInOutQuad,
273 EaseInCubic,
274 EaseOutCubic,
275 EaseInOutCubic,
276 EaseInQuart,
277 EaseOutQuart,
278 EaseInOutQuart,
279 EaseInQuint,
280 EaseOutQuint,
281 EaseInOutQuint,
282 EaseInExpo,
283 EaseOutExpo,
284 EaseInOutExpo,
285 EaseInCirc,
286 EaseOutCirc,
287 EaseInOutCirc,
288 EaseInBack,
289 EaseOutBack,
290 EaseInOutBack,
291 EaseInElastic,
292 EaseOutElastic,
293 EaseInOutElastic,
294 EaseInBounce,
295 EaseOutBounce,
296 EaseInOutBounce,
297}
298
299#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, Serialize)]
303#[serde(rename_all = "snake_case")]
304pub enum AnimationEvent {
305 #[default]
306 WindowOpen,
307 WindowMove,
308 WindowClose,
309 WorkspaceSwitch,
310}
311
312#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, Serialize)]
316#[serde(rename_all = "snake_case")]
317pub enum AnimationKind {
318 #[default]
319 BuiltIn,
320 Plugin,
321}
322
323#[derive(Debug, Clone, Default, Serialize)]
327pub struct Gaps {
328 pub x: i32,
329 pub y: i32,
330}
331
332#[derive(Debug, Clone, Serialize)]
334pub struct CustomKeyAction {
335 pub action: BindingAction,
337 pub modifiers: Vec<Modifier>,
339 pub key: Key,
341 pub command: String,
343 #[serde(skip_serializing_if = "is_false")]
346 pub allow_on_lockscreen: bool,
347}
348
349#[derive(Debug, Clone, Serialize)]
351pub struct BuiltInKeyCommandOverride {
352 pub name: String,
354 pub action: BindingAction,
356 pub modifiers: Vec<Modifier>,
358 pub key: Key,
360}
361
362#[derive(Debug, Clone, Default, Serialize)]
364pub struct StartupApp {
365 pub command: String,
366 #[serde(skip_serializing_if = "is_false")]
367 pub restart_on_death: bool,
368 #[serde(skip_serializing_if = "is_false")]
369 pub no_startup_id: bool,
370 #[serde(skip_serializing_if = "is_false")]
371 pub should_halt_compositor_on_death: bool,
372 #[serde(skip_serializing_if = "is_false")]
373 pub in_systemd_scope: bool,
374}
375
376#[derive(Debug, Clone, Default, Serialize)]
378pub struct EnvironmentVariable {
379 pub key: String,
380 pub value: String,
381}
382
383#[derive(Debug, Clone, Default, Serialize)]
389pub struct BorderConfig {
390 pub size: i32,
391 pub radius: f32,
392 pub color: String,
394 pub focus_color: String,
396}
397
398#[derive(Debug, Clone, Default, Serialize)]
400pub struct WorkspaceConfig {
401 #[serde(skip_serializing_if = "Option::is_none")]
402 pub number: Option<i32>,
403 #[serde(skip_serializing_if = "Option::is_none")]
404 pub name: Option<String>,
405}
406
407#[derive(Debug, Clone, Serialize)]
409pub struct DragAndDropConfiguration {
410 pub enabled: bool,
411 #[serde(skip_serializing_if = "Vec::is_empty")]
413 pub modifiers: Vec<Modifier>,
414}
415
416impl Default for DragAndDropConfiguration {
417 fn default() -> Self {
418 Self {
419 enabled: true,
420 modifiers: Vec::new(),
421 }
422 }
423}
424
425#[derive(Debug, Clone, Default, Serialize)]
427pub struct BuiltInAnimationPart {
428 #[serde(rename = "type")]
430 pub type_: AnimationPartType,
431 pub function: EasingFunction,
433 #[serde(skip_serializing_if = "Option::is_none")]
434 pub c1: Option<f32>,
435 #[serde(skip_serializing_if = "Option::is_none")]
436 pub c2: Option<f32>,
437 #[serde(skip_serializing_if = "Option::is_none")]
438 pub c3: Option<f32>,
439 #[serde(skip_serializing_if = "Option::is_none")]
440 pub c4: Option<f32>,
441 #[serde(skip_serializing_if = "Option::is_none")]
442 pub c5: Option<f32>,
443 #[serde(skip_serializing_if = "Option::is_none")]
444 pub n1: Option<f32>,
445 #[serde(skip_serializing_if = "Option::is_none")]
446 pub d1: Option<f32>,
447 #[serde(skip_serializing_if = "Option::is_none")]
454 pub scale: Option<f32>,
455}
456
457#[derive(Debug, Clone, Default, Serialize)]
459pub struct AnimationDefinition {
460 pub event: AnimationEvent,
462 #[serde(rename = "type")]
464 pub type_: AnimationKind,
465 #[serde(skip_serializing_if = "Option::is_none")]
467 pub duration: Option<f32>,
468 #[serde(skip_serializing_if = "Vec::is_empty")]
470 pub parts: Vec<BuiltInAnimationPart>,
471}
472
473#[derive(Debug, Clone, Default, Serialize)]
475pub struct MouseConfiguration {
476 #[serde(skip_serializing_if = "Option::is_none")]
478 pub handedness: Option<Handedness>,
479 #[serde(skip_serializing_if = "Option::is_none")]
481 pub acceleration: Option<PointerAcceleration>,
482 #[serde(skip_serializing_if = "Option::is_none")]
483 pub acceleration_bias: Option<f64>,
484 #[serde(skip_serializing_if = "Option::is_none")]
485 pub vscroll_speed: Option<f64>,
486 #[serde(skip_serializing_if = "Option::is_none")]
487 pub hscroll_speed: Option<f64>,
488}
489
490#[derive(Debug, Clone, Default, Serialize)]
492pub struct KeymapConfiguration {
493 pub language: String,
494 #[serde(skip_serializing_if = "Option::is_none")]
495 pub variant: Option<String>,
496 #[serde(skip_serializing_if = "Vec::is_empty")]
497 pub options: Vec<String>,
498}
499
500#[derive(Debug, Clone, Default, Serialize)]
502pub struct KeyboardConfiguration {
503 #[serde(skip_serializing_if = "Option::is_none")]
504 pub repeat_delay: Option<i32>,
505 #[serde(skip_serializing_if = "Option::is_none")]
506 pub repeat_rate: Option<i32>,
507 #[serde(skip_serializing_if = "Option::is_none")]
508 pub keymap: Option<KeymapConfiguration>,
509}
510
511#[derive(Debug, Clone, Default, Serialize)]
513pub struct HoverClickConfiguration {
514 pub enabled: bool,
515 #[serde(skip_serializing_if = "Option::is_none", rename = "hover_duration")]
517 pub hover_duration_ms: Option<u32>,
518 #[serde(skip_serializing_if = "Option::is_none")]
519 pub cancel_displacement_threshold: Option<i32>,
520 #[serde(skip_serializing_if = "Option::is_none")]
521 pub reclick_displacement_threshold: Option<i32>,
522}
523
524#[derive(Debug, Clone, Default, Serialize)]
526pub struct SimulatedSecondaryClickConfiguration {
527 pub enabled: bool,
528 #[serde(skip_serializing_if = "Option::is_none", rename = "hold_duration")]
530 pub hold_duration_ms: Option<u32>,
531 #[serde(skip_serializing_if = "Option::is_none")]
532 pub displacement_threshold: Option<i32>,
533}
534
535#[derive(Debug, Clone, Default, Serialize)]
537pub struct OutputFilterConfiguration {
538 #[serde(skip_serializing_if = "Option::is_none")]
539 pub shader_path: Option<String>,
540}
541
542#[derive(Debug, Clone, Default, Serialize)]
544pub struct CursorConfiguration {
545 #[serde(skip_serializing_if = "Option::is_none")]
546 pub scale: Option<f32>,
547 #[serde(skip_serializing_if = "Option::is_none")]
549 pub focus_mode: Option<CursorFocusMode>,
550}
551
552#[derive(Debug, Clone, Default, Serialize)]
554pub struct SlowKeysConfiguration {
555 pub enabled: bool,
556 #[serde(skip_serializing_if = "Option::is_none", rename = "hold_delay")]
558 pub hold_delay_ms: Option<u32>,
559}
560
561#[derive(Debug, Clone, Default, Serialize)]
563pub struct StickyKeysConfiguration {
564 pub enabled: bool,
565 #[serde(skip_serializing_if = "Option::is_none")]
566 pub should_disable_if_two_keys_are_pressed_together: Option<bool>,
567}
568
569#[derive(Debug, Clone, Default, Serialize)]
571pub struct TouchpadConfiguration {
572 #[serde(skip_serializing_if = "Option::is_none")]
573 pub disable_while_typing: Option<bool>,
574 #[serde(skip_serializing_if = "Option::is_none")]
575 pub disable_with_external_mouse: Option<bool>,
576 #[serde(skip_serializing_if = "Option::is_none")]
577 pub acceleration_bias: Option<f64>,
578 #[serde(skip_serializing_if = "Option::is_none")]
579 pub vscroll_speed: Option<f64>,
580 #[serde(skip_serializing_if = "Option::is_none")]
581 pub hscroll_speed: Option<f64>,
582 #[serde(skip_serializing_if = "Option::is_none")]
583 pub tap_to_click: Option<bool>,
584 #[serde(skip_serializing_if = "Option::is_none")]
585 pub middle_mouse_button_emulation: Option<bool>,
586 #[serde(skip_serializing_if = "Option::is_none")]
588 pub click_mode: Option<TouchpadClickMode>,
589 #[serde(skip_serializing_if = "Option::is_none")]
591 pub scroll_mode: Option<TouchpadScrollMode>,
592}
593
594#[derive(Debug, Clone, Default, Serialize)]
596pub struct MagnifierConfiguration {
597 pub enabled: bool,
598 #[serde(skip_serializing_if = "Option::is_none")]
599 pub scale: Option<f32>,
600 #[serde(skip_serializing_if = "Option::is_none")]
601 pub scale_increment: Option<f32>,
602 #[serde(skip_serializing_if = "Option::is_none")]
603 pub width: Option<i32>,
604 #[serde(skip_serializing_if = "Option::is_none")]
605 pub height: Option<i32>,
606 #[serde(skip_serializing_if = "Option::is_none")]
607 pub size_increment: Option<i32>,
608}
609
610#[derive(Debug, Clone, Default, Serialize)]
619pub struct Configuration {
620 #[serde(skip_serializing_if = "Option::is_none", rename = "action_key")]
622 pub primary_modifier: Option<Modifier>,
623
624 #[serde(skip_serializing_if = "Option::is_none", rename = "custom_actions")]
626 pub custom_key_actions: Option<Vec<CustomKeyAction>>,
627
628 #[serde(skip_serializing_if = "Option::is_none")]
630 pub default_action_overrides: Option<Vec<BuiltInKeyCommandOverride>>,
631
632 #[serde(skip_serializing_if = "Option::is_none")]
634 pub inner_gaps: Option<Gaps>,
635
636 #[serde(skip_serializing_if = "Option::is_none")]
638 pub outer_gaps: Option<Gaps>,
639
640 #[serde(skip_serializing_if = "Option::is_none")]
642 pub startup_apps: Option<Vec<StartupApp>>,
643
644 #[serde(skip_serializing_if = "Option::is_none")]
646 pub terminal: Option<String>,
647
648 #[serde(skip_serializing_if = "Option::is_none")]
650 pub resize_jump: Option<i32>,
651
652 #[serde(skip_serializing_if = "Option::is_none")]
654 pub environment_variables: Option<Vec<EnvironmentVariable>>,
655
656 #[serde(skip_serializing_if = "Option::is_none")]
658 pub border: Option<BorderConfig>,
659
660 #[serde(skip_serializing_if = "Option::is_none")]
662 pub workspaces: Option<Vec<WorkspaceConfig>>,
663
664 #[serde(skip_serializing_if = "Option::is_none")]
666 pub animations: Option<Vec<AnimationDefinition>>,
667
668 #[serde(skip_serializing_if = "Option::is_none")]
670 pub enable_animations: Option<bool>,
671
672 #[serde(skip_serializing_if = "Option::is_none")]
675 pub move_modifier: Option<Vec<Modifier>>,
676
677 #[serde(skip_serializing_if = "Option::is_none")]
679 pub drag_and_drop: Option<DragAndDropConfiguration>,
680
681 #[serde(skip_serializing_if = "Option::is_none")]
683 pub mouse: Option<MouseConfiguration>,
684
685 #[serde(skip_serializing_if = "Option::is_none")]
687 pub touchpad: Option<TouchpadConfiguration>,
688
689 #[serde(skip_serializing_if = "Option::is_none")]
691 pub keyboard: Option<KeyboardConfiguration>,
692
693 #[serde(skip_serializing_if = "Option::is_none")]
695 pub hover_click: Option<HoverClickConfiguration>,
696
697 #[serde(skip_serializing_if = "Option::is_none")]
699 pub simulated_secondary_click: Option<SimulatedSecondaryClickConfiguration>,
700
701 #[serde(skip_serializing_if = "Option::is_none")]
703 pub output_filter: Option<OutputFilterConfiguration>,
704
705 #[serde(skip_serializing_if = "Option::is_none")]
707 pub cursor: Option<CursorConfiguration>,
708
709 #[serde(skip_serializing_if = "Option::is_none")]
711 pub slow_keys: Option<SlowKeysConfiguration>,
712
713 #[serde(skip_serializing_if = "Option::is_none")]
715 pub sticky_keys: Option<StickyKeysConfiguration>,
716
717 #[serde(skip_serializing_if = "Option::is_none")]
719 pub magnifier: Option<MagnifierConfiguration>,
720
721 #[serde(skip_serializing_if = "Option::is_none")]
723 pub workspace_back_and_forth: Option<bool>,
724
725 #[serde(skip_serializing_if = "Option::is_none")]
728 pub background_color: Option<String>,
729}
730
731fn is_false(v: &bool) -> bool {
732 !v
733}