gdamore/tcell

Unicode disappears if requested twice on the same place on Windows

iscas-zac opened this issue · 6 comments

Hello, I am faced with a display issue of Lazygit, which tracks to a similar problem here in #145 , where the unicode disappears after I want it to show on the same place twice. The problem appears just one day, and I think it is due to some wrong configuration of my Windows system. The pwsh and cmd, or the terminal type seems not to make a difference.

The function I use is this:

func main() {
	var screen tcell.Screen
	if s, e := tcell.NewConsoleScreen(); e != nil {
		screen = nil
	} else if e = s.Init(); e != nil {
		screen = nil
	} else {
		screen = s
	}

	screen.SetContent(2, 7, '啊', nil, tcell.StyleDefault)
	screen.Show()
	screen.SetContent(2, 7, '啊', nil, tcell.StyleDefault)
	screen.Show()
}

and the difference is shown below:
bad image
and
good image
(the displayed case just deletes a random statement of the last four in the main function. Any one will do.)

I am pretty convinced that this problem is hard to reproduce, as my computer has also been good for a long time, so feel free to ask me about any configuration of my computer.

I also notice that the solution in #145 is finally merged with #251 . I deleted the change in it and the character showed indeed. That is, the fix may be incomplete and result in some side effects.

While not knowing the reason, I do notice a fix not exactly involving the for loop in draw. In https://github.com/gdamore/tcell/blob/main/cell.go#L53, I spot another for loop:

for i := 1; i < c.width; i++ {
	cb.SetDirty(x+i, y, true)
}

and after I change the 1 to 0, the display problem also disappeared.

As I am not quite familiar with the tcell project, the 'dirty' semantics as well as other stuff is not quite clear to me. Could anyone check this loop and tell me if there is any problem? Any other fix options are also welcome.

Reproduction Disclaimer again: the display problem appeared in my computer some day mysteriously, and it is probably difficult to reproduce for some computers.

I tried the test program but I couldn't reproduce the issue on Amazon Workspaces Windows. I think the version of Windows you are using is very important as they are changing a lot with regards the terminal during the last 5 years.

OK, here are some system information.

OS version: win11 family chinese / 22H2 / 22621.2134
experience pack: Windows Feature Experience Pack 1000.22659.1000.0
Intel UHD graphics 770 / AMD radeon RX 640

I suspect that the problem is that marking the character next to the start of the full width character dirty causes some problems indeed.

Essentially tcell needs to know not to draw whatever text is in a cell next to a full width character, because that full width character is going to occupy two cells. What may be happening is that by marking it dirty, we wind up drawing the following character (which might have some content) when we should not have.

There really is no good solution for coexistence of full width and half width here -- we probably need to have a special place holder that says "don't touch this cell", it's occupied by the previous one, but then what do we do if someone intentionally puts something in that cell? What should happen to the full width character that was displayed before? I think this is sort of undefined behavior and different terminals may behave differently here.

I'll probably take the approach of last writer wins. I need to think through this some more. It's a little hard for me as I don't read any languages where this is common, so I have to fabricate test cases...

Thanks for your attention! This issue may come from my mis-configuration of the terminal, but I don't know exactly which one. As this is a very local issue for my machine, I appreciate any suggestions for what could be wrong or what test should be run on the machine. I can not provide more professional help though, as a result of my lack of domain-specific knowledge.

As for the dirty semantics, shouldn't we also mark the start of FWC dirty besides marking the character next to the start of the full width character dirty? I'm unfamiliar with the meaning here.

p.s. OK, I read jesseduffield/lazygit#2741 and am surprised to find other victims there, and probably the problem is not very local to my machine :D