From 8eab1e81323b85fc6efc59ebab384e48fa393299 Mon Sep 17 00:00:00 2001 From: bi4k8 Date: Wed, 1 Dec 2021 02:32:24 +0000 Subject: [PATCH] parse and respect modifiers for mouse bindings --- include/config/mousebind.h | 5 ++++- src/config/mousebind.c | 16 +++++++++++++++- src/config/rcxml.c | 6 ++++-- src/cursor.c | 14 ++++++++------ 4 files changed, 31 insertions(+), 10 deletions(-) diff --git a/include/config/mousebind.h b/include/config/mousebind.h index 52ec16ae..f01a8849 100644 --- a/include/config/mousebind.h +++ b/include/config/mousebind.h @@ -19,6 +19,9 @@ struct mousebind { /* ex: BTN_LEFT, BTN_RIGHT from linux/input_event_codes.h */ uint32_t button; + /* ex: WLR_MODIFIER_SHIFT | WLR_MODIFIER_LOGO */ + uint32_t modifiers; + /* ex: doubleclick, press, drag */ enum mouse_event mouse_event; const char *action; @@ -29,7 +32,7 @@ struct mousebind { }; enum mouse_event mousebind_event_from_str(const char *str); -uint32_t mousebind_button_from_str(const char *str); +uint32_t mousebind_button_from_str(const char *str, uint32_t *modifiers); struct mousebind *mousebind_create(const char *context); #endif /* __LABWC_MOUSEBIND_H */ diff --git a/src/config/mousebind.c b/src/config/mousebind.c index f12a1131..03241c57 100644 --- a/src/config/mousebind.c +++ b/src/config/mousebind.c @@ -9,9 +9,22 @@ #include "config/rcxml.h" uint32_t -mousebind_button_from_str(const char *str) +mousebind_button_from_str(const char *str, uint32_t *modifiers) { assert(str); + + if (modifiers) { + *modifiers = 0; + while (strlen(str) >= 2 && str[1] == '-') { + char modname[2] = {str[0], 0}; + uint32_t parsed_modifier = parse_modifier(modname); + if (!parsed_modifier) + goto invalid; + *modifiers |= parsed_modifier; + str += 2; + } + } + if (!strcasecmp(str, "Left")) { return BTN_LEFT; } else if (!strcasecmp(str, "Right")) { @@ -19,6 +32,7 @@ mousebind_button_from_str(const char *str) } else if (!strcasecmp(str, "Middle")) { return BTN_MIDDLE; } +invalid: wlr_log(WLR_ERROR, "unknown button (%s)", str); return UINT32_MAX; } diff --git a/src/config/rcxml.c b/src/config/rcxml.c index 982bcb46..1eb93aee 100644 --- a/src/config/rcxml.c +++ b/src/config/rcxml.c @@ -89,7 +89,8 @@ fill_mousebind(char *nodename, char *content) string_truncate_at_pattern(nodename, ".mousebind.context.mouse"); if (!strcmp(nodename, "button")) { - current_mousebind->button = mousebind_button_from_str(content); + current_mousebind->button = mousebind_button_from_str(content, + ¤t_mousebind->modifiers); } else if (!strcmp(nodename, "action")) { /* */ current_mousebind->mouse_event = @@ -477,7 +478,8 @@ load_default_mouse_bindings(void) { for (int i = 0; mouse_combos[i].context; i++) { struct mousebind *m = mousebind_create(mouse_combos[i].context); - m->button = mousebind_button_from_str(mouse_combos[i].button); + m->button = mousebind_button_from_str(mouse_combos[i].button, + &m->modifiers); m->mouse_event = mousebind_event_from_str(mouse_combos[i].event); m->action = strdup(mouse_combos[i].action); if (mouse_combos[i].command) { diff --git a/src/cursor.c b/src/cursor.c index 24bd36ae..bcbdfcdc 100644 --- a/src/cursor.c +++ b/src/cursor.c @@ -443,12 +443,13 @@ handle_cursor_button_with_meta_key(struct view *view, uint32_t button, } static void -handle_release_mousebinding(struct server *server, uint32_t button, enum ssd_part_type view_area) +handle_release_mousebinding(struct server *server, uint32_t button, uint32_t modifiers, enum ssd_part_type view_area) { struct mousebind *mousebind; wl_list_for_each_reverse(mousebind, &rc.mousebinds, link) { if (mousebind->context == view_area - && mousebind->button == button) { + && mousebind->button == button + && modifiers == mousebind->modifiers) { if (mousebind->mouse_event == MOUSE_ACTION_RELEASE) { action(server, mousebind->action, @@ -487,7 +488,7 @@ is_double_click(long double_click_speed, uint32_t button) } static bool -handle_press_mousebinding(struct server *server, uint32_t button, enum ssd_part_type view_area) +handle_press_mousebinding(struct server *server, uint32_t button, uint32_t modifiers, enum ssd_part_type view_area) { struct mousebind *mousebind; bool double_click = is_double_click(rc.doubleclick_time, button); @@ -495,7 +496,8 @@ handle_press_mousebinding(struct server *server, uint32_t button, enum ssd_part_ wl_list_for_each_reverse(mousebind, &rc.mousebinds, link) { if (mousebind->context == view_area - && mousebind->button == button) { + && mousebind->button == button + && modifiers == mousebind->modifiers) { if (mousebind->mouse_event == MOUSE_ACTION_PRESS) { bound = true; @@ -605,9 +607,9 @@ cursor_button(struct wl_listener *listener, void *data) mousebindings: if (event->state == WLR_BUTTON_RELEASED) { - handle_release_mousebinding(server, event->button, view_area); + handle_release_mousebinding(server, event->button, modifiers, view_area); } else if (event->state == WLR_BUTTON_PRESSED) { - handle_press_mousebinding(server, event->button, view_area); + handle_press_mousebinding(server, event->button, modifiers, view_area); } }