• Head scratching event issue with Tcl 9

    From meshparts@alexandru.dadalau@meshparts.de to comp.lang.tcl on Wed Sep 24 20:59:02 2025
    From Newsgroup: comp.lang.tcl

    I have a very weird issue with Tcl 9 related to Enter and Leave events.

    The code below demonstrates this issue.
    Also see the comments, which explain what it does.

    The issue is that the Enter and Leave events are generated endlessly
    very fast although I only enter once with the mouse the red frame.
    So the red frame is created and destroyed very fast in an endless loop.

    Same code works fine with Tcl 8.

    I'm pretty shure this is a bug.
    But maybe I'm wrong.
    Furthermore: Is there an workaround for this?

    # React to the Enter event and create a simple empty frame
    proc ::Enter {w} {
    puts enter
    ::SimpleFrame $w
    }
    # React to the Leave event and destroy the empty frame
    proc ::Leave {w} {
    puts leave
    destroy $w.f
    }
    # Create an empty frame, place it over the text widget
    proc ::SimpleFrame {w} {
    if {[winfo exists $w.f]} {
    return
    }
    place [frame $w.f -bg red -width 300 -height 50] -anchor ne -relx 1.0
    -rely 0.0
    }
    # Create a toplevel window with a text widget inside
    # Bind to the events Enter and Leave of the text widget
    set w .test
    toplevel $w
    grid [text $w.t -bd 0 -height 2 -cursor arrow -pady 1] -sticky ew
    $w.t insert end "Some text\n"
    bind $w.t <Enter> [list ::Enter $w.t]
    bind $w.t <Leave> [list ::Leave $w.t]
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Emiliano@emiliano@example.invalid to comp.lang.tcl on Wed Sep 24 16:27:45 2025
    From Newsgroup: comp.lang.tcl

    On Wed, 24 Sep 2025 20:59:02 +0200
    meshparts <alexandru.dadalau@meshparts.de> wrote:

    I have a very weird issue with Tcl 9 related to Enter and Leave events.
    [...]
    I'm pretty shure this is a bug.

    Not a bug, but a feature!! Jokes aside, is an intentional change.

    See https://core.tcl-lang.org/tk/tktview/47d4f291598222849fc0
    --
    Emiliano <emiliano@example.invalid>
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From meshparts@alexandru.dadalau@meshparts.de to comp.lang.tcl on Wed Sep 24 21:46:33 2025
    From Newsgroup: comp.lang.tcl

    Am 24.09.2025 um 21:27 schrieb Emiliano:
    On Wed, 24 Sep 2025 20:59:02 +0200
    meshparts <alexandru.dadalau@meshparts.de> wrote:

    I have a very weird issue with Tcl 9 related to Enter and Leave events.
    [...]
    I'm pretty shure this is a bug.

    Not a bug, but a feature!! Jokes aside, is an intentional change.

    See https://core.tcl-lang.org/tk/tktview/47d4f291598222849fc0

    Thanks for the resolution.
    I tried to get the idea behind this change, but could not realy understand. Seems to me the explanation assumes deep understanding of the source
    code of bindings.
    Which I don't have.
    Also it says something about a patch script, which I don't see on that page. What would be the solution to this?
    I'm mean, it's not out of the world, what my script does.
    It's funny that this change is regarded as a feature while it breaks
    expected behavior.
    It's like a contradiction to itself.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Emiliano@emiliano@example.invalid to comp.lang.tcl on Wed Sep 24 23:35:24 2025
    From Newsgroup: comp.lang.tcl

    On Wed, 24 Sep 2025 21:46:33 +0200
    meshparts <alexandru.dadalau@meshparts.de> wrote:

    Am 24.09.2025 um 21:27 schrieb Emiliano:
    On Wed, 24 Sep 2025 20:59:02 +0200
    meshparts <alexandru.dadalau@meshparts.de> wrote:

    I have a very weird issue with Tcl 9 related to Enter and Leave events.
    [...]
    I'm pretty shure this is a bug.

    Not a bug, but a feature!! Jokes aside, is an intentional change.

    See https://core.tcl-lang.org/tk/tktview/47d4f291598222849fc0

    Thanks for the resolution.
    I tried to get the idea behind this change, but could not realy understand. Seems to me the explanation assumes deep understanding of the source
    code of bindings.
    Which I don't have.
    Also it says something about a patch script, which I don't see on that page. What would be the solution to this?
    I'm mean, it's not out of the world, what my script does.
    It's funny that this change is regarded as a feature while it breaks expected behavior.
    It's like a contradiction to itself.

    Some documentation on how things works at protocol (X11) event:

    https://tronche.com/gui/x/xlib/events/window-entry-exit/normal.html

    Tk provides the %d substitution on bindings to access the detail member mentioned in the above document.

    Try out this script to check the difference between 8.6 and 9.0

    =====================================================================
    package require Tk
    place [frame .f1] -relwidth 1.0 -relheight 1.0
    place [frame .f1.f2 -bg green] -relwidth 0.4 -relheight 0.4 -relx 0.5 \
    -rely 0.5 -anchor center
    foreach w {.f1 .f1.f2} {
    bind $w <Enter> {puts "Enter %W: %d"}
    bind $w <Leave> {puts "Leave %W: %d"}
    }
    --
    Emiliano <emiliano@example.invalid>
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Eric@user7600@newsgrouper.org.invalid to comp.lang.tcl on Thu Sep 25 08:20:33 2025
    From Newsgroup: comp.lang.tcl


    meshparts <alexandru.dadalau@meshparts.de> posted:

    Am 24.09.2025 um 21:27 schrieb Emiliano:
    On Wed, 24 Sep 2025 20:59:02 +0200
    meshparts <alexandru.dadalau@meshparts.de> wrote:

    I have a very weird issue with Tcl 9 related to Enter and Leave events.
    [...]
    I'm pretty shure this is a bug.

    Not a bug, but a feature!! Jokes aside, is an intentional change.

    See https://core.tcl-lang.org/tk/tktview/47d4f291598222849fc0

    Thanks for the resolution.
    I tried to get the idea behind this change, but could not realy understand. Seems to me the explanation assumes deep understanding of the source
    code of bindings.
    Which I don't have.
    Also it says something about a patch script, which I don't see on that page. What would be the solution to this?
    I'm mean, it's not out of the world, what my script does.
    It's funny that this change is regarded as a feature while it breaks expected behavior.
    It's like a contradiction to itself.

    While this change is legitimate, note that it has also landed in Tk 8.6.16, which is really unfortunate for a bug fix release, also given that the original behaviour was intentional.

    Eric
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From meshparts@alexandru.dadalau@meshparts.de to comp.lang.tcl on Thu Sep 25 12:20:08 2025
    From Newsgroup: comp.lang.tcl

    Am 25.09.2025 um 04:35 schrieb Emiliano:
    On Wed, 24 Sep 2025 21:46:33 +0200
    meshparts <alexandru.dadalau@meshparts.de> wrote:

    Am 24.09.2025 um 21:27 schrieb Emiliano:
    On Wed, 24 Sep 2025 20:59:02 +0200
    meshparts <alexandru.dadalau@meshparts.de> wrote:

    I have a very weird issue with Tcl 9 related to Enter and Leave events. >>> [...]
    I'm pretty shure this is a bug.

    Not a bug, but a feature!! Jokes aside, is an intentional change.

    See https://core.tcl-lang.org/tk/tktview/47d4f291598222849fc0

    Thanks for the resolution.
    I tried to get the idea behind this change, but could not realy understand. >> Seems to me the explanation assumes deep understanding of the source
    code of bindings.
    Which I don't have.
    Also it says something about a patch script, which I don't see on that page. >> What would be the solution to this?
    I'm mean, it's not out of the world, what my script does.
    It's funny that this change is regarded as a feature while it breaks
    expected behavior.
    It's like a contradiction to itself.

    Some documentation on how things works at protocol (X11) event:

    https://tronche.com/gui/x/xlib/events/window-entry-exit/normal.html

    Tk provides the %d substitution on bindings to access the detail member mentioned in the above document.

    Try out this script to check the difference between 8.6 and 9.0

    =====================================================================
    package require Tk
    place [frame .f1] -relwidth 1.0 -relheight 1.0
    place [frame .f1.f2 -bg green] -relwidth 0.4 -relheight 0.4 -relx 0.5 \
    -rely 0.5 -anchor center
    foreach w {.f1 .f1.f2} {
    bind $w <Enter> {puts "Enter %W: %d"}
    bind $w <Leave> {puts "Leave %W: %d"}
    }


    Ok, thanks for the link.
    I understand now better.
    So the solution must be that the red frame in my example is not a child element of the text widget (see changed code below).

    Because the event is now blocked when the mouse moves from the parent
    widget to the child widget.

    What would be the solution, when the red frame *must* be a child element?


    # React to the Enter event and create a simple empty frame
    proc ::Enter {w} {
    puts enter
    ::SimpleFrame $w
    }
    # React to the Leave event and destroy the empty frame
    proc ::Leave {w} {
    puts leave
    destroy $w.f
    }
    # Create an empty frame, place it over the text widget
    proc ::SimpleFrame {w} {
    set parent [winfo parent $w]
    if {[winfo exists $parent.f]} {
    return
    }
    place [frame $parent.f -bg red -width 300 -height 50] -anchor ne
    -relx 1.0 -rely 0.0
    }
    # Create a toplevel window with a text widget inside
    # Bind to the events Enter and Leave of the text widget
    set w .test
    toplevel $w
    grid [text $w.t -bd 0 -height 2 -cursor arrow -pady 1] -sticky ew
    $w.t insert end "Some text\n"
    bind $w.t <Enter> [list ::Enter $w.t]
    bind $w.t <Leave> [list ::Leave $w.t]

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Emiliano@emiliano@example.invalid to comp.lang.tcl on Thu Sep 25 16:58:28 2025
    From Newsgroup: comp.lang.tcl

    On Thu, 25 Sep 2025 12:20:08 +0200
    meshparts <alexandru.dadalau@meshparts.de> wrote:

    Am 25.09.2025 um 04:35 schrieb Emiliano:
    [...]
    Ok, thanks for the link.
    I understand now better.
    So the solution must be that the red frame in my example is not a child element of the text widget (see changed code below).

    Because the event is now blocked when the mouse moves from the parent
    widget to the child widget.

    What would be the solution, when the red frame *must* be a child element?

    As said in another post, the solution is to use the %d substitution.

    Here is your original script, slightly modified to discard the event when
    the detail is NotifyInferior. It behaves the same with both 8.6 and 9

    ===========================================================================
    # React to the Enter event and create a simple empty frame
    proc ::Enter {w detail} {
    if {$detail eq "NotifyInferior"} {
    return
    }
    puts enter
    ::SimpleFrame $w
    }
    # React to the Leave event and destroy the empty frame
    proc ::Leave {w detail} {
    if {$detail eq "NotifyInferior"} {
    return
    }
    puts leave
    destroy $w.f
    }
    # Create an empty frame, place it over the text widget
    proc ::SimpleFrame {w} {
    if {[winfo exists $w.f]} {
    return
    }
    place [frame $w.f -bg red -width 300 -height 50] -anchor ne -relx 1.0 -rely 0.0
    }
    # Create a toplevel window with a text widget inside
    # Bind to the events Enter and Leave of the text widget
    set w .test
    toplevel $w
    grid [text $w.t -bd 0 -height 2 -cursor arrow -pady 1] -sticky ew
    $w.t insert end "Some text\n"
    bind $w.t <Enter> [list ::Enter $w.t %d]
    bind $w.t <Leave> [list ::Leave $w.t %d]
    --
    Emiliano <emiliano@example.invalid>
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From meshparts@alexandru.dadalau@meshparts.de to comp.lang.tcl on Thu Sep 25 23:19:52 2025
    From Newsgroup: comp.lang.tcl

    Am 25.09.2025 um 21:58 schrieb Emiliano:
    On Thu, 25 Sep 2025 12:20:08 +0200
    meshparts <alexandru.dadalau@meshparts.de> wrote:

    Am 25.09.2025 um 04:35 schrieb Emiliano:
    [...]
    Ok, thanks for the link.
    I understand now better.
    So the solution must be that the red frame in my example is not a child
    element of the text widget (see changed code below).

    Because the event is now blocked when the mouse moves from the parent
    widget to the child widget.

    What would be the solution, when the red frame *must* be a child element?

    As said in another post, the solution is to use the %d substitution.

    Here is your original script, slightly modified to discard the event when
    the detail is NotifyInferior. It behaves the same with both 8.6 and 9

    ===========================================================================
    # React to the Enter event and create a simple empty frame
    proc ::Enter {w detail} {
    if {$detail eq "NotifyInferior"} {
    return
    }
    puts enter
    ::SimpleFrame $w
    }
    # React to the Leave event and destroy the empty frame
    proc ::Leave {w detail} {
    if {$detail eq "NotifyInferior"} {
    return
    }
    puts leave
    destroy $w.f
    }
    # Create an empty frame, place it over the text widget
    proc ::SimpleFrame {w} {
    if {[winfo exists $w.f]} {
    return
    }
    place [frame $w.f -bg red -width 300 -height 50] -anchor ne -relx 1.0 -rely 0.0
    }
    # Create a toplevel window with a text widget inside
    # Bind to the events Enter and Leave of the text widget
    set w .test
    toplevel $w
    grid [text $w.t -bd 0 -height 2 -cursor arrow -pady 1] -sticky ew
    $w.t insert end "Some text\n"
    bind $w.t <Enter> [list ::Enter $w.t %d]
    bind $w.t <Leave> [list ::Leave $w.t %d]



    Now I get it.
    Thanks!
    --- Synchronet 3.21a-Linux NewsLink 1.2