2023-03-21 20:52:12 +01:00
|
|
|
unsigned int
|
|
|
|
textw_clamp(const char *str, unsigned int n)
|
|
|
|
{
|
|
|
|
unsigned int w;
|
|
|
|
w = drw_fontset_getwidth_clamp(drw, str, n, True) + lrpad;
|
|
|
|
|
|
|
|
return MIN(w, n);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
motionevent(XButtonEvent *ev)
|
|
|
|
{
|
|
|
|
struct item *item;
|
|
|
|
int xy, ev_xy;
|
|
|
|
|
|
|
|
if (ev->window != win || matches == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
#if USEIMAGE
|
2023-04-02 16:10:13 +02:00
|
|
|
if (image) return;
|
2023-03-21 20:52:12 +01:00
|
|
|
#endif
|
|
|
|
|
|
|
|
int itemCount = 0;
|
|
|
|
|
|
|
|
// walk through all items
|
2023-04-02 16:10:13 +02:00
|
|
|
for (item = items; item && item->text; item++) {
|
2023-03-21 20:52:12 +01:00
|
|
|
itemCount++;
|
2023-04-02 16:10:13 +02:00
|
|
|
}
|
2023-03-21 20:52:12 +01:00
|
|
|
|
|
|
|
// to prevent slowdown, arbritary limit of 50 items
|
2023-04-02 16:10:13 +02:00
|
|
|
if (itemCount > 50) {
|
2023-03-21 20:52:12 +01:00
|
|
|
return;
|
2023-04-02 16:10:13 +02:00
|
|
|
}
|
2023-03-21 20:52:12 +01:00
|
|
|
|
|
|
|
int larrowWidth = 0;
|
|
|
|
int rarrowWidth = 0;
|
2023-04-21 09:49:38 +02:00
|
|
|
int numberWidth = 0;
|
|
|
|
int modeWidth = 0;
|
|
|
|
int capsWidth = 0;
|
2023-03-21 20:52:12 +01:00
|
|
|
|
|
|
|
if (!hidelarrow) larrowWidth = pango_leftarrow ? TEXTWM(leftarrow) : TEXTW(leftarrow);
|
|
|
|
if (!hiderarrow) rarrowWidth = pango_rightarrow ? TEXTWM(rightarrow) : TEXTW(rightarrow);
|
2023-04-21 09:49:38 +02:00
|
|
|
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);
|
2023-03-21 20:52:12 +01:00
|
|
|
|
|
|
|
xy = lines > 0 ? bh : inputw + promptw + larrowWidth;
|
2023-04-16 23:57:02 +02:00
|
|
|
xy += menumarginv;
|
2023-03-21 20:52:12 +01:00
|
|
|
ev_xy = lines > 0 ? ev->y : ev->x;
|
|
|
|
for (item = curr; item && item != next; item = item->right) {
|
2023-04-21 09:49:38 +02:00
|
|
|
int wh = lines > 0 ? bh : textw_clamp(item->text, mw - xy - rarrowWidth - menumarginh - 2 * sp - 2 * borderwidth - numberWidth - modeWidth - capsWidth);
|
2023-03-21 20:52:12 +01:00
|
|
|
if (ev_xy >= xy && ev_xy < (xy + wh)) {
|
|
|
|
sel = item;
|
|
|
|
drawmenu();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
xy += wh;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-03-08 17:20:32 +01:00
|
|
|
void
|
|
|
|
buttonpress(XEvent *e)
|
|
|
|
{
|
|
|
|
struct item *item;
|
|
|
|
XButtonPressedEvent *ev = &e->xbutton;
|
|
|
|
int x = 0, y = 0, h = bh, w, item_num = 0;
|
2023-04-02 16:10:13 +02:00
|
|
|
unsigned int i, click;
|
2023-03-21 16:30:30 +01:00
|
|
|
int xpad = 0;
|
|
|
|
|
|
|
|
if (!hidepowerline) {
|
|
|
|
x = xpad = plw;
|
|
|
|
}
|
2023-03-08 17:20:32 +01:00
|
|
|
|
2023-04-21 09:49:38 +02:00
|
|
|
// margin
|
2023-04-16 23:57:02 +02:00
|
|
|
x += menumarginh;
|
|
|
|
|
2023-04-02 16:10:13 +02:00
|
|
|
int larrowWidth = 0;
|
|
|
|
int rarrowWidth = 0;
|
|
|
|
int numberWidth = 0;
|
|
|
|
int modeWidth = 0;
|
2023-04-20 21:22:45 +02:00
|
|
|
int capsWidth = 0;
|
2023-04-02 16:10:13 +02:00
|
|
|
|
|
|
|
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);
|
2023-04-20 21:22:45 +02:00
|
|
|
if (!hidecaps) capsWidth = pango_caps ? TEXTWM(capstext) : TEXTW(capstext);
|
|
|
|
|
|
|
|
if (!strcmp(capstext, ""))
|
|
|
|
capsWidth = 0;
|
2023-04-02 16:10:13 +02:00
|
|
|
|
2023-03-16 16:54:36 +01:00
|
|
|
// if incorrect or wrong window, return
|
2023-03-08 17:20:32 +01:00
|
|
|
if (ev->window != win)
|
|
|
|
return;
|
|
|
|
|
2023-04-02 16:10:13 +02:00
|
|
|
// clicking anywhere, we use this as a base for a click
|
|
|
|
click = clickwindow;
|
|
|
|
|
|
|
|
// check if we clicked on the prompt or the input
|
2023-04-07 21:20:43 +02:00
|
|
|
if (ev->x < x + promptw + powerlineprompt ? plw : 0) {
|
2023-04-02 16:10:13 +02:00
|
|
|
click = clickprompt;
|
2023-04-21 09:49:38 +02:00
|
|
|
} else if ((ev->x > mw - capsWidth - 2 * sp - 2 * borderwidth - menumarginh) && !hidecaps && capsWidth) {
|
2023-04-20 21:22:45 +02:00
|
|
|
click = clickcaps;
|
2023-04-21 09:49:38 +02:00
|
|
|
} else if (ev->x > mw - modeWidth - capsWidth - 2 * sp - 2 * borderwidth - menumarginh) {
|
2023-04-02 16:10:13 +02:00
|
|
|
click = clickmode;
|
2023-04-21 09:49:38 +02:00
|
|
|
} else if (ev->x > mw - modeWidth - numberWidth - capsWidth - 2 * sp - 2 * borderwidth - menumarginh) {
|
2023-04-02 16:10:13 +02:00
|
|
|
click = clicknumber;
|
|
|
|
} else { // actually we clicked on the input
|
|
|
|
w = (lines > 0 || !matches) ? mw - x : inputw;
|
|
|
|
|
|
|
|
if ((lines <= 0 && ev->x >= 0 && ev->x <= x + w + promptw +
|
|
|
|
((!prev || !curr->left) ? larrowWidth : 0)) ||
|
|
|
|
(lines > 0 && ev->y >= y && ev->y <= y + h)) {
|
|
|
|
|
|
|
|
click = clickinput;
|
|
|
|
}
|
|
|
|
}
|
2023-03-08 17:20:32 +01:00
|
|
|
|
2023-04-02 16:10:13 +02:00
|
|
|
// item click
|
2023-03-08 17:20:32 +01:00
|
|
|
if (lines > 0) {
|
2023-04-02 16:10:13 +02:00
|
|
|
// vertical list
|
2023-03-08 17:20:32 +01:00
|
|
|
w = mw - x;
|
|
|
|
for (item = curr; item != next; item = item->right) {
|
2023-04-02 16:10:13 +02:00
|
|
|
if (item_num++ == lines) {
|
2023-03-08 17:20:32 +01:00
|
|
|
item_num = 1;
|
|
|
|
x += w / columns;
|
|
|
|
y = 0;
|
|
|
|
}
|
2023-04-02 16:10:13 +02:00
|
|
|
|
2023-03-08 17:20:32 +01:00
|
|
|
y += h;
|
2023-04-02 16:10:13 +02:00
|
|
|
|
|
|
|
if (ev->y >= y && ev->y <= (y + h) && ev->x >= x && ev->x <= (x + w / columns)) {
|
2023-04-04 02:28:05 +02:00
|
|
|
for (i = 0; i < LENGTH(buttons); i++) {
|
|
|
|
if (buttons[i].click == clickselitem && buttons[i].button == ev->button && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)) {
|
|
|
|
puts(item->text);
|
|
|
|
exit(0);
|
|
|
|
} else if (buttons[i].click == clickitem) {
|
|
|
|
click = clickitem;
|
|
|
|
}
|
|
|
|
}
|
2023-03-08 17:20:32 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (matches) {
|
2023-03-16 16:54:36 +01:00
|
|
|
// left-click on left arrow
|
2023-03-08 17:20:32 +01:00
|
|
|
x += inputw;
|
2023-04-02 16:10:13 +02:00
|
|
|
w = larrowWidth;
|
2023-03-08 17:20:32 +01:00
|
|
|
if (prev && curr->left) {
|
|
|
|
if (ev->x >= x && ev->x <= x + w) {
|
2023-04-02 16:10:13 +02:00
|
|
|
click = clicklarrow;
|
2023-03-08 17:20:32 +01:00
|
|
|
}
|
|
|
|
}
|
2023-04-02 16:10:13 +02:00
|
|
|
// item click
|
|
|
|
// horizontal list
|
2023-03-08 17:20:32 +01:00
|
|
|
for (item = curr; item != next; item = item->right) {
|
|
|
|
x += w;
|
2023-04-02 16:10:13 +02:00
|
|
|
w = MIN(TEXTW(item->text), mw - x - rarrowWidth);
|
2023-03-08 17:20:32 +01:00
|
|
|
if (ev->x >= x && ev->x <= x + w) {
|
2023-04-04 02:28:05 +02:00
|
|
|
for (i = 0; i < LENGTH(buttons); i++) {
|
|
|
|
if (buttons[i].click == clickselitem && buttons[i].button == ev->button && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)) {
|
|
|
|
puts(item->text);
|
|
|
|
exit(0);
|
|
|
|
} else if (buttons[i].click == clickitem) {
|
|
|
|
click = clickitem;
|
|
|
|
}
|
|
|
|
}
|
2023-04-02 16:10:13 +02:00
|
|
|
|
2023-03-08 17:20:32 +01:00
|
|
|
}
|
|
|
|
}
|
2023-03-16 16:54:36 +01:00
|
|
|
// left-click on right arrow
|
2023-04-02 16:10:13 +02:00
|
|
|
w = rarrowWidth;
|
2023-03-08 17:20:32 +01:00
|
|
|
x = mw - w;
|
|
|
|
if (next && ev->x >= x && ev->x <= x + w) {
|
2023-04-02 16:10:13 +02:00
|
|
|
click = clickrarrow;
|
2023-03-08 17:20:32 +01:00
|
|
|
}
|
2023-04-02 16:10:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// go through mouse button array
|
|
|
|
for (i = 0; i < LENGTH(buttons); i++)
|
|
|
|
if (click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button
|
|
|
|
&& CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state))
|
|
|
|
buttons[i].func(&buttons[i].arg);
|
2023-03-08 17:20:32 +01:00
|
|
|
}
|