[hackers] [libgrapheme] Add lg_utf8_*() manuals to Makefile MAN3-variable || Laslo Hunhold
commit 29c6958306523d0370488403717047ceb960bc69 Author: Laslo Hunhold AuthorDate: Sat Dec 18 01:44:28 2021 +0100 Commit: Laslo Hunhold CommitDate: Sat Dec 18 01:44:28 2021 +0100 Add lg_utf8_*() manuals to Makefile MAN3-variable Signed-off-by: Laslo Hunhold diff --git a/Makefile b/Makefile index 104d805..64327f3 100644 --- a/Makefile +++ b/Makefile @@ -27,6 +27,8 @@ TEST =\ MAN3 =\ man/lg_grapheme_isbreak.3\ man/lg_grapheme_nextbreak.3\ + man/lg_utf8_decode.3\ + man/lg_utf8_encode.3\ MAN7 = man/libgrapheme.7
[hackers] [libgrapheme] Add manual pages for lg_utf8_*() and refactor lg_grapheme_nextbreak() || Laslo Hunhold
commit 4aa9cbec9fa8cc9faeddadac5f4108c367d40718 Author: Laslo Hunhold AuthorDate: Sat Dec 18 01:26:53 2021 +0100 Commit: Laslo Hunhold CommitDate: Sat Dec 18 01:26:53 2021 +0100 Add manual pages for lg_utf8_*() and refactor lg_grapheme_nextbreak() Officially document how to treat null-terminated strings and use (size_t)-1 instead of some magic number 5. Using the maximum allowed size indicates clearly that len is not used at all within the decoder. Signed-off-by: Laslo Hunhold diff --git a/man/lg_utf8_decode.3 b/man/lg_utf8_decode.3 new file mode 100644 index 000..5dfb50a --- /dev/null +++ b/man/lg_utf8_decode.3 @@ -0,0 +1,101 @@ +.Dd 2021-12-17 +.Dt LG_UTF8_DECODE 3 +.Os suckless.org +.Sh NAME +.Nm lg_utf8_decode +.Nd decode first code point in UTF-8-encoded string +.Sh SYNOPSIS +.In grapheme.h +.Ft size_t +.Fn lg_utf8_decode "const char *str" "size_t len" "uint_least32_t *cp" +.Sh DESCRIPTION +The +.Fn lg_utf8_decode +function decodes the next code point in the UTF-8-encoded string +.Va str +of length +.Va len . +If the UTF-8-sequence is invalid (overlong encoding, unexpected byte, +string ends unexpectedly, empty string, etc.) the decoding is stopped +at the last processed byte and the decoded code point set to +.Dv LG_INVALID_CODE_POINT. +.Pp +If +.Va cp +is not +.Dv NULL +the decoded code point is stored in the memory pointed to by +.Va cp . +.Pp +Given NUL has a unique 1 byte representation, it is safe to operate on +NUL-terminated strings by setting +.Va len +to +.Dv (size_t)-1 +and terminating when +.Va cp +is 0 (see +.Sx EXAMPLES +for an example). +.Sh RETURN VALUES +The +.Fn lg_utf8_decode +function returns the number of processed bytes and 0 if +.Va str +is +.Dv NULL +or +.Va len +is 0. +If the string ends unexpectedly in a multibyte sequence, the desired +length (that is larger than +.Va len ) +is returned. +.Sh EXAMPLES +.Bd -literal +/* cc (-static) -o example example.c -lgrapheme */ +#include +#include +#include + +void +print_cps(const char *str, size_t len) +{ + size_t ret, off; + uint_least32_t cp; + + for (off = 0; off < len; off += ret) { + if ((ret = lg_utf8_decode(str + off, + len - off, )) > (len - off)) { + /* +* string ended unexpectedly in the middle of a +* multibyte sequence and we have the choice +* here to possibly expand str by ret - len + off +* bytes to get a full sequence, but we just +* bail out in this case. +*/ + break; + } + printf("%"PRIxLEAST32"\\n", cp); + } +} + +void +print_cps_nul_terminated(const char *str) +{ + size_t ret, off; + uint_least32_t cp; + + for (off = 0; (ret = lg_utf8_decode(str + off, + (size_t)-1, )) > 0 && +cp != 0; off += ret) { + printf("%"PRIxLEAST32"\\n", cp); + } +} +.Ed +.Sh SEE ALSO +.Xr lg_grapheme_encode 3 , +.Xr lg_grapheme_isbreak 3 , +.Xr libgrapheme 7 +.Sh AUTHORS +.An Laslo Hunhold Aq Mt d...@frign.de diff --git a/man/lg_utf8_encode.3 b/man/lg_utf8_encode.3 new file mode 100644 index 000..542cdae --- /dev/null +++ b/man/lg_utf8_encode.3 @@ -0,0 +1,98 @@ +.Dd 2021-12-17 +.Dt LG_UTF8_ENCODE 3 +.Os suckless.org +.Sh NAME +.Nm lg_utf8_encode +.Nd encode code point into UTF-8 string +.Sh SYNOPSIS +.In grapheme.h +.Ft size_t +.Fn lg_utf8_encode "uint_least32_t cp" "char *" "size_t" +.Sh DESCRIPTION +The +.Fn lg_utf8_encode +function encodes the code point +.Va cp +into a UTF-8-string. +If +.Va str +is not +.Dv NULL +and +.Va len +is large enough it writes the UTF-8-string to the memory pointed to by +.Va str . +.Sh RETURN VALUES +The +.Fn lg_utf8_encode +function returns the length (in bytes) of the UTF-8-string resulting +from encoding +.Va cp . +When the returned value is larger than +.Va len +it is indicated that the output string is too small and no data has been +written. +.Sh EXAMPLES +.Bd -literal +/* cc (-static) -o example example.c -lgrapheme */ +#include +#include +#include + +size_t +cps_to_utf8(const uint_least32_t *cp, size_t cplen, char *str, size_t len) +{ + size_t i, off, ret; + + for (i = 0, off = 0; i < cplen; i++, off += ret) { + if ((ret = lg_utf8_encode(cp[i], str + off, + len - off)) > (len - off)) { + /* buffer too small */ + break; + } + } + + return off; +} + +size_t +cps_bytelen(const uint_least32_t *cp, size_t cplen) +{ + size_t i, len; + + for (i = 0, len = 0; i < cplen; i++) { + len += lg_utf8_encode(cp[i], NULL, 0); + } + + return len; +} + +char * +cps_to_utf8_alloc(const uint_least32_t
[hackers] [libgrapheme] Refactor manual pages for lg_grapheme_*() || Laslo Hunhold
commit 031a47497bd4ef470bd48b8c9455ae4ce9d88121 Author: Laslo Hunhold AuthorDate: Sat Dec 18 01:25:49 2021 +0100 Commit: Laslo Hunhold CommitDate: Sat Dec 18 01:25:49 2021 +0100 Refactor manual pages for lg_grapheme_*() Signed-off-by: Laslo Hunhold diff --git a/man/lg_grapheme_isbreak.3 b/man/lg_grapheme_isbreak.3 index 2570b2f..2d975dd 100644 --- a/man/lg_grapheme_isbreak.3 +++ b/man/lg_grapheme_isbreak.3 @@ -1,4 +1,4 @@ -.Dd 2021-12-15 +.Dd 2021-12-18 .Dt LG_GRAPHEME_ISBREAK 3 .Os suckless.org .Sh NAME @@ -7,16 +7,16 @@ .Sh SYNOPSIS .In grapheme.h .Ft size_t -.Fn lg_grapheme_isbreak "uint_least32_t a, uint_least32_t b, LG_SEGMENTATION_STATE *state" +.Fn lg_grapheme_isbreak "uint_least32_t cp1" "uint_least32_t cp2" "LG_SEGMENTATION_STATE *state" .Sh DESCRIPTION The .Fn lg_grapheme_isbreak function determines if there is a grapheme cluster break (see .Xr libgrapheme 7 ) between the two code points -.Va a +.Va cp1 and -.Va b . +.Va cp2 . By specification this decision depends on a .Va state that can at most be completely reset after detecting a break and must @@ -29,13 +29,14 @@ is .Fn lg_grapheme_isbreak behaves as if it was called with a fully reset state. .Sh RETURN VALUES +The .Fn lg_grapheme_isbreak -returns +function returns .Va true if there is a grapheme cluster break between the code points -.Va a +.Va cp1 and -.Va b +.Va cp2 and .Va false if there is not. diff --git a/man/lg_grapheme_nextbreak.3 b/man/lg_grapheme_nextbreak.3 index ff78395..cad7faf 100644 --- a/man/lg_grapheme_nextbreak.3 +++ b/man/lg_grapheme_nextbreak.3 @@ -1,4 +1,4 @@ -.Dd 2021-12-15 +.Dd 2021-12-18 .Dt LG_GRAPHEME_NEXTBREAK 3 .Os suckless.org .Sh NAME @@ -9,8 +9,9 @@ .Ft size_t .Fn lg_grapheme_nextbreak "const char *str" .Sh DESCRIPTION +The .Fn lg_grapheme_nextbreak -computes the offset (in bytes) to the next grapheme +function computes the offset (in bytes) to the next grapheme cluster break (see .Xr libgrapheme 7 ) in the UTF-8-encoded NUL-terminated string @@ -23,8 +24,9 @@ For non-UTF-8 input data .Xr lg_grapheme_isbreak 3 can be used instead. .Sh RETURN VALUES +The .Fn lg_grapheme_nextbreak -returns the offset (in bytes) to the next grapheme cluster +function returns the offset (in bytes) to the next grapheme cluster break in .Va str or 0 if
[hackers] [libgrapheme] Improve a small edge-case in lg_utf8_decode() || Laslo Hunhold
commit faeaa564686873e4720a0c1ef9879f58347d754e Author: Laslo Hunhold AuthorDate: Sat Dec 18 01:04:37 2021 +0100 Commit: Laslo Hunhold CommitDate: Sat Dec 18 01:23:32 2021 +0100 Improve a small edge-case in lg_utf8_decode() Okay, this case is really crazy but possible: Before this change, when we encountered e.g. a 0xF0 (which indicates a 4-byte-UTF-8 sequence and implies 3 subsequent continuation bytes) but have a string-length of e.g. 2, we would automatically return 4 (> 2) no matter how the following bytes look like to indicate that we need a larger buffer. However, it's actually necessary to check the subsequent bytes until the buffer-end as we might have a case like 0xF0 0x80 0x00 where 0xF0 is followed by a single continuation byte but then the continuation stops and we have a NUL-byte. It's more expected to return 2 in such a situation because we obtain more information about the string by inspecting the continuation bytes instead of throwing our hands up so early. Also add this to the test-cases of the decoder to prevent any regressions. Signed-off-by: Laslo Hunhold diff --git a/src/utf8.c b/src/utf8.c index c04fc0b..efd6068 100644 --- a/src/utf8.c +++ b/src/utf8.c @@ -84,11 +84,29 @@ lg_utf8_decode(const char *s, size_t n, uint_least32_t *cp) } if (1 + off > n) { /* -* input is not long enough, set cp as invalid and -* return number of bytes needed +* input is not long enough, set cp as invalid */ *cp = LG_INVALID_CODE_POINT; - return 1 + off; + + /* +* count the following continuation bytes, but nothing +* else in case we have a "rogue" case where e.g. such a +* sequence starter occurs right before a NUL-byte. +*/ + for (i = 0; 1 + i < n; i++) { + if(!BETWEEN(((const unsigned char *)s)[1 + i], + 0x80, 0xBF)) { + break; + } + } + + /* +* if the continuation bytes do not continue until +* the end, return the incomplete sequence length. +* Otherwise return the number of bytes we actually +* expected, which is larger than n. +*/ + return ((1 + i) < n) ? (1 + i) : (1 + off); } /* diff --git a/test/utf8-decode.c b/test/utf8-decode.c index 0749688..d98314c 100644 --- a/test/utf8-decode.c +++ b/test/utf8-decode.c @@ -113,6 +113,16 @@ static const struct { .exp_len = 1, .exp_cp = LG_INVALID_CODE_POINT, }, + { + /* invalid 3-byte sequence (short string, second byte malformed) +* [ 1110 0111 ] -> +* INVALID +*/ + .arr = (char *)(unsigned char[]){ 0xE0, 0x7F }, + .len = 2, + .exp_len = 1, + .exp_cp = LG_INVALID_CODE_POINT, + }, { /* invalid 3-byte sequence (third byte missing) * [ 1110 1011 ] -> @@ -183,6 +193,27 @@ static const struct { .exp_len = 1, .exp_cp = LG_INVALID_CODE_POINT, }, + { + /* invalid 4-byte sequence (short string 1, second byte malformed) +* [ 0011 0 ] -> +* INVALID +*/ + .arr = (char *)(unsigned char[]){ 0xF3, 0x7F }, + .len = 2, + .exp_len = 1, + .exp_cp = LG_INVALID_CODE_POINT, + }, + { + /* invalid 4-byte sequence (short string 2, second byte malformed) +* [ 0011 0 1011 ] -> +* INVALID +*/ + .arr = (char *)(unsigned char[]){ 0xF3, 0x7F, 0xBF }, + .len = 3, + .exp_len = 1, + .exp_cp = LG_INVALID_CODE_POINT, + }, + { /* invalid 4-byte sequence (third byte missing) * [ 0011 1011 ] -> @@ -203,6 +234,16 @@ static const struct { .exp_len = 2, .exp_cp = LG_INVALID_CODE_POINT, }, + { + /* invalid 4-byte sequence (short string, third byte malformed) +* [ 0011 1011 0111 ] -> +* INVALID +*/ + .arr = (char *)(unsigned char[]){ 0xF3, 0xBF, 0x7F }, + .len = 3, + .exp_len = 2, + .exp_cp = LG_INVALID_CODE_POINT, + }, { /* invalid 4-byte sequence (fourth byte missing) * [
Re: [hackers] [dwm][patch] gaplessgrid focus left/right
Thanks for letting me know. Best regards On Fri, Dec 17, 2021, 11:53 Hiltjo Posthuma wrote: > You send it to the wrong mailinglist. > > If its a wiki patch you can upload it, see the wiki guidelines. > > Thanks, > > On Fri, Dec 17, 2021 at 02:03:15AM +0200, שלומי אקנין wrote: > > From 76d72e24117a5626827cfb0ef49515ec7f7dd4fe Mon Sep 17 00:00:00 2001 > > From: shlomi-aknin > > Date: Thu, 16 Dec 2021 14:53:02 +0200 > > Subject: [PATCH] This patch incorporates gaplessgrid patch. This patch > adds > > the ability to focus on left or right window of the current window > (works > > in > > gaplessgrid layout only) > > > > --- > > config.def.h | 5 +++- > > dwm.c | 74 +++- > > 2 files changed, 77 insertions(+), 2 deletions(-) > > > > diff --git a/config.def.h b/config.def.h > > index a2ac963..c63a640 100644 > > --- a/config.def.h > > +++ b/config.def.h > > @@ -42,6 +42,7 @@ static const Layout layouts[] = { > > { "[]=", tile }, /* first entry is default */ > > { "><>", NULL }, /* no layout function means floating behavior */ > > { "[M]", monocle }, > > + { "###", gaplessgrid }, > > }; > > > > /* key definitions */ > > @@ -77,6 +78,7 @@ static Key keys[] = { > > { MODKEY, XK_t, setlayout, {.v = [0]} }, > > { MODKEY, XK_f, setlayout, {.v = [1]} }, > > { MODKEY, XK_m, setlayout, {.v = [2]} }, > > + { MODKEY, XK_g, setlayout, {.v = [3]} }, > > { MODKEY, XK_space, setlayout, {0} }, > > { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, > > { MODKEY, XK_0, view, {.ui = ~0 } }, > > @@ -85,6 +87,8 @@ static Key keys[] = { > > { MODKEY, XK_period, focusmon, {.i = +1 } }, > > { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, > > { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, > > + { MODKEY|ControlMask, XK_l, gaplessgridleftright, {.i = +1 } }, > > + { MODKEY|ControlMask, XK_h, gaplessgridleftright, {.i = -1 } }, > > TAGKEYS( XK_1, 0) > > TAGKEYS( XK_2, 1) > > TAGKEYS( XK_3, 2) > > @@ -113,4 +117,3 @@ static Button buttons[] = { > > { ClkTagBar, MODKEY, Button1, tag, {0} }, > > { ClkTagBar, MODKEY, Button3, toggletag, {0} }, > > }; > > - > > diff --git a/dwm.c b/dwm.c > > index 5e4d494..a7fb265 100644 > > --- a/dwm.c > > +++ b/dwm.c > > @@ -91,6 +91,7 @@ struct Client { > > int oldx, oldy, oldw, oldh; > > int basew, baseh, incw, inch, maxw, maxh, minw, minh; > > int bw, oldbw; > > + int gridrow, gridcol; > > unsigned int tags; > > int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen; > > Client *next; > > @@ -169,6 +170,8 @@ static void focus(Client *c); > > static void focusin(XEvent *e); > > static void focusmon(const Arg *arg); > > static void focusstack(const Arg *arg); > > +static void gaplessgrid(Monitor *m); > > +static void gaplessgridleftright(const Arg *arg); > > static Atom getatomprop(Client *c, Atom prop); > > static int getrootptr(int *x, int *y); > > static long getstate(Window w); > > @@ -856,6 +859,76 @@ focusstack(const Arg *arg) > > } > > } > > > > +void > > +gaplessgrid(Monitor *m) > > +{ > > + unsigned int n, cols, rows, cn, rn, i, cx, cy, cw, ch; > > + Client *c; > > + > > + for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) ; > > + if(n == 0) > > + return; > > + > > + /* grid dimensions */ > > + for(cols = 0; cols <= n/2; cols++) > > + if(cols*cols >= n) > > + break; > > + if(n == 5) /* set layout against the general calculation: not 1:2:2, > but > > 2:3 */ > > + cols = 2; > > + rows = n/cols; > > + > > + /* window geometries */ > > + cw = cols ? m->ww / cols : m->ww; > > + cn = 0; /* current column number */ > > + rn = 0; /* current row number */ > > + for(i = 0, c = nexttiled(m->clients); c; i++, c = nexttiled(c->next)) { > > + if(i/rows + 1 > cols - n%cols) > > + rows = n/cols + 1; > > + ch = rows ? m->wh / rows : m->wh; > > + cx = m->wx + cn*cw; > > + cy = m->wy + rn*ch; > > + c->gridrow = rn; > > + c->gridcol = cn; > > + resize(c, cx, cy, cw - 2 * c->bw, ch - 2 * c->bw, False); > > + rn++; > > + if(rn >= rows) { > > + rn = 0; > > + cn++; > > + } > > + } > > +} > > + > > +void > > +gaplessgridleftright(const Arg *arg) > > +{ > > + Client *c = selmon->sel; > > + Client *t = NULL; > > + int found = 0; > > + if(selmon->lt[selmon->sellt]->arrange != gaplessgrid || !ISVISIBLE(c)) > > return; > > + > > + if (arg->i > 0) { > > + for(t = selmon->sel->next; t; t = t->next) { > > + if (t->gridcol == c->gridcol + 1 && t->gridrow == c->gridrow) break; > > + } > > + } else { > > + for(t = selmon->clients; t; t = t->next) { > > + if (t->gridcol == c->gridcol - 1 && t->gridrow == c->gridrow) { > > + found = 1; > > + break; > > + } > > + } > > + > > + if (found == 0) { > > + for(t = selmon->clients; t; t = t->next) { > > + if (t->gridcol == c->gridcol - 1 && t->gridrow == c->gridrow - 1) > break; > > + } > > + } > > + } > > + > > + focus(t); > > + arrange(selmon); > > +} > > + > > Atom > > getatomprop(Client *c, Atom prop) > > { > > @@ -1597,7 +1670,6
Re: [hackers] [dwm][patch] gaplessgrid focus left/right
You send it to the wrong mailinglist. If its a wiki patch you can upload it, see the wiki guidelines. Thanks, On Fri, Dec 17, 2021 at 02:03:15AM +0200, שלומי אקנין wrote: > From 76d72e24117a5626827cfb0ef49515ec7f7dd4fe Mon Sep 17 00:00:00 2001 > From: shlomi-aknin > Date: Thu, 16 Dec 2021 14:53:02 +0200 > Subject: [PATCH] This patch incorporates gaplessgrid patch. This patch adds > the ability to focus on left or right window of the current window (works > in > gaplessgrid layout only) > > --- > config.def.h | 5 +++- > dwm.c | 74 +++- > 2 files changed, 77 insertions(+), 2 deletions(-) > > diff --git a/config.def.h b/config.def.h > index a2ac963..c63a640 100644 > --- a/config.def.h > +++ b/config.def.h > @@ -42,6 +42,7 @@ static const Layout layouts[] = { > { "[]=", tile }, /* first entry is default */ > { "><>", NULL }, /* no layout function means floating behavior */ > { "[M]", monocle }, > + { "###", gaplessgrid }, > }; > > /* key definitions */ > @@ -77,6 +78,7 @@ static Key keys[] = { > { MODKEY, XK_t, setlayout, {.v = [0]} }, > { MODKEY, XK_f, setlayout, {.v = [1]} }, > { MODKEY, XK_m, setlayout, {.v = [2]} }, > + { MODKEY, XK_g, setlayout, {.v = [3]} }, > { MODKEY, XK_space, setlayout, {0} }, > { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, > { MODKEY, XK_0, view, {.ui = ~0 } }, > @@ -85,6 +87,8 @@ static Key keys[] = { > { MODKEY, XK_period, focusmon, {.i = +1 } }, > { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, > { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, > + { MODKEY|ControlMask, XK_l, gaplessgridleftright, {.i = +1 } }, > + { MODKEY|ControlMask, XK_h, gaplessgridleftright, {.i = -1 } }, > TAGKEYS( XK_1, 0) > TAGKEYS( XK_2, 1) > TAGKEYS( XK_3, 2) > @@ -113,4 +117,3 @@ static Button buttons[] = { > { ClkTagBar, MODKEY, Button1, tag, {0} }, > { ClkTagBar, MODKEY, Button3, toggletag, {0} }, > }; > - > diff --git a/dwm.c b/dwm.c > index 5e4d494..a7fb265 100644 > --- a/dwm.c > +++ b/dwm.c > @@ -91,6 +91,7 @@ struct Client { > int oldx, oldy, oldw, oldh; > int basew, baseh, incw, inch, maxw, maxh, minw, minh; > int bw, oldbw; > + int gridrow, gridcol; > unsigned int tags; > int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen; > Client *next; > @@ -169,6 +170,8 @@ static void focus(Client *c); > static void focusin(XEvent *e); > static void focusmon(const Arg *arg); > static void focusstack(const Arg *arg); > +static void gaplessgrid(Monitor *m); > +static void gaplessgridleftright(const Arg *arg); > static Atom getatomprop(Client *c, Atom prop); > static int getrootptr(int *x, int *y); > static long getstate(Window w); > @@ -856,6 +859,76 @@ focusstack(const Arg *arg) > } > } > > +void > +gaplessgrid(Monitor *m) > +{ > + unsigned int n, cols, rows, cn, rn, i, cx, cy, cw, ch; > + Client *c; > + > + for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) ; > + if(n == 0) > + return; > + > + /* grid dimensions */ > + for(cols = 0; cols <= n/2; cols++) > + if(cols*cols >= n) > + break; > + if(n == 5) /* set layout against the general calculation: not 1:2:2, but > 2:3 */ > + cols = 2; > + rows = n/cols; > + > + /* window geometries */ > + cw = cols ? m->ww / cols : m->ww; > + cn = 0; /* current column number */ > + rn = 0; /* current row number */ > + for(i = 0, c = nexttiled(m->clients); c; i++, c = nexttiled(c->next)) { > + if(i/rows + 1 > cols - n%cols) > + rows = n/cols + 1; > + ch = rows ? m->wh / rows : m->wh; > + cx = m->wx + cn*cw; > + cy = m->wy + rn*ch; > + c->gridrow = rn; > + c->gridcol = cn; > + resize(c, cx, cy, cw - 2 * c->bw, ch - 2 * c->bw, False); > + rn++; > + if(rn >= rows) { > + rn = 0; > + cn++; > + } > + } > +} > + > +void > +gaplessgridleftright(const Arg *arg) > +{ > + Client *c = selmon->sel; > + Client *t = NULL; > + int found = 0; > + if(selmon->lt[selmon->sellt]->arrange != gaplessgrid || !ISVISIBLE(c)) > return; > + > + if (arg->i > 0) { > + for(t = selmon->sel->next; t; t = t->next) { > + if (t->gridcol == c->gridcol + 1 && t->gridrow == c->gridrow) break; > + } > + } else { > + for(t = selmon->clients; t; t = t->next) { > + if (t->gridcol == c->gridcol - 1 && t->gridrow == c->gridrow) { > + found = 1; > + break; > + } > + } > + > + if (found == 0) { > + for(t = selmon->clients; t; t = t->next) { > + if (t->gridcol == c->gridcol - 1 && t->gridrow == c->gridrow - 1) break; > + } > + } > + } > + > + focus(t); > + arrange(selmon); > +} > + > Atom > getatomprop(Client *c, Atom prop) > { > @@ -1597,7 +1670,6 @@ setup(void) > focus(NULL); > } > > - > void > seturgent(Client *c, int urg) > { > -- > 2.34.1 > From 76d72e24117a5626827cfb0ef49515ec7f7dd4fe Mon Sep 17 00:00:00 2001 > From: shlomi-aknin > Date: Thu, 16 Dec 2021 14:53:02 +0200 > Subject: [PATCH] This patch incorporates gaplessgrid patch. This patch adds > the ability to focus on left or right window of the current window (works in >