Updates st
This commit is contained in:
commit
8f01861eba
6 changed files with 86 additions and 65 deletions
21
FAQ
21
FAQ
|
@ -1,6 +1,6 @@
|
|||
## 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!
|
||||
|
||||
|
@ -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
|
||||
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?
|
||||
|
||||
Using a terminal multiplexer.
|
||||
|
@ -104,7 +97,7 @@ St is emulating the Linux way of handling backspace being delete and delete bein
|
|||
backspace.
|
||||
|
||||
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:
|
||||
|
||||
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].
|
||||
|
||||
[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
|
||||
|
||||
|
|
27
config.def.h
27
config.def.h
|
@ -150,20 +150,22 @@ static unsigned int mousebg = 0;
|
|||
*/
|
||||
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.
|
||||
* Beware that overloading Button1 will disable the selection.
|
||||
*/
|
||||
static MouseShortcut mshortcuts[] = {
|
||||
/* button mask string */
|
||||
{ Button4, XK_NO_MOD, "\031" },
|
||||
{ Button5, XK_NO_MOD, "\005" },
|
||||
};
|
||||
|
||||
MouseKey mkeys[] = {
|
||||
/* button mask function argument */
|
||||
{ Button4, ShiftMask, kscrollup, {.i = 1} },
|
||||
{ Button5, ShiftMask, kscrolldown, {.i = 1} },
|
||||
/* mask button function argument release */
|
||||
{ XK_ANY_MOD, Button2, selpaste, {.i = 0}, 1 },
|
||||
{ XK_ANY_MOD, Button4, ttysend, {.s = "\031"} },
|
||||
{ XK_ANY_MOD, Button5, ttysend, {.s = "\005"} },
|
||||
};
|
||||
|
||||
/* Internal keyboard shortcuts. */
|
||||
|
@ -223,13 +225,6 @@ static KeySym mappedkeys[] = { -1 };
|
|||
*/
|
||||
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
|
||||
* world. Please decide about changes wisely.
|
||||
|
|
29
st.c
29
st.c
|
@ -142,7 +142,7 @@ typedef struct {
|
|||
/* ESC '[' [[ [<priv>] <arg> [;]] <mode> [<mode>]] */
|
||||
typedef struct {
|
||||
char buf[ESC_BUF_SIZ]; /* raw string */
|
||||
int len; /* raw string length */
|
||||
size_t len; /* raw string length */
|
||||
char priv;
|
||||
int arg[ESC_ARG_SIZ];
|
||||
int narg; /* nb of args */
|
||||
|
@ -153,8 +153,9 @@ typedef struct {
|
|||
/* ESC type [[ [<priv>] <arg> [;]] <mode>] ESC '\' */
|
||||
typedef struct {
|
||||
char type; /* ESC type ... */
|
||||
char buf[STR_BUF_SIZ]; /* raw string */
|
||||
int len; /* raw string length */
|
||||
char *buf; /* allocated raw string */
|
||||
size_t siz; /* allocation size */
|
||||
size_t len; /* raw string length */
|
||||
char *args[STR_ARG_SIZ];
|
||||
int narg; /* nb of args */
|
||||
} STREscape;
|
||||
|
@ -373,7 +374,7 @@ char
|
|||
base64dec_getc(const char **src)
|
||||
{
|
||||
while (**src && !isprint(**src)) (*src)++;
|
||||
return *((*src)++);
|
||||
return **src ? *((*src)++) : '='; /* emulate padding if string ends */
|
||||
}
|
||||
|
||||
char *
|
||||
|
@ -391,6 +392,10 @@ base64dec(const char *src)
|
|||
int c = 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);
|
||||
if (c == -1)
|
||||
break;
|
||||
|
@ -1859,7 +1864,7 @@ csihandle(void)
|
|||
void
|
||||
csidump(void)
|
||||
{
|
||||
int i;
|
||||
size_t i;
|
||||
uint c;
|
||||
|
||||
fprintf(stderr, "ESC[");
|
||||
|
@ -2030,7 +2035,7 @@ externalpipe(const Arg *arg)
|
|||
void
|
||||
strdump(void)
|
||||
{
|
||||
int i;
|
||||
size_t i;
|
||||
uint c;
|
||||
|
||||
fprintf(stderr, "ESC%c", strescseq.type);
|
||||
|
@ -2057,7 +2062,10 @@ strdump(void)
|
|||
void
|
||||
strreset(void)
|
||||
{
|
||||
memset(&strescseq, 0, sizeof(strescseq));
|
||||
strescseq = (STREscape){
|
||||
.buf = xrealloc(strescseq.buf, STR_BUF_SIZ),
|
||||
.siz = STR_BUF_SIZ,
|
||||
};
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -2439,7 +2447,7 @@ tputc(Rune u)
|
|||
if (term.esc&ESC_DCS && strescseq.len == 0 && u == 'q')
|
||||
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
|
||||
* some code to stop the str or esc command, then st
|
||||
|
@ -2453,7 +2461,10 @@ tputc(Rune u)
|
|||
* term.esc = 0;
|
||||
* 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);
|
||||
|
|
1
st.h
1
st.h
|
@ -74,6 +74,7 @@ typedef union {
|
|||
uint ui;
|
||||
float f;
|
||||
const void *v;
|
||||
const char *s;
|
||||
} Arg;
|
||||
|
||||
typedef struct {
|
||||
|
|
4
st.info
4
st.info
|
@ -189,10 +189,10 @@ st| simpleterm,
|
|||
rmxx=\E[29m,
|
||||
smxx=\E[9m,
|
||||
# tmux extensions, see TERMINFO EXTENSIONS in tmux(1)
|
||||
Se,
|
||||
Ss,
|
||||
Tc,
|
||||
Ms=\E]52;%p1%s;%p2%s\007,
|
||||
Se=\E[2 q,
|
||||
Ss=\E[%p1%d q,
|
||||
|
||||
st-256color| simpleterm with 256 colors,
|
||||
use=st,
|
||||
|
|
69
x.c
69
x.c
|
@ -29,9 +29,11 @@ typedef struct {
|
|||
} Shortcut;
|
||||
|
||||
typedef struct {
|
||||
uint b;
|
||||
uint mask;
|
||||
char *s;
|
||||
uint mod;
|
||||
uint button;
|
||||
void (*func)(const Arg *);
|
||||
const Arg arg;
|
||||
uint release;
|
||||
} MouseShortcut;
|
||||
|
||||
typedef struct {
|
||||
|
@ -56,6 +58,7 @@ static void selpaste(const Arg *);
|
|||
static void zoom(const Arg *);
|
||||
static void zoomabs(const Arg *);
|
||||
static void zoomreset(const Arg *);
|
||||
static void ttysend(const Arg *);
|
||||
|
||||
/* config.h for applying patches and the configuration. */
|
||||
#include "config.h"
|
||||
|
@ -163,6 +166,7 @@ static void kpress(XEvent *);
|
|||
static void cmessage(XEvent *);
|
||||
static void resize(XEvent *);
|
||||
static void focus(XEvent *);
|
||||
static int mouseaction(XEvent *, uint);
|
||||
static void brelease(XEvent *);
|
||||
static void bpress(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
|
||||
evcol(XEvent *e)
|
||||
{
|
||||
|
@ -332,7 +342,7 @@ void
|
|||
mousesel(XEvent *e, int done)
|
||||
{
|
||||
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) {
|
||||
if (match(selmasks[type], state)) {
|
||||
|
@ -408,34 +418,37 @@ mousereport(XEvent *e)
|
|||
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
|
||||
bpress(XEvent *e)
|
||||
{
|
||||
struct timespec now;
|
||||
MouseShortcut *ms;
|
||||
MouseKey *mk;
|
||||
int snap;
|
||||
|
||||
if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forceselmod)) {
|
||||
if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) {
|
||||
mousereport(e);
|
||||
return;
|
||||
}
|
||||
|
||||
for (ms = mshortcuts; ms < mshortcuts + LEN(mshortcuts); ms++) {
|
||||
if (e->xbutton.button == ms->b
|
||||
&& 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 (mouseaction(e, 0))
|
||||
return;
|
||||
|
||||
if (e->xbutton.button == Button1) {
|
||||
/*
|
||||
|
@ -652,21 +665,21 @@ xsetsel(char *str)
|
|||
void
|
||||
brelease(XEvent *e)
|
||||
{
|
||||
if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forceselmod)) {
|
||||
if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) {
|
||||
mousereport(e);
|
||||
return;
|
||||
}
|
||||
|
||||
if (e->xbutton.button == Button2)
|
||||
selpaste(NULL);
|
||||
else if (e->xbutton.button == Button1)
|
||||
if (mouseaction(e, 1))
|
||||
return;
|
||||
if (e->xbutton.button == Button1)
|
||||
mousesel(e, 1);
|
||||
}
|
||||
|
||||
void
|
||||
bmotion(XEvent *e)
|
||||
{
|
||||
if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forceselmod)) {
|
||||
if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) {
|
||||
mousereport(e);
|
||||
return;
|
||||
}
|
||||
|
@ -1142,8 +1155,8 @@ xinit(int cols, int rows)
|
|||
|
||||
win.mode = MODE_NUMLOCK;
|
||||
resettitle();
|
||||
XMapWindow(xw.dpy, xw.win);
|
||||
xhints();
|
||||
XMapWindow(xw.dpy, xw.win);
|
||||
XSync(xw.dpy, False);
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &xsel.tclick1);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue