Make CTRL and ALT work in key chords

This commit is contained in:
Johannes Marbach 2021-09-13 20:11:35 +02:00
parent f52a0c0749
commit c07085e7cd
6 changed files with 138 additions and 13 deletions

View file

@ -185,3 +185,42 @@ const int * const bb_layout_get_scancodes(lv_obj_t *keyboard, uint16_t btn_id, i
const int index = sq2lv_layouts[current_layout_id].layers[layer_index].scancode_idxs[btn_id];
return &(sq2lv_layouts[current_layout_id].layers[layer_index].scancodes[index]);
}
bool bb_is_modifier(lv_obj_t *keyboard, uint16_t btn_id) {
if (current_layout_id < 0 || current_layout_id >= sq2lv_num_layouts) {
return false;
}
int layer_index = get_layer_index(keyboard);
if (layer_index < 0 || layer_index >= sq2lv_layouts[current_layout_id].num_layers) {
return false;
}
for (int i = 0; i < sq2lv_layouts[current_layout_id].layers[layer_index].num_modifiers; ++i) {
if (sq2lv_layouts[current_layout_id].layers[layer_index].modifier_idxs[i] == btn_id) {
return true;
}
}
return false;
}
const int * const bb_get_modifier_indexes(lv_obj_t *keyboard, int *num_modifiers) {
if (current_layout_id < 0 || current_layout_id >= sq2lv_num_layouts) {
*num_modifiers = 0;
return NULL;
}
int layer_index = get_layer_index(keyboard);
if (layer_index < 0 || layer_index >= sq2lv_layouts[current_layout_id].num_layers) {
*num_modifiers = 0;
return NULL;
}
*num_modifiers = sq2lv_layouts[current_layout_id].layers[layer_index].num_modifiers;
if (*num_modifiers == 0) {
return NULL;
}
return &(sq2lv_layouts[current_layout_id].layers[layer_index].modifier_idxs[0]);
}

View file

@ -32,7 +32,7 @@
void bb_layout_switch_layout(lv_obj_t *keyboard, sq2lv_layout_id_t layout_id);
/**
* Attempt to perform a layer switch after pressing a key.
* Attempt to perform a layer switch after pressing a key in the current layer.
*
* @param keyboard keyboard widget
* @param btn_id button index corresponding to the pressed key
@ -41,8 +41,8 @@ void bb_layout_switch_layout(lv_obj_t *keyboard, sq2lv_layout_id_t layout_id);
bool bb_layout_switch_layer(lv_obj_t *keyboard, uint16_t btn_id);
/**
* Get scancodes associated with a key.
*
* Get scancodes associated with a key in the current layer.
*
* @param keyboard keyboard widget
* @param btn_id button index corresponding to the key
* @param num_scancodes pointer to an integer into which the number of scancodes will be written
@ -50,4 +50,22 @@ bool bb_layout_switch_layer(lv_obj_t *keyboard, uint16_t btn_id);
*/
const int * const bb_layout_get_scancodes(lv_obj_t *keyboard, uint16_t btn_id, int *num_scancodes);
/**
* Check if a key is a modifier in the current layer.
*
* @param keyboard keyboard widget
* @param btn_id button index corresponding to the key
* @return true if the key is a modifier, false otherwise
*/
bool bb_is_modifier(lv_obj_t *keyboard, uint16_t btn_id);
/**
* Get the button indexes for all modifier keys in the current layer.
*
* @param keyboard keyboard widget
* @param num_modifiers pointer to an integer into which the number of modifiers will be written
* @return pointer to the array of button indexes corresponding to modifier keys
*/
const int * const bb_get_modifier_indexes(lv_obj_t *keyboard, int *num_modifiers);
#endif /* BB_LAYOUT_H */

52
main.c
View file

@ -69,6 +69,16 @@ static void set_theme(bool is_dark);
*/
static void keyboard_value_changed_cb(lv_event_t *event);
/**
* Emit key down and up events for a key.
*
* @param keyboard keyboard widget
* @param btn_id button index corresponding to the key
* @param key_down true if a key down event should be emitted
* @param key_up true if a key up event should be emitted
*/
static void emit_key_events(lv_obj_t *keyboard, uint16_t btn_id, bool key_down, bool key_up);
/**
* Static functions
@ -90,17 +100,47 @@ static void keyboard_value_changed_cb(lv_event_t *event) {
return;
}
/* Note that the LV_BTNMATRIX_CTRL_CHECKED logic is inverted because LV_KEYBOARD_CTRL_BTN_FLAGS already
* contains LV_BTNMATRIX_CTRL_CHECKED. As a result, pressing e.g. CTRL will _un_check the key. To account
* for this, we invert the meaning of "checked" below. */
bool is_modifier = bb_is_modifier(keyboard, btn_id);
bool is_checked = !lv_btnmatrix_has_btn_ctrl(keyboard, btn_id, LV_BTNMATRIX_CTRL_CHECKED);
/* Emit key events. Suppress key up events for modifiers unless they were unchecked. For checked modifiers
* the key up events are sent with the next non-modifier key press. */
emit_key_events(keyboard, btn_id, true, !is_modifier || !is_checked);
/* Pop any previously checked modifiers when a non-modifier key was pressed */
if (!is_modifier) {
int num_modifiers = 0;
int *modifier_idxs = bb_get_modifier_indexes(keyboard, &num_modifiers);
for (int i = 0; i < num_modifiers; ++i) {
if (!lv_btnmatrix_has_btn_ctrl(keyboard, modifier_idxs[i], LV_BTNMATRIX_CTRL_CHECKED)) {
emit_key_events(keyboard, modifier_idxs[i], false, true);
lv_btnmatrix_set_btn_ctrl(keyboard, modifier_idxs[i], LV_BTNMATRIX_CTRL_CHECKED);
}
}
}
}
static void emit_key_events(lv_obj_t *keyboard, uint16_t btn_id, bool key_down, bool key_up) {
int num_scancodes = 0;
int *scancodes = bb_layout_get_scancodes(keyboard, btn_id, &num_scancodes);
/* Emit key downs in forward order */
for (int i = 0; i < num_scancodes; ++i) {
bb_uinput_device_emit_key_down(scancodes[i]);
if (key_down) {
/* Emit key down events in forward order */
for (int i = 0; i < num_scancodes; ++i) {
bb_uinput_device_emit_key_down(scancodes[i]);
}
}
/* Emit key ups in backward order */
for (int i = num_scancodes - 1; i >= 0; --i) {
bb_uinput_device_emit_key_up(scancodes[i]);
if (key_up) {
/* Emit key up events in backward order */
for (int i = num_scancodes - 1; i >= 0; --i) {
bb_uinput_device_emit_key_up(scancodes[i]);
}
}
}

View file

@ -24,13 +24,19 @@ static const char * const keycaps_lower_terminal_us[] = { \
};
static const lv_btnmatrix_ctrl_t attributes_lower_terminal_us[] = { \
LV_KEYBOARD_CTRL_BTN_FLAGS | 3, LV_KEYBOARD_CTRL_BTN_FLAGS | 3, LV_KEYBOARD_CTRL_BTN_FLAGS | 3, LV_KEYBOARD_CTRL_BTN_FLAGS | 3, LV_KEYBOARD_CTRL_BTN_FLAGS | 3, LV_KEYBOARD_CTRL_BTN_FLAGS | 3, \
LV_KEYBOARD_CTRL_BTN_FLAGS | LV_BTNMATRIX_CTRL_CHECKABLE | 3, LV_KEYBOARD_CTRL_BTN_FLAGS | LV_BTNMATRIX_CTRL_CHECKABLE | 3, LV_KEYBOARD_CTRL_BTN_FLAGS | 3, LV_KEYBOARD_CTRL_BTN_FLAGS | 3, LV_KEYBOARD_CTRL_BTN_FLAGS | 3, LV_KEYBOARD_CTRL_BTN_FLAGS | 3, \
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, \
2, 2, 2, 2, 2, 2, 2, 2, 2, \
LV_KEYBOARD_CTRL_BTN_FLAGS | 3, 2, 2, 2, 2, 2, 2, 2, LV_KEYBOARD_CTRL_BTN_FLAGS | 3, \
LV_KEYBOARD_CTRL_BTN_FLAGS | 3, LV_KEYBOARD_CTRL_BTN_FLAGS | 7, LV_KEYBOARD_CTRL_BTN_FLAGS | 3 \
};
static const int num_modifiers_lower_terminal_us = 2;
static const int modifier_idxs_lower_terminal_us[] = { \
0, 1 \
};
static const int num_switchers_lower_terminal_us = 2;
static const int switcher_idxs_lower_terminal_us[] = { \
@ -80,13 +86,19 @@ static const char * const keycaps_upper_terminal_us[] = { \
};
static const lv_btnmatrix_ctrl_t attributes_upper_terminal_us[] = { \
LV_KEYBOARD_CTRL_BTN_FLAGS | 3, LV_KEYBOARD_CTRL_BTN_FLAGS | 3, LV_KEYBOARD_CTRL_BTN_FLAGS | 3, LV_KEYBOARD_CTRL_BTN_FLAGS | 3, LV_KEYBOARD_CTRL_BTN_FLAGS | 3, LV_KEYBOARD_CTRL_BTN_FLAGS | 3, \
LV_KEYBOARD_CTRL_BTN_FLAGS | LV_BTNMATRIX_CTRL_CHECKABLE | 3, LV_KEYBOARD_CTRL_BTN_FLAGS | LV_BTNMATRIX_CTRL_CHECKABLE | 3, LV_KEYBOARD_CTRL_BTN_FLAGS | 3, LV_KEYBOARD_CTRL_BTN_FLAGS | 3, LV_KEYBOARD_CTRL_BTN_FLAGS | 3, LV_KEYBOARD_CTRL_BTN_FLAGS | 3, \
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, \
2, 2, 2, 2, 2, 2, 2, 2, 2, \
LV_KEYBOARD_CTRL_BTN_FLAGS | 3, 2, 2, 2, 2, 2, 2, 2, LV_KEYBOARD_CTRL_BTN_FLAGS | 3, \
LV_KEYBOARD_CTRL_BTN_FLAGS | 3, LV_KEYBOARD_CTRL_BTN_FLAGS | 7, LV_KEYBOARD_CTRL_BTN_FLAGS | 3 \
};
static const int num_modifiers_upper_terminal_us = 2;
static const int modifier_idxs_upper_terminal_us[] = { \
0, 1 \
};
static const int num_switchers_upper_terminal_us = 2;
static const int switcher_idxs_upper_terminal_us[] = { \
@ -136,13 +148,19 @@ static const char * const keycaps_numbers_terminal_us[] = { \
};
static const lv_btnmatrix_ctrl_t attributes_numbers_terminal_us[] = { \
LV_KEYBOARD_CTRL_BTN_FLAGS | 3, LV_KEYBOARD_CTRL_BTN_FLAGS | 3, LV_KEYBOARD_CTRL_BTN_FLAGS | 3, LV_KEYBOARD_CTRL_BTN_FLAGS | 3, LV_KEYBOARD_CTRL_BTN_FLAGS | 3, LV_KEYBOARD_CTRL_BTN_FLAGS | 3, \
LV_KEYBOARD_CTRL_BTN_FLAGS | LV_BTNMATRIX_CTRL_CHECKABLE | 3, LV_KEYBOARD_CTRL_BTN_FLAGS | LV_BTNMATRIX_CTRL_CHECKABLE | 3, LV_KEYBOARD_CTRL_BTN_FLAGS | 3, LV_KEYBOARD_CTRL_BTN_FLAGS | 3, LV_KEYBOARD_CTRL_BTN_FLAGS | 3, LV_KEYBOARD_CTRL_BTN_FLAGS | 3, \
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, \
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, \
2, 2, 2, 2, 2, 2, 2, LV_KEYBOARD_CTRL_BTN_FLAGS | 3, \
LV_KEYBOARD_CTRL_BTN_FLAGS | 3, LV_KEYBOARD_CTRL_BTN_FLAGS | 7, 2, LV_KEYBOARD_CTRL_BTN_FLAGS | 3 \
};
static const int num_modifiers_numbers_terminal_us = 2;
static const int modifier_idxs_numbers_terminal_us[] = { \
0, 1 \
};
static const int num_switchers_numbers_terminal_us = 1;
static const int switcher_idxs_numbers_terminal_us[] = { \
@ -188,6 +206,8 @@ static const sq2lv_layer_t layers_terminal_us[] = {
.num_keys = num_keys_lower_terminal_us,
.keycaps = keycaps_lower_terminal_us,
.attributes = attributes_lower_terminal_us,
.num_modifiers = num_modifiers_lower_terminal_us,
.modifier_idxs = modifier_idxs_lower_terminal_us,
.num_switchers = num_switchers_lower_terminal_us,
.switcher_idxs = switcher_idxs_lower_terminal_us,
.switcher_dests = switcher_dests_lower_terminal_us,
@ -200,6 +220,8 @@ static const sq2lv_layer_t layers_terminal_us[] = {
.num_keys = num_keys_upper_terminal_us,
.keycaps = keycaps_upper_terminal_us,
.attributes = attributes_upper_terminal_us,
.num_modifiers = num_modifiers_upper_terminal_us,
.modifier_idxs = modifier_idxs_upper_terminal_us,
.num_switchers = num_switchers_upper_terminal_us,
.switcher_idxs = switcher_idxs_upper_terminal_us,
.switcher_dests = switcher_dests_upper_terminal_us,
@ -212,6 +234,8 @@ static const sq2lv_layer_t layers_terminal_us[] = {
.num_keys = num_keys_numbers_terminal_us,
.keycaps = keycaps_numbers_terminal_us,
.attributes = attributes_numbers_terminal_us,
.num_modifiers = num_modifiers_numbers_terminal_us,
.modifier_idxs = modifier_idxs_numbers_terminal_us,
.num_switchers = num_switchers_numbers_terminal_us,
.switcher_idxs = switcher_idxs_numbers_terminal_us,
.switcher_dests = switcher_dests_numbers_terminal_us,

View file

@ -20,6 +20,10 @@ typedef struct {
const char ** const keycaps;
/* Button matrix attributes */
const lv_btnmatrix_ctrl_t * const attributes;
/* Number of modifier keys */
const int num_modifiers;
/* Button indexes of modifier keys */
const int * const modifier_idxs;
/* Number of buttons that trigger a layer switch */
const int num_switchers;
/* Button indexes that trigger a layer switch */

@ -1 +1 @@
Subproject commit 5f10b71d79e33b86c157c21b25575c46ca25c254
Subproject commit c0e99da8f58e525d87de5f3c2cf5f772d827fb1f