menubutton .b -text "Blah" -menu .b.m menu .b.m .b.m add command -label "Tribble" .b.m add command -label "Foo" .b.m add command -label "Bar" .b.m add cascade -label "Bittle" -menu .b.m.m menu .b.m.m .b.m.m add command -label "Stomp" pack .b bind .b.m {+menuMove %W %y %s} bind .b.m {+set menu_help(current) -1} bind .b.m {+set menu_help(current) -1} bind .b.m {+set menu_help(current) -1} bind .b.m.m {+menuMove %W %y %s} bind .b.m.m {+set menu_help(current) -1} bind .b.m.m {+set menu_help(current) -1} bind .b.m.m {+set menu_help(current) -1} set menu_help(current) -1 proc menuMove {w y s} { set oldy -1 set idx 0 set newy [$w yposition $idx] while {$oldy != $newy} { if {$y < $newy} { set idx [expr $idx - 1] handleEntry $w $idx return } set oldy $newy incr idx set newy [$w yposition $idx] } set idx [expr $idx-1] handleEntry $w $idx } proc handleEntry {w i} { global menu_help if {$i > -1 && $menu_help(current) != $i} { set menu_help(current) $i set type [$w type $i] if {$type == "tearoff"} { puts "I'm a tearoff" } elseif {$type == "separator"} { puts "I'm a separator" } elseif {$type == "command"} { set name [$w entrycget $i -label] if {$name != {}} { puts "I'm over $name at $i." } else { puts "It's a separator at $i!" } } } }