diff --git a/README.md b/README.md index 76eb393..d0e248d 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,8 @@ Refer to [https://st.suckless.org/](https://st.suckless.org/) for details on the ### Changelog: +2021-08-18 - Added the CSI 22 & 23 patch + 2021-07-26 - Added columns patch 2021-07-07 - Added sixel scrollback and the openurlonclick patch @@ -88,7 +90,8 @@ Refer to [https://st.suckless.org/](https://st.suckless.org/) for details on the - allows st to reize to any pixel size rather than snapping to character width / height - [anysize_nobar](https://github.com/connor-brooks/st-anysize-nobar) - - a patch that aims to prevent black bars being drawn on the edges of st terminals using the anysize patch + - a patch that aims to prevent black bars being drawn on the edges of st terminals using the + anysize patch - [blinking-cursor](https://st.suckless.org/patches/blinking_cursor/) - allows the use of a blinking cursor @@ -112,6 +115,10 @@ Refer to [https://st.suckless.org/](https://st.suckless.org/) for details on the - this patch allows you to select and copy the last URL displayed with Mod+l - multiple invocations cycle through the available URLs + - [csi_23_23](https://st.suckless.org/patches/csi_22_23/) + - adds support for CSI escape sequences 22 and 23, which save and restores the window title + (for instance nvim does this when opening and closing) + - default-cursor - minor change allowing escape sequences like `\e[ q` or `\e[0 q` to set the cursor back to default configuration instead of a blinking block - while many terminals do this the behaviour is not according to the specification diff --git a/patches.def.h b/patches.def.h index 9d5b770..0153aa1 100644 --- a/patches.def.h +++ b/patches.def.h @@ -94,6 +94,12 @@ */ #define COPYURL_HIGHLIGHT_SELECTED_URLS_PATCH 0 +/* This patch adds support for CSI escape sequences 22 and 23, which save and + * restores the window title (for instance nvim does this when opening and closing). + * https://st.suckless.org/patches/csi_22_23/ + */ +#define CSI_22_23_PATCH 0 + /* According to the specification (see link in BLINKING_CURSOR_PATCH) the "Set cursor style * (DECSCUSR), VT520." escape sequences define both values of 0 and 1 as a blinking block, * with 1 being the default. diff --git a/st.c b/st.c index 311db33..54f58af 100644 --- a/st.c +++ b/st.c @@ -2314,6 +2314,36 @@ csihandle(void) case 's': /* DECSC -- Save cursor position (ANSI.SYS) */ tcursor(CURSOR_SAVE); break; + #if CSI_22_23_PATCH + case 't': /* title stack operations */ + switch (csiescseq.arg[0]) { + case 22: /* pust current title on stack */ + switch (csiescseq.arg[1]) { + case 0: + case 1: + case 2: + xpushtitle(); + break; + default: + goto unknown; + } + break; + case 23: /* pop last title from stack */ + switch (csiescseq.arg[1]) { + case 0: + case 1: + case 2: + xsettitle(NULL, 1); + break; + default: + goto unknown; + } + break; + default: + goto unknown; + } + break; + #endif // CSI_22_23_PATCH case 'u': /* DECRC -- Restore cursor position (ANSI.SYS) */ tcursor(CURSOR_LOAD); break; @@ -2379,7 +2409,11 @@ strhandle(void) switch (par) { case 0: if (narg > 1) { + #if CSI_22_23_PATCH + xsettitle(strescseq.args[1], 0); + #else xsettitle(strescseq.args[1]); + #endif // CSI_22_23_PATCH xseticontitle(strescseq.args[1]); } return; @@ -2389,7 +2423,11 @@ strhandle(void) return; case 2: if (narg > 1) + #if CSI_22_23_PATCH + xsettitle(strescseq.args[1], 0); + #else xsettitle(strescseq.args[1]); + #endif // CSI_22_23_PATCH return; case 52: if (narg > 2 && allowwindowops) { @@ -2469,7 +2507,11 @@ strhandle(void) } break; case 'k': /* old title set compatibility */ + #if CSI_22_23_PATCH + xsettitle(strescseq.args[0], 0); + #else xsettitle(strescseq.args[0]); + #endif // CSI_22_23_PATCH return; case 'P': /* DCS -- Device Control String */ #if SIXEL_PATCH @@ -2905,6 +2947,9 @@ eschandle(uchar ascii) break; case 'c': /* RIS -- Reset to initial state */ treset(); + #if CSI_22_23_PATCH + xfreetitlestack(); + #endif // CSI_22_23_PATCH resettitle(); xloadcols(); break; @@ -3326,7 +3371,11 @@ tresize(int col, int row) void resettitle(void) { + #if CSI_22_23_PATCH + xsettitle(NULL, 0); + #else xsettitle(NULL); + #endif // CSI_22_23_PATCH } void diff --git a/win.h b/win.h index 3faaab9..55bd990 100644 --- a/win.h +++ b/win.h @@ -41,7 +41,13 @@ void xfinishdraw(void); void xloadcols(void); int xsetcolorname(int, const char *); void xseticontitle(char *); +#if CSI_22_23_PATCH +void xfreetitlestack(void); +void xsettitle(char *, int); +void xpushtitle(void); +#else void xsettitle(char *); +#endif // CSI_22_23_PATCH int xsetcursor(int); void xsetmode(int, unsigned int); void xsetpointermotion(int); diff --git a/x.c b/x.c index 75b987e..a3267f4 100644 --- a/x.c +++ b/x.c @@ -48,6 +48,11 @@ static void zoomreset(const Arg *); /* config.h for applying patches and the configuration. */ #include "config.h" +#if CSI_22_23_PATCH +/* size of title stack */ +#define TITLESTACKSIZE 8 +#endif // CSI_22_23_PATCH + /* XEMBED messages */ #define XEMBED_FOCUS_IN 4 #define XEMBED_FOCUS_OUT 5 @@ -148,6 +153,11 @@ XWindow xw; XSelection xsel; TermWindow win; +#if CSI_22_23_PATCH +static int tstki; /* title stack index */ +static char *titlestack[TITLESTACKSIZE]; /* title stack */ +#endif // CSI_22_23_PATCH + /* Font Ring Cache */ enum { FRC_NORMAL, @@ -2189,6 +2199,49 @@ xseticontitle(char *p) XFree(prop.value); } +#if CSI_22_23_PATCH +void +xsettitle(char *p, int pop) +{ + XTextProperty prop; + + free(titlestack[tstki]); + if (pop) { + titlestack[tstki] = NULL; + tstki = (tstki - 1 + TITLESTACKSIZE) % TITLESTACKSIZE; + p = titlestack[tstki] ? titlestack[tstki] : opt_title; + } else if (p) { + titlestack[tstki] = xstrdup(p); + } else { + titlestack[tstki] = NULL; + p = opt_title; + } + + Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle, &prop); + XSetWMName(xw.dpy, xw.win, &prop); + XSetTextProperty(xw.dpy, xw.win, &prop, xw.netwmname); + XFree(prop.value); +} + +void +xpushtitle(void) +{ + int tstkin = (tstki + 1) % TITLESTACKSIZE; + + free(titlestack[tstkin]); + titlestack[tstkin] = titlestack[tstki] ? xstrdup(titlestack[tstki]) : NULL; + tstki = tstkin; +} + +void +xfreetitlestack(void) +{ + for (int i = 0; i < LEN(titlestack); i++) { + free(titlestack[i]); + titlestack[i] = NULL; + } +} +#else void xsettitle(char *p) { @@ -2201,6 +2254,7 @@ xsettitle(char *p) XSetTextProperty(xw.dpy, xw.win, &prop, xw.netwmname); XFree(prop.value); } +#endif // CSI_22_23_PATCH int xstartdraw(void)