GNOME Bugzilla – Bug 542087
Graphical glitches after "change scroll region"
Last modified: 2015-12-26 13:03:21 UTC
Please describe the problem: After sending CSR so that the final line in the terminal is excluded from the scroll region, glitches can occur when interspersing writes to the bottom line with scrolls of the upper region. Steps to reproduce: I will attach a script (scr-fix-min) that produces the problem for me. Actual results: What I currently see: one or both of "foo" and "bar" are missing. Or, on at least one system, the bar will be black/empty when it ought to be reversed/have-text. Actually, when I _should_ see "foo" and "bar", but don't, I will sometimes actually see an effect such that it looks like the top one or two pixel-rows of the bottom line update and switch back, but not the rest of the line. So a masking problem or incorrect information about what portions of the display to update seem likely. Expected results: What you ought to see: the bottom bar flash between "x", "foo", "x", and "bar". Does this happen every time? This reproduces reliably for me on gnome-terminal. xfce4-terminal sometimes shows both "foo" and "bar" as it ought to, and sometimes doesn't (same app, same instance, different runs of script). Other information: This behavior was discovered while I was using screen, which can use the final line as a "status" line. I was playing with screen's "autoaka" feature, which allows the current screen window's name to change based on the currently-running command: I found that everything worked as it should until the prompt reached the bottom, so that hitting enter caused scrolling. At that point, the window title would stop updating.
Created attachment 114201 [details] Reproduction script This script expects LINES and COLUMNS to be exported and refer to the number of lines and columns in your terminal. These must be accurate or the bug won't be shown. If they are unset, you will get a ton of errors, rather than the simulation.
For a history of my attempt to track down this problem on screen's bug-tracker at Savannah, see https://savannah.gnu.org/bugs/?23699
The same problem shows with ne (the nice editor: http://ne.dsi.unimi.it/). When scrolling down, line/column numbers are not updated. Scrolling happens using a scroll region. If scrolling is done by manual rewrite, the problem does not appear. The problem does not appear in any other terminal (xterm, Mac terminal, rxvt, etc.). I have pinpointed very carefully the problem by looking at vim. Essentially, if you do the following on an 80x25 terminal: 1) Set scroll region 1-24 2) Move to pos (24,1) 3) Issue a line feed to scroll the region 4) Set scroll region 1-25 (full screen) 5) Move to pos (24,1) 6) Update line 24 (now empty) 7) Move to pos (25,4) 8) Update lines/cols the last step causes NO OUTPUT (bug, bug, bug...). However, if you do 8) Emit a clear-to-eol and update lines/cols this works. Emitting a clear-to-eol seems to reset the broken state of gnome-terminal.
Which vte version?
gnome-terminal 2.26.3.1
Care to provide exact instructions for reproducing?
Precise instructions were provided with the original report. Please download the attached bash script, do "export LINES COLUMNS", and then run the script with bash. Watch the bottom (reversed) line; you ought to see it flash between "foo", "x", "bar", "x", but instead I just see "x" the whole time (compare results with another term, such as xterm, to see what it is meant to look like). The glitch doesn't always manifest as "seeing x the the whole time", see the "Actual results" section of the original report. I'm still seeing this with libvte9 0.22.2(-0ubuntu2), on gnome-terminal 2.28.1.
Start ne (http://ne.dsi.unimi.it/), open a file with more lines than the terminal rows. Move down: when the file scrolls the line number does not change. It does as soon as you move the cursor on the right. Again, if you emit a clear-to-eol just before printing the line numbers (as vim does, for instance) everything works fine. You can see what ne is doing starting with "ne | tee ne.out". It you add the function call clear_to_eol(); at the start of line 660 of the source file menu.c you'll see that line numbers are now updated.
Ok, I reproduced the missing 'foo' twice out of like 20 or 30 tries.
Well, if that's reproduced why is it that after six months the bug is still "unconfirmed"? ;)
(In reply to comment #9) > Ok, I reproduced the missing 'foo' twice out of like 20 or 30 tries. There is a timing component to this bug. I have modified Micah Cowan's script to accept a "-s" parameter (for "slow") which introduces a 1 second delay immediately after updating the line below the scroll region. This causes the status line update to succeed every time. (See attachment scrollregion.sh.) I've also created a similar script which exactly follows the steps outlined by Sebastiano Vigna in comment #3. This script also takes an optional "-s" (for "slow") parameter, which causes the script to succeed every time. (See attachment scrollseba.sh.) I've also discovered that moving/dragging the mouse around a lot over the window tends to make these scripts succeed slightly more often. I suspect this increased activity is enough to tickle the timing dependency somewhat, at least on my system. C code doing the same thing though is so much faster than these shell scripts that no amount of mouse movement has caused the status line updates in "ne" to succeed (see comment #8).
Created attachment 172851 [details] scrollregion.sh demonstrates the bug
Created attachment 172852 [details] scrollseba.sh Another demo of the bug With the "-s" (for "slow") parameter, these scripts succeed. At full speed they often fail.
Created attachment 175605 [details] [review] Patch to work around update glitch; applies against vte-0.26.0 and vte-0.23.5 Found the source of the problem. The vte_terminal_process_incoming function from vte.c keeps track of a "bounding box" of cells to be invalidated, and uses that to invalidate cells at points such as after all input has been processed, or when a large enough cursor jump is made (to avoid letting the bounding box get needlessly large). This bounding box is represented in terms of the total number of lines in the terminal, including history. The problem that arises is that if a scroll takes place before the bounding box has been used to invalidate cells, then a new row is added to the total terminal rows, increasing the index number of the bottom rows. Thus, the bounding box will now be off by one (or however large the scroll is), and no longer reaches all the way to the bottom of the screen (if it did before). This problem applies, even when no scrollback history is enabled, as the relevant indexes all still increase, even though the true number of actual data rows hasn't changed. The fix I implemented is to force invalidation to take place if we move into a scroll region from outside it.
Created attachment 176035 [details] [review] Revised patch One-line addition to force the cached scroll_delta value to be refreshed after control sequences are handled; fixes this same problem in a few cases apparently not handled by the automated test scripts.
Humm, attached the wrong patch?
No? To be clear, I meant I made a one-line addition, but attached a complete, revised diff.
Ah, ok. So the fix is not a one-line patch...
Ah, no, sorry for the confusion. But it is about 10 lines (3 of which are repeats), not including simple whitespace changes, and should be pretty straightforward.
I actually see the expected result with latest vte, the same as what I see in xterm. Have you tried this with latest vte?
What's "latest"? 0.27, or current dev sources? If the latter, where do I find those? I've reproduced in 0.26 (which is the version currently used by my laptop); I guess I can try 0.27.
Actually, I can't; it's dependencies (mainly gtk+3) are a bit beyond what I'm willing to put on this machine (Ubuntu Maverick) just at the moment (Ubuntu Natty has it; perhaps I'll upgrade soon). Looking at the sources, though, I see no reason why the problem wouldn't still persist. Since I had discovered the source of the problem requires that both the write to the bottom line and the scroll in the scroll region be processed as part of the same invocation of vte_terminal_process_incoming(), and you (Behdad) have had persistent difficulties in reproducing it as easily as some others (Todd's "scrollregion.sh" script is especially consistent for me, with only occasional successes of a single one of the ten iterations), it may help if the reproduction script forces it all to be written at once (to the degree possible). I modified Todd's script slightly, so that the output of a single iteration (multiple calls to tput, etc) is stored in a variable, which is then spewed by a single printf. See if this gets you any further? I'll call it "scrollregion-spew.sh".
Created attachment 176443 [details] Slight modification of Todd's script, to improve odds of processing the codes together. -s is still accepted, but is ignored, since there's no longer a point to it in this version.
(Er, yeah, I mistakenly marked that as a "patch". Anyhoo...)
Double-checking the source, I can guarantee that the problem's still there in 0.27.2, since the same logic flaws addressed by my patch are still present (see the explanation from the first patch I attached), and in fact the function in question was never changed since 0.26.0. No other function could know of the inserted characters, to refresh them; so if this function hasn't changed, neither has the glitch. The only other way the glitch could be removed would be for something to be inadvertently causing it to be refreshed there anyway; but _vte_terminal_cursor_down still only refreshes the scroll region, not the full terminal, so I don't really see where that could happen.
(In reply to comment #22) > Actually, I can't; it's dependencies (mainly gtk+3) are a bit beyond what I'm > willing to put on this machine (Ubuntu Maverick) just at the moment vte does NOT depend on gtk3 (which is only an option; the default is still to build with gtk2).
Ah, apparently the Debian package (I was using it to build, but with patches stripped out) runs the configure script more than once (for some reason). I only paid attention to the options provided for the first invocation; the second appears to use --with-gtk=3.0, so that would explain my problem. I'll see if I can give it a try tonight.
Thanks Micah. The new script reliably reproduces the problem for me. Fixing.
(In reply to comment #28) > Thanks Micah. The new script reliably reproduces the problem for me. Fixing. I'm confused. Ten months later, this bug is still marked UNCONFIRMED, and the fix didn't make it into GNOME 3, at least as shipped with Fedora-15. Did this fall through the cracks, or was the fix rejected for some reason, or what?
Behdad/ChPe, could you please apply Micah's patch? The bug is valid, and the patch indeed seems to fix it. The patch has been shipped by Ubuntu since Precise (12.04 LTS) so it must be very well tested by now.
Note that there's another minor bug revealed by the test script (and not yet fixed): the scrollbar is positioned incorrectly.
The previously mentioned bug, and a few other relevant ones [with patches] are filed at bug 710488, bug 710484, bug 710483 and bug 710481 -- so that we can keep this one clean, for the original report only.
*** Bug 686097 has been marked as a duplicate of this bug. ***
Committed to vte-0-36. I wonder if we need to do the same when the cursor moves out of the restricted scrolling area? Ie sth like this: /* if we have moved greatly during the sequence handler, or moved - * into a scroll_region from outside it, restart the bbox. + * into/out of a scroll_region from out/inside it, restart the bbox. */ if (invalidated_text && - ((new_in_scroll_region && !in_scroll_region) || + ((new_in_scroll_region ^ in_scroll_region) ||
Fixed on 0-36, therefore on master too.