diff --git a/docs/docs.md b/docs/docs.md index 047bcb2..84e2287 100644 --- a/docs/docs.md +++ b/docs/docs.md @@ -211,6 +211,12 @@ in the config files. `-c, --center` : Position spmenu at the center of the screen +`-itt, --item-top` +: Position items above all other elements + +`-itb, --item-bottom` +: Position items below all other elements + `-hm, --hide-mode` : Hide mode indicator diff --git a/docs/spmenu.conf b/docs/spmenu.conf index 8da5565..8e293e7 100644 --- a/docs/spmenu.conf +++ b/docs/spmenu.conf @@ -187,7 +187,8 @@ spmenu = { } ); /* Line options */ - line = ( { height = 1; // Height of each line (px) + line = ( { itemposition = 0; // Item position (0: Bottom, 1: Top) + height = 1; // Height of each line (px) lines = 0; // Number of lines (number) columns = 10; // Number of columns (number) overridelines = 1; // Allow overriding lines using keybinds (0/1) diff --git a/libs/argv.c b/libs/argv.c index a7e126e..99c025e 100644 --- a/libs/argv.c +++ b/libs/argv.c @@ -126,6 +126,10 @@ void readargs(int argc, char *argv[]) { menuposition = 1; } else if (!strcmp(argv[i], "-c") || (!strcmp(argv[i], "--center"))) { // appears at the center of the screen menuposition = 2; + } else if (!strcmp(argv[i], "-itt") || (!strcmp(argv[i], "--item-top"))) { // items are placed above prompt + itemposition = 1; + } else if (!strcmp(argv[i], "-itb") || (!strcmp(argv[i], "--item-bottom"))) { // items are placed below prompt + menuposition = 0; } else if (!strcmp(argv[i], "-nm") || (!strcmp(argv[i], "--normal"))) { // normal mode mode = 0; } else if (!strcmp(argv[i], "-im") || (!strcmp(argv[i], "--insert"))) { // insert mode @@ -663,6 +667,8 @@ void usage(int status) { "spmenu -t, --top Position spmenu at the top of the screen\n" "spmenu -b, --bottom Position spmenu at the bottom of the screen\n" "spmenu -c, --center Position spmenu at the center of the screen\n" + "spmenu -itt, --item-top Position items above all other elements\n" + "spmenu -itb, --item-bottom Position items below all other elements\n" , status ? stderr : stdout); // more args diff --git a/libs/conf/config.c b/libs/conf/config.c index ea72ff2..28023cf 100644 --- a/libs/conf/config.c +++ b/libs/conf/config.c @@ -753,6 +753,7 @@ void conf_init(void) { config_setting_t *conf = config_setting_get_elem(line_setting, i); // look up + config_setting_lookup_int(conf, "itemposition", &itemposition); // spmenu.line.itemposition config_setting_lookup_int(conf, "height", &lineheight); // spmenu.line.height config_setting_lookup_int(conf, "lines", &lines); // spmenu.line.lines config_setting_lookup_int(conf, "columns", &columns); // spmenu.line.columns diff --git a/libs/draw.c b/libs/draw.c index 7dd0f4b..05a5cfd 100644 --- a/libs/draw.c +++ b/libs/draw.c @@ -686,39 +686,58 @@ void drawmenu_layer(void) { calcoffsets(); get_mh(); + int nh = 1; + // sp.bh must be removed from menu height resizing later if ((hideprompt && hideinput && hidemode && hidematchcount && hidecaps) && lines) { y -= sp.bh; + nh = 0; + } + + if (!hidemode) { + modew = pango_mode ? TEXTWM(tx.modetext) : TEXTW(tx.modetext); } if (!hideprompt) { w = sp.promptw; - x = drawprompt(x, y, w); + x = drawprompt(x, y + (nh ? lines ? itemposition ? (sp.mh - sp.bh) : 0 : 0 : 0), w); } if (!hideinput) { w = (lines > 0 || !matches) ? sp.mw - x : sp.inputw; - x = drawinput(x, y, w); + x = drawinput(x, y + (nh ? lines ? itemposition ? (sp.mh - sp.bh) : 0 : 0 : 0), w); } - if (!hidemode) modew = pango_mode ? TEXTWM(tx.modetext) : TEXTW(tx.modetext); - // draw the items, this function also calls drawrarrow() and drawlarrow() - if (!hideitem) drawitem(x, y, w); + if (!hideitem) { + drawitem(x, y - (nh ? lines ? itemposition ? sp.bh : 0 : 0 : 0), w); + } if (!hidematchcount) { w = numberw; - drawnumber(sp.mw - numberw - modew - capsw - 2 * sp.sp - 2 * borderwidth - menumarginh, y, w); + drawnumber( + sp.mw - numberw - modew - capsw - 2 * sp.sp - 2 * borderwidth - menumarginh, + y + (nh ? lines ? itemposition ? (sp.mh - sp.bh) : 0 : 0 : 0), + w + ); } if (!hidemode) { w = modew; - drawmode(sp.mw - modew - capsw - 2 * sp.sp - 2 * borderwidth - menumarginh, y, w); + drawmode( + sp.mw - modew - capsw - 2 * sp.sp - 2 * borderwidth - menumarginh, + y + (nh ? lines ? itemposition ? (sp.mh - sp.bh) : 0 : 0 : 0), + w + ); } if (!hidecaps) { w = capsw; - drawcaps(sp.mw - capsw - 2 * sp.sp - 2 * borderwidth - menumarginh, y, w); + drawcaps( + sp.mw - capsw - 2 * sp.sp - 2 * borderwidth - menumarginh, + y + (nh ? lines ? itemposition ? (sp.mh - sp.bh) : 0 : 0 : 0), + w + ); } #if USEX diff --git a/libs/options.h b/libs/options.h index ba5cbaa..52c3ac4 100644 --- a/libs/options.h +++ b/libs/options.h @@ -103,6 +103,7 @@ static int regex = 0; /* Whether or not to enable regex ma static char *listfile = NULL; /* File to read entries from instead of stdin. NULL means read from stdin instead. */ /* Line options */ +static int itemposition = 1; /* Item position (0: Bottom, 1: Top) */ static int lineheight = 1; /* Line height (0: Calculate automatically) */ static int lines = 0; /* Default number of lines */ static int columns = 10; /* Default number of columns */ diff --git a/libs/theme/theme.c b/libs/theme/theme.c index 744fd7b..0463cc3 100644 --- a/libs/theme/theme.c +++ b/libs/theme/theme.c @@ -438,6 +438,7 @@ void theme_load(void) { config_setting_t *conf = config_setting_get_elem(line_setting, i); // look up + config_setting_lookup_int(conf, "itemposition", &itemposition); // theme.line.itemposition config_setting_lookup_int(conf, "height", &lineheight); // theme.line.height config_setting_lookup_int(conf, "indentitems", &indentitems); // theme.line.indentitems } diff --git a/libs/wl/wayland.c b/libs/wl/wayland.c index 5331ceb..4540722 100644 --- a/libs/wl/wayland.c +++ b/libs/wl/wayland.c @@ -280,7 +280,9 @@ void buttonpress_wl(uint32_t button, double ex, double ey) { if ((hideprompt && hideinput && hidemode && hidematchcount && hidecaps) && lines) { yp = 1; - } else if (lines && ey < h + menumarginv && ey > menumarginv) { + } else if (!itemposition && lines && ey <= h + menumarginv && ey >= menumarginv) { + yp = 1; + } else if (itemposition && lines && ey >= (sp.mh - h) + menumarginv) { yp = 1; } else if (!lines) { yp = 1; @@ -320,7 +322,7 @@ void buttonpress_wl(uint32_t button, double ex, double ey) { ey -= menumarginv; - if (hideprompt && hideinput && hidemode && hidematchcount && hidecaps) { + if ((hideprompt && hideinput && hidemode && hidematchcount && hidecaps) || itemposition) { ey += h; } diff --git a/libs/x11/mouse.c b/libs/x11/mouse.c index 646cdef..2d059f2 100644 --- a/libs/x11/mouse.c +++ b/libs/x11/mouse.c @@ -27,7 +27,9 @@ void buttonpress_x11(XEvent *e) { if ((hideprompt && hideinput && hidemode && hidematchcount && hidecaps) && lines) { yp = 1; - } else if (lines && ev->y < h + menumarginv && ev->y > menumarginv) { + } else if (!itemposition && lines && ev->y <= h + menumarginv && ev->y >= menumarginv) { + yp = 1; + } else if (itemposition && lines && ev->y >= (sp.mh - h) + menumarginv) { yp = 1; } else if (!lines) { yp = 1; @@ -69,7 +71,7 @@ void buttonpress_x11(XEvent *e) { ev->y -= menumarginv; - if (hideprompt && hideinput && hidemode && hidematchcount && hidecaps) { + if ((hideprompt && hideinput && hidemode && hidematchcount && hidecaps) || itemposition) { ev->y += h; } diff --git a/spmenu.1 b/spmenu.1 index 8384fa9..9d77c7b 100644 --- a/spmenu.1 +++ b/spmenu.1 @@ -239,6 +239,12 @@ Position spmenu at the bottom of the screen \f[V]-c, --center\f[R] Position spmenu at the center of the screen .TP +\f[V]-itt, --item-top\f[R] +Position items above all other elements +.TP +\f[V]-itb, --item-bottom\f[R] +Position items below all other elements +.TP \f[V]-hm, --hide-mode\f[R] Hide mode indicator .TP