diff options
Diffstat (limited to 'quantum/action.c')
| -rw-r--r-- | quantum/action.c | 306 | 
1 files changed, 178 insertions, 128 deletions
| diff --git a/quantum/action.c b/quantum/action.c index be135f18f2..ceaaa551f5 100644 --- a/quantum/action.c +++ b/quantum/action.c @@ -18,6 +18,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  #include "keycode.h"  #include "keyboard.h"  #include "mousekey.h" +#include "programmable_button.h"  #include "command.h"  #include "led.h"  #include "action_layer.h" @@ -26,6 +27,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  #include "action_util.h"  #include "action.h"  #include "wait.h" +#include "keycode_config.h"  #ifdef BACKLIGHT_ENABLE  #    include "backlight.h" @@ -86,19 +88,21 @@ void action_exec(keyevent_t event) {      keyrecord_t record = {.event = event};  #ifndef NO_ACTION_ONESHOT +    if (!keymap_config.oneshot_disable) {  #    if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) -    if (has_oneshot_layer_timed_out()) { -        clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED); -    } -    if (has_oneshot_mods_timed_out()) { -        clear_oneshot_mods(); -    } +        if (has_oneshot_layer_timed_out()) { +            clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED); +        } +        if (has_oneshot_mods_timed_out()) { +            clear_oneshot_mods(); +        }  #        ifdef SWAP_HANDS_ENABLE -    if (has_oneshot_swaphands_timed_out()) { -        clear_oneshot_swaphands(); -    } +        if (has_oneshot_swaphands_timed_out()) { +            clear_oneshot_swaphands(); +        }  #        endif  #    endif +    }  #endif  #ifndef NO_ACTION_TAPPING @@ -194,7 +198,7 @@ void process_record(keyrecord_t *record) {      if (!process_record_quantum(record)) {  #ifndef NO_ACTION_ONESHOT -        if (is_oneshot_layer_active() && record->event.pressed) { +        if (is_oneshot_layer_active() && record->event.pressed && !keymap_config.oneshot_disable) {              clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);          }  #endif @@ -259,7 +263,7 @@ void process_action(keyrecord_t *record, action_t action) {  #    ifdef SWAP_HANDS_ENABLE          && !(action.kind.id == ACT_SWAP_HANDS && action.swap.code == OP_SH_ONESHOT)  #    endif -    ) { +        && !keymap_config.oneshot_disable) {          clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);          do_release_oneshot = !is_oneshot_layer_active();      } @@ -273,8 +277,8 @@ void process_action(keyrecord_t *record, action_t action) {              if (event.pressed) {                  if (mods) {                      if (IS_MOD(action.key.code) || action.key.code == KC_NO) { -                        // e.g. LSFT(KC_LGUI): we don't want the LSFT to be weak as it would make it useless. -                        // This also makes LSFT(KC_LGUI) behave exactly the same as LGUI(KC_LSFT). +                        // e.g. LSFT(KC_LEFT_GUI): we don't want the LSFT to be weak as it would make it useless. +                        // This also makes LSFT(KC_LEFT_GUI) behave exactly the same as LGUI(KC_LEFT_SHIFT).                          // Same applies for some keys like KC_MEH which are declared as MEH(KC_NO).                          add_mods(mods);                      } else { @@ -303,41 +307,68 @@ void process_action(keyrecord_t *record, action_t action) {  #    ifndef NO_ACTION_ONESHOT                  case MODS_ONESHOT:                      // Oneshot modifier -                    if (event.pressed) { -                        if (tap_count == 0) { -                            dprint("MODS_TAP: Oneshot: 0\n"); -                            register_mods(mods | get_oneshot_mods()); -                        } else if (tap_count == 1) { -                            dprint("MODS_TAP: Oneshot: start\n"); -                            set_oneshot_mods(mods | get_oneshot_mods()); -#        if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1 -                        } else if (tap_count == ONESHOT_TAP_TOGGLE) { -                            dprint("MODS_TAP: Toggling oneshot"); -                            clear_oneshot_mods(); -                            set_oneshot_locked_mods(mods); -                            register_mods(mods); -#        endif +                    if (keymap_config.oneshot_disable) { +                        if (event.pressed) { +                            if (mods) { +                                if (IS_MOD(action.key.code) || action.key.code == KC_NO) { +                                    // e.g. LSFT(KC_LGUI): we don't want the LSFT to be weak as it would make it useless. +                                    // This also makes LSFT(KC_LGUI) behave exactly the same as LGUI(KC_LSFT). +                                    // Same applies for some keys like KC_MEH which are declared as MEH(KC_NO). +                                    add_mods(mods); +                                } else { +                                    add_weak_mods(mods); +                                } +                                send_keyboard_report(); +                            } +                            register_code(action.key.code);                          } else { -                            register_mods(mods | get_oneshot_mods()); +                            unregister_code(action.key.code); +                            if (mods) { +                                if (IS_MOD(action.key.code) || action.key.code == KC_NO) { +                                    del_mods(mods); +                                } else { +                                    del_weak_mods(mods); +                                } +                                send_keyboard_report(); +                            }                          }                      } else { -                        if (tap_count == 0) { -                            clear_oneshot_mods(); -                            unregister_mods(mods); -                        } else if (tap_count == 1) { -                            // Retain Oneshot mods +                        if (event.pressed) { +                            if (tap_count == 0) { +                                dprint("MODS_TAP: Oneshot: 0\n"); +                                register_mods(mods | get_oneshot_mods()); +                            } else if (tap_count == 1) { +                                dprint("MODS_TAP: Oneshot: start\n"); +                                set_oneshot_mods(mods | get_oneshot_mods());  #        if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1 -                            if (mods & get_mods()) { -                                clear_oneshot_locked_mods(); +                            } else if (tap_count == ONESHOT_TAP_TOGGLE) { +                                dprint("MODS_TAP: Toggling oneshot");                                  clear_oneshot_mods(); -                                unregister_mods(mods); -                            } -                        } else if (tap_count == ONESHOT_TAP_TOGGLE) { -                            // Toggle Oneshot Layer +                                set_oneshot_locked_mods(mods); +                                register_mods(mods);  #        endif +                            } else { +                                register_mods(mods | get_oneshot_mods()); +                            }                          } else { -                            clear_oneshot_mods(); -                            unregister_mods(mods); +                            if (tap_count == 0) { +                                clear_oneshot_mods(); +                                unregister_mods(mods); +                            } else if (tap_count == 1) { +                                // Retain Oneshot mods +#        if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1 +                                if (mods & get_mods()) { +                                    clear_oneshot_locked_mods(); +                                    clear_oneshot_mods(); +                                    unregister_mods(mods); +                                } +                            } else if (tap_count == ONESHOT_TAP_TOGGLE) { +                                // Toggle Oneshot Layer +#        endif +                            } else { +                                clear_oneshot_mods(); +                                unregister_mods(mods); +                            }                          }                      }                      break; @@ -379,7 +410,7 @@ void process_action(keyrecord_t *record, action_t action) {                      } else {                          if (tap_count > 0) {                              dprint("MODS_TAP: Tap: unregister_code\n"); -                            if (action.layer_tap.code == KC_CAPS) { +                            if (action.layer_tap.code == KC_CAPS_LOCK) {                                  wait_ms(TAP_HOLD_CAPS_DELAY);                              } else {                                  wait_ms(TAP_CODE_DELAY); @@ -522,39 +553,47 @@ void process_action(keyrecord_t *record, action_t action) {  #        ifndef NO_ACTION_ONESHOT                  case OP_ONESHOT:                      // Oneshot modifier -#            if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1 -                    do_release_oneshot = false; -                    if (event.pressed) { -                        del_mods(get_oneshot_locked_mods()); -                        if (get_oneshot_layer_state() == ONESHOT_TOGGLED) { -                            reset_oneshot_layer(); -                            layer_off(action.layer_tap.val); -                            break; -                        } else if (tap_count < ONESHOT_TAP_TOGGLE) { +                    if (keymap_config.oneshot_disable) { +                        if (event.pressed) {                              layer_on(action.layer_tap.val); -                            set_oneshot_layer(action.layer_tap.val, ONESHOT_START); +                        } else { +                            layer_off(action.layer_tap.val);                          }                      } else { -                        add_mods(get_oneshot_locked_mods()); -                        if (tap_count >= ONESHOT_TAP_TOGGLE) { -                            reset_oneshot_layer(); -                            clear_oneshot_locked_mods(); -                            set_oneshot_layer(action.layer_tap.val, ONESHOT_TOGGLED); +#            if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1 +                        do_release_oneshot = false; +                        if (event.pressed) { +                            del_mods(get_oneshot_locked_mods()); +                            if (get_oneshot_layer_state() == ONESHOT_TOGGLED) { +                                reset_oneshot_layer(); +                                layer_off(action.layer_tap.val); +                                break; +                            } else if (tap_count < ONESHOT_TAP_TOGGLE) { +                                layer_on(action.layer_tap.val); +                                set_oneshot_layer(action.layer_tap.val, ONESHOT_START); +                            }                          } else { -                            clear_oneshot_layer_state(ONESHOT_PRESSED); +                            add_mods(get_oneshot_locked_mods()); +                            if (tap_count >= ONESHOT_TAP_TOGGLE) { +                                reset_oneshot_layer(); +                                clear_oneshot_locked_mods(); +                                set_oneshot_layer(action.layer_tap.val, ONESHOT_TOGGLED); +                            } else { +                                clear_oneshot_layer_state(ONESHOT_PRESSED); +                            }                          } -                    }  #            else -                    if (event.pressed) { -                        layer_on(action.layer_tap.val); -                        set_oneshot_layer(action.layer_tap.val, ONESHOT_START); -                    } else { -                        clear_oneshot_layer_state(ONESHOT_PRESSED); -                        if (tap_count > 1) { -                            clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED); +                        if (event.pressed) { +                            layer_on(action.layer_tap.val); +                            set_oneshot_layer(action.layer_tap.val, ONESHOT_START); +                        } else { +                            clear_oneshot_layer_state(ONESHOT_PRESSED); +                            if (tap_count > 1) { +                                clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED); +                            }                          } -                    }  #            endif +                    }                      break;  #        endif                  default: @@ -570,7 +609,7 @@ void process_action(keyrecord_t *record, action_t action) {                      } else {                          if (tap_count > 0) {                              dprint("KEYMAP_TAP_KEY: Tap: unregister_code\n"); -                            if (action.layer_tap.code == KC_CAPS) { +                            if (action.layer_tap.code == KC_CAPS_LOCK) {                                  wait_ms(TAP_HOLD_CAPS_DELAY);                              } else {                                  wait_ms(TAP_CODE_DELAY); @@ -747,44 +786,45 @@ void register_code(uint8_t code) {          return;      }  #ifdef LOCKING_SUPPORT_ENABLE -    else if (KC_LOCKING_CAPS == code) { +    else if (KC_LOCKING_CAPS_LOCK == code) {  #    ifdef LOCKING_RESYNC_ENABLE          // Resync: ignore if caps lock already is on          if (host_keyboard_leds() & (1 << USB_LED_CAPS_LOCK)) return;  #    endif -        add_key(KC_CAPSLOCK); +        add_key(KC_CAPS_LOCK);          send_keyboard_report();          wait_ms(100); -        del_key(KC_CAPSLOCK); +        del_key(KC_CAPS_LOCK);          send_keyboard_report();      } -    else if (KC_LOCKING_NUM == code) { +    else if (KC_LOCKING_NUM_LOCK == code) {  #    ifdef LOCKING_RESYNC_ENABLE          if (host_keyboard_leds() & (1 << USB_LED_NUM_LOCK)) return;  #    endif -        add_key(KC_NUMLOCK); +        add_key(KC_NUM_LOCK);          send_keyboard_report();          wait_ms(100); -        del_key(KC_NUMLOCK); +        del_key(KC_NUM_LOCK);          send_keyboard_report();      } -    else if (KC_LOCKING_SCROLL == code) { +    else if (KC_LOCKING_SCROLL_LOCK == code) {  #    ifdef LOCKING_RESYNC_ENABLE          if (host_keyboard_leds() & (1 << USB_LED_SCROLL_LOCK)) return;  #    endif -        add_key(KC_SCROLLLOCK); +        add_key(KC_SCROLL_LOCK);          send_keyboard_report();          wait_ms(100); -        del_key(KC_SCROLLLOCK); +        del_key(KC_SCROLL_LOCK);          send_keyboard_report();      }  #endif -    else if IS_KEY (code) { -        // TODO: should push command_proc out of this block? -        if (command_proc(code)) return; +    else if +        IS_KEY(code) { +            // TODO: should push command_proc out of this block? +            if (command_proc(code)) return;  #ifndef NO_ACTION_ONESHOT  /* TODO: remove @@ -801,33 +841,35 @@ void register_code(uint8_t code) {          } else  */  #endif -        { -            // Force a new key press if the key is already pressed -            // without this, keys with the same keycode, but different -            // modifiers will be reported incorrectly, see issue #1708 -            if (is_key_pressed(keyboard_report, code)) { -                del_key(code); +            { +                // Force a new key press if the key is already pressed +                // without this, keys with the same keycode, but different +                // modifiers will be reported incorrectly, see issue #1708 +                if (is_key_pressed(keyboard_report, code)) { +                    del_key(code); +                    send_keyboard_report(); +                } +                add_key(code);                  send_keyboard_report();              } -            add_key(code); +        } +    else if +        IS_MOD(code) { +            add_mods(MOD_BIT(code));              send_keyboard_report();          } -    } else if IS_MOD (code) { -        add_mods(MOD_BIT(code)); -        send_keyboard_report(); -    }  #ifdef EXTRAKEY_ENABLE -    else if IS_SYSTEM (code) { -        host_system_send(KEYCODE2SYSTEM(code)); -    } else if IS_CONSUMER (code) { -        host_consumer_send(KEYCODE2CONSUMER(code)); -    } +    else if +        IS_SYSTEM(code) { host_system_send(KEYCODE2SYSTEM(code)); } +    else if +        IS_CONSUMER(code) { host_consumer_send(KEYCODE2CONSUMER(code)); }  #endif  #ifdef MOUSEKEY_ENABLE -    else if IS_MOUSEKEY (code) { -        mousekey_on(code); -        mousekey_send(); -    } +    else if +        IS_MOUSEKEY(code) { +            mousekey_on(code); +            mousekey_send(); +        }  #endif  } @@ -840,54 +882,58 @@ void unregister_code(uint8_t code) {          return;      }  #ifdef LOCKING_SUPPORT_ENABLE -    else if (KC_LOCKING_CAPS == code) { +    else if (KC_LOCKING_CAPS_LOCK == code) {  #    ifdef LOCKING_RESYNC_ENABLE          // Resync: ignore if caps lock already is off          if (!(host_keyboard_leds() & (1 << USB_LED_CAPS_LOCK))) return;  #    endif -        add_key(KC_CAPSLOCK); +        add_key(KC_CAPS_LOCK);          send_keyboard_report(); -        del_key(KC_CAPSLOCK); +        del_key(KC_CAPS_LOCK);          send_keyboard_report();      } -    else if (KC_LOCKING_NUM == code) { +    else if (KC_LOCKING_NUM_LOCK == code) {  #    ifdef LOCKING_RESYNC_ENABLE          if (!(host_keyboard_leds() & (1 << USB_LED_NUM_LOCK))) return;  #    endif -        add_key(KC_NUMLOCK); +        add_key(KC_NUM_LOCK);          send_keyboard_report(); -        del_key(KC_NUMLOCK); +        del_key(KC_NUM_LOCK);          send_keyboard_report();      } -    else if (KC_LOCKING_SCROLL == code) { +    else if (KC_LOCKING_SCROLL_LOCK == code) {  #    ifdef LOCKING_RESYNC_ENABLE          if (!(host_keyboard_leds() & (1 << USB_LED_SCROLL_LOCK))) return;  #    endif -        add_key(KC_SCROLLLOCK); +        add_key(KC_SCROLL_LOCK);          send_keyboard_report(); -        del_key(KC_SCROLLLOCK); +        del_key(KC_SCROLL_LOCK);          send_keyboard_report();      }  #endif -    else if IS_KEY (code) { -        del_key(code); -        send_keyboard_report(); -    } else if IS_MOD (code) { -        del_mods(MOD_BIT(code)); -        send_keyboard_report(); -    } else if IS_SYSTEM (code) { -        host_system_send(0); -    } else if IS_CONSUMER (code) { -        host_consumer_send(0); -    } +    else if +        IS_KEY(code) { +            del_key(code); +            send_keyboard_report(); +        } +    else if +        IS_MOD(code) { +            del_mods(MOD_BIT(code)); +            send_keyboard_report(); +        } +    else if +        IS_SYSTEM(code) { host_system_send(0); } +    else if +        IS_CONSUMER(code) { host_consumer_send(0); }  #ifdef MOUSEKEY_ENABLE -    else if IS_MOUSEKEY (code) { -        mousekey_off(code); -        mousekey_send(); -    } +    else if +        IS_MOUSEKEY(code) { +            mousekey_off(code); +            mousekey_send(); +        }  #endif  } @@ -906,9 +952,9 @@ void tap_code_delay(uint8_t code, uint16_t delay) {  /** \brief Tap a keycode with the default delay.   * - * \param code The basic keycode to tap. If `code` is `KC_CAPS`, the delay will be `TAP_HOLD_CAPS_DELAY`, otherwise `TAP_CODE_DELAY`, if defined. + * \param code The basic keycode to tap. If `code` is `KC_CAPS_LOCK`, the delay will be `TAP_HOLD_CAPS_DELAY`, otherwise `TAP_CODE_DELAY`, if defined.   */ -void tap_code(uint8_t code) { tap_code_delay(code, code == KC_CAPS ? TAP_HOLD_CAPS_DELAY : TAP_CODE_DELAY); } +void tap_code(uint8_t code) { tap_code_delay(code, code == KC_CAPS_LOCK ? TAP_HOLD_CAPS_DELAY : TAP_CODE_DELAY); }  /** \brief Adds the given physically pressed modifiers and sends a keyboard report immediately.   * @@ -988,6 +1034,10 @@ void clear_keyboard_but_mods_and_keys() {      mousekey_clear();      mousekey_send();  #endif +#ifdef PROGRAMMABLE_BUTTON_ENABLE +    programmable_button_clear(); +    programmable_button_send(); +#endif  }  /** \brief Utilities for actions. (FIXME: Needs better description) @@ -1028,7 +1078,7 @@ bool is_tap_action(action_t action) {          case ACT_LAYER_TAP:          case ACT_LAYER_TAP_EXT:              switch (action.layer_tap.code) { -                case KC_NO ... KC_RGUI: +                case KC_NO ... KC_RIGHT_GUI:                  case OP_TAP_TOGGLE:                  case OP_ONESHOT:                      return true; @@ -1036,7 +1086,7 @@ bool is_tap_action(action_t action) {              return false;          case ACT_SWAP_HANDS:              switch (action.swap.code) { -                case KC_NO ... KC_RGUI: +                case KC_NO ... KC_RIGHT_GUI:                  case OP_SH_TAP_TOGGLE:                      return true;              } | 
