diff --git a/src/main.c b/src/main.c index 81687c3..13ad28e 100644 --- a/src/main.c +++ b/src/main.c @@ -58,6 +58,7 @@ typedef void (*keyfunc)(keycode, bool); // globals // ---------------------------------------------------------------------------- +// state of key presses static bool _kb_is_pressed[KB_ROWS][KB_COLUMNS]; static bool (*kb_is_pressed)[KB_ROWS][KB_COLUMNS] = &_kb_is_pressed; @@ -66,17 +67,24 @@ static bool (*kb_was_pressed)[KB_ROWS][KB_COLUMNS] = &_kb_was_pressed; static layer layers_pressed[KB_ROWS][KB_COLUMNS]; +// layer state static i8 layers_active[KB_LAYERS]; static layer layers_top; -static u8 layers_state; +// sticky states static bool layer_sticky_on; static bool layer_sticky[KB_LAYERS]; static bool layer_sticky_done; static u8 mod_sticky; static bool mod_sticky_done; +// key repeat config +static const millis repeat_delay = 300; // ms before key repeat kicks in +static const millis repeat_rate = 13; // send 1 / RATE key press + +// key repeat state static millis time_pressed[KB_ROWS][KB_COLUMNS]; +static bool repeating[KB_ROWS][KB_COLUMNS]; // TODO this only exists as a workaround until we handle our own key repeats static const keyfunc _kb_layer_funcs[] = { @@ -139,26 +147,12 @@ void main_key_loop() { bool is_pressed = (*kb_is_pressed)[row][col]; bool was_pressed = (*kb_was_pressed)[row][col]; - if (is_pressed != was_pressed) { - layer layer; - if (is_pressed) { - layer = layers_top; - layers_pressed[row][col] = layer; - - if (!was_pressed) { - time_pressed[row][col] = now(); - } else { - // repeat - } - } else { - layer = layers_pressed[row][col]; - layers_pressed[row][col] = 0; - - /* debug_printf("ms: %lu\n", now() - time_pressed[row][col]); */ - } - - // set remaining vars, and "execute" key - exec_key(layer, row, col, is_pressed); + if (is_pressed) { + if (!was_pressed) { main_key_down_new(row, col); } + else { main_key_down_repeat(row, col); } + } else { + if (!was_pressed) { continue; } // no change + else { main_key_up(row, col); } } } } @@ -191,6 +185,45 @@ void main_key_loop() { } } +void main_key_up(u8 row, u8 col) { + layer layer = layers_pressed[row][col]; + layers_pressed[row][col] = 0; + + // stop key repeat + if (repeating[row][col]) { + repeating[row][col] = false; + debug_printf("stop: %lu\n", now() - time_pressed[row][col]); + } + + exec_key(layer, row, col, false); +} + +void main_key_down_new(u8 row, u8 col) { + layer layer = layers_top; + layers_pressed[row][col] = layer; + + time_pressed[row][col] = now(); + debug_printf("down: %lu\n", time_pressed[row][col]); + + exec_key(layer, row, col, true); +} + +void main_key_down_repeat(u8 row, u8 col) { + millis t = now(); // consistency! + millis diff = t - time_pressed[row][col]; + + if (!repeating[row][col] && diff >= repeat_delay) { // start repeat + repeating[row][col] = true; + time_pressed[row][col] = t; + + debug_printf("start: %lu\n", diff); + } else if (repeating[row][col] && diff >= repeat_rate) { // continue repeat + time_pressed[row][col] = t; + + debug_printf("cont: %lu\n", diff); + } +} + // ---------------------------------------------------------------------------- // init functions // ---------------------------------------------------------------------------- @@ -217,7 +250,6 @@ void init_layers() { } layers_active[0] = 1; layers_top = 0; - layers_state = 1; for (u8 row=0; row 0; l--) { if (layers_active[l] > 0) { return l; } - /* if (is_set(layers_state, l)) { return l; } */ } // the base layer is always active @@ -254,7 +286,6 @@ void layer_enable(layer l) { if (l >= KB_LAYERS || l == 0) { return; } layers_active[l] += 1; - set_layer(layers_state, l); if (l > layers_top) { layers_top = l; @@ -269,9 +300,6 @@ void layer_disable(layer l) { if (layers_active[l] > 0) { layers_active[l] -= 1; } - if (layers_active[l] == 0) { - unset_layer(layers_state, l); - } if (l == layers_top) { layers_top = highest_active_layer(); diff --git a/src/main.h b/src/main.h index bf1391a..347f739 100644 --- a/src/main.h +++ b/src/main.h @@ -27,8 +27,11 @@ bool is_layer_keyfunc(keyfunc f); keyfunc kb_keyfunc(layer l,u8 row,u8 col); void layer_enable(layer l); layer highest_active_layer(); -void layer_disable(layer l); void exec_key(layer layer,u8 row,u8 col,bool is_pressed); +void layer_disable(layer l); +void main_key_up(u8 row,u8 col); +void main_key_down_repeat(u8 row,u8 col); +void main_key_down_new(u8 row,u8 col); void main_key_loop(); void init_timer(); void init_sticky();