Commit 4ed77415 authored by Eli Zaretskii's avatar Eli Zaretskii
Browse files

Support menus on text-mode terminals.

 src/xterm.h (xw_popup_dialog): Add prototype.
 src/xmenu.c (Fx_popup_dialog): Function moved to menu.c.
 (xmenu_show): Block input here, instead in Fx_popup_menu.
 (xw_popup_dialog): New function, with X-specific bits of popup
 dialogs.
 src/xdisp.c (deep_copy_glyph_row, display_tty_menu_item): New
 functions.
 src/window.c (Fset_window_configuration): Use run-time tests of the
 frame type instead of compile-time conditionals, when menu-bar
 lines are considered.
 src/w32term.h (w32con_hide_cursor, w32con_show_cursor)
 (w32_popup_dialog): New prototypes.
 src/w32menu.c (Fx_popup_dialog): Function deleted.
 (w32_popup_dialog): New function, with w32 specific bits of popup
 dialogs.  Block input here.
 src/w32inevt.c (w32_console_read_socket): Minor change to add
 debugging TTY events.
 src/w32fns.c (show_hourglass): If returning early because the frame
 is not a GUI frame, unblock input.
 src/w32console.c (w32con_hide_cursor, w32con_show_cursor, cursorX)
 (cursorY): New functions.
 src/termhooks.h (cursorX, cursorY): Prototypes of functions on
 WINDOWSNT, macros that call curX and curY elsewhere.
 src/termchar.h (struct tty_display_info) <showing_menu>: New flag.
 src/term.c (tty_hide_cursor, tty_show_cursor) [WINDOWSNT]: Call w32
 specific function to hide and show cursor on a text-mode terminal.
 (tty_menu_struct, struct tty_menu_state): New structures.
 (tty_menu_create, tty_menu_make_room, tty_menu_search_pane)
 (tty_menu_calc_size, mouse_get_xy, tty_menu_display)
 (have_menus_p, tty_menu_add_pane, tty_menu_add_selection)
 (tty_menu_locate, save_and_enable_current_matrix)
 (restore_desired_matrix, screen_update, read_menu_input)
 (tty_menu_activate, tty_menu_destroy, tty_menu_help_callback)
 (tty_pop_down_menu, tty_menu_last_menubar_item)
 (tty_menu_new_item_coords, tty_menu_show): New functions.
 (syms_of_term): New DEFSYMs for tty-menu-* symbols.
 src/nsterm.h (ns_popup_dialog): Adjust prototype.
 src/nsmenu.m (ns_menu_show): Block and unblock input here, instead
 of in x-popup-menu.
 (ns_popup_dialog): Adapt order of arguments to the other
 *_menu_show implementations.
 (Fx_popup_dialog): Function deleted.
 src/msdos.c (x_set_menu_bar_lines): Delete unused function.
 src/menu.h (tty_menu_show, menu_item_width): provide prototypes.
 src/menu.c (have_boxes): New function.
 (single_keymap_panes): Use it instead of a compile-time
 conditional.
 (single_menu_item): Use run-time tests of the frame type instead
 of compile-time conditionals.
 (encode_menu_string): New function.
 (list_of_items, list_of_panes): Use it instead of ENCODE_STRING
 the macro, since different types of frame need different encoding
 of menu items.
 (digest_single_submenu): Use run-time tests of frame type instead
 of, or in addition to, compile-time conditionals.
 (menu_item_width, Fmenu_bar_menu_at_x_y): New functions.
 (Fx_popup_menu): Detect when the function is called from keyboard
 on a TTY.  Don't barf when invoked on a text-mode frame.  Check
 frame type at run time, instead of compile-time conditionals for
 invoking terminal-specific menu-show functions.  Call
 tty_menu_show on text-mode frames.
 (Fx_popup_dialog): Moved here from xmenu.c.  Test frame types at
 run time to determine which alternative to invoke; support dialogs
 on TTYs.
 src/keyboard.h <Qmouse_movement>: Declare.
 src/keyboard.c <Qmouse_movement>: Now extern.
 <Qecho_keystrokes>: New static variable.
 (read_key_sequence): Accept an additional argument, a flag to
 prevent redisplay during reading of the key sequence.  All callers
 changed.
 (read_menu_command): New function.
 (read_char): When COMMANDFLAG is -2, do not redisplay and do not
 autosave.
 (toolkit_menubar_in_use): New function.
 (make_lispy_event): Use it instead of a compile-time test.
 src/fns.c (Fyes_or_no_p) [HAVE_MENUS]: Don't condition on
 window-system being available.
 src/editfns.c (Fmessage_box) [HAVE_MENUS]: Don't condition the call
 to x-popup-dialog on the frame type, they all now support popup
 dialogs.
 src/dispnew.c (save_current_matrix): Save the margin areas.
 (restore_current_matrix): Restore margin areas.
 (update_frame_with_menu): New function.
 src/dispextern.h (display_tty_menu_item, update_frame_with_menu):
 Add prototypes.
 src/alloc.c (make_save_ptr): Now compiled unconditionally.
 
 lisp/tmm.el (tmm-menubar): Adapt doc string to TTY menus
 functionality.
 lisp/tooltip.el (tooltip-mode): Don't error out on TTYs.
 lisp/menu-bar.el (popup-menu, popup-menu-normalize-position): Moved
 here from mouse.el.
 (popup-menu): Support menu-bar navigation on TTYs using C-f/C-b
 and arrow keys.
 (tty-menu-navigation-map): New map for TTY menu navigation.
 lisp/loadup.el ("tooltip"): Load even if x-show-tip is not available.
 lisp/frame.el (display-mouse-p): Report text-mode mouse as available
 on w32.
 (display-popup-menus-p): Report availability if mouse is
 available; don't condition on window-system.
 lisp/faces.el (tty-menu-enabled-face, tty-menu-disabled-face)
 (tty-menu-selected-face): New faces.

 configure.ac (HAVE_MENUS): Define unconditionally.

 doc/emacs/screen.texi (Menu Bar): Adapt to TTY menus.
 doc/emacs/frames.texi (Frames): Mention menu support on text terminals.
 doc/emacs/files.texi (Visiting): Mention the "File" menu-bar menu.
 doc/emacs/display.texi (Standard Faces): Mention TTY faces for menus.
 
 doc/lispref/keymaps.texi (Defining Menus, Mouse Menus, Menu Bar): Modify
 wording to the effect that menus are supported on TTYs.
 doc/lisprefframes.texi (Pop-Up Menus, Dialog Boxes)
 (Display Feature Testing): Update for menu support on TTYs.

  etc/NEWS: Mention the new features.
parents 06286513 f3370a94
2013-10-08 Eli Zaretskii <eliz@gnu.org>
* configure.ac (HAVE_MENUS): Define unconditionally.
2013-10-07 Paul Eggert <eggert@cs.ucla.edu>
Improve support for popcount and counting trailing zeros (Bug#15550).
......
......@@ -1898,11 +1898,8 @@ to configure.])
fi
fi
### If we're using X11, we should use the X menu package.
HAVE_MENUS=no
case ${HAVE_X11} in
yes ) HAVE_MENUS=yes ;;
esac
### We always support menus.
HAVE_MENUS=yes
# Does the opsystem file prohibit the use of the GNU malloc?
# Assume not, until told otherwise.
......@@ -3183,15 +3180,9 @@ if test "${HAVE_NS}" = "yes"; then
## Extra CFLAGS applied to src/*.m files.
GNU_OBJC_CFLAGS="$GNU_OBJC_CFLAGS -fgnu-runtime -Wno-import -fconstant-string-class=NSConstantString -DGNUSTEP_BASE_LIBRARY=1 -DGNU_GUI_LIBRARY=1 -DGNU_RUNTIME=1 -DGSWARN -DGSDIAGNOSE"
fi
# We also have mouse menus.
HAVE_MENUS=yes
OTHER_FILES=ns-app
fi
if test "${HAVE_W32}" = "yes"; then
HAVE_MENUS=yes
fi
### Use session management (-lSM -lICE) if available
HAVE_X_SM=no
LIBXSM=
......@@ -4672,9 +4663,7 @@ AC_SUBST(OLDXMENU_DEPS)
if test "${HAVE_MENUS}" = "yes" ; then
AC_DEFINE(HAVE_MENUS, 1,
[Define to 1 if you have mouse menus.
(This is automatic if you use X, but the option to specify it remains.)
It is also defined with other window systems that support xmenu.c.])
[Define to 1 if you have mouse menus. (This is supported in all configurations, but the option to specify it remains.)])
fi
if test "${GNU_MALLOC}" = "yes" ; then
......
2013-10-08 Eli Zaretskii <eliz@gnu.org>
Support menus on text-mode terminals.
* screen.texi (Menu Bar): Adapt to TTY menus.
* frames.texi (Frames): Mention menu support on text terminals.
* files.texi (Visiting): Mention the "File" menu-bar menu.
* display.texi (Standard Faces): Mention TTY faces for menus.
2013-10-06 Xue Fuqiao <xfq.free@gmail.com>
* cal-xtra.texi (Calendar Customizing, Diary Display): Remove @refill.
......
......@@ -710,6 +710,17 @@ This face determines the color of tool bar icons. @xref{Tool Bars}.
@cindex customization of @code{menu} face
This face determines the colors and font of Emacs's menus. @xref{Menu
Bars}.
@item tty-menu-enabled-face
@cindex faces for text-mode menus
@cindex TTY menu faces
This face is used to display enabled menu items on text-mode
terminals.
@item tty-menu-disabled-face
This face is used to display disabled menu items on text-mode
terminals.
@item tty-menu-selected-face
This face is used to display on text-mode terminals the menu item that
would be selected if you click a mouse or press @key{RET}.
@end table
@node Text Scale
......
......@@ -286,6 +286,10 @@ exception, dropping a file into a window displaying a Dired buffer
moves or copies the file into the displayed directory. For details,
see @ref{Drag and Drop}, and @ref{Misc Dired Features}.
On text-mode terminals and on graphical displays when Emacs was
built without a GUI toolkit, you can visit files via the menu-bar
``File'' menu, which has a ``Visit New File'' item.
Each time you visit a file, Emacs automatically scans its contents
to detect what character encoding and end-of-line convention it uses,
and converts these to Emacs's internal encoding and end-of-line
......
......@@ -39,7 +39,7 @@ doing so on GNU and Unix systems; and
@ifnottex
@pxref{MS-DOS Mouse},
@end ifnottex
for doing so on MS-DOS).
for doing so on MS-DOS). Menus are supported on all text terminals.
@menu
* Mouse Commands:: Moving, cutting, and pasting, with the mouse.
......
......@@ -287,13 +287,12 @@ here, as you can more easily see them yourself.
@kindex M-`
@kindex F10
@findex tmm-menubar
@findex menu-bar-open
On a graphical display, you can use the mouse to choose a command
from the menu bar. An arrow on the right edge of a menu item means it
leads to a subsidiary menu, or @dfn{submenu}. A @samp{...} at the end
of a menu item means that the command will prompt you for further
input before it actually does anything.
On a display that support a mouse, you can use the mouse to choose a
command from the menu bar. An arrow on the right edge of a menu item
means it leads to a subsidiary menu, or @dfn{submenu}. A @samp{...}
at the end of a menu item means that the command will prompt you for
further input before it actually does anything.
Some of the commands in the menu bar have ordinary key bindings as
well; if so, a key binding is shown in parentheses after the item
......@@ -305,14 +304,20 @@ the usual way (@pxref{Key Help}).
item by pressing @key{F10} (to run the command @code{menu-bar-open}).
You can then navigate the menus with the arrow keys. To activate a
selected menu item, press @key{RET}; to cancel menu navigation, press
@key{ESC}.
On a text terminal, you can use the menu bar by typing @kbd{M-`} or
@key{F10} (these run the command @code{tmm-menubar}). This lets you
select a menu item with the keyboard. A provisional choice appears in
the echo area. You can use the up and down arrow keys to move through
the menu to different items, and then you can type @key{RET} to select
the item. Each menu item is also designated by a letter or digit
(usually the initial of some word in the item's name). This letter or
digit is separated from the item name by @samp{==>}. You can type the
item's letter or digit to select the item.
@kbd{C-g} or @kbd{ESC ESC ESC}.
@findex tmm-menubar
@vindex tty-menu-open-use-tmm
On a text terminal, you can optionally access the menu-bar menus in
the echo area. To this end, customize the variable
@code{tty-menu-open-use-tmm} to a non-@code{nil} value. Then typing
@key{F10} will run the command @code{tmm-menubar} instead of dropping
down the menu. (You can also type @kbd{M-`}, which always invokes
@code{tmm-menubar}.) @code{tmm-menubar} lets you select a menu item
with the keyboard. A provisional choice appears in the echo area.
You can use the up and down arrow keys to move through the menu to
different items, and then you can type @key{RET} to select the item.
Each menu item is also designated by a letter or digit (usually the
initial of some word in the item's name). This letter or digit is
separated from the item name by @samp{==>}. You can type the item's
letter or digit to select the item.
2013-10-08 Eli Zaretskii <eliz@gnu.org>
Support menus on text-mode terminals.
* keymaps.texi (Defining Menus, Mouse Menus, Menu Bar): Modify
wording to the effect that menus are supported on TTYs.
* frames.texi (Pop-Up Menus, Dialog Boxes)
(Display Feature Testing): Update for menu support on TTYs.
2013-10-07 Stefan Monnier <monnier@iro.umontreal.ca>
* tips.texi (Comment Tips): Discourage use of triple semi-colons for
......
......@@ -1741,8 +1741,10 @@ allows to know if the pointer has been hidden.
@node Pop-Up Menus
@section Pop-Up Menus
When using a window system, a Lisp program can pop up a menu so that
the user can choose an alternative with the mouse.
A Lisp program can pop up a menu so that the user can choose an
alternative with the mouse. On a text terminal, if the mouse is not
available, the user can choose an alternative using the keyboard
motion keys---@kbd{C-n}, @kbd{C-p}, or up- and down-arrow keys.
@defun x-popup-menu position menu
This function displays a pop-up menu and returns an indication of
......@@ -1763,20 +1765,22 @@ pixels, counting from the top left corner of @var{window}. @var{window}
may be a window or a frame.
If @var{position} is @code{t}, it means to use the current mouse
position. If @var{position} is @code{nil}, it means to precompute the
key binding equivalents for the keymaps specified in @var{menu},
without actually displaying or popping up the menu.
position (or the top-left corner of the frame if the mouse is not
available on a text terminal). If @var{position} is @code{nil}, it
means to precompute the key binding equivalents for the keymaps
specified in @var{menu}, without actually displaying or popping up the
menu.
The argument @var{menu} says what to display in the menu. It can be a
keymap or a list of keymaps (@pxref{Menu Keymaps}). In this case, the
return value is the list of events corresponding to the user's choice.
This list has more than one element if the choice occurred in a
submenu. (Note that @code{x-popup-menu} does not actually execute the
command bound to that sequence of events.) On toolkits that support
menu titles, the title is taken from the prompt string of @var{menu}
if @var{menu} is a keymap, or from the prompt string of the first
keymap in @var{menu} if it is a list of keymaps (@pxref{Defining
Menus}).
command bound to that sequence of events.) On text terminals and
toolkits that support menu titles, the title is taken from the prompt
string of @var{menu} if @var{menu} is a keymap, or from the prompt
string of the first keymap in @var{menu} if it is a list of keymaps
(@pxref{Defining Menus}).
Alternatively, @var{menu} can have the following form:
......@@ -1800,7 +1804,7 @@ cell; this makes a non-selectable menu item.
If the user gets rid of the menu without making a valid choice, for
instance by clicking the mouse away from a valid choice or by typing
keyboard input, then this normally results in a quit and
@kbd{C-g}, then this normally results in a quit and
@code{x-popup-menu} does not return. But if @var{position} is a mouse
button event (indicating that the user invoked the menu with the
mouse) then no quit occurs and @code{x-popup-menu} returns @code{nil}.
......@@ -1872,7 +1876,8 @@ window don't matter; only the frame matters.
If @var{header} is non-@code{nil}, the frame title for the box is
@samp{Information}, otherwise it is @samp{Question}. The former is used
for @code{message-box} (@pxref{message-box}).
for @code{message-box} (@pxref{message-box}). (On text terminals, the
box title is not displayed.)
In some configurations, Emacs cannot display a real dialog box; so
instead it displays the same items in a pop-up menu in the center of the
......@@ -2284,9 +2289,9 @@ obtain information about displays.
@defun display-popup-menus-p &optional display
This function returns @code{t} if popup menus are supported on
@var{display}, @code{nil} if not. Support for popup menus requires that
the mouse be available, since the user cannot choose menu items without
a mouse.
@var{display}, @code{nil} if not. Support for popup menus requires
that the mouse be available, since the menu is popped up by clicking
the mouse on some portion of the Emacs display.
@end defun
@defun display-graphic-p &optional display
......
......@@ -2023,7 +2023,7 @@ which is a string that appears as an element of the keymap.
the menu's commands. Emacs displays the overall prompt string as the
menu title in some cases, depending on the toolkit (if any) used for
displaying menus.@footnote{It is required for menus which do not use a
toolkit, e.g., under MS-DOS.} Keyboard menus also display the
toolkit, e.g., on a text terminal.} Keyboard menus also display the
overall prompt string.
The easiest way to construct a keymap with a prompt string is to
......@@ -2371,16 +2371,17 @@ if the menu keymap contains a single nested keymap and no other menu
items, the menu shows the contents of the nested keymap directly, not
as a submenu.
However, if Emacs is compiled without X toolkit support, submenus
are not supported. Each nested keymap is shown as a menu item, but
clicking on it does not automatically pop up the submenu. If you wish
to imitate the effect of submenus, you can do that by giving a nested
keymap an item string which starts with @samp{@@}. This causes Emacs
to display the nested keymap using a separate @dfn{menu pane}; the
rest of the item string after the @samp{@@} is the pane label. If
Emacs is compiled without X toolkit support, menu panes are not used;
in that case, a @samp{@@} at the beginning of an item string is
omitted when the menu label is displayed, and has no other effect.
However, if Emacs is compiled without X toolkit support, or on text
terminals, submenus are not supported. Each nested keymap is shown as
a menu item, but clicking on it does not automatically pop up the
submenu. If you wish to imitate the effect of submenus, you can do
that by giving a nested keymap an item string which starts with
@samp{@@}. This causes Emacs to display the nested keymap using a
separate @dfn{menu pane}; the rest of the item string after the
@samp{@@} is the pane label. If Emacs is compiled without X toolkit
support, or if a menu is displayed on a text terminal, menu panes are
not used; in that case, a @samp{@@} at the beginning of an item string
is omitted when the menu label is displayed, and has no other effect.
@node Keyboard Menus
@subsection Menus and the Keyboard
......@@ -2485,10 +2486,10 @@ can do it this way:
@subsection The Menu Bar
@cindex menu bar
On graphical displays, there is usually a @dfn{menu bar} at the top
of each frame. @xref{Menu Bars,,,emacs, The GNU Emacs Manual}. Menu
bar items are subcommands of the fake ``function key''
@code{menu-bar}, as defined in the active keymaps.
Emacs usually shows a @dfn{menu bar} at the top of each frame.
@xref{Menu Bars,,,emacs, The GNU Emacs Manual}. Menu bar items are
subcommands of the fake ``function key'' @code{menu-bar}, as defined
in the active keymaps.
To add an item to the menu bar, invent a fake ``function key'' of your
own (let's call it @var{key}), and make a binding for the key sequence
......@@ -2575,7 +2576,7 @@ in Documentation}.
A @dfn{tool bar} is a row of clickable icons at the top of a frame,
just below the menu bar. @xref{Tool Bars,,,emacs, The GNU Emacs
Manual}.
Manual}. Emacs normally shows a tool bar on graphical displays.
On each frame, the frame parameter @code{tool-bar-lines} controls
how many lines' worth of height to reserve for the tool bar. A zero
......
......@@ -65,6 +65,22 @@ To use the old backend by default, do on the command line:
* Changes in Emacs 24.4
+++
** Emacs now supports menus on text-mode terminals.
If the terminal supports a mouse, clicking on the menu bar, or on
sensitive portions of the mode line or header line, will drop down the
menu defined at that position. Likewise, clicking C-mouse-2 or
C-mouse-2 or C-mouse-3 on the text area will pop up the menus defined
for those locations.
If the text terminal does not support a mouse, you can activate the
first menu-bar menu by typing F10, which invokes `menu-bar-open'.
If you want the previous behavior, whereby F10 invoked `tmm-menubar',
customize the option `tty-menu-open-use-tmm' to a non-nil value.
(Typing M-` will always invoke `tmm-menubar', even if
`tty-menu-open-use-tmm' is nil.)
** Key ? also describes prefix bindings like C-h.
+++
......@@ -653,6 +669,16 @@ for something (not just adding elements to it), it ought not to affect you.
* Lisp Changes in Emacs 24.4
+++
** Functions that pop up menus and dialogs now work on all terminal types,
including TTYs.
This includes `x-popup-menu', `x-popup-dialog', `message-box',
`yes-or-no-p', etc.
The function `display-popup-menus-p' will now return non-nil for a
display or frame whenever a mouse is supported on that display or
frame.
** New bool-vector set operation functions:
*** `bool-vector-exclusive-or'
*** `bool-vector-union'
......
2013-10-08 Eli Zaretskii <eliz@gnu.org>
Support menus on text-mode terminals.
* tmm.el (tmm-menubar): Adapt doc string to TTY menus
functionality.
* tooltip.el (tooltip-mode): Don't error out on TTYs.
* menu-bar.el (popup-menu, popup-menu-normalize-position): Moved
here from mouse.el.
(popup-menu): Support menu-bar navigation on TTYs using C-f/C-b
and arrow keys.
(tty-menu-navigation-map): New map for TTY menu navigation.
* loadup.el ("tooltip"): Load even if x-show-tip is not available.
* frame.el (display-mouse-p): Report text-mode mouse as available
on w32.
(display-popup-menus-p): Report availability if mouse is
available; don't condition on window-system.
* faces.el (tty-menu-enabled-face, tty-menu-disabled-face)
(tty-menu-selected-face): New faces.
2013-10-08 Stefan Monnier <monnier@iro.umontreal.ca>
* emacs-lisp/lisp-mode.el: Font-lock cl-lib constructs.
......
......@@ -2142,7 +2142,6 @@ terminal type to a different value."
(frame-set-background-mode frame t)
(face-set-after-frame-default frame)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Standard faces.
......@@ -2551,6 +2550,26 @@ It is used for characters of no fonts too."
:version "24.1"
:group 'basic-faces)
;; Faces for TTY menus.
(defface tty-menu-enabled-face
'((t
:foreground "yellow" :background "blue" :weight bold))
"Face for displaying enabled items in TTY menus."
:group 'basic-faces)
(defface tty-menu-disabled-face
'((((class color) (min-colors 16))
:foreground "lightgray" :background "blue")
(t
:foreground "white" :background "blue"))
"Face for displaying disabled items in TTY menus."
:group 'basic-faces)
(defface tty-menu-selected-face
'((t :background "red"))
"Face for displaying the currently selected item in TTY menus."
:group 'basic-faces)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Manipulating font names.
......
......@@ -1304,17 +1304,17 @@ frame's display)."
xterm-mouse-mode)
;; t-mouse is distributed with the GPM package. It doesn't have
;; a toggle.
(featurep 't-mouse))))))
(featurep 't-mouse)
;; No way to check whether a w32 console has a mouse, assume
;; it always does.
(boundp 'w32-use-full-screen-buffer))))))
(defun display-popup-menus-p (&optional display)
"Return non-nil if popup menus are supported on DISPLAY.
DISPLAY can be a display name, a frame, or nil (meaning the selected
frame's display).
Support for popup menus requires that the mouse be available."
(and
(let ((frame-type (framep-on-display display)))
(memq frame-type '(x w32 pc ns)))
(display-mouse-p display)))
(display-mouse-p display))
(defun display-graphic-p (&optional display)
"Return non-nil if DISPLAY is a graphic display.
......
......@@ -276,7 +276,7 @@
(load "vc/vc-hooks")
(load "vc/ediff-hook")
(if (fboundp 'x-show-tip) (load "tooltip"))
(if (not (eq system-type 'ms-dos)) (load "tooltip"))
;If you want additional libraries to be preloaded and their
;doc strings kept in the DOC file rather than in core,
......
......@@ -2182,13 +2182,211 @@ See `menu-bar-mode' for more information."
(declare-function x-menu-bar-open "term/x-win" (&optional frame))
(declare-function w32-menu-bar-open "term/w32-win" (&optional frame))
(defun popup-menu (menu &optional position prefix from-menu-bar)
"Popup the given menu and call the selected option.
MENU can be a keymap, an easymenu-style menu or a list of keymaps as for
`x-popup-menu'.
The menu is shown at the place where POSITION specifies. About
the form of POSITION, see `popup-menu-normalize-position'.
PREFIX is the prefix argument (if any) to pass to the command.
FROM-MENU-BAR, if non-nil, means we are dropping one of menu-bar's menus."
(let* ((map (cond
((keymapp menu) menu)
((and (listp menu) (keymapp (car menu))) menu)
(t (let* ((map (easy-menu-create-menu (car menu) (cdr menu)))
(filter (when (symbolp map)
(plist-get (get map 'menu-prop) :filter))))
(if filter (funcall filter (symbol-function map)) map)))))
(frame (selected-frame))
event cmd)
(if from-menu-bar
(let* ((xy (posn-x-y position))
(menu-symbol (menu-bar-menu-at-x-y (car xy) (cdr xy))))
(setq position (list menu-symbol (list frame '(menu-bar)
xy 0))))
(setq position (popup-menu-normalize-position position)))
;; The looping behavior was taken from lmenu's popup-menu-popup
(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)))
(setq cmd
(cond
((and from-menu-bar
(consp event)
(numberp (car event))
(numberp (cdr event)))
(let ((x (car event))
(y (cdr event))
menu-symbol)
(setq menu-symbol (menu-bar-menu-at-x-y x y))
(setq position (list menu-symbol (list frame '(menu-bar)
event 0)))
(setq map
(or
(lookup-key global-map (vector 'menu-bar menu-symbol))
(lookup-key (current-local-map) (vector 'menu-bar
menu-symbol))))))
((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))
(t
;; We were given a single keymap.
(lookup-key map (apply 'vector event)))))
;; Clear out echoing, which perhaps shows a prefix arg.
(message "")
;; Maybe try again but with the submap.
(setq map (if (keymapp cmd) cmd)))
;; If the user did not cancel by refusing to select,
;; and if the result is a command, run it.
(when (and (null map) (commandp 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))))
(defun popup-menu-normalize-position (position)
"Convert the POSITION to the form which `popup-menu' expects internally.
POSITION can an event, a posn- value, a value having
form ((XOFFSET YOFFSET) WINDOW), or nil.
If nil, the current mouse position is used."
(pcase position
;; nil -> mouse cursor position
(`nil
(let ((mp (mouse-pixel-position)))
(list (list (cadr mp) (cddr mp)) (car mp))))
;; Value returned from `event-end' or `posn-at-point'.
((pred posnp)
(let ((xy (posn-x-y position)))
(list (list (car xy) (cdr xy))
(posn-window position))))
;; Event.
((pred eventp)
(popup-menu-normalize-position (event-end position)))
(t position)))
(defvar tty-menu-navigation-map
(let ((map (make-sparse-keymap)))
;; The next line is disabled because it breaks interpretation of
;; escape sequences, produced by TTY arrow keys, as tty-menu-*
;; commands. Instead, we explicitly bind some keys to
;; tty-menu-exit.
;;(define-key map [t] 'tty-menu-exit)
;; The tty-menu-* are just symbols interpreted by term.c, they are
;; not real commands.
(substitute-key-definition 'keyboard-quit 'tty-menu-exit
map (current-global-map))
(substitute-key-definition 'keyboard-escape-quit 'tty-menu-exit
map (current-global-map))
;; The bindings of menu-bar items are so that clicking on the menu
;; bar when a menu is already shown pops down that menu.
;; FIXME: we should iterate over all the visible menu-bar items,
;; instead of naming them explicitly here. Also, this doesn't
;; include items added by current major mode.
(substitute-key-definition (lookup-key (current-global-map) [menu-bar file])
'tty-menu-exit
map (current-global-map))
(substitute-key-definition (lookup-key (current-global-map) [menu-bar edit])
'tty-menu-exit
map (current-global-map))
(substitute-key-definition (lookup-key (current-global-map) [menu-bar options])
'tty-menu-exit
map (current-global-map))
(substitute-key-definition (lookup-key (current-global-map) [menu-bar buffer])
'tty-menu-exit
map (current-global-map))
(substitute-key-definition (lookup-key (current-global-map) [menu-bar tools])
'tty-menu-exit
map (current-global-map))
(substitute-key-definition (lookup-key (current-global-map) [menu-bar help-menu])
'tty-menu-exit
map (current-global-map))
(substitute-key-definition 'forward-char 'tty-menu-next-menu
map (current-global-map))
(substitute-key-definition 'backward-char 'tty-menu-prev-menu
map (current-global-map))
;; The following two will need to be revised if we ever support
;; a right-to-left menu bar.
(substitute-key-definition 'right-char 'tty-menu-next-menu
map (current-global-map))
(substitute-key-definition 'left-char 'tty-menu-prev-menu
map (current-global-map))
(substitute-key-definition 'next-line 'tty-menu-next-item
map (current-global-map))
(substitute-key-definition 'previous-line 'tty-menu-prev-item
map (current-global-map))
(substitute-key-definition 'newline 'tty-menu-select
map (current-global-map))
(substitute-key-definition 'newline-and-indent 'tty-menu-select
map (current-global-map))
(define-key map [?\C-r] 'tty-menu-select)
(define-key map [?\C-j] 'tty-menu-select)
(define-key map [return] 'tty-menu-select)
(define-key map [linefeed] 'tty-menu-select)
(define-key map [down-mouse-1] 'tty-menu-select)
(define-key map [drag-mouse-1] 'tty-menu-select)
(define-key map [mode-line drag-mouse-1] 'tty-menu-select)
(define-key map [mode-line down-mouse-1] 'tty-menu-select)
(define-key map [header-line mouse-1] 'tty-menu-select)
(define-key map [header-line drag-mouse-1] 'tty-menu-select)
(define-key map [header-line down-mouse-1] 'tty-menu-select)
(define-key map [mode-line mouse-1] 'tty-menu-ignore)
(define-key map [mode-line mouse-2] 'tty-menu-ignore)
(define-key map [mode-line mouse-3] 'tty-menu-ignore)
(define-key map [mode-line C-mouse-1] 'tty-menu-ignore)
(define-key map [mode-line C-mouse-2] 'tty-menu-ignore)
(define-key map [mode-line C-mouse-3] 'tty-menu-ignore)
;; The mouse events must be bound to tty-menu-ignore, otherwise
;; the initial mouse click will select and immediately pop down
;; the menu.
(define-key map [mouse-1] 'tty-menu-ignore)
(define-key map [C-mouse-1] 'tty-menu-ignore)
(define-key map [C-mouse-2] 'tty-menu-ignore)
(define-key map [C-mouse-3] 'tty-menu-ignore)
(define-key map [mouse-movement] 'tty-menu-mouse-movement)
map)
"Keymap used while processing TTY menus.")