mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-04-29 06:46:35 -04:00
osc8: handle LCF correctly
When the client application has printed something to the last column, the cursor remains in that last column, but the LCF flag is set. The next time something is printed, we linewrap. This needs special consideration both when an OSC-8 URL is started, and closed, when LCF is set. Before this patch, emitting an OSC-8 URL while the cursor was in the last column (with LCF set) would incorrectly include the last character from that line, when the URL really should start at the next line. Furthermore, ending an OSC-8 URL with LCF set would inorrectly exclude the last character. This patch fixes this by using the will-be-printed-to coordinates (i.e. the next line) in the OSC-8 start/end coordinates. Note that this means that we _can_ point to uninitialized grid data (i.e. to a NULL-row). This should be ok though, since either something *will* be printed to that row before the URL is closed, or a cursor movement causes the URL to be closed while still being empty, which is a no-op.
This commit is contained in:
parent
d19326c496
commit
040f8dbe00
1 changed files with 22 additions and 11 deletions
33
terminal.c
33
terminal.c
|
|
@ -3363,7 +3363,6 @@ ascii_printer_fast(struct terminal *term, wchar_t wc)
|
|||
cell->wc = term->vt.last_printed = wc;
|
||||
cell->attrs = term->vt.attrs;
|
||||
|
||||
|
||||
/* Advance cursor */
|
||||
if (unlikely(++col >= term->cols)) {
|
||||
grid->cursor.lcf = true;
|
||||
|
|
@ -3602,10 +3601,16 @@ term_osc8_open(struct terminal *term, uint64_t id, const char *uri)
|
|||
|
||||
xassert(term->vt.osc8.uri == NULL);
|
||||
|
||||
term->vt.osc8.begin = (struct coord){
|
||||
.col = term->grid->cursor.point.col,
|
||||
.row = grid_row_absolute(term->grid, term->grid->cursor.point.row),
|
||||
};
|
||||
struct grid *grid = term->grid;
|
||||
int col = grid->cursor.point.col;
|
||||
int row = grid_row_absolute(grid, grid->cursor.point.row);
|
||||
|
||||
if (grid->cursor.lcf) {
|
||||
row = (row + 1) & (grid->num_rows - 1);
|
||||
col = 0;
|
||||
}
|
||||
|
||||
term->vt.osc8.begin = (struct coord){.col = col, .row = row};
|
||||
term->vt.osc8.id = id;
|
||||
term->vt.osc8.uri = xstrdup(uri);
|
||||
|
||||
|
|
@ -3623,11 +3628,17 @@ term_osc8_close(struct terminal *term)
|
|||
if (term->vt.osc8.uri[0] == '\0')
|
||||
goto done;
|
||||
|
||||
struct grid *grid = term->grid;
|
||||
int col = grid->cursor.point.col;
|
||||
int row = grid_row_absolute(grid, grid->cursor.point.row);
|
||||
|
||||
if (grid->cursor.lcf) {
|
||||
row = (row + 1) % (grid->num_rows - 1);
|
||||
col = 0;
|
||||
}
|
||||
|
||||
struct coord start = term->vt.osc8.begin;
|
||||
struct coord end = (struct coord){
|
||||
.col = term->grid->cursor.point.col,
|
||||
.row = grid_row_absolute(term->grid, term->grid->cursor.point.row),
|
||||
};
|
||||
struct coord end = (struct coord){col, row};
|
||||
|
||||
if (start.row == end.row && start.col == end.col) {
|
||||
/* Zero-length URL, e.g: \E]8;;http://foo\E\\\E]8;;\E\\ */
|
||||
|
|
@ -3645,7 +3656,7 @@ term_osc8_close(struct terminal *term)
|
|||
while (true) {
|
||||
int end_col = r == end.row ? end.col : term->cols - 1;
|
||||
|
||||
struct row *row = term->grid->rows[r];
|
||||
struct row *row = grid->rows[r];
|
||||
|
||||
switch (term->conf->url.osc8_underline) {
|
||||
case OSC8_UNDERLINE_ALWAYS:
|
||||
|
|
@ -3670,7 +3681,7 @@ term_osc8_close(struct terminal *term)
|
|||
break;
|
||||
|
||||
r++;
|
||||
r &= term->grid->num_rows - 1;
|
||||
r &= grid->num_rows - 1;
|
||||
}
|
||||
|
||||
done:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue