• <> and <> behavior

    From Luc@21:1/5 to All on Thu Nov 30 01:19:18 2023
    Experiments:

    bind $::text <<Selection>> {p.playwav "/home/tcl/sounds/tick.wav"} bind $::text <<Clear>> {p.playwav "/home/tcl/sounds/tock.wav"}

    I hear the tick whenever I select some text, but I can't figure out what triggers <<Clear>> to play tock.wav.

    The friendly manual says about <<Clear>>:
    "Delete the currently selected widget contents."
    So I thought that deleting text would trigger it. But it doesn't.


    Question 1:
    So what is the effect of creating a binding to <<Clear>>?


    Question 2:
    Why do I hear the tick twice when text is already selected and I extend
    the selection to include more text?


    --
    Luc


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rich@21:1/5 to Luc on Thu Nov 30 14:44:32 2023
    Luc <[email protected]d> wrote:
    Experiments:

    bind $::text <<Selection>> {p.playwav "/home/tcl/sounds/tick.wav"}
    bind $::text <<Clear>> {p.playwav "/home/tcl/sounds/tock.wav"}

    I hear the tick whenever I select some text, but I can't figure out what triggers <<Clear>> to play tock.wav.

    The friendly manual says about <<Clear>>:
    "Delete the currently selected widget contents."
    So I thought that deleting text would trigger it. But it doesn't.


    Question 1:
    So what is the effect of creating a binding to <<Clear>>?

    The text widget is not documented (at least in 8.6.12) as generating
    <<Clear>>. In what manual did you find this event? Because what you
    quote above is not typical wording for virtual events. They are
    usually worded as: "generated when X occurs"

    Question 2:
    Why do I hear the tick twice when text is already selected and I extend
    the selection to include more text?

    man n text:

    [4] Whenever the sel tag range changes a virtual event
    <<Selection>> is generated.

    "Extending" the selection is a "change" to the "tag range" -- so it
    triggers the event as documented.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Luc@21:1/5 to Rich on Thu Nov 30 12:10:56 2023
    On Thu, 30 Nov 2023 14:44:32 -0000 (UTC), Rich wrote:

    The text widget is not documented (at least in 8.6.12) as generating ><<Clear>>. In what manual did you find this event? Because what you
    quote above is not typical wording for virtual events. They are
    usually worded as: "generated when X occurs"

    It's the 'event' page on a CHM file I downloaded some time ago, about
    two years ago I think. It has this identification:

    Tcl Windows Help (V 2019.01.09)
    Copyright © 2019 Ashok P. Nadkarni (Compilation only)

    I just noticed this:

    "Tk defines the following virtual events for the purposes of unifying
    bindings across multiple platforms. Users expect them to behave in the following way:"

    A list of events ensue, <<Clear>> is the first one.

    Now, it occurs to me that "for the purposes of unifying bindings
    across multiple platforms" might indicate that <<Clear>> belongs to
    some other platform. Windows or Mac, I suppose.



    Question 2:
    Why do I hear the tick twice when text is already selected and I extend
    the selection to include more text?

    man n text:

    [4] Whenever the sel tag range changes a virtual event
    <<Selection>> is generated.

    "Extending" the selection is a "change" to the "tag range" -- so it
    triggers the event as documented.


    Thanks, but I still don't understand why it's triggered twice. Actually, sometimes it is triggered twice and sometimes it's triggered once.
    I tested it and got a consistently inconsistent behavior. Once or twice
    on some pattern I definitely can't understand. I could post a link to
    a video demonstrating it, but I know people here hate videos.


    --
    Luc


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rich@21:1/5 to Luc on Thu Nov 30 15:27:02 2023
    Luc <[email protected]d> wrote:
    On Thu, 30 Nov 2023 14:44:32 -0000 (UTC), Rich wrote:

    The text widget is not documented (at least in 8.6.12) as generating >><<Clear>>. In what manual did you find this event? Because what you
    quote above is not typical wording for virtual events. They are
    usually worded as: "generated when X occurs"

    It's the 'event' page on a CHM file I downloaded some time ago, about
    two years ago I think. It has this identification:

    Tcl Windows Help (V 2019.01.09)
    Copyright © 2019 Ashok P. Nadkarni (Compilation only)

    I just noticed this:

    "Tk defines the following virtual events for the purposes of unifying bindings across multiple platforms. Users expect them to behave in the following way:"

    A list of events ensue, <<Clear>> is the first one.

    Now, it occurs to me that "for the purposes of unifying bindings
    across multiple platforms" might indicate that <<Clear>> belongs to
    some other platform. Windows or Mac, I suppose.

    Ah, yes, it is in the 'event' man page:

    Tk defines the following virtual events for the purposes of
    unifying bindings across multiple platforms. Users expect them
    to behave in the following way:

    <<Clear>>
    Delete the currently selected widget contents.

    When do you find that the text widget generates this event? The single sentence implies it would only occur when all of the contents were
    deleted.

    Question 2:
    Why do I hear the tick twice when text is already selected and I extend
    the selection to include more text?

    man n text:

    [4] Whenever the sel tag range changes a virtual event
    <<Selection>> is generated.

    "Extending" the selection is a "change" to the "tag range" -- so it >>triggers the event as documented.


    Thanks, but I still don't understand why it's triggered twice.

    Given the small bit of docs, one explanation could be that the
    triggering code is noticing two "changes" that differ in some subtle
    way such that the author of the triggering code generated the event for separately for both changes.

    You could 'shim' the text widget so you can see what commands are being
    called that might be the cause:

    text .t
    rename .t .t-original
    proc .t {args} {
    puts stderr "args='$args'"
    .t-original {*}$args
    }

    And, change your <<Selection>> event to "puts" a message to stderr as
    well (so timing remains consistent).

    Then look at the stderr output to see what widget commands are being
    called as the pair of events is being generated.

    Actually, sometimes it is triggered twice and sometimes it's
    triggered once. I tested it and got a consistently inconsistent
    behavior. Once or twice on some pattern I definitely can't
    understand. I could post a link to a video demonstrating it, but I
    know people here hate videos.

    Well, the hatred is more for those who post a single short sentence
    artice that says little more than: "see this video: http://example.com/video.mkv".

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From et99@21:1/5 to Luc on Thu Nov 30 14:05:42 2023
    On 11/30/2023 7:10 AM, Luc wrote:
    On Thu, 30 Nov 2023 14:44:32 -0000 (UTC), Rich wrote:

    The text widget is not documented (at least in 8.6.12) as generating
    <<Clear>>. In what manual did you find this event? Because what you
    quote above is not typical wording for virtual events. They are
    usually worded as: "generated when X occurs"

    It's the 'event' page on a CHM file I downloaded some time ago, about
    two years ago I think. It has this identification:

    Tcl Windows Help (V 2019.01.09)
    Copyright © 2019 Ashok P. Nadkarni (Compilation only)

    I just noticed this:

    "Tk defines the following virtual events for the purposes of unifying bindings across multiple platforms. Users expect them to behave in the following way:"

    A list of events ensue, <<Clear>> is the first one.

    Now, it occurs to me that "for the purposes of unifying bindings
    across multiple platforms" might indicate that <<Clear>> belongs to
    some other platform. Windows or Mac, I suppose.



    Question 2:
    Why do I hear the tick twice when text is already selected and I extend
    the selection to include more text?

    man n text:

    [4] Whenever the sel tag range changes a virtual event
    <<Selection>> is generated.

    "Extending" the selection is a "change" to the "tag range" -- so it
    triggers the event as documented.


    Thanks, but I still don't understand why it's triggered twice. Actually, sometimes it is triggered twice and sometimes it's triggered once.
    I tested it and got a consistently inconsistent behavior. Once or twice
    on some pattern I definitely can't understand. I could post a link to
    a video demonstrating it, but I know people here hate videos.



    Looking at the bindings sometimes helps:

    % text .t
    .t
    % bindtags .t
    .t Text . all
    % join [lsort [bind Text]] \n
    <<Clear>>
    <<Copy>>
    <<Cut>>
    <<LineEnd>>
    <<LineStart>>
    .... snip ....
    <Shift-Key-Tab>
    <Shift-MouseWheel>
    <Triple-Button-1>
    <Triple-Shift-Button-1>

    % bind Text <<Clear>>

    # Make <<Clear>> an atomic operation on the Undo stack,
    # i.e. separate it from other delete operations on either side
    if {[%W cget -autoseparators]} {
    %W edit separator
    }
    catch {%W delete sel.first sel.last}
    if {[%W cget -autoseparators]} {
    %W edit separator
    }

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From et99@21:1/5 to All on Thu Nov 30 14:50:37 2023
    On 11/30/2023 2:05 PM, et99 wrote:
    On 11/30/2023 7:10 AM, Luc wrote:
    On Thu, 30 Nov 2023 14:44:32 -0000 (UTC), Rich wrote:

    The text widget is not documented (at least in 8.6.12) as generating
    <<Clear>>.  In what manual did you find this event?  Because what you
    quote above is not typical wording for virtual events.  They are
    usually worded as: "generated when X occurs"

    It's the 'event' page on a CHM file I downloaded some time ago, about
    two years ago I think. It has this identification:

    Tcl Windows Help (V 2019.01.09)
    Copyright © 2019 Ashok P. Nadkarni (Compilation only)

    I just noticed this:

    "Tk defines the following virtual events for the purposes of unifying
    bindings across multiple platforms. Users expect them to behave in the
    following way:"

    A list of events ensue, <<Clear>> is the first one.

    Now, it occurs to me that "for the purposes of unifying bindings
    across multiple platforms" might indicate that <<Clear>> belongs to
    some other platform. Windows or Mac, I suppose.



    Question 2:
    Why do I hear the tick twice when text is already selected and I extend >>>> the selection to include more text?

    man n text:

           [4]    Whenever the sel tag range changes a virtual event >>>               <<Selection>> is generated.

    "Extending" the selection is a "change" to the "tag range" -- so it
    triggers the event as documented.


    Thanks, but I still don't understand why it's triggered twice. Actually,
    sometimes it is triggered twice and sometimes it's triggered once.
    I tested it and got a consistently inconsistent behavior. Once or twice
    on some pattern I definitely can't understand. I could post a link to
    a video demonstrating it, but I know people here hate videos.



    Looking at the bindings sometimes helps:

    % text .t
    .t
    % bindtags .t
    .t Text . all
    % join [lsort [bind Text]] \n
    <<Clear>>
    <<Copy>>
    <<Cut>>
    <<LineEnd>>
    <<LineStart>>
    .... snip ....
    <Shift-Key-Tab>
    <Shift-MouseWheel>
    <Triple-Button-1>
    <Triple-Shift-Button-1>

    % bind Text <<Clear>>

        # Make <<Clear>> an atomic operation on the Undo stack,
        # i.e. separate it from other delete operations on either side
        if {[%W cget -autoseparators]} {
        %W edit separator
        }
        catch {%W delete sel.first sel.last}
        if {[%W cget -autoseparators]} {
        %W edit separator
        }





    Strangely, I can't locate the virtual event <<Clear>> itself:

    % event info <<Clear>>
    % join [lsort [event info]] \n
    <<ContextMenu>>
    <<Copy>>
    <<Cut>>
    <<LineEnd>>
    <<LineStart>>
    <<NextChar>>
    <<NextLine>>
    <<NextPara>>
    <<NextWindow>>
    <<NextWord>>
    <<Paste>>
    <<PasteSelection>>
    <<PrevChar>>
    <<PrevLine>>
    <<PrevPara>>
    <<PrevWindow>>
    <<PrevWord>>
    <<Redo>>
    <<SelectAll>>
    <<SelectLineEnd>>
    <<SelectLineStart>>
    <<SelectNextChar>>
    <<SelectNextLine>>
    <<SelectNextPara>>
    <<SelectNextWord>>
    <<SelectNone>>
    <<SelectPrevChar>>
    <<SelectPrevLine>>
    <<SelectPrevPara>>
    <<SelectPrevWord>>
    <<ToggleSelection>>
    <<Undo>>


    But for the above, say, <<Paste>>

    % event info <<Paste>>
    <Control-Key-v> <Shift-Key-Insert> <Control-Lock-Key-V>

    And the above list is the same on windows and linux.


    But... there's no binding to <<Paste>> in Text, but there is in Entry:

    % bind Text <<Paste>>
    % bind Entry <<Paste>>

    catch {
    if {[tk windowingsystem] ne "x11"} {
    catch {
    %W delete sel.first sel.last
    }
    }
    %W insert insert [::tk::GetSelection %W CLIPBOARD]
    tk::EntrySeeInsert %W
    }

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Luc@21:1/5 to All on Thu Nov 30 21:10:00 2023
    On Thu, 30 Nov 2023 14:05:42 -0800, et99 wrote:

    Looking at the bindings sometimes helps:

    % text .t
    .t
    % bindtags .t
    .t Text . all
    % join [lsort [bind Text]] \n
    <<Clear>>
    <<Copy>>
    <<Cut>>
    <<LineEnd>>
    <<LineStart>>
    .... snip ....
    <Shift-Key-Tab>
    <Shift-MouseWheel>
    <Triple-Button-1>
    <Triple-Shift-Button-1>

    % bind Text <<Clear>>

    # Make <<Clear>> an atomic operation on the Undo stack,
    # i.e. separate it from other delete operations on either side
    if {[%W cget -autoseparators]} {
    %W edit separator
    }
    catch {%W delete sel.first sel.last}
    if {[%W cget -autoseparators]} {
    %W edit separator
    }
    **************************


    I was about to find out something like that.

    I have another app with text widgets and a problem: when pasting text
    over existing test, the new text would be pasted next to it, or rather
    it would be pasted where the old text was and the old text would be
    pushed to the right. I never wanted that to happen.
    My text editor doesn't do that.

    Both apps had this:

    bind $::text <Shift_L><Insert> {p.paste %W; break;}
    bind $::text <Control-v> {p.paste %W; break;}


    But they had slightly different paste procs:

    proc p.paste {argWidget} {
    event generate $argWidget <<Paste>>
    $argWidget see insert

    ;# this one has the overwriting flaw
    }


    proc p.paste {argWidget} {
    if {[tk windowingsystem] eq "x11"} {
    event generate $argWidget <<Clear>>
    # For other windowing systems, this operation is explicitly
    # built into the <<Paste>> binding
    }
    event generate $argWidget <<Paste>>
    $argWidget see insert

    ;# this one doesn't have the overwriting flaw
    }


    I don't remember where that comment regarding windowing systems
    comes from. I may have stolen it from here, the wiki or the
    manual.

    Either way, I can't detect it with bind. I can detect the use of
    the Delete key, but there are many ways that text can be deleted.

    --
    Luc


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From et99@21:1/5 to Luc on Thu Nov 30 21:01:48 2023
    On 11/30/2023 4:10 PM, Luc wrote:
    On Thu, 30 Nov 2023 14:05:42 -0800, et99 wrote:

    Looking at the bindings sometimes helps:

    % text .t
    .t
    % bindtags .t
    .t Text . all
    % join [lsort [bind Text]] \n
    <<Clear>>
    <<Copy>>
    <<Cut>>
    <<LineEnd>>
    <<LineStart>>
    .... snip ....
    <Shift-Key-Tab>
    <Shift-MouseWheel>
    <Triple-Button-1>
    <Triple-Shift-Button-1>

    % bind Text <<Clear>>

    # Make <<Clear>> an atomic operation on the Undo stack,
    # i.e. separate it from other delete operations on either side
    if {[%W cget -autoseparators]} {
    %W edit separator
    }
    catch {%W delete sel.first sel.last}
    if {[%W cget -autoseparators]} {
    %W edit separator
    }
    **************************


    I was about to find out something like that.

    I have another app with text widgets and a problem: when pasting text
    over existing test, the new text would be pasted next to it, or rather
    it would be pasted where the old text was and the old text would be
    pushed to the right. I never wanted that to happen.
    My text editor doesn't do that.

    Both apps had this:

    bind $::text <Shift_L><Insert> {p.paste %W; break;}
    bind $::text <Control-v> {p.paste %W; break;}


    But they had slightly different paste procs:

    proc p.paste {argWidget} {
    event generate $argWidget <<Paste>>
    $argWidget see insert

    ;# this one has the overwriting flaw
    }


    proc p.paste {argWidget} {
    if {[tk windowingsystem] eq "x11"} {
    event generate $argWidget <<Clear>>
    # For other windowing systems, this operation is explicitly
    # built into the <<Paste>> binding
    }
    event generate $argWidget <<Paste>>
    $argWidget see insert

    ;# this one doesn't have the overwriting flaw
    }


    I don't remember where that comment regarding windowing systems
    comes from. I may have stolen it from here, the wiki or the
    manual.

    Either way, I can't detect it with bind. I can detect the use of
    the Delete key, but there are many ways that text can be deleted.


    I discovered that same problem with entry widgets being different on linux and windows. A paste on linux doesn't replace the selection as I expected.

    And here is why that happens with the entry:

    % bind Entry <<Paste>>

    catch {
    if {[tk windowingsystem] ne "x11"} {
    catch {
    %W delete sel.first sel.last
    }
    }
    %W insert insert [::tk::GetSelection %W CLIPBOARD]
    tk::EntrySeeInsert %W
    }


    I don't know why they don't do the delete of the selection on x11 systems

    On my linux I get:

    % tk windowingsystem
    x11

    vs. this on windows:

    % tk windowingsystem
    win32

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From et99@21:1/5 to All on Thu Nov 30 21:16:57 2023
    On 11/30/2023 9:01 PM, et99 wrote:
    On 11/30/2023 4:10 PM, Luc wrote:
    On Thu, 30 Nov 2023 14:05:42 -0800, et99 wrote:

    Looking at the bindings sometimes helps:

    % text .t
    .t
    % bindtags .t
    .t Text . all
    % join [lsort [bind Text]] \n
    <<Clear>>
    <<Copy>>
    <<Cut>>
    <<LineEnd>>
    <<LineStart>>
    .... snip ....
    <Shift-Key-Tab>
    <Shift-MouseWheel>
    <Triple-Button-1>
    <Triple-Shift-Button-1>

    % bind Text <<Clear>>

         # Make <<Clear>> an atomic operation on the Undo stack,
         # i.e. separate it from other delete operations on either side
         if {[%W cget -autoseparators]} {
        %W edit separator
         }
         catch {%W delete sel.first sel.last}
         if {[%W cget -autoseparators]} {
        %W edit separator
         }
    **************************


    I was about to find out something like that.

    I have another app with text widgets and a problem: when pasting text
    over existing test, the new text would be pasted next to it, or rather
    it would be pasted where the old text was and the old text would be
    pushed to the right. I never wanted that to happen.
    My text editor doesn't do that.

    Both apps had this:

    bind $::text    <Shift_L><Insert>      {p.paste %W; break;}
    bind $::text    <Control-v>         {p.paste %W; break;}


    But they had slightly different paste procs:

    proc p.paste {argWidget}    {
        event generate $argWidget <<Paste>>
        $argWidget see insert

        ;# this one has the overwriting flaw
    }


    proc p.paste {argWidget}    {
        if {[tk windowingsystem] eq "x11"} {
            event generate $argWidget <<Clear>>
            # For other windowing systems, this operation is explicitly >>         # built into the <<Paste>> binding
        }
        event generate $argWidget <<Paste>>
        $argWidget see insert

        ;# this one doesn't have the overwriting flaw
    }


    I don't remember where that comment regarding windowing systems
    comes from. I may have stolen it from here, the wiki or the
    manual.

    Either way, I can't detect it with bind. I can detect the use of
    the Delete key, but there are many ways that text can be deleted.


    I discovered that same problem with entry widgets being different on linux and windows. A paste on linux doesn't replace the selection as I expected.

    And here is why that happens with the entry:

    % bind Entry <<Paste>>

    catch {
        if {[tk windowingsystem] ne "x11"} {
            catch {
                %W delete sel.first sel.last
            }
        }
        %W insert insert [::tk::GetSelection %W CLIPBOARD]
        tk::EntrySeeInsert %W
    }


    I don't know why they don't do the delete of the selection on x11 systems

    On my linux I get:

    % tk windowingsystem
    x11

    vs. this on windows:

    % tk windowingsystem
    win32


    I just realized I had already posted the binding on <<Paste>> above. I was using that to show that Text and Entry were different and the second post to show it was the reason for the linux problem :)

    But I think now the reason there's no direct bindings to <<Clear>> is that code must only use it via generate.

    I think maybe I should write up a ticket for that (if I didn't already - need to check).

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)