Introduction
Introduction Statistics Contact Development Disclaimer Help
dwm-tab-v2b-pertab-56a31dc.diff - sites - public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log
Files
Refs
---
dwm-tab-v2b-pertab-56a31dc.diff (26011B)
---
1 diff --git a/config.def.h b/config.def.h
2 index fd77a07..8cc91c0 100644
3 --- a/config.def.h
4 +++ b/config.def.h
5 @@ -5,6 +5,14 @@ static const unsigned int borderpx = 1; /* bord…
6 static const unsigned int snap = 32; /* snap pixel */
7 static const int showbar = 1; /* 0 means no bar */
8 static const int topbar = 1; /* 0 means bottom bar */
9 +
10 +/* Display modes of the tab bar: never shown, always shown, shown onl…
11 +/* monocle mode in presence of several windows. …
12 +/* Modes after showtab_nmodes are disabled …
13 +enum showtab_modes { showtab_never, showtab_auto, showtab_nmodes, showt…
14 +static const int showtab = showtab_auto; /* Default tab bar …
15 +static const Bool toptab = False; /* False means bottom t…
16 +
17 static const char *fonts[] = { "monospace:size=10" };
18 static const char dmenufont[] = "monospace:size=10";
19 static const char col_gray1[] = "#222222";
20 @@ -18,9 +26,15 @@ static const char *colors[SchemeLast][3] = {
21 [SchemeSel] = { col_gray4, col_cyan, col_cyan },
22 };
23
24 +
25 /* tagging */
26 static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "…
27
28 +/* default layout per tags */
29 +/* The first element is for all-tag view, following i-th element corres…
30 +/* tags[i]. Layout is referred using the layouts array index.*/
31 +static int def_layouts[1 + LENGTH(tags)] = { 0, 0, 0, 0, 0, 0, 0, 0, 0…
32 +
33 static const Rule rules[] = {
34 /* xprop(1):
35 * WM_CLASS(STRING) = instance, class
36 @@ -64,6 +78,7 @@ static Key keys[] = {
37 { MODKEY, XK_p, spawn, {.v …
38 { MODKEY|ShiftMask, XK_Return, spawn, {.v …
39 { MODKEY, XK_b, togglebar, {0} …
40 + { MODKEY, XK_w, tabmode, {-1}…
41 { MODKEY, XK_j, focusstack, {.i …
42 { MODKEY, XK_k, focusstack, {.i …
43 { MODKEY, XK_i, incnmaster, {.i …
44 @@ -111,5 +126,6 @@ static Button buttons[] = {
45 { ClkTagBar, 0, Button3, togglev…
46 { ClkTagBar, MODKEY, Button1, tag, …
47 { ClkTagBar, MODKEY, Button3, togglet…
48 + { ClkTabBar, 0, Button1, focuswi…
49 };
50
51 diff --git a/dwm.1 b/dwm.1
52 index 6687011..077d92b 100644
53 --- a/dwm.1
54 +++ b/dwm.1
55 @@ -19,14 +19,22 @@ layout applied.
56 Windows are grouped by tags. Each window can be tagged with one or mult…
57 tags. Selecting certain tags displays all windows with these tags.
58 .P
59 -Each screen contains a small status bar which displays all available ta…
60 -layout, the title of the focused window, and the text read from the roo…
61 -name property, if the screen is focused. A floating window is indicated…
62 -empty square and a maximised floating window is indicated with a filled…
63 -before the windows title. The selected tags are indicated with a diffe…
64 -color. The tags of the focused window are indicated with a filled squar…
65 -top left corner. The tags which are applied to one or more windows are
66 -indicated with an empty square in the top left corner.
67 +Each screen contains two small status bars.
68 +.P
69 +One bar displays all available tags, the layout, the title of the focus…
70 +window, and the text read from the root window name property, if the sc…
71 +focused. A floating window is indicated with an empty square and a maxi…
72 +floating window is indicated with a filled square before the windows ti…
73 +selected tags are indicated with a different color. The tags of the foc…
74 +window are indicated with a filled square in the top left corner. The …
75 +which are applied to one or more windows are indicated with an empty sq…
76 +the top left corner.
77 +.P
78 +Another bar contains a tab for each window of the current view and allo…
79 +navigation between windows, especially in the monocle mode. The differe…
80 +display modes of this bar are described under the Mod1\-w Keybord comma…
81 +section. When a single tag is selected, that tag is indicated in the l…
82 +of the tab bar.
83 .P
84 dwm draws a small border around windows to indicate the focus state.
85 .SH OPTIONS
86 @@ -43,7 +51,8 @@ command.
87 .TP
88 .B Button1
89 click on a tag label to display all windows with that tag, click on the…
90 -label toggles between tiled and floating layout.
91 +label toggles between tiled and floating layout, click on a window name…
92 +tab bar brings focus to that window.
93 .TP
94 .B Button3
95 click on a tag label adds/removes all windows with that tag to/from the…
96 @@ -104,6 +113,12 @@ Increase master area size.
97 .B Mod1\-h
98 Decrease master area size.
99 .TP
100 +.B Mod1\-w
101 +Cycle over the tab bar display modes: never displayed, always displayed,
102 +displayed only in monocle mode when the view contains than one window (…
103 +mode). Some display modes can be disabled in the configuration, config.…
104 +the default configuration only "never" and "auto" display modes are ena…
105 +.TP
106 .B Mod1\-Return
107 Zooms/cycles focused window to/from master area (tiled layouts only).
108 .TP
109 diff --git a/dwm.c b/dwm.c
110 index b2bc9bd..0c34020 100644
111 --- a/dwm.c
112 +++ b/dwm.c
113 @@ -65,7 +65,7 @@ enum { NetSupported, NetWMName, NetWMState,
114 NetWMFullscreen, NetActiveWindow, NetWMWindowType,
115 NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
116 enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* defaul…
117 -enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
118 +enum { ClkTagBar, ClkTabBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
119 ClkClientWin, ClkRootWin, ClkLast }; /* clicks */
120
121 typedef union {
122 @@ -112,25 +112,35 @@ typedef struct {
123 void (*arrange)(Monitor *);
124 } Layout;
125
126 +#define MAXTABS 50
127 +
128 +typedef struct Pertag Pertag;
129 struct Monitor {
130 char ltsymbol[16];
131 float mfact;
132 int nmaster;
133 int num;
134 int by; /* bar geometry */
135 + int ty; /* tab bar geometry */
136 int mx, my, mw, mh; /* screen size */
137 int wx, wy, ww, wh; /* window area */
138 unsigned int seltags;
139 unsigned int sellt;
140 unsigned int tagset[2];
141 int showbar;
142 + int showtab;
143 int topbar;
144 + int toptab;
145 Client *clients;
146 Client *sel;
147 Client *stack;
148 Monitor *next;
149 Window barwin;
150 + Window tabwin;
151 + int ntabs;
152 + int tab_widths[MAXTABS];
153 const Layout *lt[2];
154 + Pertag *pertag;
155 };
156
157 typedef struct {
158 @@ -165,12 +175,15 @@ static void detachstack(Client *c);
159 static Monitor *dirtomon(int dir);
160 static void drawbar(Monitor *m);
161 static void drawbars(void);
162 +static void drawtab(Monitor *m);
163 +static void drawtabs(void);
164 static void enternotify(XEvent *e);
165 static void expose(XEvent *e);
166 static void focus(Client *c);
167 static void focusin(XEvent *e);
168 static void focusmon(const Arg *arg);
169 static void focusstack(const Arg *arg);
170 +static void focuswin(const Arg* arg);
171 static int getrootptr(int *x, int *y);
172 static long getstate(Window w);
173 static int gettextprop(Window w, Atom atom, char *text, unsigned int si…
174 @@ -207,6 +220,7 @@ static void setup(void);
175 static void showhide(Client *c);
176 static void sigchld(int unused);
177 static void spawn(const Arg *arg);
178 +static void tabmode(const Arg *arg);
179 static void tag(const Arg *arg);
180 static void tagmon(const Arg *arg);
181 static void tile(Monitor *);
182 @@ -241,6 +255,7 @@ static char stext[256];
183 static int screen;
184 static int sw, sh; /* X display screen geometry width, height…
185 static int bh, blw = 0; /* bar geometry */
186 +static int th = 0; /* tab bar geometry */
187 static int lrpad; /* sum of left and right padding for text …
188 static int (*xerrorxlib)(Display *, XErrorEvent *);
189 static unsigned int numlockmask = 0;
190 @@ -272,6 +287,16 @@ static Window root;
191 /* configuration, allows nested code to access above variables */
192 #include "config.h"
193
194 +struct Pertag {
195 + unsigned int curtag, prevtag; /* current and previous tag */
196 + int nmasters[LENGTH(tags) + 1]; /* number of windows in master …
197 + float mfacts[LENGTH(tags) + 1]; /* mfacts per tag */
198 + unsigned int sellts[LENGTH(tags) + 1]; /* selected layouts */
199 + const Layout *ltidxs[LENGTH(tags) + 1][2]; /* matrix of tags an…
200 + Bool showbars[LENGTH(tags) + 1]; /* display bar for the current…
201 + Client *prevzooms[LENGTH(tags) + 1]; /* store zoom information …
202 +};
203 +
204 /* compile-time check if all tags fit into an unsigned int bit array. */
205 struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; };
206
207 @@ -395,6 +420,8 @@ arrange(Monitor *m)
208 void
209 arrangemon(Monitor *m)
210 {
211 + updatebarpos(m);
212 + XMoveResizeWindow(dpy, m->tabwin, m->wx, m->ty, m->ww, th);
213 strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, sizeof m->ltsymbo…
214 if (m->lt[m->sellt]->arrange)
215 m->lt[m->sellt]->arrange(m);
216 @@ -444,14 +471,33 @@ buttonpress(XEvent *e)
217 click = ClkStatusText;
218 else
219 click = ClkWinTitle;
220 - } else if ((c = wintoclient(ev->window))) {
221 + }
222 + if(ev->window == selmon->tabwin) {
223 + i = 0; x = 0;
224 + for(c = selmon->clients; c; c = c->next){
225 + if(!ISVISIBLE(c)) continue;
226 + x += selmon->tab_widths[i];
227 + if (ev->x > x)
228 + ++i;
229 + else
230 + break;
231 + if(i >= m->ntabs) break;
232 + }
233 + if(c) {
234 + click = ClkTabBar;
235 + arg.ui = i;
236 + }
237 + }
238 + else if((c = wintoclient(ev->window))) {
239 focus(c);
240 click = ClkClientWin;
241 }
242 - for (i = 0; i < LENGTH(buttons); i++)
243 - if (click == buttons[i].click && buttons[i].func && but…
244 - && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state))
245 - buttons[i].func(click == ClkTagBar && buttons[i…
246 + for(i = 0; i < LENGTH(buttons); i++)
247 + if(click == buttons[i].click && buttons[i].func && butt…
248 + && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state…
249 + buttons[i].func(((click == ClkTagBar || click == ClkT…
250 + && buttons[i].arg.i == 0) ? &arg : &…
251 + }
252 }
253
254 void
255 @@ -476,8 +522,8 @@ cleanup(void)
256 view(&a);
257 selmon->lt[selmon->sellt] = &foo;
258 for (m = mons; m; m = m->next)
259 - while (m->stack)
260 - unmanage(m->stack, 0);
261 + while(m->stack)
262 + unmanage(m->stack, False);
263 XUngrabKey(dpy, AnyKey, AnyModifier, root);
264 while (mons)
265 cleanupmon(mons);
266 @@ -504,6 +550,8 @@ cleanupmon(Monitor *mon)
267 }
268 XUnmapWindow(dpy, mon->barwin);
269 XDestroyWindow(dpy, mon->barwin);
270 + XUnmapWindow(dpy, mon->tabwin);
271 + XDestroyWindow(dpy, mon->tabwin);
272 free(mon);
273 }
274
275 @@ -525,6 +573,7 @@ clientmessage(XEvent *e)
276 {
277 XClientMessageEvent *cme = &e->xclient;
278 Client *c = wintoclient(cme->window);
279 + int i;
280
281 if (!c)
282 return;
283 @@ -536,6 +585,8 @@ clientmessage(XEvent *e)
284 if (!ISVISIBLE(c)) {
285 c->mon->seltags ^= 1;
286 c->mon->tagset[c->mon->seltags] = c->tags;
287 + for(i=0; !(c->tags & 1 << i); i++);
288 + view(&(Arg){.ui = 1 << i});
289 }
290 pop(c);
291 }
292 @@ -564,11 +615,10 @@ void
293 configurenotify(XEvent *e)
294 {
295 Monitor *m;
296 - Client *c;
297 XConfigureEvent *ev = &e->xconfigure;
298 int dirty;
299
300 - /* TODO: updategeom handling sucks, needs to be simplified */
301 + // TODO: updategeom handling sucks, needs to be simplified
302 if (ev->window == root) {
303 dirty = (sw != ev->width || sh != ev->height);
304 sw = ev->width;
305 @@ -576,10 +626,9 @@ configurenotify(XEvent *e)
306 if (updategeom() || dirty) {
307 drw_resize(drw, sw, bh);
308 updatebars();
309 - for (m = mons; m; m = m->next) {
310 - for (c = m->clients; c; c = c->next)
311 - if (c->isfullscreen)
312 - resizeclient(c, m->mx, …
313 + //refreshing display of status bar. The tab bar…
314 + //method, which is called below
315 + for (m = mons; m; m = m->next){
316 XMoveResizeWindow(dpy, m->barwin, m->wx…
317 }
318 focus(NULL);
319 @@ -644,16 +693,41 @@ Monitor *
320 createmon(void)
321 {
322 Monitor *m;
323 + int i;
324
325 m = ecalloc(1, sizeof(Monitor));
326 m->tagset[0] = m->tagset[1] = 1;
327 m->mfact = mfact;
328 m->nmaster = nmaster;
329 m->showbar = showbar;
330 + m->showtab = showtab;
331 m->topbar = topbar;
332 - m->lt[0] = &layouts[0];
333 + m->toptab = toptab;
334 + m->ntabs = 0;
335 + m->lt[0] = &layouts[def_layouts[1] % LENGTH(layouts)];
336 m->lt[1] = &layouts[1 % LENGTH(layouts)];
337 strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
338 + if(!(m->pertag = (Pertag *)calloc(1, sizeof(Pertag))))
339 + die("fatal: could not malloc() %u bytes\n", sizeof(Pert…
340 + m->pertag->curtag = m->pertag->prevtag = 1;
341 + for(i=0; i <= LENGTH(tags); i++) {
342 + /* init nmaster */
343 + m->pertag->nmasters[i] = m->nmaster;
344 +
345 + /* init mfacts */
346 + m->pertag->mfacts[i] = m->mfact;
347 +
348 + /* init layouts */
349 + m->pertag->ltidxs[i][0] = &layouts[def_layouts[i % LENG…
350 + m->pertag->ltidxs[i][1] = m->lt[1];
351 + m->pertag->sellts[i] = m->sellt;
352 +
353 + /* init showbar */
354 + m->pertag->showbars[i] = m->showbar;
355 +
356 + /* swap focus and zoomswap*/
357 + m->pertag->prevzooms[i] = NULL;
358 + }
359 return m;
360 }
361
362 @@ -765,6 +839,104 @@ drawbars(void)
363 }
364
365 void
366 +drawtabs(void) {
367 + Monitor *m;
368 +
369 + for(m = mons; m; m = m->next)
370 + drawtab(m);
371 +}
372 +
373 +static int
374 +cmpint(const void *p1, const void *p2) {
375 + /* The actual arguments to this function are "pointers to
376 + pointers to char", but strcmp(3) arguments are "pointers
377 + to char", hence the following cast plus dereference */
378 + return *((int*) p1) > * (int*) p2;
379 +}
380 +
381 +
382 +void
383 +drawtab(Monitor *m) {
384 + Client *c;
385 + int i;
386 + int itag = -1;
387 + char view_info[50];
388 + int view_info_w = 0;
389 + int sorted_label_widths[MAXTABS];
390 + int tot_width;
391 + int maxsize = bh;
392 + int x = 0;
393 + int w = 0;
394 +
395 + //view_info: indicate the tag which is displayed in the view
396 + for(i = 0; i < LENGTH(tags); ++i){
397 + if((selmon->tagset[selmon->seltags] >> i) & 1) {
398 + if(itag >=0){ //more than one tag selected
399 + itag = -1;
400 + break;
401 + }
402 + itag = i;
403 + }
404 + }
405 + if(0 <= itag && itag < LENGTH(tags)){
406 + snprintf(view_info, sizeof view_info, "[%s]", tags[itag]);
407 + } else {
408 + strncpy(view_info, "[...]", sizeof view_info);
409 + }
410 + view_info[sizeof(view_info) - 1 ] = 0;
411 + view_info_w = TEXTW(view_info);
412 + tot_width = view_info_w;
413 +
414 + /* Calculates number of labels and their width */
415 + m->ntabs = 0;
416 + for(c = m->clients; c; c = c->next){
417 + if(!ISVISIBLE(c)) continue;
418 + m->tab_widths[m->ntabs] = TEXTW(c->name);
419 + tot_width += m->tab_widths[m->ntabs];
420 + ++m->ntabs;
421 + if(m->ntabs >= MAXTABS) break;
422 + }
423 +
424 + if(tot_width > m->ww){ //not enough space to display the labels…
425 + memcpy(sorted_label_widths, m->tab_widths, sizeof(int) * m->n…
426 + qsort(sorted_label_widths, m->ntabs, sizeof(int), cmpint);
427 + tot_width = view_info_w;
428 + for(i = 0; i < m->ntabs; ++i){
429 + if(tot_width + (m->ntabs - i) * sorted_label_widths[i] > m-…
430 + break;
431 + tot_width += sorted_label_widths[i];
432 + }
433 + maxsize = (m->ww - tot_width) / (m->ntabs - i);
434 + } else{
435 + maxsize = m->ww;
436 + }
437 + i = 0;
438 + for(c = m->clients; c; c = c->next){
439 + if(!ISVISIBLE(c)) continue;
440 + if(i >= m->ntabs) break;
441 + if(m->tab_widths[i] > maxsize) m->tab_widths[i] = maxsize;
442 + w = m->tab_widths[i];
443 + drw_setscheme(drw, (c == m->sel) ? scheme[SchemeSel] : scheme…
444 + drw_text(drw, x, 0, w, th, lrpad / 2, c->name, 0);
445 + x += w;
446 + ++i;
447 + }
448 +
449 + drw_setscheme(drw, scheme[SchemeNorm]);
450 +
451 + /* cleans interspace between window names and current viewed ta…
452 + w = m->ww - view_info_w - x;
453 + drw_text(drw, x, 0, w, th, lrpad / 2, "", 0);
454 +
455 + /* view info */
456 + x += w;
457 + w = view_info_w;
458 + drw_text(drw, x, 0, w, th, lrpad / 2, view_info, 0);
459 +
460 + drw_map(drw, m->tabwin, 0, 0, m->ww, th);
461 +}
462 +
463 +void
464 enternotify(XEvent *e)
465 {
466 Client *c;
467 @@ -789,8 +961,10 @@ expose(XEvent *e)
468 Monitor *m;
469 XExposeEvent *ev = &e->xexpose;
470
471 - if (ev->count == 0 && (m = wintomon(ev->window)))
472 + if (ev->count == 0 && (m = wintomon(ev->window))){
473 drawbar(m);
474 + drawtab(m);
475 + }
476 }
477
478 void
479 @@ -817,6 +991,7 @@ focus(Client *c)
480 }
481 selmon->sel = c;
482 drawbars();
483 + drawtabs();
484 }
485
486 /* there are some broken focus acquiring clients */
487 @@ -870,6 +1045,19 @@ focusstack(const Arg *arg)
488 }
489 }
490
491 +void
492 +focuswin(const Arg* arg){
493 + int iwin = arg->i;
494 + Client* c = NULL;
495 + for(c = selmon->clients; c && (iwin || !ISVISIBLE(c)) ; c = c->next){
496 + if(ISVISIBLE(c)) --iwin;
497 + };
498 + if(c) {
499 + focus(c);
500 + restack(selmon);
501 + }
502 +}
503 +
504 Atom
505 getatomprop(Client *c, Atom prop)
506 {
507 @@ -983,7 +1171,7 @@ grabkeys(void)
508 void
509 incnmaster(const Arg *arg)
510 {
511 - selmon->nmaster = MAX(selmon->nmaster + arg->i, 0);
512 + selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curt…
513 arrange(selmon);
514 }
515
516 @@ -1142,7 +1330,7 @@ motionnotify(XEvent *e)
517 if (ev->window != root)
518 return;
519 if ((m = recttomon(ev->x_root, ev->y_root, 1, 1)) != mon && mon…
520 - unfocus(selmon->sel, 1);
521 + unfocus(selmon->sel, True);
522 selmon = m;
523 focus(NULL);
524 }
525 @@ -1162,11 +1350,13 @@ movemouse(const Arg *arg)
526 return;
527 if (c->isfullscreen) /* no support moving fullscreen windows by…
528 return;
529 + if(c->isfullscreen) /* no support moving fullscreen windows by …
530 + return;
531 restack(selmon);
532 ocx = c->x;
533 ocy = c->y;
534 if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, Gr…
535 - None, cursor[CurMove]->cursor, CurrentTime) != GrabSuccess)
536 + None, cursor[CurMove]->cursor, CurrentTime) !=…
537 return;
538 if (!getrootptr(&x, &y))
539 return;
540 @@ -1253,12 +1443,14 @@ propertynotify(XEvent *e)
541 case XA_WM_HINTS:
542 updatewmhints(c);
543 drawbars();
544 + drawtabs();
545 break;
546 }
547 if (ev->atom == XA_WM_NAME || ev->atom == netatom[NetWM…
548 updatetitle(c);
549 if (c == c->mon->sel)
550 drawbar(c->mon);
551 + drawtab(c->mon);
552 }
553 if (ev->atom == netatom[NetWMWindowType])
554 updatewindowtype(c);
555 @@ -1320,11 +1512,13 @@ resizemouse(const Arg *arg)
556 return;
557 if (c->isfullscreen) /* no support resizing fullscreen windows …
558 return;
559 + if(c->isfullscreen) /* no support resizing fullscreen windows b…
560 + return;
561 restack(selmon);
562 ocx = c->x;
563 ocy = c->y;
564 if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, Gr…
565 - None, cursor[CurResize]->cursor, CurrentTime) !…
566 + None, cursor[CurResize]->cursor, CurrentTime) …
567 return;
568 XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c…
569 do {
570 @@ -1372,6 +1566,7 @@ restack(Monitor *m)
571 XWindowChanges wc;
572
573 drawbar(m);
574 + drawtab(m);
575 if (!m->sel)
576 return;
577 if (m->sel->isfloating || !m->lt[m->sellt]->arrange)
578 @@ -1480,11 +1675,11 @@ sendevent(Client *c, Atom proto)
579 void
580 setfocus(Client *c)
581 {
582 - if (!c->neverfocus) {
583 + if(!c->neverfocus) {
584 XSetInputFocus(dpy, c->win, RevertToPointerRoot, Curren…
585 XChangeProperty(dpy, root, netatom[NetActiveWindow],
586 - XA_WINDOW, 32, PropModeReplace,
587 - (unsigned char *) &(c->win), 1);
588 + XA_WINDOW, 32, PropModeReplace,
589 + (unsigned char *) &(c->win), 1);
590 }
591 sendevent(c, wmatom[WMTakeFocus]);
592 }
593 @@ -1520,10 +1715,13 @@ setfullscreen(Client *c, int fullscreen)
594 void
595 setlayout(const Arg *arg)
596 {
597 - if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt])
598 - selmon->sellt ^= 1;
599 - if (arg && arg->v)
600 - selmon->lt[selmon->sellt] = (Layout *)arg->v;
601 + if(!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) {
602 + selmon->pertag->sellts[selmon->pertag->curtag] ^= 1;
603 + selmon->sellt = selmon->pertag->sellts[selmon->pertag->…
604 + }
605 + if(arg && arg->v)
606 + selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->…
607 + selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pert…
608 strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, si…
609 if (selmon->sel)
610 arrange(selmon);
611 @@ -1542,7 +1740,7 @@ setmfact(const Arg *arg)
612 f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0;
613 if (f < 0.1 || f > 0.9)
614 return;
615 - selmon->mfact = f;
616 + selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag] …
617 arrange(selmon);
618 }
619
620 @@ -1564,6 +1762,7 @@ setup(void)
621 die("no fonts could be loaded.\n");
622 lrpad = drw->fonts->h;
623 bh = drw->fonts->h + 2;
624 + th = bh;
625 updategeom();
626 /* init atoms */
627 wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
628 @@ -1631,10 +1830,10 @@ sigchld(int unused)
629 void
630 spawn(const Arg *arg)
631 {
632 - if (arg->v == dmenucmd)
633 + if(arg->v == dmenucmd)
634 dmenumon[0] = '0' + selmon->num;
635 - if (fork() == 0) {
636 - if (dpy)
637 + if(fork() == 0) {
638 + if(dpy)
639 close(ConnectionNumber(dpy));
640 setsid();
641 execvp(((char **)arg->v)[0], (char **)arg->v);
642 @@ -1691,18 +1890,29 @@ tile(Monitor *m)
643 void
644 togglebar(const Arg *arg)
645 {
646 - selmon->showbar = !selmon->showbar;
647 + selmon->showbar = selmon->pertag->showbars[selmon->pertag->curt…
648 updatebarpos(selmon);
649 XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, …
650 arrange(selmon);
651 }
652
653 void
654 +tabmode(const Arg *arg)
655 +{
656 + if(arg && arg->i >= 0)
657 + selmon->showtab = arg->ui % showtab_nmodes;
658 + else
659 + selmon->showtab = (selmon->showtab + 1 ) % showtab_nmod…
660 + arrange(selmon);
661 +}
662 +
663 +
664 +void
665 togglefloating(const Arg *arg)
666 {
667 - if (!selmon->sel)
668 + if(!selmon->sel)
669 return;
670 - if (selmon->sel->isfullscreen) /* no support for fullscreen win…
671 + if(selmon->sel->isfullscreen) /* no support for fullscreen wind…
672 return;
673 selmon->sel->isfloating = !selmon->sel->isfloating || selmon->s…
674 if (selmon->sel->isfloating)
675 @@ -1730,9 +1940,29 @@ void
676 toggleview(const Arg *arg)
677 {
678 unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg…
679 + int i;
680
681 if (newtagset) {
682 + if(newtagset == ~0) {
683 + selmon->pertag->prevtag = selmon->pertag->curta…
684 + selmon->pertag->curtag = 0;
685 + }
686 + /* test if the user did not select the same tag */
687 + if(!(newtagset & 1 << (selmon->pertag->curtag - 1))) {
688 + selmon->pertag->prevtag = selmon->pertag->curta…
689 + for (i=0; !(newtagset & 1 << i); i++) ;
690 + selmon->pertag->curtag = i + 1;
691 + }
692 selmon->tagset[selmon->seltags] = newtagset;
693 +
694 + /* apply settings for this view */
695 + selmon->nmaster = selmon->pertag->nmasters[selmon->pert…
696 + selmon->mfact = selmon->pertag->mfacts[selmon->pertag->…
697 + selmon->sellt = selmon->pertag->sellts[selmon->pertag->…
698 + selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selm…
699 + selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[se…
700 + if (selmon->showbar != selmon->pertag->showbars[selmon-…
701 + togglebar(NULL);
702 focus(NULL);
703 arrange(selmon);
704 }
705 @@ -1808,20 +2038,44 @@ updatebars(void)
706 CWOverrideRedirect|CWBackPixm…
707 XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor…
708 XMapRaised(dpy, m->barwin);
709 + m->tabwin = XCreateWindow(dpy, root, m->wx, m->ty, m->w…
710 + CopyFromParent, DefaultVisual…
711 + CWOverrideRedirect|CWBackPixm…
712 + XDefineCursor(dpy, m->tabwin, cursor[CurNormal]->cursor…
713 + XMapRaised(dpy, m->tabwin);
714 }
715 }
716
717 void
718 updatebarpos(Monitor *m)
719 {
720 + Client *c;
721 + int nvis = 0;
722 +
723 m->wy = m->my;
724 m->wh = m->mh;
725 if (m->showbar) {
726 m->wh -= bh;
727 m->by = m->topbar ? m->wy : m->wy + m->wh;
728 - m->wy = m->topbar ? m->wy + bh : m->wy;
729 - } else
730 + if ( m->topbar )
731 + m->wy += bh;
732 + } else {
733 m->by = -bh;
734 + }
735 +
736 + for(c = m->clients; c; c = c->next){
737 + if(ISVISIBLE(c)) ++nvis;
738 + }
739 +
740 + if(m->showtab == showtab_always
741 + || ((m->showtab == showtab_auto) && (nvis > 1) && (m->lt[m->…
742 + m->wh -= th;
743 + m->ty = m->toptab ? m->wy : m->wy + m->wh;
744 + if ( m->toptab )
745 + m->wy += th;
746 + } else {
747 + m->ty = -th;
748 + }
749 }
750
751 void
752 @@ -2003,9 +2257,9 @@ updatewindowtype(Client *c)
753 Atom wtype = getatomprop(c, netatom[NetWMWindowType]);
754
755 if (state == netatom[NetWMFullscreen])
756 - setfullscreen(c, 1);
757 + setfullscreen(c, True);
758 if (wtype == netatom[NetWMWindowTypeDialog])
759 - c->isfloating = 1;
760 + c->isfloating = True;
761 }
762
763 void
764 @@ -2030,11 +2284,33 @@ updatewmhints(Client *c)
765 void
766 view(const Arg *arg)
767 {
768 - if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags])
769 + int i;
770 + unsigned int tmptag;
771 +
772 + if((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags])
773 return;
774 selmon->seltags ^= 1; /* toggle sel tagset */
775 - if (arg->ui & TAGMASK)
776 + if(arg->ui & TAGMASK) {
777 + selmon->pertag->prevtag = selmon->pertag->curtag;
778 selmon->tagset[selmon->seltags] = arg->ui & TAGMASK;
779 + if(arg->ui == ~0)
780 + selmon->pertag->curtag = 0;
781 + else {
782 + for (i=0; !(arg->ui & 1 << i); i++) ;
783 + selmon->pertag->curtag = i + 1;
784 + }
785 + } else {
786 + tmptag = selmon->pertag->prevtag;
787 + selmon->pertag->prevtag = selmon->pertag->curtag;
788 + selmon->pertag->curtag = tmptag;
789 + }
790 + selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curt…
791 + selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag];
792 + selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag];
793 + selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pert…
794 + selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pe…
795 + if (selmon->showbar != selmon->pertag->showbars[selmon->pertag-…
796 + togglebar(NULL);
797 focus(NULL);
798 arrange(selmon);
799 }
800 @@ -2062,7 +2338,7 @@ wintomon(Window w)
801 if (w == root && getrootptr(&x, &y))
802 return recttomon(x, y, 1, 1);
803 for (m = mons; m; m = m->next)
804 - if (w == m->barwin)
805 + if(w == m->barwin || w == m->tabwin)
806 return m;
807 if ((c = wintoclient(w)))
808 return c->mon;
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.