Skip to main content

zmk_studio_api/
binding.rs

1use crate::hid_usage::HidUsage;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
4pub enum BehaviorRole {
5    KeyPress,
6    KeyToggle,
7    LayerTap,
8    ModTap,
9    StickyKey,
10    StickyLayer,
11    MomentaryLayer,
12    ToggleLayer,
13    ToLayer,
14    Bluetooth,
15    ExternalPower,
16    OutputSelection,
17    Backlight,
18    Underglow,
19    MouseKeyPress,
20    MouseMove,
21    MouseScroll,
22    CapsWord,
23    KeyRepeat,
24    Reset,
25    Bootloader,
26    SoftOff,
27    StudioUnlock,
28    GraveEscape,
29    Transparent,
30    None,
31}
32
33/// Lossless typed behavior value for a single key binding.
34///
35/// Used by [`crate::StudioClient::get_key_at`] and [`crate::StudioClient::set_key_at`].
36/// Unknown behavior IDs are represented by [`Behavior::Unknown`].
37#[derive(Debug, Clone, PartialEq)]
38pub enum Behavior {
39    KeyPress(HidUsage),
40    KeyToggle(HidUsage),
41    LayerTap {
42        layer_id: u32,
43        tap: HidUsage,
44    },
45    ModTap {
46        hold: HidUsage,
47        tap: HidUsage,
48    },
49    StickyKey(HidUsage),
50    StickyLayer {
51        layer_id: u32,
52    },
53    MomentaryLayer {
54        layer_id: u32,
55    },
56    ToggleLayer {
57        layer_id: u32,
58    },
59    ToLayer {
60        layer_id: u32,
61    },
62    Bluetooth {
63        command: u32,
64        value: u32,
65    },
66    ExternalPower {
67        value: u32,
68    },
69    OutputSelection {
70        value: u32,
71    },
72    Backlight {
73        command: u32,
74        value: u32,
75    },
76    Underglow {
77        command: u32,
78        value: u32,
79    },
80    MouseKeyPress {
81        value: u32,
82    },
83    MouseMove {
84        value: u32,
85    },
86    MouseScroll {
87        value: u32,
88    },
89    CapsWord,
90    KeyRepeat,
91    Reset,
92    Bootloader,
93    SoftOff,
94    StudioUnlock,
95    GraveEscape,
96    Transparent,
97    None,
98    Unknown {
99        behavior_id: i32,
100        param1: u32,
101        param2: u32,
102    },
103}
104
105pub fn role_from_display_name(name: &str) -> Option<BehaviorRole> {
106    let n = name.trim().to_ascii_lowercase();
107    match n.as_str() {
108        // Explicit display-name values from zmk-main/app/dts/behaviors/*.dtsi
109        "key press" => Some(BehaviorRole::KeyPress),
110        "key toggle" => Some(BehaviorRole::KeyToggle),
111        "layer-tap" => Some(BehaviorRole::LayerTap),
112        "mod-tap" => Some(BehaviorRole::ModTap),
113        "sticky key" => Some(BehaviorRole::StickyKey),
114        "sticky layer" => Some(BehaviorRole::StickyLayer),
115        "momentary layer" => Some(BehaviorRole::MomentaryLayer),
116        "toggle layer" => Some(BehaviorRole::ToggleLayer),
117        "to layer" => Some(BehaviorRole::ToLayer),
118        "bluetooth" => Some(BehaviorRole::Bluetooth),
119        "external power" => Some(BehaviorRole::ExternalPower),
120        "output selection" => Some(BehaviorRole::OutputSelection),
121        "backlight" => Some(BehaviorRole::Backlight),
122        "underglow" => Some(BehaviorRole::Underglow),
123        "mouse key press" => Some(BehaviorRole::MouseKeyPress),
124        "caps word" => Some(BehaviorRole::CapsWord),
125        "key repeat" => Some(BehaviorRole::KeyRepeat),
126        "reset" => Some(BehaviorRole::Reset),
127        "bootloader" => Some(BehaviorRole::Bootloader),
128        "studio unlock" => Some(BehaviorRole::StudioUnlock),
129        "grave/escape" => Some(BehaviorRole::GraveEscape),
130        "transparent" => Some(BehaviorRole::Transparent),
131        "none" => Some(BehaviorRole::None),
132        // Behaviors without display-name that use DEVICE_DT_NAME(node_id)
133        "mouse_move" => Some(BehaviorRole::MouseMove),
134        "mouse_scroll" => Some(BehaviorRole::MouseScroll),
135        "z_so_off" => Some(BehaviorRole::SoftOff),
136        _ => None,
137    }
138}