qmk_firmware-mirror/docs/ref_functions.md
Andre Brait 3cf94cb308
Add easier way to set default single layer (#24376)
* Add set_single_default_layer to match set_single_persistent_default_layer
* Implements exactly the same behavior, except the write to EEPROM
2024-10-06 21:39:21 +13:00

5.6 KiB
Raw Permalink Blame History

List of Useful Core Functions To Make Your Keyboard Better

There are a lot of hidden functions in QMK that are incredibly useful, or may add a bit of functionality that you've been wanting. Functions that are specific to certain features are not included here, as those will be on their respective feature page.

(OLKB) Tri Layers

There are actually separate functions that you can use there, depending on what you're after.

update_tri_layer(x, y, z)

The first is the update_tri_layer(x, y, z) function. This function check to see if layers x and y are both on. If they are both on, then it turns on layer z. Otherwise, if both x and y are not both on (either only one is, or neither is), then it turns off layer z.

This function is useful if you want to create specific keys that have this functionality, but other layer keycodes won't do this.

Example

bool process_record_user(uint16_t keycode, keyrecord_t *record) {
  switch (keycode) {
    case LOWER:
      if (record->event.pressed) {
        layer_on(_LOWER);
        update_tri_layer(_LOWER, _RAISE, _ADJUST);
      } else {
        layer_off(_LOWER);
        update_tri_layer(_LOWER, _RAISE, _ADJUST);
      }
      return false;
    case RAISE:
      if (record->event.pressed) {
        layer_on(_RAISE);
        update_tri_layer(_LOWER, _RAISE, _ADJUST);
      } else {
        layer_off(_RAISE);
        update_tri_layer(_LOWER, _RAISE, _ADJUST);
      }
      return false;
    }
  return true;
}

update_tri_layer_state(state, x, y, z)

The other function is update_tri_layer_state(state, x, y, z). This function is meant to be called from the layer_state_set_* functions. This means that any time that you use a keycode to change the layer, this will be checked. So you could use LT(layer, kc) to change the layer and it will trigger the same layer check.

There are a couple of caveats to this method:

  1. You cannot access the z layer without having x and y layers on, since if you try to activate just layer z, it will run this code and turn off layer z before you could use it.
  2. Because layers are processed from the highest number z should be a higher layer than x and y or you may not be able to access it.

Example

layer_state_t layer_state_set_user(layer_state_t state) {
  return update_tri_layer_state(state, _LOWER, _RAISE, _ADJUST);
}

Alternatively, you don't have to immediately "return" the value. This is useful if you want to add multiple tri layers, or if you want to add additional effects.

layer_state_t layer_state_set_user(layer_state_t state) {
  state = update_tri_layer_state(state, _LOWER, _RAISE, _ADJUST);
  state = update_tri_layer_state(state, _RAISE, _SYMB, _SPECIAL);
  return state;
}

Setting the Persistent Default Layer

Do you want to set the default layer, so that it's retained even after you unplug the board? If so, this is the function for you.

To do this, you would use set_single_persistent_default_layer(layer). If you have a name defined for your layer, you can use that instead (such as _QWERTY, _DVORAK or _COLEMAK).

This will set the default layer, update the persistent settings, and play a tune if you have Audio enabled on your board, and the default layer sounds set.

To configure the default layer sounds, you would want to define this in your config.h file, like this:

#define DEFAULT_LAYER_SONGS { SONG(QWERTY_SOUND), \
                              SONG(COLEMAK_SOUND), \
                              SONG(DVORAK_SOUND) \
                            }

If you do not require it to be retained after you unplug the board, use set_single_default_layer(layer) instead.

::: tip There are a large number of predefined songs in quantum/audio/song_list.h that you can use. :::

Resetting the keyboard

There is the QK_REBOOT or QK_RBT quantum keycode that you can use. But if you want to reset the board as part of a macro, rather than hitting a key separately, you can do that.

And to do so, add soft_reset_keyboard() to your function or macro.

Reset to bootloader

To reset to the bootloader use QK_BOOTLOADER or QK_BOOT keycode or reset_keyboard() function.

Wiping the EEPROM (Persistent Storage)

If you're having issues with Audio, RGB Underglow, backlighting or keys acting weird, then you can reset the EEPROM (persistent setting storage). To force an EEPROM reset, use the EE_CLR keycode or Bootmagic functionality. If neither of those are an option, then you can use a custom macro to do so.

To wipe the EEPROM, run eeconfig_init() from your function or macro to reset most of the settings to default.

Tap random key

If you want to send a random character to the host computer, you can use the tap_random_base64() function. This pseudorandomly selects a number between 0 and 63, and then sends a key press based on that selection. (025 is AZ, 2651 is az, 5261 is 09, 62 is + and 63 is /).

::: tip Needless to say, but this is not a cryptographically secure method of generating random Base64 keys or passwords. :::

Software Timers

It's possible to start timers and read values for time-specific events. Here's an example:

static uint16_t key_timer;
key_timer = timer_read();

if (timer_elapsed(key_timer) < 100) {
  // do something if less than 100ms have passed
} else {
  // do something if 100ms or more have passed
}