Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW

How do Tk popup menus actually work?

by Falkkin (Chaplain)
on Feb 06, 2001 at 21:20 UTC ( #56705=perlquestion: print w/replies, xml ) Need Help??
Falkkin has asked for the wisdom of the Perl Monks concerning the following question:

I'm working on a Perl/Tk application, and wanted to know how popup menus (such as those created when you right-click on something in, say, Netscape) work.

There doesn't seem to be any built-in support (i.e. a specific module) for creating these -- I had to look through the Tk source distribution to find what I wanted. I basically copied their code verbatim, and it works, but relies on some sort of magic I don't understand. Here's the relevant snippet:

# A right-click in the viewer should bring up the popup menu. $viewer->bind("<3>", [\&post_popup_menu]); sub post_popup_menu { my $w = shift; # no idea how this works. my $X = $w->XEvent->X; my $Y = $w->XEvent->Y; $viewer_menu->Post($X, $Y); }
The line that mystifies me is the first line of post_popup_menu... I'm not sending the callback any arguments, but it still manages to receive a mysterious $w variable somehow. After doing some preliminary poking with Data::Dumper, it looks like $w is the $viewer that the menu is associated with.

Beyond that, however, I'm stumped... anyone know how Tk works this magic?

Replies are listed 'Best First'.
Re: How do Tk popup menus actually work?
by chipmunk (Parson) on Feb 06, 2001 at 21:42 UTC
    You're not calling the callback at all; you're just passing a reference to the callback to $viewer->bind(). When $viewer calls the callback later in the execution, it includes itself as an argument. This is just a way for your callback to get access to the information it needs from its parent widget, in this case the X and Y coordinates of the event.

    Of course, one must know what arguments a callback will be called with, in order to write the callback properly. See HTML::Parser for an example of a well-documented callback interface.

Re: How do Tk popup menus actually work?
by kschwab (Priest) on Feb 06, 2001 at 21:35 UTC
    The magic is in Tk::bind. By default, it supplies your callback with the widget object that triggered the event as an argument.

    Look at the docs for Tk::callbacks, they have some examples that make it more clear. There is also some explanation on how to pass other args, or make method calls instead of a calling a generalized subroutine.

    It is odd, though, that the docs for Tk::bind don't spell out the default behavior.

Re: How do Tk popup menus actually work?
by baku (Scribe) on Feb 06, 2001 at 21:45 UTC

    disclaimer: Without looking into the Tk source m'self...

    What the line $viewer->bind("<3>", [\&post_popup_menu]) does is call the method 'bind' in (whatever class "ref $viewer" tells you) with the parameter list: ($viewer, "<3>", $arrayref). That $arrayref is the new array reference created by the  [  ] operator, which in turn contains only the CODE ref (created by the  \& operator(s?) ) to post_popup_menu.

    Note that a CODE ref cannot have arguments associated with it; the arguments are provided by the (eventual) caller. (If you wanted to pass certain args, you could use a closure to wrap the callback, e.g.  [ sub { &some_function ($whatever, @_); } ] )

    When your callback function (post_popup_menu) is called, it looks like it receives a parameter telling it 'who called,' which from what you said here, would be $viewer. (the 'shift' pulls the next - or in this case, first - argument to the subroutine off @_.) This object then appears to have stored the X and Y location of the event for which you were called - in this example, "<3>", a right-click (mouse button 3 click; could be on the left ;-) ).

    I'd assume, then, that $viewer_menu is the menu, and to "Post" it means to "stick it" at the X,Y coords given.

    Those Data::Dumper outputs should be interesting; you might want to poke around the XEvent structure to see what else you can do this way.

Re: How do Tk popup menus actually work?
by ichimunki (Priest) on Feb 07, 2001 at 00:52 UTC
    Why were you looking through Tk source? :)

    perldoc Tk::Menu and perldoc Tk::Bind get you most of the way to the above.

    $w is simply the container in which the event happened being shifted off the callback parameters, which you are then running the XEvent method on to get the location of the right-click.

    The argument that gets shifted to $w is an inherent argument, due to object oriented nature of Tk.
Re: How do Tk popup menus actually work?
by azatoth (Curate) on Feb 06, 2001 at 21:28 UTC

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://56705]
Approved by root
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (9)
As of 2018-01-24 10:02 GMT
Find Nodes?
    Voting Booth?
    How did you see in the new year?

    Results (257 votes). Check out past polls.