Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend Qukeys to support adding Qukeys in the keymap #1408

Closed
wants to merge 13 commits into from
14 changes: 13 additions & 1 deletion plugins/Kaleidoscope-Qukeys/src/kaleidoscope/plugin/Qukeys.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

#include <Arduino.h> // for F, __FlashStringHelper
#include <Kaleidoscope-FocusSerial.h> // for Focus, FocusSerial
#include <Kaleidoscope-Ranges.h> // for DUL_FIRST, DUM_FIRST, DUL_LAST, DUM_LAST
#include <Kaleidoscope-Ranges.h> // for DUL_FIRST, DUM_FIRST, DUL_LAST, DUM_LAST, QK_FIRST, QK_LAST

#include "kaleidoscope/KeyAddrEventQueue.h" // for KeyAddrEventQueue
#include "kaleidoscope/KeyEvent.h" // for KeyEvent
Expand Down Expand Up @@ -314,6 +314,18 @@ bool Qukeys::isQukey(KeyAddr k) {
return true;
}

// Then, we check to see if this is a Qukey using the new API (defined in the keymap)
if (key >= ranges::QK_FIRST && key <= ranges::QK_LAST) {
key.setRaw(key.getRaw() - ranges::QK_FIRST);

// TODO(EvyBongers): retrieve the stored qkey index
Key qkey = cloneFromProgmem(qkeys_[i]);

queue_head_.primary_key = key;
queue_head_.alternate_key = qkey;
return true;
}

// Last, we check the qukeys array for a match
uint8_t layer_index = Layer.lookupActiveLayer(k);
for (uint8_t i{0}; i < qukeys_count_; ++i) {
Expand Down
33 changes: 26 additions & 7 deletions plugins/Kaleidoscope-Qukeys/src/kaleidoscope/plugin/Qukeys.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
#pragma once

#include <Arduino.h> // for PROGMEM
#include <Kaleidoscope-Ranges.h> // for DUL_FIRST, DUM_FIRST
#include <Kaleidoscope-Ranges.h> // for DUL_FIRST, DUM_FIRST, QK_FIRST
#include <stdint.h> // for uint8_t, uint16_t, int8_t

#include "kaleidoscope/KeyAddr.h" // for KeyAddr
Expand All @@ -33,14 +33,16 @@
// IWYU pragma: no_include "HIDAliases.h"

// DualUse Key definitions for Qukeys in the keymap
#define MT(mod, key) kaleidoscope::plugin::ModTapKey(Key_##mod, Key_##key)
#define MT(mod, key) kaleidoscope::plugin::ModTapKey(Key_##mod, Key_##key)

#define SFT_T(key) MT(LeftShift, key)
#define CTL_T(key) MT(LeftControl, key)
#define ALT_T(key) MT(LeftAlt, key)
#define GUI_T(key) MT(LeftGui, key)
#define SFT_T(key) MT(LeftShift, key)
#define CTL_T(key) MT(LeftControl, key)
#define ALT_T(key) MT(LeftAlt, key)
#define GUI_T(key) MT(LeftGui, key)

#define LT(layer, key) kaleidoscope::plugin::LayerTapKey(layer, Key_##key)
#define LT(layer, key) kaleidoscope::plugin::LayerTapKey(layer, Key_##key)

#define QK(primary_key, secondary_key) kaleidoscope::plugin::Qkey(primary_key, secondary_key)

namespace kaleidoscope {
namespace plugin {
Expand Down Expand Up @@ -138,6 +140,13 @@ class Qukeys : public kaleidoscope::Plugin {
minimum_prior_interval_ = min_interval;
}

// Function to store a Qkey
uint8_t storeQkey(Key alt_key) {
qkeys_[qkeys_count_] = alt_key;
++qkeys_count_;
return (qkeys_count_ - 1);
}

// Function for defining the array of qukeys data (in PROGMEM). It's a
// template function that takes as its sole argument an array reference of
// size `_qukeys_count`, so there's no need to use `sizeof` to calculate the
Expand All @@ -158,6 +167,10 @@ class Qukeys : public kaleidoscope::Plugin {
EventHandlerResult afterEachCycle();

private:
// An array of Qkeys in PROGMEM.
Key const *qkeys_ PROGMEM;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if this needs to be initialized somehow.

uint8_t qkeys_count_{0};

// An array of Qukey objects in PROGMEM.
Qukey const *qukeys_{nullptr};
uint8_t qukeys_count_{0};
Expand Down Expand Up @@ -234,6 +247,12 @@ bool isModifierKey(Key key);

extern kaleidoscope::plugin::Qukeys Qukeys;

constexpr Key Qkey(Key tap_key, Key qkey) {
uint8_t qkey_index = Qukeys.storeQkey(qkey);
// TODO(EvyBongers): store the qkey index somewhere, somehow
return Key(kaleidoscope::ranges::QK_FIRST + tap_key.getRaw());
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My first thought was to use the same approach as with the ModTap and LayerTap keys, but if I grokked the logic of storing key code and flags in the Key class correctly, that would not be possible without functionality. Now I just need to find some way to store the reference.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On second thought, simply using the sum of these values seems bound to go wrong. I might have to store both key values in PROGMEM (or EEPROM) and return the sum of QK_FIRST and the returned index.


// Macro for use in sketch file to simplify definition of the qukeys array and
// guarantee that the count is set correctly. This is considerably less
// important than it used to be, with the `configureQukeys()` function taking
Expand Down
35 changes: 24 additions & 11 deletions plugins/Kaleidoscope-Ranges/src/Kaleidoscope-Ranges.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,18 @@ namespace ranges {
// important for compatibility with existing Chrysalis keymaps, despite the fact
// that it makes the code more obtuse here.

constexpr uint8_t MAX_CS_KEYS = 64;
constexpr uint8_t MAX_MACROS = 255;
constexpr uint8_t MAX_OSM_KEYS = 7;
constexpr uint8_t MAX_OSL_KEYS = 7;
constexpr uint16_t MAX_DUM_KEYS = 2048;
constexpr uint16_t MAX_DUL_KEYS = 2048;
constexpr uint8_t MAX_TD_KEYS = 15;
constexpr uint8_t MAX_LEAD_KEYS = 7;
constexpr uint8_t MAX_TT_KEYS = 255;
constexpr uint8_t MAX_STENO_KEYS = 42;
constexpr uint8_t MAX_DYNAMIC_MACROS = 31;
constexpr uint8_t MAX_CS_KEYS = 64;
constexpr uint8_t MAX_QK_KEYS = 64;

enum : uint16_t {
// Macro ranges pre-date Kaleidoscope-Ranges, so they're coming before
Expand All @@ -50,43 +61,45 @@ enum : uint16_t {
// between plugin key values and core key values. The magic number
// `0b00100000` is the old `IS_MACRO` key flags bit.
MACRO_FIRST = (SYNTHETIC | 0b00100000) << 8,
MACRO_LAST = MACRO_FIRST + 255,
MACRO_LAST = MACRO_FIRST + MAX_MACROS,

FIRST = 0xc000,
KALEIDOSCOPE_FIRST = FIRST,
OS_FIRST,
OSM_FIRST = OS_FIRST,
OSM_LAST = OSM_FIRST + 7,
OSM_LAST = OSM_FIRST + MAX_OSM_KEYS,
OSL_FIRST,
OSL_LAST = OSL_FIRST + 7,
OSL_LAST = OSL_FIRST + MAX_OSL_KEYS,
OS_LAST = OSL_LAST,
DU_FIRST,
DUM_FIRST = DU_FIRST,
DUM_LAST = DUM_FIRST + (8 << 8),
DUM_LAST = DUM_FIRST + MAX_DUM_KEYS,
DUL_FIRST,
DUL_LAST = DUL_FIRST + (8 << 8),
DUL_LAST = DUL_FIRST + MAX_DUL_KEYS,
DU_LAST = DUL_LAST,
TD_FIRST,
TD_LAST = TD_FIRST + 15,
TD_LAST = TD_FIRST + MAX_TD_KEYS,
LEAD_FIRST,
LEAD_LAST = LEAD_FIRST + 7,
LEAD_LAST = LEAD_FIRST + MAX_LEAD_KEYS,
CYCLE,
SYSTER,
TT_FIRST,
TT_LAST = TT_FIRST + 255,
TT_LAST = TT_FIRST + MAX_TT_KEYS,
STENO_FIRST,
STENO_LAST = STENO_FIRST + 42,
STENO_LAST = STENO_FIRST + MAX_STENO_KEYS,
SC_FIRST,
SC_LAST,
REDIAL,
TURBO,
DYNAMIC_MACRO_FIRST,
DYNAMIC_MACRO_LAST = DYNAMIC_MACRO_FIRST + 31,
DYNAMIC_MACRO_LAST = DYNAMIC_MACRO_FIRST + MAX_DYNAMIC_MACROS,
OS_META_STICKY,
OS_ACTIVE_STICKY,
OS_CANCEL,
CS_FIRST,
CS_LAST = CS_FIRST + MAX_CS_KEYS,
QK_FIRST,
QK_LAST = QK_FIRST + MAX_QK_KEYS,
EvyBongers marked this conversation as resolved.
Show resolved Hide resolved

SAFE_START,
KALEIDOSCOPE_SAFE_START = SAFE_START
Expand Down
39 changes: 28 additions & 11 deletions tests/issues/1010/test/testcase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,47 +25,60 @@ namespace testing {

class Issue1010 : public ::testing::Test {
public:
static constexpr uint8_t MAX_CS_KEYS = 64;
static constexpr uint8_t MAX_MACROS = 255;
static constexpr uint8_t MAX_OSM_KEYS = 7;
static constexpr uint8_t MAX_OSL_KEYS = 7;
static constexpr uint16_t MAX_DUM_KEYS = 2048;
static constexpr uint16_t MAX_DUL_KEYS = 2048;
static constexpr uint8_t MAX_TD_KEYS = 15;
static constexpr uint8_t MAX_LEAD_KEYS = 7;
static constexpr uint8_t MAX_TT_KEYS = 255;
static constexpr uint8_t MAX_STENO_KEYS = 42;
static constexpr uint8_t MAX_DYNAMIC_MACROS = 31;
static constexpr uint8_t MAX_CS_KEYS = 64;
static constexpr uint8_t MAX_QK_KEYS = 64;

enum : uint16_t {
MACRO_FIRST = (SYNTHETIC | 0b00100000) << 8,
MACRO_LAST = MACRO_FIRST + 255,
MACRO_LAST = MACRO_FIRST + MAX_MACROS,

FIRST = 0xc000,
KALEIDOSCOPE_FIRST = FIRST,
OS_FIRST,
OSM_FIRST = OS_FIRST,
OSM_LAST = OSM_FIRST + 7,
OSM_LAST = OSM_FIRST + MAX_OSM_KEYS,
OSL_FIRST,
OSL_LAST = OSL_FIRST + 7,
OSL_LAST = OSL_FIRST + MAX_OSL_KEYS,
OS_LAST = OSL_LAST,
DU_FIRST,
DUM_FIRST = DU_FIRST,
DUM_LAST = DUM_FIRST + (8 << 8),
DUM_LAST = DUM_FIRST + MAX_DUM_KEYS,
DUL_FIRST,
DUL_LAST = DUL_FIRST + (8 << 8),
DUL_LAST = DUL_FIRST + MAX_DUL_KEYS,
DU_LAST = DUL_LAST,
TD_FIRST,
TD_LAST = TD_FIRST + 15,
TD_LAST = TD_FIRST + MAX_TD_KEYS,
LEAD_FIRST,
LEAD_LAST = LEAD_FIRST + 7,
LEAD_LAST = LEAD_FIRST + MAX_LEAD_KEYS,
CYCLE,
SYSTER,
TT_FIRST,
TT_LAST = TT_FIRST + 255,
TT_LAST = TT_FIRST + MAX_TT_KEYS,
STENO_FIRST,
STENO_LAST = STENO_FIRST + 42,
STENO_LAST = STENO_FIRST + MAX_STENO_KEYS,
SC_FIRST,
SC_LAST,
REDIAL,
TURBO,
DYNAMIC_MACRO_FIRST,
DYNAMIC_MACRO_LAST = DYNAMIC_MACRO_FIRST + 31,
DYNAMIC_MACRO_LAST = DYNAMIC_MACRO_FIRST + MAX_DYNAMIC_MACROS,
OS_META_STICKY,
OS_ACTIVE_STICKY,
OS_CANCEL,
CS_FIRST,
CS_LAST = CS_FIRST + MAX_CS_KEYS,
QK_FIRST,
QK_LAST = QK_FIRST + MAX_QK_KEYS,

SAFE_START,
KALEIDOSCOPE_SAFE_START = SAFE_START
Expand Down Expand Up @@ -148,6 +161,10 @@ TEST_F(Issue1010, RangesHaveNotChanged) {
uint16_t(kaleidoscope::ranges::CS_FIRST));
ASSERT_EQ(uint16_t(Issue1010::CS_LAST),
uint16_t(kaleidoscope::ranges::CS_LAST));
ASSERT_EQ(uint16_t(Issue1010::QK_FIRST),
uint16_t(kaleidoscope::ranges::QK_FIRST));
ASSERT_EQ(uint16_t(Issue1010::QK_LAST),
uint16_t(kaleidoscope::ranges::QK_LAST));

ASSERT_EQ(uint16_t(Issue1010::SAFE_START),
uint16_t(kaleidoscope::ranges::SAFE_START));
Expand Down
Loading