Compare commits

...

8 Commits

Author SHA1 Message Date
Minty Cube
404c7d975a
Merge branch 'bakkeby:master' into master 2024-10-05 02:40:40 +00:00
Bakkeby
3f1a5ed034 Revert "undercurl: support semicolons in SGR character attributes ref. #148"
This reverts commit 398aeb1cd6.
2024-10-01 23:17:07 +02:00
Bakkeby
c9390f2ca7 osc133 - changing default configuration options to Ctrl + PgUp/PgDown 2024-10-01 21:39:50 +02:00
Bakkeby
398aeb1cd6 undercurl: support semicolons in SGR character attributes ref. #148
Back in May 2024 support for colons in SGR character attributes was
added to allow both colons and semicolons to be used to separate the
subparameters in SGR escape codes.

The undercurl patch only read colons to separate parameters. This
commit allows for semicolons to be used as well when using escape
codes for undercurl.

https://invisible-island.net/xterm/ctlseqs/ctlseqs.html
https://git.suckless.org/st/commit/5dbcca49263be094fc38159c297458ae323ef647.html
https://st.suckless.org/patches/undercurl/
2024-10-01 21:35:46 +02:00
Utkarsh Verma
fe065cc366
osc133: initial patch implementation (#127)
* osc133: initial patch implementation

* Specify dependency on reflow or scrollback patch
2024-10-01 21:35:30 +02:00
lmccartneystar
e7bdaa65d7
mouse shortcuts: use XK_ANY_MOD with altscreen mouse scrollback patch (#151) 2024-09-29 10:08:38 +02:00
veltza
aaaa59eb77
sixel: fix image deletion issue (#150)
This fixes the current implementation, which does not delete an image if
an application first erases the image and then spawns a new transparent
image in its place. The reason it didn't work before was because the two
operations were handled at different stages in the rendering pipeline.
2024-09-20 09:21:30 +02:00
veltza
5d2d1d818c
sixel: prevent images from piling up (#149)
Old images are automatically deleted if a new image is spawned over
them. This prevents them from piling up and choking the terminal when
viewing animated gifs.

Now if you use the latest version of Chafa to view the gifs, it
will set the transparency attribute (P2=1) to all sixel images
regardless of whether they are transparent or not. This prevents the
auto-delete from working because if the image is transparent, we can't
delete any images behind it.

The solution is that since Chafa fills the animation frames with an
opaque black background color, we treat the images as non-transparent if
they don't have any transparent pixels. This keeps the auto-delete
running with the new Chafa.

Although the solution works now, it may not be a long-term solution.
2024-09-20 09:17:15 +02:00
9 changed files with 112 additions and 19 deletions

View File

@ -378,8 +378,8 @@ static MouseShortcut mshortcuts[] = {
{ ShiftMask, Button5, ttysend, {.s = "\033[6;2~"} }, { ShiftMask, Button5, ttysend, {.s = "\033[6;2~"} },
#endif // SCROLLBACK_MOUSE_PATCH #endif // SCROLLBACK_MOUSE_PATCH
#if SCROLLBACK_MOUSE_ALTSCREEN_PATCH || REFLOW_PATCH #if SCROLLBACK_MOUSE_ALTSCREEN_PATCH || REFLOW_PATCH
{ XK_NO_MOD, Button4, kscrollup, {.i = 1}, 0, S_PRI }, { XK_ANY_MOD, Button4, kscrollup, {.i = 1}, 0, S_PRI },
{ XK_NO_MOD, Button5, kscrolldown, {.i = 1}, 0, S_PRI }, { XK_ANY_MOD, Button5, kscrolldown, {.i = 1}, 0, S_PRI },
{ XK_ANY_MOD, Button4, ttysend, {.s = "\031"}, 0, S_ALT }, { XK_ANY_MOD, Button4, ttysend, {.s = "\031"}, 0, S_ALT },
{ XK_ANY_MOD, Button5, ttysend, {.s = "\005"}, 0, S_ALT }, { XK_ANY_MOD, Button5, ttysend, {.s = "\005"}, 0, S_ALT },
#else #else
@ -467,6 +467,10 @@ static Shortcut shortcuts[] = {
#if INVERT_PATCH #if INVERT_PATCH
{ TERMMOD, XK_X, invert, { 0 } }, { TERMMOD, XK_X, invert, { 0 } },
#endif // INVERT_PATCH #endif // INVERT_PATCH
#if OSC133_PATCH
{ ControlMask, XK_Page_Up, scrolltoprompt, {.i = -1}, S_PRI },
{ ControlMask, XK_Page_Down, scrolltoprompt, {.i = 1}, S_PRI },
#endif // OSC133_PATCH
}; };
/* /*

29
patch/osc133.c Normal file
View File

@ -0,0 +1,29 @@
void
scrolltoprompt(const Arg *arg)
{
int x, y;
#if REFLOW_PATCH
int top = term.scr - term.histf;
#else
int top = term.scr - term.histn;
#endif // REFLOW_PATCH
int bot = term.scr + term.row-1;
int dy = arg->i;
Line line;
if (!dy || tisaltscr())
return;
for (y = dy; y >= top && y <= bot; y += dy) {
for (line = TLINE(y), x = 0; x < term.col; x++) {
if (line[x].mode & ATTR_FTCS_PROMPT)
goto scroll;
}
}
scroll:
if (dy < 0)
kscrollup(&((Arg){ .i = -y }));
else
kscrolldown(&((Arg){ .i = y }));
}

1
patch/osc133.h Normal file
View File

@ -0,0 +1 @@
static void scrolltoprompt(const Arg *);

View File

@ -46,4 +46,7 @@
#endif #endif
#if XRESOURCES_PATCH #if XRESOURCES_PATCH
#include "xresources.c" #include "xresources.c"
#endif #endif
#if OSC133_PATCH
#include "osc133.c"
#endif

View File

@ -41,3 +41,6 @@
#if XRESOURCES_PATCH #if XRESOURCES_PATCH
#include "xresources.h" #include "xresources.h"
#endif #endif
#if OSC133_PATCH
#include "osc133.h"
#endif

View File

@ -301,6 +301,13 @@
*/ */
#define OPENURLONCLICK_PATCH 0 #define OPENURLONCLICK_PATCH 0
/* This patch allows jumping between prompts by utilizing the OSC 133 escape sequence
* emitted by shells. Must be used with either reflow or scrollback patch.
*
* https://codeberg.org/dnkl/foot#jumping-between-prompts
*/
#define OSC133_PATCH 0
/* Reflow. /* Reflow.
* Allows st to be resized without cutting off text when the terminal window is made larger again. * Allows st to be resized without cutting off text when the terminal window is made larger again.
* Text wraps when the terminal window is made smaller. * Text wraps when the terminal window is made smaller.

15
sixel.c
View File

@ -261,10 +261,10 @@ sixel_parser_finalize(sixel_state_t *st, ImageList **newimages, int cx, int cy,
sixel_image_t *image = &st->image; sixel_image_t *image = &st->image;
int x, y; int x, y;
sixel_color_no_t *src; sixel_color_no_t *src;
sixel_color_t *dst; sixel_color_t *dst, color;
int color;
int w, h; int w, h;
int i, j, cols, numimages; int i, j, cols, numimages;
char trans;
ImageList *im, *next, *tail; ImageList *im, *next, *tail;
if (!image->data) if (!image->data)
@ -311,7 +311,6 @@ sixel_parser_finalize(sixel_state_t *st, ImageList **newimages, int cx, int cy,
im->clipmask = NULL; im->clipmask = NULL;
im->cw = cw; im->cw = cw;
im->ch = ch; im->ch = ch;
im->transparent = st->transparent;
} }
if (!im || !im->pixels) { if (!im || !im->pixels) {
for (im = *newimages; im; im = next) { for (im = *newimages; im; im = next) {
@ -324,11 +323,15 @@ sixel_parser_finalize(sixel_state_t *st, ImageList **newimages, int cx, int cy,
return -1; return -1;
} }
dst = (sixel_color_t *)im->pixels; dst = (sixel_color_t *)im->pixels;
for (j = 0; j < im->height && y < h; j++, y++) { for (trans = 0, j = 0; j < im->height && y < h; j++, y++) {
src = st->image.data + image->width * y; src = st->image.data + image->width * y;
for (x = 0; x < w; x++) for (x = 0; x < w; x++) {
*dst++ = st->image.palette[*src++]; color = st->image.palette[*src++];
trans |= (color == 0);
*dst++ = color;
}
} }
im->transparent = (st->transparent && trans);
} }
return numimages; return numimages;

60
st.c
View File

@ -2603,8 +2603,8 @@ strhandle(void)
{ defaultcs, "cursor" } { defaultcs, "cursor" }
}; };
#if SIXEL_PATCH #if SIXEL_PATCH
ImageList *im, *newimages, *next, *tail; ImageList *im, *newimages, *next, *tail = NULL;
int i, x1, y1, x2, y2, numimages; int i, x1, y1, x2, y2, y, numimages;
int cx, cy; int cx, cy;
Line line; Line line;
#if SCROLLBACK_PATCH || REFLOW_PATCH #if SCROLLBACK_PATCH || REFLOW_PATCH
@ -2699,6 +2699,25 @@ strhandle(void)
tfulldirt(); tfulldirt();
} }
return; return;
#if OSC133_PATCH
case 133:
if (narg < 2)
break;
switch (*strescseq.args[1]) {
case 'A':
term.c.attr.mode |= ATTR_FTCS_PROMPT;
break;
/* We don't handle these arguments yet */
case 'B':
case 'C':
case 'D':
break;
default:
fprintf(stderr, "erresc: unknown OSC 133 argument: %c\n", *strescseq.args[1]);
break;
}
return;
#endif // OSC133_PATCH
} }
break; break;
case 'k': /* old title set compatibility */ case 'k': /* old title set compatibility */
@ -2729,15 +2748,33 @@ strhandle(void)
y1 = newimages->y; y1 = newimages->y;
x2 = x1 + newimages->cols; x2 = x1 + newimages->cols;
y2 = y1 + numimages; y2 = y1 + numimages;
if (newimages->transparent) { /* Delete the old images that are covered by the new image(s). We also need
for (tail = term.images; tail && tail->next; tail = tail->next); * to check if they have already been deleted before adding the new ones. */
} else { if (term.images) {
for (tail = NULL, im = term.images; im; im = next) { char transparent[numimages];
for (i = 0, im = newimages; im; im = im->next, i++) {
transparent[i] = im->transparent;
}
for (im = term.images; im; im = next) {
next = im->next; next = im->next;
if (im->x >= x1 && im->x + im->cols <= x2 && if (im->y >= y1 && im->y < y2) {
im->y >= y1 && im->y <= y2) { y = im->y - scr;
delete_image(im); if (y >= 0 && y < term.row && term.dirty[y]) {
continue; line = term.line[y];
j = MIN(im->x + im->cols, term.col);
for (i = im->x; i < j; i++) {
if (line[i].mode & ATTR_SIXEL)
break;
}
if (i == j) {
delete_image(im);
continue;
}
}
if (im->x >= x1 && im->x + im->cols <= x2 && !transparent[im->y - y1]) {
delete_image(im);
continue;
}
} }
tail = im; tail = im;
} }
@ -3431,6 +3468,9 @@ check_control_code:
} }
tsetchar(u, &term.c.attr, term.c.x, term.c.y); tsetchar(u, &term.c.attr, term.c.x, term.c.y);
#if OSC133_PATCH
term.c.attr.mode &= ~ATTR_FTCS_PROMPT;
#endif // OSC133_PATCH
term.lastc = u; term.lastc = u;
if (width == 2) { if (width == 2) {

3
st.h
View File

@ -70,6 +70,9 @@ enum glyph_attribute {
ATTR_HIGHLIGHT = 1 << 17, ATTR_HIGHLIGHT = 1 << 17,
#endif // KEYBOARDSELECT_PATCH #endif // KEYBOARDSELECT_PATCH
ATTR_BOLD_FAINT = ATTR_BOLD | ATTR_FAINT, ATTR_BOLD_FAINT = ATTR_BOLD | ATTR_FAINT,
#if OSC133_PATCH
ATTR_FTCS_PROMPT = 1 << 18, /* OSC 133 ; A ST */
#endif // OSC133_PATCH
}; };
#if SIXEL_PATCH #if SIXEL_PATCH