Skip to content

Commit ac59679

Browse files
author
__
committed
Merge remote-tracking branch 'suck/master' into master
2 parents 0dca15f + fa253f0 commit ac59679

File tree

8 files changed

+89
-39
lines changed

8 files changed

+89
-39
lines changed

FAQ

+54-5
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,22 @@
22

33
Use the excellent tool of [utmp](https://git.suckless.org/utmp/) for this task.
44

5+
56
## Some _random program_ complains that st is unknown/not recognised/unsupported/whatever!
67

78
It means that st doesn’t have any terminfo entry on your system. Chances are
89
you did not `make install`. If you just want to test it without installing it,
910
you can manually run `tic -sx st.info`.
1011

12+
1113
## Nothing works, and nothing is said about an unknown terminal!
1214

1315
* Some programs just assume they’re running in xterm i.e. they don’t rely on
1416
terminfo. What you see is the current state of the “xterm compliance”.
1517
* Some programs don’t complain about the lacking st description and default to
1618
another terminal. In that case see the question about terminfo.
1719

20+
1821
## How do I scroll back up?
1922

2023
* Using a terminal multiplexer.
@@ -23,11 +26,13 @@ you can manually run `tic -sx st.info`.
2326
* Using the excellent tool of [scroll](https://git.suckless.org/scroll/).
2427
* Using the scrollback [patch](https://st.suckless.org/patches/scrollback/).
2528

29+
2630
## I would like to have utmp and/or scroll functionality by default
2731

2832
You can add the absolute patch of both programs in your config.h
2933
file. You only have to modify the value of utmp and scroll variables.
3034

35+
3136
## Why doesn't the Del key work in some programs?
3237

3338
Taken from the terminfo manpage:
@@ -83,12 +88,14 @@ If you are using zsh, then read the zsh FAQ
8388

8489
Putting these lines into your .zshrc will fix the problems.
8590

91+
8692
## How can I use meta in 8bit mode?
8793

8894
St supports meta in 8bit mode, but the default terminfo entry doesn't
8995
use this capability. If you want it, you have to use the 'st-meta' value
9096
in TERM.
9197

98+
9299
## I cannot compile st in OpenBSD
93100

94101
OpenBSD lacks librt, despite it being mandatory in POSIX
@@ -97,6 +104,7 @@ If you want to compile st for OpenBSD you have to remove -lrt from config.mk, an
97104
st will compile without any loss of functionality, because all the functions are
98105
included in libc on this platform.
99106

107+
100108
## The Backspace Case
101109

102110
St is emulating the Linux way of handling backspace being delete and delete being
@@ -158,19 +166,60 @@ terminal users wants its backspace to be how he feels it:
158166
[1] http://www.ibb.net/~anne/keyboard.html
159167
[2] http://www.tldp.org/HOWTO/Keyboard-and-Console-HOWTO-5.html
160168

169+
161170
## But I really want the old grumpy behaviour of my terminal
162171

163172
Apply [1].
164173

165174
[1] https://st.suckless.org/patches/delkey
166175

167-
## Why do images not work in st (in programs such as w3m)?
168176

169-
This is a terrible hack that overdraws an image on top of the terminal emulator
170-
window. It also relies on a very specific way the terminal draws it's contents.
177+
## Why do images not work in st using the w3m image hack?
178+
179+
w3mimg uses a hack that draws an image on top of the terminal emulator Drawable
180+
window. The hack relies on the terminal to use a single buffer to draw its
181+
contents directly.
182+
183+
st uses double-buffered drawing so the image is quickly replaced and may show a
184+
short flicker effect.
185+
186+
Below is a patch example to change st double-buffering to a single Drawable
187+
buffer.
188+
189+
diff --git a/x.c b/x.c
190+
--- a/x.c
191+
+++ b/x.c
192+
@@ -732,10 +732,6 @@ xresize(int col, int row)
193+
win.tw = col * win.cw;
194+
win.th = row * win.ch;
195+
196+
- XFreePixmap(xw.dpy, xw.buf);
197+
- xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h,
198+
- DefaultDepth(xw.dpy, xw.scr));
199+
- XftDrawChange(xw.draw, xw.buf);
200+
xclear(0, 0, win.w, win.h);
201+
202+
/* resize to new width */
203+
@@ -1148,8 +1144,7 @@ xinit(int cols, int rows)
204+
gcvalues.graphics_exposures = False;
205+
dc.gc = XCreateGC(xw.dpy, parent, GCGraphicsExposures,
206+
&gcvalues);
207+
- xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h,
208+
- DefaultDepth(xw.dpy, xw.scr));
209+
+ xw.buf = xw.win;
210+
XSetForeground(xw.dpy, dc.gc, dc.col[defaultbg].pixel);
211+
XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, win.w, win.h);
212+
213+
@@ -1632,8 +1627,6 @@ xdrawline(Line line, int x1, int y1, int x2)
214+
void
215+
xfinishdraw(void)
216+
{
217+
- XCopyArea(xw.dpy, xw.buf, xw.win, dc.gc, 0, 0, win.w,
218+
- win.h, 0, 0);
219+
XSetForeground(xw.dpy, dc.gc,
220+
dc.col[IS_SET(MODE_REVERSE)?
221+
defaultfg : defaultbg].pixel);
171222

172-
A more proper (but limited way) would be using sixels. Which st doesn't
173-
support.
174223

175224
## BadLength X error in Xft when trying to render emoji
176225

LICENSE

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT/X Consortium License
22

3-
© 2014-2018 Hiltjo Posthuma <hiltjo at codemadness dot org>
3+
© 2014-2020 Hiltjo Posthuma <hiltjo at codemadness dot org>
44
© 2018 Devin J. Pohly <djpohly at gmail dot com>
55
© 2014-2017 Quentin Rameau <quinq at fifth dot space>
66
© 2009-2012 Aurélien APTEL <aurelien dot aptel at gmail dot com>

config.def.h

+6
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ static unsigned int tripleclicktimeout = 600;
4343
/* alt screens */
4444
int allowaltscreen = 1;
4545

46+
/* allow certain non-interactive (insecure) window operations such as:
47+
setting the clipboard text */
48+
int allowwindowops = 0;
49+
4650
/*
4751
* draw latency range in ms - from new content/keypress/etc until drawing.
4852
* within this range, st draws when content stops arriving (idle). mostly it's
@@ -171,7 +175,9 @@ static uint forcemousemod = ShiftMask;
171175
static MouseShortcut mshortcuts[] = {
172176
/* mask button function argument release */
173177
{ XK_ANY_MOD, Button2, selpaste, {.i = 0}, 1 },
178+
{ ShiftMask, Button4, ttysend, {.s = "\033[5;2~"} },
174179
{ XK_ANY_MOD, Button4, ttysend, {.s = "\031"} },
180+
{ ShiftMask, Button5, ttysend, {.s = "\033[6;2~"} },
175181
{ XK_ANY_MOD, Button5, ttysend, {.s = "\005"} },
176182
};
177183

config.mk

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# st version
2-
VERSION = 0.8.3
2+
VERSION = 0.8.4
33

44
# Customize below to fit your system
55

@@ -28,8 +28,8 @@ STLDFLAGS = $(LIBS) $(LDFLAGS)
2828
# OpenBSD:
2929
#CPPFLAGS = -DVERSION=\"$(VERSION)\" -D_XOPEN_SOURCE=600 -D_BSD_SOURCE
3030
#LIBS = -L$(X11LIB) -lm -lX11 -lutil -lXft \
31-
# `pkg-config --libs fontconfig` \
32-
# `pkg-config --libs freetype2`
31+
# `$(PKG_CONFIG) --libs fontconfig` \
32+
# `$(PKG_CONFIG) --libs freetype2`
3333

3434
# compiler and linker
3535
# CC = c99

st.c

+17-25
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ enum term_mode {
5151
MODE_ECHO = 1 << 4,
5252
MODE_PRINT = 1 << 5,
5353
MODE_UTF8 = 1 << 6,
54-
MODE_SIXEL = 1 << 7,
5554
};
5655

5756
enum cursor_movement {
@@ -78,12 +77,11 @@ enum charset {
7877
enum escape_state {
7978
ESC_START = 1,
8079
ESC_CSI = 2,
81-
ESC_STR = 4, /* OSC, PM, APC */
80+
ESC_STR = 4, /* DCS, OSC, PM, APC */
8281
ESC_ALTCHARSET = 8,
8382
ESC_STR_END = 16, /* a final string was encountered */
8483
ESC_TEST = 32, /* Enter in test mode */
8584
ESC_UTF8 = 64,
86-
ESC_DCS =128,
8785
};
8886

8987
typedef struct {
@@ -129,6 +127,7 @@ typedef struct {
129127
int charset; /* current charset */
130128
int icharset; /* selected charset for sequence */
131129
int *tabs;
130+
Rune lastc; /* last printed char outside of sequence, 0 if control */
132131
} Term;
133132

134133
/* CSI Escape sequence structs */
@@ -842,7 +841,6 @@ ttyread(void)
842841
if (buflen > 0)
843842
memmove(buf, buf + written, buflen);
844843
return ret;
845-
846844
}
847845
}
848846

@@ -1648,6 +1646,12 @@ csihandle(void)
16481646
if (csiescseq.arg[0] == 0)
16491647
ttywrite(vtiden, strlen(vtiden), 0);
16501648
break;
1649+
case 'b': /* REP -- if last char is printable print it <n> more times */
1650+
DEFAULT(csiescseq.arg[0], 1);
1651+
if (term.lastc)
1652+
while (csiescseq.arg[0]-- > 0)
1653+
tputc(term.lastc);
1654+
break;
16511655
case 'C': /* CUF -- Cursor <n> Forward */
16521656
case 'a': /* HPR -- Cursor <n> Forward */
16531657
DEFAULT(csiescseq.arg[0], 1);
@@ -1771,7 +1775,7 @@ csihandle(void)
17711775
break;
17721776
case 'n': /* DSR – Device Status Report (cursor position) */
17731777
if (csiescseq.arg[0] == 6) {
1774-
len = snprintf(buf, sizeof(buf),"\033[%i;%iR",
1778+
len = snprintf(buf, sizeof(buf), "\033[%i;%iR",
17751779
term.c.y+1, term.c.x+1);
17761780
ttywrite(buf, len, 0);
17771781
}
@@ -1855,7 +1859,7 @@ strhandle(void)
18551859
xsettitle(strescseq.args[1]);
18561860
return;
18571861
case 52:
1858-
if (narg > 2) {
1862+
if (narg > 2 && allowwindowops) {
18591863
dec = base64dec(strescseq.args[2]);
18601864
if (dec) {
18611865
xsetsel(dec);
@@ -1891,7 +1895,6 @@ strhandle(void)
18911895
xsettitle(strescseq.args[0]);
18921896
return;
18931897
case 'P': /* DCS -- Device Control String */
1894-
term.mode |= ESC_DCS;
18951898
case '_': /* APC -- Application Program Command */
18961899
case '^': /* PM -- Privacy Message */
18971900
return;
@@ -2085,12 +2088,9 @@ tdectest(char c)
20852088
void
20862089
tstrsequence(uchar c)
20872090
{
2088-
strreset();
2089-
20902091
switch (c) {
20912092
case 0x90: /* DCS -- Device Control String */
20922093
c = 'P';
2093-
term.esc |= ESC_DCS;
20942094
break;
20952095
case 0x9f: /* APC -- Application Program Command */
20962096
c = '_';
@@ -2102,6 +2102,7 @@ tstrsequence(uchar c)
21022102
c = ']';
21032103
break;
21042104
}
2105+
strreset();
21052106
strescseq.type = c;
21062107
term.esc |= ESC_STR;
21072108
}
@@ -2299,7 +2300,7 @@ tputc(Rune u)
22992300
Glyph *gp;
23002301

23012302
control = ISCONTROL(u);
2302-
if (u < 127 || !IS_SET(MODE_UTF8 | MODE_SIXEL)) {
2303+
if (u < 127 || !IS_SET(MODE_UTF8)) {
23032304
c[0] = u;
23042305
width = len = 1;
23052306
} else {
@@ -2320,23 +2321,11 @@ tputc(Rune u)
23202321
if (term.esc & ESC_STR) {
23212322
if (u == '\a' || u == 030 || u == 032 || u == 033 ||
23222323
ISCONTROLC1(u)) {
2323-
term.esc &= ~(ESC_START|ESC_STR|ESC_DCS);
2324-
if (IS_SET(MODE_SIXEL)) {
2325-
/* TODO: render sixel */;
2326-
term.mode &= ~MODE_SIXEL;
2327-
return;
2328-
}
2324+
term.esc &= ~(ESC_START|ESC_STR);
23292325
term.esc |= ESC_STR_END;
23302326
goto check_control_code;
23312327
}
23322328

2333-
if (IS_SET(MODE_SIXEL)) {
2334-
/* TODO: implement sixel mode */
2335-
return;
2336-
}
2337-
if (term.esc&ESC_DCS && strescseq.len == 0 && u == 'q')
2338-
term.mode |= MODE_SIXEL;
2339-
23402329
if (strescseq.len+len >= strescseq.siz) {
23412330
/*
23422331
* Here is a bug in terminals. If the user never sends
@@ -2373,6 +2362,8 @@ tputc(Rune u)
23732362
/*
23742363
* control codes are not shown ever
23752364
*/
2365+
if (!term.esc)
2366+
term.lastc = 0;
23762367
return;
23772368
} else if (term.esc & ESC_START) {
23782369
if (term.esc & ESC_CSI) {
@@ -2422,6 +2413,7 @@ tputc(Rune u)
24222413
}
24232414

24242415
tsetchar(u, &term.c.attr, term.c.x, term.c.y);
2416+
term.lastc = u;
24252417

24262418
if (width == 2) {
24272419
gp->mode |= ATTR_WIDE;
@@ -2445,7 +2437,7 @@ twrite(const char *buf, int buflen, int show_ctrl)
24452437
int n;
24462438

24472439
for (n = 0; n < buflen; n += charsize) {
2448-
if (IS_SET(MODE_UTF8) && !IS_SET(MODE_SIXEL)) {
2440+
if (IS_SET(MODE_UTF8)) {
24492441
/* process a complete utf8 char */
24502442
charsize = utf8decode(buf + n, &u, buflen - n);
24512443
if (charsize == 0)

st.h

+1
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ extern char *stty_args;
118118
extern char *vtiden;
119119
extern wchar_t *worddelimiters;
120120
extern int allowaltscreen;
121+
extern int allowwindowops;
121122
extern char *termname;
122123
extern unsigned int tabspaces;
123124
extern unsigned int defaultfg;

st.info

+3
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ st-mono| simpleterm monocolor,
158158
rc=\E8,
159159
rev=\E[7m,
160160
ri=\EM,
161+
rin=\E[%p1%dT,
161162
ritm=\E[23m,
162163
rmacs=\E(B,
163164
rmcup=\E[?1049l,
@@ -183,6 +184,8 @@ st-mono| simpleterm monocolor,
183184
# XTerm extensions
184185
rmxx=\E[29m,
185186
smxx=\E[9m,
187+
# disabled rep for now: causes some issues with older ncurses versions.
188+
# rep=%p1%c\E[%p2%{1}%-%db,
186189
# tmux extensions, see TERMINFO EXTENSIONS in tmux(1)
187190
Tc,
188191
Ms=\E]52;%p1%s;%p2%s\007,

x.c

+4-5
Original file line numberDiff line numberDiff line change
@@ -1526,8 +1526,8 @@ xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og)
15261526
/* draw the new one */
15271527
if (IS_SET(MODE_FOCUSED)) {
15281528
switch (win.cursor) {
1529-
case 7: /* st extension: snowman (U+2603) */
1530-
g.u = 0x2603;
1529+
case 7: /* st extension */
1530+
g.u = 0x2603; /* snowman (U+2603) */
15311531
/* FALLTHROUGH */
15321532
case 0: /* Blinking Block */
15331533
case 1: /* Blinking Block (Default) */
@@ -1690,8 +1690,7 @@ xsetmode(int set, unsigned int flags)
16901690
int
16911691
xsetcursor(int cursor)
16921692
{
1693-
DEFAULT(cursor, 1);
1694-
if (!BETWEEN(cursor, 0, 6))
1693+
if (!BETWEEN(cursor, 0, 7)) /* 7: st extension */
16951694
return 1;
16961695
win.cursor = cursor;
16971696
return 0;
@@ -1983,7 +1982,7 @@ main(int argc, char *argv[])
19831982
{
19841983
xw.l = xw.t = 0;
19851984
xw.isfixed = False;
1986-
win.cursor = cursorshape;
1985+
xsetcursor(cursorshape);
19871986

19881987
ARGBEGIN {
19891988
case 'a':

0 commit comments

Comments
 (0)