diff --git a/README.html b/README.html
index 10e16c5..a7ef3b1 100644
--- a/README.html
+++ b/README.html
@@ -140,7 +140,6 @@ free to add it to this list.
issues!
General
-- Key: Mouse bind array (Likely mouse.h).
- Config file: Add configuration file using (probably) libconfig,
allowing keybinds to be configured without recompiling spmenu.
- Image support: Stop using OpenSSL for caching images, mostly because
diff --git a/README.md b/README.md
index 73eac64..2038a36 100644
--- a/README.md
+++ b/README.md
@@ -119,7 +119,6 @@ Pull requests would be greatly appreciated for any of these issues!
### General
-- Key: Mouse bind array (Likely mouse.h).
- Config file: Add configuration file using (probably) libconfig, allowing
keybinds to be configured without recompiling spmenu.
- Image support: Stop using OpenSSL for caching images, mostly because MD5()
diff --git a/keybinds.h b/keybinds.h
index 0ffb658..73a7d04 100644
--- a/keybinds.h
+++ b/keybinds.h
@@ -2,7 +2,7 @@
*
* Types
*
- * MODIFIER1 is what you defined below, default is Super)
+ * MODIFIER1 is what you defined below, default is Alt)
*
* SHIFT is unless changed going to be your Shift key.
* CONTROL is unless changed going to be your Control key.
diff --git a/libs/mouse.c b/libs/mouse.c
index 9559d2e..12e7567 100644
--- a/libs/mouse.c
+++ b/libs/mouse.c
@@ -17,18 +17,20 @@ motionevent(XButtonEvent *ev)
return;
#if USEIMAGE
- if (image) return;
+ if (image) return;
#endif
int itemCount = 0;
// walk through all items
- for (item = items; item && item->text; item++)
+ for (item = items; item && item->text; item++) {
itemCount++;
+ }
// to prevent slowdown, arbritary limit of 50 items
- if (itemCount > 50)
+ if (itemCount > 50) {
return;
+ }
int larrowWidth = 0;
int rarrowWidth = 0;
@@ -56,117 +58,105 @@ buttonpress(XEvent *e)
struct item *item;
XButtonPressedEvent *ev = &e->xbutton;
int x = 0, y = 0, h = bh, w, item_num = 0;
+ unsigned int i, click;
int xpad = 0;
if (!hidepowerline) {
x = xpad = plw;
}
+ int larrowWidth = 0;
+ int rarrowWidth = 0;
+ int numberWidth = 0;
+ int modeWidth = 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 incorrect or wrong window, return
if (ev->window != win)
return;
- // right-click: exit
- if (ev->button == Button3)
- exit(1);
+ // clicking anywhere, we use this as a base for a click
+ click = clickwindow;
- if (prompt && *prompt)
- x += promptw + plw;
+ // check if we clicked on the prompt or the input
+ if (ev->x < x + promptw + plw) {
+ click = clickprompt;
+ } else if (ev->x > mw - modeWidth) {
+ click = clickmode;
+ } else if (ev->x > mw - modeWidth - numberWidth) {
+ click = clicknumber;
+ } else { // actually we clicked on the input
+ w = (lines > 0 || !matches) ? mw - x : inputw;
- // input field
- 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)) {
- // left-click on input: clear input
- if (ev->button == Button1 &&
- ((lines <= 0 && ev->x >= 0 && ev->x <= x + w +
- ((!prev || !curr->left) ? TEXTW(leftarrow) : 0)) ||
- (lines > 0 && ev->y >= y && ev->y <= y + h))) {
- insert(NULL, -cursor);
- drawmenu();
- return;
- }
- // middle-mouse click: paste selection
- if (ev->button == Button2) {
- XConvertSelection(dpy, (ev->state & ShiftMask) ? clip : XA_PRIMARY,
- utf8, utf8, win, CurrentTime);
- drawmenu();
- return;
- }
- // scroll up
- if (ev->button == Button4 && prev) {
- sel = curr = prev;
- calcoffsets();
- drawmenu();
- return;
- }
- // scroll down
- if (ev->button == Button5 && next) {
- sel = curr = next;
- calcoffsets();
- drawmenu();
- return;
- }
- if (ev->button != Button1)
- return;
- if (ev->state & ~ControlMask)
- return;
+ click = clickinput;
+ }
+ }
+
+ // item click
if (lines > 0) {
- // vertical list: (ctrl)left-click on item
+ // vertical list
w = mw - x;
for (item = curr; item != next; item = item->right) {
- if (item_num++ == lines){
+ if (item_num++ == lines) {
item_num = 1;
x += w / columns;
y = 0;
}
+
y += h;
- if (ev->y >= y && ev->y <= (y + h) &&
- ev->x >= x && ev->x <= (x + w / columns)) {
- puts(item->text);
- if (!(ev->state & ControlMask))
- exit(0);
- sel = item;
- if (sel) {
- drawmenu();
- }
- return;
+
+ if (ev->y >= y && ev->y <= (y + h) && ev->x >= x && ev->x <= (x + w / columns)) {
+
+ // TODO: make clickitem a thing
+ if (ev->button != Button1)
+ return;
+
+ puts(item->text);
+ exit(0);
}
}
} else if (matches) {
// left-click on left arrow
x += inputw;
- w = TEXTW(leftarrow);
+ w = larrowWidth;
if (prev && curr->left) {
if (ev->x >= x && ev->x <= x + w) {
- sel = curr = prev;
- calcoffsets();
- drawmenu();
- return;
+ click = clicklarrow;
}
}
- // horizontal list: (ctrl)left-click on item
+ // item click
+ // horizontal list
for (item = curr; item != next; item = item->right) {
x += w;
- w = MIN(TEXTW(item->text), mw - x - TEXTW(rightarrow));
+ w = MIN(TEXTW(item->text), mw - x - rarrowWidth);
if (ev->x >= x && ev->x <= x + w) {
- puts(item->text);
- if (!(ev->state & ControlMask))
- exit(0);
- sel = item;
- if (sel) {
- drawmenu();
- }
- return;
+ // TODO: make clickitem a thing
+ if (ev->button != Button1)
+ return;
+
+ puts(item->text);
+ exit(0);
}
}
// left-click on right arrow
- w = TEXTW(rightarrow);
+ w = rarrowWidth;
x = mw - w;
if (next && ev->x >= x && ev->x <= x + w) {
- sel = curr = next;
- calcoffsets();
- drawmenu();
- return;
+ click = clickrarrow;
}
- }
+ }
+
+ // 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);
}
diff --git a/libs/mouse.h b/libs/mouse.h
index b41736a..edb826d 100644
--- a/libs/mouse.h
+++ b/libs/mouse.h
@@ -1,3 +1,22 @@
+typedef struct {
+ unsigned int click;
+ unsigned int mask;
+ unsigned int button;
+ void (*func)(const Arg *arg);
+ const Arg arg;
+} Mouse;
+
+// clicks
+enum {
+ clickwindow,
+ clickprompt,
+ clickinput,
+ clicklarrow,
+ clickrarrow,
+ clicknumber,
+ clickmode,
+};
+
static unsigned int textw_clamp(const char *str, unsigned int n);
static void motionevent(XButtonEvent *ev);
static void buttonpress(XEvent *e);
diff --git a/mouse.h b/mouse.h
new file mode 100644
index 0000000..283dc9d
--- /dev/null
+++ b/mouse.h
@@ -0,0 +1,26 @@
+/* Mouse bindings
+ *
+ * This header contains mouse binds.
+ * Change them or remove them if you prefer. You can also add more if you want.
+ *
+ * clickwindow: - spmenu window/client
+ * clickinput: - Input box
+ * clickprompt: - Prompt
+ * clicklarrow: - Left arrow
+ * clickrarrow: - Right arrow
+ * clicknumber: - Match count
+ * clickmode: - Mode indicator
+ *
+ * Button1 - Left click
+ * Button2 - Middle click
+ * Button3 - Right click
+ * Button4 - Scroll up
+ * Button5 - Scroll down
+ *
+ * Note that clicking on an item will select it, as of now it's hardcoded.
+ */
+
+static Mouse buttons[] = {
+ { clickinput, 0, Button1, clear, {0} },
+ { clickprompt, 0, Button1, clear, {0} },
+};
diff --git a/spmenu.c b/spmenu.c
index db87454..b6542a4 100644
--- a/spmenu.c
+++ b/spmenu.c
@@ -199,6 +199,7 @@ static size_t nextrune(int inc);
// user configuration
#include "options.h"
#include "keybinds.h"
+#include "mouse.h"
// xresources/color arrays
#include "libs/xresources.h"