~ruther/qmk_firmware

c44fc68297029da87233777aff6978d39caebbb1 — Drashna Jaelre 6 years ago 5fa0a27
Allow Combo feature to be enabled/disabled live (#6318)

* Add ability to enable/disable combos

* Update documentation for Combo feature

* Change keycodes for appeasement

* Simplify combo_toggle function

* Update names

* Update combo docs to use tables
M docs/feature_combo.md => docs/feature_combo.md +23 -9
@@ 59,19 59,12 @@ void process_combo_event(uint8_t combo_index, bool pressed) {
  switch(combo_index) {
    case ZC_COPY:
      if (pressed) {
        register_code(KC_LCTL);
        register_code(KC_C);
        unregister_code(KC_C);
        unregister_code(KC_LCTL);
        tap_code16(LCTL(KC_C));
      }
      break;

    case XV_PASTE:
      if (pressed) {
        register_code(KC_LCTL);
        register_code(KC_V);
        unregister_code(KC_V);
        unregister_code(KC_LCTL);
        tap_code16(LCTL(KC_V));
      }
      break;
  }


@@ 87,3 80,24 @@ If you're using long combos, or even longer combos, you may run into issues with
In this case, you can add either `#define EXTRA_LONG_COMBOS` or `#define EXTRA_EXTRA_LONG_COMBOS` in your `config.h` file.

You may also be able to enable action keys by defining `COMBO_ALLOW_ACTION_KEYS`.

## Keycodes 

You can enable, disable and toggle the Combo feature on the fly.  This is useful if you need to disable them temporarily, such as for a game. 

|Keycode   |Description                      |
|----------|---------------------------------|
|`CMB_ON`  |Turns on Combo feature           |
|`CMB_OFF` |Turns off Combo feature          |
|`CMB_TOG` |Toggles Combo feature on and off |

## User callbacks

In addition to the keycodes, there are a few functions that you can use to set the status, or check it:

|Function   |Description                                                         |
|-----------|--------------------------------------------------------------------|
| `combo_enable()`     | Enables the combo feature                               |
| `combo_disable()`    | Disables the combo feature, and clears the combo buffer |
| `combo_toggle()`     | Toggles the state of the combo feature                  |
| `is_combo_enabled()` | Returns the status of the combo feature state (true or false) |

M quantum/process_keycode/process_combo.c => quantum/process_keycode/process_combo.c +42 -1
@@ 28,6 28,7 @@ static uint16_t timer = 0;
static uint8_t current_combo_index = 0;
static bool drop_buffer = false;
static bool is_active = false;
static bool b_combo_enable = true; // defaults to enabled

static uint8_t buffer_size = 0;
#ifdef COMBO_ALLOW_ACTION_KEYS


@@ 128,6 129,23 @@ bool process_combo(uint16_t keycode, keyrecord_t *record) {
  drop_buffer = false;
  bool no_combo_keys_pressed = true;

  if (keycode == CMB_ON && record->event.pressed) {
    combo_enable();
    return true;
  }

  if (keycode == CMB_OFF && record->event.pressed) {
    combo_disable();
    return true;
  }

  if (keycode == CMB_TOG && record->event.pressed) {
    combo_toggle();
    return true;
  }

  if (!is_combo_enabled()) { return true; }

  for (current_combo_index = 0; current_combo_index < COMBO_COUNT;
       ++current_combo_index) {
    combo_t *combo = &key_combos[current_combo_index];


@@ 166,7 184,7 @@ bool process_combo(uint16_t keycode, keyrecord_t *record) {
}

void matrix_scan_combo(void) {
  if (is_active && timer && timer_elapsed(timer) > COMBO_TERM) {
  if (b_combo_enable && is_active && timer && timer_elapsed(timer) > COMBO_TERM) {

    /* This disables the combo, meaning key events for this
     * combo will be handled by the next processors in the chain


@@ 175,3 193,26 @@ void matrix_scan_combo(void) {
    dump_key_buffer(true);
  }
}

void combo_enable(void) {
    b_combo_enable = true;
}

void combo_disable(void) {
    b_combo_enable = is_active = false;
    timer = 0;
    dump_key_buffer(true);

}

void combo_toggle(void) {
    if (b_combo_enable) {
        combo_disable();
    } else {
        combo_enable();
    }
}

bool is_combo_enabled(void) {
    return b_combo_enable;
}

M quantum/process_keycode/process_combo.h => quantum/process_keycode/process_combo.h +5 -0
@@ 58,4 58,9 @@ bool process_combo(uint16_t keycode, keyrecord_t *record);
void matrix_scan_combo(void);
void process_combo_event(uint8_t combo_index, bool pressed);

void combo_enable(void);
void combo_disable(void);
void combo_toggle(void);
bool is_combo_enabled(void);

#endif

M quantum/quantum_keycodes.h => quantum/quantum_keycodes.h +3 -0
@@ 489,6 489,9 @@ enum quantum_keycodes {
    // Right control, close paren
    KC_RAPC,

    CMB_ON,
    CMB_OFF,
    CMB_TOG,
    // always leave at the end
    SAFE_RANGE
};