-
Notifications
You must be signed in to change notification settings - Fork 261
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This commit provides a new plugin “LongPress” that allows producing different Keys when keys are held for a short time instead of only tapped. It is based on the existing “AutoShift” plugin and contains its functionality, but extends it for a broader area of application. Signed-off-by: Marco Herrn <[email protected]>
- Loading branch information
Showing
19 changed files
with
1,576 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
// -*- mode: c++ -*- | ||
|
||
#include <Kaleidoscope.h> | ||
|
||
#include <Kaleidoscope-LongPress.h> | ||
#include <Kaleidoscope-EEPROM-Settings.h> | ||
#include <Kaleidoscope-EEPROM-Keymap.h> | ||
#include <Kaleidoscope-FocusSerial.h> | ||
#include <Kaleidoscope-Macros.h> | ||
|
||
enum { | ||
TOGGLE_LONGPRESS, | ||
}; // macros | ||
|
||
enum { | ||
QWERTY, | ||
}; // layers | ||
|
||
// clang-format off | ||
KEYMAPS( | ||
[QWERTY] = KEYMAP_STACKED | ||
( | ||
Key_NoKey, Key_1, Key_2, Key_3, Key_4, Key_5, Key_NoKey, | ||
Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab, | ||
Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G, | ||
Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape, | ||
|
||
Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift, | ||
XXX, | ||
|
||
M(TOGGLE_LONGPRESS), Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip, | ||
Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals, | ||
Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote, | ||
Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus, | ||
|
||
Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl, | ||
XXX | ||
), | ||
) | ||
// clang-format on | ||
|
||
// Defining a macro (on the "any" key: see above) to turn LongPress on and off | ||
const macro_t *macroAction(uint8_t macro_id, KeyEvent &event) { | ||
switch (macro_id) { | ||
case TOGGLE_LONGPRESS: | ||
if (keyToggledOn(event.state)) | ||
LongPress.toggle(); | ||
break; | ||
} | ||
return MACRO_NONE; | ||
} | ||
|
||
// This sketch uses the LongPressConfig plugin, which enables run-time | ||
// configuration of LongPress configuration settings. All of the plugins marked | ||
// "for LongPressConfig" are optional; LongPress itself will work without them. | ||
KALEIDOSCOPE_INIT_PLUGINS( | ||
EEPROMSettings, // for LongPressConfig | ||
EEPROMKeymap, // for LongPressConfig | ||
Focus, // for LongPressConfig | ||
FocusEEPROMCommand, // for LongPressConfig | ||
FocusSettingsCommand, // for LongPressConfig | ||
LongPress, | ||
LongPressConfig, // for LongPressConfig | ||
Macros // for toggle LongPress Macro | ||
); | ||
|
||
void setup() { | ||
// Enable AutoShift for letter keys and number keys only: | ||
LongPress.setAutoshiftEnabled(LongPress.letterKeys() | LongPress.numberKeys()); | ||
// Add symbol keys to the enabled autoshift categories: | ||
LongPress.enableAutoshift(LongPress.symbolKeys()); | ||
|
||
LONGPRESS( | ||
// Long pressing the second key in the first row on the QWERTY layer | ||
// produces a 0 instead of a 1 (and instead of Shift-1) | ||
kaleidoscope::plugin::LongPressKey(QWERTY, KeyAddr(0, 1), Key_0), | ||
|
||
// instead of shifting, produce a backslash on long pressing slash on | ||
// all layers | ||
kaleidoscope::plugin::LongPressKey(kaleidoscope::plugin::longpress::ALL_LAYERS, Key_Slash, Key_Backslash), ) | ||
|
||
// Set the LongPress trigger time to 150ms: | ||
LongPress.setTimeout(150); | ||
// Start with LongPress turned off: | ||
LongPress.disable(); | ||
|
||
Kaleidoscope.setup(); | ||
} | ||
|
||
void loop() { | ||
Kaleidoscope.loop(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"cpu": { | ||
"fqbn": "keyboardio:avr:model01", | ||
"port": "" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
default_fqbn: keyboardio:avr:model01 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
# LongPress | ||
|
||
LongPress allows you to type different characters when long-pressing a key | ||
rather than tapping it. | ||
|
||
It is derived from the AutoShift plugin and integrates its functionality. When | ||
using LongPress it supersedes the AutoShift plugin. They conflict with each | ||
other and should not be used together. | ||
|
||
|
||
## Setup | ||
|
||
To use the plugin put the following into your .ino file: | ||
|
||
```c++ | ||
#include <Kaleidoscope-LongPress.h> | ||
|
||
KALEIDOSCOPE_INIT_PLUGINS(LongPress); | ||
``` | ||
## Configuration | ||
To do anything useful some configuration is necessary. | ||
### Long-press mappings | ||
To define the keys that should behave differently on long-press include | ||
a definition like the following: | ||
```c++ | ||
LONGPRESS( | ||
kaleidoscope::plugin::LongPressKey(kaleidoscope::plugin::longpress::ALL_LAYERS, | ||
KeyAddr(1, 1), Key_Q), // Long-press the key on QWERTY position of “q” to enter a “q” on all layers | ||
kaleidoscope::plugin::LongPressKey(QWERTY, | ||
KeyAddr(2, 4), LCTRL(Key_C)), // Long-press the key below the index finger to enter “Ctrl-C“ on the QWERTY layer | ||
kaleidoscope::plugin::LongPressKey(kaleidoscope::plugin::longpress::ALL_LAYERS, | ||
Key_T, RALT(Key_T)), // Long-press “t” to enter a “þ” on all layers | ||
) | ||
``` | ||
|
||
As can be seen in the example long-presses can be configured on either `KeyAddr` | ||
or `Key`, even in combination. Which variant is preferred is based on the use | ||
case. | ||
|
||
For example for mirroring the numbers in the number row (produce a “0” on long | ||
pressing “1”, produce a “9” on long pressing “2”, etc.) the best approach is to | ||
configure these on the `KeyAddr`. However to always generate an “ä” when “a” is | ||
long-pressed, regardless of where the “a” is mapped on (and whether it is mapped | ||
to different physical keys, probably on different layers), configuring it on the | ||
`Key` may be preferable. | ||
|
||
Be aware, however, that the order of the entries in LONGPRESS matters! Ealier | ||
definitions take precedence over later ones. Usually it is best to define | ||
long-presses on `KeyAddr` first and long-presses on `Key` afterwards as that is | ||
the least surprising behaviour in case of conflicting mappings. | ||
|
||
Another thing that can be seen in the example above is that long presses can be | ||
restricted to a single layer (the second one is restricted to the QWERTY | ||
layer). To apply the mapping to all layers, use the constant | ||
`kaleidoscope::plugin::longpress::ALL_LAYERS`[^1] as can be seen the first and the | ||
third mapping in the example above. | ||
|
||
### Enabling and disabling LongPress | ||
|
||
The following methods are provided for enabling / disabling the plugin altogether: | ||
|
||
- `LongPress.enable()` to enable the plugin (after loading the plugin is enabled by default). | ||
- `LongPress.disable()` to disable the plugin. | ||
- `LongPress.toggle()` to switch the plugin between enabled and disabled state. | ||
- `LongPress.enabled()` to check whether the plugin is currently enabled. | ||
|
||
### Setting the long-press delay | ||
|
||
To set the amount of time (in milliseconds) the LongPress plugin will wait | ||
until it executes the long-press behaviour use `LongPress.setTimeout(timeout)`. | ||
|
||
The default is 175. | ||
|
||
### Auto-Shifting | ||
|
||
One of the most common use cases for Long-Presses is auto-shifting of the | ||
generated character. This use case has special support to avoid having to | ||
configure every single key. | ||
|
||
By default no auto-shifting behaviour is applied. To set this behaviour to some | ||
certain sets of keys use one of the following methods: | ||
|
||
- `LongPress.setAutoshiftEnabled(categories)` to activate auto-shifting for exactly the given categories. | ||
To set multiple categories combine them using `|` (bitwise or), e.g.: `LongPress.setAutoshiftEnabled(LongPress.letterKeys() | LongPress.numberKeys())`. | ||
- `LongPress.enableAutoshift(category)` to add a single category to be auto-shifted. | ||
- `LongPress.disableAutoshift(category)` to remove a single category from the auto-shifted ones. | ||
- `LongPress.isAutoshiftEnabled(category)` to check whether auto-shifting is enabled for the given category. | ||
- `LongPress.enabledAutoShiftCategories()` to get an array of the categories for which auto-shifting is enabled. | ||
|
||
These are the predefined categories for auto-shifting: | ||
|
||
- `LongPress.noKeys()`: Can be used with `LongPress.setAutoshiftEnabled()` to remove all categories from being auto-shifted. | ||
- `LongPress.letterKeys`: All letter keys. | ||
- `LongPress.numberKeys`: All number keys (in the number row, not the numeric keypad). | ||
- `LongPress.symbolKeys`: Other printable symbols. | ||
- `LongPress.arrowKeys`: Navigational arrow keys. | ||
- `LongPress.functionKeys`: All function keys (F1 – F24). | ||
- `LongPress.printableKeys`: Letters, numbers and symbols. | ||
- `LongPress.allKeys`: All non-modifier USB keyboard keys. | ||
|
||
If the above categories are not sufficient for your auto-shifting needs, it is | ||
possible to get even finer-grained control of which keys are affected by | ||
auto-shifting, by overriding the `isAutoShiftable()` method in your sketch. For | ||
example, to make LongPress only auto-shift keys `A` and `Z`, include the following | ||
code in your sketch: | ||
|
||
```c++ | ||
bool LongPress::isAutoShiftable(Key key) { | ||
if (key == Key_A || key == key_Z) | ||
return true; | ||
return false; | ||
} | ||
``` | ||
As you can see, this method takes a `Key` as its input and returns either | ||
`true` (for keys eligible to be auto-shifted) or `false` (for keys to be left | ||
alone). | ||
In contrast to the explict configuration of long-presses via `LongPressKey`, | ||
such auto-shift behaviour always applies to all layers. | ||
## Conflicts with other plugins | ||
Care should be taken when using the plugin together with the Qukeys, SpaceCadet | ||
and Chords plugins. Most of the time they conflict with each other and when | ||
using one of these plugins together with LongPress it should be avoided to | ||
configure them on the same keys. | ||
In any case the LongPress plugin should be defined as the last one of these. | ||
## Further reading | ||
Starting from the [example][plugin:example] is the recommended way of getting | ||
started with the plugin. | ||
[plugin:example]: /examples/Keystrokes/LongPress/LongPress.ino | ||
[^1] The constant `kaleidoscope::plugin::longpress::ALL_LAYERS` is a bit long | ||
and unwieldy. Before integrating this plugin there were some discussions about | ||
whether that is acceptable. Therefore people using that plugin to apply | ||
mappings to all layers are kindly requested to provide some feedback about | ||
their usage and whether they are annoyed by that long constant name or not. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
name=Kaleidoscope-LongPress | ||
version=0.0.0 | ||
sentence=Provide different key strokes on long press | ||
maintainer=Kaleidoscope's Developers <[email protected]> | ||
url=https://github.com/keyboardio/Kaleidoscope | ||
author=Marco Herrn <[email protected]> | ||
paragraph= |
20 changes: 20 additions & 0 deletions
20
plugins/Kaleidoscope-LongPress/src/Kaleidoscope-LongPress.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
/* -*- mode: c++ -*- | ||
* Kaleidoscope-LongPress -- Provide different key strokes on long press | ||
* Copyright (C) 2024 Keyboard.io, Inc | ||
* | ||
* 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, version 3. | ||
* | ||
* 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/>. | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include "kaleidoscope/plugin/LongPress.h" // IWYU pragma: export |
Oops, something went wrong.