Xterm.js: Emoji can leave artifacts in right cell

Created on 8 Jun 2018  路  9Comments  路  Source: xtermjs/xterm.js

All 9 comments

Two possible solutions come to my mind:

  • mark cell as overdrawn by left cell and therefore redraw it when left cell gets new content
  • scale bogus chars to fit in wcwidth * cells, no overdrawing at all

mark cell as overdrawn by left cell and therefore redraw it when left cell gets new content

I thought this was already supported, might have been broken in some cases recently?

There is the _isOverlapping test in the code (https://github.com/xtermjs/xterm.js/blob/master/src/renderer/TextRenderLayer.ts#L84), but to me it seems it is only applied when an overlapping char gets rendered but not when it gets removed (commented out?) Maybe @bgw can have a look at it?

Yeah I think it used to, if a cell is overlapping it must be drawn at the same time as its neighbouring cell, and if it's removed the neighbouring cell needs to be redrawn as well.

Read the original issue - the example the OP gave with the aubergines looks like it is wcwidth related, where the system wcwidth gives 2 and xterm.js's 1. This would explain why the OP can move the cursor further back into the prompt. I dont have Ubuntu 18 here - can someone with Ubuntu 18 test the system wcwidth for 馃崋?

Edit:
On Ubuntu 14 it works as expected, also the overlapping is removed, so I am not sure if it is related to it.

To elaborate on what I think @Tyriar was trying to get at, we clear entire rows at a time: https://github.com/xtermjs/xterm.js/blob/fb63b3475b009b9f340703b28e0336c44030d82a/src/renderer/TextRenderLayer.ts#L213

There should be one clearRect or fillRect call (depending on alpha) per frame.

can someone with Ubuntu 18 test the system wcwidth for 馃崋?

I'm not on Ubuntu 18, but I'm on Debian Stable, which is a lot closer than Ubuntu 14. On my machine, wcwidth for 馃崋 is 2:

selection_064

The program if anyone wants it for testing:

#define _XOPEN_SOURCE
#include <stdio.h>
#include <stddef.h>
#include <wchar.h>
#include <locale.h>

int main() {
    wchar_t wc = L'\U0001F346';
    setlocale(LC_ALL, "en_US.UTF-8");
    wprintf(L"%d, %lc\n", wcwidth(wc), wc);
}

I think this has to be a bug in the parser (maybe the wcwidth stuff). I don't see how it could happen from looking at the renderer.

we clear entire rows at a time

Oh I forgot about that 馃槄. I'm quite puzzled as to how this is happening then as the emoji would need to be drawn, but it looks like the class of bugs where the right is not "cleared" (which can't happen because we always clear and redraw the cells now).

@bgw Thanks for testing - yupp this is a bug in wcwidth, which returns 1 here. This is a case where the backend wcwidth and our wcwidth return different values for a specific char (see https://github.com/xtermjs/xterm.js/issues/1467#issuecomment-391941536 for the background). We can fix it by applying custom settings once #1470 is done.

I don't think this happens anymore.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

zhangjie2012 picture zhangjie2012  路  3Comments

goxr3plus picture goxr3plus  路  3Comments

Tyriar picture Tyriar  路  4Comments

albinekb picture albinekb  路  4Comments

pfitzseb picture pfitzseb  路  3Comments