bar_tabgroups.c (7075B)
1 /* Bartabgroups properties, you can override these in your config.h if you want. */ 2 #ifndef BARTAB_BORDERS 3 #define BARTAB_BORDERS 1 // 0 = off, 1 = on 4 #endif 5 #ifndef BARTAB_SHOWFLOATING 6 #define BARTAB_SHOWFLOATING 0 // whether to show titles for floating windows, hidden clients are always shown 7 #endif 8 #ifndef BARTAB_STACKWEIGHT 9 #define BARTAB_STACKWEIGHT 1 // stack weight compared to hidden and floating window titles 10 #endif 11 #ifndef BARTAB_HIDDENWEIGHT 12 #define BARTAB_HIDDENWEIGHT 1 // hidden window title weight 13 #endif 14 #ifndef BARTAB_FLOATWEIGHT 15 #define BARTAB_FLOATWEIGHT 1 // floating window title weight, set to 0 to not show floating windows 16 #endif 17 18 int 19 width_bartabgroups(Bar *bar, BarArg *a) 20 { 21 return a->w; 22 } 23 24 int 25 draw_bartabgroups(Bar *bar, BarArg *a) 26 { 27 drw_rect(drw, a->x, a->y, a->w, a->h, 1, 1); 28 return bartabcalculate(bar->mon, a->x, a->w, -1, bartabdraw, NULL, a); 29 } 30 31 int 32 click_bartabgroups(Bar *bar, Arg *arg, BarArg *a) 33 { 34 bartabcalculate(bar->mon, 0, a->w, a->x, bartabclick, arg, a); 35 return ClkWinTitle; 36 } 37 38 void 39 bartabdraw(Monitor *m, Client *c, int unused, int x, int w, int groupactive, Arg *arg, BarArg *a) 40 { 41 if (!c) 42 return; 43 int i, nclienttags = 0, nviewtags = 0; 44 int tpad = lrpad / 2; 45 #if BAR_WINICON_PATCH 46 int ipad = c->icon ? c->icw + ICONSPACING : 0; 47 #endif // BAR_WINICON_PATCH 48 #if BAR_CENTEREDWINDOWNAME_PATCH 49 int cpad = 0; 50 #endif // BAR_CENTEREDWINDOWNAME_PATCH 51 int tx = x; 52 int tw = w; 53 54 drw_setscheme(drw, scheme[ 55 m->sel == c 56 #ifdef HIDDEN 57 && HIDDEN(c) 58 ? SchemeHidSel 59 : HIDDEN(c) 60 ? SchemeHidNorm 61 : m->sel == c 62 #endif 63 ? SchemeSel 64 : groupactive 65 ? SchemeTitleSel 66 : SchemeTitleNorm 67 ]); 68 if (w <= TEXTW("A") - lrpad + tpad) // reduce text padding if wintitle is too small 69 tpad = (w - TEXTW("A") + lrpad < 0 ? 0 : (w - TEXTW("A") + lrpad) / 2); 70 #if BAR_WINICON_PATCH && BAR_CENTEREDWINDOWNAME_PATCH 71 else if (TEXTW(c->name) + ipad < w) 72 cpad = (w - TEXTW(c->name) - ipad) / 2; 73 #elif BAR_CENTEREDWINDOWNAME_PATCH 74 else if (TEXTW(c->name) < w) 75 cpad = (w - TEXTW(c->name)) / 2; 76 #endif // BAR_CENTEREDWINDOWNAME_PATCH 77 78 XSetForeground(drw->dpy, drw->gc, drw->scheme[ColBg].pixel); 79 XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, a->y, w, a->h); 80 81 #if BAR_CENTEREDWINDOWNAME_PATCH 82 /* Apply center padding, if any */ 83 tx += cpad; 84 tw -= cpad; 85 #endif // BAR_CENTEREDWINDOWNAME_PATCH 86 87 tx += tpad; 88 tw -= lrpad; 89 90 #if BAR_WINICON_PATCH 91 if (ipad) { 92 drw_pic(drw, tx, a->y + (a->h - c->ich) / 2, c->icw, c->ich, c->icon); 93 tx += ipad; 94 tw -= ipad; 95 } 96 #endif // BAR_WINICON_PATCH 97 98 drw_text(drw, tx, a->y, tw, a->h, 0, c->name, 0, False); 99 100 drawstateindicator(m, c, 1, x, a->y, w, a->h, 0, 0, c->isfixed); 101 102 if (BARTAB_BORDERS) { 103 XSetForeground(drw->dpy, drw->gc, scheme[SchemeSel][ColBorder].pixel); 104 XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, a->y, 1, a->h); 105 XFillRectangle(drw->dpy, drw->drawable, drw->gc, x + w - (x + w >= a->w ? 1 : 0), a->y, 1, a->h); 106 } 107 /* Optional tags icons */ 108 for (i = 0; i < NUMTAGS; i++) { 109 if ((m->tagset[m->seltags] >> i) & 1) 110 nviewtags++; 111 if ((c->tags >> i) & 1) 112 nclienttags++; 113 } 114 115 if (TAGSINDICATOR == 2 || nclienttags > 1 || nviewtags > 1) 116 drawindicator(m, c, 1, x, a->y, w, a->h, 0, 0, 0, INDICATOR_RIGHT_TAGS); 117 } 118 119 #ifndef HIDDEN 120 #define HIDDEN(C) 0 121 #endif 122 123 void 124 bartabclick(Monitor *m, Client *c, int passx, int x, int w, int unused, Arg *arg, BarArg *barg) 125 { 126 if (passx >= x && passx <= x + w) 127 arg->v = c; 128 } 129 130 int 131 bartabcalculate( 132 Monitor *m, int offx, int tabw, int passx, 133 void(*tabfn)(Monitor *, Client *, int, int, int, int, Arg *arg, BarArg *barg), 134 Arg *arg, BarArg *barg 135 ) { 136 Client *c; 137 int 138 i, clientsnmaster = 0, clientsnstack = 0, clientsnfloating = 0, clientsnhidden = 0, 139 masteractive = 0, fulllayout = 0, 140 x = offx, w, r, num = 0, den, tgactive; 141 142 for (i = 0; i < LENGTH(bartabmonfns); i++) 143 if (m ->lt[m->sellt]->arrange == bartabmonfns[i]) { 144 fulllayout = 1; 145 break; 146 } 147 148 for (i = 0, c = m->clients; c; c = c->next) { 149 if (!ISVISIBLE(c)) 150 continue; 151 if (HIDDEN(c)) { 152 clientsnhidden++; 153 continue; 154 } 155 if (c->isfloating) { 156 clientsnfloating++; 157 continue; 158 } 159 if (m->sel == c) 160 masteractive = i < m->nmaster; 161 if (i < m->nmaster) 162 clientsnmaster++; 163 else 164 clientsnstack++; 165 i++; 166 } 167 168 if (clientsnmaster + clientsnstack + clientsnfloating + clientsnhidden == 0) 169 return 0; 170 171 tgactive = 1; 172 num = tabw; 173 /* floating mode */ 174 if ((fulllayout && BARTAB_FLOATWEIGHT) || clientsnmaster + clientsnstack == 0 || !m->lt[m->sellt]->arrange) { 175 den = clientsnmaster + clientsnstack + clientsnfloating + clientsnhidden; 176 r = num % den; 177 w = num / den; 178 for (c = m->clients, i = 0; c; c = c->next) { 179 if (!ISVISIBLE(c)) 180 continue; 181 tabfn(m, c, passx, x, w + (i < r ? 1 : 0), tgactive, arg, barg); 182 x += w + (i < r ? 1 : 0); 183 i++; 184 } 185 /* no master and stack mode, e.g. monocole, grid layouts, fibonacci */ 186 } else if (fulllayout) { 187 den = clientsnmaster + clientsnstack + clientsnhidden; 188 r = num % den; 189 w = num / den; 190 for (c = m->clients, i = 0; c; c = c->next) { 191 if (!ISVISIBLE(c) || (c->isfloating && !HIDDEN(c))) 192 continue; 193 tabfn(m, c, passx, x, w + (i < r ? 1 : 0), tgactive, arg, barg); 194 x += w + (i < r ? 1 : 0); 195 i++; 196 } 197 /* tiled mode */ 198 } else { 199 den = clientsnmaster; 200 c = m->clients; 201 i = 0; 202 if (den) { 203 if (clientsnstack + clientsnfloating * BARTAB_FLOATWEIGHT + clientsnhidden) { 204 tgactive = masteractive; 205 num = tabw * m->mfact; 206 } 207 r = num % den; 208 w = num / den; 209 for (; c && i < m->nmaster; c = c->next) { // tiled master 210 if (!ISVISIBLE(c) || c->isfloating || HIDDEN(c)) 211 continue; 212 tabfn(m, c, passx, x, w + (i < r ? 1 : 0), tgactive, arg, barg); 213 x += w + (i < r ? 1 : 0); 214 i++; 215 } 216 tgactive = !tgactive; 217 num = tabw - num; 218 } 219 220 den = clientsnstack * BARTAB_STACKWEIGHT + clientsnfloating * BARTAB_FLOATWEIGHT + clientsnhidden * BARTAB_HIDDENWEIGHT; 221 if (!den) 222 return 1; 223 224 r = num % den; 225 w = num / den; 226 #if BARTAB_STACKWEIGHT 227 for (; c; c = c->next) { // tiled stack 228 if (!ISVISIBLE(c) || HIDDEN(c) || c->isfloating) 229 continue; 230 tabfn(m, c, passx, x, w * BARTAB_STACKWEIGHT + (i - m->nmaster < r ? 1 : 0), tgactive, arg, barg); 231 x += w * BARTAB_STACKWEIGHT + (i - m->nmaster < r ? 1 : 0); 232 i++; 233 } 234 #endif // BARTAB_STACKWEIGHT 235 236 #if BARTAB_HIDDENWEIGHT 237 for (c = m->clients; c; c = c->next) { // hidden windows 238 if (!ISVISIBLE(c) || !HIDDEN(c)) 239 continue; 240 tabfn(m, c, passx, x, w * BARTAB_HIDDENWEIGHT + (i - m->nmaster < r ? 1 : 0), tgactive, arg, barg); 241 x += w * BARTAB_HIDDENWEIGHT + (i - m->nmaster < r ? 1 : 0); 242 i++; 243 } 244 #endif // BARTAB_HIDDENWEIGHT 245 246 #if BARTAB_FLOATWEIGHT 247 for (c = m->clients; c; c = c->next) { // floating windows 248 if (!ISVISIBLE(c) || HIDDEN(c) || !c->isfloating) 249 continue; 250 tabfn(m, c, passx, x, w * BARTAB_FLOATWEIGHT + (i - m->nmaster < r ? 1 : 0), tgactive, arg, barg); 251 x += w * BARTAB_FLOATWEIGHT + (i - m->nmaster < r ? 1 : 0); 252 i++; 253 } 254 #endif // BARTAB_FLOATWEIGHT 255 } 256 return 1; 257 } 258