The current implementation has severe problems, so it has been completely overworked.
Note that these tests are the results from the March (2016) version of wish8.6.5 (the repository of Tk doesn't provide revision numbers – this is a step backwards). In the meanwhile the first bug has been fixed (and probably some more when you read this).
Here is the first example for a crash (but fixed in newer repository versions):
pack [text .t]
bind .t <<WidgetViewSync>> { destroy .t }
.t sync -command update
exit 0
A crash with nested calls:
pack [text .t]
proc secondaryUpdateAction {} { exit 0 }
proc primaryUpdateaction {} { .t sync -command secondaryUpdateAction }
.t sync -command primaryUpdateaction
A crash with succeeding calls:
pack [text .t]
proc updateAction {} {}
.t sync -command updateAction
.t sync -command updateAction
exit 0
Now try this script:
proc Sync {} { puts [.t pendingsync]; exit 0 }
pack [text .t]
after 1 [list .t sync -command Sync]
after 1 [list .t insert end "a"]
The result is "1", with other words: procedure Sync has been called although the line height calculation is not up-to-date at this moment. This is very confusing, and should not happen at all.
Another problem in original implementation: the following script hangs (often, sometimes it doesn't), but it works as expected in the revised implementation (all other problems are also eliminated):
pack [text .t]
bind .t <<WidgetViewSync>> { set res 1 }
.t insert end "foo"
update
.t sync
vwait res
exit 0
Also the following script hangs with original implementation: updateAction will not be called, although it should be called due to documentation:
proc updateAction {} { exit 0 }
text .t
.t insert end "1"
.t sync -command updateAction
# this script should terminate with call of 'updateAction'
And also in this script sync is not working at all:
pack [text .t -height 10 -width 20 -wrap word -font {Courier -20}]
.t debug on
append str "A very "
append str [string repeat "long " 100]
append str "line."
.t insert end $str
.t sync
puts "height=[.t count -ypixels 1.0 end]"
puts $tk_textInvalidateLine
exit 0
The output is "height=18", this result is incorrect, because it has to wrap into many display lines. And it terminates with error message can't read "tk_textInvalidateLine", this is possible only if no display line calculation has been done at all (because the line metric calculation is defining this variable, if debug mode is enabled).
The revised implementation now triggers the <<WidgetViewSync>> event even when sync is returning immediately since there is no pending update:
This ensures that a following vwait, which waits for a variable change caused by <<WidgetViewSync>>, will return.
It is not a real change of the original behavior, because executing sync expects the triggering of <<WidgetViewSync>> anyway.
The updated documentation:
Controls the synchronization of the view of the text widget.
If a command is given (with -command command) then it is ensured that command will be called only when all line height values currently are up-to-date. When waiting for event <<WidgetViewSync>> it is possible that some race conditions will affect the received state.
I want to state that this definition is still compatible to original definition; the original documentation of sync is very sparse. And the extension with augmenting a script is compatible because the original implemented is crashing in this case. I cannot understand why the original implementation is not offering this standard Tk behavior with replacing and augmenting.
A note about the -update option in command count, the current documentation says:
This -update option is obsoleted by pathName sync, pathName pendingsync and <<WidgetViewSync>>.
But this is not true, there is a big difference. sync waits for the syncnronization of all display lines, but count -update only needs the synchronization within the lines of the specified range, and the revised implementation (and also the original implementation) is actually doing this. Moreover the problem with race conditions does not occur with count -update. With other words, option -update isn't obsolete at all.