taken from Hasu codebase (https://github.com/tmk/tmk_keyboard) usb.c/.h
and usb_extra.c/.h, though these files only have the PJRC
copyright/license in the header
the behavior for transparent keys not affecting sticky key state was
broken because kbfun_transparent() was only getting called for key
press and not for key release because the layer for the key was cached
on keypress. By caching the transparent key press result on key press
we can ensure that the main_arg_trans_key_pressed is set correctly for
any key function called on key release
sticky layers in the one time state were being popped anytime
kbfun_press_release() was called, which should only happen if the key
was defined for the sticky layer, i.e. kbfun_transparent() was not the
first function mapped to that key in the topmost layer.
This function gives similar behavior to sticky keys for modifiers
available on most operating systems. It is considered an accessibility
feature because it alleviates the user from having to hold down
modifiers while pressing a key to produce the modified key function. It
is useful for fast touch typing because you can avoid chording motions
which both strain your hands and take your hands out of home-row
position while pressing normal alpha keys.
This function emulates the 3-state behavior which is default on OS X
and optional in Windows where the modifier cycles between
Off->Once->Locked states. This is particularly handy for symbol layers
where you typically only type one symbol before you want to return to
unmodified typing (layer 0), e.g. 'if (condition) { a = "b" + "c"; }'.
If you assign a symbol layer to a thumb key as a layer sticky cycle,
you can type the entire line of code without taking your hands out of
home row position and you do not need to toggle off the layer after
each symbol is pressed, only immediately before keying the symbol.
The exact behavior of the layer sticky cycle function is defined as
follows for each state:
1) One time down (set on key press) - The layer was not active and the
key has been pressed but not yet released. The layer is pushed in the
one time down state.
2) One time up (set on key release) - The layer was active when the
layer sticky key was released. If a key on this layer (not set to
transparent) was pressed before the key was released, the layer will be
popped. If a non-transparent key was not pressed, the layer is popped
and pushed again in the one time up state.
3) Locked (set on key press) - The layer was active and in the one time
up state when the layer sticky key was pressed again. The layer will be
popped if the function is invoked on a subsequent keypress.
- rewrote the layer functions in main() (easiest way to get the to
work.. :) )
- fixed the keymap (i had the numpad keys pushing layer 2 instead of
layer 3)
- changed the numlock keycode.. i was using the wrong one, lol
- and some minor aesthetic changes
- linked lists need to be rewritten to be more memory efficient
- all kbfun functions are now of type `(void kbfun_...(void))`, and the
arguments they need are passed via a group of global `main_arg_...`
variables (and other `main_...` variables)
- changed KBFUN_FUNCTION_ARGS again
- changed kbfun's
- condensed `kbfun_press()` and `kbfun_release()` to `kbfun_press_release()`
- added `kbfun_toggle()`, which toggles keycodes on or off
- added `kbfun_layer_inc_dec_press_release()` which is like
...press_release(), except it increments the layer first (and
decrements it on keyrelease)
- added `_kbfun_exec_key()` (which is a public kbfun*(), but not for
assignment to keycodes) for convenience. used by main(), and
currently 1 of the kbfun*()s. it doesn't save a lot of code, but i
think it makes things slightly easier to read. not quite as elegant
a solution as i'd like, but it might have to do
- changed keymap accordingly
- changed main()
- now using `_kbfun_exec_key()` (instead of essentially inlining the code)
- now sending the USB report once every cycle. i was sending once for
every keypress (lol, by mistake: what i meant to do was only send it
if any keys had been pressed).
- addition to references.md
- keymap modification
- now using 2 shifts => capslock
- the previous capslock key -> tab
- the previous tab key -> left bracket
- bug and omission fixes; notably:
- _is_pressed() no longer changes the value of
`keyboard_modifier_keys`, lol
- kbfun_2_keys_capslock_press_release() now works. (capslock doesn't
register if left or right shift is pressed, so the shift state has
to be stored, cleared, capslock pressed, and shift state restored)
- main() no longer locally overwrites the value of `current_layer`
before sending it to the kbfun. (i didn't realize i was using the
same variable name for two different things)
- improvements
- kbfun_layer_inc() and ...dec() are now variable