Re: [hackers] [dwm][PATCH] Implement key shortcut mapping
On 230924-093006, Hiltjo Posthuma 'hil...@codemadness.org' wrote: > > >On Sun, Sep 24, 2023 at 05:34:48AM +, suiso67@macadamia.rocks wrote: >> From: suiso67 >> >> --- >> config.def.h | 43 +++ >> dwm.c| 47 +++ >> 2 files changed, 90 insertions(+) >> >> diff --git a/config.def.h b/config.def.h >> index 061ad66..98ff36f 100644 >> --- a/config.def.h >> +++ b/config.def.h >> @@ -51,6 +51,8 @@ static const Layout layouts[] = { >> { MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << >> TAG} }, \ >> { MODKEY|ShiftMask, KEY, tag,{.ui = 1 << >> TAG} }, \ >> { MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << >> TAG} }, >> +#define KEYEVENT(SRC_MOD,SRC_KEY,DST_MOD,DST_KEY) \ >> +{ SRC_MOD, SRC_KEY, sendkeyevent, { .v = &(const KeyShortcut){ DST_MOD, >> DST_KEY } } }, >> >> /* helper for spawning shell commands in the pre dwm-5.0 fashion */ >> #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } >> @@ -84,6 +86,47 @@ static const Key keys[] = { >> { MODKEY, XK_period, focusmon, {.i = +1 } }, >> { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, >> { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, >> +// Navigation(two-handed) >> +KEYEVENT(Mod1Mask, XK_h, 0, XK_Left) >> +KEYEVENT(Mod1Mask, XK_l, 0, XK_Right) >> +KEYEVENT(Mod1Mask, XK_k, 0, XK_Up) >> +KEYEVENT(Mod1Mask, XK_j, 0, XK_Down) >> +KEYEVENT(Mod1Mask, XK_p, 0, XK_Up) >> +KEYEVENT(Mod1Mask, XK_n, 0, XK_Down) >> +KEYEVENT(Mod1Mask, XK_i, ControlMask, XK_Left) >> +KEYEVENT(Mod1Mask, XK_o, ControlMask, XK_Right) >> +KEYEVENT(Mod1Mask, XK_q, ControlMask, XK_Left) >> +KEYEVENT(Mod1Mask, XK_w, ControlMask, XK_Right) >> +KEYEVENT(Mod1Mask, XK_equal, ControlMask, XK_Home) >> +KEYEVENT(Mod1Mask, XK_minus, ControlMask, XK_End) >> +// Navigation(one-handed) >> +KEYEVENT(Mod1Mask, XK_s, 0, XK_Up) >> +KEYEVENT(Mod1Mask, XK_x, 0, XK_Down) >> +KEYEVENT(Mod1Mask, XK_z, 0, XK_Left) >> +KEYEVENT(Mod1Mask, XK_c, 0, XK_Right) >> +KEYEVENT(Mod1Mask, XK_d, 0, XK_Return) >> +KEYEVENT(Mod1Mask, XK_a, 0, XK_Home) >> +KEYEVENT(Mod1Mask, XK_e, 0, XK_End) >> +// Selection(two-handed) >> +KEYEVENT(Mod1Mask|ShiftMask, XK_h, ShiftMask, XK_Left) >> +KEYEVENT(Mod1Mask|ShiftMask, XK_l, ShiftMask, XK_Right) >> +KEYEVENT(Mod1Mask|ShiftMask, XK_k, ShiftMask, XK_Up) >> +KEYEVENT(Mod1Mask|ShiftMask, XK_j, ShiftMask, XK_Down) >> +KEYEVENT(Mod1Mask|ShiftMask, XK_p, ShiftMask, XK_Up) >> +KEYEVENT(Mod1Mask|ShiftMask, XK_n, ShiftMask, XK_Down) >> +KEYEVENT(Mod1Mask|ShiftMask, XK_i, ControlMask|ShiftMask, XK_Left) >> +KEYEVENT(Mod1Mask|ShiftMask, XK_o, ControlMask|ShiftMask, XK_Right) >> +KEYEVENT(Mod1Mask|ShiftMask, XK_equal, ControlMask|ShiftMask, XK_Home) >> +KEYEVENT(Mod1Mask|ShiftMask, XK_minus, ControlMask|ShiftMask, XK_End) >> +// Selection(one-handed) >> +KEYEVENT(Mod1Mask|ShiftMask, XK_s, ShiftMask, XK_Up) >> +KEYEVENT(Mod1Mask|ShiftMask, XK_x, ShiftMask, XK_Down) >> +KEYEVENT(Mod1Mask|ShiftMask, XK_z, ShiftMask, XK_Left) >> +KEYEVENT(Mod1Mask|ShiftMask, XK_c, ShiftMask, XK_Right) >> +KEYEVENT(Mod1Mask|ShiftMask, XK_q, ControlMask|ShiftMask, XK_Left) >> +KEYEVENT(Mod1Mask|ShiftMask, XK_w, ControlMask|ShiftMask, XK_Right) >> +KEYEVENT(Mod1Mask|ShiftMask, XK_a, ShiftMask, XK_Home) >> +KEYEVENT(Mod1Mask|ShiftMask, XK_e, ShiftMask, XK_End) >> TAGKEYS(XK_1, 0) >> TAGKEYS(XK_2, 1) >> TAGKEYS(XK_3, 2) >> diff --git a/dwm.c b/dwm.c >> index e5efb6a..6988c77 100644 >> --- a/dwm.c >> +++ b/dwm.c >> @@ -106,6 +106,11 @@ typedef struct { >> const Arg arg; >> } Key; >> >> +typedef struct { >> +unsigned int mod; >> +KeySym keysym; >> +} KeyShortcut; >> + >> typedef struct { >> const char *symbol; >> void (*arrange)(Monitor *); >> @@ -196,6 +201,7 @@ static void restack(Monitor *m); >> static void run(void); >> static void scan(void); >> static int sendevent(Client *c, Atom proto); >> +static void sendkeyevent(const Arg *arg); >> static void sendmon(Client *c, Monitor *m); >> static void setclientstate(Client *c, long state); >> static void setfocus(Client *c); >> @@ -1458,6 +1464,47 @@ sendevent(Client *c, Atom proto) >> return exists; >> } >> >> +XKeyEvent >> +createkeyevent(Display *display, Window win, Window rootWindow, int type, >> KeyShortcut *keyShortcut) >> +{ >> +int keysym = keyShortcut->keysym; >> +unsigned int modifier = keyShortcut->mod; >> + >> +XKeyEvent event; >> +event.type = type; >> +event.display = display; >> +event.window = win;
[hackers] [sbase] ed: Deal signals in a reliable way || Roberto E. Vargas Caballero
commit d3780956a991d64056a4bade210fffca53c531a3 Author: Roberto E. Vargas Caballero AuthorDate: Fri Sep 22 23:10:30 2023 +0200 Commit: Roberto E. Vargas Caballero CommitDate: Tue Sep 26 11:33:45 2023 +0200 ed: Deal signals in a reliable way The signal handlers were calling longjmp() but as the code was calling non signal safe functions the behaviour was very unpredictable generating segmentation faults and dead lock. This commit changes the signal handlers to only set a variable that is checked in safe places where long loops happen. diff --git a/TODO b/TODO index 7a21d8f..3b60785 100644 --- a/TODO +++ b/TODO @@ -32,7 +32,6 @@ ed g/^line/a \ line1 . -* Signal handling is broken. * catstr = NULL; + s->siz = 0; + s->cap = 0; + + return s; +} + static char * addchar(char c, String *s) { @@ -136,6 +149,8 @@ addchar(char c, String *s) return t; } +static void chksignals(void); + static int input(void) { @@ -146,6 +161,9 @@ input(void) if ((c = getchar()) != EOF) addchar(c, &cmdline); + + chksignals(); + return c; } @@ -455,6 +473,8 @@ search(int way) i = curln; do { + chksignals(); + i = (way == '?') ? prevln(i) : nextln(i); if (i > 0 && match(i)) return i; @@ -636,12 +656,66 @@ deflines(int def1, int def2) error("invalid address"); } +static void +quit(void) +{ + clearbuf(); + exit(exstatus); +} + +static void dowrite(const char *, int); + +static void +dump(void) +{ + char *home; + + line1 = nextln(0); + line2 = lastln; + + if (!setjmp(savesp)) { + dowrite("ed.hup", 1); + return; + } + + home = getenv("HOME"); + if (!home || chdir(home) < 0) + return; + + if (!setjmp(savesp)) + dowrite("ed.hup", 1); +} + +static void +chksignals(void) +{ + if (hup) { + if (modflag) + dump(); + exstatus = 1; + quit(); + } + + if (intr) { + intr = 0; + clearerr(stdin); + error("Interrupt"); + } +} + static void dowrite(const char *fname, int trunc) { - FILE *fp; size_t bytecount = 0; - int i, r, line, sh; + int i, r, line; + FILE *aux; + static int sh; + static FILE *fp; + + if (fp) { + sh ? pclose(fp) : fclose(fp); + fp = NULL; + } if(fname[0] == '!') { sh = 1; @@ -656,6 +730,8 @@ dowrite(const char *fname, int trunc) line = curln; for (i = line1; i <= line2; ++i) { + chksignals(); + gettxt(i); bytecount += text.siz - 1; fwrite(text.str, 1, text.siz - 1, fp); @@ -663,7 +739,9 @@ dowrite(const char *fname, int trunc) curln = line2; - r = sh ? pclose(fp) : fclose(fp); + aux = fp; + fp = NULL; + r = sh ? pclose(aux) : fclose(aux); if (r) error("input/output error"); strcpy(savfname, fname); @@ -691,6 +769,7 @@ doread(const char *fname) curln = line2; for (cnt = 0; (n = getline(&s, &len, fp)) > 0; cnt += (size_t)n) { + chksignals(); if (s[n-1] != '\n') { if (len == SIZE_MAX || !(p = realloc(s, ++len))) error("out of memory"); @@ -718,6 +797,7 @@ doprint(void) if (line1 <= 0 || line2 > lastln) error("incorrect address"); for (i = line1; i <= line2; ++i) { + chksignals(); if (pflag == 'n') printf("%d\t", i); for (s = gettxt(i); (c = *s) != '\n'; ++s) { @@ -867,11 +947,11 @@ join(void) { int i; char *t, c; - String s; + static String s; - s.str = NULL; - s.siz = s.cap = 0; + string(&s); for (i = line1;; i = nextln(i)) { + chksignals(); for (t = gettxt(i); (c = *t) != '\n'; ++t) addchar(*t, &s); if (i == line2) @@ -898,6 +978,7 @@ scroll(int num) if (max > lastln) max = lastln; for (cnt = line1; cnt < max; cnt++) { + chksignals(); fputs(gettxt(ln), stdout); ln = nextln(ln); } @@ -913,6 +994,7 @@ copy(int where) curln = where; while (line1 <= line2) { + chksignals(); inject(gettxt(line1), AFTER); if (line2 >= curln) line2 = nextln(line2); @@ -922,13 +1004,6 @@ copy(int where) } } -static void -quit(void) -{ - clearbuf(); - exit(exstatus); -} - static void execs
Re: [hackers] [sbase][PATCH] Ensure commands are followed by a blank
Applied.
[hackers] [sbase] Ensure commands are followed by a blank || Rene Kita
commit 95b96039755e86cf263bae342ed719e751bf0c1b Author: Rene Kita AuthorDate: Tue Sep 26 08:17:00 2023 +0200 Commit: k0ga CommitDate: Tue Sep 26 10:50:15 2023 +0200 Ensure commands are followed by a blank POSIX.1-2017 demands in Shell & Utilities under 'Commands in ed': The e, E, f, r, and w commands shall take an optional file parameter, separated from the command letter by one or more characters. Ensure at least one character (as defined for the POSIX locale) is present or error out. Signed-off-by: Rene Kita diff --git a/ed.c b/ed.c index e14b7ad..b7ab16f 100644 --- a/ed.c +++ b/ed.c @@ -474,6 +474,24 @@ skipblank(void) back(c); } +static void +ensureblank(void) +{ + char c; + + switch ((c = input())) { + case ' ': + case '\t': + skipblank(); + case '\n': + back(c); + case EOF: + break; + default: + error("unknown command"); + } +} + static int getnum(void) { @@ -1145,10 +1163,12 @@ repeat: case 'w': trunc = 1; case 'W': + ensureblank(); deflines(nextln(0), lastln); dowrite(getfname(cmd), trunc); break; case 'r': + ensureblank(); if (nlines > 1) goto bad_address; deflines(lastln, lastln); @@ -1260,6 +1280,7 @@ repeat: quit(); break; case 'f': + ensureblank(); if (nlines > 0) goto unexpected; if (back(input()) != '\n') @@ -1271,6 +1292,7 @@ repeat: case 'E': modflag = 0; case 'e': + ensureblank(); if (nlines > 0) goto unexpected; if (modflag)
[hackers] [ubase] Explicitly include sys/sysmacros.h for makedev etc || Markus Rudy
commit a015607af0075badc0cd90523c43f391daa0572d Author: Markus Rudy AuthorDate: Fri Sep 22 10:06:21 2023 +0200 Commit: Roberto E. Vargas Caballero CommitDate: Tue Sep 26 09:22:32 2023 +0200 Explicitly include sys/sysmacros.h for makedev etc This header used to be included by sys/types.h in glibc, and musl adopted the behaviour. However, this dependency was never desired, so glibc deprecated it in 2016 and finally removed it in 2019, and so did musl. Explicitly including the header should be a no-op on older libc versions and fixes the build on newer versions. https://sourceware.org/bugzilla/show_bug.cgi?id=19239 https://git.musl-libc.org/cgit/musl/commit/?id=f552c79 diff --git a/libutil/tty.c b/libutil/tty.c index bceb01e..3cb3b70 100644 --- a/libutil/tty.c +++ b/libutil/tty.c @@ -1,4 +1,5 @@ /* See LICENSE file for copyright and license details. */ +#include #include #include diff --git a/mknod.c b/mknod.c index 8de35c7..518ecb0 100644 --- a/mknod.c +++ b/mknod.c @@ -1,5 +1,6 @@ /* See LICENSE file for copyright and license details. */ #include +#include #include #include diff --git a/mountpoint.c b/mountpoint.c index 8f205a2..9a31bbe 100644 --- a/mountpoint.c +++ b/mountpoint.c @@ -1,5 +1,6 @@ /* See LICENSE file for copyright and license details. */ #include +#include #include #include diff --git a/stat.c b/stat.c index 220a659..9e96d80 100644 --- a/stat.c +++ b/stat.c @@ -1,5 +1,6 @@ /* See LICENSE file for copyright and license details. */ #include +#include #include #include