[HaO] 2019-04-12 **Scope** The Tk [bind] command allows to add commands by the syntax: ======tcl bind win tag +cmd ====== There is no buildin way to remove the added command. **Warning** (Christian Gollwitzer on clt): The "+cmd" syntax is considered as broken. Bindtags (which are lists) or [tcllib] [uevent] should be used instead. [HaO]: Nevertheless, I face this issue for important global events like [androwish] "<>" command, which is potentially important for a lot of modules in common. Christian: This is the classic case of "misusing" Tk events - an event which has multiple listeners cannot be cleanly expressed in Tk. If you have all the modules under your control. Refire the event as a uevent in the main setup: ====== bind . <> { uevent::generate AndroidWish GoesDown } ====== then, in each module, you do: ====== set myid [uevent::bind AndroidWish GoesDown mymethod] ====== and when you unload the module ====== uevent::unbind $myid ====== We use uevent in aRTist precisely to do this - signalling general events that are not connected to a widget. And Mike Griffin about [bindtags]: You can still use bindtags: ====== % bindtags . Wish all % bindtags . [linsert [bindtags .] 1 CustomFoo] % bindtags . . CustomFoo Wish all % bind CustomFoo <> [list ScannerUnregister] ====== (Output above is on Wish on Windows; default bindtags may be different on AndroWish, or already altered by other libraries, but by using [linsert] as above you can inject your new bindtag safely regardless) **Observation** The command "bind win tag +cmd" does the following: * define "cmd" if no binding exists: "bind win tag cmd" * add a newline ("\n") and "cmd", if a binding exists Pseudocode: ======tcl proc BindAdd {w t c} { set ccur [bind $w $t] if {$ccur eq ""} { bind $w $t $c } else { bind $w $t $c $ccur\n$c } } ====== **Removal function** Here is a proposition to remove my own registration. ======tcl # Remove first Cmd from bind pattern. # @return true if removed proc BindRemove {Win Pattern CmdIn} { set CmdCur [bind $Win $Pattern] set Pos 0 while {-1 != [set Pos [string first $CmdIn $CmdCur $Pos]]} { # Check if found string starts at the beginning of after a new-line if { $Pos == 0 || [string index $CmdCur $Pos-1] eq "\n" } { # Check if found string ends at end or before a new-line set PosEnd [expr {$Pos + [string length $CmdIn]}] if { $PosEnd == [string length $CmdCur] || [string index $CmdCur $PosEnd] eq "\n" } { # Binding found if {$Pos != 0} { set CmdNew [string range $CmdCur 0 $Pos-2] } else { set CmdNew "" } if {$PosEnd!= [string length $CmdCur]} { if {$CmdNew ne ""} { append CmdNew \n } append CmdNew [string range $CmdCur $PosEnd+1 end] } bind $Win $Pattern $CmdNew return 1 } } incr Pos } return 0 } ====== Usage: ======tcl proc mymodule::init {} { bind . a +[namespace code MyModuleFunction] } proc mymodule::delete {} { bindRemove . a [namespace code MyModuleFunction] } ====== <> GUI