Codebase improvements #8

Merged
speedie merged 4 commits from imp into master 2023-06-23 17:30:22 +02:00
22 changed files with 729 additions and 719 deletions

View file

@ -89,9 +89,9 @@ void moveup(Arg *arg) {
void complete(Arg *arg) { void complete(Arg *arg) {
if (hideitem) return; if (hideitem) return;
strncpy(text, sel->clntext, sizeof text - 1); strncpy(tx.text, sel->clntext, sizeof tx.text - 1);
text[sizeof text - 1] = '\0'; tx.text[sizeof tx.text - 1] = '\0';
cursor = strlen(text); sp.cursor = strlen(tx.text);
match(); match();
drawmenu(); drawmenu();
@ -127,7 +127,7 @@ void moveitem(Arg *arg) {
void movestart(Arg *arg) { void movestart(Arg *arg) {
if (sel == matches) { if (sel == matches) {
cursor = 0; sp.cursor = 0;
drawmenu(); drawmenu();
return; return;
} }
@ -138,8 +138,8 @@ void movestart(Arg *arg) {
} }
void moveend(Arg *arg) { void moveend(Arg *arg) {
if (text[cursor] != '\0') { if (tx.text[sp.cursor] != '\0') {
cursor = strlen(text); sp.cursor = strlen(tx.text);
drawmenu(); drawmenu();
return; return;
} }
@ -193,29 +193,29 @@ void viewhist(Arg *arg) {
} }
void deleteword(Arg *arg) { void deleteword(Arg *arg) {
if (cursor == 0) return; if (sp.cursor == 0) return;
while (cursor > 0 && strchr(worddelimiters, text[nextrune(-1)])) { while (sp.cursor > 0 && strchr(worddelimiters, tx.text[nextrune(-1)])) {
insert(NULL, nextrune(-1) - cursor); insert(NULL, nextrune(-1) - sp.cursor);
} while (cursor > 0 && !strchr(worddelimiters, text[nextrune(-1)])) { } while (sp.cursor > 0 && !strchr(worddelimiters, tx.text[nextrune(-1)])) {
insert(NULL, nextrune(-1) - cursor); insert(NULL, nextrune(-1) - sp.cursor);
} }
drawmenu(); drawmenu();
} }
void moveword(Arg *arg) { void moveword(Arg *arg) {
if (arg->i < 0) { // move cursor to the start of the word if (arg->i < 0) { // move sp.cursor to the start of the word
while (cursor > 0 && strchr(worddelimiters, text[nextrune(-1)])) { while (sp.cursor > 0 && strchr(worddelimiters, tx.text[nextrune(-1)])) {
cursor = nextrune(-1); sp.cursor = nextrune(-1);
} while (cursor > 0 && !strchr(worddelimiters, text[nextrune(-1)])) { } while (sp.cursor > 0 && !strchr(worddelimiters, tx.text[nextrune(-1)])) {
cursor = nextrune(-1); sp.cursor = nextrune(-1);
} }
} else { // move cursor to the end of the word } else { // move sp.cursor to the end of the word
while (text[cursor] && strchr(worddelimiters, text[cursor])) { while (tx.text[sp.cursor] && strchr(worddelimiters, tx.text[sp.cursor])) {
cursor = nextrune(+1); sp.cursor = nextrune(+1);
} while (text[cursor] && !strchr(worddelimiters, text[cursor])) { } while (tx.text[sp.cursor] && !strchr(worddelimiters, tx.text[sp.cursor])) {
cursor = nextrune(+1); sp.cursor = nextrune(+1);
} }
} }
@ -224,12 +224,12 @@ void moveword(Arg *arg) {
void movecursor(Arg *arg) { void movecursor(Arg *arg) {
if (arg->i < 0) { if (arg->i < 0) {
if (cursor > 0) { if (sp.cursor > 0) {
cursor = nextrune(-1); sp.cursor = nextrune(-1);
} }
} else { } else {
if (text[cursor]) { if (tx.text[sp.cursor]) {
cursor = nextrune(+1); sp.cursor = nextrune(+1);
} }
} }
@ -237,10 +237,10 @@ void movecursor(Arg *arg) {
} }
void backspace(Arg *arg) { void backspace(Arg *arg) {
if (cursor == 0) if (sp.cursor == 0)
return; return;
insert(NULL, nextrune(-1) - cursor); insert(NULL, nextrune(-1) - sp.cursor);
drawmenu(); drawmenu();
} }
@ -280,7 +280,7 @@ void selectitem(Arg *arg) {
if (sel && arg->i && !hideitem) { if (sel && arg->i && !hideitem) {
selection = sel->text; selection = sel->text;
} else { } else {
selection = text; selection = tx.text;
} }
for (int i = 0; i < sel_size; i++) { for (int i = 0; i < sel_size; i++) {
@ -305,22 +305,22 @@ void navhistory(Arg *arg) {
} }
void restoresel(Arg *arg) { void restoresel(Arg *arg) {
text[cursor] = '\0'; tx.text[sp.cursor] = '\0';
match(); match();
drawmenu(); drawmenu();
} }
void clear(Arg *arg) { void clear(Arg *arg) {
insert(NULL, 0 - cursor); insert(NULL, 0 - sp.cursor);
drawmenu(); drawmenu();
} }
void clearins(Arg *arg) { void clearins(Arg *arg) {
insert(NULL, 0 - cursor); insert(NULL, 0 - sp.cursor);
curMode = 1; sp.mode = 1;
allowkeys = 0; sp.allowkeys = 0;
strncpy(modetext, instext, 15); strncpy(tx.modetext, instext, 15);
calcoffsets(); calcoffsets();
drawmenu(); drawmenu();
@ -378,7 +378,7 @@ void flipimg(Arg *arg) {
if (!image) return; if (!image) return;
flip = flip ? 0 : arg->i ? 1 : 2; img.flip = img.flip ? 0 : arg->i ? 1 : 2;
drawmenu(); drawmenu();
@ -431,14 +431,14 @@ void togglefullimg(Arg *arg) {
fullscreen = image ? !fullscreen : 0; fullscreen = image ? !fullscreen : 0;
if (fullscreen) { if (fullscreen) {
ow = imagewidth; img.ow = imagewidth;
oh = imageheight; img.oh = imageheight;
imagewidth = mw; imagewidth = sp.mw;
imageheight = mh; imageheight = sp.mh;
} else { } else {
imagewidth = ow; imagewidth = img.ow;
imageheight = oh; imageheight = img.oh;
} }
drawmenu(); drawmenu();
@ -450,10 +450,10 @@ void defaultimg(Arg *arg) {
if (hideimage || !image) return; if (hideimage || !image) return;
if (imagew) { if (img.imagew) {
imagewidth = imagew; imagewidth = img.imagew;
imageheight = imageh; imageheight = img.imageh;
imagegaps = imageg; imagegaps = img.imageg;
} }
drawmenu(); drawmenu();
@ -517,12 +517,12 @@ void setprofile(Arg *arg) {
} }
void switchmode(Arg *arg) { void switchmode(Arg *arg) {
curMode = !curMode; sp.mode = !sp.mode;
if (!type) curMode = 0; // only normal mode allowed if (!type) sp.mode = 0; // only normal mode allowed
allowkeys = !curMode; sp.allowkeys = !sp.mode;
strncpy(modetext, curMode ? instext : normtext, 15); strncpy(tx.modetext, sp.mode ? instext : normtext, 15);
drawmenu(); drawmenu();
} }

View file

@ -305,10 +305,10 @@ void readargs(int argc, char *argv[]) {
} }
} else if (!strcmp(argv[i], "-l") || (!strcmp(argv[i], "--lines"))) { // number of lines in grid } else if (!strcmp(argv[i], "-l") || (!strcmp(argv[i], "--lines"))) { // number of lines in grid
lines = atoi(argv[++i]); lines = atoi(argv[++i]);
} else if (!strcmp(argv[i], "-mh") || (!strcmp(argv[i], "--lineheight")) || (!strcmp(argv[i], "--line-height"))) { // line height } else if (!strcmp(argv[i], "-sp.mh") || (!strcmp(argv[i], "--lineheight")) || (!strcmp(argv[i], "--line-height"))) { // line height
lineheight += atoi(argv[++i]); lineheight += atoi(argv[++i]);
if (columns == 0) columns = 1; if (columns == 0) columns = 1;
} else if (!strcmp(argv[i], "-mw") || (!strcmp(argv[i], "--min-width"))) { // line height } else if (!strcmp(argv[i], "-sp.mw") || (!strcmp(argv[i], "--min-width"))) { // line height
minwidth = atoi(argv[++i]); minwidth = atoi(argv[++i]);
} else if (!strcmp(argv[i], "-txp") || (!strcmp(argv[i], "--text-padding"))) { // text padding } else if (!strcmp(argv[i], "-txp") || (!strcmp(argv[i], "--text-padding"))) { // text padding
textpadding = atoi(argv[++i]); textpadding = atoi(argv[++i]);
@ -397,7 +397,7 @@ void readargs(int argc, char *argv[]) {
imageresize = 0; imageresize = 0;
} else if (!strcmp(argv[i], "-w") || (!strcmp(argv[i], "--embed"))) { // embedding window id } else if (!strcmp(argv[i], "-w") || (!strcmp(argv[i], "--embed"))) { // embedding window id
#if USEX #if USEX
embed = argv[++i]; x11.embed = argv[++i];
#endif #endif
} else if (!strcmp(argv[i], "-n") || (!strcmp(argv[i], "--preselect"))) { // preselected item } else if (!strcmp(argv[i], "-n") || (!strcmp(argv[i], "--preselect"))) { // preselected item
preselected = atoi(argv[++i]); preselected = atoi(argv[++i]);
@ -591,8 +591,8 @@ void usage(int status) {
fputs(": fancy dynamic menu\n\n" fputs(": fancy dynamic menu\n\n"
"- Arguments -\n" "- Arguments -\n"
"spmenu -l, --lines <line> Set line count to stdin\n" "spmenu -l, --lines <line> Set line count to stdin\n"
"spmenu -mh, --line-height <height> Set spmenu line height to <height>\n" "spmenu -sp.mh, --line-height <height> Set spmenu line height to <height>\n"
"spmenu -mw, --min-width <width> Set minimum width to <width> when centered\n" "spmenu -sp.mw, --min-width <width> Set minimum width to <width> when centered\n"
"spmenu -g, --columns <grid> Set the number of grids to <grid>\n" "spmenu -g, --columns <grid> Set the number of grids to <grid>\n"
"spmenu -gc, --generate-cache Generate image cache\n" "spmenu -gc, --generate-cache Generate image cache\n"
"spmenu -ngc, --no-generate-cache Don't generate image cache\n" "spmenu -ngc, --no-generate-cache Don't generate image cache\n"

View file

@ -663,7 +663,7 @@ void conf_init(void) {
} }
} }
config_setting_lookup_int(conf, "ignoreglobalkeys", &ignoreglobalkeys); config_setting_lookup_int(conf, "ignoreglobalkeys", &sp.ignoreglobalkeys);
} }
} }
@ -730,7 +730,7 @@ void conf_init(void) {
} }
} }
config_setting_lookup_int(conf, "ignoreglobalmouse", &ignoreglobalmouse); config_setting_lookup_int(conf, "ignoreglobalmouse", &sp.ignoreglobalmouse);
} }
} }
@ -868,7 +868,7 @@ void conf_init(void) {
} }
} }
config_setting_lookup_int(conf, "ignoreglobalkeys", &ignoreglobalkeys); config_setting_lookup_int(conf, "ignoreglobalkeys", &sp.ignoreglobalkeys);
} }
} }
@ -938,7 +938,7 @@ void conf_init(void) {
} }
} }
config_setting_lookup_int(conf, "ignoreglobalmouse", &ignoreglobalmouse); config_setting_lookup_int(conf, "ignoreglobalmouse", &sp.ignoreglobalmouse);
} }
} }

View file

@ -3,8 +3,8 @@
#define INTERSECT(x,y,w,h,r) (MAX(0, MIN((x)+(w),(r).x_org+(r).width) - MAX((x),(r).x_org)) \ #define INTERSECT(x,y,w,h,r) (MAX(0, MIN((x)+(w),(r).x_org+(r).width) - MAX((x),(r).x_org)) \
&& MAX(0, MIN((y)+(h),(r).y_org+(r).height) - MAX((y),(r).y_org))) && MAX(0, MIN((y)+(h),(r).y_org+(r).height) - MAX((y),(r).y_org)))
#define LENGTH(X) (sizeof X / sizeof X[0]) #define LENGTH(X) (sizeof X / sizeof X[0])
#define TEXTW(X) (drw_font_getwidth(drw, (X), False) + lrpad) #define TEXTW(X) (draw_font_getwidth(draw, (X), False) + sp.lrpad)
#define TEXTWM(X) (drw_font_getwidth(drw, (X), True) + lrpad) #define TEXTWM(X) (draw_font_getwidth(draw, (X), True) + sp.lrpad)
#define NUMBERSMAXDIGITS 100 #define NUMBERSMAXDIGITS 100
#define NUMBERSBUFSIZE (NUMBERSMAXDIGITS * 2) + 1 #define NUMBERSBUFSIZE (NUMBERSMAXDIGITS * 2) + 1
#define MAXITEMLENGTH 1024 #define MAXITEMLENGTH 1024

View file

@ -9,24 +9,24 @@ void drawhighlights(struct item *item, int x, int y, int w, int p, const char *i
char *itemtext = strdup(ittext); char *itemtext = strdup(ittext);
if (!(strlen(itemtext) && strlen(text))) return; if (!(strlen(itemtext) && strlen(tx.text))) return;
for (i = 0, highlight = itemtext; *highlight && text[i];) { for (i = 0, highlight = itemtext; *highlight && tx.text[i];) {
if (((fuzzy && !fstrncmp(&(*highlight), &text[i], 1)) || (!fuzzy && *highlight == text[i]))) { if (((fuzzy && !fstrncmp(&(*highlight), &tx.text[i], 1)) || (!fuzzy && *highlight == tx.text[i]))) {
c = *highlight; c = *highlight;
*highlight = '\0'; *highlight = '\0';
indent = TEXTW(itemtext) - lrpad; indent = TEXTW(itemtext) - sp.lrpad;
*highlight = c; *highlight = c;
// highlight character // highlight character
c = highlight[1]; c = highlight[1];
highlight[1] = '\0'; highlight[1] = '\0';
drw_text( draw_text(
drw, draw,
x + indent + (p), x + indent + (p),
y, y,
MIN(w - indent - lrpad, TEXTW(highlight) - lrpad), MIN(w - indent - sp.lrpad, TEXTW(highlight) - sp.lrpad),
bh, 0, highlight, 0, pango_highlight ? True : False, sp.bh, 0, highlight, 0, pango_highlight ? True : False,
item == sel ? col_hlselfg : col_hlnormfg, item == sel ? col_hlselfg : col_hlnormfg,
item == sel ? col_hlselbg : col_hlnormbg, item == sel ? col_hlselbg : col_hlnormbg,
item == sel ? alpha_hlselfg : alpha_hlnormfg, item == sel ? alpha_hlselfg : alpha_hlnormfg,
@ -40,7 +40,7 @@ void drawhighlights(struct item *item, int x, int y, int w, int p, const char *i
int drawitemtext(struct item *item, int x, int y, int w) { int drawitemtext(struct item *item, int x, int y, int w) {
char buffer[MAXITEMLENGTH]; // buffer containing item text char buffer[MAXITEMLENGTH]; // buffer containing item text
int leftpadding = lrpad / 2; // padding int leftpadding = sp.lrpad / 2; // padding
int wr, rd; // character int wr, rd; // character
int fg = 7; // foreground int fg = 7; // foreground
int bg = 0; // background int bg = 0; // background
@ -118,9 +118,9 @@ int drawitemtext(struct item *item, int x, int y, int w) {
if (!hidepowerline && powerlineitems && selitem) { if (!hidepowerline && powerlineitems && selitem) {
if (itempwlstyle == 2) { if (itempwlstyle == 2) {
drw_circle(drw, x - plw, y, plw, bh, 0, col_menu, bgcol, alpha_menu, bga); draw_circle(draw, x - sp.plw, y, sp.plw, sp.bh, 0, col_menu, bgcol, alpha_menu, bga);
} else { } else {
drw_arrow(drw, x - plw, y, plw, bh, 0, itempwlstyle, col_menu, bgcol, alpha_menu, bga); draw_arrow(draw, x - sp.plw, y, sp.plw, sp.bh, 0, itempwlstyle, col_menu, bgcol, alpha_menu, bga);
} }
} }
@ -136,12 +136,12 @@ int drawitemtext(struct item *item, int x, int y, int w) {
} }
apply_fribidi(buffer); apply_fribidi(buffer);
drw_text(drw, x, y, MIN(w, TEXTW(buffer) - lrpad) + leftpadding, bh, leftpadding, isrtl ? fribidi_text : buffer, 0, pango_item ? True : False, fgcol, bgcol, fga, bga); draw_text(draw, x, y, MIN(w, TEXTW(buffer) - sp.lrpad) + leftpadding, sp.bh, leftpadding, isrtl ? fribidi_text : buffer, 0, pango_item ? True : False, fgcol, bgcol, fga, bga);
drawhighlights(item, x, y, MIN(w, TEXTW(buffer) - lrpad) + leftpadding, leftpadding, isrtl ? fribidi_text : buffer); drawhighlights(item, x, y, MIN(w, TEXTW(buffer) - sp.lrpad) + leftpadding, leftpadding, isrtl ? fribidi_text : buffer);
// position and width // position and width
x += MIN(w, TEXTW(buffer) - lrpad) + leftpadding; x += MIN(w, TEXTW(buffer) - sp.lrpad) + leftpadding;
w -= MIN(w, TEXTW(buffer) - lrpad) + leftpadding; w -= MIN(w, TEXTW(buffer) - sp.lrpad) + leftpadding;
// no highlighting if colored text // no highlighting if colored text
leftpadding = 0; leftpadding = 0;
@ -255,7 +255,7 @@ int drawitemtext(struct item *item, int x, int y, int w) {
// now draw any non-colored text // now draw any non-colored text
apply_fribidi(buffer); apply_fribidi(buffer);
int r = drw_text(drw, x, y, w, bh, leftpadding, isrtl ? fribidi_text : buffer, 0, pango_item ? True : False, fgcol, bgcol, fga, bga); int r = draw_text(draw, x, y, w, sp.bh, leftpadding, isrtl ? fribidi_text : buffer, 0, pango_item ? True : False, fgcol, bgcol, fga, bga);
if (!hidehighlight) drawhighlights(item, x, y, w, leftpadding, buffer); if (!hidehighlight) drawhighlights(item, x, y, w, leftpadding, buffer);
// copy current buffer to item->clntext instead of item->text, this way SGR sequences aren't drawn // copy current buffer to item->clntext instead of item->text, this way SGR sequences aren't drawn
@ -264,9 +264,9 @@ int drawitemtext(struct item *item, int x, int y, int w) {
if (!hidepowerline && powerlineitems && selitem) { if (!hidepowerline && powerlineitems && selitem) {
if (itempwlstyle == 2) { if (itempwlstyle == 2) {
drw_circle(drw, r, y, plw, bh, 1, col_menu, bgcol, alpha_menu, bga); draw_circle(draw, r, y, sp.plw, sp.bh, 1, col_menu, bgcol, alpha_menu, bga);
} else { } else {
drw_arrow(drw, r, y, plw, bh, 1, itempwlstyle, col_menu, bgcol, alpha_menu, bga); draw_arrow(draw, r, y, sp.plw, sp.bh, 1, itempwlstyle, col_menu, bgcol, alpha_menu, bga);
} }
} }
@ -276,22 +276,22 @@ int drawitemtext(struct item *item, int x, int y, int w) {
int drawitem(int x, int y, int w) { int drawitem(int x, int y, int w) {
struct item *item; struct item *item;
int numberWidth = 0; int numberw = 0;
int modeWidth = 0; int modew = 0;
int larrowWidth = 0; int larroww = 0;
int rarrowWidth = 0; int rarroww = 0;
int capsWidth = 0; int capsw = 0;
// add width // add width
if (!hidelarrow) larrowWidth = pango_leftarrow ? TEXTWM(leftarrow) : TEXTW(leftarrow); if (!hidelarrow) larroww = pango_leftarrow ? TEXTWM(leftarrow) : TEXTW(leftarrow);
if (!hiderarrow) rarrowWidth = pango_rightarrow ? TEXTWM(rightarrow) : TEXTW(rightarrow); if (!hiderarrow) rarroww = pango_rightarrow ? TEXTWM(rightarrow) : TEXTW(rightarrow);
if (!hidemode) modeWidth = pango_mode ? TEXTWM(modetext) : TEXTW(modetext); if (!hidemode) modew = pango_mode ? TEXTWM(tx.modetext) : TEXTW(tx.modetext);
if (!hiderarrow) rarrowWidth = pango_rightarrow ? TEXTWM(rightarrow) : TEXTW(rightarrow); if (!hiderarrow) rarroww = pango_rightarrow ? TEXTWM(rightarrow) : TEXTW(rightarrow);
if (!hidematchcount) numberWidth = pango_numbers ? TEXTWM(numbers) : TEXTW(numbers); if (!hidematchcount) numberw = pango_numbers ? TEXTWM(tx.numbers) : TEXTW(tx.numbers);
if (!hidecaps) capsWidth = pango_caps ? TEXTWM(capstext) : TEXTW(capstext); if (!hidecaps) capsw = pango_caps ? TEXTWM(tx.capstext) : TEXTW(tx.capstext);
if (!strcmp(capstext, "")) if (!strcmp(tx.capstext, ""))
capsWidth = 0; capsw = 0;
#if USEIMAGE #if USEIMAGE
int ox = 0; // original x position int ox = 0; // original x position
@ -304,7 +304,7 @@ int drawitem(int x, int y, int w) {
// draw image first // draw image first
#if USEIMAGE #if USEIMAGE
if (!hideimage && longestedge != 0) { if (!hideimage && img.longestedge != 0) {
rx = ox; rx = ox;
rx += MAX((imagegaps * 2) + imagewidth + menumarginh, indentitems ? x : 0); rx += MAX((imagegaps * 2) + imagewidth + menumarginh, indentitems ? x : 0);
} else } else
@ -321,13 +321,13 @@ int drawitem(int x, int y, int w) {
for (item = curr; item != next; item = item->right, i++) { for (item = curr; item != next; item = item->right, i++) {
x = drawitemtext( x = drawitemtext(
item, item,
rx + menumarginh + ((i / lines) * ((mw - rx) / columns)) + (powerlineitems ? plw : 0), rx + menumarginh + ((i / lines) * ((sp.mw - rx) / columns)) + (powerlineitems ? sp.plw : 0),
y + (((i % lines) + 1) * bh), y + (((i % lines) + 1) * sp.bh),
(mw - rx) / columns - (powerlineitems ? 2 * plw : 0) - (2 * menumarginh) (sp.mw - rx) / columns - (powerlineitems ? 2 * sp.plw : 0) - (2 * menumarginh)
); );
if (item == sel && itemoverride) { if (item == sel && itemoverride) {
itemnumber = i; sp.itemnumber = i;
itemoverride = 0; itemoverride = 0;
} }
@ -336,30 +336,30 @@ int drawitem(int x, int y, int w) {
// horizontal list // horizontal list
} else if (matches) { } else if (matches) {
x += inputw; x += sp.inputw;
if (!hidelarrow) { if (!hidelarrow) {
w = larrowWidth; w = larroww;
x = drawlarrow(x, y, w); x = drawlarrow(x, y, w);
} }
itemnumber = 0; sp.itemnumber = 0;
int itemoverride = 1; int itemoverride = 1;
for (item = curr; item != next; item = item->right) { // draw items for (item = curr; item != next; item = item->right) { // draw items
x = drawitemtext(item, x + (powerlineitems ? plw : 0), y, MIN(pango_item ? TEXTWM(item->text) : TEXTW(item->text), x = drawitemtext(item, x + (powerlineitems ? sp.plw : 0), y, MIN(pango_item ? TEXTWM(item->text) : TEXTW(item->text),
mw - x - sp.mw - x -
rarrowWidth - rarroww -
numberWidth - numberw -
modeWidth - modew -
capsWidth - capsw -
menumarginh - menumarginh -
2 * sp - 2 * sp.sp -
2 * borderwidth 2 * borderwidth
)); ));
if (itemoverride) { if (itemoverride) {
itemnumber++; sp.itemnumber++;
} }
if (item == sel) { if (item == sel) {
@ -368,8 +368,8 @@ int drawitem(int x, int y, int w) {
} }
if (!hiderarrow) { if (!hiderarrow) {
w = rarrowWidth + numberWidth + modeWidth + capsWidth + menumarginh + 2 * sp + 2 * borderwidth; w = rarroww + numberw + modew + capsw + menumarginh + 2 * sp.sp + 2 * borderwidth;
x = drawrarrow(mw - w, y, w); x = drawrarrow(sp.mw - w, y, w);
} }
} }
@ -378,16 +378,16 @@ int drawitem(int x, int y, int w) {
int drawprompt(int x, int y, int w) { int drawprompt(int x, int y, int w) {
if (prompt && *prompt && !hideprompt) { if (prompt && *prompt && !hideprompt) {
x = drw_text(drw, x, y, w, bh, lrpad / 2, prompt, 0, pango_prompt ? True : False, col_promptfg, col_promptbg, alpha_promptfg, alpha_promptbg); x = draw_text(draw, x, y, w, sp.bh, sp.lrpad / 2, prompt, 0, pango_prompt ? True : False, col_promptfg, col_promptbg, alpha_promptfg, alpha_promptbg);
if (!hidepowerline && powerlineprompt) { if (!hidepowerline && powerlineprompt) {
if (promptpwlstyle == 2) { if (promptpwlstyle == 2) {
drw_circle(drw, x, y, plw, bh, 1, col_menu, col_promptbg, alpha_menu, alpha_promptbg); draw_circle(draw, x, y, sp.plw, sp.bh, 1, col_menu, col_promptbg, alpha_menu, alpha_promptbg);
} else { } else {
drw_arrow(drw, x, y, plw, bh, 1, promptpwlstyle, col_menu, col_promptbg, alpha_menu, alpha_promptbg); draw_arrow(draw, x, y, sp.plw, sp.bh, 1, promptpwlstyle, col_menu, col_promptbg, alpha_menu, alpha_promptbg);
} }
x += plw; x += sp.plw;
} }
} }
@ -401,34 +401,34 @@ int drawinput(int x, int y, int w) {
int fw = MAX(2, caretwidth); int fw = MAX(2, caretwidth);
int fp = caretpadding; int fp = caretpadding;
if (fh > bh) { if (fh > sp.bh) {
fh = bh; fh = sp.bh;
} else if (!fh) { } else if (!fh) {
fh = drw->font->h; fh = draw->font->h;
} }
if (passwd) { if (passwd) {
censort = ecalloc(1, sizeof(text)); censort = ecalloc(1, sizeof(tx.text));
for (int i = 0; i < strlen(text); i++) for (int i = 0; i < strlen(tx.text); i++)
memcpy(&censort[i], password, strlen(text)); memcpy(&censort[i], password, strlen(tx.text));
apply_fribidi(censort); apply_fribidi(censort);
drw_text(drw, x, y, w, bh, lrpad / 2, isrtl ? fribidi_text : censort, 0, pango_password ? True : False, col_inputfg, col_inputbg, alpha_inputfg, alpha_inputbg); draw_text(draw, x, y, w, sp.bh, sp.lrpad / 2, isrtl ? fribidi_text : censort, 0, pango_password ? True : False, col_inputfg, col_inputbg, alpha_inputfg, alpha_inputbg);
curpos = TEXTW(censort) - TEXTW(&text[cursor]); curpos = TEXTW(censort) - TEXTW(&tx.text[sp.cursor]);
free(censort); free(censort);
} else if (!passwd) { } else if (!passwd) {
apply_fribidi(text); apply_fribidi(tx.text);
drw_text(drw, x, y, w, bh, lrpad / 2, isrtl ? fribidi_text : text, 0, pango_input ? True : False, col_inputfg, col_inputbg, alpha_inputfg, alpha_inputbg); draw_text(draw, x, y, w, sp.bh, sp.lrpad / 2, isrtl ? fribidi_text : tx.text, 0, pango_input ? True : False, col_inputfg, col_inputbg, alpha_inputfg, alpha_inputbg);
curpos = TEXTW(text) - TEXTW(&text[cursor]); curpos = TEXTW(tx.text) - TEXTW(&tx.text[sp.cursor]);
} }
if ((curpos += lrpad / 2 - 1) < w && !hidecaret && cursorstate) { if ((curpos += sp.lrpad / 2 - 1) < w && !hidecaret) {
curpos += fp; curpos += fp;
drw_rect(drw, x + curpos, 2 + (bh - fh) / 2 + y, fw, fh - 4, 1, 0, col_caretfg, col_caretbg, alpha_caretfg, alpha_caretbg); draw_rect(draw, x + curpos, 2 + (sp.bh - fh) / 2 + y, fw, fh - 4, 1, 0, col_caretfg, col_caretbg, alpha_caretfg, alpha_caretbg);
} }
return x; return x;
@ -438,7 +438,7 @@ int drawlarrow(int x, int y, int w) {
if (hidelarrow) return x; if (hidelarrow) return x;
if (curr->left) { // draw left arrow if (curr->left) { // draw left arrow
drw_text(drw, x, y, w, bh, lrpad / 2, leftarrow, 0, pango_leftarrow ? True : False, col_larrowfg, col_larrowbg, alpha_larrowfg, alpha_larrowbg); draw_text(draw, x, y, w, sp.bh, sp.lrpad / 2, leftarrow, 0, pango_leftarrow ? True : False, col_larrowfg, col_larrowbg, alpha_larrowfg, alpha_larrowbg);
x += w; x += w;
} }
@ -449,7 +449,7 @@ int drawrarrow(int x, int y, int w) {
if (hiderarrow) return x; if (hiderarrow) return x;
if (next) { // draw right arrow if (next) { // draw right arrow
drw_text(drw, mw - w, y, w, bh, lrpad / 2, rightarrow, 0, pango_rightarrow ? True : False, col_rarrowfg, col_rarrowbg, alpha_rarrowfg, alpha_rarrowbg); draw_text(draw, sp.mw - w, y, w, sp.bh, sp.lrpad / 2, rightarrow, 0, pango_rightarrow ? True : False, col_rarrowfg, col_rarrowbg, alpha_rarrowfg, alpha_rarrowbg);
x += w; x += w;
} }
@ -462,20 +462,20 @@ int drawnumber(int x, int y, int w) {
int powerlinewidth = 0; int powerlinewidth = 0;
if (!hidepowerline && powerlinecount) { if (!hidepowerline && powerlinecount) {
powerlinewidth = plw / 2; powerlinewidth = sp.plw / 2;
} }
drw_text(drw, x, y, w, bh, lrpad / 2 + powerlinewidth, numbers, 0, pango_numbers ? True : False, col_numfg, col_numbg, alpha_numfg, alpha_numbg); draw_text(draw, x, y, w, sp.bh, sp.lrpad / 2 + powerlinewidth, tx.numbers, 0, pango_numbers ? True : False, col_numfg, col_numbg, alpha_numfg, alpha_numbg);
// draw powerline for match count // draw powerline for match count
if (!hidepowerline && powerlinecount) { if (!hidepowerline && powerlinecount) {
if (matchcountpwlstyle == 2) { if (matchcountpwlstyle == 2) {
drw_circle(drw, x, y, plw, bh, 0, col_menu, col_numbg, alpha_menu, alpha_numbg); draw_circle(draw, x, y, sp.plw, sp.bh, 0, col_menu, col_numbg, alpha_menu, alpha_numbg);
} else { } else {
drw_arrow(drw, x, y, plw, bh, 0, matchcountpwlstyle, col_menu, col_numbg, alpha_menu, alpha_numbg); draw_arrow(draw, x, y, sp.plw, sp.bh, 0, matchcountpwlstyle, col_menu, col_numbg, alpha_menu, alpha_numbg);
} }
x += plw; x += sp.plw;
} }
return x; return x;
@ -486,24 +486,24 @@ int drawmode(int x, int y, int w) {
int powerlinewidth = 0; int powerlinewidth = 0;
if (!hidepowerline && powerlinemode) { if (!hidepowerline && powerlinemode) {
powerlinewidth = plw / 2; powerlinewidth = sp.plw / 2;
} }
drw_text(drw, x, y, w, bh, lrpad / 2 + powerlinewidth, modetext, 0, pango_mode ? True : False, col_modefg, col_modebg, alpha_modefg, alpha_modebg); draw_text(draw, x, y, w, sp.bh, sp.lrpad / 2 + powerlinewidth, tx.modetext, 0, pango_mode ? True : False, col_modefg, col_modebg, alpha_modefg, alpha_modebg);
// draw powerline for match count // draw powerline for match count
if (!hidepowerline && powerlinemode) { if (!hidepowerline && powerlinemode) {
if (modepwlstyle == 2) { if (modepwlstyle == 2) {
drw_circle(drw, x, y, plw, bh, 0, draw_circle(draw, x, y, sp.plw, sp.bh, 0,
hidematchcount ? col_menu : col_numbg, col_modebg, hidematchcount ? col_menu : col_numbg, col_modebg,
hidematchcount ? alpha_menu : alpha_numbg, alpha_modebg); hidematchcount ? alpha_menu : alpha_numbg, alpha_modebg);
} else { } else {
drw_arrow(drw, x, y, plw, bh, 0, modepwlstyle, draw_arrow(draw, x, y, sp.plw, sp.bh, 0, modepwlstyle,
hidematchcount ? col_menu : col_numbg, col_modebg, hidematchcount ? col_menu : col_numbg, col_modebg,
hidematchcount ? alpha_menu : alpha_numbg, alpha_modebg); hidematchcount ? alpha_menu : alpha_numbg, alpha_modebg);
} }
x += plw; x += sp.plw;
} }
} }
@ -517,24 +517,24 @@ int drawcaps(int x, int y, int w) {
int powerlinewidth = 0; int powerlinewidth = 0;
if (!hidepowerline && powerlinecaps) { if (!hidepowerline && powerlinecaps) {
powerlinewidth = plw / 2; powerlinewidth = sp.plw / 2;
} }
drw_text(drw, x, y, w, bh, lrpad / 2 + powerlinewidth, capstext, 0, pango_caps ? True : False, col_capsfg, col_capsbg, alpha_capsfg, alpha_capsbg); draw_text(draw, x, y, w, sp.bh, sp.lrpad / 2 + powerlinewidth, tx.capstext, 0, pango_caps ? True : False, col_capsfg, col_capsbg, alpha_capsfg, alpha_capsbg);
// draw powerline for caps lock indicator // draw powerline for caps lock indicator
if (!hidepowerline && powerlinecaps) { if (!hidepowerline && powerlinecaps) {
if (capspwlstyle == 2) { if (capspwlstyle == 2) {
drw_circle(drw, x, y, plw, bh, 0, draw_circle(draw, x, y, sp.plw, sp.bh, 0,
hidemode ? hidematchcount ? col_menu : col_numbg : col_modebg, col_capsbg, hidemode ? hidematchcount ? col_menu : col_numbg : col_modebg, col_capsbg,
hidemode ? hidematchcount ? alpha_menu : alpha_numbg : alpha_modebg, alpha_capsbg); hidemode ? hidematchcount ? alpha_menu : alpha_numbg : alpha_modebg, alpha_capsbg);
} else { } else {
drw_arrow(drw, x, y, plw, bh, 0, capspwlstyle, draw_arrow(draw, x, y, sp.plw, sp.bh, 0, capspwlstyle,
hidemode ? hidematchcount ? col_menu : col_numbg : col_modebg, col_capsbg, hidemode ? hidematchcount ? col_menu : col_numbg : col_modebg, col_capsbg,
hidemode ? hidematchcount ? alpha_menu : alpha_numbg : alpha_modebg, alpha_capsbg); hidemode ? hidematchcount ? alpha_menu : alpha_numbg : alpha_modebg, alpha_capsbg);
} }
x += plw; x += sp.plw;
} }
} }
@ -556,7 +556,7 @@ void drawmenu(void) {
resizeclient(); resizeclient();
match(); match();
for (int i = 0; i < itemnumber; i++) { for (int i = 0; i < sp.itemnumber; i++) {
if (sel && sel->right && (sel = sel->right) == next) { if (sel && sel->right && (sel = sel->right) == next) {
curr = next; curr = next;
} }
@ -580,26 +580,26 @@ void drawmenu(void) {
void drawmenu_layer(void) { void drawmenu_layer(void) {
int x = 0, y = 0, w = 0; int x = 0, y = 0, w = 0;
plw = hidepowerline ? 0 : drw->font->h / 2 + 1; // powerline size sp.plw = hidepowerline ? 0 : draw->font->h / 2 + 1; // powerline size
// draw menu first using menu scheme // draw menu first using menu scheme
drw_rect(drw, 0, 0, mw, mh, 1, 1, col_menu, col_menu, alpha_menu, alpha_menu); draw_rect(draw, 0, 0, sp.mw, sp.mh, 1, 1, col_menu, col_menu, alpha_menu, alpha_menu);
int numberWidth = 0; int numberw = 0;
int modeWidth = 0; int modew = 0;
int capsWidth = 0; int capsw = 0;
// add width // add width
if (!hidemode) modeWidth = pango_mode ? TEXTWM(modetext) : TEXTW(modetext); if (!hidemode) modew = pango_mode ? TEXTWM(tx.modetext) : TEXTW(tx.modetext);
if (!hidecaps) capsWidth = pango_caps ? TEXTWM(capstext) : TEXTW(capstext); if (!hidecaps) capsw = pango_caps ? TEXTWM(tx.capstext) : TEXTW(tx.capstext);
if (!strcmp(capstext, "")) if (!strcmp(tx.capstext, ""))
capsWidth = 0; capsw = 0;
// calculate match count // calculate match count
if (!hidematchcount) { if (!hidematchcount) {
recalculatenumbers(); recalculatenumbers();
numberWidth = TEXTW(numbers); numberw = TEXTW(tx.numbers);
} }
x += menumarginh; x += menumarginh;
@ -608,45 +608,45 @@ void drawmenu_layer(void) {
calcoffsets(); calcoffsets();
get_mh(); get_mh();
// bh must be removed from menu height resizing later // sp.bh must be removed from menu height resizing later
if ((hideprompt && hideinput && hidemode && hidematchcount && hidecaps) && lines) { if ((hideprompt && hideinput && hidemode && hidematchcount && hidecaps) && lines) {
y -= bh; y -= sp.bh;
} }
if (!hideprompt && !fullscreen) { if (!hideprompt && !fullscreen) {
w = promptw; w = sp.promptw;
x = drawprompt(x, y, w); x = drawprompt(x, y, w);
} }
if (!hideinput && !fullscreen) { if (!hideinput && !fullscreen) {
w = (lines > 0 || !matches) ? mw - x : inputw; w = (lines > 0 || !matches) ? sp.mw - x : sp.inputw;
x = drawinput(x, y, w); x = drawinput(x, y, w);
} }
if (!hidemode && !fullscreen) modeWidth = pango_mode ? TEXTWM(modetext) : TEXTW(modetext); if (!hidemode && !fullscreen) modew = pango_mode ? TEXTWM(tx.modetext) : TEXTW(tx.modetext);
// draw the items, this function also calls drawrarrow() and drawlarrow() // draw the items, this function also calls drawrarrow() and drawlarrow()
if (!hideitem) drawitem(x, y, w); if (!hideitem) drawitem(x, y, w);
if (!hidematchcount && !fullscreen) { if (!hidematchcount && !fullscreen) {
w = numberWidth; w = numberw;
drawnumber(mw - numberWidth - modeWidth - capsWidth - 2 * sp - 2 * borderwidth - menumarginh, y, w); drawnumber(sp.mw - numberw - modew - capsw - 2 * sp.sp - 2 * borderwidth - menumarginh, y, w);
} }
if (!hidemode && !fullscreen) { if (!hidemode && !fullscreen) {
w = modeWidth; w = modew;
drawmode(mw - modeWidth - capsWidth - 2 * sp - 2 * borderwidth - menumarginh, y, w); drawmode(sp.mw - modew - capsw - 2 * sp.sp - 2 * borderwidth - menumarginh, y, w);
} }
if (!hidecaps && !fullscreen) { if (!hidecaps && !fullscreen) {
w = capsWidth; w = capsw;
drawcaps(mw - capsWidth - 2 * sp - 2 * borderwidth - menumarginh, y, w); drawcaps(sp.mw - capsw - 2 * sp.sp - 2 * borderwidth - menumarginh, y, w);
} }
#if USEX #if USEX
#if USEIMAGE #if USEIMAGE
drawimage(); drawimage();
#endif #endif
drw_map(drw, win, 0, 0, mw, mh); draw_map(draw, win, 0, 0, sp.mw, sp.mh);
#endif #endif
} }

View file

@ -39,72 +39,72 @@ void cairo_set_source_hex(cairo_t* cr, const char *col, int alpha) {
} }
#if USEX #if USEX
Drw *drw_create_x11(Display *dpy, int screen, Window root, unsigned int w, unsigned int h, Visual *visual, unsigned int depth, Colormap cmap, int protocol) { Draw_t *draw_create_x11(Display *dpy, int screen, Window root, unsigned int w, unsigned int h, Visual *visual, unsigned int depth, Colormap cmap, int protocol) {
Drw *drw = ecalloc(1, sizeof(Drw)); Draw_t *draw = ecalloc(1, sizeof(Draw_t));
drw->protocol = protocol; draw->protocol = protocol;
drw->dpy = dpy; draw->dpy = dpy;
drw->screen = screen; draw->screen = screen;
drw->root = root; draw->root = root;
drw->w = w; draw->w = w;
drw->h = h; draw->h = h;
drw->visual = visual; draw->visual = visual;
drw->depth = depth; draw->depth = depth;
drw->cmap = cmap; draw->cmap = cmap;
drw->drawable = XCreatePixmap(dpy, root, w, h, depth); draw->drawable = XCreatePixmap(dpy, root, w, h, depth);
drw->gc = XCreateGC(dpy, drw->drawable, 0, NULL); draw->gc = XCreateGC(dpy, draw->drawable, 0, NULL);
XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter); XSetLineAttributes(dpy, draw->gc, 1, LineSolid, CapButt, JoinMiter);
return drw; return draw;
} }
#endif #endif
#if USEWAYLAND #if USEWAYLAND
Drw *drw_create_wl(int protocol) { Draw_t *draw_create_wl(int protocol) {
Drw *drw = ecalloc(1, sizeof(Drw)); Draw_t *draw = ecalloc(1, sizeof(Draw_t));
drw->protocol = protocol; draw->protocol = protocol;
return drw; return draw;
} }
void drw_create_surface_wl(Drw *drw, void *data, int32_t w, int32_t h) { void draw_create_surface_wl(Draw_t *draw, void *data, int32_t w, int32_t h) {
drw->data = data; draw->data = data;
drw->w = w; draw->w = w;
drw->h = h; draw->h = h;
drw->surface = cairo_image_surface_create_for_data(drw->data, CAIRO_FORMAT_ARGB32, drw->w, drw->h, drw->w * 4); draw->surface = cairo_image_surface_create_for_data(draw->data, CAIRO_FORMAT_ARGB32, draw->w, draw->h, draw->w * 4);
drw->d = cairo_create(drw->surface); draw->d = cairo_create(draw->surface);
} }
#endif #endif
void drw_resize(Drw *drw, unsigned int w, unsigned int h) { void draw_resize(Draw_t *draw, unsigned int w, unsigned int h) {
if (!drw) if (!draw)
return; return;
drw->w = w; draw->w = w;
drw->h = h; draw->h = h;
#if USEX #if USEX
if (drw->drawable) if (draw->drawable)
XFreePixmap(drw->dpy, drw->drawable); XFreePixmap(draw->dpy, draw->drawable);
drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, drw->depth); draw->drawable = XCreatePixmap(draw->dpy, draw->root, w, h, draw->depth);
#endif #endif
} }
void drw_free(Drw *drw) { void draw_free(Draw_t *draw) {
#if USEX #if USEX
if (!drw->protocol) { if (!draw->protocol) {
XFreePixmap(drw->dpy, drw->drawable); XFreePixmap(draw->dpy, draw->drawable);
XFreeGC(drw->dpy, drw->gc); XFreeGC(draw->dpy, draw->gc);
} }
#endif #endif
drw_font_free(drw->font); draw_font_free(draw->font);
free(drw); free(draw);
} }
static Fnt *font_create(Drw *drw, const char *fontname) { static Fnt *font_create(Draw_t *draw, const char *fontname) {
Fnt *font; Fnt *font;
PangoFontMap *fontmap; PangoFontMap *fontmap;
PangoContext *context; PangoContext *context;
@ -116,7 +116,7 @@ static Fnt *font_create(Drw *drw, const char *fontname) {
} }
font = ecalloc(1, sizeof(Fnt)); font = ecalloc(1, sizeof(Fnt));
font->dpy = drw->dpy; font->dpy = draw->dpy;
fontmap = pango_cairo_font_map_new(); fontmap = pango_cairo_font_map_new();
context = pango_font_map_create_context(fontmap); context = pango_font_map_create_context(fontmap);
@ -141,25 +141,25 @@ void font_free(Fnt *font) {
free(font); free(font);
} }
Fnt* drw_font_create(Drw* drw, char *font[], size_t fontcount) { Fnt* draw_font_create(Draw_t* draw, char *font[], size_t fontcount) {
if (!drw || !font) if (!draw || !font)
return NULL; return NULL;
Fnt *fnt = NULL; Fnt *fnt = NULL;
fnt = font_create(drw, *font); fnt = font_create(draw, *font);
return (drw->font = fnt); return (draw->font = fnt);
} }
void drw_font_free(Fnt *font) { void draw_font_free(Fnt *font) {
if (font) { if (font) {
font_free(font); font_free(font);
} }
} }
void drw_arrow(Drw *drw, int x, int y, unsigned int w, unsigned int h, int direction, int slash, char *prevcol, char *nextcol, int prevalpha, int nextalpha) { void draw_arrow(Draw_t *draw, int x, int y, unsigned int w, unsigned int h, int direction, int slash, char *prevcol, char *nextcol, int prevalpha, int nextalpha) {
if (!drw) if (!draw)
return; return;
x = direction ? x : x + w; x = direction ? x : x + w;
@ -169,10 +169,10 @@ void drw_arrow(Drw *drw, int x, int y, unsigned int w, unsigned int h, int direc
cairo_surface_t *sf = NULL; cairo_surface_t *sf = NULL;
if (drw->protocol) { if (draw->protocol) {
sf = cairo_image_surface_create_for_data(drw->data, CAIRO_FORMAT_ARGB32, drw->w, drw->h, drw->w * 4); sf = cairo_image_surface_create_for_data(draw->data, CAIRO_FORMAT_ARGB32, draw->w, draw->h, draw->w * 4);
} else { } else {
sf = cairo_xlib_surface_create(drw->dpy, drw->drawable, drw->visual, drw->w, drw->h); sf = cairo_xlib_surface_create(draw->dpy, draw->drawable, draw->visual, draw->w, draw->h);
} }
cairo_t *cr = cairo_create(sf); cairo_t *cr = cairo_create(sf);
@ -194,16 +194,16 @@ void drw_arrow(Drw *drw, int x, int y, unsigned int w, unsigned int h, int direc
cairo_surface_destroy(sf); cairo_surface_destroy(sf);
} }
void drw_circle(Drw *drw, int x, int y, unsigned int w, unsigned int h, int direction, char *prevcol, char *nextcol, int prevalpha, int nextalpha) { void draw_circle(Draw_t *draw, int x, int y, unsigned int w, unsigned int h, int direction, char *prevcol, char *nextcol, int prevalpha, int nextalpha) {
if (!drw) if (!draw)
return; return;
cairo_surface_t *sf = NULL; cairo_surface_t *sf = NULL;
if (drw->protocol) { if (draw->protocol) {
sf = cairo_image_surface_create_for_data(drw->data, CAIRO_FORMAT_ARGB32, drw->w, drw->h, drw->w * 4); sf = cairo_image_surface_create_for_data(draw->data, CAIRO_FORMAT_ARGB32, draw->w, draw->h, draw->w * 4);
} else { } else {
sf = cairo_xlib_surface_create(drw->dpy, drw->drawable, drw->visual, drw->w, drw->h); sf = cairo_xlib_surface_create(draw->dpy, draw->drawable, draw->visual, draw->w, draw->h);
} }
cairo_t *cr = cairo_create(sf); cairo_t *cr = cairo_create(sf);
@ -233,17 +233,17 @@ void drw_circle(Drw *drw, int x, int y, unsigned int w, unsigned int h, int dire
cairo_surface_destroy(sf); cairo_surface_destroy(sf);
} }
void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert, char *fgcol, char *bgcol, int fgalpha, int bgalpha) { void draw_rect(Draw_t *draw, int x, int y, unsigned int w, unsigned int h, int filled, int invert, char *fgcol, char *bgcol, int fgalpha, int bgalpha) {
if (!drw) { if (!draw) {
return; return;
} }
cairo_surface_t *sf; cairo_surface_t *sf;
if (drw->protocol) { if (draw->protocol) {
sf = cairo_image_surface_create_for_data(drw->data, CAIRO_FORMAT_ARGB32, drw->w, drw->h, drw->w * 4); sf = cairo_image_surface_create_for_data(draw->data, CAIRO_FORMAT_ARGB32, draw->w, draw->h, draw->w * 4);
} else { } else {
sf = cairo_xlib_surface_create(drw->dpy, drw->drawable, drw->visual, drw->w, drw->h); sf = cairo_xlib_surface_create(draw->dpy, draw->drawable, draw->visual, draw->w, draw->h);
} }
cairo_t *cr = cairo_create(sf); cairo_t *cr = cairo_create(sf);
@ -266,7 +266,7 @@ void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled
cairo_surface_destroy(sf); cairo_surface_destroy(sf);
} }
int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert, Bool markup, char *fgcol, char *bgcol, int fgalpha, int bgalpha) { int draw_text(Draw_t *draw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert, Bool markup, char *fgcol, char *bgcol, int fgalpha, int bgalpha) {
char buf[1024]; char buf[1024];
unsigned int ew = 0; unsigned int ew = 0;
@ -274,7 +274,7 @@ int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned in
int render = x || y || w || h; int render = x || y || w || h;
char *t; char *t;
if (!drw || !text || !drw->font) { if (!draw || !text || !draw->font) {
return 0; return 0;
} }
@ -284,28 +284,28 @@ int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned in
x += lpad; x += lpad;
w -= lpad; w -= lpad;
if (drw->protocol) { if (draw->protocol) {
drw->surface = cairo_image_surface_create_for_data(drw->data, CAIRO_FORMAT_ARGB32, drw->w, drw->h, drw->w * 4); draw->surface = cairo_image_surface_create_for_data(draw->data, CAIRO_FORMAT_ARGB32, draw->w, draw->h, draw->w * 4);
} else { } else {
drw->surface = cairo_xlib_surface_create(drw->dpy, drw->drawable, drw->visual, drw->w, drw->h); draw->surface = cairo_xlib_surface_create(draw->dpy, draw->drawable, draw->visual, draw->w, draw->h);
} }
drw->d = cairo_create(drw->surface); draw->d = cairo_create(draw->surface);
// draw bg // draw bg
cairo_set_source_hex(drw->d, invert ? fgcol : bgcol, invert ? fgalpha : bgalpha); cairo_set_source_hex(draw->d, invert ? fgcol : bgcol, invert ? fgalpha : bgalpha);
cairo_set_operator(drw->d, CAIRO_OPERATOR_SOURCE); cairo_set_operator(draw->d, CAIRO_OPERATOR_SOURCE);
cairo_rectangle(drw->d, x - lpad, y, w + lpad, h); cairo_rectangle(draw->d, x - lpad, y, w + lpad, h);
cairo_fill(drw->d); cairo_fill(draw->d);
} }
t = strdup(text); t = strdup(text);
len = strlen(t); len = strlen(t);
if (len) { if (len) {
drw_font_getexts(drw->font, t, len, &ew, NULL, markup); draw_font_getexts(draw->font, t, len, &ew, NULL, markup);
// shorten text if necessary // shorten text if necessary
for (len = MIN(len, sizeof(buf) - 1); len && ew > w; drw_font_getexts(drw->font, t, len, &ew, NULL, markup)) for (len = MIN(len, sizeof(buf) - 1); len && ew > w; draw_font_getexts(draw->font, t, len, &ew, NULL, markup))
len--; len--;
if (len) { if (len) {
@ -320,25 +320,25 @@ int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned in
if (render) { if (render) {
if (markup) { if (markup) {
pango_layout_set_markup(drw->font->layout, buf, len); pango_layout_set_markup(draw->font->layout, buf, len);
} else { } else {
pango_layout_set_text(drw->font->layout, buf, len); pango_layout_set_text(draw->font->layout, buf, len);
} }
pango_layout_set_single_paragraph_mode(drw->font->layout, True); pango_layout_set_single_paragraph_mode(draw->font->layout, True);
// draw fg // draw fg
cairo_set_source_hex(drw->d, fgcol, fgalpha); cairo_set_source_hex(draw->d, fgcol, fgalpha);
cairo_move_to(drw->d, x, y + (h - drw->font->h) / 2); cairo_move_to(draw->d, x, y + (h - draw->font->h) / 2);
// update and show layout // update and show layout
pango_cairo_update_layout(drw->d, drw->font->layout); pango_cairo_update_layout(draw->d, draw->font->layout);
pango_cairo_show_layout(drw->d, drw->font->layout); pango_cairo_show_layout(draw->d, draw->font->layout);
cairo_set_operator(drw->d, CAIRO_OPERATOR_SOURCE); cairo_set_operator(draw->d, CAIRO_OPERATOR_SOURCE);
if (markup) // clear markup attributes if (markup) // clear markup attributes
pango_layout_set_attributes(drw->font->layout, NULL); pango_layout_set_attributes(draw->font->layout, NULL);
} }
x += ew; x += ew;
@ -349,25 +349,25 @@ int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned in
return x + (render ? w : 0); return x + (render ? w : 0);
} }
void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h) { void draw_map(Draw_t *draw, Window win, int x, int y, unsigned int w, unsigned int h) {
if (!drw) if (!draw)
return; return;
#if USEX #if USEX
if (!drw->protocol) { if (!draw->protocol) {
XCopyArea(drw->dpy, drw->drawable, win, drw->gc, x, y, w, h, x, y); XCopyArea(draw->dpy, draw->drawable, win, draw->gc, x, y, w, h, x, y);
XSync(drw->dpy, False); XSync(draw->dpy, False);
} }
#endif #endif
} }
unsigned int drw_font_getwidth(Drw *drw, const char *text, Bool markup) { unsigned int draw_font_getwidth(Draw_t *draw, const char *text, Bool markup) {
if (!drw || !drw->font || !text) if (!draw || !draw->font || !text)
return 0; return 0;
return drw_text(drw, 0, 0, 0, 0, 0, text, 0, markup, "#000000", "#000000", 255, 255); return draw_text(draw, 0, 0, 0, 0, 0, text, 0, markup, "#000000", "#000000", 255, 255);
} }
void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h, Bool markup) { void draw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h, Bool markup) {
if (!font || !text) if (!font || !text)
return; return;
@ -395,31 +395,31 @@ void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned in
*h = font->h; *h = font->h;
} }
void drw_set_img(Drw *drw, void *data, int w, int h) { void draw_set_img(Draw_t *draw, void *data, int w, int h) {
if (!w || !h || !drw) { if (!w || !h || !draw) {
return; return;
} }
drw->img_data = data; draw->img_data = data;
drw->img_surface = cairo_image_surface_create_for_data(drw->img_data, CAIRO_FORMAT_ARGB32, w, h, w * 4); draw->img_surface = cairo_image_surface_create_for_data(draw->img_data, CAIRO_FORMAT_ARGB32, w, h, w * 4);
} }
void drw_img(Drw *drw, int x, int y) { void draw_img(Draw_t *draw, int x, int y) {
if (!drw) { if (!draw) {
return; return;
} }
cairo_set_operator(drw->d, CAIRO_OPERATOR_OVER); cairo_set_operator(draw->d, CAIRO_OPERATOR_OVER);
cairo_set_source_surface(drw->d, drw->img_surface, x, y); cairo_set_source_surface(draw->d, draw->img_surface, x, y);
cairo_mask_surface(drw->d, drw->img_surface, x, y); cairo_mask_surface(draw->d, draw->img_surface, x, y);
cairo_set_source_surface(drw->d, drw->surface, drw->w, drw->h); cairo_set_source_surface(draw->d, draw->surface, draw->w, draw->h);
} }
unsigned int drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n, Bool markup) { unsigned int draw_fontset_getwidth_clamp(Draw_t *draw, const char *text, unsigned int n, Bool markup) {
unsigned int tmp = 0; unsigned int tmp = 0;
if (drw && drw->font && text && n) if (draw && draw->font && text && n)
tmp = drw_text(drw, 0, 0, 0, 0, 0, text, n, markup, "#000000", "#000000", 255, 255); tmp = draw_text(draw, 0, 0, 0, 0, 0, text, n, markup, "#000000", "#000000", 255, 255);
return MIN(n, tmp); return MIN(n, tmp);
} }

View file

@ -30,37 +30,37 @@ typedef struct {
cairo_surface_t *img_surface; cairo_surface_t *img_surface;
cairo_t *d; cairo_t *d;
cairo_t *img_d; cairo_t *img_d;
} Drw; } Draw_t;
/* Cairo color convertion */ /* Cairo color convertion */
void cairo_set_source_hex(cairo_t* cr, const char *col, int alpha); void cairo_set_source_hex(cairo_t* cr, const char *col, int alpha);
/* Cairo image drawing */ /* Cairo image drawing */
void drw_img(Drw *drw, int x, int y); void draw_img(Draw_t *draw, int x, int y);
void drw_set_img(Drw *drw, void *data, int w, int h); void draw_set_img(Draw_t *draw, void *data, int w, int h);
/* Drawable abstraction */ /* Drawable abstraction */
Drw *drw_create_x11(Display *dpy, int screen, Window win, unsigned int w, unsigned int h, Visual *visual, unsigned int depth, Colormap cmap, int protocol); Draw_t *draw_create_x11(Display *dpy, int screen, Window win, unsigned int w, unsigned int h, Visual *visual, unsigned int depth, Colormap cmap, int protocol);
Drw *drw_create_wl(int protocol); Draw_t *draw_create_wl(int protocol);
void drw_create_surface_wl(Drw *drw, void *data, int32_t w, int32_t h); void draw_create_surface_wl(Draw_t *draw, void *data, int32_t w, int32_t h);
void drw_resize(Drw *drw, unsigned int w, unsigned int h); void draw_resize(Draw_t *draw, unsigned int w, unsigned int h);
void drw_free(Drw *drw); void draw_free(Draw_t *draw);
/* Fnt abstraction */ /* Fnt abstraction */
Fnt *drw_font_create(Drw* drw, char *font[], size_t fontcount); Fnt *draw_font_create(Draw_t* draw, char *font[], size_t fontcount);
void drw_font_free(Fnt* set); void draw_font_free(Fnt* set);
unsigned int drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n, Bool markup); unsigned int draw_fontset_getwidth_clamp(Draw_t *draw, const char *text, unsigned int n, Bool markup);
unsigned int drw_font_getwidth(Drw *drw, const char *text, Bool markup); unsigned int draw_font_getwidth(Draw_t *draw, const char *text, Bool markup);
void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h, Bool markup); void draw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h, Bool markup);
/* Drawing functions */ /* Drawing functions */
void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert, char *fgcol, char *bgcol, int fgalpha, int bgalpha); void draw_rect(Draw_t *draw, int x, int y, unsigned int w, unsigned int h, int filled, int invert, char *fgcol, char *bgcol, int fgalpha, int bgalpha);
int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert, Bool markup, char *fgcol, char *bgcol, int fgalpha, int bgalpha); int draw_text(Draw_t *draw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert, Bool markup, char *fgcol, char *bgcol, int fgalpha, int bgalpha);
/* Map functions */ /* Map functions */
void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h); void draw_map(Draw_t *draw, Window win, int x, int y, unsigned int w, unsigned int h);
/* Powerline functions */ /* Powerline functions */
void drw_arrow(Drw *drw, int x, int y, unsigned int w, unsigned int h, int direction, int slash, char *prevcol, char *nextcol, int prevalpha, int nextalpha); void draw_arrow(Draw_t *draw, int x, int y, unsigned int w, unsigned int h, int direction, int slash, char *prevcol, char *nextcol, int prevalpha, int nextalpha);
void drw_circle(Drw *drw, int x, int y, unsigned int w, unsigned int h, int direction, char *prevcol, char *nextcol, int prevalpha, int nextalpha); void draw_circle(Draw_t *draw, int x, int y, unsigned int w, unsigned int h, int direction, char *prevcol, char *nextcol, int prevalpha, int nextalpha);

View file

@ -59,7 +59,7 @@ void navigatehistfile(int dir) {
return; return;
if (histsz == histpos) { if (histsz == histpos) {
strncpy(def, text, sizeof(def)); strncpy(def, tx.text, sizeof(def));
} }
switch (dir) { switch (dir) {
@ -83,8 +83,8 @@ void navigatehistfile(int dir) {
} }
len = MIN(strlen(p), BUFSIZ - 1); len = MIN(strlen(p), BUFSIZ - 1);
sp_strncpy(text, p, sizeof(text)); sp_strncpy(tx.text, p, sizeof(tx.text));
text[len] = '\0'; tx.text[len] = '\0';
cursor = len; sp.cursor = len;
match(); match();
} }

View file

@ -2,7 +2,7 @@
#if USEIMAGE #if USEIMAGE
void setimagesize(int width, int height) { void setimagesize(int width, int height) {
if (!image || fullscreen || hideimage || height < 5 || width < 5 || width > mw) { if (!image || fullscreen || hideimage || height < 5 || width < 5 || width > sp.mw) {
return; return;
} }
@ -11,8 +11,7 @@ void setimagesize(int width, int height) {
} }
void flipimage(void) { void flipimage(void) {
// flip image switch (img.flip) {
switch (flip) {
case 1: // horizontal case 1: // horizontal
imlib_image_flip_horizontal(); imlib_image_flip_horizontal();
break; break;
@ -23,7 +22,7 @@ void flipimage(void) {
imlib_image_flip_diagonal(); imlib_image_flip_diagonal();
break; break;
default: default:
flip = flip ? 1 : 0; img.flip = img.flip ? 1 : 0;
return; return;
} }
} }
@ -41,19 +40,13 @@ void drawimage(void) {
if (!lines || !columns || hideimage) return; if (!lines || !columns || hideimage) return;
// to prevent the image from being drawn multiple times wasting resources
if (!needredraw) {
needredraw = 1;
return;
}
// load image cache // load image cache
if (sel && sel->image && strcmp(sel->image, limg ? limg : "")) { if (sel && sel->image && strcmp(sel->image, limg ? limg : "")) {
if (longestedge) if (img.longestedge)
loadimagecache(sel->image, &width, &height); loadimagecache(sel->image, &width, &height);
} else if ((!sel || !sel->image) && image) { // free image } else if ((!sel || !sel->image) && image) { // free image
cleanupimage(); cleanupimage();
} if (image && longestedge && width && height) { // render the image } if (image && img.longestedge && width && height) { // render the image
flipimage(); flipimage();
int leftmargin = imagegaps; // gaps between image and menu int leftmargin = imagegaps; // gaps between image and menu
@ -62,24 +55,24 @@ void drawimage(void) {
int xta = 0; // add to x int xta = 0; // add to x
if (hideprompt && hideinput && hidemode && hidematchcount && hidecaps) { if (hideprompt && hideinput && hidemode && hidematchcount && hidecaps) {
wtr = bh; wtr = sp.bh;
} else { } else {
wta = bh; wta = sp.bh;
} }
// margin // margin
xta += menumarginh; xta += menumarginh;
wta += menumarginv; wta += menumarginv;
if (mh != bh + height + leftmargin * 2 - wtr && imageresize) { // menu height cannot be smaller than image height if (sp.mh != sp.bh + height + leftmargin * 2 - wtr && imageresize) { // menu height cannot be smaller than image height
resizetoimageheight(width, imlib_image_get_height() - (fullscreen ? 2 * menumarginv : 0)); resizetoimageheight(width, imlib_image_get_height() - (fullscreen ? 2 * menumarginv : 0));
} }
drw_set_img(drw, imlib_image_get_data(), width, height); draw_set_img(draw, imlib_image_get_data(), width, height);
if (fullscreen) { if (fullscreen) {
xta = wta = leftmargin = 0; xta = wta = leftmargin = 0;
drw_img(drw, (imagewidth - width) / 2, 0); draw_img(draw, (imagewidth - width) / 2, 0);
if (sel) { if (sel) {
limg = sel->image; limg = sel->image;
@ -95,17 +88,17 @@ void drawimage(void) {
if (height > width) if (height > width)
width = height; width = height;
drw_img(drw, leftmargin + (imagewidth - width) / 2 + xta, wta + leftmargin); draw_img(draw, leftmargin + (imagewidth - width) / 2 + xta, wta + leftmargin);
} else if (imageposition == 1 && image) { // bottom mode = 1 } else if (imageposition == 1 && image) { // bottom mode = 1
if (height > width) if (height > width)
width = height; width = height;
drw_img(drw, leftmargin + (imagewidth - width) / 2 + xta, mh - height - leftmargin); draw_img(draw, leftmargin + (imagewidth - width) / 2 + xta, sp.mh - height - leftmargin);
} else if (imageposition == 2 && image) { // center mode = 2 } else if (imageposition == 2 && image) { // center mode = 2
drw_img(drw, leftmargin + (imagewidth - width) / 2 + xta, (mh - wta - height) / 2 + wta); draw_img(draw, leftmargin + (imagewidth - width) / 2 + xta, (sp.mh - wta - height) / 2 + wta);
} else if (image) { // top center } else if (image) { // top center
int minh = MIN(height, mh - bh - leftmargin * 2); int minh = MIN(height, sp.mh - sp.bh - leftmargin * 2);
drw_img(drw, leftmargin + (imagewidth - width) / 2 + xta, (minh - height) / 2 + wta + leftmargin); draw_img(draw, leftmargin + (imagewidth - width) / 2 + xta, (minh - height) / 2 + wta + leftmargin);
} }
} }
@ -207,7 +200,7 @@ void loadimagecache(const char *file, int *width, int *height) {
struct passwd *pw = NULL; struct passwd *pw = NULL;
// just load and don't store or try cache // just load and don't store or try cache
if (longestedge > maxcache) { if (img.longestedge > maxcache) {
loadimage(file, width, height); loadimage(file, width, height);
if (image) if (image)
scaleimage(width, height); scaleimage(width, height);
@ -227,7 +220,7 @@ void loadimagecache(const char *file, int *width, int *height) {
// which cache do we try? // which cache do we try?
dsize = "normal"; dsize = "normal";
if (longestedge > 128) if (img.longestedge > 128)
dsize = "large"; dsize = "large";
slen = snprintf(NULL, 0, "file://%s", file)+1; slen = snprintf(NULL, 0, "file://%s", file)+1;
@ -341,8 +334,8 @@ void resizetoimageheight(int imagewidth, int imageheight) {
#if USEX #if USEX
void resizetoimageheight_x11(int imageheight) { void resizetoimageheight_x11(int imageheight) {
int omh = mh, olines = lines; int mh = sp.mh, olines = lines;
lines = reallines; lines = img.setlines;
int x, y; int x, y;
#if USEXINERAMA #if USEXINERAMA
@ -354,11 +347,11 @@ void resizetoimageheight_x11(int imageheight) {
#endif #endif
XWindowAttributes wa; XWindowAttributes wa;
if (lines * bh < imageheight + imagegaps * 2) { if (lines * sp.bh < imageheight + imagegaps * 2) {
lines = (imageheight + imagegaps * 2) / bh; lines = (imageheight + imagegaps * 2) / sp.bh;
if (fullscreen) { if (fullscreen) {
lines = imageheight / bh - 1; lines = imageheight / sp.bh - 1;
} }
} }
@ -396,13 +389,13 @@ void resizetoimageheight_x11(int imageheight) {
// calculate x/y position // calculate x/y position
if (menuposition == 2) { // centered if (menuposition == 2) { // centered
mw = MIN(MAX(max_textw() + promptw, minwidth), info[i].width); sp.mw = MIN(MAX(max_textw() + sp.promptw, minwidth), info[i].width);
x = info[i].x_org + ((info[i].width - mw) / 2); x = info[i].x_org + ((info[i].width - sp.mw) / 2);
y = info[i].y_org + ((info[i].height - mh) / 2); y = info[i].y_org + ((info[i].height - sp.mh) / 2);
} else { // top or bottom } else { // top or bottom
x = info[i].x_org + xpos; x = info[i].x_org + xpos;
y = info[i].y_org + (menuposition ? 0 : info[i].height - mh - ypos); y = info[i].y_org + (menuposition ? 0 : info[i].height - sp.mh - ypos);
mw = (menuwidth > 0 ? menuwidth : info[i].width); sp.mw = (menuwidth > 0 ? menuwidth : info[i].width);
} }
XFree(info); XFree(info);
@ -414,24 +407,24 @@ void resizetoimageheight_x11(int imageheight) {
parentwin); // die because unable to get attributes for the parent window parentwin); // die because unable to get attributes for the parent window
if (menuposition == 2) { // centered if (menuposition == 2) { // centered
mw = MIN(MAX(max_textw() + promptw, minwidth), wa.width); sp.mw = MIN(MAX(max_textw() + sp.promptw, minwidth), wa.width);
x = (wa.width - mw) / 2; x = (wa.width - sp.mw) / 2;
y = (wa.height - mh) / 2; y = (wa.height - sp.mh) / 2;
} else { // top or bottom } else { // top or bottom
x = 0; x = 0;
y = menuposition ? 0 : wa.height - mh - ypos; y = menuposition ? 0 : wa.height - sp.mh - ypos;
mw = (menuwidth > 0 ? menuwidth : wa.width); sp.mw = (menuwidth > 0 ? menuwidth : wa.width);
} }
} }
if ( if (
!win || !win ||
omh == mh) { mh == sp.mh) {
return; return;
} }
XMoveResizeWindow(dpy, win, x + sp, y + vp, mw - 2 * sp - borderwidth * 2, mh); XMoveResizeWindow(dpy, win, x + sp.sp, y + sp.vp, sp.mw - 2 * sp.sp - borderwidth * 2, sp.mh);
drw_resize(drw, mw - 2 * sp - borderwidth, mh); draw_resize(draw, sp.mw - 2 * sp.sp - borderwidth, sp.mh);
if (olines != lines) { if (olines != lines) {
struct item *item; struct item *item;
@ -450,20 +443,20 @@ void resizetoimageheight_x11(int imageheight) {
#if USEWAYLAND #if USEWAYLAND
void resizetoimageheight_wl(int imageheight) { void resizetoimageheight_wl(int imageheight) {
int omh = mh, olines = lines; int mh = sp.mh, olines = lines;
lines = reallines; lines = img.setlines;
if (lines * bh < imageheight + imagegaps * 2) { if (lines * sp.bh < imageheight + imagegaps * 2) {
lines = (imageheight + imagegaps * 2) / bh; lines = (imageheight + imagegaps * 2) / sp.bh;
if (fullscreen) { if (fullscreen) {
lines = imageheight / bh - 1; lines = imageheight / sp.bh - 1;
} }
} }
get_mh(); get_mh();
if (omh == mh) { if (mh == sp.mh) {
return; return;
} }
@ -478,13 +471,13 @@ void resizetoimageheight_wl(int imageheight) {
jumptoindex(i); jumptoindex(i);
} }
state.width = mw; state.width = sp.mw;
state.height = mh; state.height = sp.mh;
state.buffer = create_buffer(&state); state.buffer = create_buffer(&state);
if (drw == NULL) { if (draw == NULL) {
die("spmenu: drw == NULL"); die("spmenu: draw == NULL");
} }
if (state.buffer == NULL) { if (state.buffer == NULL) {
@ -492,7 +485,7 @@ void resizetoimageheight_wl(int imageheight) {
} }
set_layer_size(&state, state.width, state.height); set_layer_size(&state, state.width, state.height);
drw_create_surface_wl(drw, state.data, state.width, state.height); draw_create_surface_wl(draw, state.data, state.width, state.height);
drawmenu(); drawmenu();
@ -504,12 +497,12 @@ void resizetoimageheight_wl(int imageheight) {
#endif #endif
void store_image_vars(void) { void store_image_vars(void) {
longestedge = MAX(imagewidth, imageheight); img.longestedge = MAX(imagewidth, imageheight);
if (!imagew || !imageh || !imageg) { if (!img.imagew || !img.imageh || !img.imageg) {
imagew = imagewidth; img.imagew = imagewidth;
imageh = imageheight; img.imageh = imageheight;
imageg = imagegaps; img.imageg = imagegaps;
} }
} }
#endif #endif

View file

@ -7,7 +7,7 @@ void fuzzymatch(void) {
lhpprefix = hpprefixend = NULL; lhpprefix = hpprefixend = NULL;
char c; char c;
int number_of_matches = 0, i, pidx, sidx, eidx; int number_of_matches = 0, i, pidx, sidx, eidx;
int text_len = strlen(text), itext_len; int text_len = strlen(tx.text), itext_len;
matches = matchend = NULL; matches = matchend = NULL;
@ -21,7 +21,7 @@ void fuzzymatch(void) {
// walk through item text // walk through item text
for (i = 0; i < itext_len && (c = it->text[i]); i++) { for (i = 0; i < itext_len && (c = it->text[i]); i++) {
// fuzzy match pattern // fuzzy match pattern
if (!fstrncmp(&text[pidx], &c, 1)) { if (!fstrncmp(&tx.text[pidx], &c, 1)) {
if(sidx == -1) if(sidx == -1)
sidx = i; sidx = i;
pidx++; pidx++;
@ -92,13 +92,13 @@ void match(void) {
static char **tokv = NULL; static char **tokv = NULL;
static int tokn = 0; static int tokn = 0;
char buf[sizeof text], *s; char buf[sizeof tx.text], *s;
int i, tokc = 0; int i, tokc = 0;
size_t len, textsize; size_t len, textsize;
struct item *item, *lhpprefix, *lprefix, *lsubstr, *hpprefixend, *prefixend, *substrend; struct item *item, *lhpprefix, *lprefix, *lsubstr, *hpprefixend, *prefixend, *substrend;
sp_strncpy(buf, text, sizeof(text)); sp_strncpy(buf, tx.text, sizeof(tx.text));
// separate input text into tokens to be matched individually // separate input text into tokens to be matched individually
for (s = strtok(buf, " "); s; tokv[tokc - 1] = s, s = strtok(NULL, " ")) for (s = strtok(buf, " "); s; tokv[tokc - 1] = s, s = strtok(NULL, " "))
if (++tokc > tokn && !(tokv = realloc(tokv, ++tokn * sizeof *tokv))) if (++tokc > tokn && !(tokv = realloc(tokv, ++tokn * sizeof *tokv)))
@ -107,7 +107,7 @@ void match(void) {
len = tokc ? strlen(tokv[0]) : 0; len = tokc ? strlen(tokv[0]) : 0;
matches = lhpprefix = lprefix = lsubstr = matchend = hpprefixend = prefixend = substrend = NULL; matches = lhpprefix = lprefix = lsubstr = matchend = hpprefixend = prefixend = substrend = NULL;
textsize = strlen(text) + 1; textsize = strlen(tx.text) + 1;
for (item = items; item && item->text; item++) { for (item = items; item && item->text; item++) {
for (i = 0; i < tokc; i++) for (i = 0; i < tokc; i++)
if (!fstrstr(item->text, tokv[i])) if (!fstrstr(item->text, tokv[i]))
@ -120,7 +120,7 @@ void match(void) {
// exact matches go first, then prefixes with high priority, then prefixes, then substrings // exact matches go first, then prefixes with high priority, then prefixes, then substrings
if (item->hp && !fstrncmp(tokv[0], item->text, len)) if (item->hp && !fstrncmp(tokv[0], item->text, len))
appenditem(item, &lhpprefix, &hpprefixend); appenditem(item, &lhpprefix, &hpprefixend);
else if (!tokc || !fstrncmp(text, item->text, textsize)) else if (!tokc || !fstrncmp(tx.text, item->text, textsize))
appenditem(item, &matches, &matchend); appenditem(item, &matches, &matchend);
else if (!fstrncmp(tokv[0], item->text, len)) else if (!fstrncmp(tokv[0], item->text, len))
appenditem(item, &lprefix, &prefixend); appenditem(item, &lprefix, &prefixend);

View file

@ -1,8 +1,4 @@
/* spmenu - fancy dynamic menu /* See LICENSE file for copyright and license details. */
*
* Below is a configuration file which is technically C source code.
* See LICENSE file for copyright and license details.
*/
/* spmenu options */ /* spmenu options */
static char *class = "spmenu"; /* Class for spmenu */ static char *class = "spmenu"; /* Class for spmenu */

View file

@ -1,12 +1,12 @@
/* See LICENSE file for copyright and license details. */ /* See LICENSE file for copyright and license details. */
void readstdin(void) { void readstdin(void) {
char buf[sizeof text], *p; char buf[sizeof tx.text], *p;
size_t i, itemsiz = 0; size_t i, itemsiz = 0;
unsigned int tmpmax = 0; unsigned int tmpmax = 0;
if (passwd) { if (passwd) {
inputw = lines = 0; sp.inputw = lines = 0;
return; return;
} }
@ -29,9 +29,9 @@ void readstdin(void) {
if (!(items[i].text = strdup(buf))) if (!(items[i].text = strdup(buf)))
die("spmenu: cannot strdup %u bytes:", strlen(buf) + 1); die("spmenu: cannot strdup %u bytes:", strlen(buf) + 1);
items[i].hp = arrayhas(hpitems, hplength, items[i].text); items[i].hp = arrayhas(hpitems, hplength, items[i].text);
drw_font_getexts(drw->font, buf, strlen(buf), &tmpmax, NULL, True); draw_font_getexts(draw->font, buf, strlen(buf), &tmpmax, NULL, True);
if (tmpmax > inputw) { if (tmpmax > sp.inputw) {
inputw = tmpmax; sp.inputw = tmpmax;
} }
items[i].index = i; items[i].index = i;
@ -48,7 +48,7 @@ void readstdin(void) {
} }
#if USEIMAGE #if USEIMAGE
if (!o) longestedge = imagegaps = 0; if (!o) img.longestedge = imagegaps = 0;
#endif #endif
// clean // clean
@ -64,7 +64,7 @@ void readstdin(void) {
void readfile(void) { void readfile(void) {
if (passwd){ if (passwd){
inputw = lines = 0; sp.inputw = lines = 0;
return; return;
} }
@ -129,7 +129,7 @@ void readfile(void) {
lines = columns == 1 ? i : MIN(i, lines); // i = number of items lines = columns == 1 ? i : MIN(i, lines); // i = number of items
#if USEIMAGE #if USEIMAGE
if (!o) longestedge = imagegaps = 0; if (!o) img.longestedge = imagegaps = 0;
#endif #endif
if (i == listcount) { if (i == listcount) {
@ -174,7 +174,7 @@ int parsemarkup(int index) {
} }
// load image cache (or generate) // load image cache (or generate)
if (generatecache && longestedge <= maxcache && items[index].image && strcmp(items[index].image, limg ? limg : "")) { if (generatecache && img.longestedge <= maxcache && items[index].image && strcmp(items[index].image, limg ? limg : "")) {
loadimagecache(items[index].image, &w, &h); loadimagecache(items[index].image, &w, &h);
} }

View file

@ -1,14 +1,16 @@
/* See LICENSE file for copyright and license details. */ /* See LICENSE file for copyright and license details. */
void prepare_window_size_wl(void) { void prepare_window_size_wl(void) {
sp = menupaddingh; sp.sp = menupaddingh;
vp = (menuposition == 1) ? menupaddingv : - menupaddingv; sp.vp = (menuposition == 1) ? menupaddingv : - menupaddingv;
bh = MAX(drw->font->h, drw->font->h + 2 + lineheight); sp.bh = MAX(draw->font->h, draw->font->h + 2 + lineheight);
lines = MAX(lines, 0); lines = MAX(lines, 0);
reallines = lines; #if USEIMAGE
img.setlines = lines;
#endif
lrpad = drw->font->h + textpadding; sp.lrpad = draw->font->h + textpadding;
return; return;
} }
@ -19,7 +21,7 @@ void handle_wl(void) {
} }
prepare_window_size_wl(); prepare_window_size_wl();
promptw = (prompt && *prompt) ? pango_prompt ? TEXTWM(prompt) : TEXTW(prompt) - lrpad / 4 : 0; sp.promptw = (prompt && *prompt) ? pango_prompt ? TEXTWM(prompt) : TEXTW(prompt) - sp.lrpad / 4 : 0;
allow_draw = 1; allow_draw = 1;
@ -32,15 +34,15 @@ void handle_wl(void) {
create_layer(&state, "spmenu"); create_layer(&state, "spmenu");
mw = (menuwidth > 0 ? menuwidth : output_width); sp.mw = (menuwidth > 0 ? menuwidth : output_width);
get_mh(); get_mh();
if (menuposition == 2) { if (menuposition == 2) {
mw = MIN(MAX(max_textw() + promptw, minwidth), output_width); sp.mw = MIN(MAX(max_textw() + sp.promptw, minwidth), output_width);
} }
state.width = mw; state.width = sp.mw;
state.height = mh; state.height = sp.mh;
set_layer_size(&state, state.width, state.height); set_layer_size(&state, state.width, state.height);

View file

@ -87,13 +87,13 @@ void keypress_wl(struct state *state, enum wl_keyboard_key_state key_state, xkb_
} }
for (i = 0; i < LENGTH(wl_keys); i++) { for (i = 0; i < LENGTH(wl_keys); i++) {
if (ignoreglobalkeys) break; if (sp.ignoreglobalkeys) break;
if (xkb_keysym_to_lower(sym) == wl_keys[i].keysym && !is_correct_modifier(state, wl_keys[i].modifier) && wl_keys[i].func) { if (xkb_keysym_to_lower(sym) == wl_keys[i].keysym && !is_correct_modifier(state, wl_keys[i].modifier) && wl_keys[i].func) {
if ((wl_keys[i].mode && curMode) || wl_keys[i].mode == -1) { if ((wl_keys[i].mode && sp.mode) || wl_keys[i].mode == -1) {
wl_keys[i].func(&(wl_keys[i].arg)); wl_keys[i].func(&(wl_keys[i].arg));
return; return;
} else if (!wl_keys[i].mode && !curMode) { } else if (!wl_keys[i].mode && !sp.mode) {
wl_keys[i].func(&(wl_keys[i].arg)); wl_keys[i].func(&(wl_keys[i].arg));
} else { } else {
continue; continue;
@ -102,13 +102,13 @@ void keypress_wl(struct state *state, enum wl_keyboard_key_state key_state, xkb_
} }
for (i = 0; i < LENGTH(wl_ckeys); i++) { for (i = 0; i < LENGTH(wl_ckeys); i++) {
if (ignoreconfkeys) break; if (sp.ignoreconfkeys) break;
if (xkb_keysym_to_lower(sym) == wl_ckeys[i].keysym && !is_correct_modifier(state, wl_ckeys[i].modifier) && wl_ckeys[i].func) { if (xkb_keysym_to_lower(sym) == wl_ckeys[i].keysym && !is_correct_modifier(state, wl_ckeys[i].modifier) && wl_ckeys[i].func) {
if ((wl_ckeys[i].mode && curMode) || wl_ckeys[i].mode == -1) { if ((wl_ckeys[i].mode && sp.mode) || wl_ckeys[i].mode == -1) {
wl_ckeys[i].func(&(wl_ckeys[i].arg)); wl_ckeys[i].func(&(wl_ckeys[i].arg));
return; return;
} else if (!wl_ckeys[i].mode && !curMode) { } else if (!wl_ckeys[i].mode && !sp.mode) {
wl_ckeys[i].func(&(wl_ckeys[i].arg)); wl_ckeys[i].func(&(wl_ckeys[i].arg));
} else { } else {
continue; continue;
@ -120,15 +120,15 @@ void keypress_wl(struct state *state, enum wl_keyboard_key_state key_state, xkb_
return; return;
} }
if (!type || !curMode) { if (!type || !sp.mode) {
return; return;
} }
if (xkb_keysym_to_utf8(sym, buf, 8)) { if (xkb_keysym_to_utf8(sym, buf, 8)) {
if (allowkeys) { if (sp.allowkeys) {
insert(buf, strnlen(buf, 8)); insert(buf, strnlen(buf, 8));
} else { } else {
allowkeys = !allowkeys; sp.allowkeys = !sp.allowkeys;
} }
drawmenu(); drawmenu();
@ -137,18 +137,18 @@ void keypress_wl(struct state *state, enum wl_keyboard_key_state key_state, xkb_
void keyboard_modifiers(void *data, struct wl_keyboard *keyboard, uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group) { void keyboard_modifiers(void *data, struct wl_keyboard *keyboard, uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group) {
struct state *state = data; struct state *state = data;
int ocapslockstate = capslockstate; int ocapslockstate = sp.capslockstate;
xkb_state_update_mask(state->xkb_state, mods_depressed, mods_latched, mods_locked, 0, 0, group); xkb_state_update_mask(state->xkb_state, mods_depressed, mods_latched, mods_locked, 0, 0, group);
if (xkb_state_mod_name_is_active(state->xkb_state, XKB_MOD_NAME_CAPS, XKB_STATE_MODS_EFFECTIVE)) { if (xkb_state_mod_name_is_active(state->xkb_state, XKB_MOD_NAME_CAPS, XKB_STATE_MODS_EFFECTIVE)) {
capslockstate = 1; sp.capslockstate = 1;
} else { } else {
capslockstate = 0; sp.capslockstate = 0;
} }
if (ocapslockstate != capslockstate) { if (ocapslockstate != sp.capslockstate) {
strncpy(capstext, capslockstate ? capslockontext : capslockofftext, 15); strncpy(tx.capstext, sp.capslockstate ? capslockontext : capslockofftext, 15);
drawmenu(); drawmenu();
} }
} }
@ -170,7 +170,7 @@ void keyboard_key(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial,
enum wl_keyboard_key_state key_state = _key_state; enum wl_keyboard_key_state key_state = _key_state;
strncpy(capstext, capslockstate ? capslockontext : capslockofftext, 15); strncpy(tx.capstext, sp.capslockstate ? capslockontext : capslockofftext, 15);
xkb_keysym_t sym = xkb_state_key_get_one_sym(state->xkb_state, key + 8); xkb_keysym_t sym = xkb_state_key_get_one_sym(state->xkb_state, key + 8);
keypress_wl(state, key_state, sym); keypress_wl(state, key_state, sym);
@ -216,7 +216,7 @@ void buttonpress_wl(uint32_t button, double ex, double ey) {
int x = 0; int x = 0;
int y = 0; int y = 0;
int w; int w;
int h = bh; int h = sp.bh;
int xpad = 0; int xpad = 0;
int item_num = 0; int item_num = 0;
int yp = 0; int yp = 0;
@ -227,25 +227,25 @@ void buttonpress_wl(uint32_t button, double ex, double ey) {
} }
if (!hidepowerline) { if (!hidepowerline) {
x = xpad = plw; x = xpad = sp.plw;
} }
x += menumarginh; x += menumarginh;
int larrowWidth = 0; int larroww = 0;
int rarrowWidth = 0; int rarroww = 0;
int numberWidth = 0; int numberw = 0;
int modeWidth = 0; int modew = 0;
int capsWidth = 0; int capsw = 0;
if (!hidelarrow) larrowWidth = pango_leftarrow ? TEXTWM(leftarrow) : TEXTW(leftarrow); if (!hidelarrow) larroww = pango_leftarrow ? TEXTWM(leftarrow) : TEXTW(leftarrow);
if (!hiderarrow) rarrowWidth = pango_rightarrow ? TEXTWM(rightarrow) : TEXTW(rightarrow); if (!hiderarrow) rarroww = pango_rightarrow ? TEXTWM(rightarrow) : TEXTW(rightarrow);
if (!hidematchcount) numberWidth = pango_numbers ? TEXTWM(numbers) : TEXTW(numbers); if (!hidematchcount) numberw = pango_numbers ? TEXTWM(tx.numbers) : TEXTW(tx.numbers);
if (!hidemode) modeWidth = pango_mode ? TEXTWM(modetext) : TEXTW(modetext); if (!hidemode) modew = pango_mode ? TEXTWM(tx.modetext) : TEXTW(tx.modetext);
if (!hidecaps) capsWidth = pango_caps ? TEXTWM(capstext) : TEXTW(capstext); if (!hidecaps) capsw = pango_caps ? TEXTWM(tx.capstext) : TEXTW(tx.capstext);
if (!strcmp(capstext, "")) if (!strcmp(tx.capstext, ""))
capsWidth = 0; capsw = 0;
if ((hideprompt && hideinput && hidemode && hidematchcount && hidecaps) && lines) { if ((hideprompt && hideinput && hidemode && hidematchcount && hidecaps) && lines) {
yp = 1; yp = 1;
@ -258,19 +258,19 @@ void buttonpress_wl(uint32_t button, double ex, double ey) {
click = ClickWindow; // clicking anywhere, we use this and override it if we clicked on something specific click = ClickWindow; // clicking anywhere, we use this and override it if we clicked on something specific
// check click position and override the value of click // check click position and override the value of click
if (yp && ex < x + promptw + powerlineprompt ? plw : 0) { // prompt if (yp && ex < x + sp.promptw + powerlineprompt ? sp.plw : 0) { // prompt
click = ClickPrompt; click = ClickPrompt;
} else if (yp && (ex > mw - capsWidth - 2 * sp - 2 * borderwidth - menumarginh) && !hidecaps && capsWidth) { // caps lock indicator } else if (yp && (ex > sp.mw - capsw - 2 * sp.sp - 2 * borderwidth - menumarginh) && !hidecaps && capsw) { // caps lock indicator
click = ClickCaps; click = ClickCaps;
} else if (yp && ex > mw - modeWidth - capsWidth - 2 * sp - 2 * borderwidth - menumarginh) { // mode indicator } else if (yp && ex > sp.mw - modew - capsw - 2 * sp.sp - 2 * borderwidth - menumarginh) { // mode indicator
click = ClickMode; click = ClickMode;
} else if (yp && ex > mw - modeWidth - numberWidth - capsWidth - 2 * sp - 2 * borderwidth - menumarginh) { // match count } else if (yp && ex > sp.mw - modew - numberw - capsw - 2 * sp.sp - 2 * borderwidth - menumarginh) { // match count
click = ClickNumber; click = ClickNumber;
} else if (yp && !hideinput) { // input } else if (yp && !hideinput) { // input
w = (lines > 0 || !matches) ? mw - x : inputw; w = (lines > 0 || !matches) ? sp.mw - x : sp.inputw;
if ((lines <= 0 && ex >= 0 && ex <= x + w + promptw + if ((lines <= 0 && ex >= 0 && ex <= x + w + sp.promptw +
((!prev || !curr->left) ? larrowWidth : 0)) || ((!prev || !curr->left) ? larroww : 0)) ||
(lines > 0 && ey >= y && ey <= y + h)) { (lines > 0 && ey >= y && ey <= y + h)) {
click = ClickInput; click = ClickInput;
@ -278,14 +278,14 @@ void buttonpress_wl(uint32_t button, double ex, double ey) {
} }
#if USEIMAGE #if USEIMAGE
if (!hideimage && longestedge != 0) { if (!hideimage && img.longestedge != 0) {
x += MAX((imagegaps * 2) + imagewidth, indentitems ? promptw : 0); x += MAX((imagegaps * 2) + imagewidth, indentitems ? sp.promptw : 0);
} }
#endif #endif
// item click // item click
if (lines > 0) { if (lines > 0) {
w = mw - x; w = sp.mw - x;
ey -= menumarginv; ey -= menumarginv;
@ -303,9 +303,9 @@ void buttonpress_wl(uint32_t button, double ex, double ey) {
y += h; y += h;
// ClickSelItem, called function doesn't matter // ClickSelItem, called function doesn't matter
if (ey >= y && ey <= (y + h) && ex >= x + (powerlineitems ? plw : 0) && ex <= (x + w / columns) + (powerlineitems ? plw : 0)) { if (ey >= y && ey <= (y + h) && ex >= x + (powerlineitems ? sp.plw : 0) && ex <= (x + w / columns) + (powerlineitems ? sp.plw : 0)) {
for (i = 0; i < LENGTH(buttons); i++) { for (i = 0; i < LENGTH(wl_buttons); i++) {
if (ignoreglobalmouse) break; if (sp.ignoreglobalmouse) break;
if (wl_buttons[i].click == ClickSelItem && wl_buttons[i].button == button) { if (wl_buttons[i].click == ClickSelItem && wl_buttons[i].button == button) {
puts(item->text); puts(item->text);
exit(0); exit(0);
@ -313,8 +313,8 @@ void buttonpress_wl(uint32_t button, double ex, double ey) {
click = ClickItem; click = ClickItem;
} }
} }
for (i = 0; i < LENGTH(cbuttons); i++) { for (i = 0; i < LENGTH(wl_cbuttons); i++) {
if (ignoreconfmouse) break; if (sp.ignoreconfmouse) break;
if (wl_cbuttons[i].click == ClickSelItem && wl_cbuttons[i].button == button) { if (wl_cbuttons[i].click == ClickSelItem && wl_cbuttons[i].button == button) {
puts(item->text); puts(item->text);
exit(0); exit(0);
@ -325,8 +325,8 @@ void buttonpress_wl(uint32_t button, double ex, double ey) {
} }
} }
} else if (matches) { // a single line, meaning it could be arrows too, so we check that here } else if (matches) { // a single line, meaning it could be arrows too, so we check that here
x += inputw; x += sp.inputw;
w = larrowWidth; w = larroww;
if (prev && curr->left) { if (prev && curr->left) {
if (ex >= x && ex <= x + w) { if (ex >= x && ex <= x + w) {
@ -335,8 +335,8 @@ void buttonpress_wl(uint32_t button, double ex, double ey) {
} }
// right arrow // right arrow
w = rarrowWidth; w = rarroww;
x = mw - w; x = sp.mw - w;
if (next && ex >= x && ex <= x + w) { if (next && ex >= x && ex <= x + w) {
click = ClickRArrow; click = ClickRArrow;
} }
@ -344,14 +344,14 @@ void buttonpress_wl(uint32_t button, double ex, double ey) {
// go through mouse button array and run function // go through mouse button array and run function
for (i = 0; i < LENGTH(wl_buttons); i++) { for (i = 0; i < LENGTH(wl_buttons); i++) {
if (ignoreglobalmouse) break; if (sp.ignoreglobalmouse) break;
if (click == wl_buttons[i].click && wl_buttons[i].func && wl_buttons[i].button == button) if (click == wl_buttons[i].click && wl_buttons[i].func && wl_buttons[i].button == button)
wl_buttons[i].func(&wl_buttons[i].arg); wl_buttons[i].func(&wl_buttons[i].arg);
} }
// go through mouse config array and run function // go through mouse config array and run function
for (i = 0; i < LENGTH(wl_cbuttons); i++) { for (i = 0; i < LENGTH(wl_cbuttons); i++) {
if (ignoreconfmouse) break; if (sp.ignoreconfmouse) break;
if (click == wl_cbuttons[i].click && wl_cbuttons[i].func && wl_cbuttons[i].button == button) if (click == wl_cbuttons[i].click && wl_cbuttons[i].func && wl_cbuttons[i].button == button)
wl_cbuttons[i].func(&wl_cbuttons[i].arg); wl_cbuttons[i].func(&wl_cbuttons[i].arg);
} }
@ -429,15 +429,15 @@ void draw_sf(struct state *state) {
// create buffer to draw on // create buffer to draw on
state->buffer = create_buffer(state); state->buffer = create_buffer(state);
if (drw == NULL) { if (draw == NULL) {
die("spmenu: drw == NULL"); die("spmenu: draw == NULL");
} }
if (state->buffer == NULL) { if (state->buffer == NULL) {
die("state->buffer == NULL"); die("state->buffer == NULL");
} }
drw_create_surface_wl(drw, state->data, state->width, state->height); draw_create_surface_wl(draw, state->data, state->width, state->height);
drawmenu_layer(); drawmenu_layer();
@ -533,40 +533,42 @@ int init_disp(struct state *state) {
void resizeclient_wl(struct state *state) { void resizeclient_wl(struct state *state) {
struct item *item; struct item *item;
int omh = mh; int mh = sp.mh;
int ic = 0; int ic = 0;
// walk through all items // walk through all items
for (item = items; item && item->text; item++) for (item = items; item && item->text; item++)
ic++; ic++;
bh = MAX(drw->font->h, drw->font->h + 2 + lineheight); sp.bh = MAX(draw->font->h, draw->font->h + 2 + lineheight);
lines = MIN(ic, MAX(lines, 0)); lines = MIN(ic, MAX(lines, 0));
reallines = lines; #if USEIMAGE
img.setlines = lines;
#endif
get_mh(); get_mh();
if (hideprompt && hideinput && hidemode && hidematchcount && hidecaps) { if (hideprompt && hideinput && hidemode && hidematchcount && hidecaps) {
mh -= bh; sp.mh -= sp.bh;
} }
if (mh == omh) { if (sp.mh == mh) {
return; return;
} }
state->width = mw; state->width = sp.mw;
state->height = mh; state->height = sp.mh;
state->buffer = create_buffer(state); state->buffer = create_buffer(state);
if (drw == NULL) { if (draw == NULL) {
die("spmenu: drw == NULL"); die("spmenu: draw == NULL");
} }
if (state->buffer == NULL) { if (state->buffer == NULL) {
die("state->buffer == null"); die("state->buffer == null");
} }
drw_create_surface_wl(drw, state->data, state->width, state->height); draw_create_surface_wl(draw, state->data, state->width, state->height);
set_layer_size(state, state->width, state->height); set_layer_size(state, state->width, state->height);
wl_surface_set_buffer_scale(state->surface, 1); wl_surface_set_buffer_scale(state->surface, 1);

View file

@ -15,7 +15,7 @@ void create_window_x11(int x, int y, int w, int h) {
swa.override_redirect = managed ? False : True; swa.override_redirect = managed ? False : True;
swa.background_pixel = 0; swa.background_pixel = 0;
swa.colormap = cmap; swa.colormap = x11.cmap;
swa.event_mask = swa.event_mask =
ExposureMask | // mapping the drawing ExposureMask | // mapping the drawing
KeyPressMask | // keypresses KeyPressMask | // keypresses
@ -25,7 +25,7 @@ void create_window_x11(int x, int y, int w, int h) {
// create client // create client
win = XCreateWindow(dpy, root, x, y, w, h, borderwidth, win = XCreateWindow(dpy, root, x, y, w, h, borderwidth,
depth, InputOutput, visual, x11.depth, InputOutput, x11.visual,
CWOverrideRedirect|CWBackPixel|CWBorderPixel|CWColormap|CWEventMask, &swa); CWOverrideRedirect|CWBackPixel|CWBorderPixel|CWColormap|CWEventMask, &swa);
return; return;
@ -45,7 +45,7 @@ void set_window_x11(void) {
col.green = g << 8; col.green = g << 8;
col.blue = b << 8; col.blue = b << 8;
if (!XAllocColor(dpy, cmap, &col)) { if (!XAllocColor(dpy, x11.cmap, &col)) {
die("spmenu: failed to allocate xcolor"); die("spmenu: failed to allocate xcolor");
} }
@ -70,7 +70,7 @@ void set_prop_x11(void) {
} }
void resizeclient_x11(void) { void resizeclient_x11(void) {
int omh = mh; int mh = sp.mh;
int x, y; int x, y;
#if USEXINERAMA #if USEXINERAMA
int j, di, a, n, area = 0; int j, di, a, n, area = 0;
@ -87,19 +87,19 @@ void resizeclient_x11(void) {
for (item = items; item && item->text; item++) for (item = items; item && item->text; item++)
ic++; ic++;
bh = MAX(drw->font->h, drw->font->h + 2 + lineheight); sp.bh = MAX(draw->font->h, draw->font->h + 2 + lineheight);
lines = MIN(ic, MAX(lines, 0)); lines = MIN(ic, MAX(lines, 0));
reallines = lines; #if USEIMAGE
img.setlines = lines;
// resize client to image height // resize client to image height
#if USEIMAGE
if (image) resizetoimageheight(imagewidth, imageheight); if (image) resizetoimageheight(imagewidth, imageheight);
#endif #endif
get_mh(); get_mh();
if (hideprompt && hideinput && hidemode && hidematchcount && hidecaps) { if (hideprompt && hideinput && hidemode && hidematchcount && hidecaps) {
mh -= bh; sp.mh -= sp.bh;
} }
// init xinerama screens // init xinerama screens
@ -134,13 +134,13 @@ void resizeclient_x11(void) {
// calculate x/y position // calculate x/y position
if (menuposition == 2) { // centered if (menuposition == 2) { // centered
mw = MIN(MAX(max_textw() + promptw, minwidth), info[i].width); sp.mw = MIN(MAX(max_textw() + sp.promptw, minwidth), info[i].width);
x = info[i].x_org + ((info[i].width - mw) / 2); x = info[i].x_org + ((info[i].width - sp.mw) / 2);
y = info[i].y_org + ((info[i].height - mh) / 2); y = info[i].y_org + ((info[i].height - sp.mh) / 2);
} else { // top or bottom } else { // top or bottom
x = info[i].x_org + xpos; x = info[i].x_org + xpos;
y = info[i].y_org + (menuposition ? 0 : info[i].height - mh - ypos); y = info[i].y_org + (menuposition ? 0 : info[i].height - sp.mh - ypos);
mw = (menuwidth>0 ? menuwidth : info[i].width); sp.mw = (menuwidth>0 ? menuwidth : info[i].width);
} }
XFree(info); XFree(info);
@ -151,21 +151,21 @@ void resizeclient_x11(void) {
die("spmenu: could not get embedding window attributes: 0x%lx", die("spmenu: could not get embedding window attributes: 0x%lx",
parentwin); // die because unable to get attributes for the parent window parentwin); // die because unable to get attributes for the parent window
if (menuposition == 2) { // centered if (menuposition == 2) { // centered
mw = MIN(MAX(max_textw() + promptw, minwidth), wa.width); sp.mw = MIN(MAX(max_textw() + sp.promptw, minwidth), wa.width);
x = (wa.width - mw) / 2; x = (wa.width - sp.mw) / 2;
y = (wa.height - mh) / 2; y = (wa.height - sp.mh) / 2;
} else { // top or bottom } else { // top or bottom
x = 0; x = 0;
y = menuposition ? 0 : wa.height - mh - ypos; y = menuposition ? 0 : wa.height - sp.mh - ypos;
mw = (menuwidth > 0 ? menuwidth : wa.width); sp.mw = (menuwidth > 0 ? menuwidth : wa.width);
} }
} }
// no window/invalid window or menu height we had before is the same as the current window height // no window/invalid window or menu height we had before is the same as the current window height
if (!win || omh == mh) return; if (!win || mh == sp.mh) return;
XMoveResizeWindow(dpy, win, x + sp, y + vp, mw - 2 * sp - borderwidth * 2, mh); XMoveResizeWindow(dpy, win, x + sp.sp, y + sp.vp, sp.mw - 2 * sp.sp - borderwidth * 2, sp.mh);
drw_resize(drw, mw - 2 * sp - borderwidth * 2, mh); draw_resize(draw, sp.mw - 2 * sp.sp - borderwidth * 2, sp.mh);
} }
void xinitvisual(void) { void xinitvisual(void) {
@ -176,7 +176,7 @@ void xinitvisual(void) {
// visual properties // visual properties
XVisualInfo tpl = { XVisualInfo tpl = {
.screen = screen, .screen = x11.screen,
.depth = 32, .depth = 32,
.class = TrueColor .class = TrueColor
}; };
@ -184,16 +184,16 @@ void xinitvisual(void) {
long masks = VisualScreenMask | VisualDepthMask | VisualClassMask; long masks = VisualScreenMask | VisualDepthMask | VisualClassMask;
infos = XGetVisualInfo(dpy, masks, &tpl, &nitems); infos = XGetVisualInfo(dpy, masks, &tpl, &nitems);
visual = NULL; x11.visual = NULL;
// create colormap // create colormap
for(i = 0; i < nitems; i ++) { for(i = 0; i < nitems; i ++) {
fmt = XRenderFindVisualFormat(dpy, infos[i].visual); fmt = XRenderFindVisualFormat(dpy, infos[i].visual);
if (fmt->type == PictTypeDirect && fmt->direct.alphaMask) { if (fmt->type == PictTypeDirect && fmt->direct.alphaMask) {
visual = infos[i].visual; x11.visual = infos[i].visual;
depth = infos[i].depth; x11.depth = infos[i].depth;
cmap = XCreateColormap(dpy, root, visual, AllocNone); x11.cmap = XCreateColormap(dpy, root, x11.visual, AllocNone);
useargb = 1; x11.useargb = 1;
break; break;
} }
} }
@ -201,9 +201,9 @@ void xinitvisual(void) {
XFree(infos); XFree(infos);
// no alpha, reset to default // no alpha, reset to default
if (!visual || !alpha) { if (!x11.visual || !alpha) {
visual = DefaultVisual(dpy, screen); x11.visual = DefaultVisual(dpy, x11.screen);
depth = DefaultDepth(dpy, screen); x11.depth = DefaultDepth(dpy, x11.screen);
cmap = DefaultColormap(dpy, screen); x11.cmap = DefaultColormap(dpy, x11.screen);
} }
} }

View file

@ -7,7 +7,7 @@ void pastesel_x11(void) {
Atom da; Atom da;
// we have been given the current selection, now insert it into input // we have been given the current selection, now insert it into input
if (XGetWindowProperty(dpy, win, utf8, 0, (sizeof text / 4) + 1, False, if (XGetWindowProperty(dpy, win, utf8, 0, (sizeof tx.text / 4) + 1, False,
utf8, &da, &di, &dl, &dl, (unsigned char **)&p) utf8, &da, &di, &dl, &dl, (unsigned char **)&p)
== Success && p) { == Success && p) {
insert(p, (q = strchr(p, '\n')) ? q - p : (ssize_t)strlen(p)); // insert selection insert(p, (q = strchr(p, '\n')) ? q - p : (ssize_t)strlen(p)); // insert selection

View file

@ -1,4 +1,4 @@
/* See LICENSE file for copyright and license details. */ /* See LICENSE file for copyright and license details. */
#define CLEANMASK(mask) (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask)) #define CLEANMASK(mask) (mask & ~(x11.numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask))
#define BUTTONMASK (ButtonPressMask|ButtonReleaseMask) #define BUTTONMASK (ButtonPressMask|ButtonReleaseMask)

View file

@ -19,7 +19,7 @@ void eventloop_x11(void) {
break; break;
case Expose: case Expose:
if (ev.xexpose.count == 0) if (ev.xexpose.count == 0)
drw_map(drw, win, 0, 0, mw, mh); draw_map(draw, win, 0, 0, sp.mw, sp.mh);
break; break;
case FocusIn: case FocusIn:
// regrab focus from parent window // regrab focus from parent window
@ -28,7 +28,7 @@ void eventloop_x11(void) {
break; break;
case KeyPress: // read key array and call functions case KeyPress: // read key array and call functions
if (incremental) { if (incremental) {
puts(text); puts(tx.text);
fflush(stdout); fflush(stdout);
} }
@ -54,7 +54,7 @@ void eventloop_x11(void) {
if (listchanged) { if (listchanged) {
match(); match();
for (int i = 0; i < itemnumber; i++) { for (int i = 0; i < sp.itemnumber; i++) {
if (sel && sel->right && (sel = sel->right) == next) { if (sel && sel->right && (sel = sel->right) == next) {
curr = next; curr = next;
} }

View file

@ -14,8 +14,8 @@ void setupdisplay_x11(void) {
#endif #endif
// set prompt width based on prompt size // set prompt width based on prompt size
promptw = (prompt && *prompt) sp.promptw = (prompt && *prompt)
? pango_prompt ? TEXTWM(prompt) : TEXTW(prompt) - lrpad / 4 : 0; // prompt width ? pango_prompt ? TEXTWM(prompt) : TEXTW(prompt) - sp.lrpad / 4 : 0; // prompt width
// init xinerama screens // init xinerama screens
#if USEXINERAMA #if USEXINERAMA
@ -51,13 +51,13 @@ void setupdisplay_x11(void) {
// calculate x/y position // calculate x/y position
if (menuposition == 2) { // centered if (menuposition == 2) { // centered
mw = MIN(MAX(max_textw() + promptw, minwidth), info[i].width); sp.mw = MIN(MAX(max_textw() + sp.promptw, minwidth), info[i].width);
x = info[i].x_org + xpos + ((info[i].width - mw) / 2); x = info[i].x_org + xpos + ((info[i].width - sp.mw) / 2);
y = info[i].y_org - ypos + ((info[i].height - mh) / 2); y = info[i].y_org - ypos + ((info[i].height - sp.mh) / 2);
} else { // top or bottom } else { // top or bottom
x = info[i].x_org + xpos; x = info[i].x_org + xpos;
y = info[i].y_org + (menuposition ? 0 : info[i].height - mh - ypos); y = info[i].y_org + (menuposition ? 0 : info[i].height - sp.mh - ypos);
mw = (menuwidth > 0 ? menuwidth : info[i].width); sp.mw = (menuwidth > 0 ? menuwidth : info[i].width);
} }
XFree(info); XFree(info);
@ -69,22 +69,22 @@ void setupdisplay_x11(void) {
parentwin); // die because unable to get attributes for the parent window parentwin); // die because unable to get attributes for the parent window
if (menuposition == 2) { // centered if (menuposition == 2) { // centered
mw = MIN(MAX(max_textw() + promptw, minwidth), wa.width); sp.mw = MIN(MAX(max_textw() + sp.promptw, minwidth), wa.width);
x = (wa.width - mw) / 2 + xpos; x = (wa.width - sp.mw) / 2 + xpos;
y = (wa.height - mh) / 2 - ypos; y = (wa.height - sp.mh) / 2 - ypos;
} else { // top or bottom } else { // top or bottom
x = 0; x = 0;
y = menuposition ? 0 : wa.width - mh - ypos; y = menuposition ? 0 : wa.width - sp.mh - ypos;
mw = (menuwidth > 0 ? menuwidth : wa.width); sp.mw = (menuwidth > 0 ? menuwidth : wa.width);
} }
} }
// create menu window and set properties for it // create menu window and set properties for it
create_window_x11( create_window_x11(
x + sp, x + sp.sp,
y + vp - (menuposition == 1 ? 0 : menuposition == 2 ? borderwidth : borderwidth * 2), y + sp.vp - (menuposition == 1 ? 0 : menuposition == 2 ? borderwidth : borderwidth * 2),
mw - 2 * sp - borderwidth * 2, sp.mw - 2 * sp.sp - borderwidth * 2,
mh sp.mh
); );
set_window_x11(); set_window_x11();
@ -105,7 +105,7 @@ void setupdisplay_x11(void) {
} }
// embed spmenu inside parent window // embed spmenu inside parent window
if (embed) { if (x11.embed) {
XReparentWindow(dpy, win, parentwin, x, y); XReparentWindow(dpy, win, parentwin, x, y);
XSelectInput(dpy, parentwin, FocusChangeMask | SubstructureNotifyMask); XSelectInput(dpy, parentwin, FocusChangeMask | SubstructureNotifyMask);
@ -119,21 +119,23 @@ void setupdisplay_x11(void) {
} }
// resize window and draw // resize window and draw
drw_resize(drw, mw - 2 * sp - borderwidth * 2, mh); draw_resize(draw, sp.mw - 2 * sp.sp - borderwidth * 2, sp.mh);
match(); match();
drawmenu(); drawmenu();
} }
void prepare_window_size_x11(void) { void prepare_window_size_x11(void) {
sp = menupaddingh; sp.sp = menupaddingh;
vp = (menuposition == 1) ? menupaddingv : - menupaddingv; sp.vp = (menuposition == 1) ? menupaddingv : - menupaddingv;
bh = MAX(drw->font->h, drw->font->h + 2 + lineheight); sp.bh = MAX(draw->font->h, draw->font->h + 2 + lineheight);
lines = MAX(lines, 0); lines = MAX(lines, 0);
reallines = lines; #if USEIMAGE
img.setlines = lines;
#endif
lrpad = drw->font->h + textpadding; sp.lrpad = draw->font->h + textpadding;
get_mh(); get_mh();
return; return;
@ -144,8 +146,8 @@ Display * opendisplay_x11(char *disp) {
} }
void set_screen_x11(Display *disp) { void set_screen_x11(Display *disp) {
screen = DefaultScreen(disp); x11.screen = DefaultScreen(disp);
root = RootWindow(disp, screen); root = RootWindow(disp, x11.screen);
} }
void handle_x11(void) { void handle_x11(void) {
@ -164,7 +166,7 @@ void handle_x11(void) {
set_screen_x11(dpy); set_screen_x11(dpy);
// parent window is the root window (ie. window manager) because we're not embedding // parent window is the root window (ie. window manager) because we're not embedding
if (!embed || !(parentwin = strtol(embed, NULL, 0))) if (!x11.embed || !(parentwin = strtol(x11.embed, NULL, 0)))
parentwin = root; parentwin = root;
if (!XGetWindowAttributes(dpy, parentwin, &wa)) { if (!XGetWindowAttributes(dpy, parentwin, &wa)) {
@ -172,7 +174,7 @@ void handle_x11(void) {
} }
xinitvisual(); // init visual and create drawable after xinitvisual(); // init visual and create drawable after
drw = drw_create_x11(dpy, screen, root, wa.width, wa.height, visual, depth, cmap, protocol); draw = draw_create_x11(dpy, x11.screen, root, wa.width, wa.height, x11.visual, x11.depth, x11.cmap, protocol);
} }
void cleanup_x11(Display *disp) { void cleanup_x11(Display *disp) {

View file

@ -4,13 +4,13 @@ void updatenumlockmask(void) {
unsigned int i, j; unsigned int i, j;
XModifierKeymap *modmap; XModifierKeymap *modmap;
numlockmask = 0; x11.numlockmask = 0;
modmap = XGetModifierMapping(dpy); modmap = XGetModifierMapping(dpy);
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
for (j = 0; j < modmap->max_keypermod; j++) for (j = 0; j < modmap->max_keypermod; j++)
if (modmap->modifiermap[i * modmap->max_keypermod + j] if (modmap->modifiermap[i * modmap->max_keypermod + j]
== XKeysymToKeycode(dpy, XK_Num_Lock)) == XKeysymToKeycode(dpy, XK_Num_Lock))
numlockmask = (1 << i); x11.numlockmask = (1 << i);
XFreeModifiermap(modmap); XFreeModifiermap(modmap);
} }
@ -36,12 +36,12 @@ void keypress_x11(XEvent *e) {
if (keysym == hkeys[0].keysym && CLEANMASK(hkeys[0].mod) == CLEANMASK(ev->state) && hkeys[0].func) hkeys[0].func(&(hkeys[0].arg)); if (keysym == hkeys[0].keysym && CLEANMASK(hkeys[0].mod) == CLEANMASK(ev->state) && hkeys[0].func) hkeys[0].func(&(hkeys[0].arg));
for (i = 0; i < LENGTH(keys); i++) { for (i = 0; i < LENGTH(keys); i++) {
if (ignoreglobalkeys) break; if (sp.ignoreglobalkeys) break;
if (keysym == keys[i].keysym && CLEANMASK(keys[i].mod) == CLEANMASK(ev->state) && keys[i].func) { if (keysym == keys[i].keysym && CLEANMASK(keys[i].mod) == CLEANMASK(ev->state) && keys[i].func) {
if ((keys[i].mode && curMode) || keys[i].mode == -1) { if ((keys[i].mode && sp.mode) || keys[i].mode == -1) {
keys[i].func(&(keys[i].arg)); keys[i].func(&(keys[i].arg));
return; return;
} else if (!keys[i].mode && !curMode) { } else if (!keys[i].mode && !sp.mode) {
keys[i].func(&(keys[i].arg)); keys[i].func(&(keys[i].arg));
} else { } else {
continue; continue;
@ -50,12 +50,12 @@ void keypress_x11(XEvent *e) {
} }
for (i = 0; i < LENGTH(ckeys); i++) { for (i = 0; i < LENGTH(ckeys); i++) {
if (ignoreconfkeys) break; if (sp.ignoreconfkeys) break;
if (keysym == ckeys[i].keysym && CLEANMASK(ckeys[i].mod) == CLEANMASK(ev->state) && ckeys[i].func) { if (keysym == ckeys[i].keysym && CLEANMASK(ckeys[i].mod) == CLEANMASK(ev->state) && ckeys[i].func) {
if ((ckeys[i].mode && curMode) || ckeys[i].mode == -1) { if ((ckeys[i].mode && sp.mode) || ckeys[i].mode == -1) {
ckeys[i].func(&(ckeys[i].arg)); ckeys[i].func(&(ckeys[i].arg));
return; return;
} else if (!ckeys[i].mode && !curMode) { } else if (!ckeys[i].mode && !sp.mode) {
ckeys[i].func(&(ckeys[i].arg)); ckeys[i].func(&(ckeys[i].arg));
} else { } else {
continue; continue;
@ -63,11 +63,11 @@ void keypress_x11(XEvent *e) {
} }
} }
if (!iscntrl(*buf) && type && curMode ) { if (!iscntrl(*buf) && type && sp.mode ) {
if (allowkeys) { if (sp.allowkeys) {
insert(buf, len); insert(buf, len);
} else { } else {
allowkeys = !allowkeys; sp.allowkeys = !sp.allowkeys;
} }
drawmenu(); drawmenu();
@ -80,7 +80,7 @@ void grabkeyboard_x11(void) {
int i; int i;
// don't grab if embedded // don't grab if embedded
if (embed || managed) if (x11.embed || managed)
return; return;
// try to grab keyboard, we may have to wait for another process to ungrab // try to grab keyboard, we may have to wait for another process to ungrab
for (i = 0; i < 1000; i++) { for (i = 0; i < 1000; i++) {
@ -98,7 +98,7 @@ void getcapsstate(void) {
unsigned int cs = 0; unsigned int cs = 0;
XkbGetIndicatorState(dpy, XkbUseCoreKbd, &cs); XkbGetIndicatorState(dpy, XkbUseCoreKbd, &cs);
capslockstate = (cs & 0x01) == 1; sp.capslockstate = (cs & 0x01) == 1;
strncpy(capstext, capslockstate ? capslockontext : capslockofftext, 15); strncpy(tx.capstext, sp.capslockstate ? capslockontext : capslockofftext, 15);
} }

View file

@ -3,27 +3,27 @@
void buttonpress_x11(XEvent *e) { void buttonpress_x11(XEvent *e) {
struct item *item; struct item *item;
XButtonPressedEvent *ev = &e->xbutton; XButtonPressedEvent *ev = &e->xbutton;
int x = 0, y = 0, h = bh, w, item_num = 0; int x = 0, y = 0, h = sp.bh, w, item_num = 0;
unsigned int i, click; unsigned int i, click;
int yp = 0; int yp = 0;
// margin // margin
x += menumarginh; x += menumarginh;
int larrowWidth = 0; int larroww = 0;
int rarrowWidth = 0; int rarroww = 0;
int numberWidth = 0; int numberw = 0;
int modeWidth = 0; int modew = 0;
int capsWidth = 0; int capsw = 0;
if (!hidelarrow) larrowWidth = pango_leftarrow ? TEXTWM(leftarrow) : TEXTW(leftarrow); if (!hidelarrow) larroww = pango_leftarrow ? TEXTWM(leftarrow) : TEXTW(leftarrow);
if (!hiderarrow) rarrowWidth = pango_rightarrow ? TEXTWM(rightarrow) : TEXTW(rightarrow); if (!hiderarrow) rarroww = pango_rightarrow ? TEXTWM(rightarrow) : TEXTW(rightarrow);
if (!hidematchcount) numberWidth = pango_numbers ? TEXTWM(numbers) : TEXTW(numbers); if (!hidematchcount) numberw = pango_numbers ? TEXTWM(tx.numbers) : TEXTW(tx.numbers);
if (!hidemode) modeWidth = pango_mode ? TEXTWM(modetext) : TEXTW(modetext); if (!hidemode) modew = pango_mode ? TEXTWM(tx.modetext) : TEXTW(tx.modetext);
if (!hidecaps) capsWidth = pango_caps ? TEXTWM(capstext) : TEXTW(capstext); if (!hidecaps) capsw = pango_caps ? TEXTWM(tx.capstext) : TEXTW(tx.capstext);
if (!strcmp(capstext, "")) if (!strcmp(tx.capstext, ""))
capsWidth = 0; capsw = 0;
if ((hideprompt && hideinput && hidemode && hidematchcount && hidecaps) && lines) { if ((hideprompt && hideinput && hidemode && hidematchcount && hidecaps) && lines) {
yp = 1; yp = 1;
@ -38,19 +38,19 @@ void buttonpress_x11(XEvent *e) {
click = ClickWindow; // clicking anywhere, we use this and override it if we clicked on something specific click = ClickWindow; // clicking anywhere, we use this and override it if we clicked on something specific
// check click position and override the value of click // check click position and override the value of click
if (yp && ev->x < x + promptw + powerlineprompt ? plw : 0) { // prompt if (yp && ev->x < x + sp.promptw + powerlineprompt ? sp.plw : 0) { // prompt
click = ClickPrompt; click = ClickPrompt;
} else if (yp && (ev->x > mw - capsWidth - 2 * sp - 2 * borderwidth - menumarginh) && !hidecaps && capsWidth) { // caps lock indicator } else if (yp && (ev->x > sp.mw - capsw - 2 * sp.sp - 2 * borderwidth - menumarginh) && !hidecaps && capsw) { // caps lock indicator
click = ClickCaps; click = ClickCaps;
} else if (yp && ev->x > mw - modeWidth - capsWidth - 2 * sp - 2 * borderwidth - menumarginh) { // mode indicator } else if (yp && ev->x > sp.mw - modew - capsw - 2 * sp.sp - 2 * borderwidth - menumarginh) { // mode indicator
click = ClickMode; click = ClickMode;
} else if (yp && ev->x > mw - modeWidth - numberWidth - capsWidth - 2 * sp - 2 * borderwidth - menumarginh) { // match count } else if (yp && ev->x > sp.mw - modew - numberw - capsw - 2 * sp.sp - 2 * borderwidth - menumarginh) { // match count
click = ClickNumber; click = ClickNumber;
} else if (yp && !hideinput) { // input } else if (yp && !hideinput) { // input
w = (lines > 0 || !matches) ? mw - x : inputw; w = (lines > 0 || !matches) ? sp.mw - x : sp.inputw;
if ((lines <= 0 && ev->x >= 0 && ev->x <= x + w + promptw + if ((lines <= 0 && ev->x >= 0 && ev->x <= x + w + sp.promptw +
((!prev || !curr->left) ? larrowWidth : 0)) || ((!prev || !curr->left) ? larroww : 0)) ||
(lines > 0 && ev->y >= y && ev->y <= y + h)) { (lines > 0 && ev->y >= y && ev->y <= y + h)) {
click = ClickInput; click = ClickInput;
@ -58,14 +58,14 @@ void buttonpress_x11(XEvent *e) {
} }
#if USEIMAGE #if USEIMAGE
if (!hideimage && longestedge != 0) { if (!hideimage && img.longestedge != 0) {
x += MAX((imagegaps * 2) + imagewidth, indentitems ? promptw : 0); x += MAX((imagegaps * 2) + imagewidth, indentitems ? sp.promptw : 0);
} }
#endif #endif
// item click // item click
if (lines > 0) { if (lines > 0) {
w = mw - x; w = sp.mw - x;
ev->y -= menumarginv; ev->y -= menumarginv;
@ -83,9 +83,9 @@ void buttonpress_x11(XEvent *e) {
y += h; y += h;
// ClickSelItem, called function doesn't matter // ClickSelItem, called function doesn't matter
if (ev->y >= y && ev->y <= (y + h) && ev->x >= x + (powerlineitems ? plw : 0) && ev->x <= (x + w / columns) + (powerlineitems ? plw : 0)) { if (ev->y >= y && ev->y <= (y + h) && ev->x >= x + (powerlineitems ? sp.plw : 0) && ev->x <= (x + w / columns) + (powerlineitems ? sp.plw : 0)) {
for (i = 0; i < LENGTH(buttons); i++) { for (i = 0; i < LENGTH(buttons); i++) {
if (ignoreglobalmouse) break; if (sp.ignoreglobalmouse) break;
if (buttons[i].click == ClickSelItem && buttons[i].button == ev->button) { if (buttons[i].click == ClickSelItem && buttons[i].button == ev->button) {
puts(item->text); puts(item->text);
exit(0); exit(0);
@ -94,7 +94,7 @@ void buttonpress_x11(XEvent *e) {
} }
} }
for (i = 0; i < LENGTH(cbuttons); i++) { for (i = 0; i < LENGTH(cbuttons); i++) {
if (ignoreconfmouse) break; if (sp.ignoreconfmouse) break;
if (cbuttons[i].click == ClickSelItem && cbuttons[i].button == ev->button) { if (cbuttons[i].click == ClickSelItem && cbuttons[i].button == ev->button) {
puts(item->text); puts(item->text);
exit(0); exit(0);
@ -105,8 +105,8 @@ void buttonpress_x11(XEvent *e) {
} }
} }
} else if (matches) { // a single line, meaning it could be arrows too, so we check that here } else if (matches) { // a single line, meaning it could be arrows too, so we check that here
x += inputw; x += sp.inputw;
w = larrowWidth; w = larroww;
if (prev && curr->left) { if (prev && curr->left) {
if (ev->x >= x && ev->x <= x + w) { if (ev->x >= x && ev->x <= x + w) {
@ -115,8 +115,8 @@ void buttonpress_x11(XEvent *e) {
} }
// right arrow // right arrow
w = rarrowWidth; w = rarroww;
x = mw - w; x = sp.mw - w;
if (next && ev->x >= x && ev->x <= x + w) { if (next && ev->x >= x && ev->x <= x + w) {
click = ClickRArrow; click = ClickRArrow;
} }
@ -124,14 +124,14 @@ void buttonpress_x11(XEvent *e) {
// go through mouse button array and run function // go through mouse button array and run function
for (i = 0; i < LENGTH(buttons); i++) { for (i = 0; i < LENGTH(buttons); i++) {
if (ignoreglobalmouse) break; if (sp.ignoreglobalmouse) break;
if (click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button) if (click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button)
buttons[i].func(&buttons[i].arg); buttons[i].func(&buttons[i].arg);
} }
// go through mouse config array and run function // go through mouse config array and run function
for (i = 0; i < LENGTH(cbuttons); i++) { for (i = 0; i < LENGTH(cbuttons); i++) {
if (ignoreconfmouse) break; if (sp.ignoreconfmouse) break;
if (click == cbuttons[i].click && cbuttons[i].func && cbuttons[i].button == ev->button) if (click == cbuttons[i].click && cbuttons[i].func && cbuttons[i].button == ev->button)
cbuttons[i].func(&cbuttons[i].arg); cbuttons[i].func(&cbuttons[i].arg);
} }

351
spmenu.c
View file

@ -80,139 +80,14 @@
#include <openssl/md5.h> #include <openssl/md5.h>
#endif #endif
// include Xlib
#if USEX
#include <X11/Xlib.h>
#endif
// include macros and other defines // include macros and other defines
#include "libs/define.c" #include "libs/define.c"
// mode
static int curMode; // 0 is command mode
static int allowkeys; // whether or not to interpret a keypress as an insertion
// various headers
#include "libs/draw/draw.h"
#include "libs/main.h"
#include "libs/draw.h"
#include "libs/stream.h"
#include "libs/schemes.h"
#include "libs/arg.h"
#include "libs/x11/inc.h" // include x11
#include "libs/wl/inc.h" // include wayland
#include "libs/sort.h"
#include "libs/history.h"
// text
static char modetext[64] = "";
static char text[BUFSIZ] = "";
static char numbers[NUMBERSBUFSIZE] = "";
// keybinds
#if USEX
static int numlockmask = 0;
#endif
static int capslockstate = 0;
static int bh, mw, mh; // height of each item, menu width, menu height
static int reallines = 0; // temporary integer which holds lines
static int inputw = 0; // input width
static int promptw; // prompt width
static int plw = 0; // powerline width
static int lrpad; // sum of left and right padding
static int vp; // vertical padding for bar
static int sp; // side padding for bar
static int cursorstate = 1; // cursor state
static int itemnumber = 0; // item number
static size_t cursor;
static struct item *items = NULL, *backup_items, *list_items;
static struct item *matches, *matchend; // matches, final match
static struct item *prev, *curr, *next, *sel; // previous, current, next, selected
static int hplength = 0; // high priority
static char **hpitems = NULL; // high priority
static int *sel_index = NULL;
static unsigned int sel_size = 0;
static int protocol_override = 0;
static int itemn = 0; // item number
#if USEX
static char *embed; // X11 embed
static int screen; // screen
#endif
// item struct
struct item {
char *text;
char *clntext;
#if USEIMAGE
char *image;
#endif
char *ex;
struct item *left, *right;
int hp;
int index;
double distance;
};
// image globals
#if USEIMAGE
static int flip = 0;
static int needredraw = 1;
static int longestedge = 0;
static int imagew = 0;
static int imageh = 0;
static int imageg = 0;
static int ow = 0;
static int oh = 0;
#endif
static int fullscreen = 0;
// set an integer to 1 if we have rtl enabled, this saves a lot of lines and duplicate code
#if USERTL
static int isrtl = 1;
#else
static int isrtl = 0;
#endif
static int ignoreconfkeys = 0; // can be set globally if you don't want to override keybinds with config file keys
static int ignoreglobalkeys = 0; // should be set in the config file, if 1, the Keys keys array is ignored
static int ignoreconfmouse = 0; // same for mouse
static int ignoreglobalmouse = 0; // same for mouse
// colors
#if USEX
static int useargb;
static int depth;
static Visual *visual;
static Colormap cmap;
#endif
static Drw *drw;
// declare functions
static int is_selected(size_t index);
static void calcoffsets(void);
static void recalculatenumbers(void);
static void insert(const char *str, ssize_t n);
static void cleanup(void);
static void navigatehistfile(int dir);
#if USEX
static void pastesel(void);
static void grabfocus(void);
#endif
static void resizeclient(void);
static void get_width(void);
static void get_mh(void);
static void set_mode(void);
static void handle(void);
static void appenditem(struct item *item, struct item **list, struct item **last);
static int max_textw(void);
static size_t nextrune(int inc);
static char * cistrstr(const char *s, const char *sub);
static int (*fstrncmp)(const char *, const char *, size_t) = strncasecmp;
static char *(*fstrstr)(const char *, const char *) = cistrstr;
static char **list;
static size_t listsize;
static int listcount;
static int listchanged = 0;
// clicks
enum { enum {
ClickWindow, ClickWindow,
ClickPrompt, ClickPrompt,
@ -226,12 +101,152 @@ enum {
ClickMode, ClickMode,
}; };
struct item {
char *text;
char *clntext;
char *image;
char *ex;
struct item *left, *right;
int hp;
int index;
double distance;
};
struct sp {
int bh; // height of each menu item
int mw; // width
int mh; // height
int vp; // vertical padding for bar
int sp; // side padding for bar
int lrpad; // sum of left and right padding
int mode; // current mode
int allowkeys; // interpret a keypress as an insertion?
int capslockstate; // caps lock state
int inputw; // input width
int promptw; // prompt width
int plw; // powerline width
int itemnumber; // item number
size_t cursor;
int ignoreconfkeys; // can be set globally if you don't want to override keybinds with config file keys
int ignoreglobalkeys; // should be set in the config file, if 1, the Keys keys array is ignored
int ignoreconfmouse; // same for mouse
int ignoreglobalmouse; // same for mouse
};
#if USEIMAGE
struct img {
int setlines;
int flip;
int longestedge;
int imagew;
int imageh;
int imageg;
int ow;
int oh;
};
#endif
struct tx {
char modetext[64]; // mode text
char text[BUFSIZ]; // input text
char numbers[NUMBERSBUFSIZE]; // number text
char capstext[64]; // caps lock text
};
#if USEX
struct x11 {
int numlockmask;
int useargb;
int depth;
char *embed;
int screen;
Visual *visual;
Colormap cmap;
};
#endif
static struct sp sp = {0};
static struct tx tx = {0};
#if USEIMAGE
static struct img img = {0};
#endif
#if USEX
static struct x11 x11 = {0};
#endif
static struct item *items = NULL, *backup_items, *list_items;
static struct item *matches, *matchend;
static struct item *prev, *curr, *next, *sel;
// various headers
#include "libs/draw/draw.h"
#include "libs/main.h"
#include "libs/draw.h"
#include "libs/stream.h"
#include "libs/schemes.h"
#include "libs/arg.h"
#include "libs/x11/inc.h" // include x11
#include "libs/wl/inc.h" // include wayland
#include "libs/sort.h"
#include "libs/history.h"
static Draw_t *draw;
// high priority
static int hplength = 0;
static char **hpitems = NULL;
static int *sel_index = NULL;
static unsigned int sel_size = 0;
static int protocol_override = 0;
static int itemn = 0;
static int fullscreen = 0;
#if USERTL
static int isrtl = 1;
#else
static int isrtl = 0;
#endif
// declare functions
static int is_selected(size_t index);
static void calcoffsets(void);
static void recalculatenumbers(void);
static void insert(const char *str, ssize_t n);
static void cleanup(void);
static void navigatehistfile(int dir);
static void resizeclient(void);
static void get_width(void);
static void get_mh(void);
static void set_mode(void);
static void handle(void);
static void appenditem(struct item *item, struct item **list, struct item **last);
static int max_textw(void);
static size_t nextrune(int inc);
static char * cistrstr(const char *s, const char *sub);
static int (*fstrncmp)(const char *, const char *, size_t) = strncasecmp;
static char *(*fstrstr)(const char *, const char *) = cistrstr;
#if USEX
static void pastesel(void);
static void grabfocus(void);
#endif
static char **list;
static size_t listsize;
static int listcount;
static int listchanged = 0;
// user configuration // user configuration
#include "libs/options.h" #include "libs/options.h"
#include "libs/keybinds.h" #include "libs/keybinds.h"
#include "libs/mouse.h" #include "libs/mouse.h"
static char capstext[16];
static char *fonts[] = { font }; static char *fonts[] = { font };
// color array // color array
@ -310,9 +325,9 @@ void recalculatenumbers(void) {
} }
if (selected) { if (selected) {
snprintf(numbers, NUMBERSBUFSIZE, "%d/%d/%d", numer, denom, selected); snprintf(tx.numbers, NUMBERSBUFSIZE, "%d/%d/%d", numer, denom, selected);
} else { } else {
snprintf(numbers, NUMBERSBUFSIZE, "%d/%d", numer, denom); snprintf(tx.numbers, NUMBERSBUFSIZE, "%d/%d", numer, denom);
} }
} }
@ -320,34 +335,34 @@ void calcoffsets(void) {
int i, n; int i, n;
if (lines > 0) if (lines > 0)
n = lines * columns * bh; n = lines * columns * sp.bh;
else { // no lines, therefore the size of items must be decreased to fit the menu elements else { // no lines, therefore the size of items must be decreased to fit the menu elements
int numberWidth = 0; int numberw = 0;
int modeWidth = 0; int modeWidth = 0;
int larrowWidth = 0; int larroww = 0;
int rarrowWidth = 0; int rarrowWidth = 0;
int capsWidth = 0; int capsw = 0;
if (!hidematchcount) numberWidth = pango_numbers ? TEXTWM(numbers) : TEXTW(numbers); if (!hidematchcount) numberw = pango_numbers ? TEXTWM(tx.numbers) : TEXTW(tx.numbers);
if (!hidemode) modeWidth = pango_mode ? TEXTWM(modetext) : TEXTW(modetext); if (!hidemode) modeWidth = pango_mode ? TEXTWM(tx.modetext) : TEXTW(tx.modetext);
if (!hidelarrow) larrowWidth = pango_leftarrow ? TEXTWM(leftarrow) : TEXTW(leftarrow); if (!hidelarrow) larroww = pango_leftarrow ? TEXTWM(leftarrow) : TEXTW(leftarrow);
if (!hiderarrow) rarrowWidth = pango_rightarrow ? TEXTWM(rightarrow) : TEXTW(rightarrow); if (!hiderarrow) rarrowWidth = pango_rightarrow ? TEXTWM(rightarrow) : TEXTW(rightarrow);
if (!hidecaps) capsWidth = pango_caps ? TEXTWM(capstext) : TEXTW(capstext); if (!hidecaps) capsw = pango_caps ? TEXTWM(tx.capstext) : TEXTW(tx.capstext);
if (!strcmp(capstext, "")) if (!strcmp(tx.capstext, ""))
capsWidth = 0; capsw = 0;
n = mw - (promptw + inputw + larrowWidth + rarrowWidth + modeWidth + numberWidth + capsWidth + menumarginh); n = sp.mw - (sp.promptw + sp.inputw + larroww + rarrowWidth + modeWidth + numberw + capsw + menumarginh);
} }
// calculate which items will begin the next page // calculate which items will begin the next page
for (i = 0, next = curr; next; next = next->right) for (i = 0, next = curr; next; next = next->right)
if ((i += (lines > 0) ? bh : MIN(TEXTWM(next->text) + (powerlineitems ? !lines ? 2 * plw : 0 : 0), n)) > n) if ((i += (lines > 0) ? sp.bh : MIN(TEXTWM(next->text) + (powerlineitems ? !lines ? 2 * sp.plw : 0 : 0), n)) > n)
break; break;
// calculate which items will begin the previous page // calculate which items will begin the previous page
for (i = 0, prev = curr; prev && prev->left; prev = prev->left) for (i = 0, prev = curr; prev && prev->left; prev = prev->left)
if ((i += (lines > 0) ? bh : MIN(TEXTWM(prev->left->text) + (powerlineitems ? !lines ? 2 * plw : 0 : 0), n)) > n) if ((i += (lines > 0) ? sp.bh : MIN(TEXTWM(prev->left->text) + (powerlineitems ? !lines ? 2 * sp.plw : 0 : 0), n)) > n)
break; break;
} }
@ -372,7 +387,7 @@ void cleanup(void) {
free(hpitems[i]); free(hpitems[i]);
// free drawing and close the display // free drawing and close the display
drw_free(drw); draw_free(draw);
#if USEX #if USEX
if (!protocol) { if (!protocol) {
@ -407,26 +422,26 @@ void grabfocus(void) {
#endif #endif
void insert(const char *str, ssize_t n) { void insert(const char *str, ssize_t n) {
if (strlen(text) + n > sizeof text - 1) if (strlen(tx.text) + n > sizeof tx.text - 1)
return; return;
static char l[BUFSIZ] = ""; static char l[BUFSIZ] = "";
if (requirematch) memcpy(l, text, BUFSIZ); if (requirematch) memcpy(l, tx.text, BUFSIZ);
// move existing text out of the way, insert new text, and update cursor // move existing text out of the way, insert new text, and update cursor
memmove(&text[cursor + n], &text[cursor], sizeof text - cursor - MAX(n, 0)); memmove(&tx.text[sp.cursor + n], &tx.text[sp.cursor], sizeof tx.text - sp.cursor - MAX(n, 0));
// update cursor // update cursor
if (n > 0 && str && n) if (n > 0 && str && n)
memcpy(&text[cursor], str, n); memcpy(&tx.text[sp.cursor], str, n);
// add to cursor position and continue matching // add to cursor position and continue matching
cursor += n; sp.cursor += n;
match(); match();
if (!matches && requirematch) { if (!matches && requirematch) {
memcpy(text, l, BUFSIZ); memcpy(tx.text, l, BUFSIZ);
cursor -= n; sp.cursor -= n;
match(); match();
} }
} }
@ -435,7 +450,7 @@ size_t nextrune(int inc) {
ssize_t n; ssize_t n;
// return location of next utf8 rune in the given direction (+1 or -1) // return location of next utf8 rune in the given direction (+1 or -1)
for (n = cursor + inc; n + inc >= 0 && (text[n] & 0xc0) == 0x80; n += inc) for (n = sp.cursor + inc; n + inc >= 0 && (tx.text[n] & 0xc0) == 0x80; n += inc)
; ;
return n; return n;
} }
@ -463,15 +478,15 @@ void resizeclient(void) {
} }
void get_width(void) { void get_width(void) {
inputw = mw / 3; sp.inputw = sp.mw / 3;
} }
void get_mh(void) { void get_mh(void) {
mh = (lines + 1) * bh; sp.mh = (lines + 1) * sp.bh;
mh += 2 * menumarginv; sp.mh += 2 * menumarginv;
if ((hideprompt && hideinput && hidemode && hidematchcount && hidecaps) && lines) { if ((hideprompt && hideinput && hidemode && hidematchcount && hidecaps) && lines) {
mh -= bh; sp.mh -= sp.bh;
} }
} }
@ -482,15 +497,15 @@ void set_mode(void) {
// set default mode, must be done before the event loop or keybindings will not work // set default mode, must be done before the event loop or keybindings will not work
if (mode) { if (mode) {
curMode = 1; sp.mode = 1;
allowkeys = 1; sp.allowkeys = 1;
sp_strncpy(modetext, instext, sizeof(modetext)); sp_strncpy(tx.modetext, instext, sizeof(tx.modetext));
} else { } else {
curMode = 0; sp.mode = 0;
allowkeys = !curMode; sp.allowkeys = !sp.mode;
sp_strncpy(modetext, normtext, sizeof(modetext)); sp_strncpy(tx.modetext, normtext, sizeof(tx.modetext));
} }
} }
@ -499,7 +514,7 @@ void handle(void) {
#if USEX #if USEX
handle_x11(); handle_x11();
if (!drw_font_create(drw, fonts, LENGTH(fonts))) { if (!draw_font_create(draw, fonts, LENGTH(fonts))) {
die("no fonts could be loaded."); die("no fonts could be loaded.");
} }
@ -537,9 +552,9 @@ void handle(void) {
borderwidth = 0; borderwidth = 0;
managed = 0; managed = 0;
drw = drw_create_wl(protocol); draw = draw_create_wl(protocol);
if (!drw_font_create(drw, fonts, LENGTH(fonts))) { if (!draw_font_create(draw, fonts, LENGTH(fonts))) {
die("no fonts could be loaded."); die("no fonts could be loaded.");
} }