diff --git a/gestures/gestures.patch b/gestures/gestures.patch new file mode 100644 index 0000000..d4b1c13 --- /dev/null +++ b/gestures/gestures.patch @@ -0,0 +1,158 @@ +diff --git a/config.def.h b/config.def.h +index db0babc..e2ec245 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -13,6 +13,8 @@ static const float urgentcolor[] = COLOR(0xff0000ff); + /* To conform the xdg-protocol, set the alpha to zero to restore the old behavior */ + static const float fullscreen_bg[] = {0.1, 0.1, 0.1, 1.0}; /* You can also use glsl colors */ + ++static const unsigned int swipe_min_threshold = 0; ++ + /* tagging - TAGCOUNT must be no greater than 31 */ + #define TAGCOUNT (9) + +@@ -167,3 +169,10 @@ static const Button buttons[] = { + { MODKEY, BTN_MIDDLE, togglefloating, {0} }, + { MODKEY, BTN_RIGHT, moveresize, {.ui = CurResize} }, + }; ++ ++static const Gesture gestures[] = { ++ // { MODKEY, SWIPE_LEFT, 4, shiftview, { .i = 1 } }, ++ // { MODKEY, SWIPE_RIGHT, 4, shiftview, { .i = -1 } }, ++ { MODKEY, SWIPE_UP, 3, focusstack, {.i = 1} }, ++ { MODKEY, SWIPE_DOWN, 3, focusstack, {.i = -1} }, ++}; +diff --git a/dwl.c b/dwl.c +index 2aeaca1..fd7ab00 100644 +--- a/dwl.c ++++ b/dwl.c +@@ -81,6 +81,7 @@ enum { LyrBg, LyrBottom, LyrTile, LyrFloat, LyrFS, LyrTop, LyrOverlay, LyrBlock, + enum { NetWMWindowTypeDialog, NetWMWindowTypeSplash, NetWMWindowTypeToolbar, + NetWMWindowTypeUtility, NetLast }; /* EWMH atoms */ + #endif ++enum { SWIPE_LEFT, SWIPE_RIGHT, SWIPE_DOWN, SWIPE_UP }; + + typedef union { + int i; +@@ -96,6 +97,14 @@ typedef struct { + const Arg arg; + } Button; + ++typedef struct { ++ unsigned int mod; ++ unsigned int motion; ++ unsigned int fingers_count; ++ void (*func)(const Arg *); ++ const Arg arg; ++} Gesture; ++ + typedef struct Monitor Monitor; + typedef struct { + /* Must keep these three elements in this order */ +@@ -236,6 +245,7 @@ static void arrangelayer(Monitor *m, struct wl_list *list, + static void arrangelayers(Monitor *m); + static void axisnotify(struct wl_listener *listener, void *data); + static void buttonpress(struct wl_listener *listener, void *data); ++static int ongesture(struct wlr_pointer_swipe_end_event *event); + static void swipe_begin(struct wl_listener *listener, void *data); + static void swipe_update(struct wl_listener *listener, void *data); + static void swipe_end(struct wl_listener *listener, void *data); +@@ -385,6 +395,10 @@ static struct wlr_box sgeom; + static struct wl_list mons; + static Monitor *selmon; + ++static uint32_t swipe_fingers = 0; ++static double swipe_dx = 0; ++static double swipe_dy = 0; ++ + #ifdef XWAYLAND + static void activatex11(struct wl_listener *listener, void *data); + static void associatex11(struct wl_listener *listener, void *data); +@@ -404,6 +418,8 @@ static xcb_atom_t netatom[NetLast]; + /* attempt to encapsulate suck into one file */ + #include "client.h" + ++static const unsigned int abzsquare = swipe_min_threshold * swipe_min_threshold; ++ + /* function implementations */ + void + applybounds(Client *c, struct wlr_box *bbox) +@@ -610,6 +626,11 @@ swipe_begin(struct wl_listener *listener, void *data) + { + struct wlr_pointer_swipe_begin_event *event = data; + ++ swipe_fingers = event->fingers; ++ // Reset swipe distance at the beginning of a swipe ++ swipe_dx = 0; ++ swipe_dy = 0; ++ + // Forward swipe begin event to client + wlr_pointer_gestures_v1_send_swipe_begin( + pointer_gestures, +@@ -624,6 +645,11 @@ swipe_update(struct wl_listener *listener, void *data) + { + struct wlr_pointer_swipe_update_event *event = data; + ++ swipe_fingers = event->fingers; ++ // Accumulate swipe distance ++ swipe_dx += event->dx; ++ swipe_dy += event->dy; ++ + // Forward swipe update event to client + wlr_pointer_gestures_v1_send_swipe_update( + pointer_gestures, +@@ -634,11 +660,53 @@ swipe_update(struct wl_listener *listener, void *data) + ); + } + ++int ++ongesture(struct wlr_pointer_swipe_end_event *event) ++{ ++ struct wlr_keyboard *keyboard; ++ uint32_t mods; ++ const Gesture *g; ++ unsigned int motion; ++ unsigned int adx = fabs(swipe_dx); ++ unsigned int ady = fabs(swipe_dy); ++ int handled = 0; ++ ++ if (event->cancelled) { ++ return handled; ++ } ++ ++ // Require absolute distance movement beyond a small thresh-hold ++ if (adx * adx + ady * ady < abzsquare) { ++ return handled; ++ } ++ ++ if (adx > ady) { ++ motion = swipe_dx < 0 ? SWIPE_LEFT : SWIPE_RIGHT; ++ } else { ++ motion = swipe_dy < 0 ? SWIPE_UP : SWIPE_DOWN; ++ } ++ ++ keyboard = wlr_seat_get_keyboard(seat); ++ mods = keyboard ? wlr_keyboard_get_modifiers(keyboard) : 0; ++ for (g = gestures; g < END(gestures); g++) { ++ if (CLEANMASK(mods) == CLEANMASK(g->mod) && ++ swipe_fingers == g->fingers_count && ++ motion == g->motion && g->func) { ++ g->func(&g->arg); ++ handled = 1; ++ } ++ } ++ return handled; ++} ++ + void + swipe_end(struct wl_listener *listener, void *data) + { + struct wlr_pointer_swipe_end_event *event = data; + ++ // TODO: should we stop here if the event has been handled? ++ ongesture(event); ++ + // Forward swipe end event to client + wlr_pointer_gestures_v1_send_swipe_end( + pointer_gestures, +