I have a problem with MenuSelect event in Tcl/Tk 8.6.11 (tried in Linux, Debian 10.7).
In fact, it doesn’t fire at all for the main and tearoff-ed menus. Though working fine in Tcl/Tk 8.6.9, and even in 8.6.11 – only while menus are not tearoff-ed.
A test code:
package require Tk
proc ::somehandler {w wt} {
puts "Step [incr ::step]: $w / $wt, index=[$wt index active]"
}
set w [menu .m -tearoff 1]
$w add command -label {Item 1}
$w add command -label {Item 2}
bind $w <<MenuSelect>> [list ::somehandler $w %W]
pack [button .b -text "Click me"
-command {tk_popup .m [winfo pointerx .] [winfo pointery .]}]
I tried the following (idiotic though) replacement:
event delete <<MenuSelect>>
event add <<MenuSelect>> <Motion>
bind $w <<MenuSelect>> [list ::somehandler $w %W]
… with the same results.
Seemingly, it’s related to menu pathes dealt in Tk somewhat tricky, as seen in the above example.
I’m too lazy to change a standard code at switching from 8.6.9 to 8.6.11/12, 8.7 etc.
TIA for any hints.
2
Answers
For Tk 8.6.11+, bind Menu should be used instead of bind $w (for individual menu items). It adds some acrobatics to an event handler that should calculate what's a menu item to be dealt with.
I.e. we have something like:
The %W wildcard is passed to ::somehandler as a "cloned" name, if the menu item is in a cloned menu.
And ::somehandler should calculate who is the %W in reality.
Csaba Nemethi advises to use a procedure like clonename (from utils.tcl of BWidget package). This procedure gets a clone name from a "normal" menu item's path.
Here is a bit modified version of it:
As an example of use, see test.tcl of:
http://chiselapp.com/user/aplsimple/repository/baltip/zip/trunk/baltip.zip
Thank you Donal and Csaba for your hints.
This is probably related to the fact that menus use clones for tearoffs and the menubar. From the documentation:
I can’t remember how exactly clones are really named, but you don’t normally interact with them directly; it’s only with event handling that you ever really see them. (I’ve only ever had to deal with them when doing tooltips for menus.)
Normally, it’s considered best to avoid using
<<MenuSelect>>
and instead just set a-command
on the entries that can be selected (or to just set the model variables right forcheckbutton
andradiobutton
entries). And avoid tearoffs entirely; they’re a style of menu interaction that went out of fashion over 25 years ago.