1use serde::Serialize;
29
30#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
45pub enum Modifier {
46 Alt,
48 AltLeft,
50 AltRight,
52 Shift,
54 ShiftLeft,
56 ShiftRight,
58 Sym,
60 Function,
62 Ctrl,
64 CtrlLeft,
66 CtrlRight,
68 Meta,
71 MetaLeft,
73 MetaRight,
75 CapsLock,
77 NumLock,
79 ScrollLock,
81 Primary,
85}
86
87impl Modifier {
88 pub fn as_str(self) -> &'static str {
90 match self {
91 Self::Alt => "alt",
92 Self::AltLeft => "alt_left",
93 Self::AltRight => "alt_right",
94 Self::Shift => "shift",
95 Self::ShiftLeft => "shift_left",
96 Self::ShiftRight => "shift_right",
97 Self::Sym => "sym",
98 Self::Function => "function",
99 Self::Ctrl => "ctrl",
100 Self::CtrlLeft => "ctrl_left",
101 Self::CtrlRight => "ctrl_right",
102 Self::Meta => "meta",
103 Self::MetaLeft => "meta_left",
104 Self::MetaRight => "meta_right",
105 Self::CapsLock => "caps_lock",
106 Self::NumLock => "num_lock",
107 Self::ScrollLock => "scroll_lock",
108 Self::Primary => "primary",
109 }
110 }
111}
112
113impl Serialize for Modifier {
114 fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
115 s.serialize_str(self.as_str())
116 }
117}
118
119#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
127pub enum BindingAction {
128 #[default]
130 Down,
131 Up,
133 Repeat,
135}
136
137impl BindingAction {
138 pub fn as_str(self) -> &'static str {
140 match self {
141 Self::Down => "down",
142 Self::Up => "up",
143 Self::Repeat => "repeat",
144 }
145 }
146}
147
148impl Serialize for BindingAction {
149 fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
150 s.serialize_str(self.as_str())
151 }
152}
153
154#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
165pub struct Key(pub String);
166
167impl Key {
168 pub fn new(name: impl Into<String>) -> Self {
170 Self(name.into())
171 }
172}
173
174impl<S: Into<String>> From<S> for Key {
175 fn from(s: S) -> Self {
176 Self(s.into())
177 }
178}
179
180impl Serialize for Key {
181 fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
182 s.serialize_str(&self.0)
183 }
184}
185
186#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, Serialize)]
190#[serde(rename_all = "snake_case")]
191pub enum Handedness {
192 #[default]
193 Right,
194 Left,
195}
196
197#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, Serialize)]
201#[serde(rename_all = "snake_case")]
202pub enum PointerAcceleration {
203 Adaptive,
204 #[default]
205 None,
206}
207
208#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, Serialize)]
212#[serde(rename_all = "snake_case")]
213pub enum CursorFocusMode {
214 #[default]
215 Hover,
216 Click,
217}
218
219#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, Serialize)]
223#[serde(rename_all = "snake_case")]
224pub enum TouchpadClickMode {
225 #[default]
226 None,
227 AreaToClick,
228 FingerCount,
229}
230
231#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, Serialize)]
235#[serde(rename_all = "snake_case")]
236pub enum TouchpadScrollMode {
237 #[default]
238 None,
239 TwoFingerScroll,
240 EdgeScroll,
241 ButtonDownScroll,
242}
243
244#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, Serialize)]
248#[serde(rename_all = "snake_case")]
249pub enum AnimationPartType {
250 #[default]
251 Disabled,
252 Slide,
253 Grow,
254 Shrink,
255 Fade,
256}
257
258#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, Serialize)]
262#[serde(rename_all = "snake_case")]
263pub enum EasingFunction {
264 #[default]
265 Linear,
266 EaseInSine,
267 EaseOutSine,
268 EaseInOutSine,
269 EaseInQuad,
270 EaseOutQuad,
271 EaseInOutQuad,
272 EaseInCubic,
273 EaseOutCubic,
274 EaseInOutCubic,
275 EaseInQuart,
276 EaseOutQuart,
277 EaseInOutQuart,
278 EaseInQuint,
279 EaseOutQuint,
280 EaseInOutQuint,
281 EaseInExpo,
282 EaseOutExpo,
283 EaseInOutExpo,
284 EaseInCirc,
285 EaseOutCirc,
286 EaseInOutCirc,
287 EaseInBack,
288 EaseOutBack,
289 EaseInOutBack,
290 EaseInElastic,
291 EaseOutElastic,
292 EaseInOutElastic,
293 EaseInBounce,
294 EaseOutBounce,
295 EaseInOutBounce,
296}
297
298#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, Serialize)]
302#[serde(rename_all = "snake_case")]
303pub enum AnimationEvent {
304 #[default]
305 WindowOpen,
306 WindowMove,
307 WindowClose,
308 WorkspaceSwitch,
309}
310
311#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, Serialize)]
315#[serde(rename_all = "snake_case")]
316pub enum AnimationKind {
317 #[default]
318 BuiltIn,
319 Plugin,
320}
321
322#[derive(Debug, Clone, Default, Serialize)]
326pub struct Gaps {
327 pub x: i32,
328 pub y: i32,
329}
330
331#[derive(Debug, Clone, Serialize)]
333pub struct CustomKeyAction {
334 pub action: BindingAction,
336 pub modifiers: Vec<Modifier>,
338 pub key: Key,
340 pub command: String,
342}
343
344#[derive(Debug, Clone, Serialize)]
346pub struct BuiltInKeyCommandOverride {
347 pub name: String,
349 pub action: BindingAction,
351 pub modifiers: Vec<Modifier>,
353 pub key: Key,
355}
356
357#[derive(Debug, Clone, Default, Serialize)]
359pub struct StartupApp {
360 pub command: String,
361 #[serde(skip_serializing_if = "is_false")]
362 pub restart_on_death: bool,
363 #[serde(skip_serializing_if = "is_false")]
364 pub no_startup_id: bool,
365 #[serde(skip_serializing_if = "is_false")]
366 pub should_halt_compositor_on_death: bool,
367 #[serde(skip_serializing_if = "is_false")]
368 pub in_systemd_scope: bool,
369}
370
371#[derive(Debug, Clone, Default, Serialize)]
373pub struct EnvironmentVariable {
374 pub key: String,
375 pub value: String,
376}
377
378#[derive(Debug, Clone, Default, Serialize)]
384pub struct BorderConfig {
385 pub size: i32,
386 pub radius: f32,
387 pub color: String,
389 pub focus_color: String,
391}
392
393#[derive(Debug, Clone, Default, Serialize)]
395pub struct WorkspaceConfig {
396 #[serde(skip_serializing_if = "Option::is_none")]
397 pub number: Option<i32>,
398 #[serde(skip_serializing_if = "Option::is_none")]
399 pub name: Option<String>,
400}
401
402#[derive(Debug, Clone, Serialize)]
404pub struct DragAndDropConfiguration {
405 pub enabled: bool,
406 #[serde(skip_serializing_if = "Vec::is_empty")]
408 pub modifiers: Vec<Modifier>,
409}
410
411impl Default for DragAndDropConfiguration {
412 fn default() -> Self {
413 Self {
414 enabled: true,
415 modifiers: Vec::new(),
416 }
417 }
418}
419
420#[derive(Debug, Clone, Default, Serialize)]
422pub struct BuiltInAnimationPart {
423 #[serde(rename = "type")]
425 pub type_: AnimationPartType,
426 pub function: EasingFunction,
428 #[serde(skip_serializing_if = "Option::is_none")]
429 pub c1: Option<f32>,
430 #[serde(skip_serializing_if = "Option::is_none")]
431 pub c2: Option<f32>,
432 #[serde(skip_serializing_if = "Option::is_none")]
433 pub c3: Option<f32>,
434 #[serde(skip_serializing_if = "Option::is_none")]
435 pub c4: Option<f32>,
436 #[serde(skip_serializing_if = "Option::is_none")]
437 pub c5: Option<f32>,
438 #[serde(skip_serializing_if = "Option::is_none")]
439 pub n1: Option<f32>,
440 #[serde(skip_serializing_if = "Option::is_none")]
441 pub d1: Option<f32>,
442 #[serde(skip_serializing_if = "Option::is_none")]
449 pub scale: Option<f32>,
450}
451
452#[derive(Debug, Clone, Default, Serialize)]
454pub struct AnimationDefinition {
455 pub event: AnimationEvent,
457 #[serde(rename = "type")]
459 pub type_: AnimationKind,
460 #[serde(skip_serializing_if = "Option::is_none")]
462 pub duration: Option<f32>,
463 #[serde(skip_serializing_if = "Vec::is_empty")]
465 pub parts: Vec<BuiltInAnimationPart>,
466}
467
468#[derive(Debug, Clone, Default, Serialize)]
470pub struct MouseConfiguration {
471 #[serde(skip_serializing_if = "Option::is_none")]
473 pub handedness: Option<Handedness>,
474 #[serde(skip_serializing_if = "Option::is_none")]
476 pub acceleration: Option<PointerAcceleration>,
477 #[serde(skip_serializing_if = "Option::is_none")]
478 pub acceleration_bias: Option<f64>,
479 #[serde(skip_serializing_if = "Option::is_none")]
480 pub vscroll_speed: Option<f64>,
481 #[serde(skip_serializing_if = "Option::is_none")]
482 pub hscroll_speed: Option<f64>,
483}
484
485#[derive(Debug, Clone, Default, Serialize)]
487pub struct KeymapConfiguration {
488 pub language: String,
489 #[serde(skip_serializing_if = "Option::is_none")]
490 pub variant: Option<String>,
491 #[serde(skip_serializing_if = "Vec::is_empty")]
492 pub options: Vec<String>,
493}
494
495#[derive(Debug, Clone, Default, Serialize)]
497pub struct KeyboardConfiguration {
498 #[serde(skip_serializing_if = "Option::is_none")]
499 pub repeat_delay: Option<i32>,
500 #[serde(skip_serializing_if = "Option::is_none")]
501 pub repeat_rate: Option<i32>,
502 #[serde(skip_serializing_if = "Option::is_none")]
503 pub keymap: Option<KeymapConfiguration>,
504}
505
506#[derive(Debug, Clone, Default, Serialize)]
508pub struct HoverClickConfiguration {
509 pub enabled: bool,
510 #[serde(skip_serializing_if = "Option::is_none", rename = "hover_duration")]
512 pub hover_duration_ms: Option<u32>,
513 #[serde(skip_serializing_if = "Option::is_none")]
514 pub cancel_displacement_threshold: Option<i32>,
515 #[serde(skip_serializing_if = "Option::is_none")]
516 pub reclick_displacement_threshold: Option<i32>,
517}
518
519#[derive(Debug, Clone, Default, Serialize)]
521pub struct SimulatedSecondaryClickConfiguration {
522 pub enabled: bool,
523 #[serde(skip_serializing_if = "Option::is_none", rename = "hold_duration")]
525 pub hold_duration_ms: Option<u32>,
526 #[serde(skip_serializing_if = "Option::is_none")]
527 pub displacement_threshold: Option<i32>,
528}
529
530#[derive(Debug, Clone, Default, Serialize)]
532pub struct OutputFilterConfiguration {
533 #[serde(skip_serializing_if = "Option::is_none")]
534 pub shader_path: Option<String>,
535}
536
537#[derive(Debug, Clone, Default, Serialize)]
539pub struct CursorConfiguration {
540 #[serde(skip_serializing_if = "Option::is_none")]
541 pub scale: Option<f32>,
542 #[serde(skip_serializing_if = "Option::is_none")]
544 pub focus_mode: Option<CursorFocusMode>,
545}
546
547#[derive(Debug, Clone, Default, Serialize)]
549pub struct SlowKeysConfiguration {
550 pub enabled: bool,
551 #[serde(skip_serializing_if = "Option::is_none", rename = "hold_delay")]
553 pub hold_delay_ms: Option<u32>,
554}
555
556#[derive(Debug, Clone, Default, Serialize)]
558pub struct StickyKeysConfiguration {
559 pub enabled: bool,
560 #[serde(skip_serializing_if = "Option::is_none")]
561 pub should_disable_if_two_keys_are_pressed_together: Option<bool>,
562}
563
564#[derive(Debug, Clone, Default, Serialize)]
566pub struct TouchpadConfiguration {
567 #[serde(skip_serializing_if = "Option::is_none")]
568 pub disable_while_typing: Option<bool>,
569 #[serde(skip_serializing_if = "Option::is_none")]
570 pub disable_with_external_mouse: Option<bool>,
571 #[serde(skip_serializing_if = "Option::is_none")]
572 pub acceleration_bias: Option<f64>,
573 #[serde(skip_serializing_if = "Option::is_none")]
574 pub vscroll_speed: Option<f64>,
575 #[serde(skip_serializing_if = "Option::is_none")]
576 pub hscroll_speed: Option<f64>,
577 #[serde(skip_serializing_if = "Option::is_none")]
578 pub tap_to_click: Option<bool>,
579 #[serde(skip_serializing_if = "Option::is_none")]
580 pub middle_mouse_button_emulation: Option<bool>,
581 #[serde(skip_serializing_if = "Option::is_none")]
583 pub click_mode: Option<TouchpadClickMode>,
584 #[serde(skip_serializing_if = "Option::is_none")]
586 pub scroll_mode: Option<TouchpadScrollMode>,
587}
588
589#[derive(Debug, Clone, Default, Serialize)]
591pub struct MagnifierConfiguration {
592 pub enabled: bool,
593 #[serde(skip_serializing_if = "Option::is_none")]
594 pub scale: Option<f32>,
595 #[serde(skip_serializing_if = "Option::is_none")]
596 pub scale_increment: Option<f32>,
597 #[serde(skip_serializing_if = "Option::is_none")]
598 pub width: Option<i32>,
599 #[serde(skip_serializing_if = "Option::is_none")]
600 pub height: Option<i32>,
601 #[serde(skip_serializing_if = "Option::is_none")]
602 pub size_increment: Option<i32>,
603}
604
605#[derive(Debug, Clone, Default, Serialize)]
614pub struct Configuration {
615 #[serde(skip_serializing_if = "Option::is_none", rename = "action_key")]
617 pub primary_modifier: Option<Modifier>,
618
619 #[serde(skip_serializing_if = "Option::is_none", rename = "custom_actions")]
621 pub custom_key_actions: Option<Vec<CustomKeyAction>>,
622
623 #[serde(skip_serializing_if = "Option::is_none")]
625 pub default_action_overrides: Option<Vec<BuiltInKeyCommandOverride>>,
626
627 #[serde(skip_serializing_if = "Option::is_none")]
629 pub inner_gaps: Option<Gaps>,
630
631 #[serde(skip_serializing_if = "Option::is_none")]
633 pub outer_gaps: Option<Gaps>,
634
635 #[serde(skip_serializing_if = "Option::is_none")]
637 pub startup_apps: Option<Vec<StartupApp>>,
638
639 #[serde(skip_serializing_if = "Option::is_none")]
641 pub terminal: Option<String>,
642
643 #[serde(skip_serializing_if = "Option::is_none")]
645 pub resize_jump: Option<i32>,
646
647 #[serde(skip_serializing_if = "Option::is_none")]
649 pub environment_variables: Option<Vec<EnvironmentVariable>>,
650
651 #[serde(skip_serializing_if = "Option::is_none")]
653 pub border: Option<BorderConfig>,
654
655 #[serde(skip_serializing_if = "Option::is_none")]
657 pub workspaces: Option<Vec<WorkspaceConfig>>,
658
659 #[serde(skip_serializing_if = "Option::is_none")]
661 pub animations: Option<Vec<AnimationDefinition>>,
662
663 #[serde(skip_serializing_if = "Option::is_none")]
665 pub enable_animations: Option<bool>,
666
667 #[serde(skip_serializing_if = "Option::is_none")]
670 pub move_modifier: Option<Vec<Modifier>>,
671
672 #[serde(skip_serializing_if = "Option::is_none")]
674 pub drag_and_drop: Option<DragAndDropConfiguration>,
675
676 #[serde(skip_serializing_if = "Option::is_none")]
678 pub mouse: Option<MouseConfiguration>,
679
680 #[serde(skip_serializing_if = "Option::is_none")]
682 pub touchpad: Option<TouchpadConfiguration>,
683
684 #[serde(skip_serializing_if = "Option::is_none")]
686 pub keyboard: Option<KeyboardConfiguration>,
687
688 #[serde(skip_serializing_if = "Option::is_none")]
690 pub hover_click: Option<HoverClickConfiguration>,
691
692 #[serde(skip_serializing_if = "Option::is_none")]
694 pub simulated_secondary_click: Option<SimulatedSecondaryClickConfiguration>,
695
696 #[serde(skip_serializing_if = "Option::is_none")]
698 pub output_filter: Option<OutputFilterConfiguration>,
699
700 #[serde(skip_serializing_if = "Option::is_none")]
702 pub cursor: Option<CursorConfiguration>,
703
704 #[serde(skip_serializing_if = "Option::is_none")]
706 pub slow_keys: Option<SlowKeysConfiguration>,
707
708 #[serde(skip_serializing_if = "Option::is_none")]
710 pub sticky_keys: Option<StickyKeysConfiguration>,
711
712 #[serde(skip_serializing_if = "Option::is_none")]
714 pub magnifier: Option<MagnifierConfiguration>,
715
716 #[serde(skip_serializing_if = "Option::is_none")]
718 pub workspace_back_and_forth: Option<bool>,
719
720 #[serde(skip_serializing_if = "Option::is_none")]
723 pub background_color: Option<String>,
724}
725
726fn is_false(v: &bool) -> bool {
727 !v
728}