added the -i option
Widths and x positions no more depend on item->h.
This commit is contained in:
parent
92e7609bcd
commit
71b4db9241
12
config.h
12
config.h
|
@ -17,12 +17,18 @@ static struct Config config = {
|
||||||
.separator_pixels = 3, /* space around separator */
|
.separator_pixels = 3, /* space around separator */
|
||||||
.gap_pixels = 0, /* gap between menus */
|
.gap_pixels = 0, /* gap between menus */
|
||||||
|
|
||||||
/* the variables below cannot be set by X resources */
|
/*
|
||||||
|
* The variables below cannot be set by X resources.
|
||||||
|
* Their values must be less than .height_pixels.
|
||||||
|
*/
|
||||||
|
|
||||||
/* geometry of the right-pointing isoceles triangle for submenus */
|
/* geometry of the right-pointing isoceles triangle for submenus */
|
||||||
.triangle_width = 3,
|
.triangle_width = 3,
|
||||||
.triangle_height = 7,
|
.triangle_height = 7,
|
||||||
|
|
||||||
/* padding of the area around the icon */
|
/* the icon size is equal to .height_pixels - .iconpadding * 2 */
|
||||||
.iconpadding = 4,
|
.iconpadding = 2,
|
||||||
|
|
||||||
|
/* area around the icon, the triangle and the separator */
|
||||||
|
.horzpadding = 8,
|
||||||
};
|
};
|
||||||
|
|
14
xmenu.1
14
xmenu.1
|
@ -3,7 +3,7 @@
|
||||||
xmenu \- menu utility for X
|
xmenu \- menu utility for X
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.B xmenu
|
.B xmenu
|
||||||
.RB [ \-w ]
|
.RB [ \-iw ]
|
||||||
.RI [ title ]
|
.RI [ title ]
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
.B xmenu
|
.B xmenu
|
||||||
|
@ -14,9 +14,19 @@ and outputs the item selected to stdout.
|
||||||
.PP
|
.PP
|
||||||
The options are as follows:
|
The options are as follows:
|
||||||
.TP
|
.TP
|
||||||
|
.B -i
|
||||||
|
Disable icons.
|
||||||
|
.B xmenu
|
||||||
|
allocates a space at the left side of the menu for the icons;
|
||||||
|
if there is no icon, then this space will be blank.
|
||||||
|
Setting the
|
||||||
|
.B -i
|
||||||
|
option removes this space, making the menu narrower.
|
||||||
|
.TP
|
||||||
.B -w
|
.B -w
|
||||||
Asks the window manager to draw a border around the menus.
|
Asks the window manager to draw a border around the menus.
|
||||||
This option may be buggy in some window managers, specially tiled ones.
|
This option may be buggy in some window managers,
|
||||||
|
specially tiled ones that do not respect window hints.
|
||||||
.PP
|
.PP
|
||||||
Each item read from stdin has the following format:
|
Each item read from stdin has the following format:
|
||||||
.IP
|
.IP
|
||||||
|
|
71
xmenu.c
71
xmenu.c
|
@ -21,7 +21,7 @@
|
||||||
static void ealloccolor(const char *s, XftColor *color);
|
static void ealloccolor(const char *s, XftColor *color);
|
||||||
static void initresources(void);
|
static void initresources(void);
|
||||||
static void initdc(void);
|
static void initdc(void);
|
||||||
static void initscreengeom(void);
|
static void initconfig(void);
|
||||||
static void initatoms(void);
|
static void initatoms(void);
|
||||||
|
|
||||||
/* structure builders, and their helper routines */
|
/* structure builders, and their helper routines */
|
||||||
|
@ -31,10 +31,10 @@ static struct Menu *buildmenutree(unsigned level, const char *label, const char
|
||||||
static struct Menu *parsestdin(void);
|
static struct Menu *parsestdin(void);
|
||||||
|
|
||||||
/* image loader */
|
/* image loader */
|
||||||
static Imlib_Image loadicon(const char *file, int size);
|
static Imlib_Image loadicon(const char *file);
|
||||||
|
|
||||||
/* structure setters, and their helper routines */
|
/* structure setters, and their helper routines */
|
||||||
static void setupmenusize(struct Menu *menu);
|
static void setupitems(struct Menu *menu);
|
||||||
static void setupmenupos(struct Menu *menu);
|
static void setupmenupos(struct Menu *menu);
|
||||||
static void setupmenu(struct Menu *menu, XClassHint *classh);
|
static void setupmenu(struct Menu *menu, XClassHint *classh);
|
||||||
|
|
||||||
|
@ -79,6 +79,7 @@ static Atom netatom[NetLast];
|
||||||
|
|
||||||
/* flags */
|
/* flags */
|
||||||
static int wflag = 0; /* whether to let the window manager control XMenu */
|
static int wflag = 0; /* whether to let the window manager control XMenu */
|
||||||
|
static int iflag = 0; /* whether to disable icons */
|
||||||
|
|
||||||
/* include config variable */
|
/* include config variable */
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
@ -96,8 +97,11 @@ main(int argc, char *argv[])
|
||||||
XClassHint classh;
|
XClassHint classh;
|
||||||
int ch;
|
int ch;
|
||||||
|
|
||||||
while ((ch = getopt(argc, argv, "w")) != -1) {
|
while ((ch = getopt(argc, argv, "iw")) != -1) {
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
|
case 'i':
|
||||||
|
iflag = 1;
|
||||||
|
break;
|
||||||
case 'w':
|
case 'w':
|
||||||
wflag = 1;
|
wflag = 1;
|
||||||
break;
|
break;
|
||||||
|
@ -121,16 +125,18 @@ main(int argc, char *argv[])
|
||||||
colormap = DefaultColormap(dpy, screen);
|
colormap = DefaultColormap(dpy, screen);
|
||||||
|
|
||||||
/* imlib2 stuff */
|
/* imlib2 stuff */
|
||||||
|
if (!iflag) {
|
||||||
imlib_set_cache_size(2048 * 1024);
|
imlib_set_cache_size(2048 * 1024);
|
||||||
imlib_context_set_dither(1);
|
imlib_context_set_dither(1);
|
||||||
imlib_context_set_display(dpy);
|
imlib_context_set_display(dpy);
|
||||||
imlib_context_set_visual(visual);
|
imlib_context_set_visual(visual);
|
||||||
imlib_context_set_colormap(colormap);
|
imlib_context_set_colormap(colormap);
|
||||||
|
}
|
||||||
|
|
||||||
/* initializers */
|
/* initializers */
|
||||||
initresources();
|
initresources();
|
||||||
initdc();
|
initdc();
|
||||||
initscreengeom();
|
initconfig();
|
||||||
initatoms();
|
initatoms();
|
||||||
|
|
||||||
/* set window class */
|
/* set window class */
|
||||||
|
@ -239,9 +245,9 @@ initdc(void)
|
||||||
dc.gc = XCreateGC(dpy, rootwin, 0, NULL);
|
dc.gc = XCreateGC(dpy, rootwin, 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* calculate screen geometry */
|
/* calculate configuration values that are not set manually */
|
||||||
static void
|
static void
|
||||||
initscreengeom(void)
|
initconfig(void)
|
||||||
{
|
{
|
||||||
Window dw; /* dummy variable */
|
Window dw; /* dummy variable */
|
||||||
int di; /* dummy variable */
|
int di; /* dummy variable */
|
||||||
|
@ -250,6 +256,7 @@ initscreengeom(void)
|
||||||
XQueryPointer(dpy, rootwin, &dw, &dw, &config.cursx, &config.cursy, &di, &di, &du);
|
XQueryPointer(dpy, rootwin, &dw, &dw, &config.cursx, &config.cursy, &di, &di, &du);
|
||||||
config.screenw = DisplayWidth(dpy, screen);
|
config.screenw = DisplayWidth(dpy, screen);
|
||||||
config.screenh = DisplayHeight(dpy, screen);
|
config.screenh = DisplayHeight(dpy, screen);
|
||||||
|
config.iconsize = config.height_pixels - config.iconpadding * 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* intern atoms */
|
/* intern atoms */
|
||||||
|
@ -441,7 +448,7 @@ parsestdin(void)
|
||||||
|
|
||||||
/* load and scale icon */
|
/* load and scale icon */
|
||||||
static Imlib_Image
|
static Imlib_Image
|
||||||
loadicon(const char *file, int size)
|
loadicon(const char *file)
|
||||||
{
|
{
|
||||||
Imlib_Image icon;
|
Imlib_Image icon;
|
||||||
int width;
|
int width;
|
||||||
|
@ -458,18 +465,20 @@ loadicon(const char *file, int size)
|
||||||
height = imlib_image_get_height();
|
height = imlib_image_get_height();
|
||||||
imgsize = MIN(width, height);
|
imgsize = MIN(width, height);
|
||||||
|
|
||||||
icon = imlib_create_cropped_scaled_image(0, 0, imgsize, imgsize, size, size);
|
icon = imlib_create_cropped_scaled_image(0, 0, imgsize, imgsize,
|
||||||
|
config.iconsize,
|
||||||
|
config.iconsize);
|
||||||
|
|
||||||
return icon;
|
return icon;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* setup the size of a menu and the position of its items */
|
/* setup the height, width and icon of the items of a menu */
|
||||||
static void
|
static void
|
||||||
setupmenusize(struct Menu *menu)
|
setupitems(struct Menu *menu)
|
||||||
{
|
{
|
||||||
XGlyphInfo ext;
|
XGlyphInfo ext;
|
||||||
struct Item *item;
|
struct Item *item;
|
||||||
int labelwidth;
|
int itemwidth;
|
||||||
|
|
||||||
menu->w = config.width_pixels;
|
menu->w = config.width_pixels;
|
||||||
for (item = menu->list; item != NULL; item = item->next) {
|
for (item = menu->list; item != NULL; item = item->next) {
|
||||||
|
@ -485,13 +494,25 @@ setupmenusize(struct Menu *menu)
|
||||||
XftTextExtentsUtf8(dpy, dc.font, (XftChar8 *)item->label,
|
XftTextExtentsUtf8(dpy, dc.font, (XftChar8 *)item->label,
|
||||||
item->labellen, &ext);
|
item->labellen, &ext);
|
||||||
|
|
||||||
/* set menu width */
|
/*
|
||||||
labelwidth = ext.xOff + item->h * 2;
|
* set menu width
|
||||||
menu->w = MAX(menu->w, labelwidth);
|
*
|
||||||
|
* the item width depends on the size of its label (ext.xOff),
|
||||||
|
* and it is only used to calculate the width of the menu (which
|
||||||
|
* is equal to the width of the largest item).
|
||||||
|
*
|
||||||
|
* the horizontal padding appears 4 times through the width of a
|
||||||
|
* item: before and after its icon, and before and after its triangle
|
||||||
|
* if the iflag is set (icons are disabled) then the horizontal
|
||||||
|
* padding appears before the label and around the triangle.
|
||||||
|
*/
|
||||||
|
itemwidth = ext.xOff + config.triangle_width + config.horzpadding * 3;
|
||||||
|
itemwidth += (iflag) ? 0 : config.iconsize + config.horzpadding;
|
||||||
|
menu->w = MAX(menu->w, itemwidth);
|
||||||
|
|
||||||
/* create icon */
|
/* create icon */
|
||||||
if (item->file != NULL)
|
if (item->file != NULL && !iflag)
|
||||||
item->icon = loadicon(item->file, item->h - config.iconpadding * 2);
|
item->icon = loadicon(item->file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -539,7 +560,7 @@ setupmenu(struct Menu *menu, XClassHint *classh)
|
||||||
XTextProperty wintitle;
|
XTextProperty wintitle;
|
||||||
|
|
||||||
/* setup size and position of menus */
|
/* setup size and position of menus */
|
||||||
setupmenusize(menu);
|
setupitems(menu);
|
||||||
setupmenupos(menu);
|
setupmenupos(menu);
|
||||||
|
|
||||||
/* update menu geometry */
|
/* update menu geometry */
|
||||||
|
@ -685,7 +706,8 @@ drawseparator(struct Menu *menu, struct Item *item)
|
||||||
y = item->y + item->h/2;
|
y = item->y + item->h/2;
|
||||||
|
|
||||||
XSetForeground(dpy, dc.gc, dc.separator.pixel);
|
XSetForeground(dpy, dc.gc, dc.separator.pixel);
|
||||||
XDrawLine(dpy, menu->pixmap, dc.gc, 0, y, menu->w, y);
|
XDrawLine(dpy, menu->pixmap, dc.gc, config.horzpadding, y,
|
||||||
|
menu->w - config.horzpadding, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* draw regular item */
|
/* draw regular item */
|
||||||
|
@ -694,7 +716,8 @@ drawitem(struct Menu *menu, struct Item *item, XftColor *color)
|
||||||
{
|
{
|
||||||
int x, y;
|
int x, y;
|
||||||
|
|
||||||
x = item->h;
|
x = config.horzpadding;
|
||||||
|
x += (iflag) ? 0 : config.horzpadding + config.iconsize;
|
||||||
y = item->y + (item->h + dc.font->ascent) / 2;
|
y = item->y + (item->h + dc.font->ascent) / 2;
|
||||||
XSetForeground(dpy, dc.gc, color[ColorFG].pixel);
|
XSetForeground(dpy, dc.gc, color[ColorFG].pixel);
|
||||||
XftDrawStringUtf8(menu->draw, &color[ColorFG], dc.font,
|
XftDrawStringUtf8(menu->draw, &color[ColorFG], dc.font,
|
||||||
|
@ -702,7 +725,7 @@ drawitem(struct Menu *menu, struct Item *item, XftColor *color)
|
||||||
|
|
||||||
/* draw triangle, if item contains a submenu */
|
/* draw triangle, if item contains a submenu */
|
||||||
if (item->submenu != NULL) {
|
if (item->submenu != NULL) {
|
||||||
x = menu->w - (item->h + config.triangle_width + 1) / 2;
|
x = menu->w - config.triangle_width - config.horzpadding;
|
||||||
y = item->y + (item->h - config.triangle_height + 1) / 2;
|
y = item->y + (item->h - config.triangle_height + 1) / 2;
|
||||||
|
|
||||||
XPoint triangle[] = {
|
XPoint triangle[] = {
|
||||||
|
@ -717,8 +740,8 @@ drawitem(struct Menu *menu, struct Item *item, XftColor *color)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* draw icon */
|
/* draw icon */
|
||||||
if (item->file != NULL) {
|
if (item->icon != NULL) {
|
||||||
x = config.iconpadding;
|
x = config.horzpadding;
|
||||||
y = item->y + config.iconpadding;
|
y = item->y + config.iconpadding;
|
||||||
imlib_context_set_drawable(menu->pixmap);
|
imlib_context_set_drawable(menu->pixmap);
|
||||||
imlib_context_set_image(item->icon);
|
imlib_context_set_image(item->icon);
|
||||||
|
@ -997,6 +1020,6 @@ cleanup(void)
|
||||||
static void
|
static void
|
||||||
usage(void)
|
usage(void)
|
||||||
{
|
{
|
||||||
(void)fprintf(stderr, "usage: xmenu [-w] [title]\n");
|
(void)fprintf(stderr, "usage: xmenu [-iw] [title]\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
3
xmenu.h
3
xmenu.h
|
@ -36,6 +36,9 @@ struct Config {
|
||||||
int triangle_height;
|
int triangle_height;
|
||||||
|
|
||||||
int iconpadding;
|
int iconpadding;
|
||||||
|
int horzpadding;
|
||||||
|
|
||||||
|
int iconsize;
|
||||||
|
|
||||||
int cursx, cursy; /* cursor position */
|
int cursx, cursy; /* cursor position */
|
||||||
int screenw, screenh; /* screen width and height */
|
int screenw, screenh; /* screen width and height */
|
||||||
|
|
Loading…
Reference in New Issue
Block a user