From 270feb968a251165157a321109a5b9d4a38c87a7 Mon Sep 17 00:00:00 2001 From: Stefan Dorn Date: Tue, 14 Jun 2016 11:34:43 +0100 Subject: [PATCH] sticky modifier keys! --- generate_layout.rb | 238 +++++++++++++++++++++--------------------- src/keyboard/layout.c | 32 +++--- src/main.c | 72 ++++++++----- src/main.h | 5 +- 4 files changed, 182 insertions(+), 165 deletions(-) diff --git a/generate_layout.rb b/generate_layout.rb index 8475dc3..5b2169d 100755 --- a/generate_layout.rb +++ b/generate_layout.rb @@ -279,125 +279,125 @@ HEADER end keys = [ - # letter type punc type nav type func type - %w{ NULL }, %w{ }, %w{ }, %w{ }, # dummy key - # - # left hand - # number - # letter type punc type nav type func type - %w{ 0 }, %w{ f11 }, %w{ f11 }, %w{ f11 }, # 1.5 - %w{ 1 }, %w{ f1 }, %w{ f1 }, %w{ f1 }, - %w{ 2 }, %w{ f2 }, %w{ f2 }, %w{ f2 }, - %w{ 3 }, %w{ f3 }, %w{ f3 }, %w{ f3 }, - %w{ 4 }, %w{ f4 }, %w{ f4 }, %w{ f4 }, - %w{ 5 }, %w{ f5 }, %w{ f5 }, %w{ f5 }, - %w{ 6 }, %w{ f6 }, %w{ f6 }, %w{ f6 }, - # top - # letter type punc type nav type func type - %w{ x }, %w{ ~ shifted }, %w{ escape }, %w{ }, # 1.5 - %w{ x }, %w{ ~ shifted }, %w{ escape }, %w{ }, - %w{ v }, %w{ [ }, %w{ backspace }, %w{ }, - %w{ l }, %w{ ' }, %w{ enter }, %w{ }, - %w{ c }, %w{ < shifted }, %w{ delete }, %w{ }, - %w{ w }, %w{ \\ }, %w{ insert }, %w{ }, - %w{ tab }, %w{ }, %w{ }, %w{ }, # 1.5 - # home - # letter type punc type nav type func type - %w{ umlaut mod }, %w{ }, %w{ }, %w{ }, # 1.5 - %w{ u }, %w{ , }, %w{ left }, %w{ audio_mute media }, - %w{ i }, %w{ \{ shifted }, %w{ up }, %w{ audio_vol_up media }, - %w{ a }, %w{ ? shifted }, %w{ down }, %w{ audio_vol_down media }, - %w{ e }, %w{ ! shifted }, %w{ right }, %w{ next_track media }, - %w{ o }, %w{ ( shifted }, %w{ tab }, %w{ prev_track media }, - # bottom - # letter type punc type nav type func type - %w{ shift_l capslock }, %w{ }, %w{ }, %w{ }, # 1.5 - %w{ % shifted }, %w{ ` }, %w{ home }, %w{ }, - %w{ * shifted }, %w{ ^ shifted }, %w{ page_up }, %w{ }, - %w{ : shifted }, %w{ | shifted }, %w{ page_down }, %w{ }, - %w{ p }, %w{ - }, %w{ end }, %w{ }, - %w{ z }, %w{ @ shifted }, %w{ }, %w{ }, - %w{ enter }, %w{ }, %w{ }, %w{ }, # 1.5 - # underbottom - # letter type punc type nav type func type - %w{ left }, %w{ }, %w{ }, %w{ }, - %w{ up }, %w{ }, %w{ }, %w{ }, - %w{ down }, %w{ }, %w{ }, %w{ }, - %w{ right }, %w{ }, %w{ }, %w{ }, - %w{ win mod }, %w{ }, %w{ }, %w{ }, - # thumb-top - # letter type punc type nav type func type - %w{ scroll_lock }, %w{ }, %w{ }, %w{ }, - %w{ func layer }, %w{ }, %w{ }, %w{ }, - # thumb-double - # letter type punc type nav type func type - %w{ space }, %w{ }, %w{ }, %w{ }, - %w{ control mod }, %w{ }, %w{ }, %w{ }, - %w{ alt mod }, %w{ }, %w{ }, %w{ }, - # thumb-home - # letter type punc type nav type func type - %w{ space }, %w{ }, %w{ }, %w{ }, - %w{ control mod }, %w{ }, %w{ }, %w{ }, - %w{ alt mod }, %w{ }, %w{ }, %w{ }, - # - # right hand - # - # number - # letter type punc type nav type func type - %w{ 5 }, %w{ f5 }, %w{ f5 }, %w{ f5 }, # 1.5 - %w{ 6 }, %w{ f6 }, %w{ f6 }, %w{ f6 }, - %w{ 7 }, %w{ f7 }, %w{ f7 }, %w{ f7 }, - %w{ 8 }, %w{ f8 }, %w{ f8 }, %w{ f8 }, - %w{ 9 }, %w{ f9 }, %w{ f9 }, %w{ f9 }, - %w{ 0 }, %w{ f10 }, %w{ f10 }, %w{ f10 }, - %w{ 0 }, %w{ f12 }, %w{ f12 }, %w{ f12 }, - # top - # letter type punc type nav type func type - %w{ NULL }, %w{ }, %w{ }, %w{ }, # 1.5 - %w{ k }, %w{ = }, %w{ 9 }, %w{ f9 }, - %w{ h }, %w{ > shifted }, %w{ 5 }, %w{ f5 }, - %w{ g }, %w{ " shifted }, %w{ 6 }, %w{ f6 }, - %w{ f }, %w{ ] }, %w{ 7 }, %w{ f7 }, - %w{ q }, %w{ ` }, %w{ 8 }, %w{ f8 }, - %w{ q }, %w{ ` }, %w{ 8 }, %w{ f8 }, # 1.5 - # home - # letter type punc type nav type func type - %w{ s }, %w{ ) shifted }, %w{ 0 }, %w{ f10 }, - %w{ n }, %w{ _ shifted }, %w{ 1 }, %w{ f1 }, - %w{ r }, %w{ / }, %w{ 2 }, %w{ f2 }, - %w{ t }, %w{ \} shifted }, %w{ 3 }, %w{ f3 }, - %w{ d }, %w{ . }, %w{ 4 }, %w{ f4 }, - %w{ umlaut mod }, %w{ }, %w{ }, %w{ }, # 1.5 - # bottom - # letter type punc type nav type func type - %w{ enter }, %w{ }, %w{ }, %w{ }, # 1.5 - %w{ b }, %w{ + shifted }, %w{ 9 }, %w{ f9 }, - %w{ m }, %w{ $ shifted }, %w{ 5 }, %w{ f5 }, - %w{ j }, %w{ & shifted }, %w{ 6 }, %w{ f6 }, - %w{ y }, %w{ # shifted }, %w{ 7 }, %w{ f7 }, - %w{ ; }, %w{ ^ shifted }, %w{ 8 }, %w{ f8 }, - %w{ shift_r capslock }, %w{ }, %w{ }, %w{ }, # 1.5 - # underbottom - # letter type punc type nav type func type - %w{ nav layer }, %w{ }, %w{ }, %w{ }, - %w{ left }, %w{ }, %w{ }, %w{ }, - %w{ up }, %w{ }, %w{ }, %w{ }, - %w{ down }, %w{ }, %w{ }, %w{ }, - %w{ right }, %w{ }, %w{ }, %w{ }, - # thumb-top - # letter type punc type nav type func type - %w{ punc layer }, %w{ }, %w{ func layer }, %w{ }, - %w{ nav layer }, %w{ func layer }, %w{ }, %w{ }, - # thumb-double - # letter type punc type nav type func type - %w{ menu }, %w{ }, %w{ }, %w{ }, - %w{ func layer }, %w{ }, %w{ }, %w{ }, - %w{ punc sticky }, %w{ punc layer }, %w{ NULL }, %w{ NULL }, - # thumb-home - # letter type punc type nav type func type - %w{ menu }, %w{ }, %w{ }, %w{ }, - %w{ func layer }, %w{ }, %w{ }, %w{ }, - %w{ punc sticky }, %w{ punc layer }, %w{ NULL }, %w{ NULL }, + # letter type punc type nav type func type + %w{ NULL }, %w{ }, %w{ }, %w{ }, # dummy key + # + # left hand + # number + # letter type punc type nav type func type + %w{ 0 }, %w{ f11 }, %w{ f11 }, %w{ f11 }, # 1.5 + %w{ 1 }, %w{ f1 }, %w{ f1 }, %w{ f1 }, + %w{ 2 }, %w{ f2 }, %w{ f2 }, %w{ f2 }, + %w{ 3 }, %w{ f3 }, %w{ f3 }, %w{ f3 }, + %w{ 4 }, %w{ f4 }, %w{ f4 }, %w{ f4 }, + %w{ 5 }, %w{ f5 }, %w{ f5 }, %w{ f5 }, + %w{ 6 }, %w{ f6 }, %w{ f6 }, %w{ f6 }, + # top + # letter type punc type nav type func type + %w{ x }, %w{ ~ shifted }, %w{ escape }, %w{ }, # 1.5 + %w{ x }, %w{ ~ shifted }, %w{ escape }, %w{ }, + %w{ v }, %w{ [ }, %w{ backspace }, %w{ }, + %w{ l }, %w{ ' }, %w{ enter }, %w{ }, + %w{ c }, %w{ < shifted }, %w{ delete }, %w{ }, + %w{ w }, %w{ \\ }, %w{ insert }, %w{ }, + %w{ tab }, %w{ }, %w{ }, %w{ }, # 1.5 + # home + # letter type punc type nav type func type + %w{ umlaut mod }, %w{ }, %w{ }, %w{ }, # 1.5 + %w{ u }, %w{ , }, %w{ left }, %w{ audio_mute media }, + %w{ i }, %w{ \{ shifted }, %w{ up }, %w{ audio_vol_up media }, + %w{ a }, %w{ ? shifted }, %w{ down }, %w{ audio_vol_down media }, + %w{ e }, %w{ ! shifted }, %w{ right }, %w{ next_track media }, + %w{ o }, %w{ ( shifted }, %w{ tab }, %w{ prev_track media }, + # bottom + # letter type punc type nav type func type + %w{ shift_l capslock }, %w{ }, %w{ }, %w{ }, # 1.5 + %w{ % shifted }, %w{ ` }, %w{ home }, %w{ }, + %w{ * shifted }, %w{ ^ shifted }, %w{ page_up }, %w{ }, + %w{ : shifted }, %w{ | shifted }, %w{ page_down }, %w{ }, + %w{ p }, %w{ - }, %w{ end }, %w{ }, + %w{ z }, %w{ @ shifted }, %w{ }, %w{ }, + %w{ enter }, %w{ }, %w{ }, %w{ }, # 1.5 + # underbottom + # letter type punc type nav type func type + %w{ left }, %w{ }, %w{ }, %w{ }, + %w{ up }, %w{ }, %w{ }, %w{ }, + %w{ down }, %w{ }, %w{ }, %w{ }, + %w{ right }, %w{ }, %w{ }, %w{ }, + %w{ win mod }, %w{ }, %w{ }, %w{ }, + # thumb-top + # letter type punc type nav type func type + %w{ scroll_lock }, %w{ }, %w{ }, %w{ }, + %w{ func layer }, %w{ }, %w{ }, %w{ }, + # thumb-double + # letter type punc type nav type func type + %w{ space }, %w{ }, %w{ }, %w{ }, + %w{ control mod }, %w{ }, %w{ }, %w{ }, + %w{ alt mod }, %w{ }, %w{ }, %w{ }, + # thumb-home + # letter type punc type nav type func type + %w{ space }, %w{ }, %w{ }, %w{ }, + %w{ control sticky_mod }, %w{ }, %w{ }, %w{ }, + %w{ alt sticky_mod }, %w{ }, %w{ }, %w{ }, + # + # right hand + # + # number + # letter type punc type nav type func type + %w{ 5 }, %w{ f5 }, %w{ f5 }, %w{ f5 }, # 1.5 + %w{ 6 }, %w{ f6 }, %w{ f6 }, %w{ f6 }, + %w{ 7 }, %w{ f7 }, %w{ f7 }, %w{ f7 }, + %w{ 8 }, %w{ f8 }, %w{ f8 }, %w{ f8 }, + %w{ 9 }, %w{ f9 }, %w{ f9 }, %w{ f9 }, + %w{ 0 }, %w{ f10 }, %w{ f10 }, %w{ f10 }, + %w{ 0 }, %w{ f12 }, %w{ f12 }, %w{ f12 }, + # top + # letter type punc type nav type func type + %w{ NULL }, %w{ }, %w{ }, %w{ }, # 1.5 + %w{ k }, %w{ = }, %w{ 9 }, %w{ f9 }, + %w{ h }, %w{ > shifted }, %w{ 5 }, %w{ f5 }, + %w{ g }, %w{ " shifted }, %w{ 6 }, %w{ f6 }, + %w{ f }, %w{ ] }, %w{ 7 }, %w{ f7 }, + %w{ q }, %w{ ` }, %w{ 8 }, %w{ f8 }, + %w{ q }, %w{ ` }, %w{ 8 }, %w{ f8 }, # 1.5 + # home + # letter type punc type nav type func type + %w{ s }, %w{ ) shifted }, %w{ 0 }, %w{ f10 }, + %w{ n }, %w{ _ shifted }, %w{ 1 }, %w{ f1 }, + %w{ r }, %w{ / }, %w{ 2 }, %w{ f2 }, + %w{ t }, %w{ \} shifted }, %w{ 3 }, %w{ f3 }, + %w{ d }, %w{ . }, %w{ 4 }, %w{ f4 }, + %w{ umlaut mod }, %w{ }, %w{ }, %w{ }, # 1.5 + # bottom + # letter type punc type nav type func type + %w{ enter }, %w{ }, %w{ }, %w{ }, # 1.5 + %w{ b }, %w{ + shifted }, %w{ 9 }, %w{ f9 }, + %w{ m }, %w{ $ shifted }, %w{ 5 }, %w{ f5 }, + %w{ j }, %w{ & shifted }, %w{ 6 }, %w{ f6 }, + %w{ y }, %w{ # shifted }, %w{ 7 }, %w{ f7 }, + %w{ ; }, %w{ ^ shifted }, %w{ 8 }, %w{ f8 }, + %w{ shift_r capslock }, %w{ }, %w{ }, %w{ }, # 1.5 + # underbottom + # letter type punc type nav type func type + %w{ nav layer }, %w{ }, %w{ }, %w{ }, + %w{ left }, %w{ }, %w{ }, %w{ }, + %w{ up }, %w{ }, %w{ }, %w{ }, + %w{ down }, %w{ }, %w{ }, %w{ }, + %w{ right }, %w{ }, %w{ }, %w{ }, + # thumb-top + # letter type punc type nav type func type + %w{ punc layer }, %w{ }, %w{ func layer }, %w{ }, + %w{ nav layer }, %w{ func layer }, %w{ }, %w{ }, + # thumb-double + # letter type punc type nav type func type + %w{ menu }, %w{ }, %w{ }, %w{ }, + %w{ func layer }, %w{ }, %w{ }, %w{ }, + %w{ punc sticky }, %w{ punc layer }, %w{ NULL }, %w{ NULL }, + # thumb-home + # letter type punc type nav type func type + %w{ menu }, %w{ }, %w{ }, %w{ }, + %w{ func layer }, %w{ }, %w{ }, %w{ }, + %w{ punc sticky }, %w{ punc layer }, %w{ NULL }, %w{ NULL }, ].each_slice(Key::Layers.size).map do |layers| Key.new layers diff --git a/src/keyboard/layout.c b/src/keyboard/layout.c index f77fc1d..fa36538 100644 --- a/src/keyboard/layout.c +++ b/src/keyboard/layout.c @@ -375,8 +375,8 @@ static const keyfunc PROGMEM _kb_layout_press[KB_LAYERS][KB_ROWS][KB_COLUMNS] (keyfunc) &kbfun_modifier_press_release, (keyfunc) &kbfun_modifier_press_release, (keyfunc) &kbfun_normal_press_release, -(keyfunc) &kbfun_modifier_press_release, -(keyfunc) &kbfun_modifier_press_release, +(keyfunc) &kbfun_modifier_sticky, +(keyfunc) &kbfun_modifier_sticky, (keyfunc) &kbfun_normal_press_release, (keyfunc) &kbfun_normal_press_release, (keyfunc) &kbfun_normal_press_release, @@ -458,8 +458,8 @@ KB_MATRIX_LAYER( (keyfunc) &kbfun_modifier_press_release, (keyfunc) &kbfun_modifier_press_release, (keyfunc) &kbfun_normal_press_release, -(keyfunc) &kbfun_modifier_press_release, -(keyfunc) &kbfun_modifier_press_release, +(keyfunc) &kbfun_modifier_sticky, +(keyfunc) &kbfun_modifier_sticky, (keyfunc) &kbfun_normal_press_release, (keyfunc) &kbfun_normal_press_release, (keyfunc) &kbfun_normal_press_release, @@ -541,8 +541,8 @@ KB_MATRIX_LAYER( (keyfunc) &kbfun_modifier_press_release, (keyfunc) &kbfun_modifier_press_release, (keyfunc) &kbfun_normal_press_release, -(keyfunc) &kbfun_modifier_press_release, -(keyfunc) &kbfun_modifier_press_release, +(keyfunc) &kbfun_modifier_sticky, +(keyfunc) &kbfun_modifier_sticky, (keyfunc) &kbfun_normal_press_release, (keyfunc) &kbfun_normal_press_release, (keyfunc) &kbfun_normal_press_release, @@ -624,8 +624,8 @@ KB_MATRIX_LAYER( (keyfunc) &kbfun_modifier_press_release, (keyfunc) &kbfun_modifier_press_release, (keyfunc) &kbfun_normal_press_release, -(keyfunc) &kbfun_modifier_press_release, -(keyfunc) &kbfun_modifier_press_release, +(keyfunc) &kbfun_modifier_sticky, +(keyfunc) &kbfun_modifier_sticky, (keyfunc) &kbfun_normal_press_release, (keyfunc) &kbfun_normal_press_release, (keyfunc) &kbfun_normal_press_release, @@ -707,8 +707,8 @@ static const keyfunc PROGMEM _kb_layout_release[KB_LAYERS][KB_ROWS][KB_COLUMNS] (keyfunc) &kbfun_modifier_press_release, (keyfunc) &kbfun_modifier_press_release, (keyfunc) &kbfun_normal_press_release, -(keyfunc) &kbfun_modifier_press_release, -(keyfunc) &kbfun_modifier_press_release, +(keyfunc) &kbfun_modifier_sticky, +(keyfunc) &kbfun_modifier_sticky, (keyfunc) &kbfun_normal_press_release, (keyfunc) &kbfun_normal_press_release, (keyfunc) &kbfun_normal_press_release, @@ -790,8 +790,8 @@ KB_MATRIX_LAYER( (keyfunc) &kbfun_modifier_press_release, (keyfunc) &kbfun_modifier_press_release, (keyfunc) &kbfun_normal_press_release, -(keyfunc) &kbfun_modifier_press_release, -(keyfunc) &kbfun_modifier_press_release, +(keyfunc) &kbfun_modifier_sticky, +(keyfunc) &kbfun_modifier_sticky, (keyfunc) &kbfun_normal_press_release, (keyfunc) &kbfun_normal_press_release, (keyfunc) &kbfun_normal_press_release, @@ -873,8 +873,8 @@ KB_MATRIX_LAYER( (keyfunc) &kbfun_modifier_press_release, (keyfunc) &kbfun_modifier_press_release, (keyfunc) &kbfun_normal_press_release, -(keyfunc) &kbfun_modifier_press_release, -(keyfunc) &kbfun_modifier_press_release, +(keyfunc) &kbfun_modifier_sticky, +(keyfunc) &kbfun_modifier_sticky, (keyfunc) &kbfun_normal_press_release, (keyfunc) &kbfun_normal_press_release, (keyfunc) &kbfun_normal_press_release, @@ -956,8 +956,8 @@ KB_MATRIX_LAYER( (keyfunc) &kbfun_modifier_press_release, (keyfunc) &kbfun_modifier_press_release, (keyfunc) &kbfun_normal_press_release, -(keyfunc) &kbfun_modifier_press_release, -(keyfunc) &kbfun_modifier_press_release, +(keyfunc) &kbfun_modifier_sticky, +(keyfunc) &kbfun_modifier_sticky, (keyfunc) &kbfun_normal_press_release, (keyfunc) &kbfun_normal_press_release, (keyfunc) &kbfun_normal_press_release, diff --git a/src/main.c b/src/main.c index 948f426..92f78c3 100644 --- a/src/main.c +++ b/src/main.c @@ -62,13 +62,13 @@ static layer current_layer; static keycode current_keycode; static bool current_is_pressed; -static bool layers_active[KB_LAYERS]; -static layer layers_top = 0; +static bool layers_active[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]; +static u8 modifier_sticky; // ---------------------------------------------------------------------------- @@ -126,6 +126,12 @@ void main_key_loop() { usb_keyboard_send(); usb_extra_consumer_send(); + // unset sticky keys if necessary + if (sticky_on && sticky_done) { + sticky_disable(); + usb_keyboard_send(); + } + // debounce in ms; see keyswitch spec for necessary value _delay_ms(5); } @@ -227,36 +233,29 @@ void init_sticky() { layer_sticky[l] = false; } for (keycode mod=0; mod < MODIFIERS; mod++) { - modifier_sticky[mod] = false; + modifier_sticky = 0; } 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; + layer_sticky[l] = false; debug_printf("sticky %d up\n", l); } } - sticky_on = false; - sticky_done = false; + if (modifier_sticky) { + debug_printf("mod %d up\n", modifier_sticky); + keyboard_modifier_keys &= ~modifier_sticky; + modifier_sticky = 0; + } + + sticky_on = false; + sticky_done = false; } // ---------------------------------------------------------------------------- @@ -342,10 +341,6 @@ void exec_key() { : kb_keyfunc_release(current_layer, current_row, current_col) ); if (key_function) { (*key_function)(); } - - if (sticky_on && sticky_done) { - sticky_disable(); - } } // normal key @@ -390,16 +385,16 @@ void kbfun_layer_disable() { // sticky layer key void kbfun_layer_sticky() { - layer l = (layer) current_keycode; + layer l = (layer) current_keycode; if (current_is_pressed) { layer_enable(l); - sticky_done = false; + sticky_done = false; debug_printf("sticky %d down\n", l); } else { if (sticky_done) { layer_disable(l); - debug_printf("sticky %d up\n", l); + debug_printf("sticky %d up and done\n", l); } else { layer_sticky[l] = true; sticky_on = true; @@ -409,6 +404,29 @@ void kbfun_layer_sticky() { } } +// sticky modifier key +void kbfun_modifier_sticky() { + // TODO handle: sticky, then same modifier + // TODO split sticky_on/done layer vs modifier so we can fine-tune it more? + keycode mod = current_keycode; + + if (current_is_pressed) { + kbfun_modifier_press_release(); + sticky_done = false; + debug_printf("mod %d down\n", mod); + } else { + if (sticky_done) { + kbfun_modifier_press_release(); + debug_printf("mod %d up and done\n", mod); + } else { + modifier_sticky |= 1<