Re: GTK v1.3.2: New text widgets



"J. Ali Harlow" <gtk-list optosun7 city ac uk> writes: 
> This was all easy to implement except for managing the scrolling. I've got my
> own mark for our insertion point and so I thought I should just be able to call
> scroll_to_mark() at the end of each putstr() function. This works if putstr()
> is only called once between calls to gtk_main(), but fails otherwise (it seems
> only the first call is actioned). I ended up having to use the adjustment
> changed signal to trap when the actual view is being updated and calling
> scroll_to_mark() then, but it seems a little gross.
> 
> I imagine I wouldn't be having these problems if I was in gtk_main() all the
> time, but that's not an option available to me. I suggest that a signal be
> added to GtkTextView which is emitted when the view is being updated, rather
> than having to hijack adjustment changed for this purpose.
> 

Hrm, I'm not sure I understand the problem fully or see exactly what
is going on, but once I do I want to fix it. ;-)

If you call scroll_to_mark() then the adjustment should immediately
(synchronously) be moved to scroll as requested. It shouldn't go
through the main loop at all. 

There may be one problem here involving the main loop. Let me explain
a bit how the view works; when you modify a line of text, the view
"invalidates" that line, which means it sets the height of the line to
zero and schedules an eventual recomputation of the line's height. It
does this recomputation in an idle handler, which means in gtk_main().

During recomputation, if your buffer is big enough you can actually
see the scroll thumb shrinking as the scrollable area expands.
However during this process the visible text should stay constant
(i.e. the top line of the view should remain the same).

It's possible that scroll_to_mark() while the whole buffer or lots of
the buffer is invalid doesn't work, because if you have a bunch of
invalid lines with 0 height, then you can really only scroll before
all of them or after all of them, and you don't have enough "space" in
the adjustment. e.g. the range of the adjustment might be from 0 to 1,
which doesn't give you any precision.

It doesn't make sense to me that one scroll_to_mark() would work but
not the following ones; that's kind of weird. I'm having trouble
coming up with a reason why that happens.


How to fix it... 

One issue with a "view updated" signal is that the view is updated
incrementally in a bunch of chunks, not all at once. So I'm not sure
when to emit this.

You also want to avoid flashing, i.e. you want the view to come up
scrolled to the mark the first time, you don't want it to start
someplace else and then scroll after it updates fully, or something
like that.

Another option is to make scroll_to_mark() a bit smarter. Instead of
scrolling immediately, it could store the mark to be scrolled to, and
only scroll just before drawing to the screen. This is potentially
unintuitive because you might scroll_to_mark() then delete or move the
mark; so the widget could add its own internal mark at the same
position and save that, instead of relying on the passed-in mark.

This would also allow you to call scroll_to_mark() before the text
widget is realized/mapped, which might be convenient.


I'm not sure yet - thanks for doing beta testing though, please
report any other issues like this.

Havoc








[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]