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;