wmii

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

commit bc91a199ab1f7b9955a16fb39efe246b24a80b0f
parent 670078b4b086ad6ecd66658d431c2327443886c6
Author: Kris Maglione <jg@suckless.org>
Date:   Thu, 16 Oct 2008 18:54:03 -0400

Update wmii9menu to take similar args to wimenu (should probably rename it, too)

Diffstat:
cmd/Makefile | 5+++--
cmd/wmii.rc.rc | 8+-------
cmd/wmii.sh.sh | 11+----------
cmd/wmii9menu.c | 317+++++++++++++++++++++++++++++++++++--------------------------------------------
rc/wmiirc.sh | 6++----
5 files changed, 146 insertions(+), 201 deletions(-)

diff --git a/cmd/Makefile b/cmd/Makefile @@ -36,6 +36,7 @@ OMENU=menu.o wmii/x11.o $(OFILES) $(LIBIXP) menu.O: $(OMENU) dall $(LINK) $@ $(OMENU) -wmii9menu.O: wmii9menu.o $(OFILES) - $(LINK) $@ $*.o $(OFILES) $(LIBX11) +O9MENU=wmii9menu.o wmii/x11.o wmii/map.o $(OFILES) $(LIBIXP) +wmii9menu.O: $(O9MENU) dall + $(LINK) $@ $(O9MENU) $(LIBX11) -lXext -lbio diff --git a/cmd/wmii.rc.rc b/cmd/wmii.rc.rc @@ -43,17 +43,11 @@ wmiifont=`{wi_readctl font} wmiinormcol=`{wi_readctl normcolors} wmiifocuscol=`{wi_readctl focuscolors} -fn wi_9menu { - wmii9menu -font `{echo $wmiifont | sed 's/,.*//'} \ - -^(nf nb br)^$wmiinormcol \ - -^(sf sb br)^$wmiifocuscol $* -} - fn wi_fnmenu { group=$1^Menu-$2 last=$group^_last fns=`{wi_getfuns $group} { shift 2 if(! ~ $#fns 0) { - res = `{wi_9menu -initial $"($last) $fns} \ + res = `{wmii9menu -initial $"($last) $fns} \ if(! ~ $res '') { ($last) = $res $group-$res $*}}} diff --git a/cmd/wmii.sh.sh b/cmd/wmii.sh.sh @@ -104,22 +104,13 @@ wmiifont="$(wi_readctl font)" wmiinormcol="$(wi_readctl normcolors)" wmiifocuscol="$(wi_readctl focuscolors)" -wi_menu() { - eval "wi_menu() { $WMII_MENU"' "$@"; }' - wi_menu "$@" -} -wi_9menu() { - eval "wi_9menu() { $WMII_9MENU"' "$@"; }' - wi_9menu "$@" -} - wi_fnmenu() { group="$1-$2"; shift 2 _last="$(echo $group|tr - _)_last" eval "last=\"\$$_last\"" res=$(set -- $(echo "$Menus" | awk -v "s=$group" 'BEGIN{n=length(s)} substr($1,1,n) == s{print substr($1,n+2)}') - [ $# != 0 ] && wi_9menu -initial "$last" "$@") + [ $# != 0 ] && wmii9menu -initial "$last" "$@") if [ -n "$res" ]; then eval "$_last="'"$res"' Menu $group-$res "$@" diff --git a/cmd/wmii9menu.c b/cmd/wmii9menu.c @@ -35,31 +35,56 @@ * Heavily modified by Kris Maglione for use with wmii. */ +#define IXP_NO_P9_ +#define IXP_P9_STRUCTS +#include <ixp.h> #include <stdarg.h> +#include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <X11/Xutil.h> #include <util.h> +#include <x11.h> char version[] = "@(#) wmii9menu version 1.8"; -/* lovely X stuff */ -Display *dpy; -int screen; -Window root; -Window menuwin; -Colormap defcmap; -XColor color; -XFontStruct *font; -GC gc; - -ulong selfg, selbg; -ulong normfg, normbg; -ulong border; -char *sfgname, *sbgname; -char *nfgname, *nbgname; -char *brcname; +static Window* menuwin; + +static CTuple cnorm; +static CTuple csel; +static Font* font; + +static IxpClient* client; +static IxpCFid* ctlfid; +static char ctl[1024]; +static char* ectl; +static char* address; + +static int wborder; + +char buffer[8092]; +char* _buffer; + +static char* +readctl(char *key) { + char *s, *p; + int nkey, n; + + nkey = strlen(key); + p = ctl - 1; + do { + p++; + if(!strncmp(p, key, nkey)) { + p += nkey; + s = strchr(p, '\n'); + n = (s ? s : ectl) - p; + s = freelater(emalloc(n + 1)); + s[n] = '\0'; + return strncpy(s, p, n); + } + } while((p = strchr(p, '\n'))); + return ""; +} /* for XSetWMProperties to use */ int g_argc; @@ -68,28 +93,14 @@ char **g_argv; char *initial = ""; int cur; -char *fontlist[] = { /* default font list if no -font */ - "pelm.latin1.9", - "lucm.latin1.9", - "blit", - "9x15bold", - "9x15", - "lucidasanstypewriter-12", - "fixed", - nil -}; - -char *progname; /* my name */ -char *displayname; /* X display */ -char *fontname; /* font */ - -char **labels; /* list of labels and commands */ -char **commands; -int numitems; +static char** labels; /* list of labels and commands */ +static char** commands; +static int numitems; void usage(void); void run_menu(void); -void create_window(int, int); +void create_window(void); +void size_window(int, int); void redraw(int, int); void warpmouse(int, int); void memory(void); @@ -100,27 +111,11 @@ int args(void); struct { char *name, **var; } argtab[] = { - {"display", &displayname}, {"initial", &initial}, - {"font", &fontname}, - {"nb", &nbgname}, - {"nf", &nfgname}, - {"sb", &sbgname}, - {"sf", &sfgname}, - {"br", &brcname}, + {"a", &address}, {0, }, }, *ap; -static ulong -getcolor(char *name, ulong def) { - if((name != nil) - && (XParseColor(dpy, defcmap, name, &color) != 0) - && (XAllocColor(dpy, defcmap, &color) != 0)) - return color.pixel; - else - return def; -} - /* main --- crack arguments, set up X stuff, run the main menu loop */ int @@ -128,17 +123,15 @@ main(int argc, char **argv) { int i, n; char *cp; - XGCValues gv; - ulong mask; g_argc = argc; g_argv = argv; /* set default label name */ if((cp = strrchr(argv[0], '/')) != nil) - progname = ++cp; + argv0 = ++cp; else - progname = argv[0]; + argv0 = argv[0]; for(i = 1; i < argc && argv[i][0] == '-'; i++) { if(strcmp(argv[i], "-version") == 0) { @@ -168,6 +161,9 @@ main(int argc, char **argv) if(argc == 0) usage(); + initdisplay(); + create_window(); + numitems = argc; labels = emalloc(numitems * sizeof *labels); @@ -184,56 +180,27 @@ main(int argc, char **argv) cur = i; } - dpy = XOpenDisplay(displayname); - if(dpy == nil) { - fprintf(stderr, "%s: cannot open display", progname); - if(displayname != nil) - fprintf(stderr, " %s", displayname); - fprintf(stderr, "\n"); - exit(1); - } - screen = DefaultScreen(dpy); - root = RootWindow(dpy, screen); - defcmap = DefaultColormap(dpy, screen); - - selbg = getcolor(sbgname, BlackPixel(dpy, screen)); - selfg = getcolor(sfgname, WhitePixel(dpy, screen)); - normbg = getcolor(nbgname, selfg); - normfg = getcolor(nfgname, selbg); - border = getcolor(brcname, selbg); - - /* try user's font first */ - if(fontname != nil) { - font = XLoadQueryFont(dpy, fontname); - if(font == nil) - fprintf(stderr, "%s: warning: can't load font '%s'\n", - progname, fontname); - } - - /* if no user font, try one of our default fonts */ - if(font == nil) { - for(i = 0; fontlist[i] != nil; i++) { - font = XLoadQueryFont(dpy, fontlist[i]); - if(font != nil) - break; - } - } + if(address && *address) + client = ixp_mount(address); + else + client = ixp_nsmount("wmii"); + if(client == nil) + fatal("can't mount: %r\n"); - if(font == nil) { - fprintf(stderr, "%s: fatal: cannot load a font\n", progname); - exit(1); - } + ctlfid = ixp_open(client, "ctl", OREAD); + i = ixp_read(ctlfid, ctl, 1023); + ectl = ctl + i; - gv.foreground = normfg; - gv.background = normbg; - gv.font = font->fid; - gv.line_width = 0; - mask = GCForeground | GCBackground | GCFont | GCLineWidth; - gc = XCreateGC(dpy, root, mask, &gv); + wborder = strtol(readctl("border "), nil, 10); + loadcolor(&cnorm, readctl("normcolors ")); + loadcolor(&csel, readctl("focuscolors ")); + font = loadfont(readctl("font ")); + if(!font) + fatal("Can't load font"); run_menu(); - XCloseDisplay(dpy); + XCloseDisplay(display); return 0; } @@ -242,15 +209,14 @@ main(int argc, char **argv) void usage(void) { - fprintf(stderr, "usage: %s [-display <displayname>] [-font <fontname>] ", progname); - fprintf(stderr, "[-{n,s}{f,b} <color>] [-br <color>] "); - fprintf(stderr, "[-version] menitem[:command] ...\n"); + fprintf(stderr, "usage: %s -version\n", argv0); + fprintf(stderr, " %s [-a <address>] [-initial <arg>] menitem[:command] ...\n", argv0); exit(0); } /* run_menu --- put up the window, execute selected commands */ - enum { +enum { MouseMask = ButtonPressMask | ButtonReleaseMask @@ -260,40 +226,31 @@ usage(void) MouseMask | StructureNotifyMask | ExposureMask - }; +}; void run_menu(void) { XEvent ev; - int i, old, wide, high, dx; + int i, old, wide, high; - dx = 0; - for(i = 0; i < numitems; i++) { - wide = XTextWidth(font, labels[i], strlen(labels[i])) + 4; - if(wide > dx) - dx = wide; - } - wide = dx; - - high = font->ascent + font->descent + 1; + high = labelh(font); + for(i = 0; i < numitems; i++) + wide = max(wide, textwidth(font, labels[i])); + wide += font->height & ~1; - create_window(wide, high); + size_window(wide, high * i); warpmouse(wide, high); - XSelectInput(dpy, menuwin, MenuMask); - - XMapWindow(dpy, menuwin); - for(;;) { - XNextEvent(dpy, &ev); + XNextEvent(display, &ev); switch (ev.type) { default: fprintf(stderr, "%s: unknown ev.type %d\n", - progname, ev.type); + argv0, ev.type); break; case ButtonRelease: - i = ev.xbutton.y/high; + i = ev.xbutton.y / high; if(ev.xbutton.x < 0 || ev.xbutton.x > wide) return; else if(i < 0 || i >= numitems) @@ -304,7 +261,7 @@ run_menu(void) case ButtonPress: case MotionNotify: old = cur; - cur = ev.xbutton.y/high; + cur = ev.xbutton.y / high; if(ev.xbutton.x < 0 || ev.xbutton.x > wide) cur = ~0; if(cur == old) @@ -313,11 +270,6 @@ run_menu(void) break; case MapNotify: redraw(high, wide); - if(XGrabPointer(dpy, menuwin, - False, MouseMask, - GrabModeAsync, GrabModeAsync, - 0, None, CurrentTime) != GrabSuccess) - fprintf(stderr, "Failed to grab the mouse\n"); break; case Expose: redraw(high, wide); @@ -331,42 +283,48 @@ run_menu(void) /* set_wm_hints --- set all the window manager hints */ void -create_window(int wide, int high) +create_window(void) +{ + WinAttr wa = { 0 }; + XEvent e; + + wa.override_redirect = true; + menuwin = createwindow(&scr.root, Rect(-1, -1, 0, 0), + scr.depth, InputOutput, + &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->w, g_argv, g_argc); +} + +void +size_window(int wide, int high) { - XSetWindowAttributes wa = { 0 }; - uint h; - int x, y, dummy; - Window wdummy; - + Point p; + int h; + h = high * numitems; - XQueryPointer(dpy, root, &wdummy, &wdummy, &x, &y, - &dummy, &dummy, (uint*)&dummy); - x -= wide / 2; - if(x < 0) - x = 0; - else if(x + wide > DisplayWidth(dpy, screen)) - x = DisplayWidth(dpy, screen) - wide; - - y -= cur * high + high / 2; - if(y < 0) - y = 0; - else if(y + h > DisplayHeight(dpy, screen)) - y = DisplayHeight(dpy, screen) - h; - - wa.override_redirect = True; - wa.border_pixel = border; - wa.background_pixel = normbg; - menuwin = XCreateWindow(dpy, root, x, y, wide, h, - 1, DefaultDepth(dpy, screen), CopyFromParent, - DefaultVisual(dpy, screen), - CWOverrideRedirect - | CWBackPixel - | CWBorderPixel - | CWEventMask, - &wa); - - XSetCommand(dpy, menuwin, g_argv, g_argc); + p = querypointer(&scr.root); + p.x -= wide / 2; + if(p.x < 0) + p.x = 0; + else if(p.x + wide > Dy(scr.rect)) + p.x = Dy(scr.rect) - wide; + + p.y -= cur * high + high / 2; + if(p.y < 0) + p.y = 0; + else if(p.y + h > Dy(scr.rect)) + p.y = Dy(scr.rect) - h; + + reshapewin(menuwin, Rpt(p, addpt(p, Pt(wide, high)))); + + //XSetWindowBackground(display, menuwin->w, cnorm.bg); + setborder(menuwin, 1, cnorm.border); } /* redraw --- actually redraw the menu */ @@ -374,22 +332,21 @@ create_window(int wide, int high) void redraw(int high, int wide) { - int tx, ty, i; + Rectangle r; + CTuple *c; + int i; + r = Rect(0, 0, wide, high); for(i = 0; i < numitems; i++) { - tx = (wide - XTextWidth(font, labels[i], strlen(labels[i]))) / 2; - ty = i*high + font->ascent + 1; if(cur == i) - XSetForeground(dpy, gc, selbg); + c = &csel; else - XSetForeground(dpy, gc, normbg); - XFillRectangle(dpy, menuwin, gc, 0, i*high, wide, high); - if(cur == i) - XSetForeground(dpy, gc, selfg); - else - XSetForeground(dpy, gc, normfg); - XDrawString(dpy, menuwin, gc, tx, ty, labels[i], strlen(labels[i])); + c = &cnorm; + r = rectsetorigin(r, Pt(0, i * high)); + fill(menuwin, r, c->bg); + drawstring(menuwin, font, r, Center, labels[i], c->fg); } + drawstring(menuwin, font, Rect(0, 0, 15, 15), West, "foo", cnorm.fg); } /* warpmouse --- bring the mouse to the menu */ @@ -397,12 +354,16 @@ redraw(int high, int wide) void warpmouse(int wide, int high) { + Point p; int offset; /* move tip of pointer into middle of menu item */ - offset = (font->ascent + font->descent + 1) / 2; + offset = labelh(font) / 2; offset += 6; /* fudge factor */ - XWarpPointer(dpy, None, menuwin, 0, 0, 0, 0, - wide/2, cur*high-high/2+offset); + p = Pt(wide / 2, cur*high - high/2 + offset); + p = addpt(p, menuwin->r.min); + + warppointer(p); } + diff --git a/rc/wmiirc.sh b/rc/wmiirc.sh @@ -22,8 +22,6 @@ WMII_BACKGROUND='#333333' WMII_FONT='-*-fixed-medium-r-*-*-13-*-*-*-*-*-*-*' set -- $(echo $WMII_NORMCOLORS $WMII_FOCUSCOLORS) -WMII_MENU='dmenu -b -fn "$WMII_FONT"'" -nf '$1' -nb '$2' -sf '$4' -sb '$5'" -WMII_9MENU='wmii9menu -font "$WMII_FONT"'" -nf '$1' -nb '$2' -sf '$4' -sb '$5' -br '$6'" WMII_TERM="xterm" # Column Rules @@ -72,7 +70,7 @@ events() { client=$1; button=$2 case "$button" in 3) - do=$(wi_9menu -initial "$menulast" Nop Delete Fullscreen) + do=$(wimii9menu -initial "$menulast" Nop Delete Fullscreen) case "$do" in Delete) wmiir xwrite /client/$client/ctl kill;; @@ -219,7 +217,7 @@ wmiir write /ctl <<! ! xsetroot -solid "$WMII_BACKGROUND" & -export WMII_MENU WMII_9MENU WMII_FONT WMII_TERM +export WMII_FONT WMII_TERM export WMII_FOCUSCOLORS WMII_SELCOLORS WMII_NORMCOLORS # Misc