GNOME Bugzilla – Bug 731155
Shifts the last line to the right if it's updated twice in a row
Last modified: 2018-01-18 11:26:46 UTC
Copying https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=525507: When the last line of a gnome-terminal is updated twice in a row, once with a shorter string and once with a longer string, both displayed flush-right, the second string is displayed at the same starting location as the first one and truncated to the length of the window. For instance, the attached program prints "0%" and then "50%" in the lower-right hand corner of the terminal. It works correctly in the Linux console and in xterm, but gnome-terminal displays "50" instead of "50%". See [debian] #455220 for a manifestation of this in the real world.
Created attachment 277791 [details] the test program
What the ncurses app does: - prints "0%", temporarily turning off wraparound (\e[?7l) for the % character - prints 2 backspaces - prints "50" This clearly assumes that the % sign did not advance the cursor, that is, it is still in the visible (1-based) 80th column, rather than in the invisible 81st column as vte thinks. xterm's behavior doesn't make too much sense to me (e.g. launch "cat", type 80 characters, then couple of Backspaces, then Enter => the line echoed back is not the same), I like vte's behavior much more, but it's not a matter of taste, we should mimic xterm. What we could do differently is to visually show the cursor elsewhere (in the invisible 81th column as we do now, or at the beginning of the next line as konsole does), but logically for all kinds of cursor moving operations it should be condsidered that it's still in the last visible column, i.e. didn't advance when printing the % sign. I think xterm needs a special internal boolean differentiating between the cursor that has just arrived at the 80th column and the cursor that should actually be in the 81st (i.e. before and after printing that % sign). We should study what kinds of operations alter this flag (e.g. what about moving the cursor vertically?)
This is also the reason for failing vttest's "Test of cursor movements" where uppercase and lowercase letters are printed vertically on the two sides: http://invisible-island.net/vttest/vttest-wrap.html#WRAP-VTE
On a slightly related mode, we don't support reverse wraparound (decset 45), enabling that mode makes it possible to backspace at line boundary in cooked tty mode. It's probably something that could make sense to enable from bashrc.
Created attachment 281686 [details] [review] Fix v1 This patch fixes the originally reported issue ("50%" shows up correctly in the bottom right corner) and the relevant bits of vttest (the left and right margins correctly display the alphabet). Note that the given screen of vttest is still buggy: the upper and lower lines are incorrect. I'll investigate.
Created attachment 281689 [details] [review] Fix part 2 - deccolm clear screen & home The remaining issue is indeed orthogonal, but so small that I'm lazy to file a new bug :) A deccolm 80/132 mode switch should clear the screen and move the cursor home. With both patches applied, vte now fully passes vttest's 1st menu entry.
Created attachment 281694 [details] [review] Fix part 1, version 2
Created attachment 281696 [details] [review] Fix part 1, version 3
Created attachment 281698 [details] [review] Fix part 1, version 4 (git merge, no actual change)
Committed to master.
*** Bug 744819 has been marked as a duplicate of this bug. ***
Hi, There's still an edge case with this one in regards to the infamous zsh "writing to the rightmost character of terminal" issues with their RPROMPT. I did some tracing to see what happens in libvte and traced it to the call "ensure_cursor_is_onscreen()" from "seq_cursor_backward()" in vteseq.cc. When writing to the rightmost character, say character 79 by your indexing in an 80 char wide terminal, this call clamps the cursor, and then when the shell performs 'termcap[cub]', it ends up being off. (Cursor moves back too far) If I disable the safety check in "seq_cursor_backward()" it works like I expect, but that is most likely not the correct way to go about it. But clamping the cursor in cases like this is not correct as this breaks anything that tries to keep track of the cursor on its own. Reproduction: Install zsh, create a simple .zshrc file that sets PROMPT and RPROMPT (set it to anything that's non-empty). In the shell toggle between ZLE_RPROMPT_INDENT=0 and ZLE_RPROMPT_INDENT=1 (default), this disables and enables their workaround for the issue. It behaves like an environment variable. Would be nice if there could be a proper fix for libvte so gnome-terminal and other libvte based terminals doesn't need to enable this workaround in zsh.
Hi, > I did some tracing to see what happens in libvte and traced it to the call > "ensure_cursor_is_onscreen()" from "seq_cursor_backward()" in vteseq.cc. > When writing to the rightmost character, say character 79 by your indexing > in an 80 char wide terminal, this call clamps the cursor, and then when the > shell performs 'termcap[cub]', it ends up being off. (Cursor moves back too > far) That's correct (and as far as I recall years later, that's exactly what this bugreport was about). This is the expected behavior for legacy reasons, changing it would break plenty of fullscreen applications. > If I disable the safety check in "seq_cursor_backward()" it works like I > expect you expect != others expect :) > clamping the cursor in cases like this is not correct as this breaks > anything that tries to keep track of the cursor on its own. Anything that tries to keep track of the cursor on its own should be aware of this behavior and should try to keep track of the cursor accordingly. Let me know if I misunderstand you and vte's behavior differs from xterm's, in that case I'll investigate.
Late night writing, it = zsh. I double-checked xterm and it behaves the same as vte in this regard, going off memory is dangerous. Apologies for the noise. It did give me some useful pointers for where to go dig next however, thank you for those.