GNOME Bugzilla – Bug 311728
scrolling queued from the expose handler doesn't get flushed
Last modified: 2018-02-10 04:34:48 UTC
this corresponds to the gedit problem filed in bug #172277. I'm filing a separate bugreport so that we can use that one to track the progress on a workarounds until it's fixed in gtk. That bug also has a patch to testtext.c which allows to reproduce the problem. A bit of context: gedit queues up a scroll from the expose event so that "gedit +100 foo.txt" works properly and appears to the user with the cursor at line 100 and the view scrolled to that point. This however seems to not work on some systems (not sure why it does works on others...) The problem seems to be the following the scroll queued during the expose callback doesn't actually get flushed. It instead gets wrongly flushed when the user clicks on the text view for the first time.
Created attachment 49842 [details] [review] patch Here is a patch to gtktextview.c which seems to fix the issue. Patch explanation: when scroll_to_mark is called it queues a scroll to be flushed in an idle handler, however the idle handler itself is not added, the code assumes it will be already there. However this is not true when queuing the event from "expose" so we need to add the handler ourselves otherwise the scroll is delayed until such an idle is added (e.g. when the user clicks on the text). Note however that my patch may break some other assumptions in the scrolling code (which is quite complicated). Also note that I added the idle explicitely, while other code paths add it by calling invalidate(), which however also adds another idle, so I went with the minimal fix.
Created attachment 50084 [details] log with patched gtktexview.c Here is the log of ./testtext testtext.c of my patched testtext and patched gtktextview. Will attach a similar log with a non patched gtktextview in a bit.
Created attachment 50085 [details] log with an unpatched gtktextview.c
Hmm, what I forgot to mention is that it would be very helpful to add some printfs to the beginning and end of the gedit expose callback in testtext.c, to see where it falls in the log...
Created attachment 50089 [details] updated log with patched gtktextview
Created attachment 50090 [details] updated log with unpatched gtktextview
This will need some debugging, in order to gain some understanding of a) what is happening b) what is supposed to happen c) why it only happens for some people
If I understand it right, the problem is gtk_text_view_update_adjustments(): when textview height changes, it moves the bottom down, i.e. adjustment value doesn't change. So, what happens is: textview is initially zero pixels high but contains lots of text, so flush_scroll (which is called after first_validate() is done) validates a region around line 1000, and adjustment is set to be one page high, and adjustment value is some small number, like 500; then incremental callbacks validate whole buffer, and adjustment becomes some ten thousand pixels, but nobody moves cursor back onscreen, adjustment value stays the same 500 pixels, even though cursor is now at 10000.
We're moving to gitlab! As part of this move, we are closing bugs that haven't seen activity in more than 5 years. If this issue is still imporant to you and still relevant with GTK+ 3.22 or master, please consider creating a gitlab issue for it.