Removed the -w option (it was too buggy)
This commit is contained in:
parent
21a9aaecb1
commit
2744390027
4
README
4
README
|
@ -4,6 +4,10 @@ Xmenu is a menu utility for X.
|
||||||
Xmenu receives a menu specification in stdin, shows a menu for the user
|
Xmenu receives a menu specification in stdin, shows a menu for the user
|
||||||
to select one of the options, and outputs the option selected to stdout.
|
to select one of the options, and outputs the option selected to stdout.
|
||||||
|
|
||||||
|
NOTE: The -w (windowed) option was removed from the master branch.
|
||||||
|
It was too buggy in tiled window managers and requires more
|
||||||
|
code to be maintained.
|
||||||
|
|
||||||
§ Installation
|
§ Installation
|
||||||
|
|
||||||
In order to build xmenu you need the Xlib header files.
|
In order to build xmenu you need the Xlib header files.
|
||||||
|
|
124
xmenu.c
124
xmenu.c
|
@ -73,7 +73,6 @@ struct Menu {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* function declarations */
|
/* function declarations */
|
||||||
static int menuexist(void);
|
|
||||||
static void getcolor(const char *s, XftColor *color);
|
static void getcolor(const char *s, XftColor *color);
|
||||||
static void getresources(void);
|
static void getresources(void);
|
||||||
static void setupdc(void);
|
static void setupdc(void);
|
||||||
|
@ -84,7 +83,6 @@ static void getmenuitem(Window win, int y, struct Menu **menu_ret, struct Item *
|
||||||
static void drawmenu(void);
|
static void drawmenu(void);
|
||||||
static void calcscreengeom(void);
|
static void calcscreengeom(void);
|
||||||
static void calcmenu(struct Menu *menu);
|
static void calcmenu(struct Menu *menu);
|
||||||
static void recalcmenu(struct Menu *menu);
|
|
||||||
static void grabpointer(void);
|
static void grabpointer(void);
|
||||||
static void grabkeyboard(void);
|
static void grabkeyboard(void);
|
||||||
static void setcurrmenu(struct Menu *currmenu_new);
|
static void setcurrmenu(struct Menu *currmenu_new);
|
||||||
|
@ -101,7 +99,6 @@ static Visual *visual;
|
||||||
static Window rootwin;
|
static Window rootwin;
|
||||||
static int screen;
|
static int screen;
|
||||||
static struct DC dc;
|
static struct DC dc;
|
||||||
static Atom wmdelete;
|
|
||||||
|
|
||||||
/* menu variables */
|
/* menu variables */
|
||||||
static struct Menu *rootmenu = NULL;
|
static struct Menu *rootmenu = NULL;
|
||||||
|
@ -113,9 +110,6 @@ static int menutitlecount;
|
||||||
static struct Geometry geom;
|
static struct Geometry geom;
|
||||||
static struct ScreenGeometry screengeom;
|
static struct ScreenGeometry screengeom;
|
||||||
|
|
||||||
/* flag variables */
|
|
||||||
static int wflag = 0;
|
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -123,11 +117,8 @@ main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int ch;
|
int ch;
|
||||||
|
|
||||||
while ((ch = getopt(argc, argv, "w")) != -1) {
|
while ((ch = getopt(argc, argv, "")) != -1) {
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case 'w':
|
|
||||||
wflag = 1;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
usage();
|
usage();
|
||||||
break;
|
break;
|
||||||
|
@ -146,13 +137,6 @@ main(int argc, char *argv[])
|
||||||
visual = DefaultVisual(dpy, screen);
|
visual = DefaultVisual(dpy, screen);
|
||||||
rootwin = RootWindow(dpy, screen);
|
rootwin = RootWindow(dpy, screen);
|
||||||
colormap = DefaultColormap(dpy, screen);
|
colormap = DefaultColormap(dpy, screen);
|
||||||
wmdelete=XInternAtom(dpy, "WM_DELETE_WINDOW", True);
|
|
||||||
|
|
||||||
/* exit if another menu exists */
|
|
||||||
if (menuexist()) {
|
|
||||||
XCloseDisplay(dpy);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* setup */
|
/* setup */
|
||||||
getresources();
|
getresources();
|
||||||
|
@ -167,13 +151,11 @@ main(int argc, char *argv[])
|
||||||
calcmenu(rootmenu);
|
calcmenu(rootmenu);
|
||||||
|
|
||||||
/* grab mouse and keyboard */
|
/* grab mouse and keyboard */
|
||||||
if (!wflag) {
|
grabpointer();
|
||||||
grabpointer();
|
grabkeyboard();
|
||||||
grabkeyboard();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* map root menu */
|
/* map root menu */
|
||||||
currmenu = rootmenu;
|
setcurrmenu(rootmenu);
|
||||||
XMapWindow(dpy, rootmenu->win);
|
XMapWindow(dpy, rootmenu->win);
|
||||||
|
|
||||||
/* run event loop */
|
/* run event loop */
|
||||||
|
@ -183,28 +165,6 @@ main(int argc, char *argv[])
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check whether another menu exists */
|
|
||||||
static int
|
|
||||||
menuexist(void)
|
|
||||||
{
|
|
||||||
Window wina, winb; /* unused variables */
|
|
||||||
Window *children;
|
|
||||||
unsigned nchildren;
|
|
||||||
XClassHint classh;
|
|
||||||
|
|
||||||
if (XQueryTree(dpy, rootwin, &wina, &winb, &children, &nchildren) == 0)
|
|
||||||
errx(1, "could not query tree");
|
|
||||||
|
|
||||||
while (nchildren-- > 0) {
|
|
||||||
if (XGetClassHint(dpy, *children, &classh) != 0)
|
|
||||||
if (strcmp(classh.res_class, PROGNAME) == 0)
|
|
||||||
return 1;
|
|
||||||
children++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* read xrdb for configuration options */
|
/* read xrdb for configuration options */
|
||||||
static void
|
static void
|
||||||
getresources(void)
|
getresources(void)
|
||||||
|
@ -338,7 +298,7 @@ allocmenu(struct Menu *parent, struct Item *list, unsigned level)
|
||||||
menu->y = 0; /* calculated by calcmenu() */
|
menu->y = 0; /* calculated by calcmenu() */
|
||||||
menu->level = level;
|
menu->level = level;
|
||||||
|
|
||||||
swa.override_redirect = (wflag) ? False : True;
|
swa.override_redirect = True;
|
||||||
swa.background_pixel = dc.decoration[ColorBG].pixel;
|
swa.background_pixel = dc.decoration[ColorBG].pixel;
|
||||||
swa.border_pixel = dc.decoration[ColorFG].pixel;
|
swa.border_pixel = dc.decoration[ColorFG].pixel;
|
||||||
swa.event_mask = ExposureMask | KeyPressMask | ButtonPressMask | ButtonReleaseMask
|
swa.event_mask = ExposureMask | KeyPressMask | ButtonPressMask | ButtonReleaseMask
|
||||||
|
@ -348,8 +308,6 @@ allocmenu(struct Menu *parent, struct Item *list, unsigned level)
|
||||||
CWOverrideRedirect | CWBackPixel | CWBorderPixel | CWEventMask,
|
CWOverrideRedirect | CWBackPixel | CWBorderPixel | CWEventMask,
|
||||||
&swa);
|
&swa);
|
||||||
|
|
||||||
XSetWMProtocols(dpy, menu->win, &wmdelete, 1);
|
|
||||||
|
|
||||||
return menu;
|
return menu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -541,32 +499,6 @@ calcmenu(struct Menu *menu)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* recalculate menu position in respect to its parent */
|
|
||||||
static void
|
|
||||||
recalcmenu(struct Menu *menu)
|
|
||||||
{
|
|
||||||
XWindowAttributes parentwin;
|
|
||||||
|
|
||||||
if (menu->parent == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
XGetWindowAttributes(dpy, menu->parent->win, &parentwin);
|
|
||||||
|
|
||||||
if (screengeom.screenw - (parentwin.x + menu->parent->w + geom.border) >= menu->w)
|
|
||||||
menu->x = parentwin.x + menu->parent->w + geom.border;
|
|
||||||
else if (parentwin.x > menu->w + geom.border)
|
|
||||||
menu->x = parentwin.x - menu->w - geom.border;
|
|
||||||
|
|
||||||
if (screengeom.screenh - (menu->caller->y + parentwin.y) > menu->h)
|
|
||||||
menu->y = menu->caller->y + parentwin.y;
|
|
||||||
else if (screengeom.screenh - parentwin.y > menu->h)
|
|
||||||
menu->y = parentwin.y;
|
|
||||||
else if (screengeom.screenh > menu->h)
|
|
||||||
menu->y = screengeom.screenh - menu->h;
|
|
||||||
|
|
||||||
XMoveWindow(dpy, menu->win, menu->x, menu->y);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* try to grab pointer, we may have to wait for another process to ungrab */
|
/* try to grab pointer, we may have to wait for another process to ungrab */
|
||||||
static void
|
static void
|
||||||
grabpointer(void)
|
grabpointer(void)
|
||||||
|
@ -634,30 +566,34 @@ setcurrmenu(struct Menu *currmenu_new)
|
||||||
unsigned minlevel; /* level of the closest to root menu */
|
unsigned minlevel; /* level of the closest to root menu */
|
||||||
unsigned maxlevel; /* level of the closest to root menu */
|
unsigned maxlevel; /* level of the closest to root menu */
|
||||||
|
|
||||||
|
/* do not update currmenu to itself */
|
||||||
if (currmenu_new == currmenu)
|
if (currmenu_new == currmenu)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/* if there was no currmenu, skip calculations */
|
||||||
|
if (currmenu == NULL) {
|
||||||
|
currmenu = currmenu_new;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* find lowest common ancestor menu */
|
/* find lowest common ancestor menu */
|
||||||
lcamenu = rootmenu;
|
lcamenu = rootmenu;
|
||||||
if (currmenu != NULL) {
|
minlevel = MIN(currmenu_new->level, currmenu->level);
|
||||||
minlevel = MIN(currmenu_new->level, currmenu->level);
|
maxlevel = MAX(currmenu_new->level, currmenu->level);
|
||||||
maxlevel = MAX(currmenu_new->level, currmenu->level);
|
if (currmenu_new->level == maxlevel) {
|
||||||
if (currmenu_new->level == maxlevel) {
|
menu = currmenu_new;
|
||||||
menu = currmenu_new;
|
menu_ = currmenu;
|
||||||
menu_ = currmenu;
|
} else {
|
||||||
} else {
|
menu = currmenu;
|
||||||
menu = currmenu;
|
menu_ = currmenu_new;
|
||||||
menu_ = currmenu_new;
|
|
||||||
}
|
|
||||||
while (menu->level > minlevel)
|
|
||||||
menu = menu->parent;
|
|
||||||
|
|
||||||
while (menu != menu_) {
|
|
||||||
menu = menu->parent;
|
|
||||||
menu_ = menu_->parent;
|
|
||||||
}
|
|
||||||
lcamenu = menu;
|
|
||||||
}
|
}
|
||||||
|
while (menu->level > minlevel)
|
||||||
|
menu = menu->parent;
|
||||||
|
while (menu != menu_) {
|
||||||
|
menu = menu->parent;
|
||||||
|
menu_ = menu_->parent;
|
||||||
|
}
|
||||||
|
lcamenu = menu;
|
||||||
|
|
||||||
/* unmap menus from currmenu (inclusive) until lcamenu (exclusive) */
|
/* unmap menus from currmenu (inclusive) until lcamenu (exclusive) */
|
||||||
for (menu = currmenu; menu != lcamenu; menu = menu->parent) {
|
for (menu = currmenu; menu != lcamenu; menu = menu->parent) {
|
||||||
|
@ -670,8 +606,6 @@ setcurrmenu(struct Menu *currmenu_new)
|
||||||
/* map menus from currmenu (inclusive) until lcamenu (exclusive) */
|
/* map menus from currmenu (inclusive) until lcamenu (exclusive) */
|
||||||
item = NULL;
|
item = NULL;
|
||||||
for (menu = currmenu; menu != lcamenu; menu = menu->parent) {
|
for (menu = currmenu; menu != lcamenu; menu = menu->parent) {
|
||||||
if (wflag)
|
|
||||||
recalcmenu(menu);
|
|
||||||
XMapWindow(dpy, menu->win);
|
XMapWindow(dpy, menu->win);
|
||||||
if (item != NULL)
|
if (item != NULL)
|
||||||
menu->selected = item;
|
menu->selected = item;
|
||||||
|
@ -867,8 +801,6 @@ selectitem:
|
||||||
currmenu->selected = NULL;
|
currmenu->selected = NULL;
|
||||||
drawmenu();
|
drawmenu();
|
||||||
break;
|
break;
|
||||||
case ClientMessage: /* user closed a window */
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -909,6 +841,6 @@ cleanup(void)
|
||||||
static void
|
static void
|
||||||
usage(void)
|
usage(void)
|
||||||
{
|
{
|
||||||
(void)fprintf(stderr, "usage: xmenu [-w] title...\n");
|
(void)fprintf(stderr, "usage: xmenu title...\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user