Parent directory

process_repeat_key.c

3548 bytes
  1// Copyright 2022-2023 Google LLC
  2//
  3// Licensed under the Apache License, Version 2.0 (the "License");
  4// you may not use this file except in compliance with the License.
  5// You may obtain a copy of the License at
  6//
  7//     https://www.apache.org/licenses/LICENSE-2.0
  8//
  9// Unless required by applicable law or agreed to in writing, software
 10// distributed under the License is distributed on an "AS IS" BASIS,
 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12// See the License for the specific language governing permissions and
 13// limitations under the License.
 14
 15#include "process_repeat_key.h"
 16#include "repeat_key.h"
 17#include "keycodes.h"
 18#include "quantum_keycodes.h"
 19#include "action_util.h"
 20
 21// Default implementation of remember_last_key_user().
 22__attribute__((weak)) bool remember_last_key_user(uint16_t keycode, keyrecord_t* record, uint8_t* remembered_mods) {
 23    return true;
 24}
 25
 26static bool remember_last_key(uint16_t keycode, keyrecord_t* record, uint8_t* remembered_mods) {
 27    switch (keycode) {
 28        // Ignore MO, TO, TG, TT, and TL layer switch keys.
 29        case QK_MOMENTARY ... QK_MOMENTARY_MAX:
 30        case QK_TO ... QK_TO_MAX:
 31        case QK_TOGGLE_LAYER ... QK_TOGGLE_LAYER_MAX:
 32        case QK_LAYER_TAP_TOGGLE ... QK_LAYER_TAP_TOGGLE_MAX:
 33        // Ignore mod keys.
 34        case KC_LCTL ... KC_RGUI:
 35        case KC_HYPR:
 36        case KC_MEH:
 37#ifndef NO_ACTION_ONESHOT // Ignore one-shot keys.
 38        case QK_ONE_SHOT_LAYER ... QK_ONE_SHOT_LAYER_MAX:
 39        case QK_ONE_SHOT_MOD ... QK_ONE_SHOT_MOD_MAX:
 40#endif                  // NO_ACTION_ONESHOT
 41#ifdef TRI_LAYER_ENABLE // Ignore Tri Layer keys.
 42        case QK_TRI_LAYER_LOWER:
 43        case QK_TRI_LAYER_UPPER:
 44#endif // TRI_LAYER_ENABLE
 45            return false;
 46
 47            // Ignore hold events on tap-hold keys.
 48#ifndef NO_ACTION_TAPPING
 49        case QK_MOD_TAP ... QK_MOD_TAP_MAX:
 50#    ifndef NO_ACTION_LAYER
 51        case QK_LAYER_TAP ... QK_LAYER_TAP_MAX:
 52#    endif // NO_ACTION_LAYER
 53            if (record->tap.count == 0) {
 54                return false;
 55            }
 56            break;
 57#endif // NO_ACTION_TAPPING
 58
 59#ifdef SWAP_HANDS_ENABLE
 60        case QK_SWAP_HANDS ... QK_SWAP_HANDS_MAX:
 61            if (IS_SWAP_HANDS_KEYCODE(keycode) || record->tap.count == 0) {
 62                return false;
 63            }
 64            break;
 65#endif // SWAP_HANDS_ENABLE
 66
 67        case QK_REPEAT_KEY:
 68#ifndef NO_ALT_REPEAT_KEY
 69        case QK_ALT_REPEAT_KEY:
 70#endif // NO_ALT_REPEAT_KEY
 71            return false;
 72    }
 73
 74    return remember_last_key_user(keycode, record, remembered_mods);
 75}
 76
 77bool process_last_key(uint16_t keycode, keyrecord_t* record) {
 78    if (get_repeat_key_count()) {
 79        return true;
 80    }
 81
 82    if (record->event.pressed) {
 83        uint8_t remembered_mods = get_mods() | get_weak_mods();
 84#ifndef NO_ACTION_ONESHOT
 85        remembered_mods |= get_oneshot_mods();
 86#endif // NO_ACTION_ONESHOT
 87
 88        if (remember_last_key(keycode, record, &remembered_mods)) {
 89            set_last_record(keycode, record);
 90            set_last_mods(remembered_mods);
 91        }
 92    }
 93
 94    return true;
 95}
 96
 97bool process_repeat_key(uint16_t keycode, keyrecord_t* record) {
 98    if (get_repeat_key_count()) {
 99        return true;
100    }
101
102    if (keycode == QK_REPEAT_KEY) {
103        repeat_key_invoke(&record->event);
104        return false;
105#ifndef NO_ALT_REPEAT_KEY
106    } else if (keycode == QK_ALT_REPEAT_KEY) {
107        alt_repeat_key_invoke(&record->event);
108        return false;
109#endif // NO_ALT_REPEAT_KEY
110    }
111
112    return true;
113}