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

This commit is contained in:
Kris Maglione 2008-10-16 18:54:03 -04:00
parent 670078b4b0
commit bc91a199ab
5 changed files with 142 additions and 197 deletions

View File

@ -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

View File

@ -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 $*}}}

View File

@ -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 "$@"

View File

@ -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;
static Window* menuwin;
ulong selfg, selbg;
ulong normfg, normbg;
ulong border;
char *sfgname, *sbgname;
char *nfgname, *nbgname;
char *brcname;
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);
if(address && *address)
client = ixp_mount(address);
else
client = ixp_nsmount("wmii");
if(client == nil)
fatal("can't mount: %r\n");
selbg = getcolor(sbgname, BlackPixel(dpy, screen));
selfg = getcolor(sfgname, WhitePixel(dpy, screen));
normbg = getcolor(nbgname, selfg);
normfg = getcolor(nfgname, selbg);
border = getcolor(brcname, selbg);
ctlfid = ixp_open(client, "ctl", OREAD);
i = ixp_read(ctlfid, ctl, 1023);
ectl = ctl + i;
/* 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(font == nil) {
fprintf(stderr, "%s: fatal: cannot load a font\n", progname);
exit(1);
}
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 = labelh(font);
for(i = 0; i < numitems; i++)
wide = max(wide, textwidth(font, labels[i]));
wide += font->height & ~1;
high = font->ascent + font->descent + 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)
{
XSetWindowAttributes wa = { 0 };
uint h;
int x, y, dummy;
Window wdummy;
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)
{
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;
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;
y -= cur * high + high / 2;
if(y < 0)
y = 0;
else if(y + h > DisplayHeight(dpy, screen))
y = DisplayHeight(dpy, screen) - h;
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;
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);
reshapewin(menuwin, Rpt(p, addpt(p, Pt(wide, high))));
XSetCommand(dpy, menuwin, g_argv, g_argc);
//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);
}

View File

@ -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