dwm-alttab2-6.4.diff (4323B)
1 diff --git a/config.def.h b/config.def.h 2 index 71ec68b..95499bd 100644 3 --- a/config.def.h 4 +++ b/config.def.h 5 @@ -2,6 +2,8 @@ 6 7 /* appearance */ 8 static const unsigned int borderpx = 1; /* border pixel of windows */ 9 +static const unsigned int tabModKey = 0x40; 10 +static const unsigned int tabCycleKey = 0x17; 11 static const unsigned int snap = 32; /* snap pixel */ 12 static const int showbar = 1; /* 0 means no bar */ 13 static const int topbar = 1; /* 0 means bottom bar */ 14 @@ -96,6 +98,7 @@ static const Key keys[] = { 15 TAGKEYS( XK_9, 8) 16 { MODKEY|ShiftMask, XK_q, quit, {0} }, 17 { MODKEY, XK_o, winview, {0} }, 18 + { Mod1Mask, XK_Tab, alttab, {0} }, 19 }; 20 21 /* button definitions */ 22 diff --git a/dwm.c b/dwm.c 23 index ec076a8..71d0ebc 100644 24 --- a/dwm.c 25 +++ b/dwm.c 26 @@ -28,6 +28,7 @@ 27 #include <stdlib.h> 28 #include <string.h> 29 #include <unistd.h> 30 +#include <time.h> 31 #include <sys/types.h> 32 #include <sys/wait.h> 33 #include <X11/cursorfont.h> 34 @@ -142,6 +143,7 @@ typedef struct { 35 } Rule; 36 37 /* function declarations */ 38 +static void alttab(const Arg *arg); 39 static void applyrules(Client *c); 40 static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact); 41 static void arrange(Monitor *m); 42 @@ -168,6 +170,7 @@ static void expose(XEvent *e); 43 static void focus(Client *c); 44 static void focusin(XEvent *e); 45 static void focusmon(const Arg *arg); 46 +static void focusnext(const Arg *arg); 47 static void focusstack(const Arg *arg); 48 static Atom getatomprop(Client *c, Atom prop); 49 static int getrootptr(int *x, int *y); 50 @@ -269,6 +272,8 @@ static Drw *drw; 51 static Monitor *mons, *selmon; 52 static Window root, wmcheckwin; 53 54 +static int alt_tab_direction = 0; 55 + 56 /* configuration, allows nested code to access above variables */ 57 #include "config.h" 58 59 @@ -276,6 +281,79 @@ static Window root, wmcheckwin; 60 struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; }; 61 62 /* function implementations */ 63 + 64 +static void 65 +alttab(const Arg *arg) { 66 + 67 + view(&(Arg){ .ui = ~0 }); 68 + focusnext(&(Arg){ .i = alt_tab_direction }); 69 + 70 + int grabbed = 1; 71 + int grabbed_keyboard = 1000; 72 + for (int i = 0; i < 100; i += 1) { 73 + struct timespec ts; 74 + ts.tv_sec = 0; 75 + ts.tv_nsec = 1000000; 76 + 77 + if (grabbed_keyboard != GrabSuccess) { 78 + grabbed_keyboard = XGrabKeyboard(dpy, DefaultRootWindow(dpy), True, 79 + GrabModeAsync, GrabModeAsync, CurrentTime); 80 + } 81 + if (grabbed_keyboard == GrabSuccess) { 82 + XGrabButton(dpy, AnyButton, AnyModifier, None, False, 83 + BUTTONMASK, GrabModeAsync, GrabModeAsync, 84 + None, None); 85 + break; 86 + } 87 + nanosleep(&ts, NULL); 88 + if (i == 100 - 1) 89 + grabbed = 0; 90 + } 91 + 92 + XEvent event; 93 + Client *c; 94 + Monitor *m; 95 + XButtonPressedEvent *ev; 96 + 97 + while (grabbed) { 98 + XNextEvent(dpy, &event); 99 + switch (event.type) { 100 + case KeyPress: 101 + if (event.xkey.keycode == tabCycleKey) 102 + focusnext(&(Arg){ .i = alt_tab_direction }); 103 + break; 104 + case KeyRelease: 105 + if (event.xkey.keycode == tabModKey) { 106 + XUngrabKeyboard(dpy, CurrentTime); 107 + XUngrabButton(dpy, AnyButton, AnyModifier, None); 108 + grabbed = 0; 109 + alt_tab_direction = !alt_tab_direction; 110 + winview(0); 111 + } 112 + break; 113 + case ButtonPress: 114 + ev = &(event.xbutton); 115 + if ((m = wintomon(ev->window)) && m != selmon) { 116 + unfocus(selmon->sel, 1); 117 + selmon = m; 118 + focus(NULL); 119 + } 120 + if ((c = wintoclient(ev->window))) 121 + focus(c); 122 + XAllowEvents(dpy, AsyncBoth, CurrentTime); 123 + break; 124 + case ButtonRelease: 125 + XUngrabKeyboard(dpy, CurrentTime); 126 + XUngrabButton(dpy, AnyButton, AnyModifier, None); 127 + grabbed = 0; 128 + alt_tab_direction = !alt_tab_direction; 129 + winview(0); 130 + break; 131 + } 132 + } 133 + return; 134 +} 135 + 136 void 137 applyrules(Client *c) 138 { 139 @@ -836,6 +914,28 @@ focusmon(const Arg *arg) 140 focus(NULL); 141 } 142 143 +static void 144 +focusnext(const Arg *arg) { 145 + Monitor *m; 146 + Client *c; 147 + m = selmon; 148 + c = m->sel; 149 + 150 + if (arg->i) { 151 + if (c->next) 152 + c = c->next; 153 + else 154 + c = m->clients; 155 + } else { 156 + Client *last = c; 157 + if (last == m->clients) 158 + last = NULL; 159 + for (c = m->clients; c->next != last; c = c->next); 160 + } 161 + focus(c); 162 + return; 163 +} 164 + 165 void 166 focusstack(const Arg *arg) 167 {