wmii

git clone git://oldgit.suckless.org/wmii/
Log | Files | Refs | README | LICENSE

commit ed809b8471e3878bceb69b049bc28c25fc381b99
parent 8ca9f3ca3ad36073958c39721a168d1b633081e9
Author: Kris Maglione <kris@suckless.org>
Date:   Thu,  7 Oct 2010 16:31:41 -0400

[menu] Add vertical mode.

Diffstat:
alternative_wmiircs/python/pygmi/util.py | 8++++----
cmd/menu/Makefile | 5+++--
cmd/menu/caret.c | 8++------
cmd/menu/dat.h | 54+++++++++++++++++++++++++++---------------------------
cmd/menu/history.c | 12++++++------
cmd/menu/keys.c | 3++-
cmd/menu/main.c | 62++++++++++++++++++++++++++++++--------------------------------
cmd/menu/menu.c | 455++++++++++++++++++++++++++++++++++++++-----------------------------------------
cmd/tray/main.c | 2+-
cmd/wmii/bar.c | 4+---
cmd/wmii/client.c | 23++++++++++++++---------
cmd/wmii/dat.h | 3+--
cmd/wmii/frame.c | 42++++++++++++++++++------------------------
cmd/wmii/main.c | 6++----
cmd/wmii/message.c | 3+--
cmd/wmiir.c | 2+-
cmd/x11/wmii9menu.c | 82++++++++++++++++++-------------------------------------------------------------
img/mkfile | 33+++++++++++++++++----------------
include/stuff/clientutil.h | 2+-
include/stuff/geom.h | 4++--
include/stuff/util.h | 7++++---
include/stuff/x11.h | 1+
lib/libstuff/client_readconfig.c | 10+++++-----
lib/libstuff/clientutil.c | 21+++++++++++----------
lib/libstuff/x11/drawing/drawstring.c | 11+++++++++++
mk/common.mk | 4++--
util/compile | 2+-
27 files changed, 402 insertions(+), 467 deletions(-)

diff --git a/alternative_wmiircs/python/pygmi/util.py b/alternative_wmiircs/python/pygmi/util.py @@ -29,14 +29,14 @@ def message(message): call(*args, input=message) def program_list(path): - names = [] + names = set() for d in path: try: for f in os.listdir(d): p = '%s/%s' % (d, f) - if f not in names and os.access(p, os.X_OK) and ( - os.path.isfile(p) or os.path.islink(p)): - names.append(f) + if (f not in names and os.access(p, os.X_OK) and + os.path.isfile(p)): + names.add(f) except Exception: pass return sorted(names) diff --git a/cmd/menu/Makefile b/cmd/menu/Makefile @@ -5,12 +5,13 @@ include $(ROOT)/mk/wmii.mk main.c: $(ROOT)/mk/wmii.mk bindings.c: keys.txt Makefile - ( echo "char binding_spec[] = "; \ + ( echo "char binding_spec[] ="; \ sed 's/.*/ "&\\n"/' keys.txt; \ - echo " ;" ) >bindings.c + echo " ;" ) >$@ TARG = wimenu HFILES= dat.h fns.h +TAGFILES= dat.h PACKAGES += $(X11PACKAGES) diff --git a/cmd/menu/caret.c b/cmd/menu/caret.c @@ -69,9 +69,7 @@ caret_find(int dir, int type) { p = next; return p; case CHAR: - if(p < end) - return p+1; - return p; + return next_rune(p, &r); } } else if(dir == BACKWARD) { @@ -88,9 +86,7 @@ caret_find(int dir, int type) { p = next; return p; case CHAR: - if(p > end) - return prev_rune(end, p, &r); - return end; + return prev_rune(end, p, &r); } } input.pos_end = nil; diff --git a/cmd/menu/dat.h b/cmd/menu/dat.h @@ -11,8 +11,6 @@ #include <stuff/x.h> #include <stuff/util.h> -#define BLOCK(x) do { x; }while(0) - #ifndef EXTERN # define EXTERN extern #endif @@ -69,38 +67,40 @@ EXTERN struct { int filter_start; } input; -extern char binding_spec[]; - -EXTERN int numlock; - -EXTERN long xtime; -EXTERN Image* ibuf; -EXTERN Font* font; -EXTERN CTuple cnorm, csel; -EXTERN bool ontop; +EXTERN struct { + Window* win; + Image* buf; + char* prompt; + int height; + int rows; + bool ontop; + Rectangle itemr; + Point arrow; +} menu; -EXTERN Cursor cursor[1]; -EXTERN Visual* render_visual; +extern char binding_spec[]; EXTERN IxpServer srv; -EXTERN Window* barwin; - -EXTERN Item* items; -EXTERN Item* matchfirst; -EXTERN Item* matchstart; -EXTERN Item* matchend; -EXTERN Item* matchidx; +EXTERN struct { + Item* all; + Item* first; + Item* start; + Item* end; + Item* sel; + int maxwidth; +} match; + +Font* font; +CTuple cnorm; +CTuple csel; EXTERN Item hist; -EXTERN Item* histidx; +EXTERN Item* histsel; -EXTERN int maxwidth; +EXTERN int itempad; EXTERN int result; -EXTERN char* (*find)(const char*, const char*); -EXTERN int (*compare)(const char*, const char*, size_t); - -EXTERN char* prompt; -EXTERN int promptw; +EXTERN char* (*find)(const char*, const char*); +EXTERN int (*compare)(const char*, const char*, size_t); diff --git a/cmd/menu/history.c b/cmd/menu/history.c @@ -19,25 +19,25 @@ history_search(int dir, char *string, int n) { Item *i; if(dir == FORWARD) { - if(histidx == &hist) + if(histsel == &hist) return hist.string; - for(i=histidx->next; i != hist.next; i=i->next) + for(i=histsel->next; i != hist.next; i=i->next) if(!i->string || !compare(i->string, string, n)) { - histidx = i; + histsel = i; return i->string; } return string; } assert(dir == BACKWARD); - if(histidx == &hist) { + if(histsel == &hist) { free(hist.string); hist.string = estrdup(input.string); } - for(i=histidx->prev; i != &hist; i=i->prev) + for(i=histsel->prev; i != &hist; i=i->prev) if(!compare(i->string, string, n)) { - histidx = i; + histsel = i; return i->string; } return string; diff --git a/cmd/menu/keys.c b/cmd/menu/keys.c @@ -13,7 +13,8 @@ struct Key { char** action; }; -static Key* bindings; +static Key* bindings; +static int numlock; /* * To do: Find my red black tree implementation. diff --git a/cmd/menu/main.c b/cmd/menu/main.c @@ -1,8 +1,6 @@ /* Copyright ©2006-2010 Kris Maglione <maglione.k at Gmail> * See LICENSE file for license details. */ -#define IXP_NO_P9_ -#define IXP_P9_STRUCTS #define EXTERN #include "dat.h" #include <X11/Xproto.h> @@ -23,7 +21,9 @@ static int screen_hint; static void usage(void) { - fatal("usage: wimenu -i [-h <history>] [-a <address>] [-p <prompt>] [-s <screen>]\n"); + fprint(2, "usage: %s -i [-a <address>] [-h <history>] [-p <prompt>] [-r <rows>] [-s <screen>]\n", argv0); + fprint(2, " See manual page for full usage details.\n"); + exit(1); } static int @@ -50,13 +50,13 @@ populate_list(Biobuf *buf, bool hist) { bool stop; stop = !hist && !isatty(buf->fid); + ret.next_link = nil; i = &ret; while((p = Brdstr(buf, '\n', true))) { if(stop && p[0] == '\0') break; - link(i, emallocz(sizeof *i)); - i->next_link = i->next; - i = i->next; + i->next_link = emallocz(sizeof *i); + i = i->next_link; i->string = p; i->retstring = p; if(cmdsep && (p = strstr(p, cmdsep))) { @@ -65,15 +65,12 @@ populate_list(Biobuf *buf, bool hist) { } if(!hist) { i->len = strlen(i->string); - i->width = textwidth_l(font, i->string, i->len); - if(i->width > maxwidth) - maxwidth = i->width; + i->width = textwidth_l(font, i->string, i->len) + itempad; + match.maxwidth = max(i->width, match.maxwidth); } } - link(i, &ret); - splice(&ret); - return ret.next != &ret ? ret.next : nil; + return ret.next_link; } static void @@ -86,7 +83,7 @@ check_competions(IxpConn *c) { return; } input.filter_start = strtol(s, nil, 10); - items = populate_list(cmplbuf, false); + match.all = populate_list(cmplbuf, false); update_filter(false); menu_draw(); } @@ -143,8 +140,8 @@ update_filter(bool print) { if(input.pos < input.end) filter = freelater(estrndup(filter, input.pos - filter)); - matchidx = nil; - matchfirst = matchstart = filter_list(items, filter); + match.sel = nil; + match.first = match.start = filter_list(match.all, filter); if(print) update_input(); } @@ -158,8 +155,7 @@ init_screens(void) { int i, n; rects = xinerama_screens(&n); - if (screen_hint >= 0 && screen_hint < n) - /* We were given a valid screen index, use that. */ + if(screen_hint >= 0 && screen_hint < n) i = screen_hint; else { /* Pick the screen with the pointer, for now. Later, @@ -178,11 +174,11 @@ init_screens(void) { int main(int argc, char *argv[]) { - Item *item; static char *address; static char *histfile; static char *keyfile; static bool nokeys; + Item *item; int i; long ndump; @@ -220,7 +216,10 @@ main(int argc, char *argv[]) { ndump = strtol(EARGF(usage()), nil, 10); break; case 'p': - prompt = EARGF(usage()); + menu.prompt = EARGF(usage()); + break; + case 'r': + menu.rows = strtol(EARGF(usage()), nil, 10); break; case 's': screen_hint = strtol(EARGF(usage()), nil, 10); @@ -249,11 +248,13 @@ main(int argc, char *argv[]) { srv.preselect = event_preselect; ixp_listen(&srv, ConnectionNumber(display), nil, event_fdready, event_fdclosed); - ontop = !strcmp(readctl("bar on "), "top"); + menu.ontop = !strcmp(readctl("/ctl", "bar "), "on top"); client_readconfig(&cnorm, &csel, &font); + itempad = (font->height & ~1) + font->pad.min.x + font->pad.max.x; + cmplbuf = Bfdopen(0, OREAD); - items = populate_list(cmplbuf, false); + match.all = populate_list(cmplbuf, false); if(!isatty(cmplbuf->fid)) ixp_listen(&srv, cmplbuf->fid, inbuf, check_competions, nil); @@ -268,21 +269,18 @@ main(int argc, char *argv[]) { parse_keys(buffer); } - histidx = &hist; + histsel = &hist; link(&hist, &hist); - if(histfile) { - inbuf = Bopen(histfile, OREAD); - if(inbuf) { - item = populate_list(inbuf, true); - if(item) { - link(item->prev, &hist); - link(&hist, item); - } - Bterm(inbuf); + if(histfile && (inbuf = Bopen(histfile, OREAD))) { + item = filter_list(populate_list(inbuf, true), ""); + if(item->string) { + link(item->prev, &hist); + link(&hist, item); } + Bterm(inbuf); } - if(barwin == nil) + if(menu.win == nil) menu_init(); init_screens(); diff --git a/cmd/menu/menu.c b/cmd/menu/menu.c @@ -4,270 +4,220 @@ #include <unistd.h> #include "fns.h" -static Handlers handlers; - -static int ltwidth; - -static void _menu_draw(bool); - -enum { - ACCEPT = CARET_LAST, - REJECT, - HIST, - KILL, - CMPL_NEXT, - CMPL_PREV, - CMPL_FIRST, - CMPL_LAST, - CMPL_NEXT_PAGE, - CMPL_PREV_PAGE, -}; +static Handlers handlers; +static int promptw; void menu_init(void) { WinAttr wa; wa.event_mask = ExposureMask | KeyPressMask; - barwin = createwindow(&scr.root, Rect(-1, -1, 1, 1), scr.depth, InputOutput, - &wa, CWEventMask); + menu.win = createwindow(&scr.root, Rect(-1, -1, 1, 1), scr.depth, InputOutput, + &wa, CWEventMask); if(scr.xim) - barwin->xic = XCreateIC(scr.xim, - XNInputStyle, XIMPreeditNothing | XIMStatusNothing, - XNClientWindow, barwin->xid, - XNFocusWindow, barwin->xid, - nil); + menu.win->xic = XCreateIC(scr.xim, + XNInputStyle, XIMPreeditNothing | XIMStatusNothing, + XNClientWindow, menu.win->xid, + XNFocusWindow, menu.win->xid, + nil); - changeprop_long(barwin, Net("WM_WINDOW_TYPE"), "ATOM", - (long[]){ TYPE("MENU") }, 1); - changeprop_string(barwin, "_WMII_TAGS", "sel"); - changeprop_textlist(barwin, "WM_CLASS", "STRING", - (char*[3]){ "wimenu", "wimenu", nil }); + changeprop_long(menu.win, Net("WM_WINDOW_TYPE"), "ATOM", (long[]){ TYPE("MENU") }, 1); + changeprop_string(menu.win, "_WMII_TAGS", "sel"); + changeprop_textlist(menu.win, "WM_CLASS", "STRING", (char*[3]){ "wimenu", "wimenu" }); - sethandler(barwin, &handlers); - mapwin(barwin); + sethandler(menu.win, &handlers); + mapwin(menu.win); int i = 0; - while(!grabkeyboard(barwin)) { + while(!grabkeyboard(menu.win)) { if(i++ > 1000) fatal("can't grab keyboard"); usleep(1000); } } -static void -menu_unmap(long id, void *p) { +void +menu_show(void) { + Rectangle r; - USED(id, p); - unmapwin(barwin); - XFlush(display); -} + if(menu.prompt) + promptw = textwidth(font, menu.prompt) + itempad; -static void -selectitem(Item *i) { - if(i != matchidx) { - caret_set(input.filter_start, input.pos - input.string); - caret_insert(i->string, 0); - matchidx = i; - } -} + r = textextents_l(font, "<", 1, nil); + menu.arrow = Pt(Dy(r) + itempad/2, Dx(r) + itempad/2); -static void -menu_cmd(int op, int motion) { - int n; - - switch(op) { - case HIST: - n = input.pos - input.string; - caret_insert(history_search(motion, input.string, n), true); - input.pos = input.string + n; - break; - case KILL: - caret_delete(BACKWARD, motion); - break; - default: - goto next; - } - update_filter(true); -next: - switch(op) { - case ACCEPT: - srv.running = false; - if(!matchidx && matchfirst->retstring && !motion) - if(input.filter_start == 0 && input.pos == input.end) - menu_cmd(CMPL_FIRST, 0); - if(!motion && matchidx && !strcmp(input.string, matchidx->string)) - lprint(1, "%s", matchidx->retstring); - else - lprint(1, "%s", input.string); - break; - case REJECT: - srv.running = false; - result = 1; - break; - case BACKWARD: - case FORWARD: - caret_move(op, motion); - update_input(); - break; - case CMPL_NEXT: - selectitem(matchidx ? matchidx->next : matchfirst); - break; - case CMPL_PREV: - selectitem((matchidx ? matchidx : matchstart)->prev); - break; - case CMPL_FIRST: - matchstart = matchfirst; - matchend = nil; - selectitem(matchstart); - break; - case CMPL_LAST: - selectitem(matchfirst->prev); - break; - case CMPL_NEXT_PAGE: - if(matchend) - selectitem(matchend->next); - break; - case CMPL_PREV_PAGE: - matchend = matchstart->prev; - matchidx = nil; - _menu_draw(false); - selectitem(matchstart); - break; - } + menu.height = labelh(font); + + freeimage(menu.buf); + menu.buf = allocimage(Dx(scr.rect), + !!menu.rows * 2 * menu.arrow.y + (menu.rows + 1) * menu.height, + menu.win->depth); + + mapwin(menu.win); + raisewin(menu.win); menu_draw(); } +/* I'd prefer to use ⌃ and ⌄, but few fonts support them. */ static void -_menu_draw(bool draw) { - Rectangle r, rd, rp, r2, extent; - CTuple *c; - Item *i; - int inputw, itemoff, end, pad, n, offset; - - r = barwin->r; - r = rectsetorigin(r, ZP); - - pad = (font->height & ~1) + font->pad.min.x + font->pad.max.x; - - rd = r; - rp = ZR; // SET(rp) - if (prompt) { - if (!promptw) - promptw = textwidth(font, prompt) + 2 * ltwidth + pad; - rd.min.x += promptw; - - rp = r; - rp.max.x = promptw; - } - - inputw = min(Dx(rd) / 3, maxwidth); - inputw = max(inputw, textwidth(font, input.string)) + pad; - itemoff = inputw + 2 * ltwidth; - end = Dx(rd) - ltwidth; - - fill(ibuf, r, &cnorm.bg); - - if(matchend && matchidx == matchend->next) - matchstart = matchidx; - else if(matchidx == matchstart->prev) - matchend = matchidx; - if (matchend == nil) - matchend = matchstart; - - if(matchend == matchstart->prev && matchstart != matchidx) { - n = itemoff; - matchstart = matchend; - for(i=matchend; ; i=i->prev) { - n += i->width + pad; - if(n > end) - break; - matchstart = i; - if(i == matchfirst) - break; - } - } - - if(!draw) - return; +drawarrow(Image *img, Rectangle r, int up, Color *col) { + Point p[3], pt; - r2 = rd; - for(i=matchstart; i->string; i=i->next) { - r2.min.x = promptw + itemoff; - itemoff = itemoff + i->width + pad; - r2.max.x = promptw + min(itemoff, end); - if(i != matchstart && itemoff > end) - break; - - c = (i == matchidx) ? &csel : &cnorm; - fill(ibuf, r2, &c->bg); - drawstring(ibuf, font, r2, Center, i->string, &c->fg); - matchend = i; - if(i->next == matchfirst) - break; - } + pt = Pt(menu.arrow.x - itempad/2, menu.arrow.y - itempad/2 & ~1); - r2 = rd; - r2.min.x = promptw + inputw; - if(matchstart != matchfirst) - drawstring(ibuf, font, r2, West, "<", &cnorm.fg); - if(matchend->next != matchfirst) - drawstring(ibuf, font, r2, East, ">", &cnorm.fg); + p[1] = Pt(r.min.x + Dx(r)/2, up ? r.min.y + itempad/4 : r.max.y - itempad/4); + p[0] = Pt(p[1].x - pt.x/2, up ? p[1].y + pt.y : p[1].y - pt.y); + p[2] = Pt(p[1].x + pt.x/2, p[0].y); + drawpoly(img, p, nelem(p), CapProjecting, 1, col); +} - r2 = rd; - r2.max.x = promptw + inputw; - drawstring(ibuf, font, r2, West, input.string, &cnorm.fg); +static Rectangle +slice(Rectangle *rp, int x, int y) { + Rectangle r; - 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--; - border(ibuf, r2, 1, &cnorm.border); + r = *rp; + if(x) + rp->min.x += x, r.max.x = min(rp->min.x, rp->max.x); + if(y) + rp->min.y += y, r.max.y = min(rp->min.y, rp->max.y); + return r; +} - if (prompt) - drawstring(ibuf, font, rp, West, prompt, &cnorm.fg); +static bool +nextrect(Item *i, Rectangle *rp, Rectangle *src) { + Rectangle r; - border(ibuf, rd, 1, &cnorm.border); - copyimage(barwin, r, ibuf, ZP); + if(menu.rows) + r = slice(src, 0, menu.height); + else + r = slice(src, i->width, 0); + return (Dx(*src) >= 0 && Dy(*src) >= 0) && (*rp = r, 1); } void menu_draw(void) { - _menu_draw(true); -} - -void -menu_show(void) { - Rectangle r; - int height, pad; - - USED(menu_unmap); - - ltwidth = textwidth(font, "<"); + Rectangle barr, extent, itemr, inputr, r, r2; + Item *item; + int inputw, offset; + + barr = r2 = Rect(0, 0, Dx(menu.win->r), menu.height); + + inputw = max(match.maxwidth + textwidth_l(font, input.string, min(input.filter_start, strlen(input.string))), + max(itempad + textwidth(font, input.string), + Dx(barr) / 3)); + + /* Calculate items box, w/ and w/o arrows */ + if(menu.rows) { + menu.itemr = barr; + menu.itemr.max.y += Dy(barr) * (menu.rows - 1); + if(menu.ontop) + menu.itemr = rectaddpt(menu.itemr, Pt(0, Dy(barr))); + itemr = menu.itemr; + if(match.start != match.first) + menu.itemr = rectaddpt(menu.itemr, Pt(0, menu.arrow.y)); + } + else { + itemr = r2; + slice(&itemr, inputw + promptw, 0); + menu.itemr = Rect(itemr.min.x + menu.arrow.x, itemr.min.y, + itemr.max.x - menu.arrow.x, itemr.max.y); + } - pad = (font->height & ~1)/2; - height = labelh(font); + fill(menu.buf, menu.buf->r, &cnorm.bg); + + /* Draw items */ + item = match.start, r2 = menu.itemr; + nextrect(item, &r, &r2); + do { + match.end = item; + if(item->string) + fillstring(menu.buf, font, r, West, item->string, + (item == match.sel ? &csel : &cnorm), 0); + item = item->next; + } while(item != match.first && nextrect(item, &r, &r2)); + + /* Adjust dimensions for arrows/number of items */ + if(menu.rows) + itemr.max.y = r.max.y + (match.end->next != match.first ? menu.arrow.y : 0); + else + itemr.max.x = r.max.x + menu.arrow.x; + if(menu.rows && !menu.ontop) + barr = rectaddpt(barr, Pt(0, itemr.max.y)); + + /* Draw indicators */ + if(!menu.rows && match.start != match.first) + drawstring(menu.buf, font, itemr, West, "<", &cnorm.fg); + if(!menu.rows && match.end->next != match.first) + drawstring(menu.buf, font, itemr, East, ">", &cnorm.fg); + + if(menu.rows && match.start != match.first) + drawarrow(menu.buf, itemr, 1, &cnorm.fg); + if(menu.rows && match.end->next != match.first) + drawarrow(menu.buf, itemr, 0, &cnorm.fg); + + /* Draw prompt */ + r2 = barr; + if(menu.prompt) + drawstring(menu.buf, font, slice(&r2, promptw, 0), + West, menu.prompt, &cnorm.fg); + + /* Border input/horizontal items */ + border(menu.buf, r2, 1, &cnorm.border); + + /* Draw input */ + inputr = slice(&r2, inputw, 0); + drawstring(menu.buf, font, inputr, West, input.string, &cnorm.fg); + + /* Draw cursor */ + extent = textextents_l(font, input.string, input.pos - input.string, &offset); + r2 = insetrect(inputr, 2); + r2.min.x = inputr.min.x - extent.min.x + offset + font->pad.min.x + itempad/2 - 1; + r2.max.x = r2.min.x + 1; + fill(menu.buf, r2, &cnorm.border); + /* Reshape window */ r = scr.rect; - if(ontop) - r.max.y = r.min.y + height; + if(menu.ontop) + r.max.y = r.min.y + itemr.max.y; else - r.min.y = r.max.y - height; - reshapewin(barwin, r); + r.min.y = r.max.y - barr.max.y; + reshapewin(menu.win, r); - freeimage(ibuf); - ibuf = allocimage(Dx(r), Dy(r), scr.depth); + /* Border window */ + r = rectsubpt(r, r.min); + border(menu.buf, r, 1, &cnorm.border); + copyimage(menu.win, r, menu.buf, ZP); +} - mapwin(barwin); - raisewin(barwin); - menu_draw(); +static Item* +pagestart(Item *i) { + Rectangle r, r2; + + r = menu.itemr; + nextrect(i, &r2, &r); + while(i->prev != match.first->prev && nextrect(i->prev, &r2, &r)) + i = i->prev; + return i; +} + +static void +selectitem(Item *i) { + if(i != match.sel) { + caret_set(input.filter_start, input.pos - input.string); + caret_insert(i->string, 0); + match.sel = i; + if(i == match.start->prev) + match.start = pagestart(i); + if(i == match.end->next) + match.start = i; + } } static bool kdown_event(Window *w, void *aux, XKeyEvent *e) { char **action, **p; char *key; - char buf[32]; + char buf[128]; int num, status; KeySym ksym; @@ -276,8 +226,7 @@ kdown_event(Window *w, void *aux, XKeyEvent *e) { status = XLookupBoth; if(w->xic) - num = Xutf8LookupString(w->xic, e, buf, sizeof buf - 1, &ksym, - &status); + num = Xutf8LookupString(w->xic, e, buf, sizeof buf - 1, &ksym, &status); else num = XLookupString(e, buf, sizeof buf - 1, &ksym, nil); @@ -319,37 +268,65 @@ kdown_event(Window *w, void *aux, XKeyEvent *e) { have(LWORD) ? WORD : have(LLINE) ? LINE : -1); + switch(getsym(action[0])) { + default: + return false; + case LHISTORY: + num = input.pos - input.string; + amount = have(LBACKWARD) ? BACKWARD : FORWARD; + caret_insert(history_search(amount, input.string, num), true); + input.pos = input.string + num; + update_filter(true); + break; + case LKILL: + caret_delete(BACKWARD, amount); + update_filter(true); + break; + case LACCEPT: - menu_cmd(ACCEPT, have(LLITERAL)); + srv.running = false; + if(!have(LLITERAL) && !match.sel && match.start->retstring) + if(input.filter_start == 0 && input.pos == input.end) + selectitem(match.start); + + if(!have(LLITERAL) && match.sel && !strcmp(input.string, match.sel->string)) + lprint(1, "%s", match.sel->retstring); + else + lprint(1, "%s", input.string); break; case LBACKWARD: - menu_cmd(BACKWARD, amount); + caret_move(BACKWARD, amount); + update_input(); break; case LCOMPLETE: - amount = ( - have(LNEXT) ? CMPL_NEXT : - have(LPREV) ? CMPL_PREV : - have(LNEXTPAGE) ? CMPL_NEXT_PAGE : - have(LPREVPAGE) ? CMPL_PREV_PAGE : - have(LFIRST) ? CMPL_FIRST : - have(LLAST) ? CMPL_LAST : - CMPL_NEXT); - menu_cmd(amount, 0); + if(have(LNEXT)) + selectitem(match.sel ? match.sel->next : match.first); + else if(have(LPREV)) + selectitem((match.sel ? match.sel : match.start)->prev); + else if(have(LFIRST)) { + match.start = match.first; + selectitem(match.start); + } + else if(have(LLAST)) + selectitem(match.first->prev); + else if(have(LNEXTPAGE)) + selectitem(match.end->next); + else if(have(LPREVPAGE)) { + match.start = pagestart(match.start->prev); + selectitem(match.start); + } break; case LFORWARD: - menu_cmd(FORWARD, amount); - break; - case LHISTORY: - menu_cmd(HIST, have(LBACKWARD) ? BACKWARD : FORWARD); - break; - case LKILL: - menu_cmd(KILL, amount); + caret_move(FORWARD, amount); + update_input(); break; case LREJECT: - menu_cmd(REJECT, 0); + srv.running = false; + result = 1; break; } + menu_draw(); } return false; } diff --git a/cmd/tray/main.c b/cmd/tray/main.c @@ -191,7 +191,7 @@ main(int argc, char *argv[]) { client_init(nil); if(tray.edge == 0) - tray.edge = West | (!strcmp(readctl("bar on "), "top") ? North : South); + tray.edge = West | (!strcmp(readctl("/ctl", "bar on "), "top") ? North : South); client_readconfig(&tray.normcolors, &tray.selcolors, &tray.font); diff --git a/cmd/wmii/bar.c b/cmd/wmii/bar.c @@ -195,9 +195,7 @@ bar_draw(WMScreen *s) { align = Center; if(b == s->bar[BRight]) align = East; - fill(ibuf, b->r, &b->colors.bg); - drawstring(ibuf, def.font, b->r, align, b->text, &b->colors.fg); - border(ibuf, b->r, 1, &b->colors.border); + fillstring(ibuf, def.font, b->r, align, b->text, &b->colors, 1); } if(s->barwin_rgba != (s->barwin->depth == 32)) diff --git a/cmd/wmii/client.c b/cmd/wmii/client.c @@ -220,7 +220,8 @@ apply_rules(Client *c) { bool ret, more; ret = true; - for(r=def.rules.rule; r; r=r->next) + more = true; + for(r=def.rules.rule; r && more; r=r->next) if(regexec(r->regex, c->props, nil, 0)) { more = false; for(rv=r->values; rv; rv=rv->next) { @@ -234,15 +235,15 @@ apply_rules(Client *c) { }else { bufclear(); bufprint("%s %s", rv->key, rv->value); - m = ixp_message(buffer, sizeof buffer, MsgPack); - if(!waserror()) { + m = ixp_message(buffer, _buf_end - buffer, MsgPack); + if(waserror()) + warning("processing rule %q=%q: %r", rv->key, rv->value); + else { message_client(c, &m); poperror(); } } } - if(!more) - return ret; } return ret; } @@ -1093,6 +1094,11 @@ client_extratags(Client *c) { toks[i] = nil; tags = comm(CLeft, toks, c->retags); + if(i == 1 && !c->tagre.regex && !c->tagvre.regex) { + free(tags); + return nil; + } + fmtstrinit(&fmt); if(i > 1) join(tags, "+", &fmt); @@ -1131,17 +1137,16 @@ client_applytags(Client *c, const char *tags) { /* Check for regex. */ if(cur[0] == '/') { cur++; - *strchr(cur, '/') = '\0'; + *strrchr(cur, '/') = '\0'; if(add == '+') reinit(&c->tagre, cur); else if(add == '-') reinit(&c->tagvre, cur); } - - trim(cur, " \t\r\n"); - if(!strcmp(cur, "~")) + else if(!strcmp(cur, "~")) c->floating = add ? On : Never; else { + trim(cur, " \t\r\n"); if(!strcmp(cur, "sel")) cur = selview->name; else if(Mbsearch(cur, badtags, bsstrcmp)) diff --git a/cmd/wmii/dat.h b/cmd/wmii/dat.h @@ -313,8 +313,7 @@ EXTERN struct Defs { uint keyssz; Ruleset colrules; Ruleset rules; - char grabmod[5]; - ulong mod; + long mod; uint border; uint snap; int colmode; diff --git a/cmd/wmii/frame.c b/cmd/wmii/frame.c @@ -398,6 +398,7 @@ pushlabel(Image *img, Rectangle *rp, char *s, CTuple *col) { w = min(w, Dx(*rp) - 30); /* Magic number. */ if(w > 0) { r = *rp; + r.min.x = r.max.x - w; rp->max.x -= w; if(0) drawline(img, Pt(rp->max.x, r.min.y+2), @@ -406,6 +407,7 @@ pushlabel(Image *img, Rectangle *rp, char *s, CTuple *col) { drawstring(img, def.font, r, East, s, &col->fg); } + free(s); } void @@ -415,7 +417,6 @@ frame_draw(Frame *f) { CTuple *col; Image *img; char *s; - uint w; int n, m; if(f == nil || f->view != selview || f->area == nil) @@ -443,6 +444,9 @@ frame_draw(Frame *f) { f->titlebar = insetrect(r, 3); f->titlebar.max.y += 3; + f->grabbox = insetrect(r, 2); + f->grabbox.max.x = f->grabbox.min.x + Dy(f->grabbox); + /* Odd focus. Unselected, with keyboard focus. */ /* Draw a border just inside the titlebar. */ if(c != selclient() && c == disp.focus) { @@ -450,15 +454,9 @@ frame_draw(Frame *f) { border(img, insetrect(r, 2), 1, &def.focuscolor.border); } - /* grabbox */ - r.min = Pt(2, 2); - r.max.y -= 2; - r.max.x = r.min.x + Dy(r); - f->grabbox = r; - if(c->urgent) - fill(img, r, &col->fg); - border(img, r, 1, &col->border); + fill(img, f->grabbox, &col->fg); + border(img, f->grabbox, 1, &col->border); /* Odd focus. Selected, without keyboard focus. */ /* Draw a border around the grabbox. */ @@ -466,38 +464,34 @@ frame_draw(Frame *f) { border(img, insetrect(r, -1), 1, &def.normcolor.bg); /* Draw a border on borderless+titleless selected apps. */ - if(f->area->floating && c->borderless && c->titleless && !c->fullscreen && c == selclient()) + if(c->borderless && c->titleless && f->area->floating && !c->fullscreen && c == selclient()) setborder(c->framewin, def.border, &def.focuscolor.border); else setborder(c->framewin, 0, &def.focuscolor.border); /* Label */ - r.min.x = r.max.x; - r.max.x = fr.max.x; - r.min.y = 0; - r.max.y = labelh(def.font); + r = Rect(f->grabbox.max.x, 0, fr.max.x, labelh(def.font)); + /* Draw count on frames in 'max' columns. */ if(f->area->max && !resizing) { - /* XXX */ n = stack_count(f, &m); - s = smprint("%d/%d", m, n); - pushlabel(img, &r, s, col); - free(s); + pushlabel(img, &r, smprint("%d/%d", m, n), col); } + /* Label clients with extra tags. */ - if((s = client_extratags(c))) { + if((s = client_extratags(c))) pushlabel(img, &r, s, col); - free(s); - }else if(f->area->floating) /* Make sure floating clients have room for their indicators. */ - r.max.x -= Dx(f->grabbox); + + if(f->area->floating) /* Make sure floating clients have room for their indicators. */ + r.max.x -= f->grabbox.max.x; if(!ewmh_responsive_p(c)) r.min.x += drawstring(img, def.font, r, West, "(wedged) ", &col->fg); - w = drawstring(img, def.font, r, West, c->name, &col->fg); + r.min.x += drawstring(img, def.font, r, West, c->name, &col->fg); /* Draw inner border on floating clients. */ if(f->area->floating) { - r.min.x = r.min.x + w + 10; + r.min.x += 10; r.max.x += Dx(f->grabbox); r.min.y = f->grabbox.min.y; r.max.y = f->grabbox.max.y; diff --git a/cmd/wmii/main.c b/cmd/wmii/main.c @@ -372,8 +372,7 @@ main(int argc, char *argv[]) { initdisplay(); traperrors(true); - selectinput(&scr.root, EnterWindowMask - | SubstructureRedirectMask); + selectinput(&scr.root, SubstructureRedirectMask); if(traperrors(false)) fatal("another window manager is already running"); @@ -388,7 +387,7 @@ main(int argc, char *argv[]) { sock = ixp_announce(address); if(sock < 0) - fatal("Can't create socket '%s': %r", address); + fatal("Can't create socket %q: %r", address); closeexec(ConnectionNumber(display)); closeexec(sock); @@ -413,7 +412,6 @@ main(int argc, char *argv[]) { def.incmode = ISqueeze; def.mod = Mod1Mask; - strcpy(def.grabmod, "Mod1"); loadcolor(&def.focuscolor, FOCUSCOLORS, nil); loadcolor(&def.normcolor, NORMCOLORS, nil); diff --git a/cmd/wmii/message.c b/cmd/wmii/message.c @@ -656,7 +656,6 @@ message_root(void *p, IxpMsg *m) { if(!parsekey(s, &i, nil) || i == 0) return Ebadvalue; - utflcpy(def.grabmod, s, sizeof def.grabmod); def.mod = i; break; case LINCMODE: @@ -700,7 +699,7 @@ readctl_root(void) { 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("grabmod %s\n", (Mask){&def.mod, modkey_names}); bufprint("incmode %s\n", incmodetab[def.incmode]); bufprint("normcolors %s\n", def.normcolor.colstr); bufprint("view %s\n", selview->name); diff --git a/cmd/wmiir.c b/cmd/wmiir.c @@ -426,7 +426,7 @@ xnamespace(int argc, char *argv[]) { path = ixp_namespace(); if(path == nil) fatal("can't find namespace: %r\n"); - Blprint(outbuf, "%s\n", path); + Blprint(outbuf, "%s", path); return 0; } diff --git a/cmd/x11/wmii9menu.c b/cmd/x11/wmii9menu.c @@ -58,15 +58,8 @@ static Font* font; static int wborder; -char buffer[8092]; -char* _buffer; - -/* for XSetWMProperties to use */ -int g_argc; -char **g_argv; - -char *initial = ""; -int cur; +static char* initial = ""; +static int cur; static char** labels; /* list of labels and commands */ static char** commands; @@ -78,13 +71,7 @@ void create_window(void); void size_window(int, int); void redraw(int, int); void warpmouse(int, int); -void memory(void); -int args(void); - -Cursor cursor[1]; -Visual* render_visual; -void init_screens(void); void init_screens(void) { Rectangle *rects; @@ -111,9 +98,6 @@ main(int argc, char **argv) char *cp; int i; - g_argc = argc; - g_argv = argv; - ARGBEGIN{ case 'v': lprint(1, "%s\n", version); @@ -137,29 +121,24 @@ main(int argc, char **argv) create_window(); numitems = argc; - labels = emalloc(numitems * sizeof *labels); commands = emalloc(numitems * sizeof *labels); for(i = 0; i < numitems; i++) { labels[i] = argv[i]; + commands[i] = argv[i]; if((cp = strchr(labels[i], ':')) != nil) { *cp++ = '\0'; commands[i] = cp; - } else - commands[i] = labels[i]; + } if(strcmp(labels[i], initial) == 0) cur = i; } client_init(address); - wborder = strtol(readctl("border "), nil, 10); - loadcolor(&cnorm, readctl("normcolors "), nil); - loadcolor(&csel, readctl("focuscolors "), nil); - font = loadfont(readctl("font ")); - if(!font) - fatal("Can't load font"); + wborder = strtol(readctl("/ctl", "border "), nil, 10); + client_readconfig(&cnorm, &csel, &font); run_menu(); @@ -167,28 +146,22 @@ main(int argc, char **argv) return 0; } -/* usage --- print a usage message and die */ - void usage(void) { - lprint(2, "usage: %s -v\n", argv0); - lprint(2, " %s [-a <address>] [-i <arg>] menitem[:command] ...\n", argv0); + lprint(2, "usage: %s [-a <address>] [-i <arg>] <menitem>[:<command>] ...\n", argv0); + lprint(2, " %s -v\n", argv0); exit(0); } -/* run_menu --- put up the window, execute selected commands */ - enum { - MouseMask = - ButtonPressMask - | ButtonReleaseMask - | ButtonMotionMask - | PointerMotionMask, - MenuMask = - MouseMask - | StructureNotifyMask - | ExposureMask + MouseMask = ButtonPressMask + | ButtonReleaseMask + | ButtonMotionMask + | PointerMotionMask, + MenuMask = MouseMask + | StructureNotifyMask + | ExposureMask }; void @@ -197,8 +170,8 @@ run_menu(void) XEvent ev; int i, old, wide, high; - wide = 0; high = labelh(font); + wide = 0; for(i = 0; i < numitems; i++) wide = max(wide, textwidth(font, labels[i])); wide += font->height & ~1; @@ -231,12 +204,10 @@ run_menu(void) break; redraw(high, wide); break; - case MapNotify: - redraw(high, wide); - break; case Expose: redraw(high, wide); break; + case MapNotify: case ConfigureNotify: case MappingNotify: break; @@ -244,13 +215,10 @@ run_menu(void) } } -/* set_wm_hints --- set all the window manager hints */ - void create_window(void) { WinAttr wa = { 0 }; - XEvent e; wa.override_redirect = true; menuwin = createwindow(&scr.root, Rect(-1, -1, 0, 0), @@ -258,10 +226,8 @@ create_window(void) &wa, CWOverrideRedirect); selectinput(menuwin, MenuMask); mapwin(menuwin); - XMaskEvent(display, StructureNotifyMask, &e); if(!grabpointer(menuwin, nil, 0, MouseMask)) fatal("Failed to grab the mouse\n"); - XSetCommand(display, menuwin->xid, g_argv, g_argc); } void @@ -284,34 +250,22 @@ size_window(int wide, int high) p.y = min(p.y, scr.rect.max.y - h); reshapewin(menuwin, rectaddpt(r, p)); - - //XSetWindowBackground(display, menuwin->xid, cnorm.bg); setborder(menuwin, 1, &cnorm.border); } -/* redraw --- actually redraw the menu */ - void redraw(int high, int wide) { Rectangle r; - CTuple *c; int i; r = Rect(0, 0, wide, high); for(i = 0; i < numitems; i++) { - if(cur == i) - c = &csel; - else - c = &cnorm; r = rectsetorigin(r, Pt(0, i * high)); - fill(menuwin, r, &c->bg); - drawstring(menuwin, font, r, Center, labels[i], &c->fg); + fillstring(menuwin, font, r, Center, labels[i], (cur == i ? &csel : &cnorm), 0); } } -/* warpmouse --- bring the mouse to the menu */ - void warpmouse(int wide, int high) { diff --git a/img/mkfile b/img/mkfile @@ -2,18 +2,22 @@ MKSHELL=rc path=$PLAN9/bin $path eps = wmii.eps -calc = rc -c 'hoc -e $"*' +calc = rc -c 'echo 4k $* p | dc} -epsbox = `{sed -n '/^%%BoundingBox:/{s/.*://p; q;}' $eps} -iconwidth = 154 -iconscale = `{*=$epsbox; $calc $iconwidth / '('$3 - $1')'} -iconheight = `{*=$epsbox; $calc '('$4 - $2') *' $iconscale} +iconwidth = 16 +imagewidth = 154 -%.png: %.eps +%.pdf: %.eps + sh epstopdf $stem.eps + +%-small.png: %.eps + epsbox = `{sed -n '/^%%BoundingBox:/{s/.*://p; q;}' $stem.eps} + iconscale = `{*=$epsbox; $calc $iconwidth $3 $1 -/} + iconheight = `{*=$epsbox; $calc $4 $2 - $iconscale '*'} * = `{hoc -e'-('$epsbox')'} x = $1 y = $2 - gs -q -dBATCH -dNOPAUSE -s'DEVICE=pngalpha' -s'OutputFile='$target -g$iconwidth'x'$iconheight - <<! + gs -q -dBATCH -dNOPAUSE -s'DEVICE=pngalpha' -s'OutputFile='$target -g$iconwidth^x^$iconheight - <<! $iconscale $iconscale scale $x $y translate ($eps) run @@ -22,18 +26,15 @@ iconheight = `{*=$epsbox; $calc '('$4 - $2') *' $iconscale} ! optipng -fix $target -%.pdf: %.eps - sh epstopdf $stem.eps - -%-small.png: %.eps - iconwidth = 16 - iconscale = `{*=$epsbox; hoc -e $iconwidth/'('$3-' '$1')'} - iconheight = `{*=$epsbox; hoc -e '('$4-' '$2')*'$iconscale} +%.png: %.eps + epsbox = `{sed -n '/^%%BoundingBox:/{s/.*://p; q;}' $stem.eps} + imagescale = `{*=$epsbox; $calc $imagewidth $3 $1 -/} + imageheight = `{*=$epsbox; $calc $4 $2 - $imagescale '*'} * = `{hoc -e'-('$epsbox')'} x = $1 y = $2 - gs -q -dBATCH -dNOPAUSE -s'DEVICE=pngalpha' -s'OutputFile='$target -g$iconwidth'x'$iconheight - <<! - $iconscale $iconscale scale + gs -q -dBATCH -dNOPAUSE -s'DEVICE=pngalpha' -s'OutputFile='$target -g$imagewidth^x^$imageheight - <<! + $imagescale $imagescale scale $x $y translate ($eps) run showpage diff --git a/include/stuff/clientutil.h b/include/stuff/clientutil.h @@ -6,7 +6,7 @@ # define CLIENTEXTERN extern #endif -char* readctl(char*); +char* readctl(char*, char*); void client_init(char*); CLIENTEXTERN IxpClient* client; diff --git a/include/stuff/geom.h b/include/stuff/geom.h @@ -30,8 +30,8 @@ typedef enum Align Align; #define Dx(r) ((r).max.x - (r).min.x) #define Dy(r) ((r).max.y - (r).min.y) #define Pt(x, y) ((Point){(x), (y)}) -#define Rpt(p, q) ((Rectangle){p, q}) -#define Rect(x0, y0, x1, y1) ((Rectangle){Pt(x0, y0), Pt(x1, y1)}) +#define Rpt(p, q) ((Rectangle){(p), (q)}) +#define Rect(x0, y0, x1, y1) Rpt(Pt(x0, y0), Pt(x1, y1)) Point addpt(Point, Point); Point divpt(Point, Point); diff --git a/include/stuff/util.h b/include/stuff/util.h @@ -42,13 +42,10 @@ enum { int Blprint(Biobuf*, const char*, ...); int Bvlprint(Biobuf*, const char*, va_list); -extern char* _buffer; void _die(char*, int, char*, ...); void backtrace(char*); -extern char buffer[8092]; void closeexec(int); char** comm(int, char**, char**); -extern char* const _buf_end; int doublefork(void); void* emalloc(uint); void* emallocz(uint); @@ -90,6 +87,10 @@ int unquote(char*, char*[], int); int utflcpy(char*, const char*, int); int vlprint(int, const char*, va_list); char* vsxprint(const char*, va_list); + +extern char* _buffer; +extern char buffer[8092]; +extern char* const _buf_end; #define bufclear() \ BLOCK( _buffer = buffer; _buffer[0] = '\0' ) #define bufprint(...) \ diff --git a/include/stuff/x11.h b/include/stuff/x11.h @@ -261,6 +261,7 @@ void drawpoly(Image*, Point*, int, int cap, int w, Color*); uint drawstring(Image*, Font*, Rectangle, Align, const char*, Color*); void fill(Image*, Rectangle, Color*); void fillpoly(Image*, Point*, int, Color*); +uint fillstring(Image*, Font*, Rectangle, Align, const char*, CTuple*, int border); Window* findwin(XWindow); void freefont(Font*); void freeimage(Image *); diff --git a/lib/libstuff/client_readconfig.c b/lib/libstuff/client_readconfig.c @@ -11,13 +11,13 @@ void client_readconfig(CTuple *norm, CTuple *focus, Font **font) { if(norm) - loadcolor(norm, readctl("normcolors "), nil); + loadcolor(norm, readctl("/ctl", "normcolors "), nil); if(focus) - loadcolor(focus, readctl("focuscolors "), nil); - *font = loadfont(readctl("font ")); + loadcolor(focus, readctl("/ctl", "focuscolors "), nil); + *font = loadfont(readctl("/ctl", "font ")); if(!*font) - fatal("Can't load font %q", readctl("font ")); - sscanf(readctl("fontpad "), "%d %d %d %d", + fatal("Can't load font %q", readctl("/ctl", "font ")); + sscanf(readctl("/ctl", "fontpad "), "%d %d %d %d", &(*font)->pad.min.x, &(*font)->pad.max.x, &(*font)->pad.min.x, &(*font)->pad.max.y); } diff --git a/lib/libstuff/clientutil.c b/lib/libstuff/clientutil.c @@ -10,20 +10,21 @@ #include <stuff/clientutil.h> #include <stuff/util.h> -static IxpCFid* ctlfid; -static char ctl[1024]; -static char* ectl; - char* -readctl(char *key) { +readctl(char *ctlname, char *key) { + static char ctlfile[128]; + static char ctl[1024]; + static char* ectl; + IxpCFid *fid; char *s, *p; int nkey, n; - if(ctlfid == nil) { - ctlfid = ixp_open(client, "ctl", OREAD); - n = ixp_read(ctlfid, ctl, 1023); + if(strcmp(ctlname, ctlfile)) { + strncpy(ctlfile, ctlname, sizeof ctlfile); + fid = ixp_open(client, ctlfile, OREAD); + n = ixp_read(fid, ctl, sizeof ctl - 1); ectl = ctl + n; - ixp_close(ctlfid); + ixp_close(fid); } nkey = strlen(key); @@ -36,7 +37,7 @@ readctl(char *key) { n = (s ? s : ectl) - p; s = freelater(emalloc(n + 1)); s[n] = '\0'; - return strncpy(s, p, n); + return memcpy(s, p, n); } } while((p = strchr(p, '\n'))); return ""; diff --git a/lib/libstuff/x11/drawing/drawstring.c b/lib/libstuff/x11/drawing/drawstring.c @@ -5,6 +5,17 @@ #include "../x11.h" uint +fillstring(Image *dst, Font *font, + Rectangle r, Align align, + const char *text, CTuple *col, int borderw) { + + fill(dst, r, &col->bg); + if(borderw) + border(dst, r, borderw, &col->border); + return drawstring(dst, font, r, align, text, &col->fg); +} + +uint drawstring(Image *dst, Font *font, Rectangle r, Align align, const char *text, Color *col) { diff --git a/mk/common.mk b/mk/common.mk @@ -41,8 +41,8 @@ tags: for f in $(OBJ); do \ [ -f "$$f.c" ] && files="$$files $$f.c"; \ done; \ - echo CTAGS $$files $(TAGFILES) || \ - ctags $$files $(TAGFILES) + echo CTAGS $$files $(TAGFILES); \ + $(DEBUG) $(CTAGS) $$files $(TAGFILES) .PHONY: all options clean dist install uninstall depend cleandep tags .PHONY: simpleuninstall simpleinstall diff --git a/util/compile b/util/compile @@ -49,7 +49,7 @@ undup() { # GCC is crap. nl=0 maxl=6 } - /: (error|note): .?Each undeclared identifier|: error: for each function it appears|is dangerous, better use|is almost always misused|: In function |: At top level:|support .long long.|use of C99 long long|ISO C forbids conversion|warning:.*warn_unused_result/ { + tolower($0) ~ /: (error|note): .?each undeclared identifier|: error: for each function it appears|is dangerous, better use|is almost always misused|: in function |: at top level:|support .long long.|use of c99 long long|iso c forbids conversion|warning:.*warn_unused_result/ { next } $1 == "warning:" {