osc: 'Set Color' now updates already rendered cells in current grid

Since we don't have the original palette index in already rendered
cells, we compare the color *value*. If it matches, we assume this was
the color index used, and updates the cell's color.

Note that for performance reasons, we only update the current
grid. This is of course wrong, strictly speaking.

However, it is expected that _Set Color_ is used by full-screen
applications using the alternate grid.
This commit is contained in:
Daniel Eklöf 2020-06-11 17:13:32 +02:00
parent 6454e897ab
commit 957e482f45
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
2 changed files with 48 additions and 1 deletions

View file

@ -30,6 +30,8 @@
double forked.
* Unicode combining character overflow errors are only logged in when
debug logging has been enabled.
* OSC 4 (_Set Color_) now already rendered cells in the **current**
grid (_normal_ or _alternate_).
### Deprecated

47
osc.c
View file

@ -470,7 +470,52 @@ osc_dispatch(struct terminal *term)
if (!color_is_valid)
continue;
LOG_DBG("change color definition for #%u to %06x", idx, color);
LOG_DBG("change color definition for #%u from %06x to %06x",
idx, term->colors.table[idx], color);
/*
* Update color of already rendered cells.
*
* Note that we do *not* store the original palette
* index. Therefor, the best we can do is compare
* colors - if they match, assume "our" palette index
* was the one used to render the cell.
*
* There are a couple of cases where this isn't necessarily true:
* - user has configured the 16 base colors with non-unique colors.
* - the client has used 24-bit escapes for colors
*
* In general though, if the client configures the
* palette, it is very likely only using index:ed
* coloring (i.e. not 24-bit direct colors), and I
* hope that it is unusual with palettes where all the
* colors aren't unique.
*
* TODO: we should update *both* grids... but that's
* really really slow. Normal usage of this OSC is by
* full-screen applications using the alt screen.
*/
for (size_t r = 0; r < term->grid->num_rows; r++) {
struct row *row = term->grid->rows[r];
if (row == NULL)
continue;
for (size_t c = 0; c < term->grid->num_cols; c++) {
struct cell *cell = &row->cells[c];
if (cell->attrs.have_fg && cell->attrs.fg == term->colors.table[idx]) {
cell->attrs.fg = color;
cell->attrs.clean = 0;
row->dirty = true;
}
if (cell->attrs.have_bg && cell->attrs.bg == term->colors.table[idx]) {
cell->attrs.bg = color;
cell->attrs.clean = 0;
row->dirty = true;
}
}
}
term->colors.table[idx] = color;
}
}