@@ -88,7 +88,24 @@ struct active_hold_tap {
8888struct active_hold_tap * undecided_hold_tap = NULL ;
8989struct active_hold_tap active_hold_taps [ZMK_BHV_HOLD_TAP_MAX_HELD ] = {};
9090// We capture most position_state_changed events and some modifiers_state_changed events.
91- const zmk_event_t * captured_events [ZMK_BHV_HOLD_TAP_MAX_CAPTURED_EVENTS ] = {};
91+
92+ enum captured_event_tag {
93+ ET_NONE ,
94+ ET_POS_CHANGED ,
95+ ET_CODE_CHANGED ,
96+ };
97+
98+ union captured_event_data {
99+ struct zmk_position_state_changed_event position ;
100+ struct zmk_keycode_state_changed_event keycode ;
101+ };
102+
103+ struct captured_event {
104+ enum captured_event_tag tag ;
105+ union captured_event_data data ;
106+ };
107+
108+ struct captured_event captured_events [ZMK_BHV_HOLD_TAP_MAX_CAPTURED_EVENTS ] = {};
92109
93110// Keep track of which key was tapped most recently for the standard, if it is a hold-tap
94111// a position, will be given, if not it will just be INT32_MIN
@@ -119,33 +136,32 @@ static bool is_quick_tap(struct active_hold_tap *hold_tap) {
119136 }
120137}
121138
122- static int capture_event (const zmk_event_t * event ) {
139+ static int capture_event (struct captured_event data ) {
123140 for (int i = 0 ; i < ZMK_BHV_HOLD_TAP_MAX_CAPTURED_EVENTS ; i ++ ) {
124- if (captured_events [i ] == NULL ) {
125- captured_events [i ] = event ;
141+ if (captured_events [i ]. tag == ET_NONE ) {
142+ memcpy ( & captured_events [i ], & data , sizeof ( struct captured_event )) ;
126143 return 0 ;
127144 }
128145 }
129146 return - ENOMEM ;
130147}
131148
132- static struct zmk_position_state_changed * find_captured_keydown_event (uint32_t position ) {
133- struct zmk_position_state_changed * last_match = NULL ;
149+ static bool have_captured_keydown_event (uint32_t position ) {
134150 for (int i = 0 ; i < ZMK_BHV_HOLD_TAP_MAX_CAPTURED_EVENTS ; i ++ ) {
135- const zmk_event_t * eh = captured_events [i ];
136- if (eh == NULL ) {
137- return last_match ;
151+ struct captured_event ev = captured_events [i ];
152+ if (ev . tag == ET_NONE ) {
153+ return false ;
138154 }
139- struct zmk_position_state_changed * position_event = as_zmk_position_state_changed ( eh );
140- if (position_event == NULL ) {
155+
156+ if (ev . tag != ET_POS_CHANGED ) {
141157 continue ;
142158 }
143159
144- if (position_event -> position == position && position_event -> state ) {
145- last_match = position_event ;
160+ if (ev . data . position . data . position == position && ev . data . position . data . state ) {
161+ return true ;
146162 }
147163 }
148- return last_match ;
164+ return false ;
149165}
150166
151167const struct zmk_listener zmk_listener_behavior_hold_tap ;
@@ -181,25 +197,33 @@ static void release_captured_events() {
181197 // [k1_down, k1_up, null, null, null, ...]
182198 // now mt2 will start releasing it's own captured positions.
183199 for (int i = 0 ; i < ZMK_BHV_HOLD_TAP_MAX_CAPTURED_EVENTS ; i ++ ) {
184- const zmk_event_t * captured_event = captured_events [i ];
185- if (captured_event == NULL ) {
200+ struct captured_event captured_event = captured_events [i ];
201+ if (captured_event . tag == ET_NONE ) {
186202 return ;
187203 }
188- captured_events [i ] = NULL ;
204+
205+ captured_events [i ].tag = ET_NONE ;
189206 if (undecided_hold_tap != NULL ) {
190207 k_msleep (10 );
191208 }
192209
193- struct zmk_position_state_changed * position_event ;
194- struct zmk_keycode_state_changed * modifier_event ;
195- if ((position_event = as_zmk_position_state_changed (captured_event )) != NULL ) {
196- LOG_DBG ("Releasing key position event for position %d %s" , position_event -> position ,
197- (position_event -> state ? "pressed" : "released" ));
198- } else if ((modifier_event = as_zmk_keycode_state_changed (captured_event )) != NULL ) {
199- LOG_DBG ("Releasing mods changed event 0x%02X %s" , modifier_event -> keycode ,
200- (modifier_event -> state ? "pressed" : "released" ));
210+ switch (captured_event .tag ) {
211+ case ET_CODE_CHANGED :
212+ LOG_DBG ("Releasing mods changed event 0x%02X %s" ,
213+ captured_event .data .keycode .data .keycode ,
214+ (captured_event .data .keycode .data .state ? "pressed" : "released" ));
215+ ZMK_EVENT_RAISE_AT (captured_event .data .keycode , behavior_hold_tap );
216+ break ;
217+ case ET_POS_CHANGED :
218+ LOG_DBG ("Releasing key position event for position %d %s" ,
219+ captured_event .data .position .data .position ,
220+ (captured_event .data .position .data .state ? "pressed" : "released" ));
221+ ZMK_EVENT_RAISE_AT (captured_event .data .position , behavior_hold_tap );
222+ break ;
223+ default :
224+ LOG_ERR ("Unhandled captured event type" );
225+ break ;
201226 }
202- ZMK_EVENT_RAISE_AT (captured_event , behavior_hold_tap );
203227 }
204228}
205229
@@ -619,7 +643,7 @@ static int position_state_changed_listener(const zmk_event_t *eh) {
619643 return ZMK_EV_EVENT_BUBBLE ;
620644 }
621645
622- if (!ev -> state && find_captured_keydown_event (ev -> position ) == NULL ) {
646+ if (!ev -> state && ! have_captured_keydown_event (ev -> position )) {
623647 // no keydown event has been captured, let it bubble.
624648 // we'll catch modifiers later in modifier_state_changed_listener
625649 LOG_DBG ("%d bubbling %d %s event" , undecided_hold_tap -> position , ev -> position ,
@@ -629,7 +653,10 @@ static int position_state_changed_listener(const zmk_event_t *eh) {
629653
630654 LOG_DBG ("%d capturing %d %s event" , undecided_hold_tap -> position , ev -> position ,
631655 ev -> state ? "down" : "up" );
632- capture_event (eh );
656+ struct captured_event capture ;
657+ capture .tag = ET_POS_CHANGED ;
658+ memcpy (& capture .data .position , eh , sizeof (struct zmk_position_state_changed_event ));
659+ capture_event (capture );
633660 decide_hold_tap (undecided_hold_tap , ev -> state ? HT_OTHER_KEY_DOWN : HT_OTHER_KEY_UP );
634661 return ZMK_EV_EVENT_CAPTURED ;
635662}
@@ -656,7 +683,10 @@ static int keycode_state_changed_listener(const zmk_event_t *eh) {
656683 // if a undecided_hold_tap is active.
657684 LOG_DBG ("%d capturing 0x%02X %s event" , undecided_hold_tap -> position , ev -> keycode ,
658685 ev -> state ? "down" : "up" );
659- capture_event (eh );
686+ struct captured_event capture ;
687+ capture .tag = ET_CODE_CHANGED ;
688+ memcpy (& capture .data .keycode , eh , sizeof (struct zmk_keycode_state_changed_event ));
689+ capture_event (capture );
660690 return ZMK_EV_EVENT_CAPTURED ;
661691}
662692
0 commit comments