Tk Source Code

View Ticket
Bounty program for improvements to Tcl and certain Tcl packages.
Tcl 2019 Conference, Houston/TX, US, Nov 4-8
Send your abstracts to
or submit via the online form by Sep 9.
Ticket UUID: 1499165
Title: 8.5 text widget slow to update scrollbar
Type: Bug Version: None
Submitter: nobody Created on: 2006-06-01 21:58:27
Subsystem: 18. [text] Assigned To: fvogel
Priority: 6 Severity: Minor
Status: Closed Last Modified: 2015-11-22 21:11:47
Resolution: Fixed Closed By: fvogel
    Closed on: 2015-11-22 21:11:47
When reading large files into a text widget,
the widget sends scrollbar updates over many seconds
as (i assume) it's calculating display lines. While 
this is happening, the scrollbar will only represent 
the part of the widget that the widget has processed.

8.4 doesnt have this slow scrollbar update behavior.

I'm assuming this was to improve scrollbar accuracy, 
counting display lines instead of file lines.

It would be nice to have an option to return to the 
inaccurate but quick behavior of 8.4.
I have one font and no line-wrapping, so a simply file 
line count is correct.

I'm running Solaris 5.8 on a 440MHz Sun.

User Comments: fvogel added on 2015-11-22 21:11:47:
This bug was fixed by a patch from Koen Danckaert: [5b11cf19].

Testcase added in core-8-5-branch([1f922fd3]) and trunk (2f487e41]) to guard against regressions.

pcmacdon added on 2008-09-01 01:33:39:
Logged In: YES 
Originator: NO

From problem 1916280, here is a reproducable script that causes
the scrollbar to dance, and you can not get to the end of
the widget using the scrollbar for several minutes.

pack [scrollbar .s -command ".t yview"] -fill y -side left
pack [text .t -yscrollcommand ".s set"] -fill both -expand y -side left
.t insert end "[string repeat a\nb\nc\n 100000]THE END\n"
.t see 1000.0

nobody added on 2006-06-09 02:40:59:
Logged In: NO 

Create any large file. Contents are immaterial.
Faster machines require a larger file to visually get the effect.
1MB shows it just fine on a 440MHz Sun.

When you open the file, the script will dump each yscrollcommand call.
Youll see the milliseconds since previous call (~200ms) and the scroll 
I see the 2nd arg (bottom of display) getting smaller w/ each call.

If I immediately scroll to bottom of scrollbar,
i see the args initially near bottom (.9xxx .9xxx)
and with each call to scrollbar, that number approaches (,
indicating that the scrolled to point is further from end of text.
I can also see the scrollbar moving upwards.

#! /bin/sh
# -*- tcl -*- \
exec wish $0 $@

package require Tcl 8.4
package require Tk 8.4

proc t {f} {
text .text
set fid [open $f]
.text insert 1.0 [read $fid [file size $f]]
scrollbar .sb -orient vertical
.text config -yscrollcommand "yscrollcommand"
.sb config -command ".text yview"
grid .sb .text -sticky ns

set ms 0
proc yscrollcommand {args} {
  set ms [clock milliseconds]
  puts "delta: [expr {$ms - $::ms}] args: $args"
  set ::ms $ms
  eval .sb set $args

t $argv

nobody added on 2006-06-05 03:26:28:
Logged In: NO 

I don't see this problem (i.e. when I load a multi-MB file
into a text widget, and scroll to the end, it's all just
fine), so will need a clear, simple reproducible example
/with code/ to be able to do any diagnosis.


nobody added on 2006-06-03 04:39:10:
Logged In: NO 

Read some large file (multi-MB) into a text widget.
Scroll to the end.
If file is sufficiently large,
end of scrollbar wont be end of text.
Scrollbar will then move up w/ each scrollbar update.

Here's an example of loading a 1MB file and immediately 
scrolling to the end.
Display is clocks between yscrollcommands and its args. 
Youll notice that the scrolled to point keep getting further 
from the end.

clocks=102 args=0.9611677479147359 0.9995366079703429
clocks=41 args=0.959927622578225 0.9964693940597555
clocks=66 args=0.8597912878488418 0.8925211479168313
clocks=210 args=0.640319114486738 0.6646942800788954
clocks=210 args=0.49692718923488155 0.5158438235361312
clocks=210 args=0.406006757135124 0.42146230377242266
clocks=207 args=0.3432110453648915 0.356276134122288
clocks=208 args=0.30033276721483504 0.3117655993261809
clocks=206 args=0.26697843404401567 0.27714155957334513
clocks=209 args=0.24645070645954428 0.25583239856328677
clocks=209 args=0.2226715259720317 0.23114801089248788
clocks=212 args=0.20524458367932363 0.21305767343549484
clocks=210 args=0.19034742277063096 0.19759341909512557
clocks=210 args=0.17746646649913514 0.1842221206879671
clocks=210 args=0.16621834354796802 0.172545813018692
clocks=210 args=0.1563110842819363 0.1622614119811429
clocks=210 args=0.1475184135208822 0.15313402872916188
clocks=210 args=0.13966225760883524 0.1449788108385771
clocks=210 args=0.1326005584208152 0.13764829242717974
clocks=210 args=0.12621860637853397 0.13102339724246787
clocks=210 args=0.12017193465157266 0.1247465455610252
clocks=210 args=0.11467812516475985 0.11904360204565825
clocks=210 args=0.1096646684245819 0.11383929696835249
clocks=210 args=0.10507120360172358 0.10907097173110737
clocks=209 args=0.10102365934994845 0.10486934874086185
clocks=210 args=0.09727638640429338 0.10097942754919499
clocks=210 args=0.09379716594651004 0.0973677628571675
clocks=201 args=0.0905582293869802 0.09400552900228154
clocks=210 args=0.08740290686694072 0.09073009214052938
clocks=210 args=0.0844600629052926 0.08767522230419757
clocks=210 args=0.08170893422639283 0.08481936581755892
clocks=210 args=0.07913137751389737 0.08214368869873978
clocks=210 args=0.07671146880720033 0.07963166080629745
clocks=210 args=0.0744351742216321 0.07726871402465317
clocks=210 args=0.07229007760440036 0.07504195955265301
clocks=210 args=0.07035083236571694 0.07302889264794828
clocks=210 args=0.06843165014944157 0.07103665250904515
clocks=210 args=0.06661439846135471 0.0691502231096928
clocks=210 args=0.06489116685362419 0.06736139287333827
clocks=210 args=0.06325484277168524 0.06566277849027083
clocks=210 args=0.061699013428492 0.06404772305649951
clocks=210 args=0.060217881812267275 0.06251020888415165
clocks=210 args=0.05880619450842985 0.06104478257578216
clocks=210 args=0.05745917944139037 0.05964649039617274
clocks=211 args=0.0561724919812612 0.05831082232747445
clocks=209 args=0.054942168132986774 0.05703366347637848
clocks=209 args=0.05442389637165684 0.05649566255232586

Here's my workaround...

$text config -yscrollcommand "yScroll $text $yScroll"
$yScroll config -command "yview $text"

proc yScroll {w yScroll args} {
  if {[info exists ::after_ysC]} { after cancel $::after_ysC
  scan "[$w index end] [$w index @0,0] [$w index @0,[winfo 
height $w]]" "%d.%d %d.%d %d" lines -> top -> bot
  $yScroll set [expr $top.0/$lines] [expr $bot.0/$lines]
  set ::after_ysC [after 700 "after_ysC $w $yScroll"]

proc yview {w args} {
  if {[lindex $args 0] eq "moveto"} { $w see [expr 
{int([lindex $args 1] * [$w index end])}].0
  } else { eval $w yview $args }

proc after_ysC {w yScroll} {
  $w config -yscrollcommand "$yScroll set"
  $yScroll config -command "$w yview"

nobody added on 2006-06-03 01:49:26:
Logged In: NO 

Or perhaps, rather than an option, the text widget can 
update the scrollbar using file lines until it has a valid 
display line count. This way, the scrollbar will be largely 
correct from the start, instead of being totally wrong while 
display lines are being counted.

As far as I recall that is exactly what it does.  So, you'll
have to provide more detail or a reproducible example to
demonstrate the problem.


nobody added on 2006-06-02 06:22:58:
Logged In: NO 

Or perhaps, rather than an option, the text widget can 
update the scrollbar using file lines until it has a valid 
display line count. This way, the scrollbar will be largely 
correct from the start, instead of being totally wrong while 
display lines are being counted.