30.17 弹出菜单

Lisp 程序可以弹出菜单,让用户使用鼠标选择选项。在文本终端上,若鼠标不可用,用户可使用键盘移动键——C-nC-p 或上下方向键进行选择。

Function: x-popup-menu position menu

该函数显示一个弹出菜单,并返回用户的选择结果。

参数 position 指定菜单左上角在屏幕上的显示位置。它可以是一个鼠标按键事件或 touchscreen-begin 事件(表示在用户触发按键的位置显示菜单),或是如下形式的列表:

((xoffset yoffset) window)

其中 xoffsetyoffset 为像素坐标,从 window 的左上角开始计算。window 可以是窗口或框架。

positiont,表示使用当前鼠标位置(文本终端上无鼠标时使用框架左上角)。若 positionnil,表示仅预计算 menu 中指定 keymap 对应的按键绑定等价项,而不实际显示或弹出菜单。

参数 menu 指定菜单中显示的内容。它可以是一个 keymap 或 keymap 列表 (see 菜单按键映射)。这种情况下返回值为对应用户选择的事件列表。若选择发生在子菜单中,该列表将包含多个元素。(注意 x-popup-menu 并不会实际执行绑定到该事件序列的命令。)在支持菜单标题的文本终端与工具包上,若 menu 为 keymap,则标题取自其提示字符串;若为 keymap 列表,则取自第一个 keymap 的提示字符串 (see 定义菜单)。

另外,menu 也可以使用如下格式:

(title pane1 pane2...)

where each pane is a list of form

(title item1 item2...)

每个 item 应为一个 cons 单元格 (line . value),其中 line 为字符串,value 为选中该行时返回的值。与菜单 keymap 不同,nil 类型的 value 并不会使菜单项不可选。 此外,每个 item 也可以直接是字符串而非 cons 单元格,这会创建一个不可选的菜单项。

若用户未做出有效选择便关闭菜单,例如点击有效选项外的区域或按下 C-g,通常会触发退出,x-popup-menu 不会返回。但如果 position 是一个鼠标按键事件(表示用户通过鼠标触发菜单),则不会退出,且 x-popup-menu 返回 nil

使用注意:如果可以通过带有菜单 keymap 的前缀按键实现功能,就不要使用 x-popup-menu 显示菜单。 若使用菜单 keymap 实现菜单,C-h cC-h a 可以识别菜单中的各个项并提供对应帮助。 反之,若通过定义调用 x-popup-menu 的命令实现菜单,帮助系统无法获知该命令内部逻辑,因此无法为菜单项提供帮助。

允许通过移动鼠标在子菜单间切换的菜单栏机制,无法深入命令定义内部识别其调用了 x-popup-menu。 因此,若尝试使用 x-popup-menu 实现子菜单,将无法与菜单栏无缝协同工作。 这也是所有菜单栏子菜单都通过父菜单内的菜单 keymap 实现,而非使用 x-popup-menu 的原因。See 菜单栏.

若你希望菜单栏子菜单的内容可动态变化,仍应使用菜单 keymap 实现。 可通过向 menu-bar-update-hook 添加钩子函数,按需更新菜单 keymap 内容。

Variable: x-pre-popup-menu-hook

一个普通钩子,在弹出菜单即将显示时运行,无论是直接调用 x-popup-menu 还是通过菜单 keymap 触发。 若 x-popup-menu 因其他原因未显示菜单就返回,则不会运行该钩子。