]> git.mdlowis.com Git - proto/labwc.git/commitdiff
parse and respect modifiers for mouse bindings
authorbi4k8 <bi4k8@github>
Wed, 1 Dec 2021 02:32:24 +0000 (02:32 +0000)
committerARDiDo <90479315+ARDiDo@users.noreply.github.com>
Wed, 1 Dec 2021 20:11:21 +0000 (15:11 -0500)
include/config/mousebind.h
src/config/mousebind.c
src/config/rcxml.c
src/cursor.c

index 52ec16aedfc0beecf074e5b31e5dd229513baf88..f01a884933a7420003dfa689a329a479e2c8706a 100644 (file)
@@ -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 */
index f12a11311e68a9d8d4a740ecba423a0432310ce6..03241c575233438492626a975e090881be7f8a8f 100644 (file)
@@ -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;
 }
index 982bcb4610a1b6f932e745c664ee9327202e1cc0..1eb93aee185ee1d8051131a67876f260d1fdc346 100644 (file)
@@ -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,
+                       &current_mousebind->modifiers);
        } else if (!strcmp(nodename, "action")) {
                 /* <mousebind button="" action="EVENT"> */
                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) {
index 24bd36ae26806c6b9d2897da07f7e8c466a8d9d3..bcbdfcdcbc5212064d4a159708cc8a7bc0ef5f1a 100644 (file)
@@ -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);
        }
 }