Tk Source Code

View Ticket
Login
Ticket UUID: 1813595
Title: loop race in canvas Enter / Leave bindings
Type: Bug Version: 8.4.1, 8.6.18, 9.0.5, 9.1b1
Submitter: stevenaaus Created on: 2007-10-15 06:21:53
Subsystem: 05. Canvas Items Assigned To: jan.nijtmans
Priority: 5 Medium Severity: Minor
Status: Closed Last Modified: 2026-10-02 18:15:12
Resolution: Fixed Closed By: nobody
    Closed on: 2026-09-30 15:52:25
Description:
Hmmm... Seems to me there's definately a bug in tk with the canvas Enter and Leave bindings. I've tested this on wish 8.4.1, 8.4.16 and 8.5b1.

TkHearts-0.86 runs fine, but when i entered these two bindings (patch backs them out) - bound only against players face up cards, tcl just freezes quite unpredictably. Occasionally on startup and in a game, but often after returning from a change of focus between apps, or even from the "about" widget.

I added two lines of debugging code that trace control into doCardUp and doCardDown. They work fine, but when the game freezes, it became apparent tcl was stuck in a Enter/Leave loop, continuously calling doCardUp and
doCardDown (which are bound to Enter and Leave). This behaviour is the same in 8.4.1 8.4.16 and 8.5b1. I run fedora4, xorg-x11-6.8.2-31.

Another data point - I also totally removed the ".c bind player0 <Leave>" command hoping to get around the bug...
leaving just the Enter binding, but i ~still~ managed to get a loop race condition :<

Thanks, Steven Atkinson, stevenaaus yahoo.com
User Comments: erikleunissen added on 2026-10-02 09:34:30:
Oh, my previous post was meant for the related ticket [e050c5a2a9]. Please disregard where it isn't appropriate for the present context.

erikleunissen added on 2026-10-02 09:24:17:
Regarding this issue and the commit message for [a0eb4e7a8c]:

    "Aqua: do not hang if idle handlers keep scheduling idle handlers."

Ticket [591829e948], part A, questions the practice of "idle handlers keep scheduling idle handlers"
more fundamentally; at least for one of the instances that the present ticket also addresses.

It shows for one of the entry points where such iterative or recursive processing
of idle tasks is induced, that the iterative or recursive approach is not necessary.
Branch bug-591829e948-A addresses the problem at a higher level in the call graph, thus
disentangling the needlessly intertwined code, resulting in elimination of that
case (i.e. that particular entry into recursive processing of idle tasks).

Lack of overview over the involved call sequences has probably lead to the current
intertwined state of the code. I wouldn't be surprised that simplification
of the call sequences, like in branch bug-591829e948-A would prove to be a solution
for the present ticket also.

serhiy.storchaka added on 2026-10-02 06:39:48:

The macOS hang has a more general cause, see [e050c5a2a9]. With that fixed, the original fix only makes [update] hang while the bindings keep moving the item, like real windows with such bindings. Branch [canvas-repick-limit] is optional: there [update] returns too.


serhiy.storchaka added on 2026-10-02 06:21:55:

Updated branch [canvas-repick-limit]: after 10 attempts in one redisplay the canvas does not stop handling such bindings, but continues 10 ms later. The timer is started from an idle handler after the pending redisplays, so [update] returns even if drawing takes long or many canvases do this. Only one continuation is pending per canvas. New test canvas-24.2 checks that the bindings are still invoked.


serhiy.storchaka added on 2026-10-01 19:55:00:

The fix can still hang: when the Enter and Leave bindings move the current item away from the pointer and back, DisplayCanvas schedules itself again as an idle handler, so loops which process idle handlers until there are none left never end: [update idletasks] and [update] on all platforms, and drawing on macOS in 8.6 (in 9.x only when a window is first shown or resized).

Proposed fix in branch [canvas-repick-limit]: the current item is chosen at most 10 times per redisplay, without rescheduling. Test canvas-24.1 now also runs [update idletasks] and [update]. It can replace the backed out backport to 8.6.


jan.nijtmans added on 2026-09-30 15:52:25:

Fixed [9333678796f71cfc|here], also backported to core-9-0-branch and core-8-6-branch.

Closing


jan.nijtmans added on 2026-09-27 20:35:20:

Having a look ....


serhiy.storchaka added on 2026-09-22 11:04:52:

Reproduced on X11 with 8.6.18 and 9.1: an item whose <Enter> binding moves it away from the pointer and whose <Leave> binding moves it back becomes the current item again and again, and the canvas chose the current item in a loop when it was redisplayed, without ever returning to the event loop, so the application hung.

Fixed in [91ba368024] (branch canvas-repick-loop): the current item is chosen once per redisplay; if the bindings make another choice necessary, it is made at the next redisplay. The bindings still alternate as long as the pointer does not move (that is what they ask for, and it is the same with real windows), but the application keeps processing events. Test canvas-30.1.


stevenaaus added on 2007-10-17 12:53:37:
Logged In: YES 
user_id=1043388
Originator: YES

Hmmm... I've ironed out this issue on my system... A couple of "update" commands in judicious places stops Tk from entering a crazy loop occasionally.

I guess i still regard it as a bug.... but one that can be worked around.

Thanks, S.A.

stevenaaus added on 2007-10-15 13:21:53:

File Added - 249694: canvas_bindings_bug.tgz

Attachments: