]> code.delx.au - gnu-emacs/blobdiff - lisp/mouse.el
(mouse-major-mode-menu): Use local-key-binding.
[gnu-emacs] / lisp / mouse.el
index b5d3a9dcb9d245c4c2ffe2701ec156816554cc2a..8cc878d2f90ed9c952a1da707bec3e14dc27d8f0 100644 (file)
@@ -60,11 +60,28 @@ PREFIX is the prefix argument (if any) to pass to the command."
                  (if filter (funcall filter (symbol-function map)) map)))))
         event)
     ;; The looping behavior was taken from lmenu's popup-menu-popup
-    (while (and map (setq event (x-popup-menu position map)))
+    (while (and map (setq event
+                         ;; map could be a prefix key, in which case
+                         ;; we need to get its function cell
+                         ;; definition.
+                         (x-popup-menu position (indirect-function map))))
       ;; Strangely x-popup-menu returns a list.
       ;; mouse-major-mode-menu was using a weird:
       ;; (key-binding (apply 'vector (append '(menu-bar) menu-prefix events)))
-      (let ((cmd (lookup-key map (apply 'vector event))))
+      (let ((cmd
+            (if (and (not (keymapp map)) (listp map))
+                ;; We were given a list of keymaps.  Search them all
+                ;; in sequence until a first binding is found.
+                (let ((mouse-click (apply 'vector event))
+                      binding)
+                  (while (and map (null binding))
+                    (setq binding (lookup-key (car map) mouse-click))
+                    (if (numberp binding) ; `too long'
+                      (setq binding nil))
+                    (setq map (cdr map)))
+                  binding)
+              ;; We were given a single keymap.
+              (lookup-key map (apply 'vector event)))))
        (setq map nil)
        ;; Clear out echoing, which perhaps shows a prefix arg.
        (message "")
@@ -73,9 +90,14 @@ PREFIX is the prefix argument (if any) to pass to the command."
              ;; Try again but with the submap.
              (setq map cmd)
            (setq prefix-arg prefix)
+           ;; `setup-specified-language-environment', for instance,
+           ;; expects this to be set from a menu keymap.
+           (setq last-command-event (car (last event)))
            ;; mouse-major-mode-menu was using `command-execute' instead.
            (call-interactively cmd)))))))
-       
+
+(defvar mouse-major-mode-menu-prefix)  ; dynamically bound
+
 (defun mouse-major-mode-menu (event prefix)
   "Pop up a mode-specific menu of mouse commands.
 Default to the Edit menu if the major mode doesn't define a menu."
@@ -91,7 +113,7 @@ Default to the Edit menu if the major mode doesn't define a menu."
         ;; Keymap from which to inherit; may be null.
         (ancestor (mouse-major-mode-menu-1
                    (and (current-local-map)
-                        (lookup-key (current-local-map) [menu-bar]))))
+                        (local-key-binding [menu-bar]))))
         ;; Make a keymap in which our last command leads to a menu or
         ;; default to the edit menu.
         (newmap (if ancestor
@@ -145,10 +167,31 @@ The contents are the items that would be in the menu bar whether or
 not it is actually displayed."
   (interactive "@e \nP")
   (run-hooks 'activate-menubar-hook)
-  (let* ((local-menu (lookup-key (current-local-map) [menu-bar]))
-        (global-menu (lookup-key global-map [menu-bar])))
+  (let* ((local-menu (and (current-local-map)
+                         (lookup-key (current-local-map) [menu-bar])))
+        (global-menu (lookup-key global-map [menu-bar]))
+        (local-title-or-map (and local-menu (cadr local-menu)))
+        (minor-mode-menus (mapcar #'cdr (minor-mode-key-binding [menu-bar])))
+        (global-title-or-map (cadr global-menu)))
+    ;; If the keymaps don't have prompt string (a lazy programmer
+    ;; didn't bother to provide one), create it and insert it into the
+    ;; keymaps; each keymap gets its own prompt.  This is required for
+    ;; non-toolkit versions to display non-empty menu pane names.
+    (or (null local-menu)
+       (stringp local-title-or-map)
+       (setq local-menu (cons 'keymap
+                              (cons (concat mode-name " Mode Menu")
+                                    (cdr local-menu)))))
+    (or (stringp global-title-or-map)
+       (setq global-menu (cons 'keymap
+                               (cons "Global Menu"
+                                     (cdr global-menu)))))
     ;; Supplying the list is faster than making a new map.
-    (popup-menu (list global-menu local-menu) event prefix)))
+    (popup-menu (append (list global-menu)
+                       (if local-menu
+                           (list local-menu))
+                       minor-mode-menus)
+               event prefix)))
 
 (defun mouse-popup-menubar-stuff (event prefix)
   "Popup a menu like either `mouse-major-mode-menu' or `mouse-popup-menubar'.