/* 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;
};
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 */
#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")) {
} else if (!strcasecmp(str, "Middle")) {
return BTN_MIDDLE;
}
+invalid:
wlr_log(WLR_ERROR, "unknown button (%s)", str);
return UINT32_MAX;
}
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")) {
/* <mousebind button="" action="EVENT"> */
current_mousebind->mouse_event =
{
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) {
}
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,
}
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);
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;
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);
}
}