diff --git a/src/config/parse_config.h b/src/config/parse_config.h index 5815f0b..ca1e164 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -18,9 +18,17 @@ enum { NUM_TYPE_MINUS, NUM_TYPE_PLUS, NUM_TYPE_DEFAULT }; +enum { KEY_TYPE_SYM, KEY_TYPE_CODE }; + +typedef struct { + xkb_keysym_t keysym; + uint32_t keycode; + int type; +} KeySymCode; + typedef struct { uint32_t mod; - xkb_keysym_t keysym; + KeySymCode keysymcode; void (*func)(const Arg *); Arg arg; } KeyBinding; @@ -69,16 +77,17 @@ typedef struct { int noswallow; } ConfigMonitorRule; -// 定义一个宏来简化默认按键绑定的添加 +// 修改后的宏定义 #define CHVT(n) \ { \ - WLR_MODIFIER_CTRL | WLR_MODIFIER_ALT, XKB_KEY_XF86Switch_VT_##n, chvt, \ + WLR_MODIFIER_CTRL | WLR_MODIFIER_ALT, \ + {.keysym = XKB_KEY_XF86Switch_VT_##n, .type = KEY_TYPE_SYM}, chvt, \ { \ .ui = (n) \ } \ } -// 默认的按键绑定数组 +// 默认按键绑定数组 KeyBinding default_key_bindings[] = {CHVT(1), CHVT(2), CHVT(3), CHVT(4), CHVT(5), CHVT(6), CHVT(7), CHVT(8), CHVT(9), CHVT(10), CHVT(11), CHVT(12)}; @@ -502,8 +511,24 @@ uint32_t parse_mod(const char *mod_str) { return mod; } -xkb_keysym_t parse_keysym(const char *keysym_str) { - return xkb_keysym_from_name(keysym_str, XKB_KEYSYM_NO_FLAGS); +KeySymCode parse_key(const char *key_str) { + KeySymCode kc; + + // 处理 code: 前缀的情况 + if (strncmp(key_str, "code:", 5) == 0) { + char *endptr; + xkb_keycode_t keycode = (xkb_keycode_t)strtol(key_str + 5, &endptr, 10); + kc.type = KEY_TYPE_CODE; + kc.keycode = keycode; + return kc; + } + + // 普通键名直接转换 + xkb_keysym_t sym = xkb_keysym_from_name(key_str, XKB_KEYSYM_NO_FLAGS); + kc.type = KEY_TYPE_SYM; + kc.keycode = 0; + kc.keysym = sym; + return kc; } int parse_button(const char *str) { @@ -1260,7 +1285,7 @@ void parse_config_line(Config *config, const char *line) { trim_whitespace(mod_str); trim_whitespace(keysym_str); rule->globalkeybinding.mod = parse_mod(mod_str); - rule->globalkeybinding.keysym = parse_keysym(keysym_str); + rule->globalkeybinding.keysymcode = parse_key(keysym_str); } } token = strtok(NULL, ","); @@ -1406,7 +1431,7 @@ void parse_config_line(Config *config, const char *line) { trim_whitespace(arg_value5); binding->mod = parse_mod(mod_str); - binding->keysym = parse_keysym(keysym_str); + binding->keysymcode = parse_key(keysym_str); binding->arg.v = NULL; binding->arg.v2 = NULL; binding->arg.v3 = NULL; diff --git a/src/maomao.c b/src/maomao.c index 4faaf24..a204495 100644 --- a/src/maomao.c +++ b/src/maomao.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -306,6 +307,7 @@ typedef struct { int nsyms; const xkb_keysym_t *keysyms; /* invalid if nsyms == 0 */ uint32_t mods; /* invalid if nsyms == 0 */ + uint32_t keycode; struct wl_event_source *key_repeat_source; struct wl_listener modifiers; @@ -525,13 +527,13 @@ 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(uint32_t mods, xkb_keysym_t sym); +static int keybinding(uint32_t mods, xkb_keysym_t sym, uint32_t 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, struct wlr_keyboard *keyboard, struct wlr_keyboard_key_event *event, uint32_t mods, - xkb_keysym_t keysym); + xkb_keysym_t keysym, uint32_t keycode); static void locksession(struct wl_listener *listener, void *data); static void mapnotify(struct wl_listener *listener, void *data); static void maximizenotify(struct wl_listener *listener, void *data); @@ -4188,13 +4190,13 @@ 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]); + keybinding(group->mods, group->keysyms[i], group->keycode); return 0; } int // 17 -keybinding(uint32_t mods, xkb_keysym_t sym) { +keybinding(uint32_t mods, xkb_keysym_t sym, uint32_t keycode) { /* * Here we handle compositor keybindings. This is when the compositor is * processing keys, rather than passing them on to the client for its own @@ -4208,7 +4210,12 @@ keybinding(uint32_t mods, xkb_keysym_t sym) { break; k = &config.key_bindings[ji]; if (CLEANMASK(mods) == CLEANMASK(k->mod) && - normalize_keysym(sym) == normalize_keysym(k->keysym) && k->func) { + ((k->keysymcode.type == KEY_TYPE_SYM && + normalize_keysym(sym) == + normalize_keysym(k->keysymcode.keysym)) || + (k->keysymcode.type == KEY_TYPE_CODE && + keycode == k->keysymcode.keycode)) && + k->func) { k->func(&k->arg); handled = 1; } @@ -4219,7 +4226,7 @@ keybinding(uint32_t mods, xkb_keysym_t sym) { bool keypressglobal(struct wlr_surface *last_surface, struct wlr_keyboard *keyboard, struct wlr_keyboard_key_event *event, uint32_t mods, - xkb_keysym_t keysym) { + xkb_keysym_t keysym, uint32_t keycode) { Client *c = NULL, *lastc = focustop(selmon); uint32_t keycodes[32] = {0}; int reset = false; @@ -4233,11 +4240,14 @@ bool keypressglobal(struct wlr_surface *last_surface, break; r = &config.window_rules[ji]; - if (!r->globalkeybinding.mod || !r->globalkeybinding.keysym) + if (!r->globalkeybinding.mod || (!r->globalkeybinding.keysymcode.keysym && !r->globalkeybinding.keysymcode.keycode)) continue; /* match key only (case insensitive) ignoring mods */ - if (r->globalkeybinding.keysym == keysym && + if (((r->globalkeybinding.keysymcode.type == KEY_TYPE_SYM && + r->globalkeybinding.keysymcode.keysym == keysym) || + (r->globalkeybinding.keysymcode.type == KEY_TYPE_CODE && + r->globalkeybinding.keysymcode.keycode == keycode)) && r->globalkeybinding.mod == mods) { wl_list_for_each(c, &clients, link) { if (c && c != lastc) { @@ -4314,12 +4324,13 @@ void keypress(struct wl_listener *listener, void *data) { * 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]) || handled; + handled = keybinding(mods, syms[i], keycode) || handled; } if (handled && group->wlr_group->keyboard.repeat_info.delay > 0) { group->mods = mods; group->keysyms = syms; + group->keycode = keycode; group->nsyms = nsyms; wl_event_source_timer_update( group->key_repeat_source, @@ -4344,7 +4355,7 @@ void keypress(struct wl_listener *listener, void *data) { /* passed keys don't get repeated */ if (pass && syms) hit_global = keypressglobal(last_surface, &group->wlr_group->keyboard, - event, mods, syms[0]); + event, mods, syms[0], keycode); if (hit_global) { return;