add Mouse array, allowing mouse binds to be easily changed similar to

the Key binds
This commit is contained in:
speedie 2023-04-02 16:10:13 +02:00
parent 3f01a71e0b
commit f1313697dc
7 changed files with 114 additions and 80 deletions

View file

@ -140,7 +140,6 @@ free to add it to this list.</p>
issues!</p> issues!</p>
<h3 id="general">General</h3> <h3 id="general">General</h3>
<ul> <ul>
<li>Key: Mouse bind array (Likely mouse.h).</li>
<li>Config file: Add configuration file using (probably) libconfig, <li>Config file: Add configuration file using (probably) libconfig,
allowing keybinds to be configured without recompiling spmenu.</li> allowing keybinds to be configured without recompiling spmenu.</li>
<li>Image support: Stop using OpenSSL for caching images, mostly because <li>Image support: Stop using OpenSSL for caching images, mostly because

View file

@ -119,7 +119,6 @@ Pull requests would be greatly appreciated for any of these issues!
### General ### General
- Key: Mouse bind array (Likely mouse.h).
- Config file: Add configuration file using (probably) libconfig, allowing - Config file: Add configuration file using (probably) libconfig, allowing
keybinds to be configured without recompiling spmenu. keybinds to be configured without recompiling spmenu.
- Image support: Stop using OpenSSL for caching images, mostly because MD5() - Image support: Stop using OpenSSL for caching images, mostly because MD5()

View file

@ -2,7 +2,7 @@
* *
* Types * 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. * SHIFT is unless changed going to be your Shift key.
* CONTROL is unless changed going to be your Control key. * CONTROL is unless changed going to be your Control key.

View file

@ -17,18 +17,20 @@ motionevent(XButtonEvent *ev)
return; return;
#if USEIMAGE #if USEIMAGE
if (image) return; if (image) return;
#endif #endif
int itemCount = 0; int itemCount = 0;
// walk through all items // walk through all items
for (item = items; item && item->text; item++) for (item = items; item && item->text; item++) {
itemCount++; itemCount++;
}
// to prevent slowdown, arbritary limit of 50 items // to prevent slowdown, arbritary limit of 50 items
if (itemCount > 50) if (itemCount > 50) {
return; return;
}
int larrowWidth = 0; int larrowWidth = 0;
int rarrowWidth = 0; int rarrowWidth = 0;
@ -56,117 +58,105 @@ buttonpress(XEvent *e)
struct item *item; struct item *item;
XButtonPressedEvent *ev = &e->xbutton; XButtonPressedEvent *ev = &e->xbutton;
int x = 0, y = 0, h = bh, w, item_num = 0; int x = 0, y = 0, h = bh, w, item_num = 0;
unsigned int i, click;
int xpad = 0; int xpad = 0;
if (!hidepowerline) { if (!hidepowerline) {
x = xpad = plw; 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 incorrect or wrong window, return
if (ev->window != win) if (ev->window != win)
return; return;
// right-click: exit // clicking anywhere, we use this as a base for a click
if (ev->button == Button3) click = clickwindow;
exit(1);
if (prompt && *prompt) // check if we clicked on the prompt or the input
x += promptw + plw; 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 if ((lines <= 0 && ev->x >= 0 && ev->x <= x + w + promptw +
w = (lines > 0 || !matches) ? mw - x : inputw; ((!prev || !curr->left) ? larrowWidth : 0)) ||
(lines > 0 && ev->y >= y && ev->y <= y + h)) {
// left-click on input: clear input click = clickinput;
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))) { // item click
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;
if (lines > 0) { if (lines > 0) {
// vertical list: (ctrl)left-click on item // vertical list
w = mw - x; w = mw - x;
for (item = curr; item != next; item = item->right) { for (item = curr; item != next; item = item->right) {
if (item_num++ == lines){ if (item_num++ == lines) {
item_num = 1; item_num = 1;
x += w / columns; x += w / columns;
y = 0; y = 0;
} }
y += h; y += h;
if (ev->y >= y && ev->y <= (y + h) &&
ev->x >= x && ev->x <= (x + w / columns)) { if (ev->y >= y && ev->y <= (y + h) && ev->x >= x && ev->x <= (x + w / columns)) {
puts(item->text);
if (!(ev->state & ControlMask)) // TODO: make clickitem a thing
exit(0); if (ev->button != Button1)
sel = item; return;
if (sel) {
drawmenu(); puts(item->text);
} exit(0);
return;
} }
} }
} else if (matches) { } else if (matches) {
// left-click on left arrow // left-click on left arrow
x += inputw; x += inputw;
w = TEXTW(leftarrow); w = larrowWidth;
if (prev && curr->left) { if (prev && curr->left) {
if (ev->x >= x && ev->x <= x + w) { if (ev->x >= x && ev->x <= x + w) {
sel = curr = prev; click = clicklarrow;
calcoffsets();
drawmenu();
return;
} }
} }
// horizontal list: (ctrl)left-click on item // item click
// horizontal list
for (item = curr; item != next; item = item->right) { for (item = curr; item != next; item = item->right) {
x += w; 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) { if (ev->x >= x && ev->x <= x + w) {
puts(item->text); // TODO: make clickitem a thing
if (!(ev->state & ControlMask)) if (ev->button != Button1)
exit(0); return;
sel = item;
if (sel) { puts(item->text);
drawmenu(); exit(0);
}
return;
} }
} }
// left-click on right arrow // left-click on right arrow
w = TEXTW(rightarrow); w = rarrowWidth;
x = mw - w; x = mw - w;
if (next && ev->x >= x && ev->x <= x + w) { if (next && ev->x >= x && ev->x <= x + w) {
sel = curr = next; click = clickrarrow;
calcoffsets();
drawmenu();
return;
} }
} }
// 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);
} }

View file

@ -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 unsigned int textw_clamp(const char *str, unsigned int n);
static void motionevent(XButtonEvent *ev); static void motionevent(XButtonEvent *ev);
static void buttonpress(XEvent *e); static void buttonpress(XEvent *e);

26
mouse.h Normal file
View file

@ -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} },
};

View file

@ -199,6 +199,7 @@ static size_t nextrune(int inc);
// user configuration // user configuration
#include "options.h" #include "options.h"
#include "keybinds.h" #include "keybinds.h"
#include "mouse.h"
// xresources/color arrays // xresources/color arrays
#include "libs/xresources.h" #include "libs/xresources.h"