5 Commits

Author SHA1 Message Date
d0c62ba1db Applied anysize patch 2025-05-05 12:53:07 +01:00
98610fcd37 Do not interpret CSI ? u as DECRC
The kitty keyboard protocol docs recommend CSI ? u to query support for
that protocol, see https://sw.kovidgoyal.net/kitty/keyboard-protocol/

For better or worse, fish shell uses this query to work around bugs
in other terminals triggered by requesting that protocol via CSI = 5 u.

Unfortunately, st interprets CSI ? u as DECRC (restore cursor
position). reproduce with 'printf "\x1b[?u"; cat'.

fish could work around this by switching to the alternate screen
before running this query; but that might cause tearing on terminals
that don't support Synchronized Output. I'm not sure.

In the meantime, let's correct our parser.

This adds a redundant else-after-return, for consistency with the
surrounding code.
2025-01-30 17:50:37 +01:00
6009e6e25b Clear screen: Fix edge case
With sequence \e[1J, if cursor is on second line, clear the first line.
2024-12-06 13:42:50 +01:00
a0274bc20e fix BadMatch error when embedding on some windows
When embedded, st fails with BadMatch error if the embedder's window has
non-default colormap/depth/visual.  This commit fixes that by creating
st's window inside root and then reparent it into embedder.

The reference window for dc.gc is also changed to match root's visuals.

A similar commit had been made for dmenu[1].
See this issue[2] on github for context.

[1]: https://git.suckless.org/dmenu/commit/0fe460dbd469a1d5b6a7140d0e1801935e4a923b.html
[2]: https://github.com/phillbush/xfiles/issues/47
2024-08-09 13:34:56 +02:00
5dbcca4926 support colons in SGR character attributes
Patch by Mikhail Kot <to@myrrc.dev>
With some modifications to behave more like xterm (see note below).

Example:

	printf '\033[48;2;255:0:0mtest\n'

https://invisible-island.net/xterm/ctlseqs/ctlseqs.html

Some notes:

"CSI Pm m  Character Attributes (SGR).
[...]
o   xterm allows either colons (standard) or semicolons
(legacy) to separate the subparameters (but after the
first colon, colons must be used).
2024-05-01 20:45:39 +02:00
3 changed files with 211 additions and 33 deletions

View File

@ -0,0 +1,164 @@
From 8dcdc4b21a73268e167d98aa30f24315c7f3b7ff Mon Sep 17 00:00:00 2001
From: Bakkeby <bakkeby@gmail.com>
Date: Mon, 18 Jul 2022 16:52:03 +0200
Subject: [PATCH] Adding anysize patch
---
x.c | 56 ++++++++++++++++++++++++++++++--------------------------
1 file changed, 30 insertions(+), 26 deletions(-)
diff --git a/x.c b/x.c
index 2a3bd38..f534347 100644
--- a/x.c
+++ b/x.c
@@ -81,6 +81,7 @@ typedef XftGlyphFontSpec GlyphFontSpec;
typedef struct {
int tw, th; /* tty width and height */
int w, h; /* window width and height */
+ int hborderpx, vborderpx;
int ch; /* char height */
int cw; /* char width */
int mode; /* window state/mode flags */
@@ -331,7 +332,7 @@ ttysend(const Arg *arg)
int
evcol(XEvent *e)
{
- int x = e->xbutton.x - borderpx;
+ int x = e->xbutton.x - win.hborderpx;
LIMIT(x, 0, win.tw - 1);
return x / win.cw;
}
@@ -339,7 +340,7 @@ evcol(XEvent *e)
int
evrow(XEvent *e)
{
- int y = e->xbutton.y - borderpx;
+ int y = e->xbutton.y - win.vborderpx;
LIMIT(y, 0, win.th - 1);
return y / win.ch;
}
@@ -739,6 +740,9 @@ cresize(int width, int height)
col = MAX(1, col);
row = MAX(1, row);
+ win.hborderpx = (win.w - col * win.cw) / 2;
+ win.vborderpx = (win.h - row * win.ch) / 2;
+
tresize(col, row);
xresize(col, row);
ttyresize(win.tw, win.th);
@@ -869,8 +873,8 @@ xhints(void)
sizeh->flags = PSize | PResizeInc | PBaseSize | PMinSize;
sizeh->height = win.h;
sizeh->width = win.w;
- sizeh->height_inc = win.ch;
- sizeh->width_inc = win.cw;
+ sizeh->height_inc = 1;
+ sizeh->width_inc = 1;
sizeh->base_height = 2 * borderpx;
sizeh->base_width = 2 * borderpx;
sizeh->min_height = win.ch + 2 * borderpx;
@@ -1152,8 +1156,8 @@ xinit(int cols, int rows)
xloadcols();
/* adjust fixed window geometry */
- win.w = 2 * borderpx + cols * win.cw;
- win.h = 2 * borderpx + rows * win.ch;
+ win.w = 2 * win.hborderpx + 2 * borderpx + cols * win.cw;
+ win.h = 2 * win.vborderpx + 2 * borderpx + rows * win.ch;
if (xw.gm & XNegative)
xw.l += DisplayWidth(xw.dpy, xw.scr) - win.w - 2;
if (xw.gm & YNegative)
@@ -1242,7 +1246,7 @@ xinit(int cols, int rows)
int
xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x, int y)
{
- float winx = borderpx + x * win.cw, winy = borderpx + y * win.ch, xp, yp;
+ float winx = win.hborderpx + x * win.cw, winy = win.vborderpx + y * win.ch, xp, yp;
ushort mode, prevmode = USHRT_MAX;
Font *font = &dc.font;
int frcflags = FRC_NORMAL;
@@ -1375,7 +1379,7 @@ void
xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, int y)
{
int charlen = len * ((base.mode & ATTR_WIDE) ? 2 : 1);
- int winx = borderpx + x * win.cw, winy = borderpx + y * win.ch,
+ int winx = win.hborderpx + x * win.cw, winy = win.vborderpx + y * win.ch,
width = charlen * win.cw;
Color *fg, *bg, *temp, revfg, revbg, truefg, truebg;
XRenderColor colfg, colbg;
@@ -1465,17 +1469,17 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i
/* Intelligent cleaning up of the borders. */
if (x == 0) {
- xclear(0, (y == 0)? 0 : winy, borderpx,
+ xclear(0, (y == 0)? 0 : winy, win.hborderpx,
winy + win.ch +
- ((winy + win.ch >= borderpx + win.th)? win.h : 0));
+ ((winy + win.ch >= win.vborderpx + win.th)? win.h : 0));
}
- if (winx + width >= borderpx + win.tw) {
+ if (winx + width >= win.hborderpx + win.tw) {
xclear(winx + width, (y == 0)? 0 : winy, win.w,
- ((winy + win.ch >= borderpx + win.th)? win.h : (winy + win.ch)));
+ ((winy + win.ch >= win.vborderpx + win.th)? win.h : (winy + win.ch)));
}
if (y == 0)
- xclear(winx, 0, winx + width, borderpx);
- if (winy + win.ch >= borderpx + win.th)
+ xclear(winx, 0, winx + width, win.vborderpx);
+ if (winy + win.ch >= win.vborderpx + win.th)
xclear(winx, winy + win.ch, winx + width, win.h);
/* Clean up the region we want to draw to. */
@@ -1569,35 +1573,35 @@ xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og)
case 3: /* Blinking Underline */
case 4: /* Steady Underline */
XftDrawRect(xw.draw, &drawcol,
- borderpx + cx * win.cw,
- borderpx + (cy + 1) * win.ch - \
+ win.hborderpx + cx * win.cw,
+ win.vborderpx + (cy + 1) * win.ch - \
cursorthickness,
win.cw, cursorthickness);
break;
case 5: /* Blinking bar */
case 6: /* Steady bar */
XftDrawRect(xw.draw, &drawcol,
- borderpx + cx * win.cw,
- borderpx + cy * win.ch,
+ win.hborderpx + cx * win.cw,
+ win.vborderpx + cy * win.ch,
cursorthickness, win.ch);
break;
}
} else {
XftDrawRect(xw.draw, &drawcol,
- borderpx + cx * win.cw,
- borderpx + cy * win.ch,
+ win.hborderpx + cx * win.cw,
+ win.vborderpx + cy * win.ch,
win.cw - 1, 1);
XftDrawRect(xw.draw, &drawcol,
- borderpx + cx * win.cw,
- borderpx + cy * win.ch,
+ win.hborderpx + cx * win.cw,
+ win.vborderpx + cy * win.ch,
1, win.ch - 1);
XftDrawRect(xw.draw, &drawcol,
- borderpx + (cx + 1) * win.cw - 1,
- borderpx + cy * win.ch,
+ win.hborderpx + (cx + 1) * win.cw - 1,
+ win.vborderpx + cy * win.ch,
1, win.ch - 1);
XftDrawRect(xw.draw, &drawcol,
- borderpx + cx * win.cw,
- borderpx + (cy + 1) * win.ch - 1,
+ win.hborderpx + cx * win.cw,
+ win.vborderpx + (cy + 1) * win.ch - 1,
win.cw, 1);
}
}
--
2.37.1

13
st.c
View File

@ -1132,6 +1132,7 @@ csiparse(void)
{ {
char *p = csiescseq.buf, *np; char *p = csiescseq.buf, *np;
long int v; long int v;
int sep = ';'; /* colon or semi-colon, but not both */
csiescseq.narg = 0; csiescseq.narg = 0;
if (*p == '?') { if (*p == '?') {
@ -1149,7 +1150,9 @@ csiparse(void)
v = -1; v = -1;
csiescseq.arg[csiescseq.narg++] = v; csiescseq.arg[csiescseq.narg++] = v;
p = np; p = np;
if (*p != ';' || csiescseq.narg == ESC_ARG_SIZ) if (sep == ';' && *p == ':')
sep = ':'; /* allow override to colon once */
if (*p != sep || csiescseq.narg == ESC_ARG_SIZ)
break; break;
p++; p++;
} }
@ -1702,7 +1705,7 @@ csihandle(void)
} }
break; break;
case 1: /* above */ case 1: /* above */
if (term.c.y > 1) if (term.c.y > 0)
tclearregion(0, 0, term.col-1, term.c.y-1); tclearregion(0, 0, term.col-1, term.c.y-1);
tclearregion(0, term.c.y, term.c.x, term.c.y); tclearregion(0, term.c.y, term.c.x, term.c.y);
break; break;
@ -1798,7 +1801,11 @@ csihandle(void)
tcursor(CURSOR_SAVE); tcursor(CURSOR_SAVE);
break; break;
case 'u': /* DECRC -- Restore cursor position (ANSI.SYS) */ case 'u': /* DECRC -- Restore cursor position (ANSI.SYS) */
tcursor(CURSOR_LOAD); if (csiescseq.priv) {
goto unknown;
} else {
tcursor(CURSOR_LOAD);
}
break; break;
case ' ': case ' ':
switch (csiescseq.mode[1]) { switch (csiescseq.mode[1]) {

67
x.c
View File

@ -81,6 +81,7 @@ typedef XftGlyphFontSpec GlyphFontSpec;
typedef struct { typedef struct {
int tw, th; /* tty width and height */ int tw, th; /* tty width and height */
int w, h; /* window width and height */ int w, h; /* window width and height */
int hborderpx, vborderpx;
int ch; /* char height */ int ch; /* char height */
int cw; /* char width */ int cw; /* char width */
int mode; /* window state/mode flags */ int mode; /* window state/mode flags */
@ -331,7 +332,7 @@ ttysend(const Arg *arg)
int int
evcol(XEvent *e) evcol(XEvent *e)
{ {
int x = e->xbutton.x - borderpx; int x = e->xbutton.x - win.hborderpx;
LIMIT(x, 0, win.tw - 1); LIMIT(x, 0, win.tw - 1);
return x / win.cw; return x / win.cw;
} }
@ -339,7 +340,7 @@ evcol(XEvent *e)
int int
evrow(XEvent *e) evrow(XEvent *e)
{ {
int y = e->xbutton.y - borderpx; int y = e->xbutton.y - win.vborderpx;
LIMIT(y, 0, win.th - 1); LIMIT(y, 0, win.th - 1);
return y / win.ch; return y / win.ch;
} }
@ -739,6 +740,9 @@ cresize(int width, int height)
col = MAX(1, col); col = MAX(1, col);
row = MAX(1, row); row = MAX(1, row);
win.hborderpx = (win.w - col * win.cw) / 2;
win.vborderpx = (win.h - row * win.ch) / 2;
tresize(col, row); tresize(col, row);
xresize(col, row); xresize(col, row);
ttyresize(win.tw, win.th); ttyresize(win.tw, win.th);
@ -869,8 +873,8 @@ xhints(void)
sizeh->flags = PSize | PResizeInc | PBaseSize | PMinSize; sizeh->flags = PSize | PResizeInc | PBaseSize | PMinSize;
sizeh->height = win.h; sizeh->height = win.h;
sizeh->width = win.w; sizeh->width = win.w;
sizeh->height_inc = win.ch; sizeh->height_inc = 1;
sizeh->width_inc = win.cw; sizeh->width_inc = 1;
sizeh->base_height = 2 * borderpx; sizeh->base_height = 2 * borderpx;
sizeh->base_width = 2 * borderpx; sizeh->base_width = 2 * borderpx;
sizeh->min_height = win.ch + 2 * borderpx; sizeh->min_height = win.ch + 2 * borderpx;
@ -1131,7 +1135,7 @@ xinit(int cols, int rows)
{ {
XGCValues gcvalues; XGCValues gcvalues;
Cursor cursor; Cursor cursor;
Window parent; Window parent, root;
pid_t thispid = getpid(); pid_t thispid = getpid();
XColor xmousefg, xmousebg; XColor xmousefg, xmousebg;
@ -1152,8 +1156,8 @@ xinit(int cols, int rows)
xloadcols(); xloadcols();
/* adjust fixed window geometry */ /* adjust fixed window geometry */
win.w = 2 * borderpx + cols * win.cw; win.w = 2 * win.hborderpx + 2 * borderpx + cols * win.cw;
win.h = 2 * borderpx + rows * win.ch; win.h = 2 * win.vborderpx + 2 * borderpx + rows * win.ch;
if (xw.gm & XNegative) if (xw.gm & XNegative)
xw.l += DisplayWidth(xw.dpy, xw.scr) - win.w - 2; xw.l += DisplayWidth(xw.dpy, xw.scr) - win.w - 2;
if (xw.gm & YNegative) if (xw.gm & YNegative)
@ -1168,16 +1172,19 @@ xinit(int cols, int rows)
| ButtonMotionMask | ButtonPressMask | ButtonReleaseMask; | ButtonMotionMask | ButtonPressMask | ButtonReleaseMask;
xw.attrs.colormap = xw.cmap; xw.attrs.colormap = xw.cmap;
root = XRootWindow(xw.dpy, xw.scr);
if (!(opt_embed && (parent = strtol(opt_embed, NULL, 0)))) if (!(opt_embed && (parent = strtol(opt_embed, NULL, 0))))
parent = XRootWindow(xw.dpy, xw.scr); parent = root;
xw.win = XCreateWindow(xw.dpy, parent, xw.l, xw.t, xw.win = XCreateWindow(xw.dpy, root, xw.l, xw.t,
win.w, win.h, 0, XDefaultDepth(xw.dpy, xw.scr), InputOutput, win.w, win.h, 0, XDefaultDepth(xw.dpy, xw.scr), InputOutput,
xw.vis, CWBackPixel | CWBorderPixel | CWBitGravity xw.vis, CWBackPixel | CWBorderPixel | CWBitGravity
| CWEventMask | CWColormap, &xw.attrs); | CWEventMask | CWColormap, &xw.attrs);
if (parent != root)
XReparentWindow(xw.dpy, xw.win, parent, xw.l, xw.t);
memset(&gcvalues, 0, sizeof(gcvalues)); memset(&gcvalues, 0, sizeof(gcvalues));
gcvalues.graphics_exposures = False; gcvalues.graphics_exposures = False;
dc.gc = XCreateGC(xw.dpy, parent, GCGraphicsExposures, dc.gc = XCreateGC(xw.dpy, xw.win, GCGraphicsExposures,
&gcvalues); &gcvalues);
xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h,
DefaultDepth(xw.dpy, xw.scr)); DefaultDepth(xw.dpy, xw.scr));
@ -1242,7 +1249,7 @@ xinit(int cols, int rows)
int int
xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x, int y) xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x, int y)
{ {
float winx = borderpx + x * win.cw, winy = borderpx + y * win.ch, xp, yp; float winx = win.hborderpx + x * win.cw, winy = win.vborderpx + y * win.ch, xp, yp;
ushort mode, prevmode = USHRT_MAX; ushort mode, prevmode = USHRT_MAX;
Font *font = &dc.font; Font *font = &dc.font;
int frcflags = FRC_NORMAL; int frcflags = FRC_NORMAL;
@ -1375,7 +1382,7 @@ void
xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, int y) xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, int y)
{ {
int charlen = len * ((base.mode & ATTR_WIDE) ? 2 : 1); int charlen = len * ((base.mode & ATTR_WIDE) ? 2 : 1);
int winx = borderpx + x * win.cw, winy = borderpx + y * win.ch, int winx = win.hborderpx + x * win.cw, winy = win.vborderpx + y * win.ch,
width = charlen * win.cw; width = charlen * win.cw;
Color *fg, *bg, *temp, revfg, revbg, truefg, truebg; Color *fg, *bg, *temp, revfg, revbg, truefg, truebg;
XRenderColor colfg, colbg; XRenderColor colfg, colbg;
@ -1465,17 +1472,17 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i
/* Intelligent cleaning up of the borders. */ /* Intelligent cleaning up of the borders. */
if (x == 0) { if (x == 0) {
xclear(0, (y == 0)? 0 : winy, borderpx, xclear(0, (y == 0)? 0 : winy, win.hborderpx,
winy + win.ch + winy + win.ch +
((winy + win.ch >= borderpx + win.th)? win.h : 0)); ((winy + win.ch >= win.vborderpx + win.th)? win.h : 0));
} }
if (winx + width >= borderpx + win.tw) { if (winx + width >= win.hborderpx + win.tw) {
xclear(winx + width, (y == 0)? 0 : winy, win.w, xclear(winx + width, (y == 0)? 0 : winy, win.w,
((winy + win.ch >= borderpx + win.th)? win.h : (winy + win.ch))); ((winy + win.ch >= win.vborderpx + win.th)? win.h : (winy + win.ch)));
} }
if (y == 0) if (y == 0)
xclear(winx, 0, winx + width, borderpx); xclear(winx, 0, winx + width, win.vborderpx);
if (winy + win.ch >= borderpx + win.th) if (winy + win.ch >= win.vborderpx + win.th)
xclear(winx, winy + win.ch, winx + width, win.h); xclear(winx, winy + win.ch, winx + width, win.h);
/* Clean up the region we want to draw to. */ /* Clean up the region we want to draw to. */
@ -1569,35 +1576,35 @@ xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og)
case 3: /* Blinking Underline */ case 3: /* Blinking Underline */
case 4: /* Steady Underline */ case 4: /* Steady Underline */
XftDrawRect(xw.draw, &drawcol, XftDrawRect(xw.draw, &drawcol,
borderpx + cx * win.cw, win.hborderpx + cx * win.cw,
borderpx + (cy + 1) * win.ch - \ win.vborderpx + (cy + 1) * win.ch - \
cursorthickness, cursorthickness,
win.cw, cursorthickness); win.cw, cursorthickness);
break; break;
case 5: /* Blinking bar */ case 5: /* Blinking bar */
case 6: /* Steady bar */ case 6: /* Steady bar */
XftDrawRect(xw.draw, &drawcol, XftDrawRect(xw.draw, &drawcol,
borderpx + cx * win.cw, win.hborderpx + cx * win.cw,
borderpx + cy * win.ch, win.vborderpx + cy * win.ch,
cursorthickness, win.ch); cursorthickness, win.ch);
break; break;
} }
} else { } else {
XftDrawRect(xw.draw, &drawcol, XftDrawRect(xw.draw, &drawcol,
borderpx + cx * win.cw, win.hborderpx + cx * win.cw,
borderpx + cy * win.ch, win.vborderpx + cy * win.ch,
win.cw - 1, 1); win.cw - 1, 1);
XftDrawRect(xw.draw, &drawcol, XftDrawRect(xw.draw, &drawcol,
borderpx + cx * win.cw, win.hborderpx + cx * win.cw,
borderpx + cy * win.ch, win.vborderpx + cy * win.ch,
1, win.ch - 1); 1, win.ch - 1);
XftDrawRect(xw.draw, &drawcol, XftDrawRect(xw.draw, &drawcol,
borderpx + (cx + 1) * win.cw - 1, win.hborderpx + (cx + 1) * win.cw - 1,
borderpx + cy * win.ch, win.vborderpx + cy * win.ch,
1, win.ch - 1); 1, win.ch - 1);
XftDrawRect(xw.draw, &drawcol, XftDrawRect(xw.draw, &drawcol,
borderpx + cx * win.cw, win.hborderpx + cx * win.cw,
borderpx + (cy + 1) * win.ch - 1, win.vborderpx + (cy + 1) * win.ch - 1,
win.cw, 1); win.cw, 1);
} }
} }