Show me your favorite QMK hacks!


#42

What would be the best way to toggle enable/disable of a single key?

I want to disable the GUI key while I play video games. I know I could add a persistent layer with the same default layer mapping and just reassign the GUI key to KC_NO, but I was wondering if there was a better way.


#43

@Ibexlord Yeah, should, I think. layer_on(x) and layer_off(x) are the functions for that.

@mmgreenmms That depends. For the GUI, there are actually some keycodes to do that already.
MAGIC_NO_GUI and MAGIC_UNNO_GUI will disable and enable the GUI button, respectively. Which may be easier than another layer.


#44

I joined the GB for the Chicory40… this thread will be more useful than ever :slight_smile:


#45

Not much of a hack but the Hyper mod is excellent for making your own shortcuts, especially when you have lots of nesting of apps and you don’t want to have to avoid conflicting bindings (like vim inside a tmux session inside a terminal).


#46

Great idea! I am starting with tinkering with qmk keymaps/macros for my massdrop/InputClub infinity keyboard. Could you give me pointers on what you did to make the macro to make the ALT keys work as desktop switching shortcuts.


#47

After playing with my qmk keymap with limited success, I found the same info here


#48

I loved the @dc_in_sf idea, and set out to implement it in process_record_user. The following changes in keymap.c work for me - YMMV.

Define a couple new keycodes and create a couple of timers for tap detection:

// Key must be released within this many milliseconds to be considered a tap
#define TAPPING_TERM 200

// Timers for tap detection in process_record_user
uint16_t lalt_timer;
uint16_t ralt_timer;

// create some custom keycodes for your keymap
enum custom_keycodes {
  PREV_DESKTOP = SAFE_RANGE,
  NEXT_DESKTOP
};

// define some useful send strings
#define SS_PREV_DESKTOP SS_LCTRL(SS_LGUI(SS_TAP(X_LEFT)))
#define SS_NEXT_DESKTOP SS_LCTRL(SS_LGUI(SS_TAP(X_RIGHT)))

In keymaps, change the LALT and RALT keys to invoke the new keycodes, like so:

KC_LCTL, KC_LGUI, PREV_DESKTOP, KC_SPC, NEXT_DESKTOP, KC_RGUI, MO(_FL), KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT \

And finally, in process_record_user(), handle events for the alt keys. The timers tell us when a key was released quickly enough to be considered a tap, so that we can invoke the desktop switching keystroke sequence.

bool process_record_user(uint16_t keycode, keyrecord_t *record) {

  switch(keycode) {
  case PREV_DESKTOP:
    if (record->event.pressed) {
      // Activate LALT
      lalt_timer = timer_read();
      SEND_STRING(SS_DOWN(X_LALT));
    } else {
      // Deactivate LALT
      SEND_STRING(SS_UP(X_LALT));
      // If the action was a tap
      if (timer_elapsed(lalt_timer) < TAPPING_TERM) {
	    SEND_STRING(SS_PREV_DESKTOP);
      }
    }
    return false;

  case NEXT_DESKTOP:
    if (record->event.pressed) {
      // Activate RALT
      ralt_timer = timer_read();
      SEND_STRING(SS_DOWN(X_RALT));
    } else {
      // Deactivate RALT
      SEND_STRING(SS_UP(X_RALT));
      // If the action was a tap
      if (timer_elapsed(ralt_timer) < TAPPING_TERM) {
	    SEND_STRING(SS_NEXT_DESKTOP);
      }
    }
    return false;
  }
  return true;
}

#49

I figured you probably needed to wire your own timers to make this work, thanks for the code sample, when my current work craziness dies down going to take a look at stealing this and merging into my user space stuff to simplify all my keymaps :smile:


#50

Thanks a lot, I’ll try this one too. The other link I had given in my previous post worked too, I did notice the qmk docs seemed to indicate that the process_record_user was the new way of doing stuff and the earlier method (which was carry over code from TMK) might get deprecated.


#51

Right…had it not been for the word “deprecated”, I would have just grabbed everything from that link too. On the other hand, that’s what forced me to dive into the QMK code, which I had been putting off for a while. Excited now about exploring QMK further…


#52

So got this working in my user space, which I am very happy about as it means I can clean up a lot of the code in my keymap.c files.

Quick question though, as I understand it you are sending a press/release of alt even if a hold is detected. This works for alt since a press/release is fairly innocuous but does mean that the technique can’t easily be extended to other key combos.

Ideally the hold key would only activate after the tapping timeout, but I don’t think process_record_user gets called if there isn’t a keyboard event, so I can’t do the calculation inside of there. Would this be something that needs to be implemented in matrix_scan_user?


#53

Glad that at least it worked for the ALT case!

I believe you’re correct - process_record_user won’t get called unless there is a keyboard event, so if you want the hold key to activate when TAPPING_TERM is reached, that would have to be done elsewhere.

I haven’t done anything with matrix_scan_user yet, but the warning here about the matrix_scan functions suggests reaching out to the QMK guys might be a good idea.