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) {
uint8_t qkey_index = key.getRaw() - ranges::QK_FIRST;

key.setRaw(cloneFromProgmem(qkeys_[i])[0].getRaw());
Key qkey = cloneFromProgmem(qkeys_[i])[1];

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,14 @@ class Qukeys : public kaleidoscope::Plugin {
minimum_prior_interval_ = min_interval;
}

// Function to store a Qkey
uint8_t storeQkey(Key primary_key, Key alt_key) {
qkeys_[qkeys_count_][0] = primary_key;
qkeys_[qkeys_count_][1] = 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 Down Expand Up @@ -222,6 +232,10 @@ class Qukeys : public kaleidoscope::Plugin {
uint8_t timeout{200};
} tap_repeat_;
bool shouldWaitForTapRepeat();

// An array of Qkeys in PROGMEM.
uint8_t qkeys_count_{0};
Key const qkeys_[][2] PROGMEM;
};

// This function returns true for any key that we expect to be used chorded with
Expand All @@ -234,6 +248,11 @@ bool isModifierKey(Key key);

extern kaleidoscope::plugin::Qukeys Qukeys;

constexpr Key Qkey(Key tap_key, Key qkey) {
uint8_t qkey_index = Qukeys.storeQkey(tap_key, qkey);
return Key(kaleidoscope::ranges::QK_FIRST + qkey_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