diff --git a/include/config/mousebind.h b/include/config/mousebind.h index b86ed4e7..47ebfd86 100644 --- a/include/config/mousebind.h +++ b/include/config/mousebind.h @@ -14,6 +14,7 @@ enum mouse_event { MOUSE_ACTION_RELEASE, MOUSE_ACTION_DRAG, MOUSE_ACTION_SCROLL, + MOUSE_ACTION_SWIPE, }; enum direction { @@ -30,6 +31,9 @@ struct mousebind { /* ex: BTN_LEFT, BTN_RIGHT from linux/input_event_codes.h */ uint32_t button; + /* used for MOUSE_ACTION_SWIPE */ + uint32_t fingers; + /* scroll direction; considered instead of button for scroll events */ enum direction direction; diff --git a/src/config/mousebind.c b/src/config/mousebind.c index 6b5254f3..0e5db5de 100644 --- a/src/config/mousebind.c +++ b/src/config/mousebind.c @@ -98,6 +98,8 @@ mousebind_event_from_str(const char *str) return MOUSE_ACTION_DRAG; } else if (!strcasecmp(str, "scroll")) { return MOUSE_ACTION_SCROLL; + } else if (!strcasecmp(str, "swipe")) { + return MOUSE_ACTION_SWIPE; } wlr_log(WLR_ERROR, "unknown mouse action (%s)", str); return MOUSE_ACTION_NONE; @@ -111,7 +113,8 @@ mousebind_the_same(struct mousebind *a, struct mousebind *b) && a->button == b->button && a->direction == b->direction && a->mouse_event == b->mouse_event - && a->modifiers == b->modifiers; + && a->modifiers == b->modifiers + && a->fingers == b->fingers; } struct mousebind * diff --git a/src/config/rcxml.c b/src/config/rcxml.c index 95285776..1bb7cbd5 100644 --- a/src/config/rcxml.c +++ b/src/config/rcxml.c @@ -591,6 +591,9 @@ fill_mousebind(xmlNode *node, const char *context) mousebind->direction = mousebind_direction_from_str( buf, &mousebind->modifiers); } + if (lab_xml_get_string(node, "fingers", buf, sizeof(buf))) { + mousebind->fingers = atoi(buf); + } if (lab_xml_get_string(node, "action", buf, sizeof(buf))) { /* */ mousebind->mouse_event = mousebind_event_from_str(buf); diff --git a/src/input/gestures.c b/src/input/gestures.c index b40da82c..6d513fc5 100644 --- a/src/input/gestures.c +++ b/src/input/gestures.c @@ -2,10 +2,20 @@ #include "input/gestures.h" #include #include +#include "action.h" #include "common/macros.h" +#include "config/mousebind.h" +#include "config/rcxml.h" +#include "input/gestures.h" #include "labwc.h" #include "idle.h" +static struct { + double dx; + double dy; + uint32_t fingers; +} swipe_state; + static void handle_pinch_begin(struct wl_listener *listener, void *data) { @@ -57,6 +67,10 @@ handle_swipe_begin(struct wl_listener *listener, void *data) wlr_pointer_gestures_v1_send_swipe_begin(seat->pointer_gestures, seat->seat, event->time_msec, event->fingers); + + swipe_state.dx = 0; + swipe_state.dy = 0; + swipe_state.fingers = event->fingers; } static void @@ -70,6 +84,14 @@ handle_swipe_update(struct wl_listener *listener, void *data) wlr_pointer_gestures_v1_send_swipe_update(seat->pointer_gestures, seat->seat, event->time_msec, event->dx, event->dy); + + if (swipe_state.fingers == event->fingers) { + swipe_state.dx += event->dx; + swipe_state.dy += event->dy; + } else { + swipe_state.dx = 0; + swipe_state.dy = 0; + } } static void @@ -83,6 +105,37 @@ handle_swipe_end(struct wl_listener *listener, void *data) wlr_pointer_gestures_v1_send_swipe_end(seat->pointer_gestures, seat->seat, event->time_msec, event->cancelled); + + // TODO: check for !event->cancelled ? + if (swipe_state.dx || swipe_state.dy) { + enum direction direction; + if (swipe_state.dx * swipe_state.dx > swipe_state.dy * swipe_state.dy) { + direction = swipe_state.dx > 0 + ? LAB_DIRECTION_RIGHT + : LAB_DIRECTION_LEFT; + } else { + direction = swipe_state.dy > 0 + ? LAB_DIRECTION_DOWN + : LAB_DIRECTION_UP; + } + struct mousebind *mousebind; + wl_list_for_each(mousebind, &rc.mousebinds, link) { + if (mousebind->mouse_event != MOUSE_ACTION_SWIPE) { + continue; + } + if (mousebind->fingers != swipe_state.fingers) { + continue; + } + if (mousebind->direction != direction) { + continue; + } + actions_run(/*view*/ NULL, seat->server, + &mousebind->actions, /*cursor_ctx*/ NULL); + } + } + swipe_state.dx = 0; + swipe_state.dy = 0; + swipe_state.fingers = 0; } static void