dwm-bartabgroups-6.2.diff - sites - public wiki contents of suckless.org
(HTM) git clone git://git.suckless.org/sites
(DIR) Log
(DIR) Files
(DIR) Refs
---
dwm-bartabgroups-6.2.diff (7487B)
---
1 From bac0e7d5f91be0a6d919396540d4e1d1009c2e8e Mon Sep 17 00:00:00 2001
2 From: Miles Alan <m@milesalan.com>
3 Date: Sat, 25 Jan 2020 21:56:31 -0600
4 Subject: [PATCH] bartabgroups: Splits the titlebar area into into an
5 mfact-respecting tabbar
6
7 In tiling mode, two tab groups are shown divided at the mfact location.
8 In monocole mode, one tab group is shown (which excludes floating windows).
9 In floating mode, one tab group is shown (which includes floating windows).
10 Clicking on a tab will focus that window.
11
12 Adjust the config.def.h to change functionality and to make exceptions for the
13 tab bar for custom layouts.
14 ---
15 config.def.h | 11 +++++
16 dwm.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++-----
17 2 files changed, 112 insertions(+), 11 deletions(-)
18
19 diff --git a/config.def.h b/config.def.h
20 index 1c0b587..e61bb55 100644
21 --- a/config.def.h
22 +++ b/config.def.h
23 @@ -16,6 +16,8 @@ static const char *colors[][3] = {
24 /* fg bg border */
25 [SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
26 [SchemeSel] = { col_gray4, col_cyan, col_cyan },
27 + [SchemeTabActive] = { col_gray2, col_gray3, col_gray2 },
28 + [SchemeTabInactive] = { col_gray1, col_gray3, col_gray1 }
29 };
30
31 /* tagging */
32 @@ -36,6 +38,15 @@ static const float mfact = 0.55; /* factor of master area size [0.05..0.95]
33 static const int nmaster = 1; /* number of clients in master area */
34 static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */
35
36 +/* Bartabgroups properties */
37 +#define BARTAB_BORDERS 1 // 0 = off, 1 = on
38 +#define BARTAB_BOTTOMBORDER 1 // 0 = off, 1 = on
39 +#define BARTAB_TAGSINDICATOR 1 // 0 = off, 1 = on if >1 client/view tag, 2 = always on
40 +#define BARTAB_TAGSPX 5 // # pixels for tag grid boxes
41 +#define BARTAB_TAGSROWS 3 // # rows in tag grid (9 tags, e.g. 3x3)
42 +static void (*bartabmonfns[])(Monitor *) = { monocle /* , customlayoutfn */ };
43 +static void (*bartabfloatfns[])(Monitor *) = { NULL /* , customlayoutfn */ };
44 +
45 static const Layout layouts[] = {
46 /* symbol arrange function */
47 { "[]=", tile }, /* first entry is default */
48 diff --git a/dwm.c b/dwm.c
49 index 4465af1..d567978 100644
50 --- a/dwm.c
51 +++ b/dwm.c
52 @@ -59,7 +59,7 @@
53
54 /* enums */
55 enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
56 -enum { SchemeNorm, SchemeSel }; /* color schemes */
57 +enum { SchemeNorm, SchemeSel, SchemeTabActive, SchemeTabInactive }; /* color schemes */
58 enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
59 NetWMFullscreen, NetActiveWindow, NetWMWindowType,
60 NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
61 @@ -377,6 +377,98 @@ applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact)
62 return *x != c->x || *y != c->y || *w != c->w || *h != c->h;
63 }
64
65 +void
66 +bartabdraw(Monitor *m, Client *c, int unused, int x, int w, int groupactive) {
67 + if (!c) return;
68 + int i, nclienttags = 0, nviewtags = 0;
69 +
70 + drw_setscheme(drw, scheme[
71 + m->sel == c ? SchemeSel : (groupactive ? SchemeTabActive: SchemeTabInactive)
72 + ]);
73 + drw_text(drw, x, 0, w, bh, lrpad / 2, c->name, 0);
74 +
75 + // Floating win indicator
76 + if (c->isfloating) drw_rect(drw, x + 2, 2, 5, 5, 0, 0);
77 +
78 + // Optional borders between tabs
79 + if (BARTAB_BORDERS) {
80 + XSetForeground(drw->dpy, drw->gc, drw->scheme[ColBorder].pixel);
81 + XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, 0, 1, bh);
82 + XFillRectangle(drw->dpy, drw->drawable, drw->gc, x + w, 0, 1, bh);
83 + }
84 +
85 + // Optional tags icons
86 + for (i = 0; i < LENGTH(tags); i++) {
87 + if ((m->tagset[m->seltags] >> i) & 1) { nviewtags++; }
88 + if ((c->tags >> i) & 1) { nclienttags++; }
89 + }
90 + if (BARTAB_TAGSINDICATOR == 2 || nclienttags > 1 || nviewtags > 1) {
91 + for (i = 0; i < LENGTH(tags); i++) {
92 + drw_rect(drw,
93 + ( x + w - 2 - ((LENGTH(tags) / BARTAB_TAGSROWS) * BARTAB_TAGSPX)
94 + - (i % (LENGTH(tags)/BARTAB_TAGSROWS)) + ((i % (LENGTH(tags) / BARTAB_TAGSROWS)) * BARTAB_TAGSPX)
95 + ),
96 + ( 2 + ((i / (LENGTH(tags)/BARTAB_TAGSROWS)) * BARTAB_TAGSPX)
97 + - ((i / (LENGTH(tags)/BARTAB_TAGSROWS)))
98 + ),
99 + BARTAB_TAGSPX, BARTAB_TAGSPX, (c->tags >> i) & 1, 0
100 + );
101 + }
102 + }
103 +}
104 +
105 +void
106 +battabclick(Monitor *m, Client *c, int passx, int x, int w, int unused) {
107 + if (passx >= x && passx <= x + w) {
108 + focus(c);
109 + restack(selmon);
110 + }
111 +}
112 +
113 +void
114 +bartabcalculate(
115 + Monitor *m, int offx, int sw, int passx,
116 + void(*tabfn)(Monitor *, Client *, int, int, int, int)
117 +) {
118 + Client *c;
119 + int
120 + i, clientsnmaster = 0, clientsnstack = 0, clientsnfloating = 0,
121 + masteractive = 0, fulllayout = 0, floatlayout = 0,
122 + x, w, tgactive;
123 +
124 + for (i = 0, c = m->clients; c; c = c->next) {
125 + if (!ISVISIBLE(c)) continue;
126 + if (c->isfloating) { clientsnfloating++; continue; }
127 + if (m->sel == c) { masteractive = i < m->nmaster; }
128 + if (i < m->nmaster) { clientsnmaster++; } else { clientsnstack++; }
129 + i++;
130 + }
131 + for (i = 0; i < LENGTH(bartabfloatfns); i++) if (m ->lt[m->sellt]->arrange == bartabfloatfns[i]) { floatlayout = 1; break; }
132 + for (i = 0; i < LENGTH(bartabmonfns); i++) if (m ->lt[m->sellt]->arrange == bartabmonfns[i]) { fulllayout = 1; break; }
133 + for (c = m->clients, i = 0; c; c = c->next) {
134 + if (!ISVISIBLE(c)) continue;
135 + if (clientsnmaster + clientsnstack == 0 || floatlayout) {
136 + x = offx + (((m->mw - offx - sw) / (clientsnmaster + clientsnstack + clientsnfloating)) * i);
137 + w = (m->mw - offx - sw) / (clientsnmaster + clientsnstack + clientsnfloating);
138 + tgactive = 1;
139 + } else if (!c->isfloating && (fulllayout || ((clientsnmaster == 0) ^ (clientsnstack == 0)))) {
140 + x = offx + (((m->mw - offx - sw) / (clientsnmaster + clientsnstack)) * i);
141 + w = (m->mw - offx - sw) / (clientsnmaster + clientsnstack);
142 + tgactive = 1;
143 + } else if (i < m->nmaster && !c->isfloating) {
144 + x = offx + ((((m->mw * m->mfact) - offx) /clientsnmaster) * i);
145 + w = ((m->mw * m->mfact) - offx) / clientsnmaster;
146 + tgactive = masteractive;
147 + } else if (!c->isfloating) {
148 + x = (m->mw * m->mfact) + ((((m->mw * (1 - m->mfact)) - sw) / clientsnstack) * (i - m->nmaster));
149 + w = ((m->mw * (1 - m->mfact)) - sw) / clientsnstack;
150 + tgactive = !masteractive;
151 + } else continue;
152 + tabfn(m, c, passx, x, w, tgactive);
153 + i++;
154 + }
155 +}
156 +
157 void
158 arrange(Monitor *m)
159 {
160 @@ -441,8 +533,8 @@ buttonpress(XEvent *e)
161 click = ClkLtSymbol;
162 else if (ev->x > selmon->ww - TEXTW(stext))
163 click = ClkStatusText;
164 - else
165 - click = ClkWinTitle;
166 + else // Focus clicked tab bar item
167 + bartabcalculate(selmon, x, TEXTW(stext) - lrpad + 2, ev->x, battabclick);
168 } else if ((c = wintoclient(ev->window))) {
169 focus(c);
170 restack(selmon);
171 @@ -728,15 +820,13 @@ drawbar(Monitor *m)
172 drw_setscheme(drw, scheme[SchemeNorm]);
173 x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0);
174
175 + // Draw bartabgroups
176 + drw_rect(drw, x, 0, m->ww - sw - x, bh, 1, 1);
177 if ((w = m->ww - sw - x) > bh) {
178 - if (m->sel) {
179 - drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]);
180 - drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0);
181 - if (m->sel->isfloating)
182 - drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0);
183 - } else {
184 - drw_setscheme(drw, scheme[SchemeNorm]);
185 - drw_rect(drw, x, 0, w, bh, 1, 1);
186 + bartabcalculate(m, x, sw, -1, bartabdraw);
187 + if (BARTAB_BOTTOMBORDER) {
188 + drw_setscheme(drw, scheme[SchemeTabActive]);
189 + drw_rect(drw, 0, bh - 1, m->ww, 1, 1, 0);
190 }
191 }
192 drw_map(drw, m->barwin, 0, 0, m->ww, bh);
193 --
194 2.23.1
195