mirror of
https://github.com/0intro/wmii
synced 2024-11-22 13:52:17 +03:00
Update wmii9menu to take similar args to wimenu (should probably rename it, too)
This commit is contained in:
parent
670078b4b0
commit
bc91a199ab
@ -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
|
||||
|
||||
|
@ -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 $*}}}
|
||||
|
@ -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 "$@"
|
||||
|
307
cmd/wmii9menu.c
307
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;
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user