From 3161db573424a554b536aaa492397341b84683ce Mon Sep 17 00:00:00 2001 From: Vito Caputo Date: Wed, 23 Dec 2020 01:12:51 -0800 Subject: *: introduce and use direction parameter This adds a direction parameter to vwm_desktop_next{_mru}() and vwm_win_focus_next(), deprecating _prev() variants in favor of a vwm_direction_t parameter. XK_r has been wired up as a modifier for reversing the direction of actions like Mod1+Tab (window next MRU cycle) and Mod1+Space (desktop next MRU cycle). So now if you overshoot, simply hold the "r" key and repeat the operation to go back, much like how Shift is often used for reversing alt+tab in i.e. Windows. --- src/desktop.c | 60 +++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 20 deletions(-) (limited to 'src/desktop.c') diff --git a/src/desktop.c b/src/desktop.c index 1fcce8c..e6130e0 100644 --- a/src/desktop.c +++ b/src/desktop.c @@ -17,6 +17,7 @@ */ /* virtual desktops */ +#include #include #include #include @@ -80,39 +81,58 @@ int vwm_desktop_focus(vwm_t *vwm, vwm_desktop_t *desktop) return 1; } -/* return next MRU desktop relative to the supplied desktop */ -vwm_desktop_t * vwm_desktop_next_mru(vwm_t *vwm, vwm_desktop_t *desktop) + +/* return next MRU desktop relative to the supplied desktop, wraps-around */ +vwm_desktop_t * vwm_desktop_next_mru(vwm_t *vwm, vwm_desktop_t *desktop, vwm_direction_t direction) { - list_head_t *next; + vwm_desktop_t *next = desktop; /* this dance is necessary because the list head @ vwm->desktops_mru has no vwm_desktop_t container, * and we're exploiting the circular nature of the doubly linked lists, so we need to take care to skip * past the container-less head. */ - if (desktop->desktops_mru.next == &vwm->desktops_mru) { - next = desktop->desktops_mru.next->next; - } else { - next = desktop->desktops_mru.next; - } + switch (direction) { + case VWM_DIRECTION_FORWARD: + if (next->desktops_mru.next == &vwm->desktops_mru) { + next = list_entry(next->desktops_mru.next->next, vwm_desktop_t, desktops_mru); + } else { + next = list_entry(next->desktops_mru.next, vwm_desktop_t, desktops_mru); + } + break; - return list_entry(next, vwm_desktop_t, desktops_mru); -} + case VWM_DIRECTION_REVERSE: + if (next->desktops_mru.prev == &vwm->desktops_mru) { + next = list_entry(next->desktops_mru.prev->prev, vwm_desktop_t, desktops_mru); + } else { + next = list_entry(next->desktops_mru.prev, vwm_desktop_t, desktops_mru); + } + break; -/* return next desktop spatially relative to the supplied desktop, no wrap-around */ -vwm_desktop_t * vwm_desktop_next(vwm_t *vwm, vwm_desktop_t *desktop) -{ - if (desktop->desktops.next != &vwm->desktops) - desktop = list_entry(desktop->desktops.next, vwm_desktop_t, desktops); + default: + assert(0); + } - return desktop; + return next; } -/* return previous desktop spatially relative to the supplied desktop, no wrap-around */ -vwm_desktop_t * vwm_desktop_prev(vwm_t *vwm, vwm_desktop_t *desktop) +/* return next desktop spatially relative to the supplied desktop, no wrap-around */ +vwm_desktop_t * vwm_desktop_next(vwm_t *vwm, vwm_desktop_t *desktop, vwm_direction_t direction) { - if (desktop->desktops.prev != &vwm->desktops) - desktop = list_entry(desktop->desktops.prev, vwm_desktop_t, desktops); + switch (direction) { + case VWM_DIRECTION_FORWARD: + if (desktop->desktops.next != &vwm->desktops) + return list_entry(desktop->desktops.next, vwm_desktop_t, desktops); + break; + + case VWM_DIRECTION_REVERSE: + if (desktop->desktops.prev != &vwm->desktops) + return list_entry(desktop->desktops.prev, vwm_desktop_t, desktops); + break; + + default: + assert(0); + } return desktop; } -- cgit v1.2.3