mirror of
https://github.com/DreamMaoMao/maomaowm.git
synced 2025-11-02 09:01:43 -05:00
feat: key parse support key code
This commit is contained in:
parent
76b7e16719
commit
860e1805d1
2 changed files with 54 additions and 18 deletions
|
|
@ -18,9 +18,17 @@
|
||||||
|
|
||||||
enum { NUM_TYPE_MINUS, NUM_TYPE_PLUS, NUM_TYPE_DEFAULT };
|
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 {
|
typedef struct {
|
||||||
uint32_t mod;
|
uint32_t mod;
|
||||||
xkb_keysym_t keysym;
|
KeySymCode keysymcode;
|
||||||
void (*func)(const Arg *);
|
void (*func)(const Arg *);
|
||||||
Arg arg;
|
Arg arg;
|
||||||
} KeyBinding;
|
} KeyBinding;
|
||||||
|
|
@ -69,16 +77,17 @@ typedef struct {
|
||||||
int noswallow;
|
int noswallow;
|
||||||
} ConfigMonitorRule;
|
} ConfigMonitorRule;
|
||||||
|
|
||||||
// 定义一个宏来简化默认按键绑定的添加
|
// 修改后的宏定义
|
||||||
#define CHVT(n) \
|
#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) \
|
.ui = (n) \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
// 默认的按键绑定数组
|
// 默认按键绑定数组
|
||||||
KeyBinding default_key_bindings[] = {CHVT(1), CHVT(2), CHVT(3), CHVT(4),
|
KeyBinding default_key_bindings[] = {CHVT(1), CHVT(2), CHVT(3), CHVT(4),
|
||||||
CHVT(5), CHVT(6), CHVT(7), CHVT(8),
|
CHVT(5), CHVT(6), CHVT(7), CHVT(8),
|
||||||
CHVT(9), CHVT(10), CHVT(11), CHVT(12)};
|
CHVT(9), CHVT(10), CHVT(11), CHVT(12)};
|
||||||
|
|
@ -502,8 +511,24 @@ uint32_t parse_mod(const char *mod_str) {
|
||||||
return mod;
|
return mod;
|
||||||
}
|
}
|
||||||
|
|
||||||
xkb_keysym_t parse_keysym(const char *keysym_str) {
|
KeySymCode parse_key(const char *key_str) {
|
||||||
return xkb_keysym_from_name(keysym_str, XKB_KEYSYM_NO_FLAGS);
|
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) {
|
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(mod_str);
|
||||||
trim_whitespace(keysym_str);
|
trim_whitespace(keysym_str);
|
||||||
rule->globalkeybinding.mod = parse_mod(mod_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, ",");
|
token = strtok(NULL, ",");
|
||||||
|
|
@ -1406,7 +1431,7 @@ void parse_config_line(Config *config, const char *line) {
|
||||||
trim_whitespace(arg_value5);
|
trim_whitespace(arg_value5);
|
||||||
|
|
||||||
binding->mod = parse_mod(mod_str);
|
binding->mod = parse_mod(mod_str);
|
||||||
binding->keysym = parse_keysym(keysym_str);
|
binding->keysymcode = parse_key(keysym_str);
|
||||||
binding->arg.v = NULL;
|
binding->arg.v = NULL;
|
||||||
binding->arg.v2 = NULL;
|
binding->arg.v2 = NULL;
|
||||||
binding->arg.v3 = NULL;
|
binding->arg.v3 = NULL;
|
||||||
|
|
|
||||||
31
src/maomao.c
31
src/maomao.c
|
|
@ -8,6 +8,7 @@
|
||||||
#include <linux/input-event-codes.h>
|
#include <linux/input-event-codes.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
|
@ -306,6 +307,7 @@ typedef struct {
|
||||||
int nsyms;
|
int nsyms;
|
||||||
const xkb_keysym_t *keysyms; /* invalid if nsyms == 0 */
|
const xkb_keysym_t *keysyms; /* invalid if nsyms == 0 */
|
||||||
uint32_t mods; /* invalid if nsyms == 0 */
|
uint32_t mods; /* invalid if nsyms == 0 */
|
||||||
|
uint32_t keycode;
|
||||||
struct wl_event_source *key_repeat_source;
|
struct wl_event_source *key_repeat_source;
|
||||||
|
|
||||||
struct wl_listener modifiers;
|
struct wl_listener modifiers;
|
||||||
|
|
@ -525,13 +527,13 @@ static void gpureset(struct wl_listener *listener, void *data);
|
||||||
static int keyrepeat(void *data);
|
static int keyrepeat(void *data);
|
||||||
|
|
||||||
static void inputdevice(struct wl_listener *listener, 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 keypress(struct wl_listener *listener, void *data);
|
||||||
static void keypressmod(struct wl_listener *listener, void *data);
|
static void keypressmod(struct wl_listener *listener, void *data);
|
||||||
static bool keypressglobal(struct wlr_surface *last_surface,
|
static bool keypressglobal(struct wlr_surface *last_surface,
|
||||||
struct wlr_keyboard *keyboard,
|
struct wlr_keyboard *keyboard,
|
||||||
struct wlr_keyboard_key_event *event, uint32_t mods,
|
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 locksession(struct wl_listener *listener, void *data);
|
||||||
static void mapnotify(struct wl_listener *listener, void *data);
|
static void mapnotify(struct wl_listener *listener, void *data);
|
||||||
static void maximizenotify(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);
|
1000 / group->wlr_group->keyboard.repeat_info.rate);
|
||||||
|
|
||||||
for (i = 0; i < group->nsyms; i++)
|
for (i = 0; i < group->nsyms; i++)
|
||||||
keybinding(group->mods, group->keysyms[i]);
|
keybinding(group->mods, group->keysyms[i], group->keycode);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int // 17
|
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
|
* Here we handle compositor keybindings. This is when the compositor is
|
||||||
* processing keys, rather than passing them on to the client for its own
|
* 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;
|
break;
|
||||||
k = &config.key_bindings[ji];
|
k = &config.key_bindings[ji];
|
||||||
if (CLEANMASK(mods) == CLEANMASK(k->mod) &&
|
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);
|
k->func(&k->arg);
|
||||||
handled = 1;
|
handled = 1;
|
||||||
}
|
}
|
||||||
|
|
@ -4219,7 +4226,7 @@ keybinding(uint32_t mods, xkb_keysym_t sym) {
|
||||||
bool keypressglobal(struct wlr_surface *last_surface,
|
bool keypressglobal(struct wlr_surface *last_surface,
|
||||||
struct wlr_keyboard *keyboard,
|
struct wlr_keyboard *keyboard,
|
||||||
struct wlr_keyboard_key_event *event, uint32_t mods,
|
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);
|
Client *c = NULL, *lastc = focustop(selmon);
|
||||||
uint32_t keycodes[32] = {0};
|
uint32_t keycodes[32] = {0};
|
||||||
int reset = false;
|
int reset = false;
|
||||||
|
|
@ -4233,11 +4240,14 @@ bool keypressglobal(struct wlr_surface *last_surface,
|
||||||
break;
|
break;
|
||||||
r = &config.window_rules[ji];
|
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;
|
continue;
|
||||||
|
|
||||||
/* match key only (case insensitive) ignoring mods */
|
/* 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) {
|
r->globalkeybinding.mod == mods) {
|
||||||
wl_list_for_each(c, &clients, link) {
|
wl_list_for_each(c, &clients, link) {
|
||||||
if (c && c != lastc) {
|
if (c && c != lastc) {
|
||||||
|
|
@ -4314,12 +4324,13 @@ void keypress(struct wl_listener *listener, void *data) {
|
||||||
* attempt to process a compositor keybinding. */
|
* attempt to process a compositor keybinding. */
|
||||||
if (!locked && event->state == WL_KEYBOARD_KEY_STATE_PRESSED) {
|
if (!locked && event->state == WL_KEYBOARD_KEY_STATE_PRESSED) {
|
||||||
for (i = 0; i < nsyms; i++)
|
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) {
|
if (handled && group->wlr_group->keyboard.repeat_info.delay > 0) {
|
||||||
group->mods = mods;
|
group->mods = mods;
|
||||||
group->keysyms = syms;
|
group->keysyms = syms;
|
||||||
|
group->keycode = keycode;
|
||||||
group->nsyms = nsyms;
|
group->nsyms = nsyms;
|
||||||
wl_event_source_timer_update(
|
wl_event_source_timer_update(
|
||||||
group->key_repeat_source,
|
group->key_repeat_source,
|
||||||
|
|
@ -4344,7 +4355,7 @@ void keypress(struct wl_listener *listener, void *data) {
|
||||||
/* passed keys don't get repeated */
|
/* passed keys don't get repeated */
|
||||||
if (pass && syms)
|
if (pass && syms)
|
||||||
hit_global = keypressglobal(last_surface, &group->wlr_group->keyboard,
|
hit_global = keypressglobal(last_surface, &group->wlr_group->keyboard,
|
||||||
event, mods, syms[0]);
|
event, mods, syms[0], keycode);
|
||||||
|
|
||||||
if (hit_global) {
|
if (hit_global) {
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue