From 54797235e1dfa536bdd5269270676fa9ff336202 Mon Sep 17 00:00:00 2001 From: speedie Date: Tue, 25 Apr 2023 16:42:15 +0200 Subject: [PATCH] fix a few issues, add in mouse bindings --- docs/spmenu.conf | 638 ++++++++++++++++++++++++--------------------- libs/conf/config.c | 58 ++++- libs/key.h | 4 +- libs/mouse.c | 28 +- libs/mouse.h | 54 +++- spmenu.c | 2 + 6 files changed, 470 insertions(+), 314 deletions(-) diff --git a/docs/spmenu.conf b/docs/spmenu.conf index 46acdf4..ece359e 100644 --- a/docs/spmenu.conf +++ b/docs/spmenu.conf @@ -213,373 +213,407 @@ spmenu = password = 0; } ); + // Mouse + mouse = ( { click = "clickinput"; + modifier = "None"; + button = "left-click"; + function = "clear"; + argument = "0"; + }, + { click = "clickprompt"; + modifier = "None"; + button = "left-click"; + function = "clear"; + argument = "0"; + }, + { click = "clickmode"; + modifier = "None"; + button = "left-click"; + function = "switchmode"; + argument = "0"; + }, + { click = "clicknumber"; + modifier = "None"; + button = "left-click"; + function = "viewhist"; + argument = "0"; + }, + { click = "clickselitem"; + modifier = "None"; + button = "left-click"; + function = "None"; + argument = "0"; + }, + + { ignoreglobalmouse = 1; } ); + // Keys keys = ( { mode = -1; modifier = "None"; key = "Enter"; function = "selectitem"; argument = "+1"; - } + }, { mode = -1; - modifier = "Shift"; - key = "Enter"; - function = "selectitem"; - argument = "0"; - } + modifier = "Shift"; + key = "Enter"; + function = "selectitem"; + argument = "0"; + }, { mode = -1; - modifier = "None"; - key = "Tab"; - function = "complete"; - argument = "0"; - } + modifier = "None"; + key = "Tab"; + function = "complete"; + argument = "0"; + }, { mode = -1; - modifier = "Ctrl"; - key = "v"; - function = "paste"; - argument = "2"; - } + modifier = "Ctrl"; + key = "v"; + function = "paste"; + argument = "2"; + }, { mode = -1; - modifier = "Ctrl+Shift"; - key = "v"; - function = "paste"; - argument = "1"; - } + modifier = "Ctrl+Shift"; + key = "v"; + function = "paste"; + argument = "1"; + }, { mode = -1; - modifier = "None"; - key = "Backspace"; - function = "backspace"; - argument = "0"; - } + modifier = "None"; + key = "Backspace"; + function = "backspace"; + argument = "0"; + }, { mode = -1; - modifier = "Ctrl"; - key = "Backspace"; - function = "deleteword"; - argument = "0"; - } + modifier = "Ctrl"; + key = "Backspace"; + function = "deleteword"; + argument = "0"; + }, { mode = -1; - modifier = "Ctrl"; - key = "Left"; - function = "moveword"; - argument = "-1"; - } + modifier = "Ctrl"; + key = "Left"; + function = "moveword"; + argument = "-1"; + }, { mode = -1; - modifier = "Ctrl"; - key = "Right"; - function = "moveword"; - argument = "+1"; - } + modifier = "Ctrl"; + key = "Right"; + function = "moveword"; + argument = "+1"; + }, { mode = -1; - modifier = "None"; - key = "Left"; - function = "movecursor"; - argument = "-1"; - } + modifier = "None"; + key = "Left"; + function = "movecursor"; + argument = "-1"; + }, { mode = -1; - modifier = "None"; - key = "Right"; - function = "movecursor"; - argument = "+1"; - } + modifier = "None"; + key = "Right"; + function = "movecursor"; + argument = "+1"; + }, { mode = -1; - modifier = "Control+Shift"; - key = "p"; - function = "spawn"; - argument = "setprofile"; - } + modifier = "Control+Shift"; + key = "p"; + function = "spawn"; + argument = "setprofile"; + }, { mode = 1; - modifier = "None"; - key = "Esc"; - function = "switchmode"; - argument = "0"; - } + modifier = "None"; + key = "Esc"; + function = "switchmode"; + argument = "0"; + }, { mode = 0; - modifier = "None"; - key = "i"; - function = "switchmode"; - argument = "0"; - } + modifier = "None"; + key = "i"; + function = "switchmode"; + argument = "0"; + }, { mode = 0; - modifier = "None"; - key = "/"; - function = "switchmode"; - argument = "0"; - } + modifier = "None"; + key = "/"; + function = "switchmode"; + argument = "0"; + }, { mode = 0; - modifier = "Ctrl"; - key = "="; - function = "setimgsize"; - argument = "+1"; - } + modifier = "Ctrl"; + key = "="; + function = "setimgsize"; + argument = "+1"; + }, { mode = 0; - modifier = "Ctrl"; - key = "-"; - function = "setimgsize"; - argument = "-1"; - } + modifier = "Ctrl"; + key = "-"; + function = "setimgsize"; + argument = "-1"; + }, { mode = 0; - modifier = "None"; - key = "-"; - function = "setimgsize"; - argument = "-10"; - } + modifier = "None"; + key = "-"; + function = "setimgsize"; + argument = "-10"; + }, { mode = 0; - modifier = "None"; - key = "="; - function = "setimgsize"; - argument = "+10"; - } + modifier = "None"; + key = "="; + function = "setimgsize"; + argument = "+10"; + }, { mode = 0; - modifier = "Shift"; - key = "-"; - function = "setimgsize"; - argument = "-100"; - } + modifier = "Shift"; + key = "-"; + function = "setimgsize"; + argument = "-100"; + }, { mode = 0; - modifier = "Shift"; - key = "="; - function = "setimgsize"; - argument = "+100"; - } + modifier = "Shift"; + key = "="; + function = "setimgsize"; + argument = "+100"; + }, { mode = 0; - modifier = "Shift"; - key = "0"; - function = "defaultimg"; - argument = "0"; - } + modifier = "Shift"; + key = "0"; + function = "defaultimg"; + argument = "0"; + }, { mode = 0; - modifier = "None"; - key = "r"; - function = "rotateimg"; - argument = "0"; - } + modifier = "None"; + key = "r"; + function = "rotateimg"; + argument = "0"; + }, { mode = 0; - modifier = "None"; - key = "p"; - function = "setimgpos"; - argument = "+1"; - } + modifier = "None"; + key = "p"; + function = "setimgpos"; + argument = "+1"; + }, { mode = 0; - modifier = "Ctrl"; - key = "1"; - function = "setimggaps"; - argument = "-1"; - } + modifier = "Ctrl"; + key = "1"; + function = "setimggaps"; + argument = "-1"; + }, { mode = 0; - modifier = "Ctrl"; - key = "2"; - function = "setimggaps"; - argument = "+1"; - } + modifier = "Ctrl"; + key = "2"; + function = "setimggaps"; + argument = "+1"; + }, { mode = 0; - modifier = "None"; - key = "1"; - function = "setimggaps"; - argument = "-10"; - } + modifier = "None"; + key = "1"; + function = "setimggaps"; + argument = "-10"; + }, { mode = 0; - modifier = "None"; - key = "2"; - function = "setimggaps"; - argument = "+10"; - } + modifier = "None"; + key = "2"; + function = "setimggaps"; + argument = "+10"; + }, { mode = 0; - modifier = "Shift"; - key = "1"; - function = "setimggaps"; - argument = "-100"; - } + modifier = "Shift"; + key = "1"; + function = "setimggaps"; + argument = "-100"; + }, { mode = 0; - modifier = "Shift"; - key = "2"; - function = "setimggaps"; - argument = "+100"; - } + modifier = "Shift"; + key = "2"; + function = "setimggaps"; + argument = "+100"; + }, { mode = 0; - modifier = "None"; - key = "t"; - function = "toggleimg"; - argument = "0"; - } + modifier = "None"; + key = "t"; + function = "toggleimg"; + argument = "0"; + }, { mode = 0; - modifier = "None"; - key = "h"; - function = "flipimg"; - argument = "1"; - } + modifier = "None"; + key = "h"; + function = "flipimg"; + argument = "1"; + }, { mode = 0; - modifier = "None"; - key = "v"; - function = "flipimg"; - argument = "0"; - } + modifier = "None"; + key = "v"; + function = "flipimg"; + argument = "0"; + }, { mode = 0; - modifier = "None"; - key = "k"; - function = "moveup"; - argument = "0"; - } + modifier = "None"; + key = "k"; + function = "moveup"; + argument = "0"; + }, { mode = 0; - modifier = "None"; - key = "j"; - function = "movedown"; - argument = "0"; - } + modifier = "None"; + key = "j"; + function = "movedown"; + argument = "0"; + }, { mode = 0; - modifier = "None"; - key = "h"; - function = "moveleft"; - argument = "0"; - } + modifier = "None"; + key = "h"; + function = "moveleft"; + argument = "0"; + }, { mode = 0; - modifier = "None"; - key = "l"; - function = "moveright"; - argument = "0"; - } + modifier = "None"; + key = "l"; + function = "moveright"; + argument = "0"; + }, { mode = 0; - modifier = "Ctrl"; - key = "u"; - function = "moveup"; - argument = "5"; - } + modifier = "Ctrl"; + key = "u"; + function = "moveup"; + argument = "5"; + }, { mode = 0; - modifier = "Ctrl"; - key = "d"; - function = "movedown"; - argument = "5"; - } + modifier = "Ctrl"; + key = "d"; + function = "movedown"; + argument = "5"; + }, { mode = 0; - modifier = "Ctrl"; - key = "k"; - function = "setlines"; - argument = "+1"; - } + modifier = "Ctrl"; + key = "k"; + function = "setlines"; + argument = "+1"; + }, { mode = 0; - modifier = "Ctrl"; - key = "j"; - function = "setlines"; - argument = "-1"; - } + modifier = "Ctrl"; + key = "j"; + function = "setlines"; + argument = "-1"; + }, { mode = 0; - modifier = "Ctrl+Alt+Shift"; - key = "k"; - function = "setlines"; - argument = "+5"; - } + modifier = "Ctrl+Alt+Shift"; + key = "k"; + function = "setlines"; + argument = "+5"; + }, { mode = 0; - modifier = "Ctrl+Alt+Shift"; - key = "j"; - function = "setlines"; - argument = "-5"; - } + modifier = "Ctrl+Alt+Shift"; + key = "j"; + function = "setlines"; + argument = "-5"; + }, { mode = 0; - modifier = "Ctrl"; - key = "h"; - function = "setcolumns"; - argument = "+1"; - } + modifier = "Ctrl"; + key = "h"; + function = "setcolumns"; + argument = "+1"; + }, { mode = 0; - modifier = "Ctrl"; - key = "h"; - function = "setcolumns"; - argument = "-1"; - } + modifier = "Ctrl"; + key = "h"; + function = "setcolumns"; + argument = "-1"; + }, { mode = 0; - modifier = "Ctrl+Alt+Shift"; - key = "h"; - function = "setcolumns"; - argument = "+5"; - } + modifier = "Ctrl+Alt+Shift"; + key = "h"; + function = "setcolumns"; + argument = "+5"; + }, { mode = 0; - modifier = "Ctrl+Alt+Shift"; - key = "l"; - function = "setcolumns"; - argument = "-5"; - } + modifier = "Ctrl+Alt+Shift"; + key = "l"; + function = "setcolumns"; + argument = "-5"; + }, { mode = 0; - modifier = "Ctrl"; - key = "k"; - function = "restoresel"; - argument = "0"; - } + modifier = "Ctrl"; + key = "k"; + function = "restoresel"; + argument = "0"; + }, { mode = 0; - modifier = "None"; - key = "u"; - function = "togglehighlight"; - argument = "0"; - } + modifier = "None"; + key = "u"; + function = "togglehighlight"; + argument = "0"; + }, { mode = 0; - modifier = "Ctrl+Shift"; - key = "h"; - function = "viewhist"; - argument = "0"; - } + modifier = "Ctrl+Shift"; + key = "h"; + function = "viewhist"; + argument = "0"; + }, { mode = 0; - modifier = "None"; - key = "d"; - function = "clear"; - argument = "0"; - } + modifier = "None"; + key = "d"; + function = "clear"; + argument = "0"; + }, { mode = 0; - modifier = "None"; - key = "c"; - function = "clearins"; - argument = "0"; - } + modifier = "None"; + key = "c"; + function = "clearins"; + argument = "0"; + }, { mode = 0; - modifier = "None"; - key = "Esc"; - function = "quit"; - argument = "0"; - } + modifier = "None"; + key = "Esc"; + function = "quit"; + argument = "0"; + }, { mode = 0; - modifier = "None"; - key = "Home"; - function = "movestart"; - argument = "0"; - } + modifier = "None"; + key = "Home"; + function = "movestart"; + argument = "0"; + }, { mode = 0; - modifier = "None"; - key = "End"; - function = "moveend"; - argument = "0"; - } + modifier = "None"; + key = "End"; + function = "moveend"; + argument = "0"; + }, { mode = 0; - modifier = "None"; - key = "g"; - function = "movestart"; - argument = "0"; - } + modifier = "None"; + key = "g"; + function = "movestart"; + argument = "0"; + }, { mode = 0; - modifier = "Shift"; - key = "g"; - function = "moveend"; - argument = "0"; - } + modifier = "Shift"; + key = "g"; + function = "moveend"; + argument = "0"; + }, { mode = 0; - modifier = "None"; - key = "Next"; - function = "movenext"; - argument = "0"; - } + modifier = "None"; + key = "Next"; + function = "movenext"; + argument = "0"; + }, { mode = 0; - modifier = "None"; - key = "Prior"; - function = "moveprev"; - argument = "0"; - } + modifier = "None"; + key = "Prior"; + function = "moveprev"; + argument = "0"; + }, { mode = 0; - modifier = "Alt"; - key = "p"; - function = "navhistory"; - argument = "-1"; - } + modifier = "Alt"; + key = "p"; + function = "navhistory"; + argument = "-1"; + }, { mode = 0; - modifier = "Alt"; - key = "n"; - function = "navhistory"; - argument = "+1"; - } + modifier = "Alt"; + key = "n"; + function = "navhistory"; + argument = "+1"; + }, - ignoreglobalkeys = 1; ), + { ignoreglobalkeys = 1; } ), }; diff --git a/libs/conf/config.c b/libs/conf/config.c index cc00707..0d0a648 100644 --- a/libs/conf/config.c +++ b/libs/conf/config.c @@ -55,7 +55,7 @@ conf_init(void) // attempt to read config file to cfg if (!config_read_file(&cfg, cfgfile)) { // invalid configuration, but let's try to read it anyway - ; + fprintf(stdout, "spmenu: Invalid configuration.\n"); } // load options spmenu.window @@ -620,6 +620,62 @@ conf_init(void) } } + // load options spmenu.keys + setting = config_lookup(&cfg, "spmenu.mouse"); + if (setting != NULL) { + unsigned int i = 0; + + conflength = config_setting_length(setting); + + for (i = 0; i < conflength; ++i) { + config_setting_t *conf = config_setting_get_elem(setting, i); + + // look up + config_setting_lookup_string(conf, "click", &dest); + + for (int j = 0; j < LENGTH(ctp); j++) { + if (!strcmp(ctp[j].tclick, strdup(dest))) { + cbuttons[i].click = ctp[j].click; + } + } + + // look up + config_setting_lookup_string(conf, "modifier", &dest); + + for (int j = 0; j < LENGTH(ml); j++) { + if (!strcmp(ml[j].mod, strdup(dest))) { + cbuttons[i].mask = ml[j].modifier; + } + } + + config_setting_lookup_string(conf, "button", &dest); + + for (int j = 0; j < LENGTH(btp); j++) { + if (!strcmp(btp[j].click, strdup(dest))) { + cbuttons[i].button = btp[j].button; + } + } + + config_setting_lookup_string(conf, "function", &dest); + + for (int j = 0; j < LENGTH(fl); j++) { + if (!strcmp(fl[j].function, strdup(dest))) { + cbuttons[i].func = fl[j].func; + } + } + + config_setting_lookup_string(conf, "argument", &dest); + + for (int j = 0; j < LENGTH(al); j++) { + if (!strcmp(al[j].argument, strdup(dest))) { + cbuttons[i].arg = al[j].arg; + } + } + + config_setting_lookup_int(conf, "ignoreglobalmouse", &ignoreglobalmouse); + } + } + // we're done here config_destroy(&cfg); return; diff --git a/libs/key.h b/libs/key.h index 59b3720..b8ec984 100644 --- a/libs/key.h +++ b/libs/key.h @@ -422,8 +422,8 @@ static KeyList kl[] = { { "g", XK_g }, { "h", XK_h }, { "i", XK_i }, - { "j", XK_k }, - { "k", XK_j }, + { "j", XK_j }, + { "k", XK_k }, { "l", XK_l }, { "m", XK_m }, { "n", XK_n }, diff --git a/libs/mouse.c b/libs/mouse.c index 3bfcc59..747ca26 100644 --- a/libs/mouse.c +++ b/libs/mouse.c @@ -73,6 +73,14 @@ buttonpress(XEvent *e) } else if (buttons[i].click == clickitem) { click = clickitem; } + } + for (i = 0; i < LENGTH(cbuttons); i++) { + if (cbuttons[i].click == clickselitem && cbuttons[i].button == ev->button && CLEANMASK(cbuttons[i].mask) == CLEANMASK(ev->state)) { + puts(item->text); + exit(0); + } else if (cbuttons[i].click == clickitem) { + click = clickitem; + } } } } @@ -99,6 +107,14 @@ buttonpress(XEvent *e) click = clickitem; } } + for (i = 0; i < LENGTH(cbuttons); i++) { + if (cbuttons[i].click == clickselitem && cbuttons[i].button == ev->button && CLEANMASK(cbuttons[i].mask) == CLEANMASK(ev->state)) { + puts(item->text); + exit(0); + } else if (cbuttons[i].click == clickitem) { + click = clickitem; + } + } } } @@ -111,8 +127,18 @@ buttonpress(XEvent *e) } // go through mouse button array and run function - for (i = 0; i < LENGTH(buttons); i++) + for (i = 0; i < LENGTH(buttons); i++) { + if (ignoreglobalmouse) break; if (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); + } + + // go through mouse config array and run function + for (i = 0; i < LENGTH(cbuttons); i++) { + if (ignoreconfmouse) break; + if (click == cbuttons[i].click && cbuttons[i].func && cbuttons[i].button == ev->button + && CLEANMASK(cbuttons[i].mask) == CLEANMASK(ev->state)) + cbuttons[i].func(&cbuttons[i].arg); + } } diff --git a/libs/mouse.h b/libs/mouse.h index 75ccf63..e10e05f 100644 --- a/libs/mouse.h +++ b/libs/mouse.h @@ -1,11 +1,3 @@ -typedef struct { - unsigned int click; - unsigned int mask; - unsigned int button; - void (*func)(Arg *arg); - Arg arg; -} Mouse; - // clicks enum { clickwindow, @@ -20,4 +12,50 @@ enum { clickmode, }; +typedef struct { + unsigned int click; + unsigned int mask; + unsigned int button; + void (*func)(Arg *arg); + Arg arg; +} Mouse; + +typedef struct { + char *click; + unsigned int button; +} ButtonType; + +typedef struct { + char *tclick; + unsigned int click; +} ClickType; + +static ButtonType btp[] = { + { "button1", Button1 }, + { "button2", Button2 }, + { "button3", Button3 }, + { "button4", Button4 }, + { "button5", Button5 }, + + { "left-click", Button1 }, + { "middle-click", Button2 }, + { "right-click", Button3 }, + { "scroll-up", Button4 }, + { "scroll-down", Button5 }, +}; + +static ClickType ctp[] = { + { "clickwindow", clickwindow }, + { "clickprompt", clickprompt }, + { "clickinput", clickinput }, + { "clicklarrow", clicklarrow }, + { "clickitem", clickitem }, + { "clickselitem", clickselitem }, + { "clickrarrow", clickrarrow }, + { "clicknumber", clicknumber }, + { "clickcaps", clickcaps }, + { "clickmode", clickmode }, +}; + +static Mouse cbuttons[256]; static void buttonpress(XEvent *e); diff --git a/spmenu.c b/spmenu.c index 3a6577a..4a2ac43 100644 --- a/spmenu.c +++ b/spmenu.c @@ -177,6 +177,8 @@ static int isrtl = 0; 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 // X11 properties static Atom clip, utf8, types, dock;