From 539fd233da13b779f8624d7da74a33eb3686b56a Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Thu, 6 Nov 2025 09:14:48 +0800 Subject: [PATCH] break change: support bind flag --- src/config/parse_config.h | 39 +++++++++++++++++++++++++++++++++++---- src/mango.c | 35 +++++++++++++++++++++++++++-------- 2 files changed, 62 insertions(+), 12 deletions(-) diff --git a/src/config/parse_config.h b/src/config/parse_config.h index 7e1be63..36aa1db 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -40,6 +40,8 @@ typedef struct { char mode[28]; bool iscommonmode; bool isdefaultmode; + bool islockapply; + bool isreleaseapply; } KeyBinding; typedef struct { @@ -410,6 +412,35 @@ char *sanitize_string(char *str) { return str; } +// 解析bind组合字符串 +void parse_bind_flags(const char *str, KeyBinding *kb) { + + // 检查是否以"bind"开头 + if (strncmp(str, "bind", 4) != 0) { + return; + } + + const char *suffix = str + 4; // 跳过"bind" + + // 遍历后缀字符 + for (int i = 0; suffix[i] != '\0'; i++) { + switch (suffix[i]) { + case 's': + kb->keysymcode.type = KEY_TYPE_SYM; + break; + case 'l': + kb->islockapply = true; + break; + case 'r': + kb->isreleaseapply = true; + break; + default: + // 忽略其他字符或可根据需要处理错误 + break; + } + } +} + int parse_circle_direction(const char *str) { // 将输入字符串转换为小写 char lowerStr[10]; @@ -1928,8 +1959,7 @@ void parse_option(Config *config, char *key, char *value) { config->exec_once_count++; - } else if (strncmp(key, "bind", 4) == 0 || - strncmp(key, "bindsym", 7) == 0) { + } else if (regex_match("^bind[s|l|r]*$", key)) { config->key_bindings = realloc(config->key_bindings, (config->key_bindings_count + 1) * sizeof(KeyBinding)); @@ -1975,9 +2005,9 @@ void parse_option(Config *config, char *key, char *value) { binding->iscommonmode = false; } + parse_bind_flags(key, binding); + binding->keysymcode = parse_key(keysym_str, binding->keysymcode.type); binding->mod = parse_mod(mod_str); - binding->keysymcode = - parse_key(keysym_str, strncmp(key, "bindsym", 7) == 0); binding->arg.v = NULL; binding->arg.v2 = NULL; binding->arg.v3 = NULL; @@ -2930,6 +2960,7 @@ void set_default_key_bindings(Config *config) { default_key_bindings[i]; config->key_bindings[config->key_bindings_count + i].iscommonmode = true; + config->key_bindings[config->key_bindings_count + i].islockapply = true; } // 更新按键绑定的总数 diff --git a/src/mango.c b/src/mango.c index f580d55..7ce5831 100644 --- a/src/mango.c +++ b/src/mango.c @@ -558,8 +558,8 @@ static void gpureset(struct wl_listener *listener, void *data); static int keyrepeat(void *data); static void inputdevice(struct wl_listener *listener, void *data); -static int keybinding(unsigned int mods, xkb_keysym_t sym, - unsigned int keycode); +static int keybinding(unsigned int state, bool locked, unsigned int mods, + xkb_keysym_t sym, unsigned int keycode); static void keypress(struct wl_listener *listener, void *data); static void keypressmod(struct wl_listener *listener, void *data); static bool keypressglobal(struct wlr_surface *last_surface, @@ -3241,13 +3241,15 @@ int keyrepeat(void *data) { 1000 / group->wlr_group->keyboard.repeat_info.rate); for (i = 0; i < group->nsyms; i++) - keybinding(group->mods, group->keysyms[i], group->keycode); + keybinding(WL_KEYBOARD_KEY_STATE_PRESSED, false, group->mods, + group->keysyms[i], group->keycode); return 0; } int // 17 -keybinding(unsigned int mods, xkb_keysym_t sym, unsigned int keycode) { +keybinding(unsigned int state, bool locked, unsigned int mods, xkb_keysym_t sym, + unsigned int keycode) { /* * Here we handle compositor keybindings. This is when the compositor is * processing keys, rather than passing them on to the client for its @@ -3266,6 +3268,22 @@ keybinding(unsigned int mods, xkb_keysym_t sym, unsigned int keycode) { for (ji = 0; ji < config.key_bindings_count; ji++) { if (config.key_bindings_count < 1) break; + + if (locked && config.key_bindings[ji].islockapply == false) + continue; + + if (state == WL_KEYBOARD_KEY_STATE_RELEASED && + config.key_bindings[ji].isreleaseapply == false) + continue; + + if (state == WL_KEYBOARD_KEY_STATE_PRESSED && + config.key_bindings[ji].isreleaseapply == true) + continue; + + if (state != WL_KEYBOARD_KEY_STATE_PRESSED && + state != WL_KEYBOARD_KEY_STATE_RELEASED) + continue; + k = &config.key_bindings[ji]; if ((k->iscommonmode || (k->isdefaultmode && keymode.isdefault) || (strcmp(keymode.mode, k->mode) == 0)) && @@ -3394,10 +3412,11 @@ void keypress(struct wl_listener *listener, void *data) { /* On _press_ if there is no active screen locker, * attempt to process a compositor keybinding. */ - if (!locked && event->state == WL_KEYBOARD_KEY_STATE_PRESSED) { - for (i = 0; i < nsyms; i++) - handled = keybinding(mods, syms[i], keycode) || handled; - } else if (event->state == WL_KEYBOARD_KEY_STATE_RELEASED) { + for (i = 0; i < nsyms; i++) + handled = + keybinding(event->state, locked, mods, syms[i], keycode) || handled; + + if (event->state == WL_KEYBOARD_KEY_STATE_RELEASED) { tag_combo = false; }