mirror of
				https://github.com/mfulz/qmk_firmware.git
				synced 2025-11-04 07:12:33 +01:00 
			
		
		
		
	FIX: layer switching bug when Fn has no keycode.
- Fn without keycode doesn't need LAYER_SWITCH_DELAY.
This commit is contained in:
		
							parent
							
								
									660ea5a2cd
								
							
						
					
					
						commit
						11f0870020
					
				
							
								
								
									
										47
									
								
								host.c
									
									
									
									
									
								
							
							
						
						
									
										47
									
								
								host.c
									
									
									
									
									
								
							@ -35,7 +35,9 @@ report_keyboard_t *keyboard_report_prev = &report1;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void add_key_byte(uint8_t code);
 | 
					static inline void add_key_byte(uint8_t code);
 | 
				
			||||||
 | 
					static inline void del_key_byte(uint8_t code);
 | 
				
			||||||
static inline void add_key_bit(uint8_t code);
 | 
					static inline void add_key_bit(uint8_t code);
 | 
				
			||||||
 | 
					static inline void del_key_bit(uint8_t code);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void host_set_driver(host_driver_t *d)
 | 
					void host_set_driver(host_driver_t *d)
 | 
				
			||||||
@ -66,11 +68,27 @@ void host_add_key(uint8_t key)
 | 
				
			|||||||
    add_key_byte(key);
 | 
					    add_key_byte(key);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void host_del_key(uint8_t key)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#ifdef NKRO_ENABLE
 | 
				
			||||||
 | 
					    if (keyboard_nkro) {
 | 
				
			||||||
 | 
					        del_key_bit(key);
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    del_key_byte(key);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void host_add_mod_bit(uint8_t mod)
 | 
					void host_add_mod_bit(uint8_t mod)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    keyboard_report->mods |= mod;
 | 
					    keyboard_report->mods |= mod;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void host_del_mod_bit(uint8_t mod)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    keyboard_report->mods &= ~mod;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void host_set_mods(uint8_t mods)
 | 
					void host_set_mods(uint8_t mods)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    keyboard_report->mods = mods;
 | 
					    keyboard_report->mods = mods;
 | 
				
			||||||
@ -85,6 +103,15 @@ void host_add_code(uint8_t code)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void host_del_code(uint8_t code)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (IS_MOD(code)) {
 | 
				
			||||||
 | 
					        host_del_mod_bit(MOD_BIT(code));
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        host_del_key(code);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void host_swap_keyboard_report(void)
 | 
					void host_swap_keyboard_report(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    uint8_t sreg = SREG;
 | 
					    uint8_t sreg = SREG;
 | 
				
			||||||
@ -180,6 +207,17 @@ static inline void add_key_byte(uint8_t code)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline void del_key_byte(uint8_t code)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int i = 0;
 | 
				
			||||||
 | 
					    for (; i < REPORT_KEYS; i++) {
 | 
				
			||||||
 | 
					        if (keyboard_report->keys[i] == code) {
 | 
				
			||||||
 | 
					            keyboard_report->keys[i] = 0;
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void add_key_bit(uint8_t code)
 | 
					static inline void add_key_bit(uint8_t code)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if ((code>>3) < REPORT_KEYS) {
 | 
					    if ((code>>3) < REPORT_KEYS) {
 | 
				
			||||||
@ -188,3 +226,12 @@ static inline void add_key_bit(uint8_t code)
 | 
				
			|||||||
        debug("add_key_bit: can't add: "); phex(code); debug("\n");
 | 
					        debug("add_key_bit: can't add: "); phex(code); debug("\n");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline void del_key_bit(uint8_t code)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if ((code>>3) < REPORT_KEYS) {
 | 
				
			||||||
 | 
					        keyboard_report->keys[code>>3] &= ~(1<<(code&7));
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        debug("del_key_bit: can't del: "); phex(code); debug("\n");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										3
									
								
								host.h
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								host.h
									
									
									
									
									
								
							@ -37,9 +37,12 @@ uint8_t host_keyboard_leds(void);
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/* keyboard report operations */
 | 
					/* keyboard report operations */
 | 
				
			||||||
void host_add_key(uint8_t key);
 | 
					void host_add_key(uint8_t key);
 | 
				
			||||||
 | 
					void host_del_key(uint8_t key);
 | 
				
			||||||
void host_add_mod_bit(uint8_t mod);
 | 
					void host_add_mod_bit(uint8_t mod);
 | 
				
			||||||
 | 
					void host_del_mod_bit(uint8_t mod);
 | 
				
			||||||
void host_set_mods(uint8_t mods);
 | 
					void host_set_mods(uint8_t mods);
 | 
				
			||||||
void host_add_code(uint8_t code);
 | 
					void host_add_code(uint8_t code);
 | 
				
			||||||
 | 
					void host_del_code(uint8_t code);
 | 
				
			||||||
void host_swap_keyboard_report(void);
 | 
					void host_swap_keyboard_report(void);
 | 
				
			||||||
void host_clear_keyboard_report(void);
 | 
					void host_clear_keyboard_report(void);
 | 
				
			||||||
uint8_t host_has_anykey(void);
 | 
					uint8_t host_has_anykey(void);
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										44
									
								
								layer.c
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
						
						
									
										44
									
								
								layer.c
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							@ -25,7 +25,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Parameters:
 | 
					 * Parameters:
 | 
				
			||||||
 *     ENTER_DELAY         |=======|
 | 
					 *     SWITCH_DELAY        |=======|
 | 
				
			||||||
 *     SEND_FN_TERM        |================|
 | 
					 *     SEND_FN_TERM        |================|
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Fn key processing cases:
 | 
					 * Fn key processing cases:
 | 
				
			||||||
@ -49,7 +49,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			|||||||
 *     other key press  _____________|~~|__________
 | 
					 *     other key press  _____________|~~|__________
 | 
				
			||||||
 *     other key send   _____________|~~|__________
 | 
					 *     other key send   _____________|~~|__________
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * 4. press other key during ENTER_DELAY.
 | 
					 * 4. press other key during SWITCH_DELAY.
 | 
				
			||||||
 *     Layer sw         ___________________________
 | 
					 *     Layer sw         ___________________________
 | 
				
			||||||
 *     Fn key press     ___|~~~~~~~~~|_____________
 | 
					 *     Fn key press     ___|~~~~~~~~~|_____________
 | 
				
			||||||
 *     Fn key send      ______|~~~~~~|_____________
 | 
					 *     Fn key send      ______|~~~~~~|_____________
 | 
				
			||||||
@ -69,11 +69,15 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			|||||||
 *     Fn key send      _____|~|__|~~~~~~~~~~~~~~~~
 | 
					 *     Fn key send      _____|~|__|~~~~~~~~~~~~~~~~
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// LAYER_ENTER_DELAY: prevent from moving new layer
 | 
					// LAYER_SWITCH_DELAY: prevent from moving to new layer
 | 
				
			||||||
#define LAYER_ENTER_DELAY 150
 | 
					#ifndef LAYER_SWITCH_DELAY
 | 
				
			||||||
 | 
					#   define LAYER_SWITCH_DELAY 150
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// LAYER_SEND_FN_TERM: send keycode if release key in this term
 | 
					// LAYER_SEND_FN_TERM: send keycode if release key in this term
 | 
				
			||||||
#define LAYER_SEND_FN_TERM 500
 | 
					#ifndef LAYER_SEND_FN_TERM
 | 
				
			||||||
 | 
					#   define LAYER_SEND_FN_TERM 500
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
uint8_t default_layer = 0;
 | 
					uint8_t default_layer = 0;
 | 
				
			||||||
@ -107,10 +111,11 @@ void layer_switching(uint8_t fn_bits)
 | 
				
			|||||||
        if (fn_bits == 0) {
 | 
					        if (fn_bits == 0) {
 | 
				
			||||||
            // do nothing
 | 
					            // do nothing
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            if (timer_elapsed(last_timer) > LAYER_ENTER_DELAY) {
 | 
					            if (!keymap_fn_keycode(BIT_SUBST(fn_bits, sent_fn)) ||
 | 
				
			||||||
 | 
					                    timer_elapsed(last_timer) > LAYER_SWITCH_DELAY) {
 | 
				
			||||||
                uint8_t _layer_to_switch = new_layer(BIT_SUBST(fn_bits, sent_fn));
 | 
					                uint8_t _layer_to_switch = new_layer(BIT_SUBST(fn_bits, sent_fn));
 | 
				
			||||||
                if (current_layer != _layer_to_switch) { // not switch layer yet
 | 
					                if (current_layer != _layer_to_switch) { // not switch layer yet
 | 
				
			||||||
                    debug("Fn case: 1,2,3(LAYER_ENTER_DELAY passed)\n");
 | 
					                    debug("Fn case: 1,2,3(LAYER_SWITCH_DELAY passed)\n");
 | 
				
			||||||
                    debug("Switch Layer: "); debug_hex(current_layer);
 | 
					                    debug("Switch Layer: "); debug_hex(current_layer);
 | 
				
			||||||
                    current_layer = _layer_to_switch;
 | 
					                    current_layer = _layer_to_switch;
 | 
				
			||||||
                    layer_used = false;
 | 
					                    layer_used = false;
 | 
				
			||||||
@ -120,14 +125,14 @@ void layer_switching(uint8_t fn_bits)
 | 
				
			|||||||
                if (host_has_anykey()) { // other keys is pressed
 | 
					                if (host_has_anykey()) { // other keys is pressed
 | 
				
			||||||
                    uint8_t _fn_to_send = BIT_SUBST(fn_bits, sent_fn);
 | 
					                    uint8_t _fn_to_send = BIT_SUBST(fn_bits, sent_fn);
 | 
				
			||||||
                    if (_fn_to_send) {
 | 
					                    if (_fn_to_send) {
 | 
				
			||||||
                        debug("Fn case: 4(send Fn before other key pressed)\n");
 | 
					                        debug("Fn case: 4(press other key during SWITCH_DELAY.)\n");
 | 
				
			||||||
                        // send only Fn key first
 | 
					                        // send only Fn key first
 | 
				
			||||||
                        host_swap_keyboard_report();
 | 
					                        uint8_t tmp_mods = keyboard_report->mods;
 | 
				
			||||||
                        host_clear_keyboard_report();
 | 
					                        host_add_code(keymap_fn_keycode(_fn_to_send));
 | 
				
			||||||
                        host_set_mods(last_mods);
 | 
					                        host_set_mods(last_mods);
 | 
				
			||||||
                        host_add_code(keymap_fn_keycode(_fn_to_send));   // TODO: do all Fn keys
 | 
					 | 
				
			||||||
                        host_send_keyboard_report();
 | 
					                        host_send_keyboard_report();
 | 
				
			||||||
                        host_swap_keyboard_report();
 | 
					                        host_set_mods(tmp_mods);
 | 
				
			||||||
 | 
					                        host_del_code(keymap_fn_keycode(_fn_to_send));
 | 
				
			||||||
                        sent_fn |= _fn_to_send;
 | 
					                        sent_fn |= _fn_to_send;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
@ -143,15 +148,16 @@ void layer_switching(uint8_t fn_bits)
 | 
				
			|||||||
        debug("last_fn: "); debug_bin(last_fn); debug("\n");
 | 
					        debug("last_fn: "); debug_bin(last_fn); debug("\n");
 | 
				
			||||||
        debug("last_mods: "); debug_hex(last_mods); debug("\n");
 | 
					        debug("last_mods: "); debug_hex(last_mods); debug("\n");
 | 
				
			||||||
        debug("last_timer: "); debug_hex16(last_timer); debug("\n");
 | 
					        debug("last_timer: "); debug_hex16(last_timer); debug("\n");
 | 
				
			||||||
 | 
					        debug("timer_count: "); debug_hex16(timer_count); debug("\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // pressed Fn
 | 
					        // pressed Fn
 | 
				
			||||||
        if ((fn_changed = BIT_SUBST(fn_bits, last_fn))) {
 | 
					        if ((fn_changed = BIT_SUBST(fn_bits, last_fn))) {
 | 
				
			||||||
        debug("fn_changed: "); debug_bin(fn_changed); debug("\n");
 | 
					            debug("fn_changed: "); debug_bin(fn_changed); debug("\n");
 | 
				
			||||||
            if (host_has_anykey()) {
 | 
					            if (host_has_anykey()) {
 | 
				
			||||||
                debug("Fn case: 5(pressed Fn with other key)\n");
 | 
					                debug("Fn case: 5(pressed Fn with other key)\n");
 | 
				
			||||||
                sent_fn |= fn_changed;
 | 
					                sent_fn |= fn_changed;
 | 
				
			||||||
            } else if (fn_changed & sent_fn) { // pressed same Fn in a row
 | 
					            } else if (fn_changed & sent_fn) { // pressed same Fn in a row
 | 
				
			||||||
                if (timer_elapsed(last_timer) > LAYER_ENTER_DELAY) {
 | 
					                if (timer_elapsed(last_timer) > LAYER_SEND_FN_TERM) {
 | 
				
			||||||
                    debug("Fn case: 6(not repeat)\n");
 | 
					                    debug("Fn case: 6(not repeat)\n");
 | 
				
			||||||
                    // time passed: not repeate
 | 
					                    // time passed: not repeate
 | 
				
			||||||
                    sent_fn &= ~fn_changed;
 | 
					                    sent_fn &= ~fn_changed;
 | 
				
			||||||
@ -162,17 +168,17 @@ void layer_switching(uint8_t fn_bits)
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        // released Fn
 | 
					        // released Fn
 | 
				
			||||||
        if ((fn_changed = BIT_SUBST(last_fn, fn_bits))) {
 | 
					        if ((fn_changed = BIT_SUBST(last_fn, fn_bits))) {
 | 
				
			||||||
        debug("fn_changed: "); debug_bin(fn_changed); debug("\n");
 | 
					            debug("fn_changed: "); debug_bin(fn_changed); debug("\n");
 | 
				
			||||||
            if (timer_elapsed(last_timer) < LAYER_SEND_FN_TERM) {
 | 
					            if (timer_elapsed(last_timer) < LAYER_SEND_FN_TERM) {
 | 
				
			||||||
                if (!layer_used && BIT_SUBST(fn_changed, sent_fn)) {
 | 
					                if (!layer_used && BIT_SUBST(fn_changed, sent_fn)) {
 | 
				
			||||||
                    debug("Fn case: 2(send Fn one shot: released Fn during LAYER_SEND_FN_TERM)\n");
 | 
					                    debug("Fn case: 2(send Fn one shot: released Fn during LAYER_SEND_FN_TERM)\n");
 | 
				
			||||||
                    // send only Fn key first
 | 
					                    // send only Fn key first
 | 
				
			||||||
                    host_swap_keyboard_report();
 | 
					                    uint8_t tmp_mods = keyboard_report->mods;
 | 
				
			||||||
                    host_clear_keyboard_report();
 | 
					                    host_add_code(keymap_fn_keycode(fn_changed));
 | 
				
			||||||
                    host_set_mods(last_mods);
 | 
					                    host_set_mods(last_mods);
 | 
				
			||||||
                    host_add_code(keymap_fn_keycode(fn_changed));   // TODO: do all Fn keys
 | 
					 | 
				
			||||||
                    host_send_keyboard_report();
 | 
					                    host_send_keyboard_report();
 | 
				
			||||||
                    host_swap_keyboard_report();
 | 
					                    host_set_mods(tmp_mods);
 | 
				
			||||||
 | 
					                    host_del_code(keymap_fn_keycode(fn_changed));
 | 
				
			||||||
                    sent_fn |= fn_changed;
 | 
					                    sent_fn |= fn_changed;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user