Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 33 additions & 16 deletions app/src/pointing/input_processor_temp_layer.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,37 +81,54 @@ static void update_layer_state(struct temp_layer_state *state, bool activate) {
}

struct layer_state_action {
const struct device *dev;
uint8_t layer;
bool activate;
};

K_MSGQ_DEFINE(temp_layer_action_msgq, sizeof(struct layer_state_action),
CONFIG_ZMK_INPUT_PROCESSOR_TEMP_LAYER_MAX_ACTION_EVENTS, 4);

static void layer_action_work_cb(struct k_work *work) {

const struct device *dev = DEVICE_DT_INST_GET(0);
static void deactivate_if_matching(const struct device *dev, uint8_t layer) {
struct temp_layer_data *data = (struct temp_layer_data *)dev->data;

int ret = k_mutex_lock(&data->lock, K_FOREVER);
if (ret < 0) {
LOG_ERR("Error locking for updating %d", ret);
LOG_ERR("Error locking for deactivating %d", ret);
return;
}
if (data->state.is_active && data->state.toggle_layer == layer) {
update_layer_state(&data->state, false);
}
k_mutex_unlock(&data->lock);
}

#define DEACTIVATE_MATCHING(n) deactivate_if_matching(DEVICE_DT_INST_GET(n), action.layer);

static void layer_action_work_cb(struct k_work *work) {
struct layer_state_action action;

while (k_msgq_get(&temp_layer_action_msgq, &action, K_MSEC(10)) >= 0) {
if (!action.activate) {
if (zmk_keymap_layer_active(action.layer)) {
if (action.dev) {
struct temp_layer_data *data = (struct temp_layer_data *)action.dev->data;
int ret = k_mutex_lock(&data->lock, K_FOREVER);
if (ret < 0) {
LOG_ERR("Error locking for updating %d", ret);
continue;
}

if (action.activate) {
update_layer_state(&data->state, true);
} else if (zmk_keymap_layer_active(action.layer)) {
// Only deactivate if we think it's necessary to avoid churn,
// though update_layer_state handles idempotency.
update_layer_state(&data->state, false);
}
k_mutex_unlock(&data->lock);
} else {
update_layer_state(&data->state, true);
// No device specified (timeout case), search for matching instances
DT_INST_FOREACH_STATUS_OKAY(DEACTIVATE_MATCHING)
}
}

k_mutex_unlock(&data->lock);
}

static K_WORK_DEFINE(layer_action_work, layer_action_work_cb);
Expand All @@ -121,7 +138,7 @@ static void layer_disable_callback(struct k_work *work) {
struct k_work_delayable *d_work = k_work_delayable_from_work(work);
int layer_index = ARRAY_INDEX(layer_disable_works, d_work);

struct layer_state_action action = {.layer = layer_index, .activate = false};
struct layer_state_action action = {.dev = NULL, .layer = layer_index, .activate = false};

int ret = k_msgq_put(&temp_layer_action_msgq, &action, K_MSEC(10));
k_work_submit(&layer_action_work);
Expand Down Expand Up @@ -249,7 +266,7 @@ static int temp_layer_handle_event(const struct device *dev, struct input_event

if (!data->state.is_active &&
!should_quick_tap(cfg, data->state.last_tapped_timestamp, k_uptime_get())) {
struct layer_state_action action = {.layer = param1, .activate = true};
struct layer_state_action action = {.dev = dev, .layer = param1, .activate = true};

int ret = k_msgq_put(&temp_layer_action_msgq, &action, K_MSEC(10));
k_work_submit(&layer_action_work);
Expand Down Expand Up @@ -281,19 +298,19 @@ static const struct zmk_input_processor_driver_api temp_layer_driver_api = {
};

/* Event Listeners Conditions */
#define NEEDS_POSITION_HANDLERS(n, ...) DT_INST_PROP_HAS_IDX(n, excluded_positions, 0)
#define NEEDS_KEYCODE_HANDLERS(n, ...) (DT_INST_PROP_OR(n, require_prior_idle_ms, 0) > 0)
#define NEEDS_POSITION_HANDLERS(n) DT_INST_PROP_HAS_IDX(n, excluded_positions, 0) ||
#define NEEDS_KEYCODE_HANDLERS(n) (DT_INST_PROP_OR(n, require_prior_idle_ms, 0) > 0) ||

/* Event Handlers Registration */
ZMK_LISTENER(processor_temp_layer, handle_event_dispatcher);
ZMK_SUBSCRIPTION(processor_temp_layer, zmk_layer_state_changed);

/* Individual Subscriptions */
#if DT_INST_FOREACH_STATUS_OKAY_VARGS(NEEDS_POSITION_HANDLERS, ||)
#if DT_INST_FOREACH_STATUS_OKAY(NEEDS_POSITION_HANDLERS) 0
ZMK_SUBSCRIPTION(processor_temp_layer, zmk_position_state_changed);
#endif

#if DT_INST_FOREACH_STATUS_OKAY_VARGS(NEEDS_KEYCODE_HANDLERS, ||)
#if DT_INST_FOREACH_STATUS_OKAY(NEEDS_KEYCODE_HANDLERS) 0
ZMK_SUBSCRIPTION(processor_temp_layer, zmk_keycode_state_changed);
#endif

Expand Down
Loading