rework sticky layer keys
parent
f52da5065a
commit
6786b70ecc
121
src/main.c
121
src/main.c
|
@ -25,12 +25,6 @@
|
||||||
typedef uint8_t u8;
|
typedef uint8_t u8;
|
||||||
typedef uint16_t u16;
|
typedef uint16_t u16;
|
||||||
|
|
||||||
typedef enum StickyState {
|
|
||||||
StickyNone,
|
|
||||||
StickyOnceDown,
|
|
||||||
StickyOnceUp,
|
|
||||||
} StickyState;
|
|
||||||
|
|
||||||
typedef u8 keycode;
|
typedef u8 keycode;
|
||||||
typedef u16 media_keycode;
|
typedef u16 media_keycode;
|
||||||
typedef u8 layer;
|
typedef u8 layer;
|
||||||
|
@ -67,12 +61,15 @@ static u8 current_col;
|
||||||
static layer current_layer;
|
static layer current_layer;
|
||||||
static keycode current_keycode;
|
static keycode current_keycode;
|
||||||
static bool current_is_pressed;
|
static bool current_is_pressed;
|
||||||
static bool sticky_done;
|
|
||||||
|
|
||||||
static bool layers_active[KB_LAYERS];
|
static bool layers_active[KB_LAYERS];
|
||||||
static StickyState layers_sticky[KB_LAYERS];
|
|
||||||
static layer layers_top = 0;
|
static layer layers_top = 0;
|
||||||
|
|
||||||
|
static bool sticky_on;
|
||||||
|
static bool sticky_done;
|
||||||
|
static bool layer_sticky[KB_LAYERS];
|
||||||
|
static bool modifier_sticky[MODIFIERS];
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
@ -80,8 +77,9 @@ int main() {
|
||||||
usb_init();
|
usb_init();
|
||||||
while (!usb_configured());
|
while (!usb_configured());
|
||||||
|
|
||||||
// initialize layers
|
// initialize
|
||||||
init_layers();
|
init_layers();
|
||||||
|
init_sticky();
|
||||||
|
|
||||||
// never return
|
// never return
|
||||||
main_key_loop();
|
main_key_loop();
|
||||||
|
@ -140,7 +138,6 @@ void main_key_loop() {
|
||||||
void init_layers() {
|
void init_layers() {
|
||||||
for (layer l=0; l < KB_LAYERS; l++) {
|
for (layer l=0; l < KB_LAYERS; l++) {
|
||||||
layers_active[l] = false;
|
layers_active[l] = false;
|
||||||
layers_sticky[l] = StickyNone;
|
|
||||||
}
|
}
|
||||||
layers_active[0] = true;
|
layers_active[0] = true;
|
||||||
}
|
}
|
||||||
|
@ -158,26 +155,11 @@ layer highest_active_layer(layer offset) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// return if highest active layer is sticky
|
|
||||||
StickyState layer_top_sticky() {
|
|
||||||
return layer_sticky(layers_top);
|
|
||||||
}
|
|
||||||
|
|
||||||
// return if layer is sticky
|
|
||||||
StickyState layer_sticky(layer l) {
|
|
||||||
if (l < KB_LAYERS) {
|
|
||||||
return layers_sticky[l];
|
|
||||||
}
|
|
||||||
return StickyNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
// enable a layer
|
// enable a layer
|
||||||
void layer_enable(layer l, StickyState sticky) {
|
void layer_enable(layer l) {
|
||||||
// FIXME split off sticky part
|
|
||||||
if (l >= KB_LAYERS) { return; }
|
if (l >= KB_LAYERS) { return; }
|
||||||
|
|
||||||
layers_active[l] = true;
|
layers_active[l] = true;
|
||||||
layers_sticky[l] = sticky;
|
|
||||||
|
|
||||||
if (l > layers_top) {
|
if (l > layers_top) {
|
||||||
layers_top = l;
|
layers_top = l;
|
||||||
|
@ -191,11 +173,6 @@ void layer_disable(layer l) {
|
||||||
|
|
||||||
layers_active[l] = false;
|
layers_active[l] = false;
|
||||||
|
|
||||||
if (layers_sticky[l] != StickyNone) {
|
|
||||||
debug_printf("sticky %d up!\n", l);
|
|
||||||
}
|
|
||||||
layers_sticky[l] = StickyNone;
|
|
||||||
|
|
||||||
if (l == layers_top) {
|
if (l == layers_top) {
|
||||||
layers_top = highest_active_layer(1);
|
layers_top = highest_active_layer(1);
|
||||||
}
|
}
|
||||||
|
@ -235,12 +212,53 @@ void layer_enable_upto(layer max_layer) {
|
||||||
if (is_layer_enable(key_function)) {
|
if (is_layer_enable(key_function)) {
|
||||||
layer enable_layer = (layer) kb_keycode(l, current_row, current_col);
|
layer enable_layer = (layer) kb_keycode(l, current_row, current_col);
|
||||||
if (enable_layer <= max_layer) {
|
if (enable_layer <= max_layer) {
|
||||||
layer_enable(enable_layer, StickyNone);
|
layer_enable(enable_layer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// sticky functions
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void init_sticky() {
|
||||||
|
for (layer l=0; l < KB_LAYERS; l++) {
|
||||||
|
layer_sticky[l] = false;
|
||||||
|
}
|
||||||
|
for (keycode mod=0; mod < MODIFIERS; mod++) {
|
||||||
|
modifier_sticky[mod] = false;
|
||||||
|
}
|
||||||
|
sticky_on = false;
|
||||||
|
sticky_done = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// return if highest active layer is sticky
|
||||||
|
bool layer_top_is_sticky() {
|
||||||
|
return layer_is_sticky(layers_top);
|
||||||
|
}
|
||||||
|
|
||||||
|
// return if layer is sticky
|
||||||
|
bool layer_is_sticky(layer l) {
|
||||||
|
if (l < KB_LAYERS) {
|
||||||
|
return layer_sticky[l];
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sticky_disable() {
|
||||||
|
for (layer l = 1; l < KB_LAYERS; l++) {
|
||||||
|
if (layer_sticky[l]) {
|
||||||
|
layer_disable(l);
|
||||||
|
layer_sticky[l] = false;
|
||||||
|
debug_printf("sticky %d up\n", l);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sticky_on = false;
|
||||||
|
sticky_done = false;
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// layout info
|
// layout info
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@ -325,11 +343,8 @@ void exec_key() {
|
||||||
|
|
||||||
if (key_function) { (*key_function)(); }
|
if (key_function) { (*key_function)(); }
|
||||||
|
|
||||||
// FIXME
|
if (sticky_on && sticky_done) {
|
||||||
// If the current layer is in the sticky once up state and a key defined
|
sticky_disable();
|
||||||
// for this layer (a non-transparent key) was pressed, pop the layer
|
|
||||||
if (layer_top_sticky() == StickyOnceUp && sticky_done) {
|
|
||||||
layer_disable_top();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -352,12 +367,16 @@ void kbfun_modifier_press_release() {
|
||||||
|
|
||||||
// enable layer
|
// enable layer
|
||||||
void kbfun_layer_enable() {
|
void kbfun_layer_enable() {
|
||||||
|
sticky_done = true;
|
||||||
|
|
||||||
layer l = (layer) current_keycode;
|
layer l = (layer) current_keycode;
|
||||||
layer_enable_upto(l);
|
layer_enable_upto(l);
|
||||||
}
|
}
|
||||||
|
|
||||||
// disable layer
|
// disable layer
|
||||||
void kbfun_layer_disable() {
|
void kbfun_layer_disable() {
|
||||||
|
sticky_done = true;
|
||||||
|
|
||||||
// letting go off a key releases *all* layers on that key
|
// letting go off a key releases *all* layers on that key
|
||||||
for (layer l=0; l <= KB_LAYERS; l++) {
|
for (layer l=0; l <= KB_LAYERS; l++) {
|
||||||
void (*key_function)(void) = kb_keyfunc_release(l, current_row, current_col);
|
void (*key_function)(void) = kb_keyfunc_release(l, current_row, current_col);
|
||||||
|
@ -372,30 +391,20 @@ void kbfun_layer_disable() {
|
||||||
// sticky layer key
|
// sticky layer key
|
||||||
void kbfun_layer_sticky() {
|
void kbfun_layer_sticky() {
|
||||||
layer l = (layer) current_keycode;
|
layer l = (layer) current_keycode;
|
||||||
StickyState top_sticky = layer_top_sticky();
|
|
||||||
|
|
||||||
if (current_is_pressed) {
|
if (current_is_pressed) {
|
||||||
if (l != layers_top) {
|
layer_enable(l);
|
||||||
// only the topmost layer on the stack should be in sticky once state
|
|
||||||
if (top_sticky == StickyOnceDown || top_sticky == StickyOnceUp) {
|
|
||||||
layer_disable_top();
|
|
||||||
}
|
|
||||||
layer_enable(l, StickyOnceDown);
|
|
||||||
debug_printf("sticky %d down!\n", l);
|
|
||||||
|
|
||||||
// this should be the only place we care about this flag being cleared
|
|
||||||
sticky_done = false;
|
sticky_done = false;
|
||||||
}
|
debug_printf("sticky %d down\n", l);
|
||||||
} else {
|
} else {
|
||||||
if (layer_sticky(l) == StickyOnceDown) {
|
if (sticky_done) {
|
||||||
// When releasing this sticky key, pop the layer always
|
|
||||||
layer_disable(l);
|
layer_disable(l);
|
||||||
|
debug_printf("sticky %d up\n", l);
|
||||||
if (!sticky_done) {
|
} else {
|
||||||
// re-enable the sticky key if we didn't actually use it yet
|
layer_sticky[l] = true;
|
||||||
layer_enable(l, StickyOnceUp);
|
sticky_on = true;
|
||||||
debug_printf("sticky %d still down!\n", l);
|
sticky_done = false;
|
||||||
}
|
debug_printf("sticky %d up, but still on\n", l);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,9 @@ void _kbfun_modifier_press_release(bool press,keycode key);
|
||||||
void _kbfun_mediakey_press_release(bool press,keycode key);
|
void _kbfun_mediakey_press_release(bool press,keycode key);
|
||||||
void _kbfun_normal_press_release(bool press,keycode key);
|
void _kbfun_normal_press_release(bool press,keycode key);
|
||||||
keyfunc kb_keyfunc_release(layer l,u8 row,u8 col);
|
keyfunc kb_keyfunc_release(layer l,u8 row,u8 col);
|
||||||
|
void sticky_disable();
|
||||||
|
bool layer_is_sticky(layer l);
|
||||||
|
bool layer_top_is_sticky();
|
||||||
keyfunc kb_keyfunc_press(layer l,u8 row,u8 col);
|
keyfunc kb_keyfunc_press(layer l,u8 row,u8 col);
|
||||||
void layer_enable_upto(layer max_layer);
|
void layer_enable_upto(layer max_layer);
|
||||||
void kbfun_layer_disable();
|
void kbfun_layer_disable();
|
||||||
|
@ -25,12 +28,11 @@ bool is_layer_enable(keyfunc f);
|
||||||
layer layer_peek(layer offset);
|
layer layer_peek(layer offset);
|
||||||
void layer_disable_top();
|
void layer_disable_top();
|
||||||
void layer_disable(layer l);
|
void layer_disable(layer l);
|
||||||
void layer_enable(layer l,StickyState sticky);
|
void layer_enable(layer l);
|
||||||
StickyState layer_sticky(layer l);
|
|
||||||
StickyState layer_top_sticky();
|
|
||||||
layer highest_active_layer(layer offset);
|
layer highest_active_layer(layer offset);
|
||||||
void exec_key();
|
void exec_key();
|
||||||
keycode kb_keycode(layer l,u8 row,u8 col);
|
keycode kb_keycode(layer l,u8 row,u8 col);
|
||||||
void main_key_loop();
|
void main_key_loop();
|
||||||
|
void init_sticky();
|
||||||
void init_layers();
|
void init_layers();
|
||||||
int main();
|
int main();
|
||||||
|
|
Loading…
Reference in New Issue