diff --git a/src/main.c b/src/main.c index 35ad0e8..948f426 100644 --- a/src/main.c +++ b/src/main.c @@ -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); } } } diff --git a/src/main.h b/src/main.h index 9778778..7574d1a 100644 --- a/src/main.h +++ b/src/main.h @@ -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();