Add Kaleidoscope-OneShotMetaKeys plugin

Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
pull/1062/head
Michael Richters 3 years ago
parent c04542759f
commit d0b6f5a21b
No known key found for this signature in database
GPG Key ID: 1288FD13E4EEF0C0

@ -0,0 +1,88 @@
/* -*- mode: c++ -*-
* Kaleidoscope-OneShotMetaKeys -- Special OneShot keys
* Copyright (C) 2021 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/>.
*/
#include <Kaleidoscope.h>
#include <Kaleidoscope-Macros.h>
#include <Kaleidoscope-OneShot.h>
#include <Kaleidoscope-OneShotMetaKeys.h>
// Macros
enum {
TOGGLE_ONESHOT,
};
// *INDENT-OFF*
KEYMAPS(
[0] = KEYMAP_STACKED
(
M(TOGGLE_ONESHOT), Key_1, Key_2, Key_3, Key_4, Key_5, OneShot_MetaStickyKey,
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,
OSM(LeftControl), Key_Backspace, OSM(LeftGui), OSM(LeftShift),
Key_Meh,
OneShot_ActiveStickyKey, Key_6, Key_7, Key_8, Key_9, Key_0, ___,
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_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus,
Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl,
OSL(1)),
[1] = KEYMAP_STACKED
(
___, ___, ___, ___, ___, ___, ___,
___, ___, ___, ___, ___, ___, ___,
___, ___, ___, ___, ___, ___,
___, ___, ___, ___, ___, ___, ___,
___, ___, ___, ___,
___,
___, ___, ___, ___, ___, ___, ___,
___, ___, ___, ___, ___, ___, ___,
Key_UpArrow, Key_DownArrow, Key_LeftArrow, Key_RightArrow,___, ___,
___, ___, ___, ___, ___, ___, ___,
___, ___, ___, ___,
___),
)
// *INDENT-ON*
void macroToggleOneShot() {
OneShot.toggleAutoOneShot();
}
const macro_t *macroAction(uint8_t macro_id, KeyEvent &event) {
if (macro_id == TOGGLE_ONESHOT) {
macroToggleOneShot();
}
return MACRO_NONE;
}
KALEIDOSCOPE_INIT_PLUGINS(OneShot, OneShotMetaKeys, Macros);
void setup() {
Kaleidoscope.setup();
}
void loop() {
Kaleidoscope.loop();
}

@ -0,0 +1,6 @@
{
"cpu": {
"fqbn": "keyboardio:avr:model01",
"port": ""
}
}

@ -0,0 +1,56 @@
# OneShot Meta Keys
This plugin provides support for two special OneShot keys:
`OneShot_MetaStickyKey` & `OneShot_ActiveStickyKey`, each of which can be used
to make any key on the keyboard (not just modifiers and layer shift keys)
"sticky", so that they remain active even after the key has been released.
These are both `Key` values that can be used as entries in your sketch's keymap.
Any keys made sticky in this way can be released just like OneShot modifier
keys, by tapping them again to cancel the effect.
## The `OneShot_MetaStickyKey`
This special OneShot key behaves like other OneShot keys, but its affect is to
make the next key pressed sticky. Tap `OneShot_MetaStickyKey`, then tap `X`, and
`X` will become sticky. Tap `X` again to deactivate it.
Double-tapping `OneShot_MetaStickyKey` will make it sticky, just like any other
OneShot key. A third tap will release the key.
## The `OneShot_ActiveStickyKey`
This special key doesn't act like a OneShot key, but instead makes any key(s)
currently held (or otherwise active) sticky. Press (and hold) `X`, tap
`OneShot_ActiveStickyKey`, then release `X`, and `X` will stay active until it
is tapped again to deactivate it.
## Using the plugin
To use the plugin, just include one of the two special OneShot keys somewhere in
your keymap, and add both OneShot and OneShotMetaKeys to your sketch:
```c++
#include <Kaleidoscope-OneShot.h>
#include <Kaleidoscope-OneShotMetaKeys.h>
// somewhere in the keymap...
OneShot_MetaStickyKey, OneShot_ActiveStickyKey
KALEIDOSCOPE_INIT_PLUGINS(OneShot, OneShotMetaKeys);
```
Important note: OneShotMetaKeys _must_ be registered after OneShot in
`KALEIDOSCOPE_INIT_PLUGINS()` in order to function properly.
## Dependencies
* [Kaleidoscope-OneShot](Kaleidoscope-OneShot.md)
* [Kaleidoscope-Ranges](Kaleidoscope-Ranges.md)
## Further reading
Starting from the [example][plugin:example] is the recommended way of getting
started with the plugin.
[plugin:example]: /examples/Keystrokes/OneShotMetaKeys/OneShotMetaKeys.ino

@ -0,0 +1,7 @@
name=Kaleidoscope-OneShotMetaKeys
version=0.0.0
sentence=OneShot_ActiveStickyKey & OneShot_MetaStickyKey
maintainer=Kaleidoscope's Developers <jesse@keyboard.io>
url=https://github.com/keyboardio/Kaleidoscope
author=Keyboardio
paragraph=

@ -0,0 +1,20 @@
/* -*- mode: c++ -*-
* Kaleidoscope-OneShot -- One-shot modifiers and layers
* Copyright (C) 2021 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/OneShotMetaKeys.h>

@ -0,0 +1,94 @@
/* -*- mode: c++ -*-
* Kaleidoscope-OneShot -- One-shot modifiers and layers
* Copyright (C) 2021 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/>.
*/
#include <Kaleidoscope-OneShotMetaKeys.h>
#include <Kaleidoscope-FocusSerial.h>
#include <Kaleidoscope-OneShot.h>
#include "kaleidoscope/KeyAddr.h"
#include "kaleidoscope/key_defs.h"
#include "kaleidoscope/KeyEvent.h"
#include "kaleidoscope/keyswitch_state.h"
#include "kaleidoscope/LiveKeys.h"
namespace kaleidoscope {
namespace plugin {
// ============================================================================
// Public interface
// ----------------------------------------------------------------------------
// Plugin hook functions
EventHandlerResult OneShotMetaKeys::onNameQuery() {
return ::Focus.sendName(F("OneShotMetaKeys"));
}
EventHandlerResult OneShotMetaKeys::onKeyEvent(KeyEvent &event) {
// Ignore key release and injected events.
if (keyToggledOff(event.state) || event.state & INJECTED)
return EventHandlerResult::OK;
// Make all held keys sticky if `OneShot_ActiveStickyKey` toggles on.
if (event.key == OneShot_ActiveStickyKey) {
// Note: we don't need to explicitly skip the key the active sticky key
// itself (i.e. `event.addr`), because its entry in `live_keys[]` has not
// yet been inserted at this point.
for (KeyAddr addr : KeyAddr::all()) {
// Get the entry from the keyboard state array.
Key key = live_keys[addr];
// Skip idle and masked entries.
if (key == Key_Inactive || key == Key_Masked) {
continue;
}
// Make everything else sticky.
::OneShot.setSticky(addr);
}
return EventHandlerResult::OK;
}
// If there's an active meta-sticky key, we need to make newly-pressed keys
// sticky, unless they were already active, in which case we let OneShot
// release them from the "sticky" state.
if (isMetaStickyActive() &&
live_keys[event.addr] != event.key) {
::OneShot.setSticky(event.addr);
return EventHandlerResult::OK;
}
// If a previously-inactive meta-sticky key was just pressed, we have OneShot
// put it in the "pending" state so it will act like a OneShot key.
if (event.key == OneShot_MetaStickyKey &&
live_keys[event.addr] != OneShot_MetaStickyKey) {
::OneShot.setPending(event.addr);
}
return EventHandlerResult::OK;
}
bool OneShotMetaKeys::isMetaStickyActive() {
for (Key key : live_keys.all()) {
if (key == OneShot_MetaStickyKey)
return true;
}
return false;
}
} // namespace plugin
} // namespace kaleidoscope
kaleidoscope::plugin::OneShotMetaKeys OneShotMetaKeys;

@ -0,0 +1,52 @@
/* -*- mode: c++ -*-
* Kaleidoscope-OneShot -- One-shot modifiers and layers
* Copyright (C) 2021 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-OneShot.h>
#include <Kaleidoscope-Ranges.h>
#include "kaleidoscope/event_handler_result.h"
#include "kaleidoscope/key_defs.h"
#include "kaleidoscope/KeyEvent.h"
#include "kaleidoscope/plugin.h"
// ----------------------------------------------------------------------------
// Key constants
constexpr Key OneShot_MetaStickyKey {kaleidoscope::ranges::OS_META_STICKY};
constexpr Key OneShot_ActiveStickyKey {kaleidoscope::ranges::OS_ACTIVE_STICKY};
namespace kaleidoscope {
namespace plugin {
class OneShotMetaKeys : public kaleidoscope::Plugin {
public:
// --------------------------------------------------------------------------
// Plugin hook functions
EventHandlerResult onNameQuery();
EventHandlerResult onKeyEvent(KeyEvent &event);
private:
static bool isMetaStickyActive();
};
} // namespace plugin
} // namespace kaleidoscope
extern kaleidoscope::plugin::OneShotMetaKeys OneShotMetaKeys;

@ -0,0 +1,53 @@
/* -*- mode: c++ -*-
* Copyright (C) 2021 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/>.
*/
#include <Kaleidoscope.h>
#include <Kaleidoscope-OneShot.h>
#include <Kaleidoscope-OneShotMetaKeys.h>
// *INDENT-OFF*
KEYMAPS(
[0] = KEYMAP_STACKED
(
OneShot_MetaStickyKey, OneShot_ActiveStickyKey, ___, ___, ___, ___, ___,
Key_A, Key_B, ___, ___, ___, ___, ___,
___, ___, ___, ___, ___, ___,
___, ___, ___, ___, ___, ___, ___,
___, ___, ___, ___,
___,
___, ___, ___, ___, ___, ___, ___,
___, ___, ___, ___, ___, ___, ___,
___, ___, ___, ___, ___, ___,
___, ___, ___, ___, ___, ___, ___,
___, ___, ___, ___,
___
),
)
// *INDENT-ON*
KALEIDOSCOPE_INIT_PLUGINS(OneShot, OneShotMetaKeys);
void setup() {
Kaleidoscope.setup();
OneShot.setTimeout(50);
OneShot.setHoldTimeout(20);
OneShot.setDoubleTapTimeout(20);
}
void loop() {
Kaleidoscope.loop();
}

@ -0,0 +1,6 @@
{
"cpu": {
"fqbn": "keyboardio:virtual:model01",
"port": ""
}
}

@ -0,0 +1,325 @@
VERSION 1
KEYSWITCH OS_META 0 0
KEYSWITCH OS_ACTIVE 0 1
KEYSWITCH A 1 0
KEYSWITCH B 1 1
# ==============================================================================
NAME OneShot meta sticky
RUN 4 ms
PRESS OS_META
RUN 1 cycle
RUN 4 ms
RELEASE OS_META
RUN 1 cycle
RUN 4 ms
PRESS A
RUN 1 cycle
EXPECT keyboard-report Key_A
RUN 4 ms
RELEASE A
RUN 1 cycle
RUN 4 ms
PRESS A
RUN 1 cycle
RUN 4 ms
RELEASE A
RUN 1 cycle
EXPECT keyboard-report empty
RUN 4 ms
PRESS A
RUN 1 cycle
EXPECT keyboard-report Key_A
RUN 4 ms
RELEASE A
RUN 1 cycle
EXPECT keyboard-report empty
RUN 5 ms
# ==============================================================================
NAME OneShot meta sticky rollover
RUN 4 ms
PRESS OS_META
RUN 1 cycle
RUN 4 ms
PRESS A
RUN 1 cycle
EXPECT keyboard-report Key_A
RUN 4 ms
RELEASE OS_META
RUN 1 cycle
RUN 4 ms
RELEASE A
RUN 1 cycle
RUN 4 ms
PRESS A
RUN 1 cycle
RUN 4 ms
RELEASE A
RUN 1 cycle
EXPECT keyboard-report empty
RUN 4 ms
PRESS A
RUN 1 cycle
EXPECT keyboard-report Key_A
RUN 4 ms
RELEASE A
RUN 1 cycle
EXPECT keyboard-report empty
RUN 5 ms
# ==============================================================================
NAME OneShot meta sticky overlap
RUN 4 ms
PRESS OS_META
RUN 1 cycle
RUN 4 ms
PRESS A
RUN 1 cycle
EXPECT keyboard-report Key_A
RUN 4 ms
RELEASE A
RUN 1 cycle
RUN 4 ms
RELEASE OS_META
RUN 1 cycle
RUN 4 ms
PRESS A
RUN 1 cycle
RUN 4 ms
RELEASE A
RUN 1 cycle
EXPECT keyboard-report empty
RUN 4 ms
PRESS A
RUN 1 cycle
EXPECT keyboard-report Key_A
RUN 4 ms
RELEASE A
RUN 1 cycle
EXPECT keyboard-report empty
RUN 5 ms
# ==============================================================================
NAME OneShot meta sticky overlap to rollover
RUN 4 ms
PRESS OS_META
RUN 1 cycle
RUN 4 ms
PRESS A
RUN 1 cycle
EXPECT keyboard-report Key_A
RUN 4 ms
RELEASE A
RUN 1 cycle
RUN 4 ms
PRESS A
RUN 1 cycle
RUN 4 ms
RELEASE OS_META
RUN 1 cycle
RUN 4 ms
RELEASE A
RUN 1 cycle
EXPECT keyboard-report empty
RUN 4 ms
PRESS A
RUN 1 cycle
EXPECT keyboard-report Key_A
RUN 4 ms
RELEASE A
RUN 1 cycle
EXPECT keyboard-report empty
RUN 5 ms
# ==============================================================================
NAME OneShot meta sticky sticky
RUN 4 ms
PRESS OS_META
RUN 1 cycle
RUN 4 ms
RELEASE OS_META
RUN 1 cycle
RUN 4 ms
PRESS OS_META
RUN 1 cycle
RUN 4 ms
RELEASE OS_META
RUN 1 cycle
RUN 4 ms
PRESS A
RUN 1 cycle
EXPECT keyboard-report Key_A
RUN 4 ms
RELEASE A
RUN 1 cycle
RUN 4 ms
PRESS B
RUN 1 cycle
EXPECT keyboard-report Key_A Key_B
RUN 4 ms
RELEASE B
RUN 1 cycle
RUN 4 ms
PRESS OS_META
RUN 1 cycle
RUN 4 ms
RELEASE OS_META
RUN 1 cycle
RUN 4 ms
PRESS A
RUN 1 cycle
RUN 4 ms
RELEASE A
RUN 1 cycle
EXPECT keyboard-report Key_B
RUN 4 ms
PRESS B
RUN 1 cycle
RUN 4 ms
RELEASE B
RUN 1 cycle
EXPECT keyboard-report empty
RUN 4 ms
PRESS A
RUN 1 cycle
EXPECT keyboard-report Key_A
RUN 4 ms
RELEASE A
RUN 1 cycle
EXPECT keyboard-report empty
RUN 5 ms
# ==============================================================================
NAME OneShot active sticky
RUN 4 ms
PRESS A
RUN 1 cycle
EXPECT keyboard-report Key_A
RUN 4 ms
PRESS OS_ACTIVE
RUN 1 cycle
RUN 4 ms
RELEASE OS_ACTIVE
RUN 1 cycle
RUN 4 ms
RELEASE A
RUN 1 cycle
RUN 4 ms
PRESS A
RUN 1 cycle
RUN 4 ms
RELEASE A
RUN 1 cycle
EXPECT keyboard-report empty
RUN 5 ms
# ==============================================================================
NAME OneShot active sticky two keys
RUN 4 ms
PRESS A
RUN 1 cycle
EXPECT keyboard-report Key_A
RUN 4 ms
PRESS B
RUN 1 cycle
EXPECT keyboard-report Key_A Key_B
RUN 4 ms
PRESS OS_ACTIVE
RUN 1 cycle
RUN 4 ms
RELEASE OS_ACTIVE
RUN 1 cycle
RUN 4 ms
RELEASE A
RUN 1 cycle
RUN 4 ms
RELEASE B
RUN 1 cycle
RUN 4 ms
PRESS A
RUN 1 cycle
RUN 4 ms
RELEASE A
RUN 1 cycle
EXPECT keyboard-report Key_B
RUN 4 ms
PRESS B
RUN 1 cycle
RUN 4 ms
RELEASE B
RUN 1 cycle
EXPECT keyboard-report empty
RUN 5 ms
Loading…
Cancel
Save