Updating on this. I did some extra digging and it looks like the menu should
be set to hold a max of 32 chars as that's the input limit. I re-adjusted my
patch and now it takes the font width * 32 and uses that as the width
measurement. With this I removed the custom size option and just allowed the
caller to have it on or off by simply using a -w flag. I've checked with both
fixed and variable width fonts and it looks to operate correctly although it
does give extra space with variable width fonts as I believe the reported width
is for the widest character in the font.
diff attached.
> Date: Sat, 17 Mar 2012 19:28:00 +0000
> Subject: Re: [dev] dmenu idea and diff, Ability to set menu width
> From: [email protected]
> To: [email protected]
>
> > I wasn't suggesting resizing it depending on the match, but resizing
> > it to the given font metrics for the longest item read from stdin
> > instead (only once at the start of dmenu).
> >
> Most simply, dmenu would be as wide as the screen.
>
diff -r dc4b49011838 dmenu.1
--- a/dmenu.1 Fri Apr 06 16:38:01 2012 +0100
+++ b/dmenu.1 Thu Apr 19 00:12:04 2012 -0700
@@ -8,6 +8,7 @@
.RB [ \-i ]
.RB [ \-l
.IR lines ]
+.RB [ \-w ]
.RB [ \-p
.IR prompt ]
.RB [ \-fn
@@ -49,6 +50,9 @@
.BI \-l " lines"
dmenu lists items vertically, with the given number of lines.
.TP
+.BI \-w
+trims dmenu width to fit the currently used font (for vertical lists)
+.TP
.BI \-p " prompt"
defines the prompt to be displayed to the left of the input field.
.TP
diff -r dc4b49011838 dmenu.c
--- a/dmenu.c Fri Apr 06 16:38:01 2012 +0100
+++ b/dmenu.c Thu Apr 19 00:12:04 2012 -0700
@@ -50,6 +50,7 @@
static const char *selbgcolor = "#005577";
static const char *selfgcolor = "#eeeeee";
static unsigned int lines = 0;
+static Bool trimWidth = False;
static unsigned long normcol[ColLast];
static unsigned long selcol[ColLast];
static Atom clip, utf8;
@@ -83,6 +84,8 @@
fstrncmp = strncasecmp;
fstrstr = cistrstr;
}
+ else if(!strcmp(argv[i], "-w")) /* change menu width to auto fit column */
+ trimWidth = True;
else if(i+1 == argc)
usage();
/* these options take one argument */
@@ -482,6 +485,7 @@
eprintf("cannot strdup %u bytes:", strlen(buf)+1);
if(strlen(items[i].text) > max)
max = strlen(maxstr = items[i].text);
+
}
if(items)
items[i].text = NULL;
@@ -569,7 +573,7 @@
x = info[i].x_org;
y = info[i].y_org + (topbar ? 0 : info[i].height - mh);
- mw = info[i].width;
+ mw = trimWidth ? dc->font.width * 32 : info[i].width;
XFree(info);
}
else
@@ -577,7 +581,7 @@
{
x = 0;
y = topbar ? 0 : DisplayHeight(dc->dpy, screen) - mh;
- mw = DisplayWidth(dc->dpy, screen);
+ mw = trimWidth ? dc->font.width * 32 : DisplayWidth(dc->dpy, screen);
}
promptw = prompt ? textw(dc, prompt) : 0;
inputw = MIN(inputw, mw/3);
@@ -604,7 +608,7 @@
void
usage(void) {
- fputs("usage: dmenu [-b] [-f] [-i] [-l lines] [-p prompt] [-fn font]\n"
+ fputs("usage: dmenu [-b] [-f] [-i] [-w] [-l lines] [-p prompt] [-fn font]\n"
" [-nb color] [-nf color] [-sb color] [-sf color] [-v]\n", stderr);
exit(EXIT_FAILURE);
}