Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Combo compatibility #5

Open
anderso opened this issue Aug 27, 2024 · 10 comments
Open

Combo compatibility #5

anderso opened this issue Aug 27, 2024 · 10 comments

Comments

@anderso
Copy link

anderso commented Aug 27, 2024

I am interested in trying this out but as I use a lot of combos on the home row, I'd like to know if that is at all possible with this solution? And if so, how? Or even if no consideration for this has been made, a mention of this in the docs would be nice.

@stasmarkin
Copy link
Owner

stasmarkin commented Aug 28, 2024

Hi @anderso !
Thanks for the suggestion, I will add another wiki page with interoperability with qmk features.
Talking about combos, SM_TD works well with QMK combo system. I also have HRM and many combos on the same keys.
You don't have to do anything extra to make it work. Once you change your keymap with CKC_* keycodes, you just need to update combo configurations with those CKC_* keycodes. So, instead of

const uint16_t PROGMEM combo_AS[] = { KC_A, KC_S, COMBO_END }

you must create

const uint16_t PROGMEM combo_AS[] = { CKC_A, CKC_S, COMBO_END }

And so on. Just change the keycodes in each combo accordingly and you are good to go.

@stasmarkin
Copy link
Owner

If you want a combo to be a part of SM_TD (for example, you want to distinguish tap a combo and hold a combo), you will need to imlicitly pass it to SM_TD like that:

void process_combo_event(uint16_t combo_index, bool pressed) {
    switch (combo_index) {
        case DF: {
            keyrecord_t record = {.event = MAKE_KEYEVENT(0, 0, pressed)};
            process_smtd(CKC_DF_COMBO, &record);
            return;
        }
    ...

@anderso
Copy link
Author

anderso commented Aug 28, 2024

Awesome, thanks, l will definitely try this out then. Actually I may not need to change the combos at all since I use a separate combo reference layer.

@stasmarkin
Copy link
Owner

I have another repo with my personal settings, so you may find some useful snippets there. I have many combos in different configurations with SM_TD

https://github.com/stasmarkin/sm_voyager_keymap/blob/main/sm/sm_voyager_combo.h

@anderso
Copy link
Author

anderso commented Sep 8, 2024

The good news is that combos work. The bad news is that they don't interact well with modifiers. I have backspace on combo. I can't do ctrl + backspace without pausing between ctrl and hitting backspace. And if I do multiple modifiers, it seems I need to wait longer.

@stasmarkin
Copy link
Owner

Take a look at my CKC_DF_COMBO. Just call process_smtd() from process_combo_event(), so sm_td will know that you pressed another key and it will immediately interpret SMTD_MT as hold.
If you need further assistance, please share your configuration, so I could give you an exact patch

@anderso
Copy link
Author

anderso commented Sep 22, 2024

Thanks! I did try the following after looking at your code:

void on_smtd_action(uint16_t keycode, smtd_action action, uint8_t tap_count) { 
    switch (keycode) {
        SMTD_MT(CKC_N, KC_N, KC_LCTL)
    }
}

enum combos {
  AI_BSPC
};

const uint16_t PROGMEM ai_combo[] = {KC_A, KC_I, COMBO_END};

combo_t key_combos[] = {
  [AI_BSPC] = COMBO_ACTION(ai_combo),
};

void process_combo_event(uint16_t combo_index, bool pressed) {
    switch (combo_index) {
        case AI_BSPC: {
            keyrecord_t record = {.event = MAKE_KEYEVENT(0, 0, pressed)};
            process_smtd(KC_BSPC, &record);
            if (pressed) {
                tap_code16(KC_BSPC);
            }
            return;
        }
    }
}

But holding N and then pressing A and I in quick succession still does not produce ctrl-backspace, if I wait a bit it works. I can for example hold N and S quickly for ctrl-S. Any ideas?

@stasmarkin
Copy link
Owner

Just noticed, that I have the same issue too...
I will fix it later, however you can try a quick fix here:

        case AI_BSPC: {
            if (pressed) {
                keyrecord_t press = {.event = MAKE_KEYEVENT(0, 0, true)};
                process_smtd(KC_BSPC, &press);
                keyrecord_t release = {.event = MAKE_KEYEVENT(0, 0, false)};
                process_smtd(KC_BSPC, &release);
                tap_code16(KC_BSPC);
            }
            return;
        }

I'm not 100% sure, but that might work for you

@chklauser
Copy link

chklauser commented Feb 3, 2025

Hey, I'm struggling to set up a must-tap combo. I have J and K configured as MT for shift and control

    SMTD_MT(CKC_J, KC_J, KC_RIGHT_SHIFT, 1)
    SMTD_MT(CKC_K, KC_K, KC_RIGHT_CTRL, 1)

With the combo set up as follows:

const uint16_t PROGMEM combo_jk[] = { CKC_J, CKC_K, COMBO_END};

combo_t key_combos[COMBO_COUNT] = {
    // ... other combo
    COMBO(combo_jk, KC_NO),
};

void process_combo_event(uint16_t combo_index, bool pressed) {
  switch(combo_index) {
    case 1: // index of my jk combo
      keyrecord_t record = {.event = MAKE_KEYEVENT(0, 0, pressed)};
      process_smtd(CKC_JK, &record);
      return;
  }
}

and with this block in on_smtd_action:

case CKC_JK:
      switch(action){
        case SMTD_ACTION_TOUCH:
          break;
        case SMTD_ACTION_TAP:
          tap_code16(KC_RIGHT_ALT);
          break;
        case SMTD_ACTION_HOLD:
          register_mods(MOD_BIT(KC_RSFT) | MOD_BIT(KC_RCTL));
          break;
        case SMTD_ACTION_RELEASE:
          unregister_mods(MOD_BIT(KC_RSFT) | MOD_BIT(KC_RCTL));
          break;
      }
      return;

Background/Intention

Right Alt is my compose key. I never want to hold that key. I only ever want to tap it. A hold of the combo should ideally be interpreted as if the combo didn't exist (just the hold of the individual keys MT keys).

Right now, I can never get the tap action of the combo to fire. Earlier, I had accidentally set up the combo with COMBO(combo_jk, KC_RIGHT_ALT), with which I got the right alt tap, but not the shift+ctrl hold.

Am I doing something obviously wrong?

@stasmarkin
Copy link
Owner

@chklauser try to define combos with COMBO_ACTION instead of single COMBO
That would require you to introduce process_combo_event function (see https://docs.qmk.fm/features/combo )
I'm not sure why yet, but in some cases COMBO() doesn't work with sm_td

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants