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

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
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]);
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]);
} else if (!strcmp(argv[i], "-txp") || (!strcmp(argv[i], "--text-padding"))) { // text padding
textpadding = atoi(argv[++i]);
@ -397,7 +397,7 @@ void readargs(int argc, char *argv[]) {
imageresize = 0;
} else if (!strcmp(argv[i], "-w") || (!strcmp(argv[i], "--embed"))) { // embedding window id
#if USEX
embed = argv[++i];
x11.embed = argv[++i];
#endif
} else if (!strcmp(argv[i], "-n") || (!strcmp(argv[i], "--preselect"))) { // preselected item
preselected = atoi(argv[++i]);
@ -591,8 +591,8 @@ void usage(int status) {
fputs(": fancy dynamic menu\n\n"
"- Arguments -\n"
"spmenu -l, --lines <line> Set line count to stdin\n"
"spmenu -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.mh, --line-height <height> Set spmenu line height to <height>\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 -gc, --generate-cache 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)) \
&& MAX(0, MIN((y)+(h),(r).y_org+(r).height) - MAX((y),(r).y_org)))
#define LENGTH(X) (sizeof X / sizeof X[0])
#define TEXTW(X) (drw_font_getwidth(drw, (X), False) + lrpad)
#define TEXTWM(X) (drw_font_getwidth(drw, (X), True) + lrpad)
#define TEXTW(X) (draw_font_getwidth(draw, (X), False) + sp.lrpad)
#define TEXTWM(X) (draw_font_getwidth(draw, (X), True) + sp.lrpad)
#define NUMBERSMAXDIGITS 100
#define NUMBERSBUFSIZE (NUMBERSMAXDIGITS * 2) + 1
#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);
if (!(strlen(itemtext) && strlen(text))) return;
if (!(strlen(itemtext) && strlen(tx.text))) return;
for (i = 0, highlight = itemtext; *highlight && text[i];) {
if (((fuzzy && !fstrncmp(&(*highlight), &text[i], 1)) || (!fuzzy && *highlight == text[i]))) {
for (i = 0, highlight = itemtext; *highlight && tx.text[i];) {
if (((fuzzy && !fstrncmp(&(*highlight), &tx.text[i], 1)) || (!fuzzy && *highlight == tx.text[i]))) {
c = *highlight;
*highlight = '\0';
indent = TEXTW(itemtext) - lrpad;
indent = TEXTW(itemtext) - sp.lrpad;
*highlight = c;
// highlight character
c = highlight[1];
highlight[1] = '\0';
drw_text(
drw,
draw_text(
draw,
x + indent + (p),
y,
MIN(w - indent - lrpad, TEXTW(highlight) - lrpad),
bh, 0, highlight, 0, pango_highlight ? True : False,
MIN(w - indent - sp.lrpad, TEXTW(highlight) - sp.lrpad),
sp.bh, 0, highlight, 0, pango_highlight ? True : False,
item == sel ? col_hlselfg : col_hlnormfg,
item == sel ? col_hlselbg : col_hlnormbg,
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) {
char buffer[MAXITEMLENGTH]; // buffer containing item text
int leftpadding = lrpad / 2; // padding
int leftpadding = sp.lrpad / 2; // padding
int wr, rd; // character
int fg = 7; // foreground
int bg = 0; // background
@ -118,9 +118,9 @@ int drawitemtext(struct item *item, int x, int y, int w) {
if (!hidepowerline && powerlineitems && selitem) {
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 {
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);
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);
drawhighlights(item, x, y, MIN(w, TEXTW(buffer) - lrpad) + leftpadding, leftpadding, isrtl ? fribidi_text : buffer);
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) - sp.lrpad) + leftpadding, leftpadding, isrtl ? fribidi_text : buffer);
// position and width
x += MIN(w, TEXTW(buffer) - lrpad) + leftpadding;
w -= MIN(w, TEXTW(buffer) - lrpad) + leftpadding;
x += MIN(w, TEXTW(buffer) - sp.lrpad) + leftpadding;
w -= MIN(w, TEXTW(buffer) - sp.lrpad) + leftpadding;
// no highlighting if colored text
leftpadding = 0;
@ -255,7 +255,7 @@ int drawitemtext(struct item *item, int x, int y, int w) {
// now draw any non-colored text
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);
// 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 (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 {
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) {
struct item *item;
int numberWidth = 0;
int modeWidth = 0;
int larrowWidth = 0;
int rarrowWidth = 0;
int capsWidth = 0;
int numberw = 0;
int modew = 0;
int larroww = 0;
int rarroww = 0;
int capsw = 0;
// add width
if (!hidelarrow) larrowWidth = pango_leftarrow ? TEXTWM(leftarrow) : TEXTW(leftarrow);
if (!hiderarrow) rarrowWidth = pango_rightarrow ? TEXTWM(rightarrow) : TEXTW(rightarrow);
if (!hidemode) modeWidth = pango_mode ? TEXTWM(modetext) : TEXTW(modetext);
if (!hiderarrow) rarrowWidth = pango_rightarrow ? TEXTWM(rightarrow) : TEXTW(rightarrow);
if (!hidematchcount) numberWidth = pango_numbers ? TEXTWM(numbers) : TEXTW(numbers);
if (!hidecaps) capsWidth = pango_caps ? TEXTWM(capstext) : TEXTW(capstext);
if (!hidelarrow) larroww = pango_leftarrow ? TEXTWM(leftarrow) : TEXTW(leftarrow);
if (!hiderarrow) rarroww = pango_rightarrow ? TEXTWM(rightarrow) : TEXTW(rightarrow);
if (!hidemode) modew = pango_mode ? TEXTWM(tx.modetext) : TEXTW(tx.modetext);
if (!hiderarrow) rarroww = pango_rightarrow ? TEXTWM(rightarrow) : TEXTW(rightarrow);
if (!hidematchcount) numberw = pango_numbers ? TEXTWM(tx.numbers) : TEXTW(tx.numbers);
if (!hidecaps) capsw = pango_caps ? TEXTWM(tx.capstext) : TEXTW(tx.capstext);
if (!strcmp(capstext, ""))
capsWidth = 0;
if (!strcmp(tx.capstext, ""))
capsw = 0;
#if USEIMAGE
int ox = 0; // original x position
@ -304,7 +304,7 @@ int drawitem(int x, int y, int w) {
// draw image first
#if USEIMAGE
if (!hideimage && longestedge != 0) {
if (!hideimage && img.longestedge != 0) {
rx = ox;
rx += MAX((imagegaps * 2) + imagewidth + menumarginh, indentitems ? x : 0);
} else
@ -321,13 +321,13 @@ int drawitem(int x, int y, int w) {
for (item = curr; item != next; item = item->right, i++) {
x = drawitemtext(
item,
rx + menumarginh + ((i / lines) * ((mw - rx) / columns)) + (powerlineitems ? plw : 0),
y + (((i % lines) + 1) * bh),
(mw - rx) / columns - (powerlineitems ? 2 * plw : 0) - (2 * menumarginh)
rx + menumarginh + ((i / lines) * ((sp.mw - rx) / columns)) + (powerlineitems ? sp.plw : 0),
y + (((i % lines) + 1) * sp.bh),
(sp.mw - rx) / columns - (powerlineitems ? 2 * sp.plw : 0) - (2 * menumarginh)
);
if (item == sel && itemoverride) {
itemnumber = i;
sp.itemnumber = i;
itemoverride = 0;
}
@ -336,30 +336,30 @@ int drawitem(int x, int y, int w) {
// horizontal list
} else if (matches) {
x += inputw;
x += sp.inputw;
if (!hidelarrow) {
w = larrowWidth;
w = larroww;
x = drawlarrow(x, y, w);
}
itemnumber = 0;
sp.itemnumber = 0;
int itemoverride = 1;
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),
mw - x -
rarrowWidth -
numberWidth -
modeWidth -
capsWidth -
x = drawitemtext(item, x + (powerlineitems ? sp.plw : 0), y, MIN(pango_item ? TEXTWM(item->text) : TEXTW(item->text),
sp.mw - x -
rarroww -
numberw -
modew -
capsw -
menumarginh -
2 * sp -
2 * sp.sp -
2 * borderwidth
));
if (itemoverride) {
itemnumber++;
sp.itemnumber++;
}
if (item == sel) {
@ -368,8 +368,8 @@ int drawitem(int x, int y, int w) {
}
if (!hiderarrow) {
w = rarrowWidth + numberWidth + modeWidth + capsWidth + menumarginh + 2 * sp + 2 * borderwidth;
x = drawrarrow(mw - w, y, w);
w = rarroww + numberw + modew + capsw + menumarginh + 2 * sp.sp + 2 * borderwidth;
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) {
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 (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 {
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 fp = caretpadding;
if (fh > bh) {
fh = bh;
if (fh > sp.bh) {
fh = sp.bh;
} else if (!fh) {
fh = drw->font->h;
fh = draw->font->h;
}
if (passwd) {
censort = ecalloc(1, sizeof(text));
censort = ecalloc(1, sizeof(tx.text));
for (int i = 0; i < strlen(text); i++)
memcpy(&censort[i], password, strlen(text));
for (int i = 0; i < strlen(tx.text); i++)
memcpy(&censort[i], password, strlen(tx.text));
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);
} else if (!passwd) {
apply_fribidi(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);
apply_fribidi(tx.text);
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;
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;
@ -438,7 +438,7 @@ int drawlarrow(int x, int y, int w) {
if (hidelarrow) return x;
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;
}
@ -449,7 +449,7 @@ int drawrarrow(int x, int y, int w) {
if (hiderarrow) return x;
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;
}
@ -462,20 +462,20 @@ int drawnumber(int x, int y, int w) {
int powerlinewidth = 0;
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
if (!hidepowerline && powerlinecount) {
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 {
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;
@ -486,24 +486,24 @@ int drawmode(int x, int y, int w) {
int powerlinewidth = 0;
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
if (!hidepowerline && powerlinemode) {
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 ? alpha_menu : alpha_numbg, alpha_modebg);
} 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 ? 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;
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
if (!hidepowerline && powerlinecaps) {
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 ? alpha_menu : alpha_numbg : alpha_modebg, alpha_capsbg);
} 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 ? alpha_menu : alpha_numbg : alpha_modebg, alpha_capsbg);
}
x += plw;
x += sp.plw;
}
}
@ -556,7 +556,7 @@ void drawmenu(void) {
resizeclient();
match();
for (int i = 0; i < itemnumber; i++) {
for (int i = 0; i < sp.itemnumber; i++) {
if (sel && sel->right && (sel = sel->right) == next) {
curr = next;
}
@ -580,26 +580,26 @@ void drawmenu(void) {
void drawmenu_layer(void) {
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
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 modeWidth = 0;
int capsWidth = 0;
int numberw = 0;
int modew = 0;
int capsw = 0;
// add width
if (!hidemode) modeWidth = pango_mode ? TEXTWM(modetext) : TEXTW(modetext);
if (!hidecaps) capsWidth = pango_caps ? TEXTWM(capstext) : TEXTW(capstext);
if (!hidemode) modew = pango_mode ? TEXTWM(tx.modetext) : TEXTW(tx.modetext);
if (!hidecaps) capsw = pango_caps ? TEXTWM(tx.capstext) : TEXTW(tx.capstext);
if (!strcmp(capstext, ""))
capsWidth = 0;
if (!strcmp(tx.capstext, ""))
capsw = 0;
// calculate match count
if (!hidematchcount) {
recalculatenumbers();
numberWidth = TEXTW(numbers);
numberw = TEXTW(tx.numbers);
}
x += menumarginh;
@ -608,45 +608,45 @@ void drawmenu_layer(void) {
calcoffsets();
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) {
y -= bh;
y -= sp.bh;
}
if (!hideprompt && !fullscreen) {
w = promptw;
w = sp.promptw;
x = drawprompt(x, y, w);
}
if (!hideinput && !fullscreen) {
w = (lines > 0 || !matches) ? mw - x : inputw;
w = (lines > 0 || !matches) ? sp.mw - x : sp.inputw;
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()
if (!hideitem) drawitem(x, y, w);
if (!hidematchcount && !fullscreen) {
w = numberWidth;
drawnumber(mw - numberWidth - modeWidth - capsWidth - 2 * sp - 2 * borderwidth - menumarginh, y, w);
w = numberw;
drawnumber(sp.mw - numberw - modew - capsw - 2 * sp.sp - 2 * borderwidth - menumarginh, y, w);
}
if (!hidemode && !fullscreen) {
w = modeWidth;
drawmode(mw - modeWidth - capsWidth - 2 * sp - 2 * borderwidth - menumarginh, y, w);
w = modew;
drawmode(sp.mw - modew - capsw - 2 * sp.sp - 2 * borderwidth - menumarginh, y, w);
}
if (!hidecaps && !fullscreen) {
w = capsWidth;
drawcaps(mw - capsWidth - 2 * sp - 2 * borderwidth - menumarginh, y, w);
w = capsw;
drawcaps(sp.mw - capsw - 2 * sp.sp - 2 * borderwidth - menumarginh, y, w);
}
#if USEX
#if USEIMAGE
drawimage();
#endif
drw_map(drw, win, 0, 0, mw, mh);
draw_map(draw, win, 0, 0, sp.mw, sp.mh);
#endif
}

View file

@ -39,72 +39,72 @@ void cairo_set_source_hex(cairo_t* cr, const char *col, int alpha) {
}
#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) {
Drw *drw = ecalloc(1, sizeof(Drw));
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) {
Draw_t *draw = ecalloc(1, sizeof(Draw_t));
drw->protocol = protocol;
drw->dpy = dpy;
drw->screen = screen;
drw->root = root;
drw->w = w;
drw->h = h;
drw->visual = visual;
drw->depth = depth;
drw->cmap = cmap;
drw->drawable = XCreatePixmap(dpy, root, w, h, depth);
drw->gc = XCreateGC(dpy, drw->drawable, 0, NULL);
XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter);
draw->protocol = protocol;
draw->dpy = dpy;
draw->screen = screen;
draw->root = root;
draw->w = w;
draw->h = h;
draw->visual = visual;
draw->depth = depth;
draw->cmap = cmap;
draw->drawable = XCreatePixmap(dpy, root, w, h, depth);
draw->gc = XCreateGC(dpy, draw->drawable, 0, NULL);
XSetLineAttributes(dpy, draw->gc, 1, LineSolid, CapButt, JoinMiter);
return drw;
return draw;
}
#endif
#if USEWAYLAND
Drw *drw_create_wl(int protocol) {
Drw *drw = ecalloc(1, sizeof(Drw));
Draw_t *draw_create_wl(int protocol) {
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) {
drw->data = data;
drw->w = w;
drw->h = h;
drw->surface = cairo_image_surface_create_for_data(drw->data, CAIRO_FORMAT_ARGB32, drw->w, drw->h, drw->w * 4);
drw->d = cairo_create(drw->surface);
void draw_create_surface_wl(Draw_t *draw, void *data, int32_t w, int32_t h) {
draw->data = data;
draw->w = w;
draw->h = h;
draw->surface = cairo_image_surface_create_for_data(draw->data, CAIRO_FORMAT_ARGB32, draw->w, draw->h, draw->w * 4);
draw->d = cairo_create(draw->surface);
}
#endif
void drw_resize(Drw *drw, unsigned int w, unsigned int h) {
if (!drw)
void draw_resize(Draw_t *draw, unsigned int w, unsigned int h) {
if (!draw)
return;
drw->w = w;
drw->h = h;
draw->w = w;
draw->h = h;
#if USEX
if (drw->drawable)
XFreePixmap(drw->dpy, drw->drawable);
if (draw->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
}
void drw_free(Drw *drw) {
void draw_free(Draw_t *draw) {
#if USEX
if (!drw->protocol) {
XFreePixmap(drw->dpy, drw->drawable);
XFreeGC(drw->dpy, drw->gc);
if (!draw->protocol) {
XFreePixmap(draw->dpy, draw->drawable);
XFreeGC(draw->dpy, draw->gc);
}
#endif
drw_font_free(drw->font);
free(drw);
draw_font_free(draw->font);
free(draw);
}
static Fnt *font_create(Drw *drw, const char *fontname) {
static Fnt *font_create(Draw_t *draw, const char *fontname) {
Fnt *font;
PangoFontMap *fontmap;
PangoContext *context;
@ -116,7 +116,7 @@ static Fnt *font_create(Drw *drw, const char *fontname) {
}
font = ecalloc(1, sizeof(Fnt));
font->dpy = drw->dpy;
font->dpy = draw->dpy;
fontmap = pango_cairo_font_map_new();
context = pango_font_map_create_context(fontmap);
@ -141,25 +141,25 @@ void font_free(Fnt *font) {
free(font);
}
Fnt* drw_font_create(Drw* drw, char *font[], size_t fontcount) {
if (!drw || !font)
Fnt* draw_font_create(Draw_t* draw, char *font[], size_t fontcount) {
if (!draw || !font)
return 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) {
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) {
if (!drw)
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 (!draw)
return;
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;
if (drw->protocol) {
sf = cairo_image_surface_create_for_data(drw->data, CAIRO_FORMAT_ARGB32, drw->w, drw->h, drw->w * 4);
if (draw->protocol) {
sf = cairo_image_surface_create_for_data(draw->data, CAIRO_FORMAT_ARGB32, draw->w, draw->h, draw->w * 4);
} 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);
@ -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);
}
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) {
if (!drw)
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 (!draw)
return;
cairo_surface_t *sf = NULL;
if (drw->protocol) {
sf = cairo_image_surface_create_for_data(drw->data, CAIRO_FORMAT_ARGB32, drw->w, drw->h, drw->w * 4);
if (draw->protocol) {
sf = cairo_image_surface_create_for_data(draw->data, CAIRO_FORMAT_ARGB32, draw->w, draw->h, draw->w * 4);
} 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);
@ -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);
}
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) {
if (!drw) {
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 (!draw) {
return;
}
cairo_surface_t *sf;
if (drw->protocol) {
sf = cairo_image_surface_create_for_data(drw->data, CAIRO_FORMAT_ARGB32, drw->w, drw->h, drw->w * 4);
if (draw->protocol) {
sf = cairo_image_surface_create_for_data(draw->data, CAIRO_FORMAT_ARGB32, draw->w, draw->h, draw->w * 4);
} 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);
@ -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);
}
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];
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;
char *t;
if (!drw || !text || !drw->font) {
if (!draw || !text || !draw->font) {
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;
w -= lpad;
if (drw->protocol) {
drw->surface = cairo_image_surface_create_for_data(drw->data, CAIRO_FORMAT_ARGB32, drw->w, drw->h, drw->w * 4);
if (draw->protocol) {
draw->surface = cairo_image_surface_create_for_data(draw->data, CAIRO_FORMAT_ARGB32, draw->w, draw->h, draw->w * 4);
} 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
cairo_set_source_hex(drw->d, invert ? fgcol : bgcol, invert ? fgalpha : bgalpha);
cairo_set_operator(drw->d, CAIRO_OPERATOR_SOURCE);
cairo_rectangle(drw->d, x - lpad, y, w + lpad, h);
cairo_fill(drw->d);
cairo_set_source_hex(draw->d, invert ? fgcol : bgcol, invert ? fgalpha : bgalpha);
cairo_set_operator(draw->d, CAIRO_OPERATOR_SOURCE);
cairo_rectangle(draw->d, x - lpad, y, w + lpad, h);
cairo_fill(draw->d);
}
t = strdup(text);
len = strlen(t);
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
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--;
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 (markup) {
pango_layout_set_markup(drw->font->layout, buf, len);
pango_layout_set_markup(draw->font->layout, buf, len);
} 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
cairo_set_source_hex(drw->d, fgcol, fgalpha);
cairo_move_to(drw->d, x, y + (h - drw->font->h) / 2);
cairo_set_source_hex(draw->d, fgcol, fgalpha);
cairo_move_to(draw->d, x, y + (h - draw->font->h) / 2);
// update and show layout
pango_cairo_update_layout(drw->d, drw->font->layout);
pango_cairo_show_layout(drw->d, drw->font->layout);
pango_cairo_update_layout(draw->d, draw->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
pango_layout_set_attributes(drw->font->layout, NULL);
pango_layout_set_attributes(draw->font->layout, NULL);
}
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);
}
void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h) {
if (!drw)
void draw_map(Draw_t *draw, Window win, int x, int y, unsigned int w, unsigned int h) {
if (!draw)
return;
#if USEX
if (!drw->protocol) {
XCopyArea(drw->dpy, drw->drawable, win, drw->gc, x, y, w, h, x, y);
XSync(drw->dpy, False);
if (!draw->protocol) {
XCopyArea(draw->dpy, draw->drawable, win, draw->gc, x, y, w, h, x, y);
XSync(draw->dpy, False);
}
#endif
}
unsigned int drw_font_getwidth(Drw *drw, const char *text, Bool markup) {
if (!drw || !drw->font || !text)
unsigned int draw_font_getwidth(Draw_t *draw, const char *text, Bool markup) {
if (!draw || !draw->font || !text)
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)
return;
@ -395,31 +395,31 @@ void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned in
*h = font->h;
}
void drw_set_img(Drw *drw, void *data, int w, int h) {
if (!w || !h || !drw) {
void draw_set_img(Draw_t *draw, void *data, int w, int h) {
if (!w || !h || !draw) {
return;
}
drw->img_data = data;
drw->img_surface = cairo_image_surface_create_for_data(drw->img_data, CAIRO_FORMAT_ARGB32, w, h, w * 4);
draw->img_data = data;
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) {
if (!drw) {
void draw_img(Draw_t *draw, int x, int y) {
if (!draw) {
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_mask_surface(drw->d, drw->img_surface, x, y);
cairo_set_source_surface(draw->d, draw->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;
if (drw && drw->font && text && n)
tmp = drw_text(drw, 0, 0, 0, 0, 0, text, n, markup, "#000000", "#000000", 255, 255);
if (draw && draw->font && text && n)
tmp = draw_text(draw, 0, 0, 0, 0, 0, text, n, markup, "#000000", "#000000", 255, 255);
return MIN(n, tmp);
}

View file

@ -30,37 +30,37 @@ typedef struct {
cairo_surface_t *img_surface;
cairo_t *d;
cairo_t *img_d;
} Drw;
} Draw_t;
/* Cairo color convertion */
void cairo_set_source_hex(cairo_t* cr, const char *col, int alpha);
/* Cairo image drawing */
void drw_img(Drw *drw, int x, int y);
void drw_set_img(Drw *drw, void *data, int w, int h);
void draw_img(Draw_t *draw, int x, int y);
void draw_set_img(Draw_t *draw, void *data, int w, int h);
/* 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);
Drw *drw_create_wl(int protocol);
void drw_create_surface_wl(Drw *drw, void *data, int32_t w, int32_t h);
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);
Draw_t *draw_create_wl(int protocol);
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 drw_free(Drw *drw);
void draw_resize(Draw_t *draw, unsigned int w, unsigned int h);
void draw_free(Draw_t *draw);
/* Fnt abstraction */
Fnt *drw_font_create(Drw* drw, char *font[], size_t fontcount);
void drw_font_free(Fnt* set);
unsigned int drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n, Bool markup);
unsigned int drw_font_getwidth(Drw *drw, 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);
Fnt *draw_font_create(Draw_t* draw, char *font[], size_t fontcount);
void draw_font_free(Fnt* set);
unsigned int draw_fontset_getwidth_clamp(Draw_t *draw, const char *text, unsigned int n, Bool markup);
unsigned int draw_font_getwidth(Draw_t *draw, const char *text, Bool markup);
void draw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h, Bool markup);
/* 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);
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);
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 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 */
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 */
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 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_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 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;
if (histsz == histpos) {
strncpy(def, text, sizeof(def));
strncpy(def, tx.text, sizeof(def));
}
switch (dir) {
@ -83,8 +83,8 @@ void navigatehistfile(int dir) {
}
len = MIN(strlen(p), BUFSIZ - 1);
sp_strncpy(text, p, sizeof(text));
text[len] = '\0';
cursor = len;
sp_strncpy(tx.text, p, sizeof(tx.text));
tx.text[len] = '\0';
sp.cursor = len;
match();
}

View file

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

View file

@ -7,7 +7,7 @@ void fuzzymatch(void) {
lhpprefix = hpprefixend = NULL;
char c;
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;
@ -21,7 +21,7 @@ void fuzzymatch(void) {
// walk through item text
for (i = 0; i < itext_len && (c = it->text[i]); i++) {
// fuzzy match pattern
if (!fstrncmp(&text[pidx], &c, 1)) {
if (!fstrncmp(&tx.text[pidx], &c, 1)) {
if(sidx == -1)
sidx = i;
pidx++;
@ -92,13 +92,13 @@ void match(void) {
static char **tokv = NULL;
static int tokn = 0;
char buf[sizeof text], *s;
char buf[sizeof tx.text], *s;
int i, tokc = 0;
size_t len, textsize;
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
for (s = strtok(buf, " "); s; tokv[tokc - 1] = s, s = strtok(NULL, " "))
if (++tokc > tokn && !(tokv = realloc(tokv, ++tokn * sizeof *tokv)))
@ -107,7 +107,7 @@ void match(void) {
len = tokc ? strlen(tokv[0]) : 0;
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 (i = 0; i < tokc; 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
if (item->hp && !fstrncmp(tokv[0], item->text, len))
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);
else if (!fstrncmp(tokv[0], item->text, len))
appenditem(item, &lprefix, &prefixend);

View file

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

View file

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

View file

@ -1,14 +1,16 @@
/* See LICENSE file for copyright and license details. */
void prepare_window_size_wl(void) {
sp = menupaddingh;
vp = (menuposition == 1) ? menupaddingv : - menupaddingv;
sp.sp = menupaddingh;
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);
reallines = lines;
#if USEIMAGE
img.setlines = lines;
#endif
lrpad = drw->font->h + textpadding;
sp.lrpad = draw->font->h + textpadding;
return;
}
@ -19,7 +21,7 @@ void handle_wl(void) {
}
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;
@ -32,15 +34,15 @@ void handle_wl(void) {
create_layer(&state, "spmenu");
mw = (menuwidth > 0 ? menuwidth : output_width);
sp.mw = (menuwidth > 0 ? menuwidth : output_width);
get_mh();
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.height = mh;
state.width = sp.mw;
state.height = sp.mh;
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++) {
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 ((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));
return;
} else if (!wl_keys[i].mode && !curMode) {
} else if (!wl_keys[i].mode && !sp.mode) {
wl_keys[i].func(&(wl_keys[i].arg));
} else {
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++) {
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 ((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));
return;
} else if (!wl_ckeys[i].mode && !curMode) {
} else if (!wl_ckeys[i].mode && !sp.mode) {
wl_ckeys[i].func(&(wl_ckeys[i].arg));
} else {
continue;
@ -120,15 +120,15 @@ void keypress_wl(struct state *state, enum wl_keyboard_key_state key_state, xkb_
return;
}
if (!type || !curMode) {
if (!type || !sp.mode) {
return;
}
if (xkb_keysym_to_utf8(sym, buf, 8)) {
if (allowkeys) {
if (sp.allowkeys) {
insert(buf, strnlen(buf, 8));
} else {
allowkeys = !allowkeys;
sp.allowkeys = !sp.allowkeys;
}
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) {
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);
if (xkb_state_mod_name_is_active(state->xkb_state, XKB_MOD_NAME_CAPS, XKB_STATE_MODS_EFFECTIVE)) {
capslockstate = 1;
sp.capslockstate = 1;
} else {
capslockstate = 0;
sp.capslockstate = 0;
}
if (ocapslockstate != capslockstate) {
strncpy(capstext, capslockstate ? capslockontext : capslockofftext, 15);
if (ocapslockstate != sp.capslockstate) {
strncpy(tx.capstext, sp.capslockstate ? capslockontext : capslockofftext, 15);
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;
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);
keypress_wl(state, key_state, sym);
@ -216,7 +216,7 @@ void buttonpress_wl(uint32_t button, double ex, double ey) {
int x = 0;
int y = 0;
int w;
int h = bh;
int h = sp.bh;
int xpad = 0;
int item_num = 0;
int yp = 0;
@ -227,25 +227,25 @@ void buttonpress_wl(uint32_t button, double ex, double ey) {
}
if (!hidepowerline) {
x = xpad = plw;
x = xpad = sp.plw;
}
x += menumarginh;
int larrowWidth = 0;
int rarrowWidth = 0;
int numberWidth = 0;
int modeWidth = 0;
int capsWidth = 0;
int larroww = 0;
int rarroww = 0;
int numberw = 0;
int modew = 0;
int capsw = 0;
if (!hidelarrow) larrowWidth = pango_leftarrow ? TEXTWM(leftarrow) : TEXTW(leftarrow);
if (!hiderarrow) rarrowWidth = pango_rightarrow ? TEXTWM(rightarrow) : TEXTW(rightarrow);
if (!hidematchcount) numberWidth = pango_numbers ? TEXTWM(numbers) : TEXTW(numbers);
if (!hidemode) modeWidth = pango_mode ? TEXTWM(modetext) : TEXTW(modetext);
if (!hidecaps) capsWidth = pango_caps ? TEXTWM(capstext) : TEXTW(capstext);
if (!hidelarrow) larroww = pango_leftarrow ? TEXTWM(leftarrow) : TEXTW(leftarrow);
if (!hiderarrow) rarroww = pango_rightarrow ? TEXTWM(rightarrow) : TEXTW(rightarrow);
if (!hidematchcount) numberw = pango_numbers ? TEXTWM(tx.numbers) : TEXTW(tx.numbers);
if (!hidemode) modew = pango_mode ? TEXTWM(tx.modetext) : TEXTW(tx.modetext);
if (!hidecaps) capsw = pango_caps ? TEXTWM(tx.capstext) : TEXTW(tx.capstext);
if (!strcmp(capstext, ""))
capsWidth = 0;
if (!strcmp(tx.capstext, ""))
capsw = 0;
if ((hideprompt && hideinput && hidemode && hidematchcount && hidecaps) && lines) {
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
// 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;
} 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;
} 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;
} 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;
} 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 +
((!prev || !curr->left) ? larrowWidth : 0)) ||
if ((lines <= 0 && ex >= 0 && ex <= x + w + sp.promptw +
((!prev || !curr->left) ? larroww : 0)) ||
(lines > 0 && ey >= y && ey <= y + h)) {
click = ClickInput;
@ -278,14 +278,14 @@ void buttonpress_wl(uint32_t button, double ex, double ey) {
}
#if USEIMAGE
if (!hideimage && longestedge != 0) {
x += MAX((imagegaps * 2) + imagewidth, indentitems ? promptw : 0);
if (!hideimage && img.longestedge != 0) {
x += MAX((imagegaps * 2) + imagewidth, indentitems ? sp.promptw : 0);
}
#endif
// item click
if (lines > 0) {
w = mw - x;
w = sp.mw - x;
ey -= menumarginv;
@ -303,9 +303,9 @@ void buttonpress_wl(uint32_t button, double ex, double ey) {
y += h;
// ClickSelItem, called function doesn't matter
if (ey >= y && ey <= (y + h) && ex >= x + (powerlineitems ? plw : 0) && ex <= (x + w / columns) + (powerlineitems ? plw : 0)) {
for (i = 0; i < LENGTH(buttons); i++) {
if (ignoreglobalmouse) break;
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(wl_buttons); i++) {
if (sp.ignoreglobalmouse) break;
if (wl_buttons[i].click == ClickSelItem && wl_buttons[i].button == button) {
puts(item->text);
exit(0);
@ -313,8 +313,8 @@ void buttonpress_wl(uint32_t button, double ex, double ey) {
click = ClickItem;
}
}
for (i = 0; i < LENGTH(cbuttons); i++) {
if (ignoreconfmouse) break;
for (i = 0; i < LENGTH(wl_cbuttons); i++) {
if (sp.ignoreconfmouse) break;
if (wl_cbuttons[i].click == ClickSelItem && wl_cbuttons[i].button == button) {
puts(item->text);
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
x += inputw;
w = larrowWidth;
x += sp.inputw;
w = larroww;
if (prev && curr->left) {
if (ex >= x && ex <= x + w) {
@ -335,8 +335,8 @@ void buttonpress_wl(uint32_t button, double ex, double ey) {
}
// right arrow
w = rarrowWidth;
x = mw - w;
w = rarroww;
x = sp.mw - w;
if (next && ex >= x && ex <= x + w) {
click = ClickRArrow;
}
@ -344,14 +344,14 @@ void buttonpress_wl(uint32_t button, double ex, double ey) {
// go through mouse button array and run function
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)
wl_buttons[i].func(&wl_buttons[i].arg);
}
// go through mouse config array and run function
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)
wl_cbuttons[i].func(&wl_cbuttons[i].arg);
}
@ -429,15 +429,15 @@ void draw_sf(struct state *state) {
// create buffer to draw on
state->buffer = create_buffer(state);
if (drw == NULL) {
die("spmenu: drw == NULL");
if (draw == NULL) {
die("spmenu: draw == NULL");
}
if (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();
@ -533,40 +533,42 @@ int init_disp(struct state *state) {
void resizeclient_wl(struct state *state) {
struct item *item;
int omh = mh;
int mh = sp.mh;
int ic = 0;
// walk through all items
for (item = items; item && item->text; item++)
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));
reallines = lines;
#if USEIMAGE
img.setlines = lines;
#endif
get_mh();
if (hideprompt && hideinput && hidemode && hidematchcount && hidecaps) {
mh -= bh;
sp.mh -= sp.bh;
}
if (mh == omh) {
if (sp.mh == mh) {
return;
}
state->width = mw;
state->height = mh;
state->width = sp.mw;
state->height = sp.mh;
state->buffer = create_buffer(state);
if (drw == NULL) {
die("spmenu: drw == NULL");
if (draw == NULL) {
die("spmenu: draw == NULL");
}
if (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);
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.background_pixel = 0;
swa.colormap = cmap;
swa.colormap = x11.cmap;
swa.event_mask =
ExposureMask | // mapping the drawing
KeyPressMask | // keypresses
@ -25,7 +25,7 @@ void create_window_x11(int x, int y, int w, int h) {
// create client
win = XCreateWindow(dpy, root, x, y, w, h, borderwidth,
depth, InputOutput, visual,
x11.depth, InputOutput, x11.visual,
CWOverrideRedirect|CWBackPixel|CWBorderPixel|CWColormap|CWEventMask, &swa);
return;
@ -45,7 +45,7 @@ void set_window_x11(void) {
col.green = g << 8;
col.blue = b << 8;
if (!XAllocColor(dpy, cmap, &col)) {
if (!XAllocColor(dpy, x11.cmap, &col)) {
die("spmenu: failed to allocate xcolor");
}
@ -70,7 +70,7 @@ void set_prop_x11(void) {
}
void resizeclient_x11(void) {
int omh = mh;
int mh = sp.mh;
int x, y;
#if USEXINERAMA
int j, di, a, n, area = 0;
@ -87,19 +87,19 @@ void resizeclient_x11(void) {
for (item = items; item && item->text; item++)
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));
reallines = lines;
#if USEIMAGE
img.setlines = lines;
// resize client to image height
#if USEIMAGE
if (image) resizetoimageheight(imagewidth, imageheight);
#endif
get_mh();
if (hideprompt && hideinput && hidemode && hidematchcount && hidecaps) {
mh -= bh;
sp.mh -= sp.bh;
}
// init xinerama screens
@ -134,13 +134,13 @@ void resizeclient_x11(void) {
// calculate x/y position
if (menuposition == 2) { // centered
mw = MIN(MAX(max_textw() + promptw, minwidth), info[i].width);
x = info[i].x_org + ((info[i].width - mw) / 2);
y = info[i].y_org + ((info[i].height - mh) / 2);
sp.mw = MIN(MAX(max_textw() + sp.promptw, minwidth), info[i].width);
x = info[i].x_org + ((info[i].width - sp.mw) / 2);
y = info[i].y_org + ((info[i].height - sp.mh) / 2);
} else { // top or bottom
x = info[i].x_org + xpos;
y = info[i].y_org + (menuposition ? 0 : info[i].height - mh - ypos);
mw = (menuwidth>0 ? menuwidth : info[i].width);
y = info[i].y_org + (menuposition ? 0 : info[i].height - sp.mh - ypos);
sp.mw = (menuwidth>0 ? menuwidth : info[i].width);
}
XFree(info);
@ -151,21 +151,21 @@ void resizeclient_x11(void) {
die("spmenu: could not get embedding window attributes: 0x%lx",
parentwin); // die because unable to get attributes for the parent window
if (menuposition == 2) { // centered
mw = MIN(MAX(max_textw() + promptw, minwidth), wa.width);
x = (wa.width - mw) / 2;
y = (wa.height - mh) / 2;
sp.mw = MIN(MAX(max_textw() + sp.promptw, minwidth), wa.width);
x = (wa.width - sp.mw) / 2;
y = (wa.height - sp.mh) / 2;
} else { // top or bottom
x = 0;
y = menuposition ? 0 : wa.height - mh - ypos;
mw = (menuwidth > 0 ? menuwidth : wa.width);
y = menuposition ? 0 : wa.height - sp.mh - ypos;
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
if (!win || omh == mh) return;
if (!win || mh == sp.mh) return;
XMoveResizeWindow(dpy, win, x + sp, y + vp, mw - 2 * sp - borderwidth * 2, mh);
drw_resize(drw, mw - 2 * sp - borderwidth * 2, mh);
XMoveResizeWindow(dpy, win, x + sp.sp, y + sp.vp, sp.mw - 2 * sp.sp - borderwidth * 2, sp.mh);
draw_resize(draw, sp.mw - 2 * sp.sp - borderwidth * 2, sp.mh);
}
void xinitvisual(void) {
@ -176,7 +176,7 @@ void xinitvisual(void) {
// visual properties
XVisualInfo tpl = {
.screen = screen,
.screen = x11.screen,
.depth = 32,
.class = TrueColor
};
@ -184,16 +184,16 @@ void xinitvisual(void) {
long masks = VisualScreenMask | VisualDepthMask | VisualClassMask;
infos = XGetVisualInfo(dpy, masks, &tpl, &nitems);
visual = NULL;
x11.visual = NULL;
// create colormap
for(i = 0; i < nitems; i ++) {
fmt = XRenderFindVisualFormat(dpy, infos[i].visual);
if (fmt->type == PictTypeDirect && fmt->direct.alphaMask) {
visual = infos[i].visual;
depth = infos[i].depth;
cmap = XCreateColormap(dpy, root, visual, AllocNone);
useargb = 1;
x11.visual = infos[i].visual;
x11.depth = infos[i].depth;
x11.cmap = XCreateColormap(dpy, root, x11.visual, AllocNone);
x11.useargb = 1;
break;
}
}
@ -201,9 +201,9 @@ void xinitvisual(void) {
XFree(infos);
// no alpha, reset to default
if (!visual || !alpha) {
visual = DefaultVisual(dpy, screen);
depth = DefaultDepth(dpy, screen);
cmap = DefaultColormap(dpy, screen);
if (!x11.visual || !alpha) {
x11.visual = DefaultVisual(dpy, x11.screen);
x11.depth = DefaultDepth(dpy, x11.screen);
x11.cmap = DefaultColormap(dpy, x11.screen);
}
}

View file

@ -7,7 +7,7 @@ void pastesel_x11(void) {
Atom da;
// 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)
== Success && p) {
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. */
#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)

View file

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

View file

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

View file

@ -4,13 +4,13 @@ void updatenumlockmask(void) {
unsigned int i, j;
XModifierKeymap *modmap;
numlockmask = 0;
x11.numlockmask = 0;
modmap = XGetModifierMapping(dpy);
for (i = 0; i < 8; i++)
for (j = 0; j < modmap->max_keypermod; j++)
if (modmap->modifiermap[i * modmap->max_keypermod + j]
== XKeysymToKeycode(dpy, XK_Num_Lock))
numlockmask = (1 << i);
x11.numlockmask = (1 << i);
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));
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 ((keys[i].mode && curMode) || keys[i].mode == -1) {
if ((keys[i].mode && sp.mode) || keys[i].mode == -1) {
keys[i].func(&(keys[i].arg));
return;
} else if (!keys[i].mode && !curMode) {
} else if (!keys[i].mode && !sp.mode) {
keys[i].func(&(keys[i].arg));
} else {
continue;
@ -50,12 +50,12 @@ void keypress_x11(XEvent *e) {
}
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 ((ckeys[i].mode && curMode) || ckeys[i].mode == -1) {
if ((ckeys[i].mode && sp.mode) || ckeys[i].mode == -1) {
ckeys[i].func(&(ckeys[i].arg));
return;
} else if (!ckeys[i].mode && !curMode) {
} else if (!ckeys[i].mode && !sp.mode) {
ckeys[i].func(&(ckeys[i].arg));
} else {
continue;
@ -63,11 +63,11 @@ void keypress_x11(XEvent *e) {
}
}
if (!iscntrl(*buf) && type && curMode ) {
if (allowkeys) {
if (!iscntrl(*buf) && type && sp.mode ) {
if (sp.allowkeys) {
insert(buf, len);
} else {
allowkeys = !allowkeys;
sp.allowkeys = !sp.allowkeys;
}
drawmenu();
@ -80,7 +80,7 @@ void grabkeyboard_x11(void) {
int i;
// don't grab if embedded
if (embed || managed)
if (x11.embed || managed)
return;
// try to grab keyboard, we may have to wait for another process to ungrab
for (i = 0; i < 1000; i++) {
@ -98,7 +98,7 @@ void getcapsstate(void) {
unsigned int cs = 0;
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) {
struct item *item;
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;
int yp = 0;
// margin
x += menumarginh;
int larrowWidth = 0;
int rarrowWidth = 0;
int numberWidth = 0;
int modeWidth = 0;
int capsWidth = 0;
int larroww = 0;
int rarroww = 0;
int numberw = 0;
int modew = 0;
int capsw = 0;
if (!hidelarrow) larrowWidth = pango_leftarrow ? TEXTWM(leftarrow) : TEXTW(leftarrow);
if (!hiderarrow) rarrowWidth = pango_rightarrow ? TEXTWM(rightarrow) : TEXTW(rightarrow);
if (!hidematchcount) numberWidth = pango_numbers ? TEXTWM(numbers) : TEXTW(numbers);
if (!hidemode) modeWidth = pango_mode ? TEXTWM(modetext) : TEXTW(modetext);
if (!hidecaps) capsWidth = pango_caps ? TEXTWM(capstext) : TEXTW(capstext);
if (!hidelarrow) larroww = pango_leftarrow ? TEXTWM(leftarrow) : TEXTW(leftarrow);
if (!hiderarrow) rarroww = pango_rightarrow ? TEXTWM(rightarrow) : TEXTW(rightarrow);
if (!hidematchcount) numberw = pango_numbers ? TEXTWM(tx.numbers) : TEXTW(tx.numbers);
if (!hidemode) modew = pango_mode ? TEXTWM(tx.modetext) : TEXTW(tx.modetext);
if (!hidecaps) capsw = pango_caps ? TEXTWM(tx.capstext) : TEXTW(tx.capstext);
if (!strcmp(capstext, ""))
capsWidth = 0;
if (!strcmp(tx.capstext, ""))
capsw = 0;
if ((hideprompt && hideinput && hidemode && hidematchcount && hidecaps) && lines) {
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
// 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;
} 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;
} 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;
} 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;
} 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 +
((!prev || !curr->left) ? larrowWidth : 0)) ||
if ((lines <= 0 && ev->x >= 0 && ev->x <= x + w + sp.promptw +
((!prev || !curr->left) ? larroww : 0)) ||
(lines > 0 && ev->y >= y && ev->y <= y + h)) {
click = ClickInput;
@ -58,14 +58,14 @@ void buttonpress_x11(XEvent *e) {
}
#if USEIMAGE
if (!hideimage && longestedge != 0) {
x += MAX((imagegaps * 2) + imagewidth, indentitems ? promptw : 0);
if (!hideimage && img.longestedge != 0) {
x += MAX((imagegaps * 2) + imagewidth, indentitems ? sp.promptw : 0);
}
#endif
// item click
if (lines > 0) {
w = mw - x;
w = sp.mw - x;
ev->y -= menumarginv;
@ -83,9 +83,9 @@ void buttonpress_x11(XEvent *e) {
y += h;
// 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++) {
if (ignoreglobalmouse) break;
if (sp.ignoreglobalmouse) break;
if (buttons[i].click == ClickSelItem && buttons[i].button == ev->button) {
puts(item->text);
exit(0);
@ -94,7 +94,7 @@ void buttonpress_x11(XEvent *e) {
}
}
for (i = 0; i < LENGTH(cbuttons); i++) {
if (ignoreconfmouse) break;
if (sp.ignoreconfmouse) break;
if (cbuttons[i].click == ClickSelItem && cbuttons[i].button == ev->button) {
puts(item->text);
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
x += inputw;
w = larrowWidth;
x += sp.inputw;
w = larroww;
if (prev && curr->left) {
if (ev->x >= x && ev->x <= x + w) {
@ -115,8 +115,8 @@ void buttonpress_x11(XEvent *e) {
}
// right arrow
w = rarrowWidth;
x = mw - w;
w = rarroww;
x = sp.mw - w;
if (next && ev->x >= x && ev->x <= x + w) {
click = ClickRArrow;
}
@ -124,14 +124,14 @@ void buttonpress_x11(XEvent *e) {
// go through mouse button array and run function
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)
buttons[i].func(&buttons[i].arg);
}
// go through mouse config array and run function
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)
cbuttons[i].func(&cbuttons[i].arg);
}

351
spmenu.c
View file

@ -80,139 +80,14 @@
#include <openssl/md5.h>
#endif
// include Xlib
#if USEX
#include <X11/Xlib.h>
#endif
// include macros and other defines
#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 {
ClickWindow,
ClickPrompt,
@ -226,12 +101,152 @@ enum {
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
#include "libs/options.h"
#include "libs/keybinds.h"
#include "libs/mouse.h"
static char capstext[16];
static char *fonts[] = { font };
// color array
@ -310,9 +325,9 @@ void recalculatenumbers(void) {
}
if (selected) {
snprintf(numbers, NUMBERSBUFSIZE, "%d/%d/%d", numer, denom, selected);
snprintf(tx.numbers, NUMBERSBUFSIZE, "%d/%d/%d", numer, denom, selected);
} 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;
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
int numberWidth = 0;
int numberw = 0;
int modeWidth = 0;
int larrowWidth = 0;
int larroww = 0;
int rarrowWidth = 0;
int capsWidth = 0;
int capsw = 0;
if (!hidematchcount) numberWidth = pango_numbers ? TEXTWM(numbers) : TEXTW(numbers);
if (!hidemode) modeWidth = pango_mode ? TEXTWM(modetext) : TEXTW(modetext);
if (!hidelarrow) larrowWidth = pango_leftarrow ? TEXTWM(leftarrow) : TEXTW(leftarrow);
if (!hidematchcount) numberw = pango_numbers ? TEXTWM(tx.numbers) : TEXTW(tx.numbers);
if (!hidemode) modeWidth = pango_mode ? TEXTWM(tx.modetext) : TEXTW(tx.modetext);
if (!hidelarrow) larroww = pango_leftarrow ? TEXTWM(leftarrow) : TEXTW(leftarrow);
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, ""))
capsWidth = 0;
if (!strcmp(tx.capstext, ""))
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
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;
// calculate which items will begin the previous page
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;
}
@ -372,7 +387,7 @@ void cleanup(void) {
free(hpitems[i]);
// free drawing and close the display
drw_free(drw);
draw_free(draw);
#if USEX
if (!protocol) {
@ -407,26 +422,26 @@ void grabfocus(void) {
#endif
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;
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
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
if (n > 0 && str && n)
memcpy(&text[cursor], str, n);
memcpy(&tx.text[sp.cursor], str, n);
// add to cursor position and continue matching
cursor += n;
sp.cursor += n;
match();
if (!matches && requirematch) {
memcpy(text, l, BUFSIZ);
cursor -= n;
memcpy(tx.text, l, BUFSIZ);
sp.cursor -= n;
match();
}
}
@ -435,7 +450,7 @@ size_t nextrune(int inc) {
ssize_t n;
// 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;
}
@ -463,15 +478,15 @@ void resizeclient(void) {
}
void get_width(void) {
inputw = mw / 3;
sp.inputw = sp.mw / 3;
}
void get_mh(void) {
mh = (lines + 1) * bh;
mh += 2 * menumarginv;
sp.mh = (lines + 1) * sp.bh;
sp.mh += 2 * menumarginv;
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
if (mode) {
curMode = 1;
allowkeys = 1;
sp.mode = 1;
sp.allowkeys = 1;
sp_strncpy(modetext, instext, sizeof(modetext));
sp_strncpy(tx.modetext, instext, sizeof(tx.modetext));
} else {
curMode = 0;
allowkeys = !curMode;
sp.mode = 0;
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
handle_x11();
if (!drw_font_create(drw, fonts, LENGTH(fonts))) {
if (!draw_font_create(draw, fonts, LENGTH(fonts))) {
die("no fonts could be loaded.");
}
@ -537,9 +552,9 @@ void handle(void) {
borderwidth = 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.");
}