mirror of
https://github.com/DreamMaoMao/maomaowm.git
synced 2026-03-23 05:35:53 -04:00
Merge 6236adbe07 into 74d24c3cd9
This commit is contained in:
commit
2a5c8d2b82
2 changed files with 89 additions and 1 deletions
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
enum { NUM_TYPE_MINUS, NUM_TYPE_PLUS, NUM_TYPE_DEFAULT };
|
||||
|
||||
enum { KEY_TYPE_CODE, KEY_TYPE_SYM };
|
||||
enum { KEY_TYPE_CODE, KEY_TYPE_SYM, KEY_TYPE_NONE };
|
||||
|
||||
typedef struct {
|
||||
uint32_t keycode1;
|
||||
|
|
@ -788,6 +788,22 @@ void create_config_keymap(void) {
|
|||
KeySymCode parse_key(const char *key_str, bool isbindsym) {
|
||||
KeySymCode kc = {0}; // 初始化为0
|
||||
|
||||
// Handle "none" key for modifier-only bindings
|
||||
{
|
||||
char lower_key[10];
|
||||
int32_t ki = 0;
|
||||
while (key_str[ki] && ki < 9) {
|
||||
lower_key[ki] = tolower(key_str[ki]);
|
||||
ki++;
|
||||
}
|
||||
lower_key[ki] = '\0';
|
||||
if (strcmp(lower_key, "none") == 0) {
|
||||
kc.type = KEY_TYPE_NONE;
|
||||
kc.keysym = XKB_KEY_NoSymbol;
|
||||
return kc;
|
||||
}
|
||||
}
|
||||
|
||||
if (config.keymap == NULL || config.ctx == NULL) {
|
||||
// 处理错误
|
||||
kc.type = KEY_TYPE_SYM;
|
||||
|
|
@ -2358,6 +2374,18 @@ bool parse_option(Config *config, char *key, char *value) {
|
|||
binding->func =
|
||||
parse_func_name(func_name, &binding->arg, arg_value, arg_value2,
|
||||
arg_value3, arg_value4, arg_value5);
|
||||
|
||||
/* KEY_TYPE_NONE bindings must use the release flag (bindr) */
|
||||
if (binding->keysymcode.type == KEY_TYPE_NONE) {
|
||||
if (!binding->isreleaseapply) {
|
||||
fprintf(stderr,
|
||||
"\033[1m\033[33m[WARN]:\033[0m "
|
||||
"\"none\" key only works with bindr "
|
||||
"(release bind), forcing release mode\n");
|
||||
binding->isreleaseapply = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!binding->func || binding->mod == UINT32_MAX ||
|
||||
(binding->keysymcode.type == KEY_TYPE_SYM &&
|
||||
binding->keysymcode.keysym == XKB_KEY_NoSymbol)) {
|
||||
|
|
|
|||
60
src/mango.c
60
src/mango.c
|
|
@ -905,6 +905,8 @@ static struct wl_event_source *hide_cursor_source;
|
|||
static struct wl_event_source *keep_idle_inhibit_source;
|
||||
static bool cursor_hidden = false;
|
||||
static bool tag_combo = false;
|
||||
static bool mod_key_used = false;
|
||||
static uint32_t prev_mods = 0;
|
||||
static const char *cli_config_path = NULL;
|
||||
static bool cli_debug_log = false;
|
||||
static KeyMode keymode = {
|
||||
|
|
@ -2072,6 +2074,9 @@ buttonpress(struct wl_listener *listener, void *data) {
|
|||
if (locked)
|
||||
break;
|
||||
|
||||
/* Invalidate modifier-only bindings on mouse click */
|
||||
mod_key_used = true;
|
||||
|
||||
xytonode(cursor->x, cursor->y, &surface, NULL, NULL, NULL, NULL);
|
||||
if (toplevel_from_wlr_surface(surface, &c, &l) >= 0) {
|
||||
if (c && c->scene->node.enabled &&
|
||||
|
|
@ -3755,6 +3760,10 @@ keybinding(uint32_t state, bool locked, uint32_t mods, xkb_keysym_t sym,
|
|||
state != WL_KEYBOARD_KEY_STATE_RELEASED)
|
||||
continue;
|
||||
|
||||
/* Skip KEY_TYPE_NONE bindings here; they are handled in keypressmod */
|
||||
if (config.key_bindings[ji].keysymcode.type == KEY_TYPE_NONE)
|
||||
continue;
|
||||
|
||||
k = &config.key_bindings[ji];
|
||||
if ((k->iscommonmode || (k->isdefaultmode && keymode.isdefault) ||
|
||||
(strcmp(keymode.mode, k->mode) == 0)) &&
|
||||
|
|
@ -3885,6 +3894,16 @@ void keypress(struct wl_listener *listener, void *data) {
|
|||
}
|
||||
}
|
||||
|
||||
/* Track non-modifier key presses to invalidate modifier-only bindings.
|
||||
* Modifier keycodes: 133,134=Super, 37,105=Ctrl, 50,62=Shift, 64,108=Alt */
|
||||
if (event->state == WL_KEYBOARD_KEY_STATE_PRESSED &&
|
||||
keycode != 133 && keycode != 134 && /* Super_L, Super_R */
|
||||
keycode != 37 && keycode != 105 && /* Control_L, Control_R */
|
||||
keycode != 50 && keycode != 62 && /* Shift_L, Shift_R */
|
||||
keycode != 64 && keycode != 108) { /* Alt_L, Alt_R */
|
||||
mod_key_used = true;
|
||||
}
|
||||
|
||||
/* On _press_ if there is no active screen locker,
|
||||
* attempt to process a compositor keybinding. */
|
||||
for (i = 0; i < nsyms; i++)
|
||||
|
|
@ -3941,6 +3960,47 @@ void keypressmod(struct wl_listener *listener, void *data) {
|
|||
* pressed. We simply communicate this to the client. */
|
||||
KeyboardGroup *group = wl_container_of(listener, group, modifiers);
|
||||
|
||||
uint32_t mods = wlr_keyboard_get_modifiers(&group->wlr_group->keyboard);
|
||||
|
||||
/* Handle modifier-only keybindings (KEY_TYPE_NONE).
|
||||
* Fire when a modifier is released without any non-modifier key having
|
||||
* been pressed during the hold. We detect release by checking if a
|
||||
* modifier bit was set in prev_mods but is now cleared.
|
||||
* The (prev_mods & ~mods) check ensures a modifier was actually
|
||||
* released (bits cleared), not just a new modifier added. */
|
||||
if (!locked && group == kb_group && !mod_key_used && prev_mods != 0 &&
|
||||
mods != prev_mods && (prev_mods & ~mods) != 0) {
|
||||
/* A modifier was released — check if the previously held modifier
|
||||
* combination matches any KEY_TYPE_NONE bindings */
|
||||
for (int32_t ji = 0; ji < config.key_bindings_count; ji++) {
|
||||
const KeyBinding *k = &config.key_bindings[ji];
|
||||
if (k->keysymcode.type != KEY_TYPE_NONE)
|
||||
continue;
|
||||
if (!k->func)
|
||||
continue;
|
||||
if (!(k->iscommonmode ||
|
||||
(k->isdefaultmode && keymode.isdefault) ||
|
||||
(strcmp(keymode.mode, k->mode) == 0)))
|
||||
continue;
|
||||
/* The binding's mod should match the modifiers that were held
|
||||
* before this release */
|
||||
if (CLEANMASK(prev_mods) == CLEANMASK(k->mod)) {
|
||||
k->func(&k->arg);
|
||||
/* Mark as used so we don't fire again during
|
||||
* subsequent releases of the same combo */
|
||||
mod_key_used = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Reset tracking when all modifiers are released */
|
||||
if (mods == 0) {
|
||||
mod_key_used = false;
|
||||
}
|
||||
|
||||
prev_mods = mods;
|
||||
|
||||
if (!dwl_im_keyboard_grab_forward_modifiers(group)) {
|
||||
|
||||
wlr_seat_set_keyboard(seat, &group->wlr_group->keyboard);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue