parent
87021371e6
commit
abba393f57
@ -0,0 +1,161 @@ |
||||
# Auto Shift: Why do we need a shift key? |
||||
|
||||
Tap a key and you get its character. Tap a key, but hold it *slightly* longer |
||||
and you get its shifted state. Viola! No shift key needeed! |
||||
|
||||
## Why Auto Shift? |
||||
|
||||
Many people suffer from various forms of RSI. A common cause is stretching your |
||||
fingers repeitively long distances. For us on the keyboard, the pinky does that |
||||
all too often when reaching for the shift key. Auto Shift looks to aliviate that |
||||
problem. |
||||
|
||||
## How does it work? |
||||
|
||||
When you tap a key, it stays depressed for a short period of time before it is |
||||
then released. This depressed time is a different length everyone. Auto Shift |
||||
defines a constant `AUTO_SHIFT_TIMEOUT` which is typically set to twice your |
||||
normal pressed state time. When you press a key, a timer starts and then stops |
||||
when you release the key. If the time depressed is greater than or equal to the |
||||
`AUTO_SHIFT_TIMEOUT` then a shifted version of the key is emitted. If the time |
||||
is less than the `AUTO_SHIFT_TIMEOUT` time, then the normal state is emitted. |
||||
|
||||
## Are there limitations to Auto Shift? |
||||
|
||||
Yes, unfortunately. |
||||
|
||||
1. Key repeat will cease to work. For example, before if you wanted 20 'a' |
||||
characters, you could press and hold the 'a' key for a second or two. This no |
||||
longer works with Auto Shift because it is timing your depressed time instead |
||||
of emitting a depressed key state to your operating system. |
||||
2. Auto Shift is disabled for any key press that is accompanied by one or more |
||||
modifiers. Thus, Ctrl+A that you hold for a really long time is not the same |
||||
as Ctrl+Shift+A. |
||||
3. You will have characters that are shifted you did not intend on shifting, and |
||||
other characters you wanted shifted, but were not. This simply comes down to |
||||
practice. As we get in a hurry, we think we might have hit the key long enough |
||||
for a shifted version, but we did not. On the other hand, we may think we are |
||||
tapping the keys, but really we have held it for a little longer than |
||||
anticipated. |
||||
|
||||
## How do I enable Auto Shift? |
||||
|
||||
Add to your `rules.mk` in the keymap folder: |
||||
|
||||
AUTO_SHIFT_ENABLE = YES |
||||
|
||||
If no `rules.mk` exists, you can create one. |
||||
|
||||
Then compile and install your new firmware with Auto Key enabled! That's it! |
||||
|
||||
## Configuring Auto Shift |
||||
|
||||
If desired, there is some configuration that can be done to change the |
||||
behavior of Auto Shift. This is done by setting various variables the |
||||
`config.h` file located in your keymap folder. |
||||
|
||||
If no `config.h` file exists, you can create one. A sample is |
||||
|
||||
#ifndef CONFIG_USER_H |
||||
#define CONFIG_USER_H |
||||
|
||||
#include "../../config.h" |
||||
|
||||
#define AUTO_SHIFT_TIMEOUT 150 |
||||
#define NO_AUTO_SHIFT_SPECIAL |
||||
|
||||
#endif |
||||
|
||||
### AUTO_SHIFT_TIMEOUT (value in ms) |
||||
|
||||
This controls how long you have to hold a key before you get the shifted state. |
||||
Obviously, this is different for everyone. For the common person a setting of |
||||
135 to 150 works great but one should start with a value of at least 175, which |
||||
is the default value. Then work down from there. The idea is to have as short |
||||
of a time required to get the shifted state without having false positives. |
||||
|
||||
Play with this value until things are perfect. Many find that all will work well |
||||
at a given value, but one or two keys will still emit the shifted state on |
||||
occassion. This is simply due to habit and holding some keys a little longer |
||||
than others. Once you find this value, work on tapping your problem keys a little |
||||
quicker than normal and you will be set. |
||||
|
||||
{% hint style='info' %} |
||||
Auto Shift has three special keys that can help you get this value right very |
||||
quick. See "Auto Shift Setup" for more details! |
||||
{% endhint %} |
||||
|
||||
### NO_AUTO_SHIFT_SPECIAL (simple define) |
||||
|
||||
Do not Auto Shift special keys, which include -_, =+, [{, ]}, ;:, '", ,<, .>, |
||||
and /? |
||||
|
||||
### NO_AUTO_SHIFT_NUMERIC (simple define) |
||||
|
||||
Do not Auto Shift numeric keys, zero through nine. |
||||
|
||||
### NO_AUTO_SHIFT_ALPHA (simple define) |
||||
|
||||
Do not Auto Shift alpha characters, which include A through Z. |
||||
|
||||
## Using Auto Shift Setup |
||||
|
||||
This will enable you to define three keys temporailiy to increase, decrease and report your `AUTO_SHIFT_TIMEOUT`. |
||||
|
||||
### Setup |
||||
|
||||
Map three keys temporarily in your keymap: |
||||
|
||||
| Key Name | Description | |
||||
|----------|-----------------------------------------------------| |
||||
| KC_ASDN | Lower the Auto Shift timeout variable (down) | |
||||
| KC_ASUP | Raise the Auto Shift timeout variable (up) | |
||||
| KC_ASRP | Report your current Auto Shift timeout value | |
||||
|
||||
Compile and upload your new firmware. |
||||
|
||||
### Use |
||||
|
||||
It is important to note that during these tests, you should be typing |
||||
completely normal and with no intention of shifted keys. |
||||
|
||||
1. Type multiple sentences of alphabetical letters. |
||||
2. Observe any upper case letters. |
||||
3. If there are none, press the key you have mapped to `KC_ASDN` to decrease |
||||
time Auto Shift timeout value and go back to step 1. |
||||
4. If there are some upper case letters, decide if you need to work on tapping |
||||
those keys with less down time, or if you need to increase the timeout. |
||||
5. If you decide to increase the timeout, press the key you have mapped to |
||||
`KC_ASUP` and go back to step 1. |
||||
6. Once you are happy with your results, press the key you have mapped to |
||||
`KC_ASRP`. The keyboard will type by itself the value of your |
||||
`AUTO_SHIFT_TIMEOUT`. |
||||
7. Update `AUTO_SHIFT_TIMEOUT` in your `config.h` with the value reported. |
||||
8. Remove `AUTO_SHIFT_SETUP` from your `config.h`. |
||||
9. Remove the key bindings `KC_ASDN`, `KC_ASUP` and `KC_ASRP`. |
||||
10. Compile and upload your new firmware. |
||||
|
||||
#### An example run |
||||
|
||||
\'\'\' |
||||
hello world. my name is john doe. i am a computer programmer playing with |
||||
keyboards right now. |
||||
|
||||
[PRESS KC_ASDN quite a few times] |
||||
|
||||
heLLo woRLd. mY nAMe is JOHn dOE. i AM A compUTeR proGRaMMER PlAYiNG witH |
||||
KEYboArDS RiGHT NOw. |
||||
|
||||
[PRESS KC_ASUP a few times] |
||||
|
||||
hello world. my name is john Doe. i am a computer programmer play with |
||||
keyboarDs right now. |
||||
|
||||
[PRESS KC_ASRP] |
||||
|
||||
115 |
||||
\'\'\' |
||||
|
||||
The keyboard typed `115` which represents your current `AUTO_SHIFT_TIMEOUT` |
||||
value. You are now set! Practice on the *D* key a little bit that showed up |
||||
in the testing and you'll be golden. |
@ -0,0 +1,168 @@ |
||||
/* Copyright 2017 Jeremy Cowgar
|
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License as published by |
||||
* the Free Software Foundation, either version 2 of the License, or |
||||
* (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ |
||||
|
||||
#ifdef AUTO_SHIFT_ENABLE |
||||
|
||||
#include <stdio.h> |
||||
|
||||
#include "process_auto_shift.h" |
||||
|
||||
#define TAP(key) \ |
||||
register_code(key); \
|
||||
unregister_code(key) |
||||
|
||||
#define TAP_WITH_MOD(mod, key) \ |
||||
register_code(mod); \
|
||||
register_code(key); \
|
||||
unregister_code(key); \
|
||||
unregister_code(mod) |
||||
|
||||
uint16_t autoshift_time = 0; |
||||
uint16_t autoshift_timeout = AUTO_SHIFT_TIMEOUT; |
||||
uint16_t autoshift_lastkey = KC_NO; |
||||
|
||||
void autoshift_timer_report(void) { |
||||
char display[8]; |
||||
|
||||
snprintf(display, 8, "\n%d\n", autoshift_timeout); |
||||
|
||||
send_string((const char *)display); |
||||
} |
||||
|
||||
void autoshift_on(uint16_t keycode) { |
||||
autoshift_time = timer_read(); |
||||
autoshift_lastkey = keycode; |
||||
} |
||||
|
||||
void autoshift_flush(void) { |
||||
if (autoshift_lastkey != KC_NO) { |
||||
uint16_t elapsed = timer_elapsed(autoshift_time); |
||||
|
||||
if (elapsed > autoshift_timeout) { |
||||
register_code(KC_LSFT); |
||||
} |
||||
|
||||
register_code(autoshift_lastkey); |
||||
unregister_code(autoshift_lastkey); |
||||
|
||||
if (elapsed > autoshift_timeout) { |
||||
unregister_code(KC_LSFT); |
||||
} |
||||
|
||||
autoshift_time = 0; |
||||
autoshift_lastkey = KC_NO; |
||||
} |
||||
} |
||||
|
||||
bool process_auto_shift(uint16_t keycode, keyrecord_t *record) { |
||||
static uint8_t any_mod_pressed; |
||||
|
||||
if (record->event.pressed) { |
||||
switch (keycode) { |
||||
case KC_ASUP: |
||||
autoshift_timeout += 5; |
||||
return false; |
||||
|
||||
case KC_ASDN: |
||||
autoshift_timeout -= 5; |
||||
return false; |
||||
|
||||
case KC_ASRP: |
||||
autoshift_timer_report(); |
||||
return false; |
||||
|
||||
#ifndef NO_AUTO_SHIFT_ALPHA |
||||
case KC_A: |
||||
case KC_B: |
||||
case KC_C: |
||||
case KC_D: |
||||
case KC_E: |
||||
case KC_F: |
||||
case KC_G: |
||||
case KC_H: |
||||
case KC_I: |
||||
case KC_J: |
||||
case KC_K: |
||||
case KC_L: |
||||
case KC_M: |
||||
case KC_N: |
||||
case KC_O: |
||||
case KC_P: |
||||
case KC_Q: |
||||
case KC_R: |
||||
case KC_S: |
||||
case KC_T: |
||||
case KC_U: |
||||
case KC_V: |
||||
case KC_W: |
||||
case KC_X: |
||||
case KC_Y: |
||||
case KC_Z: |
||||
#endif |
||||
#ifndef NO_AUTO_SHIFT_NUMERIC |
||||
case KC_1: |
||||
case KC_2: |
||||
case KC_3: |
||||
case KC_4: |
||||
case KC_5: |
||||
case KC_6: |
||||
case KC_7: |
||||
case KC_8: |
||||
case KC_9: |
||||
case KC_0: |
||||
#endif |
||||
#ifndef NO_AUTO_SHIFT_SPECIAL |
||||
case KC_TILD: |
||||
case KC_MINUS: |
||||
case KC_EQL: |
||||
case KC_TAB: |
||||
case KC_LBRC: |
||||
case KC_RBRC: |
||||
case KC_BSLS: |
||||
case KC_SCLN: |
||||
case KC_QUOT: |
||||
case KC_COMM: |
||||
case KC_DOT: |
||||
case KC_SLSH: |
||||
#endif |
||||
autoshift_flush(); |
||||
|
||||
any_mod_pressed = get_mods() & ( |
||||
MOD_BIT(KC_LGUI)|MOD_BIT(KC_RGUI)| |
||||
MOD_BIT(KC_LALT)|MOD_BIT(KC_RALT)| |
||||
MOD_BIT(KC_LCTL)|MOD_BIT(KC_RCTL)| |
||||
MOD_BIT(KC_LSFT)|MOD_BIT(KC_RSFT) |
||||
); |
||||
|
||||
if (any_mod_pressed) { |
||||
return true; |
||||
} |
||||
|
||||
autoshift_on(keycode); |
||||
return false; |
||||
|
||||
default: |
||||
autoshift_flush(); |
||||
return true; |
||||
} |
||||
} else { |
||||
autoshift_flush(); |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
|
||||
#endif |
@ -0,0 +1,28 @@ |
||||
/* Copyright 2017 Jeremy Cowgar
|
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License as published by |
||||
* the Free Software Foundation, either version 2 of the License, or |
||||
* (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ |
||||
|
||||
#ifndef PROCESS_AUTO_SHIFT_H |
||||
#define PROCESS_AUTO_SHIFT_H |
||||
|
||||
#include "quantum.h" |
||||
|
||||
#ifndef AUTO_SHIFT_TIMEOUT |
||||
#define AUTO_SHIFT_TIMEOUT 175 |
||||
#endif |
||||
|
||||
bool process_auto_shift(uint16_t keycode, keyrecord_t *record); |
||||
|
||||
#endif |
Loading…
Reference in new issue