Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things

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 taking refuge in the Monastery: (6)
As of 2017-07-23 16:50 GMT
Find Nodes?
    Voting Booth?
    I came, I saw, I ...

    Results (347 votes). Check out past polls.