diff options
| -rw-r--r-- | doc/keymap.md | 13 | ||||
| -rw-r--r-- | tmk_core/common/action.c | 57 | ||||
| -rw-r--r-- | tmk_core/common/action_code.h | 28 | 
3 files changed, 89 insertions, 9 deletions
diff --git a/doc/keymap.md b/doc/keymap.md index 1285ad6cd1..6f2a663fc8 100644 --- a/doc/keymap.md +++ b/doc/keymap.md @@ -456,8 +456,9 @@ Turn the backlight on and off without changing level.  ### 2.6 Swap-Hands Action -The swap-hands action allows support for one-handed keyboards without requiring a separate layer. Set `ONEHAND_ENABLE` in the Makefile and define a `hand_swap_config` entry in your keymap. Now whenever the `ACTION_SWAP_HANDS` command is executed the keyboard is mirrored. For instance, to type "Hello, World" on QWERTY you would type `^Ge^s^s^w^c W^wr^sd` +The swap-hands action allows support for one-handed keyboards without requiring a separate layer. Set `ONEHAND_ENABLE` in the Makefile and define a `hand_swap_config` entry in your keymap. Now whenever the `ACTION_SWAP_HANDS` command key is pressed the keyboard is mirrored. For instance, to type "Hello, World" on QWERTY you would type `^Ge^s^s^w^c W^wr^sd` +### 2.6.1 Configuration  The configuration table is a simple 2-dimensional array to map from column/row to new column/row. Example `hand_swap_config` for Planck:  ``` @@ -471,6 +472,16 @@ const keypos_t hand_swap_config[MATRIX_ROWS][MATRIX_COLS] = {  Note that the array indices are reversed same as the matrix and the values are of type `keypos_t` which is `{col, row}` and all values are zero-based. In the example above, `hand_swap_config[2][4]` (third row, fifth column) would return {7, 2} (third row, eighth column). +### 2.6.2 Advanced Swap Commands +- **`ACTION_SWAP_HANDS()`** Swaps hands when pressed, returns to normal when released (momentary). +- **`ACTION_SWAP_HANDS_TOGGLE()`** Toggles swap on and off with every keypress. +- **`ACTION_SWAP_HANDS_TAP_TOGGLE()`** Toggles with a tap; momentary when held. +- **`ACTION_SWAP_HANDS_TAP_KEY(key)`** Sends `key` with a tap; momentary swap when held. +- **`ACTION_SWAP_HANDS_ON_OFF()`** Alias for `ACTION_SWAP_HANDS()` +- **`ACTION_SWAP_HANDS_OFF_ON()`** Momentarily turns off swap. +- **`ACTION_SWAP_HANDS_ON()`** Turns on swapping and leaves it on. +- **`ACTION_SWAP_HANDS_OFF()`** Turn off swapping and leaves it off. Good for returning to a known state. +  ## 3. Layer switching Example diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c index 0413b1a997..08ef22eb97 100644 --- a/tmk_core/common/action.c +++ b/tmk_core/common/action.c @@ -465,14 +465,55 @@ void process_action(keyrecord_t *record, action_t action)              break;  #endif          case ACT_COMMAND: -            switch (action.command.id) { +            break;  #ifdef ONEHAND_ENABLE -                case CMD_SWAP_HANDS: +        case ACT_SWAP_HANDS: +            switch (action.swap.code) { +                case OP_SH_TOGGLE: +                    if (event.pressed) { +                        swap_hands = !swap_hands; +                    } +                    break; +                case OP_SH_ON_OFF:                      swap_hands = event.pressed;                      break; -#endif +                case OP_SH_OFF_ON: +                    swap_hands = !event.pressed; +                    break; +                case OP_SH_ON: +                    if (!event.pressed) { +                        swap_hands = true; +                    } +                    break; +                case OP_SH_OFF: +                    if (!event.pressed) { +                        swap_hands = false; +                    } +                    break; +    #ifndef NO_ACTION_TAPPING +                case OP_SH_TAP_TOGGLE: +                    /* tap toggle */ +                    if (tap_count > 0) { +                        if (!event.pressed) { +                            swap_hands = !swap_hands; +                        } +                    } else { +                        swap_hands = event.pressed; +                    } +                    break; +                default: +                    if (tap_count > 0) { +                        if (event.pressed) { +                            register_code(action.swap.code); +                        } else { +                            unregister_code(action.swap.code); +                        } +                    } else { +                        swap_hands = event.pressed; +                    } +    #endif              } -            break; +#endif  #ifndef NO_ACTION_FUNCTION          case ACT_FUNCTION:              action_function(record, action.func.id, action.func.opt); @@ -685,6 +726,13 @@ bool is_tap_key(keypos_t key)                      return true;              }              return false; +        case ACT_SWAP_HANDS: +            switch (action.swap.code) { +                case 0x00 ... 0xdf: +                case OP_SH_TAP_TOGGLE: +                    return true; +            } +            return false;          case ACT_MACRO:          case ACT_FUNCTION:              if (action.func.opt & FUNC_TAP) { return true; } @@ -725,6 +773,7 @@ void debug_action(action_t action)          case ACT_MACRO:             dprint("ACT_MACRO");             break;          case ACT_COMMAND:           dprint("ACT_COMMAND");           break;          case ACT_FUNCTION:          dprint("ACT_FUNCTION");          break; +        case ACT_SWAP_HANDS:        dprint("ACT_SWAP_HANDS");        break;          default:                    dprint("UNKNOWN");               break;      }      dprintf("[%X:%02X]", action.kind.param>>8, action.kind.param&0xff); diff --git a/tmk_core/common/action_code.h b/tmk_core/common/action_code.h index 95d2cbf3e4..33da35f35f 100644 --- a/tmk_core/common/action_code.h +++ b/tmk_core/common/action_code.h @@ -108,6 +108,8 @@ enum action_kind_id {      /* Other Keys */      ACT_USAGE           = 0b0100,      ACT_MOUSEKEY        = 0b0101, +    /* One-hand Support */ +    ACT_SWAP_HANDS      = 0b0110,      /* Layer Actions */      ACT_LAYER           = 0b1000,      ACT_LAYER_TAP       = 0b1010, /* Layer  0-15 */ @@ -178,6 +180,11 @@ typedef union {          uint8_t  opt    :4;          uint8_t  kind   :4;      } func; +    struct action_swap { +        uint8_t  code   :8; +        uint8_t  opt   :4; +        uint8_t  kind   :4; +    } swap;  } action_t; @@ -296,9 +303,6 @@ enum backlight_opt {      BACKLIGHT_LEVEL    = 4,  }; -enum command_id { -    CMD_SWAP_HANDS = 0x14, -};  /* Macro */  #define ACTION_MACRO(id)                ACTION(ACT_MACRO, (id))  #define ACTION_MACRO_TAP(id)            ACTION(ACT_MACRO, FUNC_TAP<<8 | (id)) @@ -319,6 +323,22 @@ enum function_opts {  #define ACTION_FUNCTION_TAP(id)         ACTION(ACT_FUNCTION, FUNC_TAP<<8 | (id))  #define ACTION_FUNCTION_OPT(id, opt)    ACTION(ACT_FUNCTION, (opt)<<8 | (id))  /* OneHand Support */ -#define ACTION_SWAP_HANDS()             ACTION_COMMAND(CMD_SWAP_HANDS, 0) +enum swap_hands_pram_tap_op { +    OP_SH_TOGGLE = 0xF0, +    OP_SH_TAP_TOGGLE, +    OP_SH_ON_OFF, +    OP_SH_OFF_ON, +    OP_SH_OFF, +    OP_SH_ON, +}; + +#define ACTION_SWAP_HANDS()             ACTION_SWAP_HANDS_ON_OFF() +#define ACTION_SWAP_HANDS_TOGGLE()      ACTION(ACT_SWAP_HANDS, OP_SH_TOGGLE) +#define ACTION_SWAP_HANDS_TAP_TOGGLE()  ACTION(ACT_SWAP_HANDS, OP_SH_TAP_TOGGLE) +#define ACTION_SWAP_HANDS_TAP_KEY(key)  ACTION(ACT_SWAP_HANDS, key) +#define ACTION_SWAP_HANDS_ON_OFF()      ACTION(ACT_SWAP_HANDS, OP_SH_ON_OFF) +#define ACTION_SWAP_HANDS_OFF_ON()      ACTION(ACT_SWAP_HANDS, OP_SH_OFF_ON) +#define ACTION_SWAP_HANDS_ON()          ACTION(ACT_SWAP_HANDS, OP_SH_ON) +#define ACTION_SWAP_HANDS_OFF()         ACTION(ACT_SWAP_HANDS, OP_SH_OFF)  #endif /* ACTION_CODE_H */  | 
