summaryrefslogtreecommitdiff
path: root/src/desktop.c
diff options
context:
space:
mode:
authorVito Caputo <vcaputo@pengaru.com>2020-12-23 01:12:51 -0800
committerVito Caputo <vcaputo@pengaru.com>2020-12-23 16:58:42 -0800
commit3161db573424a554b536aaa492397341b84683ce (patch)
tree1f72d7aa908dbb484bb8907b17bf493f551e2b85 /src/desktop.c
parenta6998186a3546f9f871e2cab3e994c782bd98a98 (diff)
*: 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.
Diffstat (limited to 'src/desktop.c')
-rw-r--r--src/desktop.c60
1 files changed, 40 insertions, 20 deletions
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 <assert.h>
#include <X11/Xlib.h>
#include <stdlib.h>
#include <string.h>
@@ -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;
}
© All Rights Reserved