Open okke-formsma opened 3 years ago
Something else that's been a burden for more complex behaviors, is the problem of context.
A subscription for a listener is not associated with any context. This forced introduction of global variables in many behaviors such as 'hold-tap' to keep track of the 'current hold-tap'. If the keycode listener could be registered in a 'context', it could be associated with the currently active hold-tap.
An interface similar to how work-items are handled would be interesting:
If the handler function requires additional information about the work it is to perform, the work item can be embedded in a larger data structure. The handler function can then use the argument value to compute the address of the enclosing data structure with CONTAINER_OF, and thereby obtain access to the additional information it needs.
static void work_handler(struct k_work *work)
{
struct k_work_delayable *dwork = k_work_delayable_from_work(work);
struct work_context *ctx = CONTAINER_OF(dwork, struct work_context,
timed_work);
this would translate to something like
static int keycode_state_changed_listener(const struct zmk_keycode_state_changed *ev)
struct hold_tap_context *hold_tap = CONTAINER_OF(ev, struct hold_tap_context, keycode_listener);
CMakeLists.txt
. This makes it impossible for behavior X to handle event 1 before behavior Y, and handle event 2 after behavior Y does.CMakeLists.txt
, thus it can not control it's priority in event handlers.const zmk_event_t
and do cast checks for which event is received. This seems wasteful. Additionally, many events have astate
("pressed"/"released"). Most event handlers call a different method for each of these. In these cases, we should define two events, one for press and one for release.A possible solution is to keep a (linked) list of event handlers for each event. The event handlers would be ordered by "priority". Event handlers are called in order of priority. In addition to the current
ZMK_SUBSCRIPTION
macro, functions should be exposed for (de)registering event handlers. This could be done similar to zehyr'sK_WORK_DEFINE
/k_work
.example 1: fine grained event handlers with priority
old code:
new code;
example 2: dynamic event handlers
old code
new code