# menu.tcl -- # # This file defines the default bindings for Tk menus and menubuttons. # It also implements keyboard traversal of menus and implements a few # other utility procedures related to menus. # # Copyright (c) 1992-1994 The Regents of the University of California. # Copyright (c) 1994-1997 Sun Microsystems, Inc. # Copyright (c) 1998-1999 by Scriptics Corporation. # Copyright (c) 2007 Daniel A. Steffen # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # #------------------------------------------------------------------------- # Elements of tk::Priv that are used in this file: # # cursor - Saves the -cursor option for the posted menubutton. # focus - Saves the focus during a menu selection operation. # Focus gets restored here when the menu is unposted. # grabGlobal - Used in conjunction with tk::Priv(oldGrab): if # tk::Priv(oldGrab) is non-empty, then tk::Priv(grabGlobal) # contains either an empty string or "-global" to # indicate whether the old grab was a local one or # a global one. # inMenubutton - The name of the menubutton widget containing # the mouse, or an empty string if the mouse is # not over any menubutton. # menuBar - The name of the menubar that is the root # of the cascade hierarchy which is currently # posted. This is null when there is no menu currently # being pulled down from a menu bar. # oldGrab - Window that had the grab before a menu was posted. # Used to restore the grab state after the menu # is unposted. Empty string means there was no # grab previously set. # popup - If a menu has been popped up via tk_popup, this # gives the name of the menu. Otherwise this # value is empty. # postedMb - Name of the menubutton whose menu is currently # posted, or an empty string if nothing is posted # A grab is set on this widget. # relief - Used to save the original relief of the current # menubutton. # window - When the mouse is over a menu, this holds the # name of the menu; it's cleared when the mouse # leaves the menu. # tearoff - Whether the last menu posted was a tearoff or not. # This is true always for unix, for tearoffs for Mac # and Windows. # activeMenu - This is the last active menu for use # with the <> virtual event. # activeItem - This is the last active menu item for # use with the <> virtual event. #------------------------------------------------------------------------- #------------------------------------------------------------------------- # Overall note: # This file is tricky because there are five different ways that menus # can be used: # # 1. As a pulldown from a menubutton. In this style, the variable # tk::Priv(postedMb) identifies the posted menubutton. # 2. As a torn-off menu copied from some other menu. In this style # tk::Priv(postedMb) is empty, and menu's type is "tearoff". # 3. As an option menu, triggered from an option menubutton. In this # style tk::Priv(postedMb) identifies the posted menubutton. # 4. As a popup menu. In this style tk::Priv(postedMb) is empty and # the top-level menu's type is "normal". # 5. As a pulldown from a menubar. The variable tk::Priv(menubar) has # the owning menubar, and the menu itself is of type "normal". # # The various binding procedures use the state described above to # distinguish the various cases and take different actions in each # case. #------------------------------------------------------------------------- #------------------------------------------------------------------------- # The code below creates the default class bindings for menus # and menubuttons. #------------------------------------------------------------------------- bind Menubutton {} bind Menubutton { tk::MbEnter %W } bind Menubutton { tk::MbLeave %W } bind Menubutton <1> { if {$tk::Priv(inMenubutton) ne ""} { tk::MbPost $tk::Priv(inMenubutton) %X %Y } } bind Menubutton { tk::MbMotion %W up %X %Y } bind Menubutton { tk::MbMotion %W down %X %Y } bind Menubutton { tk::MbButtonUp %W } bind Menubutton { tk::MbPost %W tk::MenuFirstEntry [%W cget -menu] } bind Menubutton <> { tk::MbPost %W tk::MenuFirstEntry [%W cget -menu] } # Must set focus when mouse enters a menu, in order to allow # mixed-mode processing using both the mouse and the keyboard. # Don't set the focus if the event comes from a grab release, # though: such an event can happen after as part of unposting # a cascaded chain of menus, after the focus has already been # restored to wherever it was before menu selection started. bind Menu {} bind Menu { set tk::Priv(window) %W if {[%W cget -type] eq "tearoff"} { if {"%m" ne "NotifyUngrab"} { if {[tk windowingsystem] eq "x11"} { tk_menuSetFocus %W } } } tk::MenuMotion %W %x %y %s } bind Menu { tk::MenuLeave %W %X %Y %s } bind Menu { tk::MenuMotion %W %x %y %s } bind Menu