• [event generate] not working as expected

    From Luc@21:1/5 to All on Fri Mar 10 19:37:30 2023
    Of course I am doing something wrong, but I don't know what.
    Can somebody please point it out?


    proc p.paste {argWidget} {
    if {[catch "set ::selection [selection get]"] == 0} {
    event generate $argWidget <<Clear>>
    }
    set ::t1::currindex [$::t1::text index insert]
    event generate $argWidget <<Paste>>
    set clipcontent [selection get -selection CLIPBOARD -type UTF8_STRING]
    set cliplinecount [llength [split $clipcontent "\n"]]
    $::t1::text see "$::t1::currindex + $cliplinecount l"
    }


    What it is supposed to do:
    Detect whether there is selected text, in which case issue the
    event generate $argWidget <<Clear>>
    command to do just that.
    Then it issues the
    event generate $argWidget <<Paste>>
    command to paste
    text from the clipboard where the selected text used to be.

    What it really does:
    It detects whether there is selected text, in which case issue the
    event generate $argWidget <<Clear>>
    command to do just that.
    That command fails. The selected text is not deleted. It is, instead
    placed after the newly pasted text with different formatting.
    The new text is inserted by
    event generate $argWidget <<Paste>>


    --
    Luc


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mike Griffiths@21:1/5 to Luc on Sat Mar 11 13:09:23 2023
    On Friday, 10 March 2023 at 22:37:35 UTC, Luc wrote:
    Of course I am doing something wrong, but I don't know what.
    Can somebody please point it out?


    proc p.paste {argWidget} {
    if {[catch "set ::selection [selection get]"] == 0} {
    event generate $argWidget <<Clear>>
    }
    set ::t1::currindex [$::t1::text index insert]
    event generate $argWidget <<Paste>>
    set clipcontent [selection get -selection CLIPBOARD -type UTF8_STRING]
    set cliplinecount [llength [split $clipcontent "\n"]]
    $::t1::text see "$::t1::currindex + $cliplinecount l"
    }


    What it is supposed to do:
    Detect whether there is selected text, in which case issue the
    event generate $argWidget <<Clear>>
    command to do just that.
    Then it issues the
    event generate $argWidget <<Paste>>
    command to paste
    text from the clipboard where the selected text used to be.

    What it really does:
    It detects whether there is selected text, in which case issue the
    event generate $argWidget <<Clear>>
    command to do just that.
    That command fails. The selected text is not deleted. It is, instead
    placed after the newly pasted text with different formatting.
    The new text is inserted by
    event generate $argWidget <<Paste>>


    --
    Luc

    It's hard to answer what's happening without more information. What type of widget is $argWidget? How is p.paste being executed? What bindings do you have on <<Clear>> and <<Paste>> on the widget?

    A minimal, but fully "working", code sample will help to answer your questions.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Luc@21:1/5 to Mike Griffiths on Sun Mar 12 16:51:10 2023
    **************************
    On Sat, 11 Mar 2023 13:09:23 -0800 (PST), Mike Griffiths wrote:

    It's hard to answer what's happening without more information. What type
    of widget is $argWidget? How is p.paste being executed? What bindings do
    you have on <<Clear>> and <<Paste>> on the widget?

    A minimal, but fully "working", code sample will help to answer your questions.



    Here is the code:

    package require Tk
    wm withdraw .
    eval destroy [winfo children .]
    set ::w [toplevel .editor -background #c0c0c0]

    namespace eval ::t1 {}
    set ::t1::text $::w.text
    text $::t1::text
    $::t1::text configure -wrap word -font "Monospace 14" -padx 4 -pady 2 $::t1::text configure -background #ffffff -foreground #000000
    $::t1::text configure -takefocus 1 -exportselection 1 -state normal -undo 1 pack $::t1::text -fill both -expand 1

    ######## SHIFT + INSERT TO PASTE
    bind $::t1::text <Shift_L><Insert> {p.paste %W; break}
    bind $::w <Alt_L><q> {exit 0}
    wm protocol $::w WM_DELETE_WINDOW {exit 0}

    proc p.paste {argWidget} {
    catch {set ::selection [selection get]} catcherror
    if {![info exists catcherror]} {
    event generate $argWidget <<Clear>>
    }

    set ::t1::currindex [$::t1::text index insert]
    event generate $argWidget <<Paste>>
    set clipcontent [selection get -selection CLIPBOARD -type UTF8_STRING]
    set cliplinecount [llength [split $clipcontent "\n"]]
    $::t1::text see "$::t1::currindex + $cliplinecount l"
    }

    focus $::t1::text


    --
    Luc


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mike Griffiths@21:1/5 to Luc on Sun Mar 12 14:47:05 2023
    On Sunday, 12 March 2023 at 19:51:15 UTC, Luc wrote:
    **************************
    On Sat, 11 Mar 2023 13:09:23 -0800 (PST), Mike Griffiths wrote:

    It's hard to answer what's happening without more information. What type of widget is $argWidget? How is p.paste being executed? What bindings do you have on <<Clear>> and <<Paste>> on the widget?

    A minimal, but fully "working", code sample will help to answer your questions.
    Here is the code:

    package require Tk
    wm withdraw .
    eval destroy [winfo children .]
    set ::w [toplevel .editor -background #c0c0c0]

    namespace eval ::t1 {}
    set ::t1::text $::w.text
    text $::t1::text
    $::t1::text configure -wrap word -font "Monospace 14" -padx 4 -pady 2 $::t1::text configure -background #ffffff -foreground #000000
    $::t1::text configure -takefocus 1 -exportselection 1 -state normal -undo 1 pack $::t1::text -fill both -expand 1

    ######## SHIFT + INSERT TO PASTE
    bind $::t1::text <Shift_L><Insert> {p.paste %W; break}
    bind $::w <Alt_L><q> {exit 0}
    wm protocol $::w WM_DELETE_WINDOW {exit 0}

    proc p.paste {argWidget} {
    catch {set ::selection [selection get]} catcherror
    if {![info exists catcherror]} {
    event generate $argWidget <<Clear>>
    }

    set ::t1::currindex [$::t1::text index insert]
    event generate $argWidget <<Paste>>
    set clipcontent [selection get -selection CLIPBOARD -type UTF8_STRING]
    set cliplinecount [llength [split $clipcontent "\n"]]
    $::t1::text see "$::t1::currindex + $cliplinecount l"
    }
    focus $::t1::text


    --
    Luc


    I notice you've changed your [catch] statement, you have a few errors with this (and did previously, too). The variable (catchError in this case) will be set either way, it just depends whether it contains an error message (if the code failed) or the
    result (if it succeeded). You need to be checking the return value of the [catch] itself. However, as far as I can see, [selection get] with no arguments will never throw an error. You also have a potential bug from the fact you're using [selection get]
    in that check (and storing its value in a global variable for some reason) but then not using that later, and doing another [selection get] with arguments - which may return a different result.

    You can simplify your code a lot for the desired behaviour by doing:

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

    You shouldn't need the [focus] - this is on a keyboard binding, so the widget should have focus already for it to be triggered in the first place.
    However, note that this separate <<Clear>> bindings adds an additional entry to the "undo" stack - for your best option, look at the existing <<Paste>> binding and the proc it runs, duplicate this and remove the check for x11 if you always want the
    selection cleared, and just add the 'see insert' at the end.

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