rework sticky layer keys

master
Stefan Dorn 2016-06-14 10:51:17 +01:00
parent f52da5065a
commit 6786b70ecc
2 changed files with 70 additions and 59 deletions

View File

@ -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);
} }
} }
} }

View File

@ -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();