Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Incomplete screen update with [update idletasks]

131 views
Skip to first unread message

Erik Leunissen

unread,
Aug 21, 2019, 7:16:23 AM8/21/19
to
L.S.

I experience unexpected behaviour w.r.t. screen updates when using
[update idletasks].

The observed behaviour can be exercised with the attached script
"updateIssue.tcl". This script swaps two labels using [pack], and
subsequently waits for 2 seconds doing nothing using [after 2000]. A
screen update is attempted just before the app starts waiting. The tiny
gui lets you choose whether you want the screen update to be done by
[update] or [update idletasks]. Please experiment at liberty.

My observation (on Linux, KDE window manager):
- when using [update], the new widget is completely updated (including
text and borders) before the waiting period of two seconds.
- when using [update idletasks], the new widget's background is shown
immediately, but text and borders are updated after the waiting period
of two seconds (at idle time I guess).

Questions:

- Is the incomplete screen update with [update idletasks] intended
behaviour? [*]
- If so: how exactly does that behaviour correspond to the description
in the manual page? [**]


Thanks in advance for any insight,

Erik Leunissen.


[*] : Unexpected to me because various written sources (manpage and
several books related to Tk) mention [update idletasks] as the method of
choice for updating the screen before carrying out long-lasting operations.

[**] Quoting the man page: "The update idletasks command is useful in
scripts where changes have been made to the application's state and
you want those changes to appear on the display immediately, rather
than waiting for the script to complete."


--
elns@ nl | Merge the left part of these two lines into one,
xs4all. | respecting a character's position in a line.
updateIssue.tcl

Rich

unread,
Aug 21, 2019, 7:55:40 AM8/21/19
to
Erik Leunissen <lo...@the.footer.invalid> wrote:
> I experience unexpected behaviour w.r.t. screen updates when using
> [update idletasks].
>
[snip]
>
> My observation (on Linux, KDE window manager):
> - when using [update], the new widget is completely updated (including
> text and borders) before the waiting period of two seconds.
> - when using [update idletasks], the new widget's background is shown
> immediately, but text and borders are updated after the waiting period
> of two seconds (at idle time I guess).

I see the same on Linux using Fvwm2 and Tcl 8.6.

> Questions:
>
> - Is the incomplete screen update with [update idletasks] intended
> behaviour? [*]
> - If so: how exactly does that behaviour correspond to the description
> in the manual page? [**]

On it's face, the behavior does not seem to perfectly correspond with
the manual description. Although the man page does say "most display
updates" rather than "all display updates". So you may have found the
boundary between "most" and "all".

The manpage does continue with:

"However, there are some kinds of updates that only happen in
response to events, such as those triggered by window size changes;
these updates will not occur in update idletasks."

Swapping a widget by using pack forget and repacking a new widget may
very well fall into "updates that only happen in response to events"
which might explain what you are seeing. Is there some reason you are
fully swapping the widget rather than simply reconfiguring the same
widget (i.e., omitting the pack forget and repacking)?

> Thanks in advance for any insight,

Would you care to let us know what you are *really* attempting to
accomplish? If we knew what your real purpose was, we might be able to
suggest an alternative that does not use either update or update
idletasks to accomplish your desired outcome.

Erik Leunissen

unread,
Aug 21, 2019, 12:27:33 PM8/21/19
to
On 21/08/2019 13:55, Rich wrote:

<snip>
>
> I see the same on Linux using Fvwm2 and Tcl 8.6.
>

Thanks for verifying this.

My primary goal is to determine whether this is a bug.

I'd really like this thread to remain focused on that goal (I have no
other "real" purpose, as you suggest).

Erik.
--



(Your analysis of the text of the manual page below provides possible
justifications of the observed behaviour. We need more, however, to be
conclusive about a bug.)


>> Questions:
>>
>> - Is the incomplete screen update with [update idletasks] intended
>> behaviour? [*]
>> - If so: how exactly does that behaviour correspond to the description
>> in the manual page? [**]
>
> On it's face, the behavior does not seem to perfectly correspond with
> the manual description. Although the man page does say "most display
> updates" rather than "all display updates". So you may have found the
> boundary between "most" and "all".
>
> The manpage does continue with:
>
> "However, there are some kinds of updates that only happen in
> response to events, such as those triggered by window size changes;
> these updates will not occur in update idletasks."
>
> Swapping a widget by using pack forget and repacking a new widget may
> very well fall into "updates that only happen in response to events"
> which might explain what you are seeing. Is there some reason you are > fully swapping the widget rather than simply reconfiguring the same
> widget (i.e., omitting the pack forget and repacking)?
>
>> Thanks in advance for any insight,
>
> Would you care to let us know what you are *really* attempting to
> accomplish? If we knew what your real purpose was, we might be able to
> suggest an alternative that does not use either update or update
> idletasks to accomplish your desired outcome.

Thanks for offering help in finding alternatives, but that's not what
I'm after, not yet anyway.

briang

unread,
Aug 21, 2019, 6:14:28 PM8/21/19
to
It's seems there is a basic assumption that an application can make some change to the GUI and then go off into deep computation and expect the GUI to reflect the most recent state immediately. Unfortunately that's not how Tk works, nor most other GUI tool kits. What is really happing is that the GUI queues requests as smallish bits of work when a change is made. This queued work evaluates when the event loop makes a pass. This work can then create another bit of work that gets queued, and so on. The [update] command only makes a single pass through the event queue, then it returns.
When there is only a single thread of execution, this is the only sane way to keep things active and "alive" in the GUI. Smallish amounts of computation can be done in between and mostly all works well. When deep computation required, either the deep work needs to periodically spin the event loop (e.g. [update]), or the work needs to be done in a separate process or thread.

My rule of thumb is 300ms. If a computation can't be completed in under 300ms, it must call the event loop or be off loaded to a non-gui process/thread.

Try replacing the line "after 2000" with: "work 2000"

proc work {t} {
set s [expr {int($t) / 300}]
while {$s > 0} {
update
after 300 ;# do some of the work
incr s -1
}
}

-Brian


Erik Leunissen

unread,
Aug 22, 2019, 3:53:20 AM8/22/19
to
On 22/08/2019 00:14, briang wrote:

Thanks for your explanation Brian. However, some aspects of your
explanation do not correspond to the results of the reproducible script
(attached to my original post) and to what the manpage says.

I'll point them out:

> It's seems there is a basic assumption that an application can make some change to the GUI and then go off into deep computation and expect the GUI to reflect the most recent state immediately.

In the reproducible script a raw [update] appears to do an immediate and
complete screen update, in contrast to [update idletasks].

B.t.w. the manpage for [update] mentions: "The update idletasks command
is useful in scripts where changes have been made to the application's
state and you want those changes to appear on the display
immediately, rather than waiting for the script to complete."

Note the word *immediately*

Unfortunately that's not how Tk works, nor most other GUI tool kits.
What is really happing is that the GUI queues requests as smallish bits
of work when a change is made. This queued work evaluates when the
event loop makes a pass. This work can then create another bit of work
that gets queued, and so on. The [update] command only makes a single
pass through the event queue, then it returns.

Then why does [update] result in an immediate and complete screen update
and [update idletasks] does not?

Furthermore the manpage for [update] says: "This command is used to
bring the application ``up to date'' by entering the event loop
repeatedly until all pending events (including idle callbacks) have been
processed."

Note the word *repeatedly*


Please bear with my persistence; I'd really like to make the manpage
(and my own understanding) correspond with what happens in reality and
see whether there is a (documentation) bug here.

Erik.

> When there is only a single thread of execution, this is the only sane way to keep things active and "alive" in the GUI. Smallish amounts of computation can be done in between and mostly all works well. When deep computation required, either the deep work needs to periodically spin the event loop (e.g. [update]), or the work needs to be done in a separate process or thread.
>
> My rule of thumb is 300ms. If a computation can't be completed in under 300ms, it must call the event loop or be off loaded to a non-gui process/thread.
>
> Try replacing the line "after 2000" with: "work 2000"
>
> proc work {t} {
> set s [expr {int($t) / 300}]
> while {$s > 0} {
> update
> after 300 ;# do some of the work
> incr s -1
> }
> }
>
> -Brian
>
>


Erik Leunissen

unread,
Aug 22, 2019, 4:10:54 AM8/22/19
to
<Reposted without breaking the quoting format>

On 22/08/2019 00:14, briang wrote:


Thanks for your explanation Brian. However, some aspects of your
explanation do not correspond to the results of the reproducible script
(attached to my original post) and to what the manpage says.

I'll point them out:

> It's seems there is a basic assumption that an application can make some change to the GUI and then go off into deep computation and expect the GUI to reflect the most recent state immediately. Unfortunately that's not how Tk works, nor most other GUI tool kits. What is really happing is that the GUI queues requests as smallish bits of work when a change is made. This queued work evaluates when the event loop makes a pass. This work can then create another bit of work that gets queued, and so on. The [update] command only makes a single pass through the event queue, then it returns.

Then why (in the reproducible script) does a raw [update] appear to do
an immediate and complete screen update, in contrast to [update idletasks]?

B.t.w. the manpage for [update] mentions: "The update idletasks command
is useful in scripts where changes have been made to the application's
state and you want those changes to appear on the display
immediately, rather than waiting for the script to complete."

Note the word *immediately*

Furthermore the manpage for [update] says: "This command is used to
bring the application ``up to date'' by entering the event loop
repeatedly until all pending events (including idle callbacks) have been
processed."

Note the word *repeatedly*


Please bear with my persistence; I'd really like to make the manpage
(and my own understanding) correspond with what happens in reality and
see whether there is a (documentation) bug here.

Erik.


> When there is only a single thread of execution, this is the only sane way to keep things active and "alive" in the GUI. Smallish amounts of computation can be done in between and mostly all works well. When deep computation required, either the deep work needs to periodically spin the event loop (e.g. [update]), or the work needs to be done in a separate process or thread.
>
> My rule of thumb is 300ms. If a computation can't be completed in under 300ms, it must call the event loop or be off loaded to a non-gui process/thread.
>
> Try replacing the line "after 2000" with: "work 2000"
>
> proc work {t} {
> set s [expr {int($t) / 300}]
> while {$s > 0} {
> update
> after 300 ;# do some of the work
> incr s -1
> }
> }
>
> -Brian
>
>


briang

unread,
Aug 22, 2019, 10:53:15 AM8/22/19
to
Hi Erik,

The swap script is not simply tossing 1 stone into the pond making a hole. It is tossing several stones that cause ripples, and it take "time" for the ripples to settle out.

I'll try to answer your questions below.

On Thursday, August 22, 2019 at 1:10:54 AM UTC-7, Erik Leunissen wrote:
> <Reposted without breaking the quoting format>
>
> On 22/08/2019 00:14, briang wrote:
>
>
> Thanks for your explanation Brian. However, some aspects of your
> explanation do not correspond to the results of the reproducible script
> (attached to my original post) and to what the manpage says.
>
> I'll point them out:
>
> > It's seems there is a basic assumption that an application can make some change to the GUI and then go off into deep computation and expect the GUI to reflect the most recent state immediately. Unfortunately that's not how Tk works, nor most other GUI tool kits. What is really happing is that the GUI queues requests as smallish bits of work when a change is made. This queued work evaluates when the event loop makes a pass. This work can then create another bit of work that gets queued, and so on. The [update] command only makes a single pass through the event queue, then it returns.
>
> Then why (in the reproducible script) does a raw [update] appear to do
> an immediate and complete screen update, in contrast to [update idletasks]?

I did misrepresent what "update" does. It will empty the event queue, but it does not allow "time" to pass in doing so. Once there are no more events in the queue, it returns. By "time" I mean anything that is literally waiting for "time" or a response from another thread of execution. Windowing system calls can fall into this category, since they often involve other threads or processes. This also doesn't mean a response won't get queued while in this loop, it just means there's no guarantee that *all* work will get done in this single call to [update].

>
> B.t.w. the manpage for [update] mentions: "The update idletasks command
> is useful in scripts where changes have been made to the application's
> state and you want those changes to appear on the display
> immediately, rather than waiting for the script to complete."
>
> Note the word *immediately*

All widgets schedule the redraw as an idle task, i.e., a low priority event. This is more efficient because often things change before the redraw is completed, and thus making the prior redraw obsolete. When this happens, the scheduled idle redraw is removed, and replaced with an updated redraw, thus saving time in the end. The "update idletasks" bypasses other queued events and executes the idle events only (sort-of).

>
> Furthermore the manpage for [update] says: "This command is used to
> bring the application ``up to date'' by entering the event loop
> repeatedly until all pending events (including idle callbacks) have been
> processed."
>
> Note the word *repeatedly*

while (Tcl_DoOneEvent(flags) != 0) {...}

See the Tcl Library man page on Tcl_DoOneEvent().

>
>
> Please bear with my persistence; I'd really like to make the manpage
> (and my own understanding) correspond with what happens in reality and
> see whether there is a (documentation) bug here.

These are good questions. I think it's hard to explain what's really happening without overwhelming the reader. There is a pattern to writing GUI's and for a GUI to work well, following the correct pattern is important. Unfortunately, it is easy to write GUI code that works good enough that most of the time the flaws are not noticed. Once the pattern is understood, you'll see that using "update" is not needed and not a good idea in general.

-Brian

Rich

unread,
Aug 22, 2019, 12:21:26 PM8/22/19
to
Erik Leunissen <lo...@the.footer.invalid> wrote:
> B.t.w. the manpage for [update] mentions: "The update idletasks command
> is useful in scripts where changes have been made to the application's
> state and you want those changes to appear on the display
> immediately, rather than waiting for the script to complete."
>
> Note the word *immediately*

Also note the word "state". I suspect that by "state" what was meant
was contents of variables connected to -textvariable links and/or
"configure -text" changes, not "pack forget" and "pack a different
widget". And myself, what "state" says to me if I read this part of
the manpage is contents of variables that are linked via -textvariable
links, and/or direct "configure -text" settings, not the pack/unpacked
aspect of widgets.

Now, the page is ambigious in that it does not give an explicit
definition of "application's state", but given the sentence:

However, there are some kinds of updates that only happen in
response to events, such as those triggered by window size
changes; these updates will not occur in update idletasks.

in the 'idletasks' section, that suggests that "state" was defined in
the manpage writer's mind to mean "variable contents" and/or "configure
-text" settings". Unpacking a widget will very likely cause a "window
size change" as will repacking a new widget likely cause a "window size
change" (as in both instances the window might shrink [unpack] and grow
[repack]). Therefore packing/unpacking a widget most likely falls into
the "some kinds of updates ... will not occur in update idletasks"
bucket. Since window size changes are clearly indicated as "not update
idletasks" items, it is reasonable to presume that the manpage writer
was not including those in their definition of "state" when writing the
sentence about "state changes".

But to fully answer your question requires someone with very low level
knowledge of the inner C workings of Tk to weigh in.


Gerald Lester

unread,
Aug 22, 2019, 5:52:49 PM8/22/19
to
On 8/22/19 11:21 AM, Rich wrote:
> Erik Leunissen <lo...@the.footer.invalid> wrote:
>> B.t.w. the manpage for [update] mentions: "The update idletasks command
>> is useful in scripts where changes have been made to the application's
>> state and you want those changes to appear on the display
>> immediately, rather than waiting for the script to complete."
>>
>> Note the word *immediately*
>
> Also note the word "state". I suspect that by "state" what was meant
> was contents of variables connected to -textvariable links and/or
> "configure -text" changes, not "pack forget" and "pack a different
> widget". And myself, what "state" says to me if I read this part of
> the manpage is contents of variables that are linked via -textvariable
> links, and/or direct "configure -text" settings, not the pack/unpacked
> aspect of widgets.
>
> Now, the page is ambigious in that it does not give an explicit
> definition of "application's state", but given the sentence:
>
> However, there are some kinds of updates that only happen in
> response to events, such as those triggered by window size
> changes; these updates will not occur in update idletasks.
>
> in the 'idletasks' section, that suggests that "state" was defined in
> the manpage writer's mind to mean "variable contents" and/or "configure
> -text" settings".

That was the intent.

> Unpacking a widget will very likely cause a "window
> size change" as will repacking a new widget likely cause a "window size
> change" (as in both instances the window might shrink [unpack] and grow
> [repack]). Therefore packing/unpacking a widget most likely falls into
> the "some kinds of updates ... will not occur in update idletasks"
> bucket. Since window size changes are clearly indicated as "not update
> idletasks" items, it is reasonable to presume that the manpage writer
> was not including those in their definition of "state" when writing the
> sentence about "state changes".
>
> But to fully answer your question requires someone with very low level
> knowledge of the inner C workings of Tk to weigh in.

And it may change on different windowing systems and/or window managers
-- as well as change over time.

--
+----------------------------------------------------------------------+
| Gerald W. Lester, President, KNG Consulting LLC |
| Email: Gerald...@kng-consulting.net |
+----------------------------------------------------------------------+

Erik Leunissen

unread,
Aug 23, 2019, 7:10:03 AM8/23/19
to
Thanks for your additional explanation Brian, and thanks for the further
analysis of the text of the manpage, Rich.

They provided me with several clues about where my understanding failed.
Further study on my part, starting with these clues, is needed for
adequate understanding the case of screen updates.

Given the complexity of the matter demonstrated in this thread, the text
of the manual page for [update] strikes me as extremely terse. It pales
w.r.t. adequate explanation when compared to manpages for other
complicated systems, like regexp/re_syntax and the option database [*].

Considering the chunks of information in this thread that clued me in, I
would like to identify the following three categories of information
that deserve/require better treatment in the text of the manpage:

1. a (course?) description of the fundamentals of the event loop, its
work flow.
2. a description of how changes to a GUI are divided into distinct tasks
for screen updates.
3. how these distinct tasks are processed or scheduled for processing by
the event loop

I expect it to require considerable effort to choose the right level of
detail and wording. Maybe pictures are needed besides words. Who knows,
maybe one day the knowledgeable writer with enough time comes forward.

Thanks again,
Erik Leunissen.
--

[*] That's meant as a statement without any further implications. I
know/appreciate how much private effort goes into this language.

Harald Oehlmann

unread,
Aug 23, 2019, 7:24:56 AM8/23/19
to
Erik,

great and fundamental discussion.

Perhaps, it is a good start to get all information together on a tcl
core wiki page ? If you have commit access, you can create one:

https://core.tcl-lang.org/tcl/wcontent

Just an idea,
Harald

Erik Leunissen

unread,
Aug 23, 2019, 10:16:23 AM8/23/19
to
On 23/08/2019 13:24, Harald Oehlmann wrote:
>
> great and fundamental discussion.
>
> Perhaps, it is a good start to get all information together on a tcl
> core wiki page ? If you have commit access, you can create one:
>
> https://core.tcl-lang.org/tcl/wcontent
>
> Just an idea,
> Harald
>

Hi Harald,

I'm glad that you value this thread.

The intention of my last post was to identify and summarize what I
experienced from this thread as a start/outline for a better
documentation. I hope it is going to serve that purpose sometime.

However, it remains to be seen whether the more knowledgeable people
(contributors in this thread, or elsewhere), agree with my summary, and
whether the need for better documentation is felt more broadly in the
first place. That the discussion has been of use for you, which is of
course a good sign in this respect.

As for producing a more useful text than the current manpage: the
problem is that it takes thorough understanding of the subject matter in
order to do that. It has been demonstrated that I'm lacking in this
respect. I don't trust myself to "get all information together", at
least not in a useful way (and we want it to be useful don't we?).

By providing the summary I've taken my contribution to the limit of my
abilities. In case it's necessary: as of now that summary has been
placed in the public domain.

Thanks for the response,
Erik.

briang

unread,
Aug 23, 2019, 11:03:15 AM8/23/19
to
See my comments below.
-Brian

On Friday, August 23, 2019 at 4:10:03 AM UTC-7, Erik Leunissen wrote:
> Thanks for your additional explanation Brian, and thanks for the further
> analysis of the text of the manpage, Rich.
>
> They provided me with several clues about where my understanding failed.
> Further study on my part, starting with these clues, is needed for
> adequate understanding the case of screen updates.

One aspect to look into is the Model-View-Controller design pattern, and understand the how and why of this pattern. Important in this is the separation of the user interface from the business logic of the application. (one possible starting point: https://en.wikipedia.org/wiki/Model–view–controller)

>
> Given the complexity of the matter demonstrated in this thread, the text
> of the manual page for [update] strikes me as extremely terse. It pales
> w.r.t. adequate explanation when compared to manpages for other
> complicated systems, like regexp/re_syntax and the option database [*].
>
> Considering the chunks of information in this thread that clued me in, I
> would like to identify the following three categories of information
> that deserve/require better treatment in the text of the manpage:
>
> 1. a (course?) description of the fundamentals of the event loop, its
> work flow.

See the man page on Tcl_InitNotifier(). (https://www.tcl.tk/man/tcl8.6/TclLib/Notifier.htm)
I wouldn't expect any user to know to look at this man page to understand the event loop, but the detailed description you are seeking is there.

> 2. a description of how changes to a GUI are divided into distinct tasks
> for screen updates.

Every widget does different things, and consequently will do tasks and updates slightly differently.
Every widget has various degrees of configurability, so tcl scripts can change this behavior.
The various geometry managers, by definition, propagate update changes up and down a widget hierarchy. This means"updates" are not a simple single Cause-and-Effect.

What this means is that you have to read the description for each widget and geometry manager. Look at the way a set of widgets has been laid out on the screen, and then determine what the consequences are for the give set of objects and actions. Add to this what the business logic of the application does in triggering and responding to the GUI.

> 3. how these distinct tasks are processed or scheduled for processing by
> the event loop

See the references above.
Also, it's been a long time since I read this book, but if I remember correctly, it describes how to implement some things in Tk with explanation of how things work: "Practical Programming in Tcl and Tk" by Brent Welch and Ken Jones.

>
> I expect it to require considerable effort to choose the right level of
> detail and wording. Maybe pictures are needed besides words. Who knows,
> maybe one day the knowledgeable writer with enough time comes forward.

Also worth reading, at least once, is the chapter on Tk in "Tcl and the Tk Toolkit" by John Ousterhout and Ken Jones. (It's got pictures!)

Erik Leunissen

unread,
Aug 24, 2019, 3:31:25 AM8/24/19
to
Brian, thanks for the sources and the various indications for reading.
Specifically:

On 23/08/2019 17:03, briang wrote:

<snip>

>
> One aspect to look into is the Model-View-Controller design pattern, and understand the how and why of this pattern. Important in this is the separation of the user interface from the business logic of the application. (one possible starting point: https://en.wikipedia.org/wiki/Model–view–controller)
>

OK. I know the term, but have never understood the relation to Tk well.
This is a new incentive for me to do another attempt to grasp that
design pattern and find out how that relates to Tk/GUI.

<snip>

>>
>> 1. a (course?) description of the fundamentals of the event loop, its
>> work flow.
>
> See the man page on Tcl_InitNotifier(). (https://www.tcl.tk/man/tcl8.6/TclLib/Notifier.htm)
> I wouldn't expect any user to know to look at this man page to understand the event loop, but the detailed description you are seeking is there.

OK. Will do.

>
>> 2. a description of how changes to a GUI are divided into distinct tasks
>> for screen updates.

I probably didn't formulate the question above clearly enough, and you
may have understood only partially what I meant.

>
> Every widget does different things, and consequently will do tasks and updates slightly differently.
> Every widget has various degrees of configurability, so tcl scripts can change this behavior.
> The various geometry managers, by definition, propagate update changes up and down a widget hierarchy. This means"updates" are not a simple single Cause-and-Effect.
>
> What this means is that you have to read the description for each widget and geometry manager. Look at the way a set of widgets has been laid out on the screen, and then determine what the consequences are for the give set of objects and actions. Add to this what the business logic of the application does in triggering and responding to the GUI.

The books that you mention below, I already have read both of them (but
"Practical Programming in Tcl and Tk" only in its third edition by
Brewnt Welch alone). It's my experience that on the subject of geometry
managers, they focus on the algorithms for lay-out of widgets in a GUI.
However, they do not describe how a change to a widget/GUI is decomposed
into distinct redrawing tasks for processing by the event loop (which
are collected until idle time, and possibly
recombined/selected/reordered/rescheduled/... and finally executed in
physical screen access actions as you indicated in a previous post with
an analogy of a stone and ripples ... ).

It seems to me that it's especially this information that a programmmer
needs in order to understand exactly which (partial) screen updates are
executed at what stage/pass in the event loop. I believe it is
especially this part which makes me fail to understand why [update
idletasks] in my script in the original post results in a partial screen
update and why [update] results a complete redraw.

Do you know of any sources that specifically address this?
(sorry if my original question didn't convey this)

TIA,
Erik


>
>> 3. how these distinct tasks are processed or scheduled for processing by
>> the event loop
>
> See the references above.
> Also, it's been a long time since I read this book, but if I remember correctly, it describes how to implement some things in Tk with explanation of how things work: "Practical Programming in Tcl and Tk" by Brent Welch and Ken Jones.
>
>>
>> I expect it to require considerable effort to choose the right level of
>> detail and wording. Maybe pictures are needed besides words. Who knows,
>> maybe one day the knowledgeable writer with enough time comes forward.
>
> Also worth reading, at least once, is the chapter on Tk in "Tcl and the Tk Toolkit" by John Ousterhout and Ken Jones. (It's got pictures!)
>
>>
>> Thanks again,
>> Erik Leunissen.
>> --
>>
>> [*] That's meant as a statement without any further implications. I
>> know/appreciate how much private effort goes into this language.
>


briang

unread,
Aug 31, 2019, 8:30:43 PM8/31/19
to
On Saturday, August 24, 2019 at 12:31:25 AM UTC-7, Erik Leunissen wrote:
> Brian, thanks for the sources and the various indications for reading.
> Specifically:
>
> On 23/08/2019 17:03, briang wrote:
>
> <snip>
>
>
> It seems to me that it's especially this information that a programmmer
> needs in order to understand exactly which (partial) screen updates are
> executed at what stage/pass in the event loop. I believe it is
> especially this part which makes me fail to understand why [update
> idletasks] in my script in the original post results in a partial screen
> update and why [update] results a complete redraw.
>

One way to understand how this works is to examine what really happens when a script like the OP attachment is run. I've created a trace log file, using gdb, of the running script. I picked key points in the code and had gdb print out info to illustrate in what order things happen. You'll see the commands from the script as well as calls the Tcl_DoOneEvent (the entry to the event loop). Also noted are bind events, scripts tied to things like <Configure> and <Button-1>, etc. There are also C bindings as well. Pay particular attention to TkpDisplayButton and DisplayFrame, this is where the screen is actually updated, and the WindowEventProc is called when the OS windowing system wants to tell the application something (window resize, expose, refresh, mouse motion, etc.) If you carefully review this log and compare it to the script, you should eventually understand. There is a lot going on under the hood and most of it goes through the event loop.

http://griffintk.org/Images/trace_final.txt

-Brian

Erik Leunissen

unread,
Sep 1, 2019, 3:45:58 AM9/1/19
to
On 01/09/2019 02:30, briang wrote:
>
> One way to understand how this works is to examine what really happens when a script like the OP attachment is run. I've created a trace log file, using gdb, of the running script. I picked key points in the code and had gdb print out info to illustrate in what order things happen. You'll see the commands from the script as well as calls the Tcl_DoOneEvent (the entry to the event loop). Also noted are bind events, scripts tied to things like <Configure> and <Button-1>, etc. There are also C bindings as well. Pay particular attention to TkpDisplayButton and DisplayFrame, this is where the screen is actually updated, and the WindowEventProc is called when the OS windowing system wants to tell the application something (window resize, expose, refresh, mouse motion, etc.) If you carefully review this log and compare it to the script, you should eventually understand. There is a lot going on under the hood and most of it goes through the event loop.

Extraordinary!

Many thanks for coming up with this specific method of analysis, use of
instruments and having it worked out in a trace log.

Highly appreciated!


Following the link below though results in:

404 Not Found


I'm very interested of course ...

Erik.
--

>
> http://griffintk.org/Images/trace_final.txt
>
> -Brian

briang

unread,
Sep 1, 2019, 10:17:48 AM9/1/19
to
On Sunday, September 1, 2019 at 12:45:58 AM UTC-7, Erik Leunissen wrote:
> On 01/09/2019 02:30, briang wrote:
> >
> > One way to understand how this works is to examine what really happens when a script like the OP attachment is run. I've created a trace log file, using gdb, of the running script. I picked key points in the code and had gdb print out info to illustrate in what order things happen. You'll see the commands from the script as well as calls the Tcl_DoOneEvent (the entry to the event loop). Also noted are bind events, scripts tied to things like <Configure> and <Button-1>, etc. There are also C bindings as well. Pay particular attention to TkpDisplayButton and DisplayFrame, this is where the screen is actually updated, and the WindowEventProc is called when the OS windowing system wants to tell the application something (window resize, expose, refresh, mouse motion, etc.) If you carefully review this log and compare it to the script, you should eventually understand. There is a lot going on under the hood and most of it goes through the event loop.
>
> Extraordinary!
>
> Many thanks for coming up with this specific method of analysis, use of
> instruments and having it worked out in a trace log.
>
> Highly appreciated!
>
>
> Following the link below though results in:
>
> 404 Not Found
>
>
> I'm very interested of course ...
>
> Erik.


Oops! Typed it wrong. Try this:

http://griffintk.org/Images/outgoing/trace_final.txt

-Brian

Erik Leunissen

unread,
Sep 1, 2019, 10:57:19 AM9/1/19
to
OK, got it!

thx.
Erik.

heinrichmartin

unread,
Sep 1, 2019, 3:48:20 PM9/1/19
to
On Sunday, September 1, 2019 at 2:30:43 AM UTC+2, briang wrote:
> calls the Tcl_DoOneEvent (the entry to the event loop).

There is no such thing as *the* event loop - at least not at script level. This is something that caught me once. My understanding of *the* event loop was that of coroutines, i.e. all equal events. Now I'd rather see Tcl_DoOneEvent providing a new level of event loops (see man vwait > nested vwaits by example).

This remark is probably not relevant for Tk, but it was crucial for my understanding of the internals of Tcl.

Maybe it helps.
Martin
0 new messages