diff --git a/cmd/menu/main.c b/cmd/menu/main.c index 5d647257..819c0634 100644 --- a/cmd/menu/main.c +++ b/cmd/menu/main.c @@ -293,6 +293,8 @@ main(int argc, char *argv[]) { loadcolor(&cnorm, readctl("normcolors ")); loadcolor(&csel, readctl("focuscolors ")); font = loadfont(readctl("font ")); + sscanf(readctl("fontpad "), "%d %d %d %d", &font->pad.min.x, &font->pad.max.x, + &font->pad.min.x, &font->pad.max.y); if(!font) fatal("Can't load font %q", readctl("font ")); diff --git a/cmd/menu/menu.c b/cmd/menu/menu.c index 62500504..343fc40b 100644 --- a/cmd/menu/menu.c +++ b/cmd/menu/menu.c @@ -130,15 +130,15 @@ next: static void _menu_draw(bool draw) { - Rectangle r, rd, rp, r2; + Rectangle r, rd, rp, r2, extent; CTuple *c; Item *i; - int inputw, itemoff, end, pad, n; + int inputw, itemoff, end, pad, n, offset; r = barwin->r; r = rectsetorigin(r, ZP); - pad = (font->height & ~1); + pad = (font->height & ~1) + font->pad.min.x + font->pad.max.x; rd = r; rp = ZR; // SET(rp) @@ -208,7 +208,8 @@ _menu_draw(bool draw) { r2.max.x = promptw + inputw; drawstring(ibuf, font, r2, West, input.string, cnorm.fg); - r2.min.x = promptw + textwidth_l(font, input.string, input.pos - input.string) + pad/2 - 1; + extent = textextents_l(font, input.string, input.pos - input.string, &offset); + r2.min.x = promptw + offset + font->pad.min.x - extent.min.x + pad/2 - 1; r2.max.x = r2.min.x + 2; r2.min.y++; r2.max.y--; @@ -236,7 +237,7 @@ menu_show(void) { ltwidth = textwidth(font, "<"); pad = (font->height & ~1)/2; - height = font->height + 2; + height = labelh(font); r = scr.rect; if(ontop) diff --git a/cmd/wmii/bar.c b/cmd/wmii/bar.c index d4178651..13864814 100644 --- a/cmd/wmii/bar.c +++ b/cmd/wmii/bar.c @@ -140,7 +140,7 @@ bar_draw(WMScreen *s) { foreach_bar(s, b) { b->r.min = ZP; b->r.max.y = Dy(s->brect); - b->r.max.x = def.font->height & ~1; + b->r.max.x = (def.font->height & ~1) + def.font->pad.min.x + def.font->pad.max.x; if(b->text && strlen(b->text)) b->r.max.x += textwidth(def.font, b->text); width += Dx(b->r); diff --git a/cmd/wmii/frame.c b/cmd/wmii/frame.c index 228ca61e..ad5e3cca 100644 --- a/cmd/wmii/frame.c +++ b/cmd/wmii/frame.c @@ -466,8 +466,8 @@ frame_draw(Frame *f) { /* grabbox */ r.min = Pt(2, 2); - r.max.x = r.min.x + def.font->height - 3; r.max.y -= 2; + r.max.x = r.min.x + Dy(r); f->grabbox = r; if(c->urgent) diff --git a/cmd/wmii/message.c b/cmd/wmii/message.c index cf8a5283..51995351 100644 --- a/cmd/wmii/message.c +++ b/cmd/wmii/message.c @@ -35,6 +35,7 @@ enum { LEXEC, LFOCUSCOLORS, LFONT, + LFONTPAD, LGRABMOD, LGROW, LINCMODE, @@ -69,6 +70,7 @@ char *symtab[] = { "exec", "focuscolors", "font", + "fontpad", "grabmod", "grow", "incmode", @@ -265,6 +267,16 @@ getbase(const char **s, long *sign) { return ret; } +static bool +getint(const char *s, int *ret) { + long l; + bool res; + + res = getlong(s, &l); + *ret = l; + return res; +} + bool getlong(const char *s, long *ret) { const char *end; @@ -537,6 +549,18 @@ message_root(void *p, IxpMsg *m) { ret = "can't load font"; view_update(selview); break; + case LFONTPAD: + if(!getint(msg_getword(m), &def.font->pad.min.x) || + !getint(msg_getword(m), &def.font->pad.max.x) || + !getint(msg_getword(m), &def.font->pad.max.y) || + !getint(msg_getword(m), &def.font->pad.min.y)) + ret = "invalid rectangle"; + else { + for(n=0; n < nscreens; n++) + bar_resize(screens[n]); + view_update(selview); + } + break; case LGRABMOD: s = msg_getword(m); if(!parsekey(s, &i, nil) || i == 0) @@ -598,6 +622,8 @@ readctl_root(void) { } bufprint("focuscolors %s\n", def.focuscolor.colstr); bufprint("font %s\n", def.font->name); + bufprint("fontpad %d %d %d %d\n", def.font->pad.min.x, def.font->pad.max.x, + def.font->pad.max.y, def.font->pad.min.y); bufprint("grabmod %s\n", def.grabmod); bufprint("incmode %s\n", incmodetab[def.incmode]); bufprint("normcolors %s\n", def.normcolor.colstr); diff --git a/cmd/wmii/x11.c b/cmd/wmii/x11.c index 12023b4f..fdded900 100644 --- a/cmd/wmii/x11.c +++ b/cmd/wmii/x11.c @@ -537,8 +537,9 @@ uint drawstring(Image *dst, Font *font, Rectangle r, Align align, char *text, ulong col) { + Rectangle tr; char *buf; - uint x, y, w, h, len; + uint x, y, width, height, len; int shortened; shortened = 0; @@ -547,14 +548,22 @@ drawstring(Image *dst, Font *font, buf = emalloc(len+1); memcpy(buf, text, len+1); - h = font->ascent + font->descent; - y = r.min.y + Dy(r) / 2 - h / 2 + font->ascent; + r.max.y -= font->pad.min.y; + r.min.y += font->pad.max.y; + + height = font->ascent + font->descent; + y = r.min.y + Dy(r) / 2 - height / 2 + font->ascent; + + width = Dx(r) - font->pad.min.x - font->pad.max.x - (font->height & ~1); + + r.min.x += font->pad.min.x; + r.max.x -= font->pad.max.x; /* shorten text if necessary */ - w = 0; + tr = ZR; while(len > 0) { - w = textwidth_l(font, buf, len + min(shortened, 3)); - if(w <= Dx(r) - (font->height & ~1)) + tr = textextents_l(font, buf, len + min(shortened, 3), nil); + if(Dx(tr) <= width) break; while(len > 0 && (buf[--len]&0xC0) == 0x80) buf[len] = '.'; @@ -562,7 +571,7 @@ drawstring(Image *dst, Font *font, shortened++; } - if(len == 0 || w > Dx(r)) + if(len == 0 || Dx(tr) > width) goto done; /* mark shortened info in the string */ @@ -571,13 +580,13 @@ drawstring(Image *dst, Font *font, switch (align) { case East: - x = r.max.x - (w + (font->height / 2)); + x = r.max.x - (tr.max.x + (font->height / 2)); break; case Center: - x = r.min.x + (Dx(r) - w) / 2; + x = r.min.x + (Dx(r) - Dx(tr)) / 2 - tr.min.x; break; default: - x = r.min.x + (font->height / 2); + x = r.min.x + (font->height / 2) - tr.min.x; break; } @@ -605,7 +614,7 @@ drawstring(Image *dst, Font *font, done: free(buf); - return w; + return Dx(tr); } void @@ -745,26 +754,44 @@ freefont(Font *f) { free(f); } -uint -textwidth_l(Font *font, char *text, uint len) { +Rectangle +textextents_l(Font *font, char *text, uint len, int *offset) { + Rectangle rect; XRectangle r; XGlyphInfo i; + int unused; + + if(!offset) + offset = &unused; switch(font->type) { case FFontSet: - Xutf8TextExtents(font->font.set, text, len, nil, &r); - return r.width; + *offset = Xutf8TextExtents(font->font.set, text, len, &r, nil); + return Rect(r.x, -r.y - r.height, r.x + r.width, -r.y); case FXft: XftTextExtentsUtf8(display, font->font.xft, (uchar*)text, len, &i); - return i.width; + *offset = i.xOff; + return Rect(-i.x, i.y - i.height, -i.x + i.width, i.y); case FX11: - return XTextWidth(font->font.x11, text, len); + rect = ZR; + rect.max.x = XTextWidth(font->font.x11, text, len); + rect.max.y = font->ascent; + *offset = rect.max.x; + return rect; default: die("Invalid font type"); - return 0; /* shut up ken */ + return ZR; /* shut up ken */ } } +uint +textwidth_l(Font *font, char *text, uint len) { + Rectangle r; + + r = textextents_l(font, text, len, nil); + return Dx(r); +} + uint textwidth(Font *font, char *text) { return textwidth_l(font, text, strlen(text)); @@ -772,7 +799,7 @@ textwidth(Font *font, char *text) { uint labelh(Font *font) { - return font->height + 2; + return font->height + font->descent + font->pad.min.y + font->pad.max.y; } /* Misc */ diff --git a/cmd/wmiir.c b/cmd/wmiir.c index e719a98d..11dd7abc 100644 --- a/cmd/wmiir.c +++ b/cmd/wmiir.c @@ -367,6 +367,7 @@ struct exectab { {0, } }, utiltab[] = { {"namespace", xnamespace}, + {"ns", xnamespace}, {"setsid", xsetsid}, {0, } }; diff --git a/include/x11.h b/include/x11.h index 10cb4378..e3174e08 100644 --- a/include/x11.h +++ b/include/x11.h @@ -91,6 +91,7 @@ struct Font { XFontSet set; XftFont* xft; } font; + Rectangle pad; int ascent; int descent; uint height; @@ -261,6 +262,7 @@ Point subpt(Point, Point); void sync(void); uint textwidth(Font*, char*); uint textwidth_l(Font*, char*, uint len); +Rectangle textextents_l(Font*, char*, uint, int*); int traperrors(bool); Point translate(Window*, Window*, Point); void ungrabkeyboard(void);