mirror of
https://github.com/DreamMaoMao/maomaowm.git
synced 2026-07-06 00:06:43 -04:00
feat: add bindm (modifier-only exclusive keybind)
This commit is contained in:
parent
cabafb2393
commit
01a7bf5a8d
2 changed files with 132 additions and 0 deletions
|
|
@ -45,6 +45,7 @@ typedef struct {
|
||||||
bool islockapply;
|
bool islockapply;
|
||||||
bool isreleaseapply;
|
bool isreleaseapply;
|
||||||
bool ispassapply;
|
bool ispassapply;
|
||||||
|
bool ismodonly;
|
||||||
} KeyBinding;
|
} KeyBinding;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
@ -2436,6 +2437,92 @@ bool parse_option(Config *config, char *key, char *value) {
|
||||||
config->key_bindings_count++;
|
config->key_bindings_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else if (regex_match("^bindm[lp]*$", key)) {
|
||||||
|
/* bindm: fire on modifier release if no other bind used the hold
|
||||||
|
* format: bindm[flags]=MODIFIERS,,COMMAND,PARAMS */
|
||||||
|
config->key_bindings =
|
||||||
|
realloc(config->key_bindings,
|
||||||
|
(config->key_bindings_count + 1) * sizeof(KeyBinding));
|
||||||
|
if (!config->key_bindings) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"\033[1m\033[31m[ERROR]:\033[33m Failed to allocate "
|
||||||
|
"memory for key bindings (bindm)\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyBinding *binding = &config->key_bindings[config->key_bindings_count];
|
||||||
|
memset(binding, 0, sizeof(KeyBinding));
|
||||||
|
|
||||||
|
char mod_str[256], func_name[256],
|
||||||
|
arg_value[256] = "0\0", arg_value2[256] = "0\0",
|
||||||
|
arg_value3[256] = "0\0", arg_value4[256] = "0\0",
|
||||||
|
arg_value5[256] = "0\0";
|
||||||
|
|
||||||
|
if (sscanf(value,
|
||||||
|
"%255[^,],,%255[^,],%255[^,],%255[^,],%255[^,],%255[^\n]",
|
||||||
|
mod_str, func_name, arg_value, arg_value2,
|
||||||
|
arg_value3, arg_value4) < 2) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"\033[1m\033[31m[ERROR]:\033[33m Invalid bindm format "
|
||||||
|
"(expected MODIFIERS,,COMMAND,...): "
|
||||||
|
"\033[1m\033[31m%s\n",
|
||||||
|
value);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
trim_whitespace(mod_str);
|
||||||
|
trim_whitespace(func_name);
|
||||||
|
trim_whitespace(arg_value);
|
||||||
|
trim_whitespace(arg_value2);
|
||||||
|
trim_whitespace(arg_value3);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const char *f = key + 5; *f != '\0'; f++) {
|
||||||
|
if (*f == 'l') binding->islockapply = true;
|
||||||
|
if (*f == 'p') binding->ispassapply = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
binding->mod = parse_mod(mod_str);
|
||||||
|
binding->ismodonly = true;
|
||||||
|
|
||||||
|
binding->func =
|
||||||
|
parse_func_name(func_name, &binding->arg, arg_value, arg_value2,
|
||||||
|
arg_value3, arg_value4, arg_value5);
|
||||||
|
if (!binding->func || binding->mod == UINT32_MAX) {
|
||||||
|
if (binding->arg.v) {
|
||||||
|
free(binding->arg.v);
|
||||||
|
binding->arg.v = NULL;
|
||||||
|
}
|
||||||
|
if (binding->arg.v2) {
|
||||||
|
free(binding->arg.v2);
|
||||||
|
binding->arg.v2 = NULL;
|
||||||
|
}
|
||||||
|
if (binding->arg.v3) {
|
||||||
|
free(binding->arg.v3);
|
||||||
|
binding->arg.v3 = NULL;
|
||||||
|
}
|
||||||
|
if (!binding->func)
|
||||||
|
fprintf(stderr,
|
||||||
|
"\033[1m\033[31m[ERROR]:\033[33m Unknown dispatch in "
|
||||||
|
"bindm: \033[1m\033[31m%s\n",
|
||||||
|
func_name);
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
config->key_bindings_count++;
|
||||||
|
}
|
||||||
|
|
||||||
} else if (strncmp(key, "mousebind", 9) == 0) {
|
} else if (strncmp(key, "mousebind", 9) == 0) {
|
||||||
config->mouse_bindings =
|
config->mouse_bindings =
|
||||||
realloc(config->mouse_bindings,
|
realloc(config->mouse_bindings,
|
||||||
|
|
|
||||||
45
src/mango.c
45
src/mango.c
|
|
@ -922,6 +922,10 @@ static struct wl_event_source *hide_cursor_source;
|
||||||
static struct wl_event_source *keep_idle_inhibit_source;
|
static struct wl_event_source *keep_idle_inhibit_source;
|
||||||
static bool cursor_hidden = false;
|
static bool cursor_hidden = false;
|
||||||
static bool tag_combo = false;
|
static bool tag_combo = false;
|
||||||
|
|
||||||
|
/* set when a bind fires while modifiers held; cleared on modifier press */
|
||||||
|
static bool mod_used_for_bind = false;
|
||||||
|
|
||||||
static const char *cli_config_path = NULL;
|
static const char *cli_config_path = NULL;
|
||||||
static bool cli_debug_log = false;
|
static bool cli_debug_log = false;
|
||||||
static KeyMode keymode = {
|
static KeyMode keymode = {
|
||||||
|
|
@ -2332,6 +2336,7 @@ buttonpress(struct wl_listener *listener, void *data) {
|
||||||
event->button == m->button && m->func &&
|
event->button == m->button && m->func &&
|
||||||
(CLEANMASK(m->mod) != 0 ||
|
(CLEANMASK(m->mod) != 0 ||
|
||||||
(event->button != BTN_LEFT && event->button != BTN_RIGHT))) {
|
(event->button != BTN_LEFT && event->button != BTN_RIGHT))) {
|
||||||
|
mod_used_for_bind = true;
|
||||||
m->func(&m->arg);
|
m->func(&m->arg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -3996,6 +4001,9 @@ keybinding(uint32_t state, bool locked, uint32_t mods, xkb_keysym_t sym,
|
||||||
state != WL_KEYBOARD_KEY_STATE_RELEASED)
|
state != WL_KEYBOARD_KEY_STATE_RELEASED)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (config.key_bindings[ji].ismodonly)
|
||||||
|
continue;
|
||||||
|
|
||||||
k = &config.key_bindings[ji];
|
k = &config.key_bindings[ji];
|
||||||
if ((k->iscommonmode || (k->isdefaultmode && keymode.isdefault) ||
|
if ((k->iscommonmode || (k->isdefaultmode && keymode.isdefault) ||
|
||||||
(strcmp(keymode.mode, k->mode) == 0)) &&
|
(strcmp(keymode.mode, k->mode) == 0)) &&
|
||||||
|
|
@ -4014,6 +4022,9 @@ keybinding(uint32_t state, bool locked, uint32_t mods, xkb_keysym_t sym,
|
||||||
else
|
else
|
||||||
handled = 0;
|
handled = 0;
|
||||||
|
|
||||||
|
if (!k->ispassapply)
|
||||||
|
mod_used_for_bind = true;
|
||||||
|
|
||||||
isbreak = k->func(&k->arg);
|
isbreak = k->func(&k->arg);
|
||||||
|
|
||||||
if (isbreak)
|
if (isbreak)
|
||||||
|
|
@ -4115,6 +4126,15 @@ void keypress(struct wl_listener *listener, void *data) {
|
||||||
|
|
||||||
wlr_idle_notifier_v1_notify_activity(idle_notifier, seat);
|
wlr_idle_notifier_v1_notify_activity(idle_notifier, seat);
|
||||||
|
|
||||||
|
bool is_modifier_key =
|
||||||
|
(keycode == 133 || keycode == 134 ||
|
||||||
|
keycode == 37 || keycode == 105 ||
|
||||||
|
keycode == 64 || keycode == 108 ||
|
||||||
|
keycode == 50 || keycode == 62);
|
||||||
|
|
||||||
|
if (is_modifier_key && event->state == WL_KEYBOARD_KEY_STATE_PRESSED)
|
||||||
|
mod_used_for_bind = false;
|
||||||
|
|
||||||
// ov tab mode detect moe key release
|
// ov tab mode detect moe key release
|
||||||
if (config.ov_tab_mode && !locked && group == kb_group &&
|
if (config.ov_tab_mode && !locked && group == kb_group &&
|
||||||
event->state == WL_KEYBOARD_KEY_STATE_RELEASED &&
|
event->state == WL_KEYBOARD_KEY_STATE_RELEASED &&
|
||||||
|
|
@ -4132,6 +4152,31 @@ void keypress(struct wl_listener *listener, void *data) {
|
||||||
handled =
|
handled =
|
||||||
keybinding(event->state, locked, mods, syms[i], keycode) || handled;
|
keybinding(event->state, locked, mods, syms[i], keycode) || handled;
|
||||||
|
|
||||||
|
/* bindm: fire mod-only binds on release if no combo fired */
|
||||||
|
if (is_modifier_key && event->state == WL_KEYBOARD_KEY_STATE_RELEASED &&
|
||||||
|
!mod_used_for_bind) {
|
||||||
|
int32_t ji;
|
||||||
|
for (ji = 0; ji < config.key_bindings_count; ji++) {
|
||||||
|
const KeyBinding *k = &config.key_bindings[ji];
|
||||||
|
|
||||||
|
if (!k->ismodonly)
|
||||||
|
continue;
|
||||||
|
if (locked && !k->islockapply)
|
||||||
|
continue;
|
||||||
|
if (!(k->iscommonmode ||
|
||||||
|
(k->isdefaultmode && keymode.isdefault) ||
|
||||||
|
(strcmp(keymode.mode, k->mode) == 0)))
|
||||||
|
continue;
|
||||||
|
if (CLEANMASK(mods) != CLEANMASK(k->mod))
|
||||||
|
continue;
|
||||||
|
if (!k->func)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
handled = 1;
|
||||||
|
k->func(&k->arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (event->state == WL_KEYBOARD_KEY_STATE_RELEASED) {
|
if (event->state == WL_KEYBOARD_KEY_STATE_RELEASED) {
|
||||||
tag_combo = false;
|
tag_combo = false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue