From 522580020fc6808477b3c1148482fb95e43b94a8 Mon Sep 17 00:00:00 2001 From: ulixxe <1309337+ulixxe@users.noreply.github.com> Date: Wed, 14 Aug 2024 13:45:40 +0200 Subject: [PATCH] Increased flexibility in selecting layers ADD: dummy "with_other" to allow dual-key behavior for non-modifier keys without a hold action. ADD: "or_layer" condition to "define_layer". --- README.md | 43 ++++++++- config.example.txt | 6 ++ keyboard_remapper.c | 2 +- remap.c | 206 ++++++++++++++++++++++++++++++++------------ 4 files changed, 197 insertions(+), 60 deletions(-) mode change 100644 => 100755 config.example.txt diff --git a/README.md b/README.md index b91e7e7..228773a 100644 --- a/README.md +++ b/README.md @@ -117,10 +117,25 @@ Layers can be activated momentarily or permanently: - **`when_press`**: While the `remap_key` is held down, the layer specified by `when_press` is active. - **`when_doublepress`**: While the `remap_key` is tap&pressed, the layer specified by `when_doublepress` is active. + It is possible to use a non-modifier key as a dual-role key to enable a layer. Here’s a configuration example: + + ``` + remap_key=TAB + when_alone=TAB + with_other= + when_press=layer_tab + ``` + + Explanation: + + - **`with_other=`**: This setting allows the TAB key to function as a dual-role key, where the tap action is registered as TAB and the hold action is set to nothing. + - **`when_press=layer_tab`**: When the TAB key is pressed, it activates the `layer_tab` without registering the TAB key itself if it is held beyond the `tap_timeout`. + To enable a layer with multiple key presses it is possibile to use `define_layer` as in the following configuration example: ``` define_layer=layer_vi + or_layer=layer_tab and_layer=layer_ctrl and_layer=layer_win and_not_layer=layer_shift @@ -129,10 +144,19 @@ Layers can be activated momentarily or permanently: Explanation: - **`define_layer=layer_vi`**: This line specifies that you are defining the `layer_vi`. This is the primary layer that will be activated when the conditions are met. - - **`and_layer=layer_ctrl`**: This indicates that the `layer_ctrl` must also be active for `layer_vi` to be enabled. This allows you to combine multiple layers for more complex key remapping. - - **`and_layer=layer_win`**: Similarly, this specifies that `layer_win` must also be active to enable `layer_vi`. This means that all specified layers must be active simultaneously for the remappings of `layer_vi` to take effect. + - **`or_layer=layer_tab`**: This indicates that if the `layer_tab` is active, then the `layer_vi` is also active. + - **`and_layer=layer_ctrl`**: This indicates that the `layer_ctrl` must also be active for `layer_vi` to be enabled if `layer_tab` is not active. This allows you to combine multiple layers for more complex key remapping. + - **`and_layer=layer_win`**: Similarly, this specifies that `layer_win` must also be active to enable `layer_vi`. This means that all specified layers by `and_layer=` must be active simultaneously for the remappings of `layer_vi` to take effect. - **`and_not_layer=layer_shift`**: This setting specifies that `layer_shift` must **not** be active to enable `layer_vi`. + The logic to enable a layer can be expressed as follows: + + `or_layer` OR `or_layer` OR ... OR (`and_layer` AND `and_layer` AND NOT `and_not_layer` AND ...) + + This means that `layer_vi` will be active if either `layer_tab` is active, or both `layer_ctrl` and `layer_win` are active while `layer_shift` is not. + + If a layer is defined with `define_layer` and activated by `when_press` or `when_doublepress`, an implicit `or_layer` is created. + 2. **Permanent Activation (Lock System)** A layer can also be activated permanently using a lock mechanism. This means that once the layer is activated, all remappings associated with it remain in effect until the layer is explicitly deactivated. @@ -226,3 +250,18 @@ The key press sequence follows the order of the `when_alone` lines. Whereas the It is possible to map multiple keys for `when_alone`, `with_other`, `when_doublepress`, `when_tap_lock`, and `when_double_tap_lock`. +### Key list + +- CTRL LEFT_CTRL RIGHT_CTRL SHIFT LEFT_SHIFT RIGHT_SHIFT ALT LEFT_ALT RIGHT_ALT LEFT_WIN RIGHT_WIN +- BACKSPACE CAPSLOCK ENTER ESCAPE SPACE TAB PLUS COMMA MINUS PERIOD +- UP LEFT RIGHT DOWN +- F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 +- KEY_0 KEY_1 KEY_2 KEY_3 KEY_4 KEY_5 KEY_6 KEY_7 KEY_8 KEY_9 +- KEY_A KEY_B KEY_C KEY_D KEY_E KEY_F KEY_G KEY_H KEY_I KEY_J KEY_K KEY_L KEY_M KEY_N KEY_O KEY_P KEY_Q KEY_R KEY_S KEY_T KEY_U KEY_V KEY_W KEY_X KEY_Y KEY_Z +- INSERT DELETE HOME END PAGE_UP PAGE_DOWN PRINT_SCREEN NUMLOCK SCROLLLOCK PAUSE US_SEMI US_SLASH US_TILDE +- MOUSE_UP MOUSE_DOWN MOUSE_LEFT MOUSE_RIGHT +- MOUSE_FORWARD MOUSE_BACKWARD MOUSE_STEER_LEFT MOUSE_STEER_RIGHT +- MOUSE_WHEEL_UP MOUSE_WHEEL_DOWN MOUSE_WHEEL_LEFT MOUSE_WHEEL_RIGHT +- MOUSE_LBUTTON MOUSE_RBUTTON MOUSE_MBUTTON MOUSE_XBUTTON1 MOUSE_XBUTTON2 +- MOUSE_SBUTTON MOUSE_SHOLD MOUSE_SRELEASE MOUSE_LBUTTON_SEL MOUSE_RBUTTON_SEL MOUSE_MBUTTON_SEL MOUSE_XBUTTON1_SEL MOUSE_XBUTTON2_SEL + diff --git a/config.example.txt b/config.example.txt old mode 100644 new mode 100755 index f19eb57..5cb1491 --- a/config.example.txt +++ b/config.example.txt @@ -20,6 +20,11 @@ remap_key=LEFT_WIN with_other=LEFT_WIN when_press=layer_win +remap_key=TAB +when_alone=TAB +with_other= +when_press=layer_tab + # hyper key with simple remapping remap_key=RIGHT_ALT when_alone=CTRL @@ -58,6 +63,7 @@ when_doublepress=layer_mouse # layer definition define_layer=layer_vi +or_layer=layer_tab and_layer=layer_ctrl_win and_not_layer=layer_alt and_not_layer=layer_shift diff --git a/keyboard_remapper.c b/keyboard_remapper.c index 4dbefe6..9c972b1 100644 --- a/keyboard_remapper.c +++ b/keyboard_remapper.c @@ -1,4 +1,4 @@ -#define VERSION "1.0" +#define VERSION "1.1.0" #include #include diff --git a/remap.c b/remap.c index 7c543d7..3d35de3 100644 --- a/remap.c +++ b/remap.c @@ -35,51 +35,14 @@ struct Layer { char * name; int state; int lock, prev_lock; + struct LayerNode * or_master_layers; struct LayerNode * and_master_layers; struct LayerNode * and_not_master_layers; - struct LayerNode * and_slave_layers; + struct LayerNode * slave_layers; struct Layer * next; }; -void toggle_layer_lock(struct Layer * layer) { - layer->prev_lock = layer->lock; - layer->lock = 1 - layer->lock; -} - -void set_layer_lock(struct Layer * layer) { - layer->prev_lock = layer->lock; - layer->lock = 1; -} - -void reset_layer_lock(struct Layer * layer) { - layer->prev_lock = layer->lock; - layer->lock = 0; -} - -int check_layer_states(struct LayerNode * layer_list, int expected_state) { - while (layer_list) { - if (layer_list->layer->state != expected_state) { - return 0; - } - layer_list = layer_list->next; - } - return 1; -} - -void set_layer_state(struct Layer * layer, int state) { - //if (!layer) return; - layer->state = state; - struct LayerNode * slave_iter = layer->and_slave_layers; - while (slave_iter) { - struct Layer * slave_layer = slave_iter->layer; - int all_master_active = check_layer_states(slave_layer->and_master_layers, 1) && - check_layer_states(slave_layer->and_not_master_layers, 0); - set_layer_state(slave_layer, all_master_active ? 1 : slave_layer->lock); - slave_iter = slave_iter->next; - } -} - struct LayerConf { struct Layer * layer; void (*conf)(struct Layer * layer); @@ -100,11 +63,14 @@ struct Remap { struct KeyDefNode * to_when_doublepress; struct KeyDefNode * to_when_tap_lock; struct KeyDefNode * to_when_double_tap_lock; + int to_with_other_dummy; int to_when_alone_modifiers; int to_with_other_modifiers; int to_when_doublepress_modifiers; int to_when_tap_lock_modifiers; int to_when_double_tap_lock_modifiers; + int to_when_alone_is_modifier_only; + int to_when_doublepress_is_modifier_only; int tap_lock; int double_tap_lock; @@ -194,6 +160,77 @@ void log_send_input(char * remap_name, KEY_DEF * key, enum Direction direction) // Remapping // ------------------------------------- +void toggle_layer_lock(struct Layer * layer) { + layer->prev_lock = layer->lock; + layer->lock = 1 - layer->lock; +} + +void set_layer_lock(struct Layer * layer) { + layer->prev_lock = layer->lock; + layer->lock = 1; +} + +void reset_layer_lock(struct Layer * layer) { + layer->prev_lock = layer->lock; + layer->lock = 0; +} + +int check_layer_state(struct Layer * layer) { + int state = layer->state; + if (state) { + struct Remap * remap_iter = g_remap_list; + while (remap_iter) { + if ((remap_iter->to_when_press_layer == layer && + (remap_iter->state == HELD_DOWN_ALONE || + remap_iter->state == HELD_DOWN_WITH_OTHER || + remap_iter->state == TAP)) || + (remap_iter->to_when_doublepress_layer == layer && + remap_iter->state == DOUBLE_TAP)) { + return 1; + } + remap_iter = remap_iter->next; + } + } + struct LayerNode * layer_node_iter = layer->or_master_layers; + if (layer_node_iter) { + while (layer_node_iter) { + if (check_layer_state(layer_node_iter->layer) != 0) { + return 1; + } + layer_node_iter = layer_node_iter->next; + } + state = 0; + } + layer_node_iter = layer->and_master_layers; + if (layer_node_iter) { + while (layer_node_iter) { + if (check_layer_state(layer_node_iter->layer) == 0) { + return 0; + } + layer_node_iter = layer_node_iter->next; + } + state = 1; + } + layer_node_iter = layer->and_not_master_layers; + while (layer_node_iter) { + if (check_layer_state(layer_node_iter->layer) != 0) { + return 0; + } + layer_node_iter = layer_node_iter->next; + } + return state; +} + +void set_layer_state(struct Layer * layer, int state) { + //if (!layer) return; + layer->state = state; + struct LayerNode * slave_iter = layer->slave_layers; + while (slave_iter) { + set_layer_state(slave_iter->layer, check_layer_state(slave_iter->layer) ? 1 : slave_iter->layer->lock); + slave_iter = slave_iter->next; + } +} + struct KeyDefNode * new_key_node(KEY_DEF * key_def) { struct KeyDefNode * key_node = malloc(sizeof(struct KeyDefNode)); key_node->key_def = key_def; @@ -215,9 +252,10 @@ struct Layer * new_layer(char * name) { layer->state = 0; layer->lock = 0; layer->prev_lock = 0; + layer->or_master_layers = NULL; layer->and_master_layers = NULL; layer->and_not_master_layers = NULL; - layer->and_slave_layers = NULL; + layer->slave_layers = NULL; layer->next = NULL; return layer; } @@ -250,11 +288,14 @@ struct Remap * new_remap(KEY_DEF * from, remap->to_when_doublepress = to_when_doublepress; remap->to_when_tap_lock = to_when_tap_lock; remap->to_when_double_tap_lock = to_when_double_tap_lock; + remap->to_with_other_dummy = 0; remap->to_when_alone_modifiers = 0; remap->to_with_other_modifiers = 0; remap->to_when_doublepress_modifiers = 0; remap->to_when_tap_lock_modifiers = 0; remap->to_when_double_tap_lock_modifiers = 0; + remap->to_when_alone_is_modifier_only = 0; + remap->to_when_doublepress_is_modifier_only = 0; remap->tap_lock = 0; remap->double_tap_lock = 0; remap->state = IDLE; @@ -283,17 +324,33 @@ void append_layer_node(struct LayerNode ** list, struct LayerNode * elem) { *list = elem; } +int check_layer_states(struct LayerNode * layer_list, int expected_state) { + while (layer_list) { + if (layer_list->layer->state != expected_state) { + return 0; + } + layer_list = layer_list->next; + } + return 1; +} + int is_master_layer(struct Layer * master_layer, struct Layer * slave_layer) { - struct LayerNode * master_iter = slave_layer->and_master_layers; + struct LayerNode * master_iter = slave_layer->or_master_layers; while (master_iter) { if (master_iter->layer == master_layer || is_master_layer(master_layer, master_iter->layer)) { - if (check_layer_states(slave_layer->and_master_layers, 1) && - check_layer_states(slave_layer->and_not_master_layers, 0)) { + return master_iter->layer->state; + } + master_iter = master_iter->next; + } + if (check_layer_states(slave_layer->and_master_layers, 1) && + check_layer_states(slave_layer->and_not_master_layers, 0)) { + master_iter = slave_layer->and_master_layers; + while (master_iter) { + if (master_iter->layer == master_layer || is_master_layer(master_layer, master_iter->layer)) { return 1; } - return 0; + master_iter = master_iter->next; } - master_iter = master_iter->next; } return 0; } @@ -325,6 +382,17 @@ int modifiers(struct KeyDefNode * head) { return modifiers; } +int is_modifier_only(struct KeyDefNode * head) +{ + struct KeyDefNode * cur = head; + int modifier_only = 1; + do { + modifier_only *= cur->key_def->modifier; + cur = cur->next; + } while(cur != head); + return modifier_only ? 1 : 0; +} + void free_key_nodes(struct KeyDefNode * head) { if (head) { head->previous->next = NULL; @@ -352,9 +420,10 @@ void free_layers(struct Layer * head) { struct Layer * layer = cur; cur = cur->next; free(layer->name); + free_layer_nodes(layer->or_master_layers); free_layer_nodes(layer->and_master_layers); free_layer_nodes(layer->and_not_master_layers); - free_layer_nodes(layer->and_slave_layers); + free_layer_nodes(layer->slave_layers); free(layer); } } @@ -446,10 +515,11 @@ int register_remap(struct Remap * remap) { } if (remap->to_when_alone) { remap->to_when_alone_modifiers = modifiers(remap->to_when_alone); + remap->to_when_alone_is_modifier_only = is_modifier_only(remap->to_when_alone); } if (remap->to_with_other) { remap->to_with_other_modifiers = modifiers(remap->to_with_other); - if (!remap->to_with_other_modifiers) { + if (!is_modifier_only(remap->to_with_other)) { free_key_nodes(remap->to_with_other); remap->to_with_other = NULL; remap->to_with_other_modifiers = 0; @@ -457,6 +527,7 @@ int register_remap(struct Remap * remap) { } if (remap->to_when_doublepress) { remap->to_when_doublepress_modifiers = modifiers(remap->to_when_doublepress); + remap->to_when_doublepress_is_modifier_only = is_modifier_only(remap->to_when_doublepress); } if (remap->to_when_tap_lock) { remap->to_when_tap_lock_modifiers = modifiers(remap->to_when_tap_lock); @@ -583,7 +654,7 @@ void unlock_all(struct InputBuffer * input_buffer) { /* @return block_input */ int event_remapped_key_down(struct Remap * remap, DWORD time, struct InputBuffer * input_buffer) { if (remap->state == IDLE) { - if (remap->to_with_other) { + if (remap->to_with_other || remap->to_with_other_dummy) { remap->time = time; remap->state = HELD_DOWN_ALONE; } else { @@ -635,7 +706,7 @@ int event_remapped_key_down(struct Remap * remap, DWORD time, struct InputBuffer remap->active_modifiers = remap->to_when_alone_modifiers; } } else { - if (remap->to_with_other) { + if (remap->to_with_other || remap->to_with_other_dummy) { remap->time = time; remap->state = HELD_DOWN_ALONE; } else { @@ -805,7 +876,7 @@ int event_other_input(int virt_code, enum Direction direction, DWORD time, int r } } } else if (remap->state == TAP) { - if (remap->to_when_alone && remap->to_when_alone_modifiers) { + if (remap->to_when_alone && remap->to_when_alone_is_modifier_only) { if (!has_to_block_modifiers(g_remap_by_id[remap_id], remap->to_when_press_layer)) { block_input |= send_key_def_input_down("when_alone", remap->to_when_alone, remap->id, 0, input_buffer); } else { @@ -813,7 +884,7 @@ int event_other_input(int virt_code, enum Direction direction, DWORD time, int r } } } else if (remap->state == DOUBLE_TAP) { - if (remap->to_when_doublepress && remap->to_when_doublepress_modifiers) { + if (remap->to_when_doublepress && remap->to_when_doublepress_is_modifier_only) { if (!has_to_block_modifiers(g_remap_by_id[remap_id], remap->to_when_doublepress_layer)) { block_input |= send_key_def_input_down("when_doublepress", remap->to_when_doublepress, remap->id, 0, input_buffer); } else { @@ -1000,12 +1071,12 @@ int load_config_line(char * line, int linenum) { } char * key_name = after_eq + 1; KEY_DEF * key_def = find_key_def_by_name(key_name); - if (!key_def && strncmp(key_name, "layer", strlen("layer")) && + if (!key_def && strlen(key_name) != 0 && + strncmp(key_name, "layer", strlen("layer")) && strncmp(key_name, "toggle_layer", strlen("toggle_layer")) && strncmp(key_name, "set_layer", strlen("set_layer")) && strncmp(key_name, "reset_layer", strlen("reset_layer"))) { printf("Config error (line %d): Invalid key name '%s'.\n", linenum, key_name); - printf("Key names were changed in the most recent version. Please review review the wiki for the new names!\n"); return 1; } @@ -1050,11 +1121,13 @@ int load_config_line(char * line, int linenum) { append_key_node(g_remap_parsee->to_when_alone, key_def); } } else if (strncmp(line, "with_other=", strlen("with_other=")) == 0) { - if (!key_def) { + if (!key_def && strlen(key_name) != 0) { printf("Config error (line %d): Invalid key name '%s'.\n", linenum, key_name); return 1; } - if (g_remap_parsee->to_with_other == NULL) { + if (strlen(key_name) == 0) { + g_remap_parsee->to_with_other_dummy = 1; + } else if (g_remap_parsee->to_with_other == NULL) { g_remap_parsee->to_with_other = new_key_node(key_def); } else { append_key_node(g_remap_parsee->to_with_other, key_def); @@ -1156,6 +1229,25 @@ int load_config_line(char * line, int linenum) { printf("Config error (line %d): Invalid key name '%s'.\n", linenum, key_name); return 1; } + } else if (strncmp(line, "or_layer=", strlen("or_layer=")) == 0) { + if (strncmp(key_name, "layer", strlen("layer")) == 0) { + if (g_layer_parsee == NULL) { + printf("Config error (line %d): Incomplete layer definition.\n" + "Each layer definition must start with a 'define_layer'.\n", + linenum); + return 1; + } else { + struct Layer * master_layer = find_layer(g_layer_list, key_name); + if (master_layer == NULL) { + master_layer = append_layer(&g_layer_list, new_layer(key_name)); + } + append_layer_node(&g_layer_parsee->or_master_layers, new_layer_node(master_layer)); + append_layer_node(&master_layer->slave_layers, new_layer_node(g_layer_parsee)); + } + } else { + printf("Config error (line %d): Invalid key name '%s'.\n", linenum, key_name); + return 1; + } } else if (strncmp(line, "and_layer=", strlen("and_layer=")) == 0) { if (strncmp(key_name, "layer", strlen("layer")) == 0) { if (g_layer_parsee == NULL) { @@ -1169,7 +1261,7 @@ int load_config_line(char * line, int linenum) { master_layer = append_layer(&g_layer_list, new_layer(key_name)); } append_layer_node(&g_layer_parsee->and_master_layers, new_layer_node(master_layer)); - append_layer_node(&master_layer->and_slave_layers, new_layer_node(g_layer_parsee)); + append_layer_node(&master_layer->slave_layers, new_layer_node(g_layer_parsee)); } } else { printf("Config error (line %d): Invalid key name '%s'.\n", linenum, key_name); @@ -1188,7 +1280,7 @@ int load_config_line(char * line, int linenum) { master_layer = append_layer(&g_layer_list, new_layer(key_name)); } append_layer_node(&g_layer_parsee->and_not_master_layers, new_layer_node(master_layer)); - append_layer_node(&master_layer->and_slave_layers, new_layer_node(g_layer_parsee)); + append_layer_node(&master_layer->slave_layers, new_layer_node(g_layer_parsee)); } } else { printf("Config error (line %d): Invalid key name '%s'.\n", linenum, key_name);