From 572fe6ae27e7e86c2fb3f227c6ac6dacde452f97 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Tue, 7 Oct 2025 11:57:48 +0800 Subject: [PATCH] feat: support keybind mode --- protocols/dwl-ipc-unstable-v2.xml | 7 +++++++ src/config/parse_config.h | 28 +++++++++++++++++++++++++++- src/dispatch/bind_declare.h | 1 + src/dispatch/bind_define.h | 11 +++++++++++ src/ext-protocol/dwl-ipc.h | 5 +++++ src/mango.c | 15 +++++++++++++-- 6 files changed, 64 insertions(+), 3 deletions(-) diff --git a/protocols/dwl-ipc-unstable-v2.xml b/protocols/dwl-ipc-unstable-v2.xml index 501a7c4..a43a7f0 100644 --- a/protocols/dwl-ipc-unstable-v2.xml +++ b/protocols/dwl-ipc-unstable-v2.xml @@ -234,6 +234,13 @@ I would probably just submit raphi's patchset but I don't think that would be po + + + current keybind mode. + + + + diff --git a/src/config/parse_config.h b/src/config/parse_config.h index 7f10b4c..0dc0388 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -31,6 +31,9 @@ typedef struct { KeySymCode keysymcode; void (*func)(const Arg *); Arg arg; + char mode[28]; + bool iscommonmode; + bool isdefaultmode; } KeyBinding; typedef struct { @@ -318,6 +321,9 @@ typedef struct { int adaptive_sync; struct xkb_rule_names xkb_rules; + + char keymode[28]; + } Config; typedef void (*FuncType)(const Arg *); @@ -763,6 +769,9 @@ FuncType parse_func_name(char *func_name, Arg *arg, char *arg_value, func = focuslast; } else if (strcmp(func_name, "toggle_trackpad_enable") == 0) { func = toggle_trackpad_enable; + } else if (strcmp(func_name, "setkeymode") == 0) { + func = setkeymode; + (*arg).v = strdup(arg_value); } else if (strcmp(func_name, "setlayout") == 0) { func = setlayout; (*arg).v = strdup(arg_value); @@ -921,7 +930,9 @@ void parse_config_line(Config *config, const char *line) { trim_whitespace(key); trim_whitespace(value); - if (strcmp(key, "animations") == 0) { + if (strcmp(key, "keymode") == 0) { + snprintf(config->keymode, sizeof(config->keymode), "%.27s", value); + } else if (strcmp(key, "animations") == 0) { config->animations = atoi(value); } else if (strcmp(key, "layer_animations") == 0) { config->layer_animations = atoi(value); @@ -1776,6 +1787,18 @@ void parse_config_line(Config *config, const char *line) { trim_whitespace(arg_value4); trim_whitespace(arg_value5); + strcpy(binding->mode, config->keymode); + if (strcmp(binding->mode, "common") == 0) { + binding->iscommonmode = true; + binding->isdefaultmode = false; + } else if (strcmp(binding->mode, "default") == 0) { + binding->isdefaultmode = true; + binding->iscommonmode = false; + } else { + binding->isdefaultmode = false; + binding->iscommonmode = false; + } + binding->mod = parse_mod(mod_str); binding->keysymcode = parse_key(keysym_str); binding->arg.v = NULL; @@ -2692,6 +2715,8 @@ void set_default_key_bindings(Config *config) { for (size_t i = 0; i < default_key_bindings_count; i++) { config->key_bindings[config->key_bindings_count + i] = default_key_bindings[i]; + config->key_bindings[config->key_bindings_count + i].iscommonmode = + true; } // 更新按键绑定的总数 @@ -2735,6 +2760,7 @@ void parse_config(void) { config.tag_rules = NULL; config.tag_rules_count = 0; config.cursor_theme = NULL; + strcpy(config.keymode, "default"); // 获取 MANGOCONFIG 环境变量 const char *mangoconfig = getenv("MANGOCONFIG"); diff --git a/src/dispatch/bind_declare.h b/src/dispatch/bind_declare.h index fd23bec..2f553d2 100644 --- a/src/dispatch/bind_declare.h +++ b/src/dispatch/bind_declare.h @@ -22,6 +22,7 @@ void tagmon(const Arg *arg); void spawn(const Arg *arg); void spawn_shell(const Arg *arg); void spawn_on_empty(const Arg *arg); +void setkeymode(const Arg *arg); void setlayout(const Arg *arg); void switch_layout(const Arg *arg); void switch_keyboard_layout(const Arg *arg); diff --git a/src/dispatch/bind_define.h b/src/dispatch/bind_define.h index e1ebbaf..3184975 100644 --- a/src/dispatch/bind_define.h +++ b/src/dispatch/bind_define.h @@ -457,6 +457,17 @@ setlayout(const Arg *arg) { } } +void // 17 +setkeymode(const Arg *arg) { + snprintf(keymode.mode, sizeof(keymode.mode), "%.27s", arg->v); + if (strcmp(keymode.mode, "default") == 0) { + keymode.isdefault = true; + } else { + keymode.isdefault = false; + } + printstatus(); +} + void set_proportion(const Arg *arg) { if (selmon->sel) { unsigned int max_client_width = diff --git a/src/ext-protocol/dwl-ipc.h b/src/ext-protocol/dwl-ipc.h index 9ca3ae9..589d42d 100644 --- a/src/ext-protocol/dwl-ipc.h +++ b/src/ext-protocol/dwl-ipc.h @@ -199,6 +199,11 @@ void dwl_ipc_output_printstatus_to(DwlIpcOutput *ipc_output) { zdwl_ipc_output_v2_send_kb_layout(ipc_output->resource, kb_layout); } + if (wl_resource_get_version(ipc_output->resource) >= + ZDWL_IPC_OUTPUT_V2_KEYMODE_SINCE_VERSION) { + zdwl_ipc_output_v2_send_keymode(ipc_output->resource, keymode.mode); + } + zdwl_ipc_output_v2_send_frame(ipc_output->resource); } diff --git a/src/mango.c b/src/mango.c index 8c294fb..17c20a7 100644 --- a/src/mango.c +++ b/src/mango.c @@ -195,6 +195,11 @@ typedef struct { const Arg arg; } Button; // 鼠标按键 +typedef struct { + char mode[28]; + bool isdefault; +} KeyMode; + typedef struct { unsigned int mod; unsigned int dir; @@ -786,7 +791,10 @@ struct dvec2 *baked_points_close; static struct wl_event_source *hide_source; static bool cursor_hidden = false; static bool tag_combo = false; - +static KeyMode keymode = { + .mode = {'d', 'e', 'f', 'a', 'u', 'l', 't', '\0'}, + .isdefault = true, +}; static struct { enum wp_cursor_shape_device_v1_shape shape; struct wlr_surface *surface; @@ -3265,7 +3273,9 @@ keybinding(unsigned int mods, xkb_keysym_t sym, unsigned int keycode) { if (config.key_bindings_count < 1) break; k = &config.key_bindings[ji]; - if (CLEANMASK(mods) == CLEANMASK(k->mod) && + if ((k->iscommonmode || (k->isdefaultmode && keymode.isdefault) || + (strcmp(keymode.mode, k->mode) == 0)) && + CLEANMASK(mods) == CLEANMASK(k->mod) && ((k->keysymcode.type == KEY_TYPE_SYM && normalize_keysym(sym) == normalize_keysym(k->keysymcode.keysym)) || @@ -3274,6 +3284,7 @@ keybinding(unsigned int mods, xkb_keysym_t sym, unsigned int keycode) { k->func) { k->func(&k->arg); handled = 1; + break; } } return handled;