Quoted from here:
if (to_end)
{
/* If we want to scroll to the end, including horizontal scrolling,
* then we just create a mark with right gravity at the end of the
* buffer. It will stay at the end unless explicitely moved with
* gtk_text_buffer_move_mark.
*/
gtk_text_buffer_create_mark (buffer, "end", &iter, FALSE);
/* Add scrolling timeout. */
return g_timeout_add (50, (GSourceFunc) scroll_to_end, textview);
}
else
{
/* If we want to scroll to the bottom, but not scroll horizontally,
* then an end mark won't do the job. Just create a mark so we can
* use it with gtk_text_view_scroll_mark_onscreen, we'll position it
* explicitely when needed. Use left gravity so the mark stays where
* we put it after inserting new text.
*/
gtk_text_buffer_create_mark (buffer, "scroll", &iter, TRUE);
/* Add scrolling timeout. */
return g_timeout_add (100, (GSourceFunc) scroll_to_bottom, textview);
}
Though there are quite a few lines of comments, I still don't understand the logic in it,especially, what's the relation between an mark and the position of scroll bar?
UPDATE
It seems that I'm mislead by this comment:
/* and place the mark at iter. the mark will stay there after we
* insert some text at the end because it has right gravity.
*/
Say, the scroll
mark has left gravity,not right gravity,is that right?
Marks have no relation whatsoever to the position of the scroll bar.
They use marks in that code, because it's convenient for the function gtk_text_view_scroll_mark_onscreen()
which is a shortcut for calculating the position of a mark, and then moving the scroll bars to that position.
The "end"
mark is a right-gravity mark, so when they add text to the end of the buffer, the mark stays at the end. That way, when they scroll_mark_onscreen
, both the vertical and horizontal scroll bars move, to display the end of the last line.
The "scroll"
mark has left gravity. They don't care about where it goes when they add text to the end of the buffer, because they move it themselves whenever they add text, to the beginning of the last line. That way, when they scroll_mark_onscreen
, only the vertical scroll bars move, to display the beginning of the last line.
They could just as well have had right gravity for both marks, because they don't care about where the "scroll"
mark goes.
They could also just as well have had left gravity for both marks, and manually moved the "end"
mark to the end of the last line whenever they added text, but they didn't, because they could get the same effect automatically by giving the "end"
mark right gravity.
After checking in the GTK docs, it would appear that mark
is some sort of named position in the scroll area, while the position of the scroll bar is where in the buffer you're actually scrolled to. If you're more familiar with HTML, it would seem like a mark
is slightly equivalent to an anchor on a webpage that you can programmatically scroll to.
In the scroll functions, the function gtk_text_view_scroll_mark_onscreen()
is used to position the scroll bar. This seems to be the most simple way to synchronize a text position and the position of the scroll bars.
They are using two functions to be able to emulate "show the end of the text" (i.e. something which might include a horizontal offset) and "show the last line of text" (where the horizontal offset is left unchanged).