diff --git a/colors.h b/colors.h index 85c7713..bcdd6c4 100644 --- a/colors.h +++ b/colors.h @@ -2,44 +2,46 @@ /* Alpha */ static const unsigned int alphas[][3] = { - /* fg bg border */ - [SchemeNorm] = { opaque, baralpha, borderalpha }, - [SchemeSel] = { opaque, baralpha, borderalpha }, - [SchemePrompt] = { opaque, baralpha, borderalpha }, - [SchemeNormHighlight] = { opaque, baralpha, borderalpha }, - [SchemeSelHighlight] = { opaque, baralpha, borderalpha }, - [SchemeCaret] = { opaque, baralpha, borderalpha }, - [SchemeNumber] = { opaque, baralpha, borderalpha }, + /* fg bg border */ + [SchemeNorm] = { fgalpha, bgalpha, borderalpha }, + [SchemeSel] = { fgalpha, bgalpha, borderalpha }, + [SchemePrompt] = { fgalpha, bgalpha, borderalpha }, + [SchemeNormHighlight] = { fgalpha, bgalpha, borderalpha }, + [SchemeSelHighlight] = { fgalpha, bgalpha, borderalpha }, + [SchemeCaret] = { fgalpha, bgalpha, borderalpha }, + [SchemeNumber] = { fgalpha, bgalpha, borderalpha }, + [SchemeBorder] = { fgalpha, bgalpha, borderalpha }, }; /* Colors */ static const char *colors[SchemeLast][2] = { - /* fg bg */ - [SchemeNorm] = { normfgcolor, normbgcolor }, - [SchemeSel] = { selfgcolor, selbgcolor }, - [SchemePrompt] = { selfgcolor, selbgcolor }, - [SchemeNormHighlight] = { normhlfgcolor, normhlbgcolor }, - [SchemeSelHighlight] = { selhlfgcolor, selhlbgcolor }, - [SchemeCaret] = { caretfgcolor, NULL }, - [SchemeNumber] = { numfgcolor, numbgcolor }, + /* fg bg */ + [SchemeNorm] = { col_normfgcolor, col_normbgcolor }, + [SchemeSel] = { col_selfgcolor, col_selbgcolor }, + [SchemeBorder] = { NULL, col_bordercolor }, + [SchemePrompt] = { col_selfgcolor, col_selbgcolor }, + [SchemeNormHighlight] = { col_normhlfgcolor, col_normhlbgcolor }, + [SchemeSelHighlight] = { col_selhlfgcolor, col_selhlbgcolor }, + [SchemeCaret] = { col_caretfgcolor, NULL }, + [SchemeNumber] = { col_numfgcolor, col_numbgcolor }, }; /* sgr colors */ static char *textcolors[] = { - sgrcolor0, - sgrcolor1, - sgrcolor2, - sgrcolor3, - sgrcolor4, - sgrcolor5, - sgrcolor6, - sgrcolor7, - sgrcolor8, - sgrcolor9, - sgrcolor10, - sgrcolor11, - sgrcolor12, - sgrcolor13, - sgrcolor14, - sgrcolor15, + col_sgrcolor0, + col_sgrcolor1, + col_sgrcolor2, + col_sgrcolor3, + col_sgrcolor4, + col_sgrcolor5, + col_sgrcolor6, + col_sgrcolor7, + col_sgrcolor8, + col_sgrcolor9, + col_sgrcolor10, + col_sgrcolor11, + col_sgrcolor12, + col_sgrcolor13, + col_sgrcolor14, + col_sgrcolor15, }; diff --git a/docs/example.Xresources b/docs/example.Xresources index fefb761..ef8a77d 100644 --- a/docs/example.Xresources +++ b/docs/example.Xresources @@ -1,37 +1,32 @@ -!! spmenu -!! -!! colors spmenu.font: DejaVu Sans Mono 8 -spmenu.normfgcolor: #bbbbbb -spmenu.normbgcolor: #222222 -spmenu.selfgcolor: #eeeeee -spmenu.selbgcolor: #005577 -spmenu.normhlfgcolor: #ffffff -spmenu.normhlbgcolor: #000000 -spmenu.selhlfgcolor: #ffffff -spmenu.selhlbgcolor: #000000 -spmenu.outfgcolor: #000000 -spmenu.outbgcolor: #5e81ac -spmenu.caretfgcolor: #222222 -spmenu.sgrcolor0: #000000 -spmenu.sgrcolor1: #7f0000 -spmenu.sgrcolor2: #007f00 -spmenu.sgrcolor3: #7f7f00 -spmenu.sgrcolor4: #00007f -spmenu.sgrcolor5: #7f007f -spmenu.sgrcolor6: #007f7f -spmenu.sgrcolor7: #cccccc -spmenu.sgrcolor8: #333333 -spmenu.sgrcolor9: #ff0000 -spmenu.sgrcolor10: #00ff00 -spmenu.sgrcolor11: #ffff00 -spmenu.sgrcolor12: #0000ff -spmenu.sgrcolor13: #ff00ff -spmenu.sgrcolor14: #00ffff -spmenu.sgrcolor15: #ffffff - -!! misc +spmenu.col_normfgcolor: #bbbbbb +spmenu.col_normbgcolor: #222222 +spmenu.col_selfgcolor: #eeeeee +spmenu.col_selbgcolor: #005577 +spmenu.col_normhlfgcolor: #ffffff +spmenu.col_normhlbgcolor: #000000 +spmenu.col_selhlfgcolor: #ffffff +spmenu.col_selhlbgcolor: #000000 +spmenu.col_caretfgcolor: #ffffff +spmenu.col_bordercolor: #005577 +spmenu.col_sgrcolor0: #000000 +spmenu.col_sgrcolor1: #7f0000 +spmenu.col_sgrcolor2: #007f00 +spmenu.col_sgrcolor3: #7f7f00 +spmenu.col_sgrcolor4: #00007f +spmenu.col_sgrcolor5: #7f007f +spmenu.col_sgrcolor6: #007f7f +spmenu.col_sgrcolor7: #cccccc +spmenu.col_sgrcolor8: #333333 +spmenu.col_sgrcolor9: #ff0000 +spmenu.col_sgrcolor10: #00ff00 +spmenu.col_sgrcolor11: #ffff00 +spmenu.col_sgrcolor12: #0000ff +spmenu.col_sgrcolor13: #ff00ff +spmenu.col_sgrcolor14: #00ffff +spmenu.col_sgrcolor15: #ffffff spmenu.alpha: 1 +spmenu.accuratewidth: 1 spmenu.bordercentered: 1 spmenu.borderwidth: 2 spmenu.lines: 0 @@ -50,5 +45,4 @@ spmenu.type: 1 spmenu.class: spmenu spmenu.leftarrow: < spmenu.rightarrow: > - spmenu.hidematchcount: 0 diff --git a/options.h b/options.h index e284791..b5c4018 100644 --- a/options.h +++ b/options.h @@ -32,6 +32,7 @@ static char *rightarrow = ">"; /* Right arrow, used to indicate y static int type = 1; /* Allow typing into spmenu or only allow keybinds. */ static int casesensitive = 0; /* Case-sensitive by default? (0/1) */ static int preselected = 0; /* Which line should spmenu preselect? */ +static int accuratewidth = 1; /* Enable accurate width. May have a performance hit if you are matching a lot of items at once */ static int fuzzy = 1; /* Whether or not to enable fuzzy matching by default */ /* Line options */ @@ -55,48 +56,52 @@ static int hidematchcount = 0; /* Hide match count (0/1) */ * * Normal foreground colors */ -static char normfgcolor[] = "#bbbbbb"; /* Text color for unselected */ -static char normbgcolor[] = "#222222"; /* Background color for unselected */ +static char col_normfgcolor[] = "#bbbbbb"; /* Text color for unselected */ +static char col_normbgcolor[] = "#222222"; /* Background color for unselected */ /* Selected foreground colors */ -static char selfgcolor[] = "#eeeeee"; /* Text color for selected */ -static char selbgcolor[] = "#5e81ac"; /* Background color for selected */ +static char col_selfgcolor[] = "#eeeeee"; /* Text color for selected */ +static char col_selbgcolor[] = "#005577"; /* Background color for selected */ /* Normal highlight colors */ -static char normhlfgcolor[] = "#ffffff"; /* Text highlight color for unselected */ -static char normhlbgcolor[] = "#000000"; /* Background highlight color for unselected */ +static char col_normhlfgcolor[] = "#ffffff"; /* Text highlight color for unselected */ +static char col_normhlbgcolor[] = "#000000"; /* Background highlight color for unselected */ /* Selected highlight colors */ -static char selhlfgcolor[] = "#ffffff"; /* Text highlight color for selected */ -static char selhlbgcolor[] = "#000000"; /* Background highlight color for selected */ +static char col_selhlfgcolor[] = "#ffffff"; /* Text highlight color for selected */ +static char col_selhlbgcolor[] = "#000000"; /* Background highlight color for selected */ /* Match count colors */ -static char numfgcolor[] = "#ffffff"; /* Match count text color */ -static char numbgcolor[] = "#000000"; /* Match count background color */ +static char col_numfgcolor[] = "#ffffff"; /* Match count text color */ +static char col_numbgcolor[] = "#000000"; /* Match count background color */ + +/* Border color */ +static char col_bordercolor[] = "#005577"; /* Border color */ /* Caret colors */ -static char caretfgcolor[] = "#222222"; /* Caret color */ +static char col_caretfgcolor[] = "#ffffff"; /* Caret color */ /* SGR colors */ -static char sgrcolor0[] = "#000000"; /* SGR color #0 */ -static char sgrcolor1[] = "#7f0000"; /* SGR color #1 */ -static char sgrcolor2[] = "#007f00"; /* SGR color #2 */ -static char sgrcolor3[] = "#7f7f00"; /* SGR color #3 */ -static char sgrcolor4[] = "#00007f"; /* SGR color #4 */ -static char sgrcolor5[] = "#7f007f"; /* SGR color #5 */ -static char sgrcolor6[] = "#007f7f"; /* SGR color #6 */ -static char sgrcolor7[] = "#cccccc"; /* SGR color #7 */ -static char sgrcolor8[] = "#333333"; /* SGR color #8 */ -static char sgrcolor9[] = "#ff0000"; /* SGR color #9 */ -static char sgrcolor10[] = "#00ff00"; /* SGR color #10 */ -static char sgrcolor11[] = "#ffff00"; /* SGR color #11 */ -static char sgrcolor12[] = "#0000ff"; /* SGR color #12 */ -static char sgrcolor13[] = "#ff00ff"; /* SGR color #13 */ -static char sgrcolor14[] = "#00ffff"; /* SGR color #14 */ -static char sgrcolor15[] = "#ffffff"; /* SGR color #15 */ +static char col_sgrcolor0[] = "#000000"; /* SGR color #0 */ +static char col_sgrcolor1[] = "#7f0000"; /* SGR color #1 */ +static char col_sgrcolor2[] = "#007f00"; /* SGR color #2 */ +static char col_sgrcolor3[] = "#7f7f00"; /* SGR color #3 */ +static char col_sgrcolor4[] = "#00007f"; /* SGR color #4 */ +static char col_sgrcolor5[] = "#7f007f"; /* SGR color #5 */ +static char col_sgrcolor6[] = "#007f7f"; /* SGR color #6 */ +static char col_sgrcolor7[] = "#cccccc"; /* SGR color #7 */ +static char col_sgrcolor8[] = "#333333"; /* SGR color #8 */ +static char col_sgrcolor9[] = "#ff0000"; /* SGR color #9 */ +static char col_sgrcolor10[] = "#00ff00"; /* SGR color #10 */ +static char col_sgrcolor11[] = "#ffff00"; /* SGR color #11 */ +static char col_sgrcolor12[] = "#0000ff"; /* SGR color #12 */ +static char col_sgrcolor13[] = "#ff00ff"; /* SGR color #13 */ +static char col_sgrcolor14[] = "#00ffff"; /* SGR color #14 */ +static char col_sgrcolor15[] = "#ffffff"; /* SGR color #15 */ /* Alpha options */ -#define baralpha 200 /* Bar alpha */ +#define fgalpha opaque /* Foreground alpha */ +#define bgalpha 200 /* Background alpha */ #define borderalpha opaque /* Border alpha */ /* Misc */ diff --git a/spmenu.c b/spmenu.c index d3f7f9d..bf10cc6 100644 --- a/spmenu.c +++ b/spmenu.c @@ -66,6 +66,7 @@ enum { SchemeNorm, SchemeNumber, SchemeNormHighlight, SchemeSelHighlight, + SchemeBorder, SchemeLast }; /* color schemes */ struct item { @@ -108,7 +109,7 @@ static struct item *prev, *curr, *next, *sel; static int mon = -1, screen; static int managed = 0; -static Atom clip, utf8; +static Atom clip, utf8, types, dock; static Display *dpy; static Window root, parentwin, win; static XIC xic; @@ -1510,6 +1511,9 @@ setup(void) { int x, y, i, j; unsigned int du; + unsigned int tmp, minstrlen = 0, curstrlen = 0; + int numwidthchecks = 100; + struct item *item; XSetWindowAttributes swa; XIM xim; Window w, dw, *dws; @@ -1573,6 +1577,8 @@ setup(void) clip = XInternAtom(dpy, "CLIPBOARD", False); utf8 = XInternAtom(dpy, "UTF8_STRING", False); + types = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False); + dock = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DOCK", False); /* calculate menu geometry */ bh = drw->font->h + 2; @@ -1580,6 +1586,21 @@ setup(void) lines = MAX(lines, 0); mh = (lines + 1) * bh; promptw = (prompt && *prompt) ? TEXTWM(prompt) - lrpad / 4 : 0; + + if (accuratewidth) { + for (item = items; !lines && item && item->text; ++item) { + curstrlen = strlen(item->text); + if (numwidthchecks || minstrlen < curstrlen) { + numwidthchecks = MAX(numwidthchecks - 1, 0); + minstrlen = MAX(minstrlen, curstrlen); + if ((tmp = MIN(TEXTW(item->text), mw/3) > inputw)) { + inputw = tmp; + if (tmp == mw/3) + break; + } + } + } + } #ifdef XINERAMA i = 0; if (parentwin == root && (info = XineramaQueryScreens(dpy, &n))) { @@ -1636,7 +1657,9 @@ setup(void) mw = wa.width; } } - inputw = MIN(inputw, mw/3); + + /* might be faster in some instances, most of the time unnecessary */ + if (!accuratewidth) inputw = MIN(inputw, mw/3); match(); /* create menu window */ @@ -1661,8 +1684,9 @@ setup(void) } } - XSetWindowBorder(dpy, win, scheme[SchemeSel][ColBg].pixel); + XSetWindowBorder(dpy, win, scheme[SchemeBorder][ColBg].pixel); XSetClassHint(dpy, win, &ch); + XChangeProperty(dpy, win, types, XA_ATOM, 32, PropModeReplace, (unsigned char *) &dock, 1); /* input methods */ @@ -1694,6 +1718,8 @@ usage(void) "spmenu -l Set line count to stdin\n" "spmenu -h Set spmenu height to \n" "spmenu -g Set the number of grids to \n" + "spmenu -rw Enable relative input width\n" + "spmenu -nrw Disable relative input width\n" "spmenu -f Grabs keyboard before reading stdin\n" "spmenu -F Enable fuzzy matching\n" "spmenu -P Hide characters\n" @@ -1806,9 +1832,13 @@ main(int argc, char *argv[]) } else if (!strcmp(argv[i], "-bc")) { /* draw border when centered */ bordercentered = 1; centered = 1; - } else if (!strcmp(argv[i], "-f")) /* grabs keyboard before reading stdin */ + } else if (!strcmp(argv[i], "-f")) { /* grabs keyboard before reading stdin */ fast = 1; - else if (!strcmp(argv[i], "-xrdb")) /* xresources */ + } else if (!strcmp(argv[i], "-rw")) { /* relative width */ + accuratewidth = 1; + } else if (!strcmp(argv[i], "-nrw")) { /* no relative width */ + accuratewidth = 0; + } else if (!strcmp(argv[i], "-xrdb")) /* xresources */ xresources = 1; else if (!strcmp(argv[i], "-nxrdb")) /* no xresources */ xresources = 0; diff --git a/xresources.h b/xresources.h index 013c7a3..b92310b 100644 --- a/xresources.h +++ b/xresources.h @@ -3,72 +3,75 @@ */ ResourcePref resources[] = { - { "font", STRING, &font }, - { "caretfgcolor", STRING, &caretfgcolor }, - { "normfgcolor", STRING, &normfgcolor }, - { "normbgcolor", STRING, &normbgcolor }, - { "selfgcolor", STRING, &selfgcolor }, - { "selbgcolor", STRING, &selbgcolor }, - { "numfgcolor", STRING, &numfgcolor }, - { "numbgcolor", STRING, &numbgcolor }, - { "normhlfgcolor", STRING, &normhlfgcolor }, - { "normhlbgcolor", STRING, &normhlbgcolor }, - { "selhlfgcolor", STRING, &selhlfgcolor }, - { "selhlbgcolor", STRING, &selhlbgcolor }, + { "font", STRING, &font }, + { "col_caretfgcolor", STRING, &col_caretfgcolor }, + { "col_normfgcolor", STRING, &col_normfgcolor }, + { "col_normbgcolor", STRING, &col_normbgcolor }, + { "col_selfgcolor", STRING, &col_selfgcolor }, + { "col_selbgcolor", STRING, &col_selbgcolor }, + { "col_numfgcolor", STRING, &col_numfgcolor }, + { "col_numbgcolor", STRING, &col_numbgcolor }, + { "col_normhlfgcolor", STRING, &col_normhlfgcolor }, + { "col_normhlbgcolor", STRING, &col_normhlbgcolor }, + { "col_selhlfgcolor", STRING, &col_selhlfgcolor }, + { "col_selhlbgcolor", STRING, &col_selhlbgcolor }, + { "col_bordercolor", STRING, &col_bordercolor }, /* Pywal support */ - { "color0", STRING, &caretfgcolor }, - { "color10", STRING, &normfgcolor }, - { "color0", STRING, &normbgcolor }, - { "color0", STRING, &selfgcolor }, - { "color6", STRING, &selbgcolor }, - { "color0", STRING, &numfgcolor }, - { "color6", STRING, &numbgcolor }, - { "color2", STRING, &normhlbgcolor }, - { "color3", STRING, &selhlbgcolor }, - { "color3", STRING, &normhlfgcolor }, - { "color0", STRING, &selhlfgcolor }, + { "color10", STRING, &col_caretfgcolor }, + { "color10", STRING, &col_normfgcolor }, + { "color0", STRING, &col_normbgcolor }, + { "color0", STRING, &col_selfgcolor }, + { "color6", STRING, &col_selbgcolor }, + { "color6", STRING, &col_bordercolor }, + { "color0", STRING, &col_numfgcolor }, + { "color6", STRING, &col_numbgcolor }, + { "color2", STRING, &col_normhlbgcolor }, + { "color3", STRING, &col_selhlbgcolor }, + { "color3", STRING, &col_normhlfgcolor }, + { "color0", STRING, &col_selhlfgcolor }, /* sgr colors */ - { "sgrcolor0", STRING, &sgrcolor0 }, - { "sgrcolor1", STRING, &sgrcolor1 }, - { "sgrcolor2", STRING, &sgrcolor2 }, - { "sgrcolor3", STRING, &sgrcolor3 }, - { "sgrcolor4", STRING, &sgrcolor4 }, - { "sgrcolor5", STRING, &sgrcolor5 }, - { "sgrcolor6", STRING, &sgrcolor6 }, - { "sgrcolor7", STRING, &sgrcolor7 }, - { "sgrcolor8", STRING, &sgrcolor8 }, - { "sgrcolor9", STRING, &sgrcolor9 }, - { "sgrcolor10", STRING, &sgrcolor10 }, - { "sgrcolor11", STRING, &sgrcolor11 }, - { "sgrcolor12", STRING, &sgrcolor12 }, - { "sgrcolor13", STRING, &sgrcolor13 }, - { "sgrcolor14", STRING, &sgrcolor14 }, - { "sgrcolor15", STRING, &sgrcolor15 }, + { "col_sgrcolor0", STRING, &col_sgrcolor0 }, + { "col_sgrcolor1", STRING, &col_sgrcolor1 }, + { "col_sgrcolor2", STRING, &col_sgrcolor2 }, + { "col_sgrcolor3", STRING, &col_sgrcolor3 }, + { "col_sgrcolor4", STRING, &col_sgrcolor4 }, + { "col_sgrcolor5", STRING, &col_sgrcolor5 }, + { "col_sgrcolor6", STRING, &col_sgrcolor6 }, + { "col_sgrcolor7", STRING, &col_sgrcolor7 }, + { "col_sgrcolor8", STRING, &col_sgrcolor8 }, + { "col_sgrcolor9", STRING, &col_sgrcolor9 }, + { "col_sgrcolor10", STRING, &col_sgrcolor10 }, + { "col_sgrcolor11", STRING, &col_sgrcolor11 }, + { "col_sgrcolor12", STRING, &col_sgrcolor12 }, + { "col_sgrcolor13", STRING, &col_sgrcolor13 }, + { "col_sgrcolor14", STRING, &col_sgrcolor14 }, + { "col_sgrcolor15", STRING, &col_sgrcolor15 }, /* sgr colors */ - { "color0", STRING, &sgrcolor0 }, - { "color1", STRING, &sgrcolor1 }, - { "color2", STRING, &sgrcolor2 }, - { "color3", STRING, &sgrcolor3 }, - { "color4", STRING, &sgrcolor4 }, - { "color5", STRING, &sgrcolor5 }, - { "color6", STRING, &sgrcolor6 }, - { "color7", STRING, &sgrcolor7 }, - { "color8", STRING, &sgrcolor8 }, - { "color9", STRING, &sgrcolor9 }, - { "color10", STRING, &sgrcolor10 }, - { "color11", STRING, &sgrcolor11 }, - { "color12", STRING, &sgrcolor12 }, - { "color13", STRING, &sgrcolor13 }, - { "color14", STRING, &sgrcolor14 }, - { "color15", STRING, &sgrcolor15 }, + { "color0", STRING, &col_sgrcolor0 }, + { "color1", STRING, &col_sgrcolor1 }, + { "color2", STRING, &col_sgrcolor2 }, + { "color3", STRING, &col_sgrcolor3 }, + { "color4", STRING, &col_sgrcolor4 }, + { "color5", STRING, &col_sgrcolor5 }, + { "color6", STRING, &col_sgrcolor6 }, + { "color7", STRING, &col_sgrcolor7 }, + { "color8", STRING, &col_sgrcolor8 }, + { "color9", STRING, &col_sgrcolor9 }, + { "color10", STRING, &col_sgrcolor10 }, + { "color11", STRING, &col_sgrcolor11 }, + { "color12", STRING, &col_sgrcolor12 }, + { "color13", STRING, &col_sgrcolor13 }, + { "color14", STRING, &col_sgrcolor14 }, + { "color15", STRING, &col_sgrcolor15 }, { "menuposition", INTEGER, &menuposition }, { "menupaddingv", INTEGER, &menupaddingv }, { "menupaddingh", INTEGER, &menupaddingh }, + { "accuratewidth", INTEGER, &accuratewidth }, { "alpha", INTEGER, &alpha }, { "type", INTEGER, &type }, { "preselected", INTEGER, &preselected },