diff --git a/README b/README index 4df29b9..ca341d2 100644 --- a/README +++ b/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 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 In order to build xmenu you need the Xlib header files. diff --git a/xmenu.c b/xmenu.c index cce791e..03c184e 100644 --- a/xmenu.c +++ b/xmenu.c @@ -73,7 +73,6 @@ struct Menu { }; /* function declarations */ -static int menuexist(void); static void getcolor(const char *s, XftColor *color); static void getresources(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 calcscreengeom(void); static void calcmenu(struct Menu *menu); -static void recalcmenu(struct Menu *menu); static void grabpointer(void); static void grabkeyboard(void); static void setcurrmenu(struct Menu *currmenu_new); @@ -101,7 +99,6 @@ static Visual *visual; static Window rootwin; static int screen; static struct DC dc; -static Atom wmdelete; /* menu variables */ static struct Menu *rootmenu = NULL; @@ -113,9 +110,6 @@ static int menutitlecount; static struct Geometry geom; static struct ScreenGeometry screengeom; -/* flag variables */ -static int wflag = 0; - #include "config.h" int @@ -123,11 +117,8 @@ main(int argc, char *argv[]) { int ch; - while ((ch = getopt(argc, argv, "w")) != -1) { + while ((ch = getopt(argc, argv, "")) != -1) { switch (ch) { - case 'w': - wflag = 1; - break; default: usage(); break; @@ -146,13 +137,6 @@ main(int argc, char *argv[]) visual = DefaultVisual(dpy, screen); rootwin = RootWindow(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 */ getresources(); @@ -167,13 +151,11 @@ main(int argc, char *argv[]) calcmenu(rootmenu); /* grab mouse and keyboard */ - if (!wflag) { - grabpointer(); - grabkeyboard(); - } + grabpointer(); + grabkeyboard(); /* map root menu */ - currmenu = rootmenu; + setcurrmenu(rootmenu); XMapWindow(dpy, rootmenu->win); /* run event loop */ @@ -183,28 +165,6 @@ main(int argc, char *argv[]) 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 */ static void getresources(void) @@ -338,7 +298,7 @@ allocmenu(struct Menu *parent, struct Item *list, unsigned level) menu->y = 0; /* calculated by calcmenu() */ menu->level = level; - swa.override_redirect = (wflag) ? False : True; + swa.override_redirect = True; swa.background_pixel = dc.decoration[ColorBG].pixel; swa.border_pixel = dc.decoration[ColorFG].pixel; swa.event_mask = ExposureMask | KeyPressMask | ButtonPressMask | ButtonReleaseMask @@ -348,8 +308,6 @@ allocmenu(struct Menu *parent, struct Item *list, unsigned level) CWOverrideRedirect | CWBackPixel | CWBorderPixel | CWEventMask, &swa); - XSetWMProtocols(dpy, menu->win, &wmdelete, 1); - 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 */ static void grabpointer(void) @@ -634,30 +566,34 @@ setcurrmenu(struct Menu *currmenu_new) unsigned minlevel; /* 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) return; + /* if there was no currmenu, skip calculations */ + if (currmenu == NULL) { + currmenu = currmenu_new; + return; + } + /* find lowest common ancestor menu */ lcamenu = rootmenu; - if (currmenu != NULL) { - minlevel = MIN(currmenu_new->level, currmenu->level); - maxlevel = MAX(currmenu_new->level, currmenu->level); - if (currmenu_new->level == maxlevel) { - menu = currmenu_new; - menu_ = currmenu; - } else { - menu = currmenu; - menu_ = currmenu_new; - } - while (menu->level > minlevel) - menu = menu->parent; - - while (menu != menu_) { - menu = menu->parent; - menu_ = menu_->parent; - } - lcamenu = menu; + minlevel = MIN(currmenu_new->level, currmenu->level); + maxlevel = MAX(currmenu_new->level, currmenu->level); + if (currmenu_new->level == maxlevel) { + menu = currmenu_new; + menu_ = currmenu; + } else { + menu = currmenu; + menu_ = currmenu_new; } + 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) */ 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) */ item = NULL; for (menu = currmenu; menu != lcamenu; menu = menu->parent) { - if (wflag) - recalcmenu(menu); XMapWindow(dpy, menu->win); if (item != NULL) menu->selected = item; @@ -867,8 +801,6 @@ selectitem: currmenu->selected = NULL; drawmenu(); break; - case ClientMessage: /* user closed a window */ - return; } } } @@ -909,6 +841,6 @@ cleanup(void) static void usage(void) { - (void)fprintf(stderr, "usage: xmenu [-w] title...\n"); + (void)fprintf(stderr, "usage: xmenu title...\n"); exit(1); }