59 #endif |
59 #endif |
60 #define MOUSEMASK (BUTTONMASK|PointerMotionMask) |
60 #define MOUSEMASK (BUTTONMASK|PointerMotionMask) |
61 #define WIDTH(X) ((X)->w + 2 * (X)->bw) |
61 #define WIDTH(X) ((X)->w + 2 * (X)->bw) |
62 #define HEIGHT(X) ((X)->h + 2 * (X)->bw) |
62 #define HEIGHT(X) ((X)->h + 2 * (X)->bw) |
63 #define TAGMASK ((1 << LENGTH(tags)) - 1) |
63 #define TAGMASK ((1 << LENGTH(tags)) - 1) |
64 #define TEXTW(X) (textnw(X, strlen(X)) + dc.font.height) |
64 #define TEXTW(X) (textnw(X, strlen(X), False) + dc.font.height) |
|
65 #define TEXTWM(X) (textnw(X, strlen(X), True) + dc.font.height) |
65 |
66 |
66 /* enums */ |
67 /* enums */ |
67 enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ |
68 enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ |
68 enum { ColBorder, ColFG, ColBG, ColLast }; /* color */ |
69 enum { ColBorder, ColFG, ColBG, ColLast }; /* color */ |
69 enum { NetSupported, NetWMName, NetWMState, |
70 enum { NetSupported, NetWMName, NetWMState, |
169 static void die(const char *errstr, ...); |
170 static void die(const char *errstr, ...); |
170 static Monitor *dirtomon(int dir); |
171 static Monitor *dirtomon(int dir); |
171 static void drawbar(Monitor *m); |
172 static void drawbar(Monitor *m); |
172 static void drawbars(void); |
173 static void drawbars(void); |
173 static void drawsquare(Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]); |
174 static void drawsquare(Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]); |
174 static void drawtext(const char *text, unsigned long col[ColLast], Bool invert); |
175 static void drawtext(const char *text, unsigned long col[ColLast], Bool invert, Bool markup); |
175 static void enternotify(XEvent *e); |
176 static void enternotify(XEvent *e); |
176 static void expose(XEvent *e); |
177 static void expose(XEvent *e); |
177 static void focus(Client *c); |
178 static void focus(Client *c); |
178 static void focusin(XEvent *e); |
179 static void focusin(XEvent *e); |
179 static void focusmon(const Arg *arg); |
180 static void focusmon(const Arg *arg); |
211 static void showhide(Client *c); |
212 static void showhide(Client *c); |
212 static void sigchld(int unused); |
213 static void sigchld(int unused); |
213 static void spawn(const Arg *arg); |
214 static void spawn(const Arg *arg); |
214 static void tag(const Arg *arg); |
215 static void tag(const Arg *arg); |
215 static void tagmon(const Arg *arg); |
216 static void tagmon(const Arg *arg); |
216 static int textnw(const char *text, unsigned int len); |
217 static int textnw(const char *text, unsigned int len, Bool markup); |
217 static void tile(Monitor *); |
218 static void tile(Monitor *); |
218 static void togglebar(const Arg *arg); |
219 static void togglebar(const Arg *arg); |
219 static void togglefloating(const Arg *arg); |
220 static void togglefloating(const Arg *arg); |
220 static void toggletag(const Arg *arg); |
221 static void toggletag(const Arg *arg); |
221 static void toggleview(const Arg *arg); |
222 static void toggleview(const Arg *arg); |
721 } |
722 } |
722 dc.x = 0; |
723 dc.x = 0; |
723 for(i = 0; i < LENGTH(tags); i++) { |
724 for(i = 0; i < LENGTH(tags); i++) { |
724 dc.w = TEXTW(tags[i]); |
725 dc.w = TEXTW(tags[i]); |
725 col = m->tagset[m->seltags] & 1 << i ? dc.sel : dc.norm; |
726 col = m->tagset[m->seltags] & 1 << i ? dc.sel : dc.norm; |
726 drawtext(tags[i], col, urg & 1 << i); |
727 drawtext(tags[i], col, urg & 1 << i, False); |
727 drawsquare(m == selmon && selmon->sel && selmon->sel->tags & 1 << i, |
728 drawsquare(m == selmon && selmon->sel && selmon->sel->tags & 1 << i, |
728 occ & 1 << i, urg & 1 << i, col); |
729 occ & 1 << i, urg & 1 << i, col); |
729 dc.x += dc.w; |
730 dc.x += dc.w; |
730 } |
731 } |
731 dc.w = blw = TEXTW(m->ltsymbol); |
732 dc.w = blw = TEXTW(m->ltsymbol); |
732 drawtext(m->ltsymbol, dc.norm, False); |
733 drawtext(m->ltsymbol, dc.norm, False, False); |
733 dc.x += dc.w; |
734 dc.x += dc.w; |
734 x = dc.x; |
735 x = dc.x; |
735 if(m == selmon) { /* status is only drawn on selected monitor */ |
736 if(m == selmon) { /* status is only drawn on selected monitor */ |
736 dc.w = TEXTW(stext); |
737 dc.w = TEXTWM(stext); |
737 dc.x = m->ww - dc.w; |
738 dc.x = m->ww - dc.w; |
738 if(dc.x < x) { |
739 if(dc.x < x) { |
739 dc.x = x; |
740 dc.x = x; |
740 dc.w = m->ww - x; |
741 dc.w = m->ww - x; |
741 } |
742 } |
742 drawtext(stext, dc.norm, False); |
743 drawtext(stext, dc.norm, False, True); |
743 } |
744 } |
744 else |
745 else |
745 dc.x = m->ww; |
746 dc.x = m->ww; |
746 if((dc.w = dc.x - x) > bh) { |
747 if((dc.w = dc.x - x) > bh) { |
747 dc.x = x; |
748 dc.x = x; |
748 if(m->sel) { |
749 if(m->sel) { |
749 col = m == selmon ? dc.sel : dc.norm; |
750 col = m == selmon ? dc.sel : dc.norm; |
750 drawtext(m->sel->name, col, False); |
751 drawtext(m->sel->name, col, False, False); |
751 drawsquare(m->sel->isfixed, m->sel->isfloating, False, col); |
752 drawsquare(m->sel->isfixed, m->sel->isfloating, False, col); |
752 } |
753 } |
753 else |
754 else |
754 drawtext(NULL, dc.norm, False); |
755 drawtext(NULL, dc.norm, False, False); |
755 } |
756 } |
756 XCopyArea(dpy, dc.drawable, m->barwin, dc.gc, 0, 0, m->ww, bh, 0, 0); |
757 XCopyArea(dpy, dc.drawable, m->barwin, dc.gc, 0, 0, m->ww, bh, 0, 0); |
757 XSync(dpy, False); |
758 XSync(dpy, False); |
758 } |
759 } |
759 |
760 |
785 XDrawRectangles(dpy, dc.drawable, dc.gc, &r, 1); |
786 XDrawRectangles(dpy, dc.drawable, dc.gc, &r, 1); |
786 } |
787 } |
787 } |
788 } |
788 |
789 |
789 void |
790 void |
790 drawtext(const char *text, unsigned long col[ColLast], Bool invert) { |
791 drawtext(const char *text, unsigned long col[ColLast], Bool invert, Bool markup) { |
791 char buf[256]; |
792 char buf[256]; |
792 int i, x, y, h, len, olen; |
793 int i, x, y, h, len, olen; |
793 XRectangle r = { dc.x, dc.y, dc.w, dc.h }; |
794 XRectangle r = { dc.x, dc.y, dc.w, dc.h }; |
794 |
795 |
795 XSetForeground(dpy, dc.gc, col[invert ? ColFG : ColBG]); |
796 XSetForeground(dpy, dc.gc, col[invert ? ColFG : ColBG]); |
800 h = dc.font.ascent + dc.font.descent; |
801 h = dc.font.ascent + dc.font.descent; |
801 //y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent; |
802 //y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent; |
802 y = dc.y; |
803 y = dc.y; |
803 x = dc.x + (h / 2); |
804 x = dc.x + (h / 2); |
804 /* shorten text if necessary */ |
805 /* shorten text if necessary */ |
805 for(len = MIN(olen, sizeof buf); len && textnw(text, len) > dc.w - h; len--); |
806 for(len = MIN(olen, sizeof buf); len && textnw(text, len, markup) > dc.w - h; len--); |
806 if(!len) |
807 if(!len) |
807 return; |
808 return; |
808 memcpy(buf, text, len); |
809 memcpy(buf, text, len); |
809 if(len < olen) |
810 if(len < olen) |
810 for(i = len; i && i > len - 3; buf[--i] = '.'); |
811 for(i = len; i && i > len - 3; buf[--i] = '.'); |
811 pango_layout_set_markup(dc.plo, text, len); |
812 if (markup) |
|
813 pango_layout_set_markup(dc.plo, text, len); |
|
814 else |
|
815 pango_layout_set_text(dc.plo, text, len); |
812 pango_xft_render_layout(dc.xftdrawable, (col==dc.norm?dc.xftnorm:dc.xftsel)+(invert?ColBG:ColFG), dc.plo, x * PANGO_SCALE, y * PANGO_SCALE); |
816 pango_xft_render_layout(dc.xftdrawable, (col==dc.norm?dc.xftnorm:dc.xftsel)+(invert?ColBG:ColFG), dc.plo, x * PANGO_SCALE, y * PANGO_SCALE); |
813 } |
817 } |
814 |
818 |
815 void |
819 void |
816 enternotify(XEvent *e) { |
820 enternotify(XEvent *e) { |
1618 return; |
1622 return; |
1619 sendmon(selmon->sel, dirtomon(arg->i)); |
1623 sendmon(selmon->sel, dirtomon(arg->i)); |
1620 } |
1624 } |
1621 |
1625 |
1622 int |
1626 int |
1623 textnw(const char *text, unsigned int len) { |
1627 textnw(const char *text, unsigned int len, Bool markup) { |
1624 PangoRectangle r; |
1628 PangoRectangle r; |
1625 pango_layout_set_markup(dc.plo, text, len); |
1629 if (markup) |
|
1630 pango_layout_set_markup(dc.plo, text, len); |
|
1631 else { |
|
1632 pango_layout_set_attributes(dc.plo, NULL); |
|
1633 pango_layout_set_text(dc.plo, text, len); |
|
1634 } |
1626 pango_layout_get_extents(dc.plo, &r, 0); |
1635 pango_layout_get_extents(dc.plo, &r, 0); |
1627 return r.width / PANGO_SCALE; |
1636 return r.width / PANGO_SCALE; |
1628 } |
1637 } |
1629 |
1638 |
1630 void |
1639 void |