master
Jonathan Hodgson 5 years ago
commit 8f01861eba
  1. 21
      FAQ
  2. 27
      config.def.h
  3. 29
      st.c
  4. 1
      st.h
  5. 4
      st.info
  6. 69
      x.c

21
FAQ

@ -1,6 +1,6 @@
## Why does st not handle utmp entries? ## Why does st not handle utmp entries?
Use the excellent tool of [utmp](http://git.suckless.org/utmp/) for this task. Use the excellent tool of [utmp](https://git.suckless.org/utmp/) for this task.
## Some _random program_ complains that st is unknown/not recognised/unsupported/whatever! ## Some _random program_ complains that st is unknown/not recognised/unsupported/whatever!
@ -15,13 +15,6 @@ you can manually run `tic -sx st.info`.
* Some programs don’t complain about the lacking st description and default to * Some programs don’t complain about the lacking st description and default to
another terminal. In that case see the question about terminfo. another terminal. In that case see the question about terminfo.
## I get some weird glitches/visual bug on _random program_!
Try launching it with a different TERM: $ TERM=xterm myapp. toe(1) will give
you a list of available terminals, but you’ll most likely switch between xterm,
st or st-256color. The default value for TERM can be changed in config.h
(TNAME).
## How do I scroll back up? ## How do I scroll back up?
Using a terminal multiplexer. Using a terminal multiplexer.
@ -104,7 +97,7 @@ St is emulating the Linux way of handling backspace being delete and delete bein
backspace. backspace.
This is an issue that was discussed in suckless mailing list This is an issue that was discussed in suckless mailing list
<http://lists.suckless.org/dev/1404/20697.html>. Here is why some old grumpy <https://lists.suckless.org/dev/1404/20697.html>. Here is why some old grumpy
terminal users wants its backspace to be how he feels it: terminal users wants its backspace to be how he feels it:
Well, I am going to comment why I want to change the behaviour Well, I am going to comment why I want to change the behaviour
@ -163,7 +156,15 @@ terminal users wants its backspace to be how he feels it:
Apply [1]. Apply [1].
[1] http://st.suckless.org/patches/delkey [1] https://st.suckless.org/patches/delkey
## Why do images not work in st (in programs such as w3m)?
This is a terrible hack that overdraws an image on top of the terminal emulator
window. It also relies on a very specific way the terminal draws it's contents.
A more proper (but limited way) would be using sixels. Which st doesn't
support.
## BadLength X error in Xft when trying to render emoji ## BadLength X error in Xft when trying to render emoji

@ -150,20 +150,22 @@ static unsigned int mousebg = 0;
*/ */
static unsigned int defaultattr = 11; static unsigned int defaultattr = 11;
/*
* Force mouse select/shortcuts while mask is active (when MODE_MOUSE is set).
* Note that if you want to use ShiftMask with selmasks, set this to an other
* modifier, set to 0 to not use it.
*/
static uint forcemousemod = ShiftMask;
/* /*
* Internal mouse shortcuts. * Internal mouse shortcuts.
* Beware that overloading Button1 will disable the selection. * Beware that overloading Button1 will disable the selection.
*/ */
static MouseShortcut mshortcuts[] = { static MouseShortcut mshortcuts[] = {
/* button mask string */ /* mask button function argument release */
{ Button4, XK_NO_MOD, "\031" }, { XK_ANY_MOD, Button2, selpaste, {.i = 0}, 1 },
{ Button5, XK_NO_MOD, "\005" }, { XK_ANY_MOD, Button4, ttysend, {.s = "\031"} },
}; { XK_ANY_MOD, Button5, ttysend, {.s = "\005"} },
MouseKey mkeys[] = {
/* button mask function argument */
{ Button4, ShiftMask, kscrollup, {.i = 1} },
{ Button5, ShiftMask, kscrolldown, {.i = 1} },
}; };
/* Internal keyboard shortcuts. */ /* Internal keyboard shortcuts. */
@ -223,13 +225,6 @@ static KeySym mappedkeys[] = { -1 };
*/ */
static uint ignoremod = Mod2Mask|XK_SWITCH_MOD; static uint ignoremod = Mod2Mask|XK_SWITCH_MOD;
/*
* Override mouse-select while mask is active (when MODE_MOUSE is set).
* Note that if you want to use ShiftMask with selmasks, set this to an other
* modifier, set to 0 to not use it.
*/
static uint forceselmod = ShiftMask;
/* /*
* This is the huge key array which defines all compatibility to the Linux * This is the huge key array which defines all compatibility to the Linux
* world. Please decide about changes wisely. * world. Please decide about changes wisely.

29
st.c

@ -142,7 +142,7 @@ typedef struct {
/* ESC '[' [[ [<priv>] <arg> [;]] <mode> [<mode>]] */ /* ESC '[' [[ [<priv>] <arg> [;]] <mode> [<mode>]] */
typedef struct { typedef struct {
char buf[ESC_BUF_SIZ]; /* raw string */ char buf[ESC_BUF_SIZ]; /* raw string */
int len; /* raw string length */ size_t len; /* raw string length */
char priv; char priv;
int arg[ESC_ARG_SIZ]; int arg[ESC_ARG_SIZ];
int narg; /* nb of args */ int narg; /* nb of args */
@ -153,8 +153,9 @@ typedef struct {
/* ESC type [[ [<priv>] <arg> [;]] <mode>] ESC '\' */ /* ESC type [[ [<priv>] <arg> [;]] <mode>] ESC '\' */
typedef struct { typedef struct {
char type; /* ESC type ... */ char type; /* ESC type ... */
char buf[STR_BUF_SIZ]; /* raw string */ char *buf; /* allocated raw string */
int len; /* raw string length */ size_t siz; /* allocation size */
size_t len; /* raw string length */
char *args[STR_ARG_SIZ]; char *args[STR_ARG_SIZ];
int narg; /* nb of args */ int narg; /* nb of args */
} STREscape; } STREscape;
@ -373,7 +374,7 @@ char
base64dec_getc(const char **src) base64dec_getc(const char **src)
{ {
while (**src && !isprint(**src)) (*src)++; while (**src && !isprint(**src)) (*src)++;
return *((*src)++); return **src ? *((*src)++) : '='; /* emulate padding if string ends */
} }
char * char *
@ -391,6 +392,10 @@ base64dec(const char *src)
int c = base64_digits[(unsigned char) base64dec_getc(&src)]; int c = base64_digits[(unsigned char) base64dec_getc(&src)];
int d = base64_digits[(unsigned char) base64dec_getc(&src)]; int d = base64_digits[(unsigned char) base64dec_getc(&src)];
/* invalid input. 'a' can be -1, e.g. if src is "\n" (c-str) */
if (a == -1 || b == -1)
break;
*dst++ = (a << 2) | ((b & 0x30) >> 4); *dst++ = (a << 2) | ((b & 0x30) >> 4);
if (c == -1) if (c == -1)
break; break;
@ -1859,7 +1864,7 @@ csihandle(void)
void void
csidump(void) csidump(void)
{ {
int i; size_t i;
uint c; uint c;
fprintf(stderr, "ESC["); fprintf(stderr, "ESC[");
@ -2030,7 +2035,7 @@ externalpipe(const Arg *arg)
void void
strdump(void) strdump(void)
{ {
int i; size_t i;
uint c; uint c;
fprintf(stderr, "ESC%c", strescseq.type); fprintf(stderr, "ESC%c", strescseq.type);
@ -2057,7 +2062,10 @@ strdump(void)
void void
strreset(void) strreset(void)
{ {
memset(&strescseq, 0, sizeof(strescseq)); strescseq = (STREscape){
.buf = xrealloc(strescseq.buf, STR_BUF_SIZ),
.siz = STR_BUF_SIZ,
};
} }
void void
@ -2439,7 +2447,7 @@ tputc(Rune u)
if (term.esc&ESC_DCS && strescseq.len == 0 && u == 'q') if (term.esc&ESC_DCS && strescseq.len == 0 && u == 'q')
term.mode |= MODE_SIXEL; term.mode |= MODE_SIXEL;
if (strescseq.len+len >= sizeof(strescseq.buf)-1) { if (strescseq.len+len >= strescseq.siz) {
/* /*
* Here is a bug in terminals. If the user never sends * Here is a bug in terminals. If the user never sends
* some code to stop the str or esc command, then st * some code to stop the str or esc command, then st
@ -2453,7 +2461,10 @@ tputc(Rune u)
* term.esc = 0; * term.esc = 0;
* strhandle(); * strhandle();
*/ */
return; if (strescseq.siz > (SIZE_MAX - UTF_SIZ) / 2)
return;
strescseq.siz *= 2;
strescseq.buf = xrealloc(strescseq.buf, strescseq.siz);
} }
memmove(&strescseq.buf[strescseq.len], c, len); memmove(&strescseq.buf[strescseq.len], c, len);

@ -74,6 +74,7 @@ typedef union {
uint ui; uint ui;
float f; float f;
const void *v; const void *v;
const char *s;
} Arg; } Arg;
typedef struct { typedef struct {

@ -189,10 +189,10 @@ st| simpleterm,
rmxx=\E[29m, rmxx=\E[29m,
smxx=\E[9m, smxx=\E[9m,
# tmux extensions, see TERMINFO EXTENSIONS in tmux(1) # tmux extensions, see TERMINFO EXTENSIONS in tmux(1)
Se,
Ss,
Tc, Tc,
Ms=\E]52;%p1%s;%p2%s\007, Ms=\E]52;%p1%s;%p2%s\007,
Se=\E[2 q,
Ss=\E[%p1%d q,
st-256color| simpleterm with 256 colors, st-256color| simpleterm with 256 colors,
use=st, use=st,

69
x.c

@ -29,9 +29,11 @@ typedef struct {
} Shortcut; } Shortcut;
typedef struct { typedef struct {
uint b; uint mod;
uint mask; uint button;
char *s; void (*func)(const Arg *);
const Arg arg;
uint release;
} MouseShortcut; } MouseShortcut;
typedef struct { typedef struct {
@ -56,6 +58,7 @@ static void selpaste(const Arg *);
static void zoom(const Arg *); static void zoom(const Arg *);
static void zoomabs(const Arg *); static void zoomabs(const Arg *);
static void zoomreset(const Arg *); static void zoomreset(const Arg *);
static void ttysend(const Arg *);
/* config.h for applying patches and the configuration. */ /* config.h for applying patches and the configuration. */
#include "config.h" #include "config.h"
@ -163,6 +166,7 @@ static void kpress(XEvent *);
static void cmessage(XEvent *); static void cmessage(XEvent *);
static void resize(XEvent *); static void resize(XEvent *);
static void focus(XEvent *); static void focus(XEvent *);
static int mouseaction(XEvent *, uint);
static void brelease(XEvent *); static void brelease(XEvent *);
static void bpress(XEvent *); static void bpress(XEvent *);
static void bmotion(XEvent *); static void bmotion(XEvent *);
@ -312,6 +316,12 @@ zoomreset(const Arg *arg)
} }
} }
void
ttysend(const Arg *arg)
{
ttywrite(arg->s, strlen(arg->s), 1);
}
int int
evcol(XEvent *e) evcol(XEvent *e)
{ {
@ -332,7 +342,7 @@ void
mousesel(XEvent *e, int done) mousesel(XEvent *e, int done)
{ {
int type, seltype = SEL_REGULAR; int type, seltype = SEL_REGULAR;
uint state = e->xbutton.state & ~(Button1Mask | forceselmod); uint state = e->xbutton.state & ~(Button1Mask | forcemousemod);
for (type = 1; type < LEN(selmasks); ++type) { for (type = 1; type < LEN(selmasks); ++type) {
if (match(selmasks[type], state)) { if (match(selmasks[type], state)) {
@ -408,34 +418,37 @@ mousereport(XEvent *e)
ttywrite(buf, len, 0); ttywrite(buf, len, 0);
} }
int
mouseaction(XEvent *e, uint release)
{
MouseShortcut *ms;
for (ms = mshortcuts; ms < mshortcuts + LEN(mshortcuts); ms++) {
if (ms->release == release &&
ms->button == e->xbutton.button &&
(match(ms->mod, e->xbutton.state) || /* exact or forced */
match(ms->mod, e->xbutton.state & ~forcemousemod))) {
ms->func(&(ms->arg));
return 1;
}
}
return 0;
}
void void
bpress(XEvent *e) bpress(XEvent *e)
{ {
struct timespec now; struct timespec now;
MouseShortcut *ms;
MouseKey *mk;
int snap; int snap;
if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forceselmod)) { if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) {
mousereport(e); mousereport(e);
return; return;
} }
for (ms = mshortcuts; ms < mshortcuts + LEN(mshortcuts); ms++) { if (mouseaction(e, 0))
if (e->xbutton.button == ms->b return;
&& match(ms->mask, e->xbutton.state)) {
ttywrite(ms->s, strlen(ms->s), 1);
return;
}
}
for (mk = mkeys; mk < mkeys + LEN(mkeys); mk++) {
if (e->xbutton.button == mk->b
&& match(mk->mask, e->xbutton.state)) {
mk->func(&mk->arg);
return;
}
}
if (e->xbutton.button == Button1) { if (e->xbutton.button == Button1) {
/* /*
@ -652,21 +665,21 @@ xsetsel(char *str)
void void
brelease(XEvent *e) brelease(XEvent *e)
{ {
if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forceselmod)) { if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) {
mousereport(e); mousereport(e);
return; return;
} }
if (e->xbutton.button == Button2) if (mouseaction(e, 1))
selpaste(NULL); return;
else if (e->xbutton.button == Button1) if (e->xbutton.button == Button1)
mousesel(e, 1); mousesel(e, 1);
} }
void void
bmotion(XEvent *e) bmotion(XEvent *e)
{ {
if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forceselmod)) { if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) {
mousereport(e); mousereport(e);
return; return;
} }
@ -1142,8 +1155,8 @@ xinit(int cols, int rows)
win.mode = MODE_NUMLOCK; win.mode = MODE_NUMLOCK;
resettitle(); resettitle();
XMapWindow(xw.dpy, xw.win);
xhints(); xhints();
XMapWindow(xw.dpy, xw.win);
XSync(xw.dpy, False); XSync(xw.dpy, False);
clock_gettime(CLOCK_MONOTONIC, &xsel.tclick1); clock_gettime(CLOCK_MONOTONIC, &xsel.tclick1);

Loading…
Cancel
Save