Incomplete redraw in GtkTextView when inserting, deleting and scrolling
Steps to reproduce
#!/usr/bin/env python3
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, GLib
class TextArtifacts:
def __init__(self):
self.window = Gtk.Window(title='text artifacts')
self.window.set_default_size(800, 600)
self.scrolledwin = Gtk.ScrolledWindow()
self.window.add(self.scrolledwin)
self.scrolledwin.set_hexpand(True)
self.scrolledwin.set_vexpand(True)
self.textbuffer = Gtk.TextBuffer()
self.end_mark = self.textbuffer.create_mark(None, self.textbuffer.get_end_iter(), False)
self.textview = Gtk.TextView()
self.textview.set_buffer(self.textbuffer)
self.scrolledwin.add(self.textview)
self.scrolledwin.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.ALWAYS)
self.scrolledwin.get_settings().props.gtk_enable_animations = False
self.marks = []
self.window.show_all()
def scroll_to_bottom(self):
self.textview.scroll_to_mark(self.end_mark, 0, False, 1, 1)
def add_number(self, number):
getend = self.textbuffer.get_end_iter
markbefore = self.textbuffer.create_mark(None, getend(), True)
self.textbuffer.insert(getend(), '%s\n' % number)
markafter = self.textbuffer.create_mark(None, getend(), True)
self.marks.append((markbefore, markafter))
self.scroll_to_bottom()
def remove_first(self):
markbefore, markafter = self.marks.pop(0)
before = self.textbuffer.get_iter_at_mark(markbefore)
after = self.textbuffer.get_iter_at_mark(markafter)
self.textbuffer.delete(before, after)
self.textbuffer.delete_mark(markbefore)
self.textbuffer.delete_mark(markafter)
def do_number(self, number):
self.add_number(number)
while len(self.marks) > 100:
self.remove_first()
if number < 200:
GLib.timeout_add(100, self.do_number, number+1)
demo = TextArtifacts()
demo.do_number(0)
Gtk.main()
Current behavior
The demo program adds numbers at the bottom and keeps scrolling to the bottom.
After 100 numbers, it keeps the list at length 100 by removing lines from the top. At that point, the textview shows some artifacts: it only updates the bottom two lines and the upper part of the window does not scroll up any more.
When you trigger redraws manually (e.g. select some text), the window reverts to the state it should have.
Expected outcome
It should scroll up all of the contents consistently.
Version information
Tested on Debian and arch Linux, both have GTK 3.24.20-1, X11.
Additional information
Screenshot is attached.