Mercurial > hg > xemacs-beta
annotate src/menubar.c @ 5923:61d7d7bcbe76 cygwin
merged heads after pull -u
author | Henry Thompson <ht@markup.co.uk> |
---|---|
date | Thu, 05 Feb 2015 17:19:05 +0000 |
parents | 68f8d295be49 |
children |
rev | line source |
---|---|
428 | 1 /* Implements an elisp-programmable menubar. |
2 Copyright (C) 1993, 1994 Free Software Foundation, Inc. | |
3 Copyright (C) 1995 Tinker Systems and INS Engineering Corp. | |
3025 | 4 Copyright (C) 2001, 2002, 2003, 2005 Ben Wing. |
428 | 5 |
6 This file is part of XEmacs. | |
7 | |
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
4952
diff
changeset
|
8 XEmacs is free software: you can redistribute it and/or modify it |
428 | 9 under the terms of the GNU General Public License as published by the |
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
4952
diff
changeset
|
10 Free Software Foundation, either version 3 of the License, or (at your |
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
4952
diff
changeset
|
11 option) any later version. |
428 | 12 |
13 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 for more details. | |
17 | |
18 You should have received a copy of the GNU General Public License | |
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
4952
diff
changeset
|
19 along with XEmacs. If not, see <http://www.gnu.org/licenses/>. */ |
428 | 20 |
21 /* Synched up with: Not in FSF. */ | |
22 | |
442 | 23 /* Authorship: |
24 | |
25 Created by Ben Wing as part of device-abstraction work for 19.12. | |
26 Menu filters and many other keywords added by Stig for 19.12. | |
27 Menu accelerators c. 1997? by ??. Moved here from event-stream.c. | |
28 Much other work post-1996 by ??. | |
29 */ | |
428 | 30 |
31 #include <config.h> | |
32 #include "lisp.h" | |
33 | |
34 #include "buffer.h" | |
872 | 35 #include "device-impl.h" |
36 #include "frame-impl.h" | |
428 | 37 #include "gui.h" |
442 | 38 #include "keymap.h" |
428 | 39 #include "menubar.h" |
40 #include "redisplay.h" | |
800 | 41 #include "specifier.h" |
872 | 42 #include "window-impl.h" |
428 | 43 |
44 int menubar_show_keybindings; | |
45 Lisp_Object Vmenubar_configuration; | |
46 | |
47 Lisp_Object Qcurrent_menubar; | |
48 | |
49 Lisp_Object Qactivate_menubar_hook, Vactivate_menubar_hook; | |
50 | |
51 Lisp_Object Vmenubar_visible_p; | |
52 | |
53 static Lisp_Object Vcurrent_menubar; /* DO NOT ever reference this. | |
54 Always go through Qcurrent_menubar. | |
55 See below. */ | |
56 | |
57 Lisp_Object Vblank_menubar; | |
58 | |
59 int popup_menu_titles; | |
1279 | 60 int in_menu_callback; |
428 | 61 |
62 Lisp_Object Vmenubar_pointer_glyph; | |
63 | |
442 | 64 /* prefix key(s) that must match in order to activate menu. |
65 This is ugly. fix me. | |
66 */ | |
67 Lisp_Object Vmenu_accelerator_prefix; | |
68 | |
69 /* list of modifier keys to match accelerator for top level menus */ | |
70 Lisp_Object Vmenu_accelerator_modifiers; | |
71 | |
72 /* whether menu accelerators are enabled */ | |
73 Lisp_Object Vmenu_accelerator_enabled; | |
74 | |
75 /* keymap for auxiliary menu accelerator functions */ | |
76 Lisp_Object Vmenu_accelerator_map; | |
77 | |
78 Lisp_Object Qmenu_force; | |
79 Lisp_Object Qmenu_fallback; | |
80 Lisp_Object Qmenu_quit; | |
81 Lisp_Object Qmenu_up; | |
82 Lisp_Object Qmenu_down; | |
83 Lisp_Object Qmenu_left; | |
84 Lisp_Object Qmenu_right; | |
85 Lisp_Object Qmenu_select; | |
86 Lisp_Object Qmenu_escape; | |
87 | |
428 | 88 static int |
2286 | 89 menubar_variable_changed (Lisp_Object UNUSED (sym), Lisp_Object *UNUSED (val), |
90 Lisp_Object UNUSED (in_object), int UNUSED (flags)) | |
428 | 91 { |
92 MARK_MENUBAR_CHANGED; | |
93 return 0; | |
94 } | |
95 | |
96 void | |
97 update_frame_menubars (struct frame *f) | |
98 { | |
99 if (f->menubar_changed || f->windows_changed) | |
100 MAYBE_FRAMEMETH (f, update_frame_menubars, (f)); | |
101 | |
102 f->menubar_changed = 0; | |
103 } | |
104 | |
105 void | |
106 free_frame_menubars (struct frame *f) | |
107 { | |
108 /* If we had directly allocated any memory for the menubars instead | |
109 of using all Lisp_Objects this is where we would now free it. */ | |
110 | |
111 MAYBE_FRAMEMETH (f, free_frame_menubars, (f)); | |
112 } | |
113 | |
114 static void | |
2286 | 115 menubar_visible_p_changed (Lisp_Object UNUSED (specifier), |
116 struct window *UNUSED (w), | |
117 Lisp_Object UNUSED (oldval)) | |
428 | 118 { |
119 MARK_MENUBAR_CHANGED; | |
120 } | |
121 | |
122 static void | |
2286 | 123 menubar_visible_p_changed_in_frame (Lisp_Object UNUSED (specifier), |
124 struct frame *f, | |
125 Lisp_Object UNUSED (oldval)) | |
428 | 126 { |
127 update_frame_menubars (f); | |
128 } | |
129 | |
130 Lisp_Object | |
442 | 131 current_frame_menubar (const struct frame* f) |
428 | 132 { |
133 struct window *w = XWINDOW (FRAME_LAST_NONMINIBUF_WINDOW (f)); | |
134 return symbol_value_in_buffer (Qcurrent_menubar, w->buffer); | |
135 } | |
136 | |
137 Lisp_Object | |
138 menu_parse_submenu_keywords (Lisp_Object desc, Lisp_Object gui_item) | |
139 { | |
442 | 140 Lisp_Gui_Item *pgui_item = XGUI_ITEM (gui_item); |
428 | 141 |
142 /* Menu descriptor should be a list */ | |
143 CHECK_CONS (desc); | |
144 | |
145 /* First element may be menu name, although can be omitted. | |
146 Let's think that if stuff begins with anything than a keyword | |
147 or a list (submenu), this is a menu name, expected to be a string */ | |
148 if (!KEYWORDP (XCAR (desc)) && !CONSP (XCAR (desc))) | |
149 { | |
150 CHECK_STRING (XCAR (desc)); | |
151 pgui_item->name = XCAR (desc); | |
152 desc = XCDR (desc); | |
153 if (!NILP (desc)) | |
154 CHECK_CONS (desc); | |
155 } | |
156 | |
157 /* Walk along all key-value pairs */ | |
158 while (!NILP(desc) && KEYWORDP (XCAR (desc))) | |
159 { | |
160 Lisp_Object key, val; | |
161 key = XCAR (desc); | |
162 desc = XCDR (desc); | |
163 CHECK_CONS (desc); | |
164 val = XCAR (desc); | |
165 desc = XCDR (desc); | |
166 if (!NILP (desc)) | |
167 CHECK_CONS (desc); | |
168 gui_item_add_keyval_pair (gui_item, key, val, ERROR_ME); | |
169 } | |
170 | |
171 /* Return the rest - supposed to be a list of items */ | |
172 return desc; | |
173 } | |
174 | |
175 DEFUN ("menu-find-real-submenu", Fmenu_find_real_submenu, 2, 2, 0, /* | |
176 Find a submenu descriptor within DESC by following PATH. | |
177 This function finds a submenu descriptor, either from the description | |
178 DESC or generated by a filter within DESC. The function regards :config | |
179 and :included keywords in the DESC, and expands submenus along the | |
180 PATH using :filter functions. Return value is a descriptor for the | |
181 submenu, NOT expanded and NOT checked against :config and :included. | |
182 Also, individual menu items are not looked for, only submenus. | |
183 | |
184 See also 'find-menu-item'. | |
185 */ | |
186 (desc, path)) | |
187 { | |
442 | 188 struct gcpro gcpro1, gcpro2; |
428 | 189 Lisp_Object gui_item = allocate_gui_item (); |
440 | 190 Lisp_Gui_Item* pgui_item = XGUI_ITEM (gui_item); |
428 | 191 |
442 | 192 GCPRO2 (gui_item, desc); |
428 | 193 |
2367 | 194 { |
195 EXTERNAL_LIST_LOOP_2 (elt, path) | |
196 { | |
197 /* Verify that DESC describes a menu, not single item */ | |
198 if (!CONSP (desc)) | |
199 RETURN_UNGCPRO (Qnil); | |
200 | |
201 /* Parse this menu */ | |
202 desc = menu_parse_submenu_keywords (desc, gui_item); | |
203 | |
204 /* Check that this (sub)menu is active */ | |
205 if (!gui_item_active_p (gui_item)) | |
206 RETURN_UNGCPRO (Qnil); | |
428 | 207 |
2367 | 208 /* Apply :filter */ |
209 if (!NILP (pgui_item->filter)) | |
210 desc = call1 (pgui_item->filter, desc); | |
428 | 211 |
2367 | 212 /* Find the next menu on the path inside this one */ |
213 { | |
214 EXTERNAL_LIST_LOOP_2 (submenu, desc) | |
215 { | |
216 if (CONSP (submenu) | |
217 && STRINGP (XCAR (submenu)) | |
218 && !NILP (Fstring_equal (XCAR (submenu), elt))) | |
219 { | |
220 desc = submenu; | |
221 goto descend; | |
222 } | |
223 } | |
224 } | |
225 /* Submenu not found */ | |
428 | 226 RETURN_UNGCPRO (Qnil); |
227 | |
2367 | 228 descend: |
229 /* Prepare for the next iteration */ | |
230 gui_item_init (gui_item); | |
231 } | |
232 } | |
428 | 233 |
234 /* We have successfully descended down the end of the path */ | |
235 UNGCPRO; | |
236 return desc; | |
237 } | |
238 | |
239 DEFUN ("popup-menu", Fpopup_menu, 1, 2, 0, /* | |
444 | 240 Pop up the menu described by MENU-DESCRIPTION. |
428 | 241 A menu description is a list of menu items, strings, and submenus. |
242 | |
243 The first element of a menu must be a string, which is the name of the menu. | |
244 This is the string that will be displayed in the parent menu, if any. For | |
245 toplevel menus, it is ignored. This string is not displayed in the menu | |
246 itself. | |
247 | |
248 If an element of a menu is a string, then that string will be presented in | |
249 the menu as unselectable text. | |
250 | |
251 If an element of a menu is a string consisting solely of hyphens, then that | |
252 item will be presented as a solid horizontal line. | |
253 | |
254 If an element of a menu is a list, it is treated as a submenu. The name of | |
255 that submenu (the first element in the list) will be used as the name of the | |
256 item representing this menu on the parent. | |
257 | |
258 Otherwise, the element must be a vector, which describes a menu item. | |
259 A menu item can have any of the following forms: | |
260 | |
261 [ "name" callback <active-p> ] | |
262 [ "name" callback <active-p> <suffix> ] | |
263 [ "name" callback :<keyword> <value> :<keyword> <value> ... ] | |
264 | |
265 The name is the string to display on the menu; it is filtered through the | |
266 resource database, so it is possible for resources to override what string | |
267 is actually displayed. | |
268 | |
269 If the `callback' of a menu item is a symbol, then it must name a command. | |
270 It will be invoked with `call-interactively'. If it is a list, then it is | |
271 evaluated with `eval'. | |
272 | |
273 The possible keywords are this: | |
274 | |
275 :active <form> Same as <active-p> in the first two forms: the | |
276 expression is evaluated just before the menu is | |
277 displayed, and the menu will be selectable only if | |
278 the result is non-nil. | |
279 | |
280 :suffix <form> Same as <suffix> in the second form: the expression | |
281 is evaluated just before the menu is displayed and | |
282 resulting string is appended to the displayed name, | |
283 providing a convenient way of adding the name of a | |
284 command's ``argument'' to the menu, like | |
285 ``Kill Buffer NAME''. | |
286 | |
287 :keys "string" Normally, the keyboard equivalents of commands in | |
288 menus are displayed when the `callback' is a symbol. | |
289 This can be used to specify keys for more complex menu | |
290 items. It is passed through `substitute-command-keys' | |
291 first. | |
292 | |
293 :style <style> Specifies what kind of object this menu item is: | |
294 | |
295 nil A normal menu item. | |
296 toggle A toggle button. | |
297 radio A radio button. | |
298 | |
299 The only difference between toggle and radio buttons is | |
300 how they are displayed. But for consistency, a toggle | |
301 button should be used when there is one option whose | |
302 value can be turned on or off, and radio buttons should | |
303 be used when there is a set of mutually exclusive | |
304 options. When using a group of radio buttons, you | |
305 should arrange for no more than one to be marked as | |
306 selected at a time. | |
307 | |
308 :selected <form> Meaningful only when STYLE is `toggle' or `radio'. | |
309 This specifies whether the button will be in the | |
310 selected or unselected state. | |
311 | |
312 For example: | |
313 | |
314 [ "Save As..." write-file t ] | |
315 [ "Revert Buffer" revert-buffer (buffer-modified-p) ] | |
316 [ "Read Only" toggle-read-only :style toggle :selected buffer-read-only ] | |
317 | |
318 See menubar.el for many more examples. | |
319 */ | |
444 | 320 (menu_description, event)) |
428 | 321 { |
444 | 322 struct frame *f = decode_frame (Qnil); |
323 MAYBE_FRAMEMETH (f, popup_menu, (menu_description, event)); | |
428 | 324 return Qnil; |
325 } | |
326 | |
2545 | 327 DEFUN ("compare-menu-text", Fcompare_menu_text, 2, 2, 0, /* |
328 Compare the text of two menu items, ignoring accelerator specs and case. | |
329 Also treat %% as a single %. Return < 0 if STRING1 is less than STRING2, | |
330 0 if equal, > 0 if STRING1 is greater than STRING2. | |
331 */ | |
332 (string1, string2)) | |
333 { | |
334 Ibyte *p; | |
335 Ibyte *q; | |
336 | |
337 CHECK_STRING (string1); | |
338 CHECK_STRING (string2); | |
339 | |
340 p = XSTRING_DATA (string1); | |
341 q = XSTRING_DATA (string2); | |
342 | |
343 for (;;) | |
344 { | |
345 Ichar val; | |
346 if (*p == '%' && *(p + 1) == '%') | |
347 p++; | |
348 else if (*p == '%' && *(p + 1) == '_') | |
349 p += 2; | |
350 if (*q == '%' && *(q + 1) == '%') | |
351 q++; | |
352 else if (*q == '%' && *(q + 1) == '_') | |
353 q += 2; | |
354 if (!*p || !*q) | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5402
diff
changeset
|
355 return make_fixnum (*p - *q); |
2545 | 356 val = DOWNCASE (0, itext_ichar (p)) - DOWNCASE (0, itext_ichar (q)); |
357 if (val) | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5402
diff
changeset
|
358 return make_fixnum (val); |
2545 | 359 INC_IBYTEPTR (p); |
360 INC_IBYTEPTR (q); | |
361 } | |
362 } | |
363 | |
364 DEFUN ("normalize-menu-text", Fnormalize_menu_text, 1, 1, 0, /* | |
428 | 365 Convert a menu item name string into normal form, and return the new string. |
366 Menu item names should be converted to normal form before being compared. | |
442 | 367 This removes %_'s (accelerator indications) and converts %% to %. |
2545 | 368 The returned string may be the same string as the original. |
428 | 369 */ |
2545 | 370 (name)) |
428 | 371 { |
372 Charcount end; | |
373 int i; | |
867 | 374 Ibyte *name_data; |
375 Ibyte *string_result; | |
376 Ibyte *string_result_ptr; | |
377 Ichar elt; | |
428 | 378 int expecting_underscore = 0; |
379 | |
380 CHECK_STRING (name); | |
381 | |
826 | 382 end = string_char_length (name); |
793 | 383 name_data = XSTRING_DATA (name); |
428 | 384 |
2367 | 385 string_result = alloca_ibytes (end * MAX_ICHAR_LEN); |
428 | 386 string_result_ptr = string_result; |
387 for (i = 0; i < end; i++) | |
388 { | |
867 | 389 elt = itext_ichar (name_data); |
428 | 390 if (expecting_underscore) |
391 { | |
392 expecting_underscore = 0; | |
393 switch (elt) | |
394 { | |
395 case '%': | |
396 /* Allow `%%' to mean `%'. */ | |
867 | 397 string_result_ptr += set_itext_ichar (string_result_ptr, '%'); |
428 | 398 break; |
399 case '_': | |
400 break; | |
401 default: | |
867 | 402 string_result_ptr += set_itext_ichar (string_result_ptr, '%'); |
403 string_result_ptr += set_itext_ichar (string_result_ptr, elt); | |
428 | 404 } |
405 } | |
406 else if (elt == '%') | |
407 expecting_underscore = 1; | |
408 else | |
867 | 409 string_result_ptr += set_itext_ichar (string_result_ptr, elt); |
410 INC_IBYTEPTR (name_data); | |
428 | 411 } |
412 | |
442 | 413 if (string_result_ptr - string_result == XSTRING_LENGTH (name) |
414 && !memcmp (string_result, XSTRING_DATA (name), XSTRING_LENGTH (name))) | |
415 return name; | |
416 | |
428 | 417 return make_string (string_result, string_result_ptr - string_result); |
418 } | |
419 | |
420 void | |
421 syms_of_menubar (void) | |
422 { | |
563 | 423 DEFSYMBOL (Qcurrent_menubar); |
442 | 424 |
563 | 425 DEFSYMBOL (Qmenu_force); |
426 DEFSYMBOL (Qmenu_fallback); | |
442 | 427 |
563 | 428 DEFSYMBOL (Qmenu_quit); |
429 DEFSYMBOL (Qmenu_up); | |
430 DEFSYMBOL (Qmenu_down); | |
431 DEFSYMBOL (Qmenu_left); | |
432 DEFSYMBOL (Qmenu_right); | |
433 DEFSYMBOL (Qmenu_select); | |
434 DEFSYMBOL (Qmenu_escape); | |
442 | 435 |
428 | 436 DEFSUBR (Fpopup_menu); |
2545 | 437 DEFSUBR (Fcompare_menu_text); |
438 DEFSUBR (Fnormalize_menu_text); | |
428 | 439 DEFSUBR (Fmenu_find_real_submenu); |
440 } | |
441 | |
442 void | |
443 vars_of_menubar (void) | |
444 { | |
440 | 445 /* put in Vblank_menubar a menubar value which has no visible |
446 * items. This is a bit tricky due to various quirks. We | |
447 * could use '(["" nil nil]), but this is apparently equivalent | |
448 * to '(nil), and a new frame created with this menubar will | |
449 * get a vertically-squished menubar. If we use " " as the | |
450 * button title instead of "", we get an etched button border. | |
451 * So we use | |
452 * '(("No active menubar" ["" nil nil])) | |
453 * which creates a menu whose title is "No active menubar", | |
454 * and this works fine. | |
455 */ | |
428 | 456 |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
3025
diff
changeset
|
457 Vblank_menubar = list1 (list2 (build_defer_string ("No active menubar"), |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
3025
diff
changeset
|
458 vector3 (build_ascstring (""), Qnil, Qnil))); |
440 | 459 staticpro (&Vblank_menubar); |
428 | 460 |
461 DEFVAR_BOOL ("popup-menu-titles", &popup_menu_titles /* | |
462 If true, popup menus will have title bars at the top. | |
463 */ ); | |
464 popup_menu_titles = 1; | |
465 | |
466 /* #### Replace current menubar with a specifier. */ | |
467 | |
468 /* All C code must access the menubar via Qcurrent_menubar | |
469 because it can be buffer-local. Note that Vcurrent_menubar | |
470 doesn't need to exist at all, except for the magic function. */ | |
471 | |
472 DEFVAR_LISP_MAGIC ("current-menubar", &Vcurrent_menubar /* | |
473 The current menubar. This may be buffer-local. | |
474 | |
475 When the menubar is changed, the function `set-menubar-dirty-flag' has to | |
476 be called for the menubar to be updated on the frame. See `set-menubar' | |
477 and `set-buffer-menubar'. | |
478 | |
479 A menubar is a list of menus and menu-items. | |
480 A menu is a list of menu items, keyword-value pairs, strings, and submenus. | |
481 | |
482 The first element of a menu must be a string, which is the name of the menu. | |
483 This is the string that will be displayed in the parent menu, if any. For | |
484 toplevel menus, it is ignored. This string is not displayed in the menu | |
485 itself. | |
486 | |
442 | 487 Menu accelerators can be indicated in the string by putting the |
488 sequence "%_" before the character corresponding to the key that will | |
489 invoke the menu or menu item. Uppercase and lowercase accelerators | |
490 are equivalent. The sequence "%%" is also special, and is translated | |
491 into a single %. | |
492 | |
493 If no menu accelerator is present in the string, XEmacs will act as if | |
494 the first character has been tagged as an accelerator. | |
495 | |
496 Immediately following the name string of the menu, various optional | |
497 keyword-value pairs are permitted: currently, :filter, :active, :included, | |
5715
68f8d295be49
Support :visible in menu specifications.
Jerry James <james@xemacs.org>
parents:
5581
diff
changeset
|
498 :visible, and :config. (See below.) |
428 | 499 |
500 If an element of a menu (or menubar) is a string, then that string will be | |
501 presented as unselectable text. | |
502 | |
503 If an element of a menu is a string consisting solely of hyphens, then that | |
504 item will be presented as a solid horizontal line. | |
505 | |
442 | 506 If an element of a menu is a string beginning with "--:", it will be |
507 presented as a line whose appearance is controlled by the rest of the | |
508 text in the string. The allowed line specs are system-dependent, and | |
509 currently work only under X Windows (with Lucid and Motif menubars); | |
510 otherwise, a solid horizontal line is presented, as if the string were | |
511 all hyphens. | |
512 | |
513 The possibilities are: | |
514 | |
515 "--:singleLine" | |
516 "--:doubleLine" | |
517 "--:singleDashedLine" | |
518 "--:doubleDashedLine" | |
519 "--:noLine" | |
520 "--:shadowEtchedIn" | |
521 "--:shadowEtchedOut" | |
522 "--:shadowEtchedInDash" | |
523 "--:shadowEtchedOutDash" | |
524 "--:shadowDoubleEtchedIn" (Lucid menubars only) | |
525 "--:shadowDoubleEtchedOut" (Lucid menubars only) | |
526 "--:shadowDoubleEtchedInDash" (Lucid menubars only) | |
527 "--:shadowDoubleEtchedOutDash" (Lucid menubars only) | |
528 | |
428 | 529 If an element of a menu is a list, it is treated as a submenu. The name of |
530 that submenu (the first element in the list) will be used as the name of the | |
531 item representing this menu on the parent. | |
532 | |
533 If an element of a menubar is `nil', then it is used to represent the | |
534 division between the set of menubar-items which are flushleft and those | |
535 which are flushright. | |
536 | |
537 Otherwise, the element must be a vector, which describes a menu item. | |
442 | 538 A menu item is of the following form: |
539 | |
540 [ "name" callback :<keyword> <value> :<keyword> <value> ... ] | |
541 | |
542 The following forms are also accepted for compatibility, but deprecated: | |
428 | 543 |
544 [ "name" callback <active-p> ] | |
545 [ "name" callback <active-p> <suffix> ] | |
546 | |
547 The name is the string to display on the menu; it is filtered through the | |
548 resource database, so it is possible for resources to override what string | |
442 | 549 is actually displayed. Menu accelerator indicators (the sequence `%_') are |
550 also processed; see above. If the name is not a string, it will be | |
551 evaluated with `eval', and the result should be a string. | |
428 | 552 |
553 If the `callback' of a menu item is a symbol, then it must name a command. | |
554 It will be invoked with `call-interactively'. If it is a list, then it is | |
555 evaluated with `eval'. | |
556 | |
442 | 557 In the deprecated forms, <active-p> is equivalent to using the :active |
558 keyword, and <suffix> is equivalent to using the :suffix keyword. | |
428 | 559 |
442 | 560 The possible keywords are: |
561 | |
562 :active <form> The expression is evaluated just before the menu is | |
428 | 563 displayed, and the menu will be selectable only if |
564 the result is non-nil. | |
565 | |
442 | 566 :suffix <form> The expression is evaluated just before the menu is |
567 displayed and the resulting string is appended to | |
568 the displayed name, providing a convenient way of | |
569 adding the name of a command's ``argument'' to the | |
570 menu, like ``Kill Buffer NAME''. | |
428 | 571 |
572 :keys "string" Normally, the keyboard equivalents of commands in | |
573 menus are displayed when the `callback' is a symbol. | |
574 This can be used to specify keys for more complex menu | |
575 items. It is passed through `substitute-command-keys' | |
576 first. | |
577 | |
578 :style <style> Specifies what kind of object this menu item is: | |
579 | |
580 nil A normal menu item. | |
581 toggle A toggle button. | |
582 radio A radio button. | |
583 button A menubar button. | |
584 | |
585 The only difference between toggle and radio buttons is | |
586 how they are displayed. But for consistency, a toggle | |
587 button should be used when there is one option whose | |
588 value can be turned on or off, and radio buttons should | |
589 be used when there is a set of mutually exclusive | |
590 options. When using a group of radio buttons, you | |
591 should arrange for no more than one to be marked as | |
592 selected at a time. | |
593 | |
594 :selected <form> Meaningful only when STYLE is `toggle', `radio' or | |
595 `button'. This specifies whether the button will be in | |
596 the selected or unselected state. | |
597 | |
598 :included <form> This can be used to control the visibility of a menu or | |
599 menu item. The form is evaluated and the menu or menu | |
5715
68f8d295be49
Support :visible in menu specifications.
Jerry James <james@xemacs.org>
parents:
5581
diff
changeset
|
600 item is only displayed if the result is non-nil. The |
68f8d295be49
Support :visible in menu specifications.
Jerry James <james@xemacs.org>
parents:
5581
diff
changeset
|
601 keyword :visible is an alias for :included. |
428 | 602 |
603 :config <symbol> This is an efficient shorthand for | |
604 :included (memq symbol menubar-configuration) | |
605 See the variable `menubar-configuration'. | |
606 | |
442 | 607 :filter <function> A menu filter can only be used at the beginning of a |
608 submenu description (i.e. not in a menu item itself). | |
609 (Remember that most of the keywords can take evaluated | |
610 expressions as well as constants.) The filter is used to | |
611 incrementally create a submenu only when it is selected | |
612 by the user and not every time the menubar is activated. | |
613 The filter function is passed the list of menu items in | |
614 the submenu and must return the modified list to be | |
615 actually used. The filter MUST NOT destructively modify | |
616 the list of menu items passed to it. It is called only | |
617 when the menu is about to be displayed, so other menus | |
618 may already be displayed. Vile and terrible things will | |
619 happen if a menu filter function changes the current | |
620 buffer, window, or frame. It also should not raise, | |
621 lower, or iconify any frames. Basically, the filter | |
622 function should have no side-effects. | |
428 | 623 |
624 :key-sequence keys Used in FSF Emacs as an hint to an equivalent keybinding. | |
442 | 625 Ignored by XEmacs for easymenu.el compatibility. |
626 (XEmacs computes this information automatically.) | |
428 | 627 |
628 For example: | |
629 | |
442 | 630 ("%_File" |
428 | 631 :filter file-menu-filter ; file-menu-filter is a function that takes |
632 ; one argument (a list of menu items) and | |
633 ; returns a list of menu items | |
442 | 634 [ "Save %_As..." write-file t ] |
635 [ "%_Revert Buffer" revert-buffer (buffer-modified-p) ] | |
636 [ "R%_ead Only" toggle-read-only :style toggle | |
428 | 637 :selected buffer-read-only ] |
638 ) | |
639 | |
442 | 640 See menubar-items.el for many more examples. |
428 | 641 |
642 After the menubar is clicked upon, but before any menus are popped up, | |
643 the functions on the `activate-menubar-hook' are invoked to make top-level | |
644 changes to the menus and menubar. Note, however, that the use of menu | |
645 filters (using the :filter keyword) is usually a more efficient way to | |
442 | 646 dynamically alter or sensitize menus. */, menubar_variable_changed); |
428 | 647 |
648 Vcurrent_menubar = Qnil; | |
649 | |
650 DEFVAR_LISP ("activate-menubar-hook", &Vactivate_menubar_hook /* | |
651 Function or functions called before a menubar menu is pulled down. | |
652 These functions are called with no arguments, and should interrogate and | |
653 modify the value of `current-menubar' as desired. | |
654 | |
655 The functions on this hook are invoked after the mouse goes down, but before | |
656 the menu is mapped, and may be used to activate, deactivate, add, or delete | |
657 items from the menus. However, it is probably the case that using a :filter | |
658 keyword in a submenu would be a more efficient way of updating menus. See | |
659 the documentation of `current-menubar'. | |
660 | |
661 These functions may return the symbol `t' to assert that they have made | |
662 no changes to the menubar. If any other value is returned, the menubar is | |
663 recomputed. If `t' is returned but the menubar has been changed, then the | |
664 changes may not show up right away. Returning `nil' when the menubar has | |
665 not changed is not so bad; more computation will be done, but redisplay of | |
666 the menubar will still be performed optimally. | |
667 */ ); | |
668 Vactivate_menubar_hook = Qnil; | |
563 | 669 DEFSYMBOL (Qactivate_menubar_hook); |
428 | 670 |
671 DEFVAR_BOOL ("menubar-show-keybindings", &menubar_show_keybindings /* | |
672 If true, the menubar will display keyboard equivalents. | |
673 If false, only the command names will be displayed. | |
674 */ ); | |
675 menubar_show_keybindings = 1; | |
676 | |
677 DEFVAR_LISP_MAGIC ("menubar-configuration", &Vmenubar_configuration /* | |
678 A list of symbols, against which the value of the :config tag for each | |
679 menubar item will be compared. If a menubar item has a :config tag, then | |
680 it is omitted from the menubar if that tag is not a member of the | |
681 `menubar-configuration' list. | |
682 */ , menubar_variable_changed); | |
683 Vmenubar_configuration = Qnil; | |
684 | |
685 DEFVAR_LISP ("menubar-pointer-glyph", &Vmenubar_pointer_glyph /* | |
686 *The shape of the mouse-pointer when over the menubar. | |
687 This is a glyph; use `set-glyph-image' to change it. | |
688 If unspecified in a particular domain, the window-system-provided | |
689 default pointer is used. | |
690 */ ); | |
691 | |
442 | 692 DEFVAR_LISP ("menu-accelerator-prefix", &Vmenu_accelerator_prefix /* |
693 Prefix key(s) that must be typed before menu accelerators will be activated. | |
694 Set this to a value acceptable by define-key. | |
695 | |
696 NOTE: This currently only has any effect under X Windows. | |
697 */ ); | |
698 Vmenu_accelerator_prefix = Qnil; | |
699 | |
700 DEFVAR_LISP ("menu-accelerator-modifiers", &Vmenu_accelerator_modifiers /* | |
701 Modifier keys which must be pressed to get to the top level menu accelerators. | |
702 This is a list of modifier key symbols. All modifier keys must be held down | |
703 while a valid menu accelerator key is pressed in order for the top level | |
704 menu to become active. | |
705 | |
706 NOTE: This currently only has any effect under X Windows. | |
707 | |
708 See also menu-accelerator-enabled and menu-accelerator-prefix. | |
709 */ ); | |
710 Vmenu_accelerator_modifiers = list1 (Qmeta); | |
711 | |
712 DEFVAR_LISP ("menu-accelerator-enabled", &Vmenu_accelerator_enabled /* | |
713 Whether menu accelerator keys can cause the menubar to become active. | |
3025 | 714 If `menu-force' or `menu-fallback', then menu accelerator keys can |
442 | 715 be used to activate the top level menu. Once the menubar becomes active, the |
716 accelerator keys can be used regardless of the value of this variable. | |
717 | |
718 menu-force is used to indicate that the menu accelerator key takes | |
719 precedence over bindings in the current keymap(s). menu-fallback means | |
720 that bindings in the current keymap take precedence over menu accelerator keys. | |
721 Thus a top level menu with an accelerator of "T" would be activated on a | |
722 keypress of Meta-t if menu-accelerator-enabled is menu-force. | |
723 However, if menu-accelerator-enabled is menu-fallback, then | |
724 Meta-t will not activate the menubar and will instead run the function | |
725 transpose-words, to which it is normally bound. | |
726 | |
727 See also menu-accelerator-modifiers and menu-accelerator-prefix. | |
728 */ ); | |
729 Vmenu_accelerator_enabled = Qnil; | |
730 | |
731 DEFVAR_LISP ("menu-accelerator-map", &Vmenu_accelerator_map /* | |
732 Keymap for use when the menubar is active. | |
733 The actions menu-quit, menu-up, menu-down, menu-left, menu-right, | |
734 menu-select and menu-escape can be mapped to keys in this map. | |
735 NOTE: This currently only has any effect under X Windows. | |
736 | |
737 menu-quit Immediately deactivate the menubar and any open submenus without | |
738 selecting an item. | |
739 menu-up Move the menu cursor up one row in the current menu. If the | |
740 move extends past the top of the menu, wrap around to the bottom. | |
741 menu-down Move the menu cursor down one row in the current menu. If the | |
742 move extends past the bottom of the menu, wrap around to the top. | |
743 If executed while the cursor is in the top level menu, move down | |
744 into the selected menu. | |
745 menu-left Move the cursor from a submenu into the parent menu. If executed | |
746 while the cursor is in the top level menu, move the cursor to the | |
747 left. If the move extends past the left edge of the menu, wrap | |
748 around to the right edge. | |
749 menu-right Move the cursor into a submenu. If the cursor is located in the | |
750 top level menu or is not currently on a submenu heading, then move | |
751 the cursor to the next top level menu entry. If the move extends | |
752 past the right edge of the menu, wrap around to the left edge. | |
753 menu-select Activate the item under the cursor. If the cursor is located on | |
754 a submenu heading, then move the cursor into the submenu. | |
755 menu-escape Pop up to the next level of menus. Moves from a submenu into its | |
756 parent menu. From the top level menu, this deactivates the | |
757 menubar. | |
758 | |
759 This keymap can also contain normal key-command bindings, in which case the | |
760 menubar is deactivated and the corresponding command is executed. | |
761 | |
762 The action bindings used by the menu accelerator code are designed to mimic | |
763 the actions of menu traversal keys in a commonly used PC operating system. | |
764 */ ); | |
765 | |
428 | 766 Fprovide (intern ("menubar")); |
464 | 767 Fprovide (intern ("menu-accelerator-support")); |
428 | 768 } |
769 | |
770 void | |
771 specifier_vars_of_menubar (void) | |
772 { | |
773 DEFVAR_SPECIFIER ("menubar-visible-p", &Vmenubar_visible_p /* | |
774 *Whether the menubar is visible. | |
775 This is a specifier; use `set-specifier' to change it. | |
776 */ ); | |
777 Vmenubar_visible_p = Fmake_specifier (Qboolean); | |
778 | |
779 set_specifier_fallback (Vmenubar_visible_p, list1 (Fcons (Qnil, Qt))); | |
780 set_specifier_caching (Vmenubar_visible_p, | |
438 | 781 offsetof (struct window, menubar_visible_p), |
428 | 782 menubar_visible_p_changed, |
438 | 783 offsetof (struct frame, menubar_visible_p), |
444 | 784 menubar_visible_p_changed_in_frame, 0); |
428 | 785 } |
786 | |
787 void | |
788 complex_vars_of_menubar (void) | |
789 { | |
790 Vmenubar_pointer_glyph = Fmake_glyph_internal (Qpointer); | |
442 | 791 |
792 Vmenu_accelerator_map = Fmake_keymap (Qnil); | |
428 | 793 } |