Adapt TopsyTurvy plugin to KeyEvent handlers

fixes #990

Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
pull/1024/head
Michael Richters 4 years ago
parent abba881257
commit 0bf128be09
No known key found for this signature in database
GPG Key ID: 1288FD13E4EEF0C0

@ -17,68 +17,77 @@
#include <Kaleidoscope-TopsyTurvy.h> #include <Kaleidoscope-TopsyTurvy.h>
#include "kaleidoscope/keyswitch_state.h" #include "kaleidoscope/keyswitch_state.h"
#include "kaleidoscope/LiveKeys.h"
namespace kaleidoscope { namespace kaleidoscope {
namespace plugin { namespace plugin {
KeyAddr TopsyTurvy::tt_addr_ = KeyAddr::none(); KeyAddr TopsyTurvy::tt_addr_ = KeyAddr::none();
bool TopsyTurvy::shift_detected_ = false;
EventHandlerResult TopsyTurvy::beforeEachCycle() { EventHandlerResult TopsyTurvy::onKeyEvent(KeyEvent &event) {
// Clear the shift detection state before each scan cycle. if (keyToggledOff(event.state)) {
shift_detected_ = false; if (event.addr == tt_addr_)
return EventHandlerResult::OK; tt_addr_.clear();
} return EventHandlerResult::OK;
}
EventHandlerResult TopsyTurvy::beforeReportingState() { if (event.key.isKeyboardModifier())
// If no TopsyTurvy key is active, there's nothing to do.
if (! tt_addr_.isValid())
return EventHandlerResult::OK; return EventHandlerResult::OK;
// A TopsyTurvy key is active. That means we need to reverse the shift state, if (isTopsyTurvyKey(event.key)) {
// whether it was on or off. event.key.setRaw(event.key.getRaw() - ranges::TT_FIRST);
if (shift_detected_) { tt_addr_ = event.addr;
kaleidoscope::Runtime.hid().keyboard().releaseKey(Key_LeftShift);
kaleidoscope::Runtime.hid().keyboard().releaseKey(Key_RightShift);
} else { } else {
kaleidoscope::Runtime.hid().keyboard().pressKey(Key_LeftShift); live_keys.activate(tt_addr_, Key_NoKey);
tt_addr_.clear();
}
if (tt_addr_.isValid()) {
for (KeyAddr key_addr : KeyAddr::all()) {
if (key_addr == event.addr)
continue;
Key active_key = live_keys[key_addr];
if (active_key == Key_Transparent)
continue;
if (active_key.isKeyboardKey() && !active_key.isKeyboardModifier()) {
live_keys.activate(key_addr, Key_NoKey);
}
}
} }
return EventHandlerResult::OK; return EventHandlerResult::OK;
} }
EventHandlerResult TopsyTurvy::onKeyswitchEvent(Key &key, EventHandlerResult TopsyTurvy::beforeReportingState(const KeyEvent &event) {
KeyAddr key_addr,
uint8_t key_state) {
// If a modifer key (including combo modifiers, but not non-modifier keys with
// mod flags) is active, and it includes `shift` (either from its keycode or a
// mod flag), record that we detected an "intentional shift".
if (key.isKeyboardShift() && keyIsPressed(key_state))
shift_detected_ = true;
// If the active TopsyTurvy key toggles off, clear the stored address to if (!tt_addr_.isValid()) {
// record that.
if (keyToggledOff(key_state)) {
if (key_addr == tt_addr_) {
tt_addr_.clear();
}
return EventHandlerResult::OK; return EventHandlerResult::OK;
} }
// If a TopsyTurvy key is being held, no other KeyboardKey should be able to
if (keyToggledOn(key_state)) { // toggle off, because those keys were masked. It's possible for other plugins
if (isTopsyTurvyKey(key)) { // to change that, but those types of complex plugin interactions can't be
// If a TopsyTurvy key toggles on, store its address to indicate that it's // guaranteed to be safe, anyway. Therefore, we assume that if `tt_addr` is
// active, and decode its key value to store in the active keys cache. // valid, it is also the last key pressed.
tt_addr_ = key_addr; bool shift_detected = false;
key = Key(key.getRaw() - ranges::TT_FIRST); for (KeyAddr key_addr : KeyAddr::all()) {
} else { if (live_keys[key_addr].isKeyboardShift()) {
// If any other key toggles on, clear the active TopsyTurvy address. shift_detected = true;
tt_addr_.clear(); break;
} }
} }
if (shift_detected) {
Runtime.hid().keyboard().releaseKey(Key_LeftShift);
Runtime.hid().keyboard().releaseKey(Key_RightShift);
} else {
Runtime.hid().keyboard().pressKey(Key_LeftShift);
}
return EventHandlerResult::OK; return EventHandlerResult::OK;
} }
} } // namespace plugin
} } // namespace kaleidoscope
kaleidoscope::plugin::TopsyTurvy TopsyTurvy; kaleidoscope::plugin::TopsyTurvy TopsyTurvy;

@ -29,9 +29,8 @@ class TopsyTurvy: public kaleidoscope::Plugin {
public: public:
TopsyTurvy(void) {} TopsyTurvy(void) {}
EventHandlerResult beforeEachCycle(); EventHandlerResult onKeyEvent(KeyEvent &event);
EventHandlerResult beforeReportingState(); EventHandlerResult beforeReportingState(const KeyEvent &event);
EventHandlerResult onKeyswitchEvent(Key &key, KeyAddr key_addr, uint8_t key_state);
static bool isTopsyTurvyKey(Key key) { static bool isTopsyTurvyKey(Key key) {
return (key >= ranges::TT_FIRST && return (key >= ranges::TT_FIRST &&
@ -40,8 +39,8 @@ class TopsyTurvy: public kaleidoscope::Plugin {
private: private:
static KeyAddr tt_addr_; static KeyAddr tt_addr_;
static bool shift_detected_;
}; };
} }
} }

Loading…
Cancel
Save