Tk Source Code

View Ticket
Login
Ticket UUID: 2949648
Title: 'text see' doesn't work when the text is not yet
Type: Bug Version: obsolete: 8.5.5
Submitter: ebrunel Created on: 2010-02-11 11:12:58
Subsystem: 18. [text] Assigned To: fvogel
Priority: 6 Severity: Minor
Status: Closed Last Modified: 2015-12-05 17:29:05
Resolution: Invalid Closed By: fvogel
    Closed on: 2015-12-05 17:29:05
Description:
An initial 'text see' command issued just after populating the text often doesn't work. In specific cases of complex layout, and/or when the text contains a lot of lines, doing 'update idletasks' or 'update' before the 'text see' doesn't solve the problem, and neither does performing the see in an 'after idle' or via a custom event sent via 'event generate'.

The wrong behavior can be seen with the attached example script: the initial call to center_text does not center the line in the text on display. Successive calls via the 'Center' button work.

A workaround seems to be to add the following lines at the beginning of proc center_text:
.texts.txt count -update -ypixels 1.0 end
.texts.lines count -update -ypixels 1.0 end
and to replace the line center_text with:
tkwait visibility .texts
after idle after 5 center_text
(thanks to Peter Spjuth for this)

This workaround is quite complicated and basically impossible to find without help. It would be better if an initial 'text see' command worked out of the box, without any need for such a trick.
User Comments: fvogel added on 2015-12-05 17:29:05:
Thanks for the very clear explanation about what's happening in the provided example. Makes perfect sense.

Considering this explanation, my understanding is there is no bug in Tk, therefore I'm closing this ticket now. Please simply reopen in case you disagree.

Thanks again for the comments!

danckaert added on 2015-12-02 16:45:58:
The example contains a complex interaction of [text see] and [text yview moveto]. The intention is that the scroll position of the two windows is kept in sync by the scrollbar commands. But Tk scrollbars are simply not designed to work this way.

The [text see] command internally computes the pixel heights of one widgets up to that specific line, then sets the scroll position. But the other widget's lineheights have not been computed yet at that moment, such that it will set its scroll position wrong. In turn, this causes a reset of the scroll position of the first widget, etc. In fact, syncing the scroll position between the two widgets cannot work reliably in both directions, unless all line metrics have been computed.

The example can be fixed in the following way:
- After packing the widgets, an [update idletasks] is necessary such that the window layouts are known.
- Modify the scroll procs like this:
    proc scroll_text { first last } {
      .texts.vscroll set $first $last
      .texts.lines count -update -ypixels 1.0 end
      .texts.lines yview moveto $first
    }
    proc scroll_lines { first last } {
      .texts.vscroll set $first $last
      .texts.txt count -update -ypixels 1.0 end
      .texts.txt yview moveto $first
    }

This will of course slow down scrolling initially. Better solutions may be possible with the asynchronous [sync -command] of TIP 438, but it will be more complex to avoid back-and-forth iterations between the two widgets.

martynsmith added on 2013-05-15 16:29:07:
I just updated my code to use the obsoleted -pickplace option and that works correctly.

However when I update the attached code (replace see by yview -pickplace) it does nothing and clicking on the button as soon as the display appears produces a sort of scrolling animation which stops after a moment but not on the correct line.

Its as if the text widget is updating something in the background

martynsmith added on 2013-05-15 15:03:32:
I forgot to mention that this is with TCL8.6.0 so the problem is still present

martynsmith added on 2013-05-15 15:01:27:
I am having the same problem with the 'yview moveto' command, if I trace the value, I set 0. 9 and then ask for 'yview' it returns "0.0 1.0" with about 1500 lines in the widget

I too found the 'count -update' trick but with several text widgets and several thousand lines of text it hangs the display for several seconds (on an i7 with 8GB RAM), plus the yview seems to shift down slightly every reload.

I even tried 'yview scroll xxx units' which did not work either.

ebrunel added on 2010-02-11 18:12:58:

File Added - 362501: text_see_pb.tcl

Attachments: