dwm-fancybarclickable-6.1.diff (6638B)
1 diff --git a/config.def.h b/config.def.h 2 index 875885b..05865bb 100644 3 --- a/config.def.h 4 +++ b/config.def.h 5 @@ -97,6 +97,7 @@ static Button buttons[] = { 6 /* click event mask button function argument */ 7 { ClkLtSymbol, 0, Button1, setlayout, {0} }, 8 { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} }, 9 + { ClkWinTitle, 0, Button1, focusonclick, {0} }, 10 { ClkWinTitle, 0, Button2, zoom, {0} }, 11 { ClkStatusText, 0, Button2, spawn, {.v = termcmd } }, 12 { ClkClientWin, MODKEY, Button1, movemouse, {0} }, 13 diff --git a/dwm.c b/dwm.c 14 index f896170..cc2a4f2 100644 15 --- a/dwm.c 16 +++ b/dwm.c 17 @@ -129,6 +129,8 @@ struct Monitor { 18 Monitor *next; 19 Window barwin; 20 const Layout *lt[2]; 21 + int titlebarbegin; 22 + int titlebarend; 23 }; 24 25 typedef struct { 26 @@ -163,9 +165,11 @@ static void detachstack(Client *c); 27 static Monitor *dirtomon(int dir); 28 static void drawbar(Monitor *m); 29 static void drawbars(void); 30 +static void drawline(int x, int y); 31 static void enternotify(XEvent *e); 32 static void expose(XEvent *e); 33 static void focus(Client *c); 34 +static void focusonclick(const Arg *arg); 35 static void focusin(XEvent *e); 36 static void focusmon(const Arg *arg); 37 static void focusstack(const Arg *arg); 38 @@ -432,10 +436,12 @@ buttonpress(XEvent *e) { 39 } 40 else if(ev->x < x + blw) 41 click = ClkLtSymbol; 42 - else if(ev->x > selmon->ww - TEXTW(stext)) 43 + else if(ev->x > selmon->titlebarend) 44 click = ClkStatusText; 45 - else 46 + else { 47 + arg.ui = ev->x; 48 click = ClkWinTitle; 49 + } 50 } 51 else if((c = wintoclient(ev->window))) { 52 focus(c); 53 @@ -444,7 +450,7 @@ buttonpress(XEvent *e) { 54 for(i = 0; i < LENGTH(buttons); i++) 55 if(click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button 56 && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)) 57 - buttons[i].func(click == ClkTagBar && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg); 58 + buttons[i].func((click == ClkTagBar || click == ClkWinTitle) && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg); 59 } 60 61 void 62 @@ -692,11 +698,14 @@ dirtomon(int dir) { 63 64 void 65 drawbar(Monitor *m) { 66 - int x, xx, w; 67 - unsigned int i, occ = 0, urg = 0; 68 - Client *c; 69 + int x, xx, w, ow, mw = 0, extra, tw, a = 0, s = 0; 70 + char posbuf[10]; 71 + unsigned int i, occ = 0, urg = 0, n = 0; 72 + Client *c, *firstvis, *lastvis = NULL; 73 74 for(c = m->clients; c; c = c->next) { 75 + if(ISVISIBLE(c)) 76 + n++; 77 occ |= c->tags; 78 if(c->isurgent) 79 urg |= c->tags; 80 @@ -716,32 +725,109 @@ drawbar(Monitor *m) { 81 x += w; 82 xx = x; 83 if(m == selmon) { /* status is only drawn on selected monitor */ 84 - w = TEXTW(stext); 85 + if(m->lt[m->sellt]->arrange == monocle){ 86 + x = xx; 87 + for(c = nexttiled(m->clients), a = 0, s = 0; c; c = nexttiled(c->next), a++) { 88 + if(c == m->stack) 89 + s = a; 90 + } 91 + if(!s && a) 92 + s = a; 93 + snprintf(posbuf, LENGTH(posbuf), "[%d/%d]", s, a); 94 + w = TEXTW(posbuf); 95 + drw_text(drw, x, 0, w, bh, posbuf, 0); 96 + xx = x + w; 97 + } 98 + 99 + /* char *buf = stext, *ptr = buf; 100 + while (*ptr) { 101 + for (i = 0; *ptr < 0; i++, ptr++); 102 + w 2+= drw_font_getexts_width(drw->font, buf, i); 103 + w += TEXTW(buf); 104 + buf=++ptr; 105 + } */ 106 + w = TEXTW(stext); 107 + 108 x = m->ww - w; 109 if(x < xx) { 110 x = xx; 111 w = m->ww - xx; 112 } 113 + m->titlebarend=x; 114 drw_text(drw, x, 0, w, bh, stext, 0); 115 } 116 - else 117 + else { 118 x = m->ww; 119 - if((w = x - xx) > bh) { 120 - x = xx; 121 - if(m->sel) { 122 - drw_setscheme(drw, m == selmon ? &scheme[SchemeSel] : &scheme[SchemeNorm]); 123 - drw_text(drw, x, 0, w, bh, m->sel->name, 0); 124 - drw_rect(drw, x, 0, w, bh, m->sel->isfixed, m->sel->isfloating, 0); 125 - } 126 - else { 127 + m->titlebarbegin=x; 128 + } 129 + for(c = m->clients; c && !ISVISIBLE(c); c = c->next); 130 + firstvis = c; 131 + 132 + drw_setscheme(drw, m == selmon ? &scheme[SchemeSel] : &scheme[SchemeNorm]); 133 + w = x - xx; 134 + x = xx; 135 + 136 + if(n > 0) { 137 + mw = w / n; 138 + extra = 0; 139 + i = 0; 140 + 141 + while(c) { 142 + lastvis = c; 143 + tw = TEXTW(c->name); 144 + if(tw < mw) extra += (mw - tw); else i++; 145 + for(c = c->next; c && !ISVISIBLE(c); c = c->next); 146 + } 147 + 148 + if(i > 0) mw += extra / i; 149 + 150 + c = firstvis; 151 + xx = x; 152 + } 153 + m->titlebarbegin=x; 154 + while(w > bh) { 155 + if(c) { 156 + ow = w; 157 + tw = TEXTW(c->name); 158 + w = MIN(ow, tw); 159 + 160 + if(w > mw) w = mw; 161 + if(c == lastvis) w = ow; 162 + 163 + drw_text(drw, x, 0, w, bh, c->name, False); 164 + if(c != firstvis) drawline(x, 0); 165 + drw_rect(drw, x, 0, w, bh, m->sel->isfixed, m->sel->isfloating, True); 166 + 167 + x += w; 168 + w = ow - w; 169 + for(c = c->next; c && !ISVISIBLE(c); c = c->next); 170 + } else { 171 drw_setscheme(drw, &scheme[SchemeNorm]); 172 drw_text(drw, x, 0, w, bh, NULL, 0); 173 + break; 174 } 175 } 176 + 177 + if(m == selmon && m->sel && ISVISIBLE(m->sel)) { 178 + drw_text(drw, x, 0, w, bh, m->sel->name, True); 179 + drw_rect(drw, x, 0, w, bh, m->sel->isfixed, m->sel->isfloating, True); 180 + } 181 + 182 drw_map(drw, m->barwin, 0, 0, m->ww, bh); 183 } 184 185 void 186 +drawline(int x, int y) { 187 + XGCValues gcv; 188 + 189 + gcv.foreground = drw->scheme->fg->rgb; 190 + 191 + XChangeGC(dpy, drw->gc, GCForeground, &gcv); 192 + XDrawLine(dpy, drw->drawable, drw->gc, x, y, x, y + (drw->font->ascent + drw->font->descent + 2)); 193 +} 194 + 195 +void 196 drawbars(void) { 197 Monitor *m; 198 199 @@ -804,6 +890,51 @@ focus(Client *c) { 200 } 201 202 void 203 +focusonclick(const Arg *arg) { 204 + int x, w, mw = 0, tw, n = 0, i = 0, extra = 0; 205 + Monitor *m = selmon; 206 + Client *c, *firstvis; 207 + 208 + for(c = m->clients; c && !ISVISIBLE(c); c = c->next); 209 + firstvis = c; 210 + 211 + for(c = m->clients; c; c = c->next) 212 + if (ISVISIBLE(c)) 213 + n++; 214 + 215 + if(n > 0) { 216 + mw = (m->titlebarend - m->titlebarbegin) / n; 217 + c = firstvis; 218 + while(c) { 219 + tw = TEXTW(c->name); 220 + if(tw < mw) extra += (mw - tw); else i++; 221 + for(c = c->next; c && !ISVISIBLE(c); c = c->next); 222 + } 223 + if(i > 0) mw += extra / i; 224 + } 225 + 226 + x=m->titlebarbegin; 227 + 228 + c = firstvis; 229 + while(x < m->titlebarend) { 230 + if(c) { 231 + w=MIN(TEXTW(c->name), mw); 232 + if (x < arg->i && x+w > arg->i) { 233 + focus(c); 234 + restack(selmon); 235 + break; 236 + } else { 237 + x+=w; 238 + } 239 + 240 + for(c = c->next; c && !ISVISIBLE(c); c = c->next); 241 + } else { 242 + break; 243 + } 244 + } 245 +} 246 + 247 +void 248 focusin(XEvent *e) { /* there are some broken focus acquiring clients */ 249 XFocusChangeEvent *ev = &e->xfocus; 250 251 @@ -1221,8 +1352,7 @@ propertynotify(XEvent *e) { 252 } 253 if(ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) { 254 updatetitle(c); 255 - if(c == c->mon->sel) 256 - drawbar(c->mon); 257 + drawbar(c->mon); 258 } 259 if(ev->atom == netatom[NetWMWindowType]) 260 updatewindowtype(c);