Introduction
Introduction Statistics Contact Development Disclaimer Help
dwm-alttab-6.4.diff - sites - public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log
Files
Refs
---
dwm-alttab-6.4.diff (10136B)
---
1 From 8b1d33db9cbc03bf12df398bb14e62389efc70a3 Mon Sep 17 00:00:00 2001
2 From: ViliamKovac1223 <[email protected]>
3 Date: Sun, 9 Oct 2022 16:29:28 -0400
4 Subject: [PATCH] add alt-tab functionality
5
6 Co-authored-by: Daniel Gerblick <[email protected]>
7 ---
8 config.def.h | 11 ++-
9 dwm.c | 218 +++++++++++++++++++++++++++++++++++++++++++++++++++
10 2 files changed, 228 insertions(+), 1 deletion(-)
11
12 diff --git a/config.def.h b/config.def.h
13 index 061ad66..7a9e3b1 100644
14 --- a/config.def.h
15 +++ b/config.def.h
16 @@ -1,5 +1,13 @@
17 /* See LICENSE file for copyright and license details. */
18
19 +/* alt-tab configuration */
20 +static const unsigned int tabModKey = 0x40; /* i…
21 +static const unsigned int tabCycleKey = 0x17; /*…
22 +static const unsigned int tabPosY = 1; /…
23 +static const unsigned int tabPosX = 1; /…
24 +static const unsigned int maxWTab = 600; …
25 +static const unsigned int maxHTab = 200; …
26 +
27 /* appearance */
28 static const unsigned int borderpx = 1; /* border pixel of wind…
29 static const unsigned int snap = 32; /* snap pixel */
30 @@ -71,7 +79,7 @@ static const Key keys[] = {
31 { MODKEY, XK_h, setmfact, {.f …
32 { MODKEY, XK_l, setmfact, {.f …
33 { MODKEY, XK_Return, zoom, {0} …
34 - { MODKEY, XK_Tab, view, {0} …
35 + { MODKEY, XK_q, view, …
36 { MODKEY|ShiftMask, XK_c, killclient, {0} …
37 { MODKEY, XK_t, setlayout, {.v …
38 { MODKEY, XK_f, setlayout, {.v …
39 @@ -84,6 +92,7 @@ static const Key keys[] = {
40 { MODKEY, XK_period, focusmon, {.i …
41 { MODKEY|ShiftMask, XK_comma, tagmon, {.i …
42 { MODKEY|ShiftMask, XK_period, tagmon, {.i …
43 + { Mod1Mask, XK_Tab, altTabStart,…
44 TAGKEYS( XK_1, 0)
45 TAGKEYS( XK_2, 1)
46 TAGKEYS( XK_3, 2)
47 diff --git a/dwm.c b/dwm.c
48 index e5efb6a..f606311 100644
49 --- a/dwm.c
50 +++ b/dwm.c
51 @@ -40,6 +40,7 @@
52 #include <X11/extensions/Xinerama.h>
53 #endif /* XINERAMA */
54 #include <X11/Xft/Xft.h>
55 +#include <time.h>
56
57 #include "drw.h"
58 #include "util.h"
59 @@ -119,6 +120,11 @@ struct Monitor {
60 int by; /* bar geometry */
61 int mx, my, mw, mh; /* screen size */
62 int wx, wy, ww, wh; /* window area */
63 + int altTabN; /* move that many clients forward…
64 + int nTabs; /* number of active clients…
65 + int isAlt; /* 1,0 */
66 + int maxWTab;
67 + int maxHTab;
68 unsigned int seltags;
69 unsigned int sellt;
70 unsigned int tagset[2];
71 @@ -127,8 +133,10 @@ struct Monitor {
72 Client *clients;
73 Client *sel;
74 Client *stack;
75 + Client ** altsnext; /* array of all clients in the tag */
76 Monitor *next;
77 Window barwin;
78 + Window tabwin;
79 const Layout *lt[2];
80 };
81
82 @@ -234,6 +242,9 @@ static int xerror(Display *dpy, XErrorEvent *ee);
83 static int xerrordummy(Display *dpy, XErrorEvent *ee);
84 static int xerrorstart(Display *dpy, XErrorEvent *ee);
85 static void zoom(const Arg *arg);
86 +void drawTab(int nwins, int first, Monitor *m);
87 +void altTabStart(const Arg *arg);
88 +static void altTabEnd();
89
90 /* variables */
91 static const char broken[] = "broken";
92 @@ -477,6 +488,7 @@ cleanup(void)
93 Monitor *m;
94 size_t i;
95
96 + altTabEnd();
97 view(&a);
98 selmon->lt[selmon->sellt] = &foo;
99 for (m = mons; m; m = m->next)
100 @@ -644,6 +656,7 @@ createmon(void)
101 m->topbar = topbar;
102 m->lt[0] = &layouts[0];
103 m->lt[1] = &layouts[1 % LENGTH(layouts)];
104 + m->nTabs = 0;
105 strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
106 return m;
107 }
108 @@ -1648,6 +1661,211 @@ spawn(const Arg *arg)
109 }
110 }
111
112 +void
113 +altTab()
114 +{
115 + /* move to next window */
116 + if (selmon->sel != NULL && selmon->sel->snext != NULL) {
117 + selmon->altTabN++;
118 + if (selmon->altTabN >= selmon->nTabs)
119 + selmon->altTabN = 0; /* reset altTabN */
120 +
121 + focus(selmon->altsnext[selmon->altTabN]);
122 + restack(selmon);
123 + }
124 +
125 + /* redraw tab */
126 + XRaiseWindow(dpy, selmon->tabwin);
127 + drawTab(selmon->nTabs, 0, selmon);
128 +}
129 +
130 +void
131 +altTabEnd()
132 +{
133 + if (selmon->isAlt == 0)
134 + return;
135 +
136 + /*
137 + * move all clients between 1st and choosen position,
138 + * one down in stack and put choosen client to the first positio…
139 + * so they remain in right order for the next time that alt-tab …
140 + */
141 + if (selmon->nTabs > 1) {
142 + if (selmon->altTabN != 0) { /* if user picked original …
143 + Client *buff = selmon->altsnext[selmon->altTabN…
144 + if (selmon->altTabN > 1)
145 + for (int i = selmon->altTabN;i > 0;i--)
146 + selmon->altsnext[i] = selmon->a…
147 + else /* swap them if there are just 2 clients */
148 + selmon->altsnext[selmon->altTabN] = sel…
149 + selmon->altsnext[0] = buff;
150 + }
151 +
152 + /* restack clients */
153 + for (int i = selmon->nTabs - 1;i >= 0;i--) {
154 + focus(selmon->altsnext[i]);
155 + restack(selmon);
156 + }
157 +
158 + free(selmon->altsnext); /* free list of clients */
159 + }
160 +
161 + /* turn off/destroy the window */
162 + selmon->isAlt = 0;
163 + selmon->nTabs = 0;
164 + XUnmapWindow(dpy, selmon->tabwin);
165 + XDestroyWindow(dpy, selmon->tabwin);
166 +}
167 +
168 +void
169 +drawTab(int nwins, int first, Monitor *m)
170 +{
171 + /* little documentation of functions */
172 + /* void drw_rect(Drw *drw, int x, int y, unsigned int w, unsign…
173 + /* int drw_text(Drw *drw, int x, int y, unsigned int w, unsigne…
174 + /* void drw_map(Drw *drw, Window win, int x, int y, unsigned in…
175 +
176 + Client *c;
177 + int h;
178 +
179 + if (first) {
180 + Monitor *m = selmon;
181 + XSetWindowAttributes wa = {
182 + .override_redirect = True,
183 + .background_pixmap = ParentRelative,
184 + .event_mask = ButtonPressMask|ExposureMask
185 + };
186 +
187 + selmon->maxWTab = maxWTab;
188 + selmon->maxHTab = maxHTab;
189 +
190 + /* decide position of tabwin */
191 + int posX = selmon->mx;
192 + int posY = selmon->my;
193 + if (tabPosX == 0)
194 + posX += 0;
195 + if (tabPosX == 1)
196 + posX += (selmon->mw / 2) - (maxWTab / 2);
197 + if (tabPosX == 2)
198 + posX += selmon->mw - maxWTab;
199 +
200 + if (tabPosY == 0)
201 + posY += selmon->mh - maxHTab;
202 + if (tabPosY == 1)
203 + posY += (selmon->mh / 2) - (maxHTab / 2);
204 + if (tabPosY == 2)
205 + posY += 0;
206 +
207 + h = selmon->maxHTab;
208 + /* XCreateWindow(display, parent, x, y, width, height, …
209 + m->tabwin = XCreateWindow(dpy, root, posX, posY, selmon…
210 + CopyFro…
211 + CWOverr…
212 +
213 + XDefineCursor(dpy, m->tabwin, cursor[CurNormal]->cursor…
214 + XMapRaised(dpy, m->tabwin);
215 +
216 + }
217 +
218 + h = selmon->maxHTab / m->nTabs;
219 +
220 + int y = 0;
221 + int n = 0;
222 + for (int i = 0;i < m->nTabs;i++) { /* draw all clients into tab…
223 + c = m->altsnext[i];
224 + if(!ISVISIBLE(c)) continue;
225 + /* if (HIDDEN(c)) continue; uncomment if you're using a…
226 +
227 + n++;
228 + drw_setscheme(drw, scheme[(c == m->sel) ? SchemeSel : S…
229 + drw_text(drw, 0, y, selmon->maxWTab, h, 0, c->name, 0);
230 + y += h;
231 + }
232 +
233 + drw_setscheme(drw, scheme[SchemeNorm]);
234 + drw_map(drw, m->tabwin, 0, 0, selmon->maxWTab, selmon->maxHTab);
235 +}
236 +
237 +void
238 +altTabStart(const Arg *arg)
239 +{
240 + selmon->altsnext = NULL;
241 + if (selmon->tabwin)
242 + altTabEnd();
243 +
244 + if (selmon->isAlt == 1) {
245 + altTabEnd();
246 + } else {
247 + selmon->isAlt = 1;
248 + selmon->altTabN = 0;
249 +
250 + Client *c;
251 + Monitor *m = selmon;
252 +
253 + m->nTabs = 0;
254 + for(c = m->clients; c; c = c->next) { /* count clients …
255 + if(!ISVISIBLE(c)) continue;
256 + /* if (HIDDEN(c)) continue; uncomment if you're…
257 +
258 + ++m->nTabs;
259 + }
260 +
261 + if (m->nTabs > 0) {
262 + m->altsnext = (Client **) malloc(m->nTabs * siz…
263 +
264 + int listIndex = 0;
265 + for(c = m->stack; c; c = c->snext) { /* add cli…
266 + if(!ISVISIBLE(c)) continue;
267 + /* if (HIDDEN(c)) continue; uncomment i…
268 +
269 + m->altsnext[listIndex++] = c;
270 + }
271 +
272 + drawTab(m->nTabs, 1, m);
273 +
274 + struct timespec ts = { .tv_sec = 0, .tv_nsec = …
275 +
276 + /* grab keyboard (take all input from keyboard)…
277 + int grabbed = 1;
278 + for (int i = 0;i < 1000;i++) {
279 + if (XGrabKeyboard(dpy, DefaultRootWindo…
280 + break;
281 + nanosleep(&ts, NULL);
282 + if (i == 1000 - 1)
283 + grabbed = 0;
284 + }
285 +
286 + XEvent event;
287 + altTab();
288 + if (grabbed == 0) {
289 + altTabEnd();
290 + } else {
291 + while (grabbed) {
292 + XNextEvent(dpy, &event);
293 + if (event.type == KeyPress || e…
294 + if (event.type == KeyRe…
295 + break;
296 + } else if (event.type =…
297 + if (event.xkey.…
298 + altTab(…
299 + }
300 + }
301 + }
302 + }
303 +
304 + c = selmon->sel;
305 + altTabEnd(); /* end the alt-tab functio…
306 + /* XUngrabKeyboard(display, time); just…
307 + XUngrabKeyboard(dpy, CurrentTime); /* s…
308 + focus(c);
309 + restack(selmon);
310 + }
311 + } else {
312 + altTabEnd(); /* end the alt-tab functionality */
313 + }
314 + }
315 +}
316 +
317 void
318 tag(const Arg *arg)
319 {
320 --
321 2.37.3
322
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.