|
@@ -9,6 +9,7 @@ |
|
|
/* macros */ |
|
|
/* macros */ |
|
|
#define LEN(x) (sizeof (x) / sizeof (x[0])) |
|
|
#define LEN(x) (sizeof (x) / sizeof (x[0])) |
|
|
#define MAX(x,y) ((x)>(y)?(x):(y)) |
|
|
#define MAX(x,y) ((x)>(y)?(x):(y)) |
|
|
|
|
|
#define MIN(x,y) ((x)<(y)?(x):(y)) |
|
|
|
|
|
|
|
|
/* color enum */ |
|
|
/* color enum */ |
|
|
enum {ColorFG, ColorBG, ColorLast}; |
|
|
enum {ColorFG, ColorBG, ColorLast}; |
|
@@ -42,25 +43,25 @@ struct ScreenGeometry { |
|
|
|
|
|
|
|
|
/* menu item structure */ |
|
|
/* menu item structure */ |
|
|
struct Item { |
|
|
struct Item { |
|
|
char *label; |
|
|
|
|
|
char *output; |
|
|
|
|
|
int y; |
|
|
|
|
|
int h; |
|
|
|
|
|
size_t labellen; |
|
|
|
|
|
struct Item *next; |
|
|
|
|
|
struct Menu *submenu; |
|
|
|
|
|
|
|
|
char *label; /* string to be drawed on menu */ |
|
|
|
|
|
char *output; /* string to be outputed when item is clicked */ |
|
|
|
|
|
int y; /* item y position relative to menu */ |
|
|
|
|
|
int h; /* item height */ |
|
|
|
|
|
size_t labellen; /* strlen(label) */ |
|
|
|
|
|
struct Item *next; /* next item */ |
|
|
|
|
|
struct Menu *submenu; /* submenu spawned by clicking on item */ |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
/* menu structure */ |
|
|
/* menu structure */ |
|
|
struct Menu { |
|
|
struct Menu { |
|
|
struct Menu *parent; |
|
|
|
|
|
struct Item *caller; |
|
|
|
|
|
struct Item *list; |
|
|
|
|
|
struct Item *selected; |
|
|
|
|
|
int x, y, w, h; |
|
|
|
|
|
unsigned level; |
|
|
|
|
|
Drawable pixmap; |
|
|
|
|
|
Window win; |
|
|
|
|
|
|
|
|
struct Menu *parent; /* parent menu */ |
|
|
|
|
|
struct Item *caller; /* item that spawned the menu */ |
|
|
|
|
|
struct Item *list; /* list of items contained by the menu */ |
|
|
|
|
|
struct Item *selected; /* item currently selected in the menu */ |
|
|
|
|
|
int x, y, w, h; /* menu geometry */ |
|
|
|
|
|
unsigned level; /* menu level relative to root */ |
|
|
|
|
|
Drawable pixmap; /* pixmap to draw the menu on */ |
|
|
|
|
|
Window win; /* menu window to map on the screen */ |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
/* function declarations */ |
|
|
/* function declarations */ |
|
@@ -138,6 +139,10 @@ main(int argc, char *argv[]) |
|
|
calcscreengeom(); |
|
|
calcscreengeom(); |
|
|
calcmenu(rootmenu); |
|
|
calcmenu(rootmenu); |
|
|
|
|
|
|
|
|
|
|
|
/* map root menu */ |
|
|
|
|
|
currmenu = rootmenu; |
|
|
|
|
|
XMapWindow(dpy, rootmenu->win); |
|
|
|
|
|
|
|
|
/* run event loop */ |
|
|
/* run event loop */ |
|
|
run(); |
|
|
run(); |
|
|
|
|
|
|
|
@@ -454,20 +459,45 @@ done: |
|
|
static void |
|
|
static void |
|
|
setcurrmenu(struct Menu *currmenu_new) |
|
|
setcurrmenu(struct Menu *currmenu_new) |
|
|
{ |
|
|
{ |
|
|
struct Menu *menu; |
|
|
|
|
|
|
|
|
struct Menu *menu, *menu_; |
|
|
struct Item *item; |
|
|
struct Item *item; |
|
|
|
|
|
struct Menu *lcamenu; /* lowest common ancestor menu */ |
|
|
|
|
|
unsigned minlevel; /* level of the closest to root menu */ |
|
|
|
|
|
unsigned maxlevel; /* level of the closest to root menu */ |
|
|
|
|
|
|
|
|
if (currmenu_new == currmenu) |
|
|
if (currmenu_new == currmenu) |
|
|
return; |
|
|
return; |
|
|
|
|
|
|
|
|
for (menu = currmenu; menu != NULL; menu = menu->parent) { |
|
|
|
|
|
|
|
|
/* 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; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
for (menu = currmenu; menu != lcamenu; menu = menu->parent) { |
|
|
XUnmapWindow(dpy, menu->win); |
|
|
XUnmapWindow(dpy, menu->win); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
currmenu = currmenu_new; |
|
|
currmenu = currmenu_new; |
|
|
|
|
|
|
|
|
item = NULL; |
|
|
item = NULL; |
|
|
for (menu = currmenu; menu != NULL; menu = menu->parent) { |
|
|
|
|
|
|
|
|
for (menu = currmenu; menu != lcamenu; menu = menu->parent) { |
|
|
XMapWindow(dpy, menu->win); |
|
|
XMapWindow(dpy, menu->win); |
|
|
if (item != NULL) |
|
|
if (item != NULL) |
|
|
menu->selected = item; |
|
|
menu->selected = item; |
|
|