2022-05-14 08:00:32 +02:00
// Copyright 2021-2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
# include "process_caps_word.h"
bool process_caps_word ( uint16_t keycode , keyrecord_t * record ) {
if ( keycode = = CAPSWRD ) { // Pressing CAPSWRD toggles Caps Word.
if ( record - > event . pressed ) {
caps_word_toggle ( ) ;
}
return false ;
}
# ifndef NO_ACTION_ONESHOT
const uint8_t mods = get_mods ( ) | get_oneshot_mods ( ) ;
# else
const uint8_t mods = get_mods ( ) ;
# endif // NO_ACTION_ONESHOT
if ( ! is_caps_word_on ( ) ) {
// The following optionally turns on Caps Word by holding left and
// right shifts or by double tapping left shift. This way Caps Word
// may be used without needing a dedicated key and also without
// needing combos or tap dance.
# ifdef BOTH_SHIFTS_TURNS_ON_CAPS_WORD
// Many keyboards enable the Command feature by default, which also
// uses left+right shift. It can be configured to use a different
// key combination by defining IS_COMMAND(). We make a non-fatal
// warning if Command is enabled but IS_COMMAND() is *not* defined.
# if defined(COMMAND_ENABLE) && !defined(IS_COMMAND)
# pragma message "BOTH_SHIFTS_TURNS_ON_CAPS_WORD and Command should not be enabled at the same time, since both use the Left Shift + Right Shift key combination. Please disable Command, or ensure that `IS_COMMAND` is not set to (get_mods() == MOD_MASK_SHIFT)."
# else
if ( mods = = MOD_MASK_SHIFT
# ifdef COMMAND_ENABLE
// Don't activate Caps Word at the same time as Command.
& & ! ( IS_COMMAND ( ) )
# endif // COMMAND_ENABLE
) {
caps_word_on ( ) ;
}
# endif // defined(COMMAND_ENABLE) && !defined(IS_COMMAND)
# endif // BOTH_SHIFTS_TURNS_ON_CAPS_WORD
# ifdef DOUBLE_TAP_SHIFT_TURNS_ON_CAPS_WORD
// Double tapping left shift turns on Caps Word.
//
// NOTE: This works with KC_LSFT and one-shot left shift. It
// wouldn't make sense with mod-tap or Space Cadet shift since
// double tapping would of course trigger the tapping action.
if ( record - > event . pressed ) {
static bool tapped = false ;
static uint16_t timer = 0 ;
if ( keycode = = KC_LSFT | | keycode = = OSM ( MOD_LSFT ) ) {
if ( tapped & & ! timer_expired ( record - > event . time , timer ) ) {
// Left shift was double tapped, activate Caps Word.
caps_word_on ( ) ;
}
tapped = true ;
timer = record - > event . time + GET_TAPPING_TERM ( keycode , record ) ;
} else {
tapped = false ; // Reset when any other key is pressed.
}
}
# endif // DOUBLE_TAP_SHIFT_TURNS_ON_CAPS_WORD
return true ;
}
# if CAPS_WORD_IDLE_TIMEOUT > 0
caps_word_reset_idle_timer ( ) ;
# endif // CAPS_WORD_IDLE_TIMEOUT > 0
// From here on, we only take action on press events.
if ( ! record - > event . pressed ) {
return true ;
}
2022-05-20 02:39:00 +02:00
if ( ! ( mods & ~ ( MOD_MASK_SHIFT | MOD_BIT ( KC_RALT ) ) ) ) {
2022-05-14 08:00:32 +02:00
switch ( keycode ) {
// Ignore MO, TO, TG, TT, and OSL layer switch keys.
case QK_MOMENTARY . . . QK_MOMENTARY_MAX :
case QK_TO . . . QK_TO_MAX :
case QK_TOGGLE_LAYER . . . QK_TOGGLE_LAYER_MAX :
case QK_LAYER_TAP_TOGGLE . . . QK_LAYER_TAP_TOGGLE_MAX :
case QK_ONE_SHOT_LAYER . . . QK_ONE_SHOT_LAYER_MAX :
2022-05-20 02:39:00 +02:00
// Ignore AltGr.
case KC_RALT :
case OSM ( MOD_RALT ) :
2022-05-14 08:00:32 +02:00
return true ;
# ifndef NO_ACTION_TAPPING
case QK_MOD_TAP . . . QK_MOD_TAP_MAX :
if ( record - > tap . count = = 0 ) {
// Deactivate if a mod becomes active through holding
// a mod-tap key.
caps_word_off ( ) ;
return true ;
}
keycode & = 0xff ;
break ;
# ifndef NO_ACTION_LAYER
case QK_LAYER_TAP . . . QK_LAYER_TAP_MAX :
# endif // NO_ACTION_LAYER
if ( record - > tap . count = = 0 ) {
return true ;
}
keycode & = 0xff ;
break ;
# endif // NO_ACTION_TAPPING
# ifdef SWAP_HANDS_ENABLE
case QK_SWAP_HANDS . . . QK_SWAP_HANDS_MAX :
if ( keycode > 0x56F0 | | record - > tap . count = = 0 ) {
return true ;
}
keycode & = 0xff ;
break ;
# endif // SWAP_HANDS_ENABLE
}
2022-08-13 15:48:51 +02:00
# ifdef AUTO_SHIFT_ENABLE
del_weak_mods ( get_autoshift_state ( ) ? ~ MOD_BIT ( KC_LSFT ) : 0xff ) ;
# else
2022-05-14 08:00:32 +02:00
clear_weak_mods ( ) ;
2022-08-13 15:48:51 +02:00
# endif // AUTO_SHIFT_ENABLE
2022-05-14 08:00:32 +02:00
if ( caps_word_press_user ( keycode ) ) {
send_keyboard_report ( ) ;
return true ;
}
}
caps_word_off ( ) ;
return true ;
}
__attribute__ ( ( weak ) ) bool caps_word_press_user ( uint16_t keycode ) {
switch ( keycode ) {
// Keycodes that continue Caps Word, with shift applied.
case KC_A . . . KC_Z :
case KC_MINS :
add_weak_mods ( MOD_BIT ( KC_LSFT ) ) ; // Apply shift to next key.
return true ;
// Keycodes that continue Caps Word, without shifting.
case KC_1 . . . KC_0 :
case KC_BSPC :
case KC_DEL :
case KC_UNDS :
return true ;
default :
return false ; // Deactivate Caps Word.
}
}