| dwm-alttab2-6.4.diff - sites - public wiki contents of suckless.org | |
| git clone git://git.suckless.org/sites | |
| Log | |
| Files | |
| Refs | |
| --- | |
| 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 wind… | |
| 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, in… | |
| 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, DefaultRo… | |
| 79 + … | |
| 80 + } | |
| 81 + if (grabbed_keyboard == GrabSuccess) { | |
| 82 + XGrabButton(dpy, AnyButton, AnyModifier, None, … | |
| 83 + BUTTONMASK, GrabModeAsy… | |
| 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_directio… | |
| 103 + break; | |
| 104 + case KeyRelease: | |
| 105 + if (event.xkey.keycode == tabModKey) { | |
| 106 + XUngrabKeyboard(dpy, CurrentTime); | |
| 107 + XUngrabButton(dpy, AnyButton, AnyModifi… | |
| 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 { |