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