Introduction
Introduction Statistics Contact Development Disclaimer Help
dwm-tab-i3like-20211121-a786211.diff - sites - public wiki contents of suckless…
git clone git://git.suckless.org/sites
Log
Files
Refs
---
dwm-tab-i3like-20211121-a786211.diff (14158B)
---
1 From 5e489a57cdce6517996df26808b58bdd32bbd99f Mon Sep 17 00:00:00 2001
2 From: howoz <[email protected]>
3 Date: Sun, 21 Nov 2021 16:23:04 +0300
4 Subject: [PATCH] [dwm][patches][tab] i3 like tabs that cover the whole s…
5 width
6
7 ---
8 config.def.h | 9 +++
9 dwm.1 | 33 ++++++++---
10 dwm.c | 160 +++++++++++++++++++++++++++++++++++++++++++++++----
11 3 files changed, 183 insertions(+), 19 deletions(-)
12
13 diff --git a/config.def.h b/config.def.h
14 index a2ac963..931d7ae 100644
15 --- a/config.def.h
16 +++ b/config.def.h
17 @@ -5,6 +5,13 @@ static const unsigned int borderpx = 1; /* bord…
18 static const unsigned int snap = 32; /* snap pixel */
19 static const int showbar = 1; /* 0 means no bar */
20 static const int topbar = 1; /* 0 means bottom bar */
21 +/* Display modes of the tab bar: never shown, always shown, shown only…
22 +/* monocle mode in the presence of several windows. …
23 +/* Modes after showtab_nmodes are disabled. …
24 +enum showtab_modes { showtab_never, showtab_auto, showtab_nmodes, showt…
25 +static const int showtab = showtab_auto; …
26 +static const int toptab = False; …
27 +
28 static const char *fonts[] = { "monospace:size=10" };
29 static const char dmenufont[] = "monospace:size=10";
30 static const char col_gray1[] = "#222222";
31 @@ -65,6 +72,7 @@ static Key keys[] = {
32 { MODKEY, XK_p, spawn, {.v …
33 { MODKEY|ShiftMask, XK_Return, spawn, {.v …
34 { MODKEY, XK_b, togglebar, {0} …
35 + { MODKEY, XK_w, tabmode, {-1}…
36 { MODKEY, XK_j, focusstack, {.i …
37 { MODKEY, XK_k, focusstack, {.i …
38 { MODKEY, XK_i, incnmaster, {.i …
39 @@ -112,5 +120,6 @@ static Button buttons[] = {
40 { ClkTagBar, 0, Button3, togglev…
41 { ClkTagBar, MODKEY, Button1, tag, …
42 { ClkTagBar, MODKEY, Button3, togglet…
43 + { ClkTabBar, 0, Button1, focuswi…
44 };
45
46 diff --git a/dwm.1 b/dwm.1
47 index ddc8321..7752444 100644
48 --- a/dwm.1
49 +++ b/dwm.1
50 @@ -20,14 +20,22 @@ layout applied.
51 Windows are grouped by tags. Each window can be tagged with one or mult…
52 tags. Selecting certain tags displays all windows with these tags.
53 .P
54 -Each screen contains a small status bar which displays all available ta…
55 -layout, the title of the focused window, and the text read from the roo…
56 -name property, if the screen is focused. A floating window is indicated…
57 -empty square and a maximised floating window is indicated with a filled…
58 -before the windows title. The selected tags are indicated with a diffe…
59 -color. The tags of the focused window are indicated with a filled squar…
60 -top left corner. The tags which are applied to one or more windows are
61 -indicated with an empty square in the top left corner.
62 +Each screen contains two small status bars.
63 +.P
64 +One bar displays all available tags, the layout, the title of the focus…
65 +window, and the text read from the root window name property, if the sc…
66 +focused. A floating window is indicated with an empty square and a maxi…
67 +floating window is indicated with a filled square before the windows ti…
68 +selected tags are indicated with a different color. The tags of the foc…
69 +window are indicated with a filled square in the top left corner. The …
70 +which are applied to one or more windows are indicated with an empty sq…
71 +the top left corner.
72 +.P
73 +Another bar contains a tab for each window of the current view and allo…
74 +navigation between windows, especially in the monocle mode. The differe…
75 +display modes of this bar are described under the Mod1\-w Keybord comma…
76 +section. When a single tag is selected, this tag is indicated in the l…
77 +of the tab bar.
78 .P
79 dwm draws a small border around windows to indicate the focus state.
80 .SH OPTIONS
81 @@ -44,7 +52,8 @@ command.
82 .TP
83 .B Button1
84 click on a tag label to display all windows with that tag, click on the…
85 -label toggles between tiled and floating layout.
86 +label toggles between tiled and floating layout, click on a window name…
87 +tab bar brings focus to that window.
88 .TP
89 .B Button3
90 click on a tag label adds/removes all windows with that tag to/from the…
91 @@ -110,6 +119,12 @@ Increase master area size.
92 .B Mod1\-h
93 Decrease master area size.
94 .TP
95 +.B Mod1\-w
96 +Cycle over the tab bar display modes: never displayed, always displayed,
97 +displayed only in monocle mode when the view contains more than one win…
98 +mode). Some display modes can be disabled in the configuration, config.…
99 +the default configuration only "never" and "auto" display modes are ena…
100 +.TP
101 .B Mod1\-Return
102 Zooms/cycles focused window to/from master area (tiled layouts only).
103 .TP
104 diff --git a/dwm.c b/dwm.c
105 index 5e4d494..8404747 100644
106 --- a/dwm.c
107 +++ b/dwm.c
108 @@ -64,7 +64,7 @@ enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
109 NetWMFullscreen, NetActiveWindow, NetWMWindowType,
110 NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
111 enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* defaul…
112 -enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
113 +enum { ClkTagBar, ClkTabBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
114 ClkClientWin, ClkRootWin, ClkLast }; /* clicks */
115
116 typedef union {
117 @@ -111,24 +111,32 @@ typedef struct {
118 void (*arrange)(Monitor *);
119 } Layout;
120
121 +#define MAXTABS 50
122 +
123 struct Monitor {
124 char ltsymbol[16];
125 float mfact;
126 int nmaster;
127 int num;
128 int by; /* bar geometry */
129 + int ty; /* tab bar geometry */
130 int mx, my, mw, mh; /* screen size */
131 int wx, wy, ww, wh; /* window area */
132 unsigned int seltags;
133 unsigned int sellt;
134 unsigned int tagset[2];
135 int showbar;
136 + int showtab;
137 int topbar;
138 + int toptab;
139 Client *clients;
140 Client *sel;
141 Client *stack;
142 Monitor *next;
143 Window barwin;
144 + Window tabwin;
145 + int ntabs;
146 + int tab_widths[MAXTABS];
147 const Layout *lt[2];
148 };
149
150 @@ -169,6 +177,7 @@ static void focus(Client *c);
151 static void focusin(XEvent *e);
152 static void focusmon(const Arg *arg);
153 static void focusstack(const Arg *arg);
154 +static void focuswin(const Arg* arg);
155 static Atom getatomprop(Client *c, Atom prop);
156 static int getrootptr(int *x, int *y);
157 static long getstate(Window w);
158 @@ -207,6 +216,7 @@ static void seturgent(Client *c, int urg);
159 static void showhide(Client *c);
160 static void sigchld(int unused);
161 static void spawn(const Arg *arg);
162 +static void tabmode(const Arg *arg);
163 static void tag(const Arg *arg);
164 static void tagmon(const Arg *arg);
165 static void tile(Monitor *);
166 @@ -241,6 +251,7 @@ static char stext[256];
167 static int screen;
168 static int sw, sh; /* X display screen geometry width, height…
169 static int bh, blw = 0; /* bar geometry */
170 +static int th = 0; /* tab bar geometry */
171 static int lrpad; /* sum of left and right padding for text …
172 static int (*xerrorxlib)(Display *, XErrorEvent *);
173 static unsigned int numlockmask = 0;
174 @@ -393,8 +404,9 @@ arrange(Monitor *m)
175 }
176
177 void
178 -arrangemon(Monitor *m)
179 -{
180 +arrangemon(Monitor *m) {
181 + updatebarpos(m);
182 + XMoveResizeWindow(dpy, m->tabwin, m->wx, m->ty, m->ww, th);
183 strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, sizeof m->ltsymbo…
184 if (m->lt[m->sellt]->arrange)
185 m->lt[m->sellt]->arrange(m);
186 @@ -444,7 +456,24 @@ buttonpress(XEvent *e)
187 click = ClkStatusText;
188 else
189 click = ClkWinTitle;
190 - } else if ((c = wintoclient(ev->window))) {
191 + }
192 + if(ev->window == selmon->tabwin) {
193 + i = 0; x = 0;
194 + for(c = selmon->clients; c; c = c->next){
195 + if(!ISVISIBLE(c)) continue;
196 + x += selmon->tab_widths[i];
197 + if (ev->x > x)
198 + ++i;
199 + else
200 + break;
201 + if(i >= m->ntabs) break;
202 + }
203 + if(c) {
204 + click = ClkTabBar;
205 + arg.ui = i;
206 + }
207 + }
208 + else if((c = wintoclient(ev->window))) {
209 focus(c);
210 restack(selmon);
211 XAllowEvents(dpy, ReplayPointer, CurrentTime);
212 @@ -452,8 +481,9 @@ buttonpress(XEvent *e)
213 }
214 for (i = 0; i < LENGTH(buttons); i++)
215 if (click == buttons[i].click && buttons[i].func && but…
216 - && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state))
217 - buttons[i].func(click == ClkTagBar && buttons[i…
218 + && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)){
219 + buttons[i].func(((click == ClkTagBar || click =…
220 + }
221 }
222
223 void
224 @@ -507,6 +537,8 @@ cleanupmon(Monitor *mon)
225 }
226 XUnmapWindow(dpy, mon->barwin);
227 XDestroyWindow(dpy, mon->barwin);
228 + XUnmapWindow(dpy, mon->tabwin);
229 + XDestroyWindow(dpy, mon->tabwin);
230 free(mon);
231 }
232
233 @@ -638,7 +670,10 @@ createmon(void)
234 m->mfact = mfact;
235 m->nmaster = nmaster;
236 m->showbar = showbar;
237 + m->showtab = showtab;
238 m->topbar = topbar;
239 + m->toptab = toptab;
240 + m->ntabs = 0;
241 m->lt[0] = &layouts[0];
242 m->lt[1] = &layouts[1 % LENGTH(layouts)];
243 strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
244 @@ -752,6 +787,56 @@ drawbars(void)
245 drawbar(m);
246 }
247
248 +void
249 +drawtabs(void) {
250 + Monitor *m;
251 +
252 + for(m = mons; m; m = m->next)
253 + drawtab(m);
254 +}
255 +
256 +void
257 +drawtab(Monitor *m) {
258 + Client *c;
259 + int i;
260 + int maxsize;
261 + int remainder = 0;
262 + int x = 0;
263 + int w = 0;
264 +
265 + /* Calculates number of labels and their width */
266 + m->ntabs = 0;
267 + for(c = m->clients; c; c = c->next){
268 + if(!ISVISIBLE(c)) continue;
269 + m->tab_widths[m->ntabs] = (int)TEXTW(c->name);
270 + ++m->ntabs;
271 + if(m->ntabs >= MAXTABS) break;
272 + }
273 +
274 + if(m->ntabs > 0) remainder = m->mw % m->ntabs;
275 + maxsize = (1.0 / (double)m->ntabs) * m->mw;
276 +
277 + i = 0;
278 + int tm; /* middle of the tab*/
279 + for(c = m->clients; c; c = c->next){
280 + if(!ISVISIBLE(c)) continue;
281 + if(i >= m->ntabs) break;
282 + m->tab_widths[i] = maxsize;
283 + /* add the remainder to the last tab so there is no leftover …
284 + if(remainder && i == m->ntabs - 1) m->tab_widths[i] += remain…
285 + w = m->tab_widths[i];
286 + drw_setscheme(drw, scheme[(c == m->sel) ? SchemeSel : SchemeN…
287 + tm = (m->tab_widths[i] - (int)TEXTW(c->name)) / 2;
288 + tm = (int)TEXTW(c->name) >= m->tab_widths[i] ? lrpad / 2 : tm;
289 + drw_text(drw, x, 0, w, th, tm, c->name, 0);
290 + x += w;
291 + ++i;
292 + }
293 +
294 + drw_setscheme(drw, scheme[SchemeNorm]);
295 + drw_map(drw, m->tabwin, 0, 0, m->mw, th);
296 +}
297 +
298 void
299 enternotify(XEvent *e)
300 {
301 @@ -777,8 +862,10 @@ expose(XEvent *e)
302 Monitor *m;
303 XExposeEvent *ev = &e->xexpose;
304
305 - if (ev->count == 0 && (m = wintomon(ev->window)))
306 + if(ev->count == 0 && (m = wintomon(ev->window))){
307 drawbar(m);
308 + drawtab(m);
309 + }
310 }
311
312 void
313 @@ -804,6 +891,7 @@ focus(Client *c)
314 }
315 selmon->sel = c;
316 drawbars();
317 + drawtabs();
318 }
319
320 /* there are some broken focus acquiring clients needing extra handling…
321 @@ -856,6 +944,19 @@ focusstack(const Arg *arg)
322 }
323 }
324
325 +void
326 +focuswin(const Arg* arg){
327 + int iwin = arg->i;
328 + Client* c = NULL;
329 + for(c = selmon->clients; c && (iwin || !ISVISIBLE(c)) ; c = c->next){
330 + if(ISVISIBLE(c)) --iwin;
331 + };
332 + if(c) {
333 + focus(c);
334 + restack(selmon);
335 + }
336 +}
337 +
338 Atom
339 getatomprop(Client *c, Atom prop)
340 {
341 @@ -1234,12 +1335,14 @@ propertynotify(XEvent *e)
342 case XA_WM_HINTS:
343 updatewmhints(c);
344 drawbars();
345 + drawtabs();
346 break;
347 }
348 if (ev->atom == XA_WM_NAME || ev->atom == netatom[NetWM…
349 updatetitle(c);
350 if (c == c->mon->sel)
351 drawbar(c->mon);
352 + drawtab(c->mon);
353 }
354 if (ev->atom == netatom[NetWMWindowType])
355 updatewindowtype(c);
356 @@ -1353,6 +1456,7 @@ restack(Monitor *m)
357 XWindowChanges wc;
358
359 drawbar(m);
360 + drawtab(m);
361 if (!m->sel)
362 return;
363 if (m->sel->isfloating || !m->lt[m->sellt]->arrange)
364 @@ -1547,6 +1651,7 @@ setup(void)
365 die("no fonts could be loaded.");
366 lrpad = drw->fonts->h;
367 bh = drw->fonts->h + 2;
368 + th = bh;
369 updategeom();
370 /* init atoms */
371 utf8string = XInternAtom(dpy, "UTF8_STRING", False);
372 @@ -1708,6 +1813,17 @@ togglebar(const Arg *arg)
373 arrange(selmon);
374 }
375
376 +void
377 +tabmode(const Arg *arg)
378 +{
379 + if(arg && arg->i >= 0)
380 + selmon->showtab = arg->ui % showtab_nmodes;
381 + else
382 + selmon->showtab = (selmon->showtab + 1 ) % showtab_nmod…
383 + arrange(selmon);
384 +}
385 +
386 +
387 void
388 togglefloating(const Arg *arg)
389 {
390 @@ -1819,6 +1935,11 @@ updatebars(void)
391 CWOverrideRedirect|CWBackPixmap|CWEvent…
392 XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor…
393 XMapRaised(dpy, m->barwin);
394 + m->tabwin = XCreateWindow(dpy, root, m->wx, m->ty, m->w…
395 + CopyFromParent, Default…
396 + CWOverrideRedirect|CWBa…
397 + XDefineCursor(dpy, m->tabwin, cursor[CurNormal]->cursor…
398 + XMapRaised(dpy, m->tabwin);
399 XSetClassHint(dpy, m->barwin, &ch);
400 }
401 }
402 @@ -1826,14 +1947,33 @@ updatebars(void)
403 void
404 updatebarpos(Monitor *m)
405 {
406 + Client *c;
407 + int nvis = 0;
408 +
409 m->wy = m->my;
410 m->wh = m->mh;
411 if (m->showbar) {
412 m->wh -= bh;
413 m->by = m->topbar ? m->wy : m->wy + m->wh;
414 - m->wy = m->topbar ? m->wy + bh : m->wy;
415 - } else
416 + if ( m->topbar )
417 + m->wy += bh;
418 + } else {
419 m->by = -bh;
420 + }
421 +
422 + for(c = m->clients; c; c = c->next) {
423 + if(ISVISIBLE(c)) ++nvis;
424 + }
425 +
426 + if(m->showtab == showtab_always
427 + || ((m->showtab == showtab_auto) && (nvis > 1) && (m->lt[m->…
428 + m->wh -= th;
429 + m->ty = m->toptab ? m->wy : m->wy + m->wh;
430 + if ( m->toptab )
431 + m->wy += th;
432 + } else {
433 + m->ty = -th;
434 + }
435 }
436
437 void
438 @@ -2070,7 +2210,7 @@ wintomon(Window w)
439 if (w == root && getrootptr(&x, &y))
440 return recttomon(x, y, 1, 1);
441 for (m = mons; m; m = m->next)
442 - if (w == m->barwin)
443 + if (w == m->barwin || w == m->tabwin)
444 return m;
445 if ((c = wintoclient(w)))
446 return c->mon;
447 --
448 2.34.0
449
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.