I found weird anomalies in GTK textview, hopefully someone can explain them.
There is a simple function to scroll to bottom of window:
richTextBox.ScrollToIter(richTextBox.Buffer.EndIter, 0, true, 0, 0);
this is probably supposed to work and work in most cases. But sometimes it crashes whole application with MemoryAccessViolation (SIGSEGV in linux)
My application call this everytime I insert a text to TreeView so that I can be always down (you are inserting a text to some window, and you want to see the latest text, like in a chat)
The text is only inserted from main thread and this function is ALSO called only in main thread, so this can't be related to multithreading in my own application, however I found out that TextView is rendering text asynchronously with the rest of application. Like if the thread responsible for painting and processing the text wasn't really a main thread. For example if I load a huge text into a TextView, my application IS responding, even if TextView is somehow loading the text.
For this reason I believe that TextView is actually working with own separate thread, and this thread is changing the text as I am trying to scroll the window. Text being changed invalidates the iter, so somewhere between in the IL code where I am passing richTextBox.Buffer.EndIter
to TextView ScrollToBottom function the text is probably changed by this foreign thread and iter is invalidated, which is why I get this memory access exception.
This may be even a bug in GTK, but I am using very stable version (2.1.20) that is shipped with all mono versions until mono3 and even for all windows gtk# versions.
Is there any other way to scroll down "safely"
This seems to work:
Connect the function that scrolls to SizeAllocated
event:
this.tv.SizeAllocated += new SizeAllocatedHandler(Scroll2);
Create a function for scrolling
public void Scroll2(object sender, Gtk.SizeAllocatedArgs e)
{
tv.ScrollToIter(tv.Buffer.EndIter, 0, false, 0, 0);
}
I don't know if it's correct, but it didn't crash to me so far and it always scroll to bottom once rendering is done