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