qmk/qmk_firmware

[Bug] get_oneshot_locked_mods() returns 0 when two or more locked mods are on then one is disabled

Open

#10,921 opened on Nov 11, 2020

View on GitHub
 (2 comments) (0 reactions) (0 assignees)C (20,368 stars) (43,867 forks)batch import
bughelp wanted

Description

Describe the Bug

I'm writing a line on the display on my Corne keyboard that reports which oneshot keys are active and which oneshot locked keys are active. get_oneshot_mods() works as expected, but get_oneshot_locked_mods() will return a 0 if, for example, Shift is locked on (2), then Left Alt (4). After toggling Left Alt off, get_oneshot_locked_mods() will return 0, even though Shift is still locked on.

System Information

  • Keyboard: crkbd
  • Operating system: Arch Linux
  • AVR GCC version: 8.3.0
  • ARM GCC version: 10.2.0
  • QMK Firmware version: 0.10.51
  • Any keyboard related software installed?
    • AutoHotKey
    • Karabiner
    • Other:

Additional Context

Here is how it's being used:

char mods_str[21] = {};

const char *oneshot_mods_status(uint8_t mods, uint8_t locked_mods) {
  snprintf(mods_str, sizeof(mods_str), " ");
  if (layer_state_is(_STICKY)) {
    char ctrl_status = ' ';
    char shft_status = ' ';
    char lgui_status = ' ';
    char lalt_status = ' ';
    // If there are active mods, denote them with lowercase
    if (mods & MOD_MASK_CTRL) {
      ctrl_status = 'c';
    }
    if (mods & MOD_MASK_SHIFT) {
      shft_status = 's';
    }
    if (mods & MOD_MASK_GUI) {
      lgui_status = 'm';
    }
    if (mods & MOD_MASK_ALT) {
      lalt_status = 'a';
    }
    // And if there are active locked mods, denote those with uppercase
    if (locked_mods & MOD_MASK_CTRL) {
      ctrl_status = 'C';
    }
    if (locked_mods & MOD_MASK_SHIFT) {
      shft_status = 'S';
    }
    if (locked_mods & MOD_MASK_GUI) {
      lgui_status = 'm';
    }
    if (locked_mods & MOD_MASK_ALT) {
      lalt_status = 'A';
    }
    snprintf(mods_str, sizeof(mods_str), "Mods:[%c] [%c] [%c] [%c]", ctrl_status, shft_status, lgui_status, lalt_status);
  }
  return mods_str;
}

void matrix_render_user(struct CharacterMatrix *matrix) {
  if (is_master) {
    // If you want to change the display of OLED, you need to change here
    matrix_write_ln(matrix, read_layer_state());
    matrix_write_ln(matrix, read_keylog());
    // This is what is writing the sticky keys status line
    matrix_write_ln(matrix, oneshot_mods_status(get_oneshot_mods(), get_oneshot_locked_mods()));
    //matrix_write_ln(matrix, read_keylogs());
    //matrix_write_ln(matrix, read_mode_icon(keymap_config.swap_lalt_lgui));
    //matrix_write_ln(matrix, read_host_led_state());
    //matrix_write_ln(matrix, read_timelog());
  } else {
    matrix_write(matrix, read_logo());
  }
}

Contributor guide