From 9c3bd4caabd80f590a317d00917e95a6a60ffabe Mon Sep 17 00:00:00 2001 From: speedie Date: Tue, 25 Apr 2023 09:56:11 +0200 Subject: [PATCH] basic keybind config file --- libs/arg.c | 64 ++++++++-------- libs/arg.h | 64 ++++++++-------- libs/conf/config.c | 49 +++++++++++++ libs/key.c | 15 ++++ libs/key.h | 178 ++++++++++++++++++++++++++++++++++++++++++++- libs/mode.c | 2 +- libs/mode.h | 2 +- libs/mouse.h | 4 +- spmenu.c | 3 + 9 files changed, 311 insertions(+), 70 deletions(-) diff --git a/libs/arg.c b/libs/arg.c index 3c38401..f8ffd01 100644 --- a/libs/arg.c +++ b/libs/arg.c @@ -1,5 +1,5 @@ void -moveleft(const Arg *arg) +moveleft(Arg *arg) { struct item *tmpsel; int i, offscreen = 0; @@ -37,7 +37,7 @@ moveleft(const Arg *arg) } void -moveright(const Arg *arg) +moveright(Arg *arg) { struct item *tmpsel; int i, offscreen = 0; @@ -74,7 +74,7 @@ moveright(const Arg *arg) } void -movedown(const Arg *arg) +movedown(Arg *arg) { int argu = arg->i ? arg->i : 1; @@ -90,7 +90,7 @@ movedown(const Arg *arg) } void -moveup(const Arg *arg) +moveup(Arg *arg) { int argu = arg->i ? arg->i : 1; @@ -105,7 +105,7 @@ moveup(const Arg *arg) } void -complete(const Arg *arg) +complete(Arg *arg) { if (hideitem) return; strncpy(text, sel->clntext, sizeof text - 1); @@ -116,7 +116,7 @@ complete(const Arg *arg) } void -movenext(const Arg *arg) +movenext(Arg *arg) { if (!next) return; @@ -127,7 +127,7 @@ movenext(const Arg *arg) } void -moveprev(const Arg *arg) +moveprev(Arg *arg) { if (!prev) return; @@ -138,7 +138,7 @@ moveprev(const Arg *arg) } void -movestart(const Arg *arg) +movestart(Arg *arg) { if (sel == matches) { cursor = 0; @@ -152,7 +152,7 @@ movestart(const Arg *arg) } void -moveend(const Arg *arg) +moveend(Arg *arg) { if (text[cursor] != '\0') { cursor = strlen(text); @@ -175,7 +175,7 @@ moveend(const Arg *arg) } void -paste(const Arg *arg) +paste(Arg *arg) { int clipboard; @@ -191,7 +191,7 @@ paste(const Arg *arg) } void -viewhist(const Arg *arg) +viewhist(Arg *arg) { int i; @@ -219,7 +219,7 @@ viewhist(const Arg *arg) } void -deleteword(const Arg *arg) +deleteword(Arg *arg) { if (cursor == 0) return; @@ -233,7 +233,7 @@ deleteword(const Arg *arg) } void -moveword(const Arg *arg) +moveword(Arg *arg) { if (arg->i < 0) { // move cursor to the start of the word while (cursor > 0 && strchr(worddelimiters, text[nextrune(-1)])) { @@ -253,7 +253,7 @@ moveword(const Arg *arg) } void -movecursor(const Arg *arg) +movecursor(Arg *arg) { if (arg->i < 0) { if (cursor > 0) { @@ -269,7 +269,7 @@ movecursor(const Arg *arg) } void -backspace(const Arg *arg) +backspace(Arg *arg) { if (cursor == 0) return; @@ -279,7 +279,7 @@ backspace(const Arg *arg) } void -selectitem(const Arg *arg) +selectitem(Arg *arg) { char *selection; @@ -300,14 +300,14 @@ selectitem(const Arg *arg) } void -navhistory(const Arg *arg) +navhistory(Arg *arg) { navigatehistfile(arg->i); drawmenu(); } void -restoresel(const Arg *arg) +restoresel(Arg *arg) { text[cursor] = '\0'; match(); @@ -315,14 +315,14 @@ restoresel(const Arg *arg) } void -clear(const Arg *arg) +clear(Arg *arg) { insert(NULL, 0 - cursor); drawmenu(); } void -clearins(const Arg *arg) +clearins(Arg *arg) { insert(NULL, 0 - cursor); @@ -342,7 +342,7 @@ clearins(const Arg *arg) } void -quit(const Arg *arg) +quit(Arg *arg) { cleanup(); exit(1); @@ -386,7 +386,7 @@ out: } void -setimgsize(const Arg *arg) +setimgsize(Arg *arg) { #if USEIMAGE setimagesize(imagewidth + arg->i, imageheight + arg->i); @@ -394,7 +394,7 @@ setimgsize(const Arg *arg) } void -flipimg(const Arg *arg) +flipimg(Arg *arg) { #if USEIMAGE @@ -408,7 +408,7 @@ flipimg(const Arg *arg) } void -setimgpos(const Arg *arg) +setimgpos(Arg *arg) { #if USEIMAGE if (!image || hideimage) return; @@ -424,7 +424,7 @@ setimgpos(const Arg *arg) } void -setimggaps(const Arg *arg) +setimggaps(Arg *arg) { #if USEIMAGE imagegaps += arg->i; @@ -443,7 +443,7 @@ setimggaps(const Arg *arg) } void -rotateimg(const Arg *arg) +rotateimg(Arg *arg) { #if USEIMAGE @@ -456,7 +456,7 @@ rotateimg(const Arg *arg) } void -toggleimg(const Arg *arg) +toggleimg(Arg *arg) { #if USEIMAGE @@ -468,7 +468,7 @@ toggleimg(const Arg *arg) } void -defaultimg(const Arg *arg) +defaultimg(Arg *arg) { #if USEIMAGE @@ -485,7 +485,7 @@ defaultimg(const Arg *arg) } void -setlines(const Arg *arg) +setlines(Arg *arg) { lines += arg->i; if (lines < 0) lines = 0; @@ -496,7 +496,7 @@ setlines(const Arg *arg) } void -setcolumns(const Arg *arg) +setcolumns(Arg *arg) { columns += arg->i; if (columns < 1) columns = 1; @@ -507,7 +507,7 @@ setcolumns(const Arg *arg) } void -spawn(const Arg *arg) +spawn(Arg *arg) { if (!system(arg->c)) die("spmenu: failed to execute command '%s'", arg->c); @@ -516,7 +516,7 @@ spawn(const Arg *arg) } void -togglehighlight(const Arg *arg) +togglehighlight(Arg *arg) { hidehighlight = !hidehighlight; drawmenu(); diff --git a/libs/arg.h b/libs/arg.h index 37d4f12..f6abaf0 100644 --- a/libs/arg.h +++ b/libs/arg.h @@ -7,36 +7,36 @@ typedef union { } Arg; // declare keybind functions -static void moveup(const Arg *arg); -static void movedown(const Arg *arg); -static void moveleft(const Arg *arg); -static void moveright(const Arg *arg); -static void moveend(const Arg *arg); -static void movestart(const Arg *arg); -static void movenext(const Arg *arg); -static void moveprev(const Arg *arg); -static void paste(const Arg *arg); -static void restoresel(const Arg *arg); -static void clear(const Arg *arg); -static void clearins(const Arg *arg); -static void viewhist(const Arg *arg); -static void moveword(const Arg *arg); -static void deleteword(const Arg *arg); -static void movecursor(const Arg *arg); -static void navhistory(const Arg *arg); -static void backspace(const Arg *arg); -static void selectitem(const Arg *arg); -static void quit(const Arg *arg); -static void complete(const Arg *arg); +static void moveup(Arg *arg); +static void movedown(Arg *arg); +static void moveleft(Arg *arg); +static void moveright(Arg *arg); +static void moveend(Arg *arg); +static void movestart(Arg *arg); +static void movenext(Arg *arg); +static void moveprev(Arg *arg); +static void paste(Arg *arg); +static void restoresel(Arg *arg); +static void clear(Arg *arg); +static void clearins(Arg *arg); +static void viewhist(Arg *arg); +static void moveword(Arg *arg); +static void deleteword(Arg *arg); +static void movecursor(Arg *arg); +static void navhistory(Arg *arg); +static void backspace(Arg *arg); +static void selectitem(Arg *arg); +static void quit(Arg *arg); +static void complete(Arg *arg); static void savehistory(char *input); -static void setimgsize(const Arg *arg); -static void toggleimg(const Arg *arg); -static void defaultimg(const Arg *arg); -static void rotateimg(const Arg *arg); -static void flipimg(const Arg *arg); -static void setimgpos(const Arg *arg); -static void setimggaps(const Arg *arg); -static void setlines(const Arg *arg); -static void setcolumns(const Arg *arg); -static void spawn(const Arg *arg); -static void togglehighlight(const Arg *arg); +static void setimgsize(Arg *arg); +static void toggleimg(Arg *arg); +static void defaultimg(Arg *arg); +static void rotateimg(Arg *arg); +static void flipimg(Arg *arg); +static void setimgpos(Arg *arg); +static void setimggaps(Arg *arg); +static void setlines(Arg *arg); +static void setcolumns(Arg *arg); +static void spawn(Arg *arg); +static void togglehighlight(Arg *arg); diff --git a/libs/conf/config.c b/libs/conf/config.c index d7fe9c2..0760dea 100644 --- a/libs/conf/config.c +++ b/libs/conf/config.c @@ -568,6 +568,55 @@ conf_init(void) } } + // load options spmenu.keys + setting = config_lookup(&cfg, "spmenu.keys"); + if (setting != NULL) { + unsigned int i = 0; + int nmode = 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, "modifier", &dest); + + for (int j = 0; j < LENGTH(ml); j++) { + if (!strcmp(ml[j].mod, strdup(dest))) { + ckeys[i].mod = ml[j].modifier; + } + } + + if (config_setting_lookup_int(conf, "mode", &nmode)) { + ckeys[i].mode = nmode; + } + + config_setting_lookup_string(conf, "key", &dest); + + for (int j = 0; j < LENGTH(kl); j++) { + if (!strcmp(kl[j].key, strdup(dest))) { + ckeys[i].keysym = kl[j].keysym; + } + } + + config_setting_lookup_string(conf, "function", &dest); + + for (int j = 0; j < LENGTH(fl); j++) { + if (!strcmp(fl[j].function, strdup(dest))) { + ckeys[i].func = fl[j].func; + } + } + + for (int j = 0; j < LENGTH(fl); j++) { + if (!strcmp(fl[j].function, strdup(dest))) { + ckeys[i].func = fl[j].func; + ckeys[i].arg = fl[j].arg; + } + } + } + } + // we're done here config_destroy(&cfg); return; diff --git a/libs/key.c b/libs/key.c index 9c958dd..bc793e4 100644 --- a/libs/key.c +++ b/libs/key.c @@ -33,6 +33,7 @@ keypress(XEvent *e) keysym = XkbKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0, 0); for (i = 0; i < LENGTH(keys); i++) { + if (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) { keys[i].func(&(keys[i].arg)); @@ -45,6 +46,20 @@ keypress(XEvent *e) } } + for (i = 0; i < LENGTH(ckeys); i++) { + if (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) { + ckeys[i].func(&(ckeys[i].arg)); + return; + } else if (!ckeys[i].mode && !curMode) { + ckeys[i].func(&(ckeys[i].arg)); + } else { + continue; + } + } + } + if (!iscntrl(*buf) && type && curMode ) { if (allowkeys) { insert(buf, len); diff --git a/libs/key.h b/libs/key.h index 85d3a43..0a4fc0d 100644 --- a/libs/key.h +++ b/libs/key.h @@ -2,13 +2,187 @@ typedef struct { unsigned int mode; unsigned int mod; KeySym keysym; - void (*func)(const Arg *); - const Arg arg; + void (*func)(Arg *); + Arg arg; } Key; +typedef struct { + char *key; + KeySym keysym; +} KeyList; + +typedef struct { + char *mod; + unsigned int modifier; +} ModList; + +typedef struct { + char *modif; + char *key; + char *func; +} ConfKeys; + +typedef struct { + char *function; + void (*func)(Arg *); + Arg arg; +} FuncList; + +static FuncList fl[] = { + { "moveup", moveup, {0} }, + { "movedown", movedown, {0} }, + { "moveleft", moveleft, {0} }, + { "moveright", moveright, {0} }, + { "moveend", moveend, {0} }, + { "movestart", movestart, {0} }, + { "move+", movenext, {0} }, + { "move-", moveprev, {0} }, + { "paste", paste, {.i = 2 } }, + { "pastesel", paste, {.i = 1 } }, + { "restoresel", restoresel, {0} }, + { "clear", clear, {0} }, + { "clearins", clearins, {0} }, + { "viewhist", viewhist, {0} }, + { "moveword-", moveword, {.i = -1 } }, + { "moveword+", moveword, {.i = +1 } }, + { "deleteword", deleteword, {0} }, + { "movecursor-", movecursor, {.i = -1 } }, + { "movecursor+", movecursor, {.i = +1 } }, + { "navhistory-", navhistory, {.i = -1 } }, + { "navhistory+", navhistory, {.i = +1 } }, + { "backspace", backspace, {0} }, + { "selectitem", selectitem, {.i = +1 } }, + { "selectinput", selectitem, {0} }, + { "quit", quit, {0} }, + { "complete", complete, {0} }, + { "imgsize+", setimgsize, {.i = +1 } }, + { "imgsize-", setimgsize, {.i = -1 } }, + { "toggleimg", toggleimg, {0} }, + { "defaultimg", defaultimg, {0} }, + { "rotateimg", rotateimg, {0} }, + { "flipimg", flipimg, {0} }, + { "setimgpos+", setimgpos, {.i = +1 } }, + { "setimgpos-", setimgpos, {.i = -1 } }, + { "setimggaps+", setimggaps, {.i = +1 } }, + { "setimggaps-", setimggaps, {.i = -1 } }, + { "setlines+", setlines, {.i = +1 } }, + { "setlines-", setlines, {.i = -1 } }, + { "setcolumns+", setcolumns, {.i = +1 } }, + { "setcolumns-", setcolumns, {.i = -1 } }, + { "togglehighlight", togglehighlight, {0} }, +}; + +// list of modifiers that can be used in the config file +static ModList ml[] = { + { "Shift", ShiftMask }, + { "Lock", LockMask }, + { "Ctrl", ControlMask }, + { "Alt", Mod1Mask }, + { "AltGr", Mod3Mask }, + { "Super", Mod4Mask }, + { "ShiftGr", Mod5Mask }, +}; + +// list of keys that can be used in the config file +// expand this array if you want more +static KeyList kl[] = { + { "Space", XK_space }, + { "Enter", XK_Return }, + { "Tab", XK_Tab }, + { "a", XK_a }, + { "b", XK_b }, + { "c", XK_c }, + { "d", XK_d }, + { "e", XK_e }, + { "f", XK_f }, + { "g", XK_g }, + { "h", XK_h }, + { "i", XK_i }, + { "j", XK_k }, + { "k", XK_j }, + { "l", XK_l }, + { "m", XK_m }, + { "n", XK_n }, + { "o", XK_o }, + { "p", XK_p }, + { "q", XK_q }, + { "r", XK_r }, + { "s", XK_s }, + { "t", XK_t }, + { "u", XK_u }, + { "v", XK_v }, + { "w", XK_w }, + { "x", XK_x }, + { "y", XK_y }, + { "z", XK_z }, + { "0", XK_0 }, + { "1", XK_1 }, + { "2", XK_2 }, + { "3", XK_3 }, + { "4", XK_4 }, + { "5", XK_5 }, + { "6", XK_6 }, + { "7", XK_7 }, + { "8", XK_8 }, + { "9", XK_9 }, + { "!", XK_exclam }, + { "\"", XK_quotedbl }, + { "#", XK_numbersign }, + { "$", XK_dollar }, + { "%", XK_percent }, + { "&", XK_ampersand }, + { "'", XK_apostrophe }, + { "(", XK_parenleft }, + { ")", XK_parenright }, + { "*", XK_asterisk }, + { "+", XK_plus }, + { ",", XK_comma }, + { "-", XK_minus }, + { ".", XK_period }, + { "/", XK_slash }, + { ":", XK_colon }, + { ";", XK_semicolon }, + { "<", XK_less }, + { "=", XK_equal }, + { ">", XK_greater }, + { "?", XK_question }, + { "@", XK_at }, + { "[", XK_bracketleft }, + { "\\", XK_backslash }, + { "]", XK_bracketright }, + { "_", XK_underscore }, + { "grave", XK_grave }, + { "{", XK_braceleft }, + { "bar", XK_bar }, + { "}", XK_braceright }, + { "~", XK_asciitilde }, + { "F1", XK_F1 }, + { "F2", XK_F2 }, + { "F3", XK_F3 }, + { "F4", XK_F4 }, + { "F5", XK_F5 }, + { "F6", XK_F6 }, + { "F7", XK_F7 }, + { "F8", XK_F8 }, + { "F9", XK_F9 }, + { "F10", XK_F10 }, + { "F11", XK_F11 }, + { "F12", XK_F12 }, + { "PageUp", XK_Page_Up }, + { "PageDown", XK_Page_Down }, + { "Home", XK_Home }, + { "End", XK_End }, + { "Delete", XK_Delete }, + { "PrintScr", XK_Print }, + { "Esc", XK_Escape }, + { "Pause", XK_Pause }, + { "ScrollLock", XK_Scroll_Lock }, +}; + static void updatenumlockmask(void); static void keypress(XEvent *e); static void grabkeyboard(void); static void getcapsstate(void); +static Key ckeys[256]; static char capstext[16] = "Caps Lock"; diff --git a/libs/mode.c b/libs/mode.c index c127b82..7fbf537 100644 --- a/libs/mode.c +++ b/libs/mode.c @@ -1,5 +1,5 @@ void -switchmode(const Arg *arg) +switchmode(Arg *arg) { curMode = !curMode; allowkeys = !curMode; diff --git a/libs/mode.h b/libs/mode.h index 4251bab..784e4e0 100644 --- a/libs/mode.h +++ b/libs/mode.h @@ -5,4 +5,4 @@ static int curMode = 1; // 0 is command mode static int allowkeys = 1; // whether or not to interpret a keypress as an insertion // mode functions -static void switchmode(const Arg *arg); +static void switchmode(Arg *arg); diff --git a/libs/mouse.h b/libs/mouse.h index 25894c3..75ccf63 100644 --- a/libs/mouse.h +++ b/libs/mouse.h @@ -2,8 +2,8 @@ typedef struct { unsigned int click; unsigned int mask; unsigned int button; - void (*func)(const Arg *arg); - const Arg arg; + void (*func)(Arg *arg); + Arg arg; } Mouse; // clicks diff --git a/spmenu.c b/spmenu.c index 5ec4f07..3a6577a 100644 --- a/spmenu.c +++ b/spmenu.c @@ -175,6 +175,9 @@ static int isrtl = 1; 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 + // X11 properties static Atom clip, utf8, types, dock; static Display *dpy;