parse and respect modifiers for mouse bindings

This commit is contained in:
bi4k8 2021-12-01 02:32:24 +00:00 committed by ARDiDo
parent c34a2fc976
commit 8eab1e8132
4 changed files with 31 additions and 10 deletions

View file

@ -19,6 +19,9 @@ struct mousebind {
/* ex: BTN_LEFT, BTN_RIGHT from linux/input_event_codes.h */ /* ex: BTN_LEFT, BTN_RIGHT from linux/input_event_codes.h */
uint32_t button; uint32_t button;
/* ex: WLR_MODIFIER_SHIFT | WLR_MODIFIER_LOGO */
uint32_t modifiers;
/* ex: doubleclick, press, drag */ /* ex: doubleclick, press, drag */
enum mouse_event mouse_event; enum mouse_event mouse_event;
const char *action; const char *action;
@ -29,7 +32,7 @@ struct mousebind {
}; };
enum mouse_event mousebind_event_from_str(const char *str); 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); struct mousebind *mousebind_create(const char *context);
#endif /* __LABWC_MOUSEBIND_H */ #endif /* __LABWC_MOUSEBIND_H */

View file

@ -9,9 +9,22 @@
#include "config/rcxml.h" #include "config/rcxml.h"
uint32_t uint32_t
mousebind_button_from_str(const char *str) mousebind_button_from_str(const char *str, uint32_t *modifiers)
{ {
assert(str); 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")) { if (!strcasecmp(str, "Left")) {
return BTN_LEFT; return BTN_LEFT;
} else if (!strcasecmp(str, "Right")) { } else if (!strcasecmp(str, "Right")) {
@ -19,6 +32,7 @@ mousebind_button_from_str(const char *str)
} else if (!strcasecmp(str, "Middle")) { } else if (!strcasecmp(str, "Middle")) {
return BTN_MIDDLE; return BTN_MIDDLE;
} }
invalid:
wlr_log(WLR_ERROR, "unknown button (%s)", str); wlr_log(WLR_ERROR, "unknown button (%s)", str);
return UINT32_MAX; return UINT32_MAX;
} }

View file

@ -89,7 +89,8 @@ fill_mousebind(char *nodename, char *content)
string_truncate_at_pattern(nodename, ".mousebind.context.mouse"); string_truncate_at_pattern(nodename, ".mousebind.context.mouse");
if (!strcmp(nodename, "button")) { 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")) { } else if (!strcmp(nodename, "action")) {
/* <mousebind button="" action="EVENT"> */ /* <mousebind button="" action="EVENT"> */
current_mousebind->mouse_event = current_mousebind->mouse_event =
@ -477,7 +478,8 @@ load_default_mouse_bindings(void)
{ {
for (int i = 0; mouse_combos[i].context; i++) { for (int i = 0; mouse_combos[i].context; i++) {
struct mousebind *m = mousebind_create(mouse_combos[i].context); 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->mouse_event = mousebind_event_from_str(mouse_combos[i].event);
m->action = strdup(mouse_combos[i].action); m->action = strdup(mouse_combos[i].action);
if (mouse_combos[i].command) { if (mouse_combos[i].command) {

View file

@ -443,12 +443,13 @@ handle_cursor_button_with_meta_key(struct view *view, uint32_t button,
} }
static void 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; struct mousebind *mousebind;
wl_list_for_each_reverse(mousebind, &rc.mousebinds, link) { wl_list_for_each_reverse(mousebind, &rc.mousebinds, link) {
if (mousebind->context == view_area if (mousebind->context == view_area
&& mousebind->button == button) { && mousebind->button == button
&& modifiers == mousebind->modifiers) {
if (mousebind->mouse_event if (mousebind->mouse_event
== MOUSE_ACTION_RELEASE) { == MOUSE_ACTION_RELEASE) {
action(server, mousebind->action, action(server, mousebind->action,
@ -487,7 +488,7 @@ is_double_click(long double_click_speed, uint32_t button)
} }
static bool 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; struct mousebind *mousebind;
bool double_click = is_double_click(rc.doubleclick_time, button); 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) { wl_list_for_each_reverse(mousebind, &rc.mousebinds, link) {
if (mousebind->context == view_area if (mousebind->context == view_area
&& mousebind->button == button) { && mousebind->button == button
&& modifiers == mousebind->modifiers) {
if (mousebind->mouse_event if (mousebind->mouse_event
== MOUSE_ACTION_PRESS) { == MOUSE_ACTION_PRESS) {
bound = true; bound = true;
@ -605,9 +607,9 @@ cursor_button(struct wl_listener *listener, void *data)
mousebindings: mousebindings:
if (event->state == WLR_BUTTON_RELEASED) { 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) { } else if (event->state == WLR_BUTTON_PRESSED) {
handle_press_mousebinding(server, event->button, view_area); handle_press_mousebinding(server, event->button, modifiers, view_area);
} }
} }