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 uint16_t u16;
typedef enum StickyState {
StickyNone,
StickyOnceDown,
StickyOnceUp,
} StickyState;
typedef u8 keycode;
typedef u16 media_keycode;
typedef u8 layer;
@ -67,12 +61,15 @@ static u8 current_col;
static layer current_layer;
static keycode current_keycode;
static bool current_is_pressed;
static bool sticky_done;
static bool layers_active[KB_LAYERS];
static StickyState layers_sticky[KB_LAYERS];
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() {
@ -80,8 +77,9 @@ int main() {
usb_init();
while (!usb_configured());
// initialize layers
// initialize
init_layers();
init_sticky();
// never return
main_key_loop();
@ -140,7 +138,6 @@ void main_key_loop() {
void init_layers() {
for (layer l=0; l < KB_LAYERS; l++) {
layers_active[l] = false;
layers_sticky[l] = StickyNone;
}
layers_active[0] = true;
}
@ -158,26 +155,11 @@ layer highest_active_layer(layer offset) {
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
void layer_enable(layer l, StickyState sticky) {
// FIXME split off sticky part
void layer_enable(layer l) {
if (l >= KB_LAYERS) { return; }
layers_active[l] = true;
layers_sticky[l] = sticky;
if (l > layers_top) {
layers_top = l;
@ -191,11 +173,6 @@ void layer_disable(layer l) {
layers_active[l] = false;
if (layers_sticky[l] != StickyNone) {
debug_printf("sticky %d up!\n", l);
}
layers_sticky[l] = StickyNone;
if (l == layers_top) {
layers_top = highest_active_layer(1);
}
@ -235,12 +212,53 @@ void layer_enable_upto(layer max_layer) {
if (is_layer_enable(key_function)) {
layer enable_layer = (layer) kb_keycode(l, current_row, current_col);
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
// ----------------------------------------------------------------------------
@ -325,11 +343,8 @@ void exec_key() {
if (key_function) { (*key_function)(); }
// FIXME
// If the current layer is in the sticky once up state and a key defined
// for this layer (a non-transparent key) was pressed, pop the layer
if (layer_top_sticky() == StickyOnceUp && sticky_done) {
layer_disable_top();
if (sticky_on && sticky_done) {
sticky_disable();
}
}
@ -352,12 +367,16 @@ void kbfun_modifier_press_release() {
// enable layer
void kbfun_layer_enable() {
sticky_done = true;
layer l = (layer) current_keycode;
layer_enable_upto(l);
}
// disable layer
void kbfun_layer_disable() {
sticky_done = true;
// letting go off a key releases *all* layers on that key
for (layer l=0; l <= KB_LAYERS; l++) {
void (*key_function)(void) = kb_keyfunc_release(l, current_row, current_col);
@ -372,30 +391,20 @@ void kbfun_layer_disable() {
// sticky layer key
void kbfun_layer_sticky() {
layer l = (layer) current_keycode;
StickyState top_sticky = layer_top_sticky();
if (current_is_pressed) {
if (l != layers_top) {
// 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
layer_enable(l);
sticky_done = false;
}
debug_printf("sticky %d down\n", l);
} else {
if (layer_sticky(l) == StickyOnceDown) {
// When releasing this sticky key, pop the layer always
if (sticky_done) {
layer_disable(l);
if (!sticky_done) {
// re-enable the sticky key if we didn't actually use it yet
layer_enable(l, StickyOnceUp);
debug_printf("sticky %d still down!\n", l);
}
debug_printf("sticky %d up\n", l);
} else {
layer_sticky[l] = true;
sticky_on = true;
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_normal_press_release(bool press,keycode key);
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);
void layer_enable_upto(layer max_layer);
void kbfun_layer_disable();
@ -25,12 +28,11 @@ bool is_layer_enable(keyfunc f);
layer layer_peek(layer offset);
void layer_disable_top();
void layer_disable(layer l);
void layer_enable(layer l,StickyState sticky);
StickyState layer_sticky(layer l);
StickyState layer_top_sticky();
void layer_enable(layer l);
layer highest_active_layer(layer offset);
void exec_key();
keycode kb_keycode(layer l,u8 row,u8 col);
void main_key_loop();
void init_sticky();
void init_layers();
int main();