142 void configurenotify(XEvent *e); |
142 void configurenotify(XEvent *e); |
143 void configurerequest(XEvent *e); |
143 void configurerequest(XEvent *e); |
144 void destroynotify(XEvent *e); |
144 void destroynotify(XEvent *e); |
145 void detach(Client *c); |
145 void detach(Client *c); |
146 void detachstack(Client *c); |
146 void detachstack(Client *c); |
147 void drawbar(void); |
147 void drawbar(Monitor *m); |
148 void drawsquare(Monitor *, Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]); |
148 void drawsquare(Monitor *m, Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]); |
149 void drawtext(Monitor *, const char *text, unsigned long col[ColLast], Bool invert); |
149 void drawtext(Monitor *m, const char *text, unsigned long col[ColLast], Bool invert); |
150 void *emallocz(unsigned int size); |
150 void *emallocz(unsigned int size); |
151 void enternotify(XEvent *e); |
151 void enternotify(XEvent *e); |
152 void eprint(const char *errstr, ...); |
152 void eprint(const char *errstr, ...); |
153 void expose(XEvent *e); |
153 void expose(XEvent *e); |
154 void floating(Monitor *m); /* default floating layout */ |
154 void floating(Monitor *m); /* default floating layout */ |
156 void focusin(XEvent *e); |
156 void focusin(XEvent *e); |
157 void focusnext(const char *arg); |
157 void focusnext(const char *arg); |
158 void focusprev(const char *arg); |
158 void focusprev(const char *arg); |
159 Client *getclient(Window w); |
159 Client *getclient(Window w); |
160 unsigned long getcolor(const char *colstr); |
160 unsigned long getcolor(const char *colstr); |
|
161 Monitor *getmonitor(Window barwin); |
161 long getstate(Window w); |
162 long getstate(Window w); |
162 Bool gettextprop(Window w, Atom atom, char *text, unsigned int size); |
163 Bool gettextprop(Window w, Atom atom, char *text, unsigned int size); |
163 void grabbuttons(Client *c, Bool focused); |
164 void grabbuttons(Client *c, Bool focused); |
164 void grabkeys(void); |
165 void grabkeys(void); |
165 unsigned int idxoftag(const char *tag); |
166 unsigned int idxoftag(const char *tag); |
178 void propertynotify(XEvent *e); |
179 void propertynotify(XEvent *e); |
179 void quit(const char *arg); |
180 void quit(const char *arg); |
180 void reapply(const char *arg); |
181 void reapply(const char *arg); |
181 void resize(Client *c, int x, int y, int w, int h, Bool sizehints); |
182 void resize(Client *c, int x, int y, int w, int h, Bool sizehints); |
182 void resizemouse(Client *c); |
183 void resizemouse(Client *c); |
183 void restack(void); |
184 void restack(Monitor *m); |
184 void run(void); |
185 void run(void); |
185 void scan(void); |
186 void scan(void); |
186 void setclientstate(Client *c, long state); |
187 void setclientstate(Client *c, long state); |
187 void setlayout(const char *arg); |
188 void setlayout(const char *arg); |
188 void setmwfact(const char *arg); |
189 void setmwfact(const char *arg); |
560 for(tc=&stack; *tc && *tc != c; tc=&(*tc)->snext); |
561 for(tc=&stack; *tc && *tc != c; tc=&(*tc)->snext); |
561 *tc = c->snext; |
562 *tc = c->snext; |
562 } |
563 } |
563 |
564 |
564 void |
565 void |
565 drawbar(void) { |
566 drawbar(Monitor *m) { |
566 int i, j, x; |
567 int j, x; |
567 Client *c; |
568 Client *c; |
568 |
569 |
569 for(i = 0; i < mcount; i++) { |
570 dc.x = 0; |
570 Monitor *m = &monitors[i]; |
571 for(c = stack; c && !isvisible(c, m->id); c = c->snext); |
571 dc.x = 0; |
572 for(j = 0; j < LENGTH(tags); j++) { |
572 for(c = stack; c && !isvisible(c, i); c = c->snext); |
573 dc.w = textw(tags[j]); |
573 fprintf(stderr, "m%d %s\n", i, c ? c->name : "NIL"); |
574 if(m->seltags[j]) { |
574 for(j = 0; j < LENGTH(tags); j++) { |
575 drawtext(m, tags[j], dc.sel, isurgent(m->id, j)); |
575 dc.w = textw(tags[j]); |
576 drawsquare(m, c && c->tags[j] && c->monitor == m->id, |
576 if(m->seltags[j]) { |
577 isoccupied(m->id, j), isurgent(m->id, j), dc.sel); |
577 drawtext(m, tags[j], dc.sel, isurgent(i, j)); |
578 } |
578 drawsquare(m, c && c->tags[j] && c->monitor == i, |
579 else { |
579 isoccupied(i, j), isurgent(i, j), dc.sel); |
580 drawtext(m, tags[j], dc.norm, isurgent(m->id, j)); |
580 } |
581 drawsquare(m, c && c->tags[j] && c->monitor == m->id, |
581 else { |
582 isoccupied(m->id, j), isurgent(m->id, j), dc.norm); |
582 drawtext(m, tags[j], dc.norm, isurgent(i, j)); |
583 } |
583 drawsquare(m, c && c->tags[j] && c->monitor == i, |
584 dc.x += dc.w; |
584 isoccupied(i, j), isurgent(i, j), dc.norm); |
585 } |
585 } |
586 dc.w = blw; |
586 dc.x += dc.w; |
587 drawtext(m, m->layout->symbol, dc.norm, False); |
587 } |
588 x = dc.x + dc.w; |
588 dc.w = blw; |
589 if(m->id == selmonitor) { |
589 drawtext(m, m->layout->symbol, dc.norm, False); |
590 dc.w = textw(stext); |
590 x = dc.x + dc.w; |
591 dc.x = m->sw - dc.w; |
591 if(i == selmonitor) { |
592 if(dc.x < x) { |
592 dc.w = textw(stext); |
593 dc.x = x; |
593 dc.x = m->sw - dc.w; |
594 dc.w = m->sw - x; |
594 if(dc.x < x) { |
595 } |
595 dc.x = x; |
596 drawtext(m, stext, dc.norm, False); |
596 dc.w = m->sw - x; |
597 } |
597 } |
598 else |
598 drawtext(m, stext, dc.norm, False); |
599 dc.x = m->sw; |
|
600 if((dc.w = dc.x - x) > bh) { |
|
601 dc.x = x; |
|
602 if(c) { |
|
603 drawtext(m, c->name, dc.sel, False); |
|
604 drawsquare(m, False, c->isfloating, False, dc.sel); |
599 } |
605 } |
600 else |
606 else |
601 dc.x = m->sw; |
607 drawtext(m, NULL, dc.norm, False); |
602 if((dc.w = dc.x - x) > bh) { |
608 } |
603 dc.x = x; |
609 XCopyArea(dpy, dc.drawable, m->barwin, dc.gc, 0, 0, m->sw, bh, 0, 0); |
604 if(c) { |
610 XSync(dpy, False); |
605 drawtext(m, c->name, dc.sel, False); |
|
606 drawsquare(m, False, c->isfloating, False, dc.sel); |
|
607 } |
|
608 else |
|
609 drawtext(m, NULL, dc.norm, False); |
|
610 } |
|
611 XCopyArea(dpy, dc.drawable, m->barwin, dc.gc, 0, 0, m->sw, bh, 0, 0); |
|
612 XSync(dpy, False); |
|
613 } |
|
614 } |
611 } |
615 |
612 |
616 void |
613 void |
617 drawsquare(Monitor *m, Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]) { |
614 drawsquare(Monitor *m, Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]) { |
618 int x; |
615 int x; |
748 detachstack(c); |
744 detachstack(c); |
749 attachstack(c); |
745 attachstack(c); |
750 grabbuttons(c, True); |
746 grabbuttons(c, True); |
751 } |
747 } |
752 sel = c; |
748 sel = c; |
753 drawbar(); |
|
754 if(c) { |
749 if(c) { |
755 XSetWindowBorder(dpy, c->win, dc.sel[ColBorder]); |
750 XSetWindowBorder(dpy, c->win, dc.sel[ColBorder]); |
756 XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); |
751 XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); |
757 selmonitor = c->monitor; |
752 selmonitor = c->monitor; |
758 } |
753 } |
759 else { |
754 else |
760 XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); |
755 XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); |
761 drawbar(); |
756 drawbar(&monitors[selmonitor]); |
762 } |
|
763 } |
757 } |
764 |
758 |
765 void |
759 void |
766 focusin(XEvent *e) { /* there are some broken focus acquiring clients */ |
760 focusin(XEvent *e) { /* there are some broken focus acquiring clients */ |
767 XFocusChangeEvent *ev = &e->xfocus; |
761 XFocusChangeEvent *ev = &e->xfocus; |
1223 |
1227 |
1224 if(ev->state == PropertyDelete) |
1228 if(ev->state == PropertyDelete) |
1225 return; /* ignore */ |
1229 return; /* ignore */ |
1226 if((c = getclient(ev->window))) { |
1230 if((c = getclient(ev->window))) { |
1227 switch (ev->atom) { |
1231 switch (ev->atom) { |
1228 default: break; |
1232 default: break; |
1229 case XA_WM_TRANSIENT_FOR: |
1233 case XA_WM_TRANSIENT_FOR: |
1230 XGetTransientForHint(dpy, c->win, &trans); |
1234 XGetTransientForHint(dpy, c->win, &trans); |
1231 if(!c->isfloating && (c->isfloating = (getclient(trans) != NULL))) |
1235 if(!c->isfloating && (c->isfloating = (getclient(trans) != NULL))) |
1232 arrange(); |
1236 arrange(); |
1233 break; |
1237 break; |
1234 case XA_WM_NORMAL_HINTS: |
1238 case XA_WM_NORMAL_HINTS: |
1235 updatesizehints(c); |
1239 updatesizehints(c); |
1236 break; |
1240 break; |
1237 case XA_WM_HINTS: |
1241 case XA_WM_HINTS: |
1238 updatewmhints(c); |
1242 updatewmhints(c); |
1239 drawbar(); |
1243 drawbar(&monitors[c->monitor]); |
1240 break; |
1244 break; |
1241 } |
1245 } |
1242 if(ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) { |
1246 if(ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) { |
1243 updatetitle(c); |
1247 updatetitle(c); |
1244 if(c == sel) |
1248 if(c == sel) |
1245 drawbar(); |
1249 drawbar(&monitors[c->monitor]); |
1246 } |
1250 } |
1247 } |
1251 } |
1248 } |
1252 } |
1249 |
1253 |
1250 void |
1254 void |
1373 } |
1377 } |
1374 } |
1378 } |
1375 } |
1379 } |
1376 |
1380 |
1377 void |
1381 void |
1378 restack(void) { |
1382 restack(Monitor *m) { |
1379 unsigned int i; |
|
1380 Client *c; |
1383 Client *c; |
1381 XEvent ev; |
1384 XEvent ev; |
1382 XWindowChanges wc; |
1385 XWindowChanges wc; |
1383 |
1386 |
1384 drawbar(); |
1387 drawbar(m); |
1385 if(!sel) |
1388 if(!sel) |
1386 return; |
1389 return; |
1387 if(sel->isfloating || (monitors[selmonitor].layout->arrange == floating)) |
1390 if(sel->isfloating || (m->layout->arrange == floating)) |
1388 XRaiseWindow(dpy, sel->win); |
1391 XRaiseWindow(dpy, sel->win); |
1389 if(monitors[selmonitor].layout->arrange != floating) { |
1392 if(m->layout->arrange != floating) { |
1390 wc.stack_mode = Below; |
1393 wc.stack_mode = Below; |
1391 wc.sibling = monitors[selmonitor].barwin; |
1394 wc.sibling = m->barwin; |
1392 if(!sel->isfloating) { |
1395 if(!sel->isfloating) { |
1393 XConfigureWindow(dpy, sel->win, CWSibling | CWStackMode, &wc); |
1396 XConfigureWindow(dpy, sel->win, CWSibling | CWStackMode, &wc); |
1394 wc.sibling = sel->win; |
1397 wc.sibling = sel->win; |
1395 } |
1398 } |
1396 for(i = 0; i < mcount; i++) { |
1399 for(c = nexttiled(clients, m->id); c; c = nexttiled(c->next, m->id)) { |
1397 for(c = nexttiled(clients, i); c; c = nexttiled(c->next, i)) { |
1400 if(c == sel) |
1398 if(c == sel) |
1401 continue; |
1399 continue; |
1402 XConfigureWindow(dpy, c->win, CWSibling | CWStackMode, &wc); |
1400 XConfigureWindow(dpy, c->win, CWSibling | CWStackMode, &wc); |
1403 wc.sibling = c->win; |
1401 wc.sibling = c->win; |
|
1402 } |
|
1403 } |
1404 } |
1404 } |
1405 } |
1405 XSync(dpy, False); |
1406 XSync(dpy, False); |
1406 while(XCheckMaskEvent(dpy, EnterWindowMask, &ev)); |
1407 while(XCheckMaskEvent(dpy, EnterWindowMask, &ev)); |
1407 } |
1408 } |