This page was started on Saturday, July 13, 2002.
Rohan Pall writes about his short but lively experience with tk_popup:
Why do I care about this?
My ultrat (ultra table) package makes it easy for me to quickly make auto-scrolled tables that have a cool way of hiliting the item under the mouse. I also wanted a popup when the right-button is clicked over an item, like you've prolly seen in lots of progs. The problem was that tk_popup is inconsistent on different platforms. So I worked around it. Now I'm showing you what I figured out in the hopes that it helps y'all. And this way I'll remember a year from now what I was doing ;)
A lucid description of the issues
Here's another guy struggling with the same prob I had! Nice description, worth a read. [L1 ]
Platform diffs
I've noticed some diffs with tk_popup on Windows and on Unix, specifically on Windows98 and on Linux. I use $::tcl_platform(platform) to test what platform I'm on, i.e. "windows" or "unix".
windows:
I'm assuming this happens because the native windows menu widget is being called, and not a Tk toplevel. All I know for sure is that I have observed this widget phenomena.
unix:
This inconsistent behavior causes problems when doing cool things with The Cool Language.
Code that shows you the prob, bob
Run this code on Windows and Unix. Notice how as soon as the popup is displayed on unix, the message that the script is resuming is displayed. See how on windows this only happens after the popup disappears (is dismissed, whatever).
set noob [label .noob -text noob -bg purple -fg red] pack $noob set t [text .t -height 20 -width 70 -wrap none] pack $t -fill both -expand 1 proc ins {msg} { global t $t insert end \ "[clock format [clock seconds] -format %T] $msg\n" } set m [menu .m -tearoff 0] $m add command \ -label Party! \ -command [list ins "Noob Party!"] \ -underline 0 bind $noob <Button-3> [list showpopup %X %Y] proc showpopup {X Y} { global m t tk_popup $m $X $Y ins "script resumes now after tk_popup command..." return }
So how do I fix this!?
Pretty simple. Well umm it took me a while to figure it though ;)
So I want the item that was right-clicked on to stay hilited when showing the popup. If the mouse moves over any other item, I don't want the hilited item to change. This is because the user doesn't remember what item was clicked on -- jeez, I am the user and I can't remember much for long!
So here's the algo:
The item gets right clicked:
Ta da!
I hope you enjoyed your stay ;)
LV a note recently posted on comp.lang.tcl suggests that if you no longer want the native behavior, you could rename the command and then source in the Tcl script implementing the Unix behavior. Some people prefer to have cross platform identical look and feel and behavior, while others prefer the native approach, even when it means that things don't work the same across platforms.
Vince: surely the fact that the 'unmap' binding isn't called is simply a bug in WinTk and should be reported on sourceforge so a maintainer can perhaps fix it...
Ro: Yeah, I agree, the <Unmap> event really should be fired on Windows. But thats not the only difference. Witness how in unix the script continues after the popup is shown, which is not what happens in Windows.
Vince: and that indeed is another bug (at the very least it should be documented as a platform-difference, and preferably fixed for consistency). Please do report these problems a bugs to the tktoolkit project on sourceforge.
Ro: July 22, 2002 - Done [L2 ]. Thanks Vince.
#!/usr/bin/wish -f #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! # tk_popup at <ButtonPress-1> eats <ButtonRelease-1> !!!! # tk8.4, tested at 2 Linux boxes !!!! #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! canvas .cv -height 200 -width 200 .cv create rectangle 1 1 200 200 -fill red pack .cv -fill both -expand yes #Variant1: .cv bind all <ButtonPress-1> {puts <ButtonPress-1>; create_menu %X %Y} .cv bind all <ButtonRelease-1> {puts {<ButtonRelease-1> never put}} #Variant2: (same Problem) #bind .cv <ButtonPress-1> {puts <ButtonPress-1>; create_menu %X %Y} #bind .cv <ButtonRelease-1> {puts {<ButtonRelease-1> never put}} #Variant3: (same Problem) #.cv bind all <ButtonPress-1> {puts <ButtonPress-1>; create_menu %X %Y} #bind .cv <ButtonRelease-1> {puts {<ButtonRelease-1> never put}} #Variant4: (same Problem) #bind .cv <ButtonPress-1> {puts <ButtonPress-1>; create_menu %X %Y} #.cv bind all <ButtonRelease-1> {puts {<ButtonRelease-1> never put}} proc create_menu {X Y} { puts "Creating the menu" catch { destroy .cv.m } menu .cv.m -tearoff 1 .cv.m add command -label "Something" -command "puts Something" tk_popup .cv.m $X $Y puts "Menu popped up" #... and <ButtonRelease-1> gone }