comparison src/xmenu.c @ 6291:38ec8e76594f

(Fx_popup_menu): If POSITION is nil, don't require an open X connection. (single_keymap_panes, keymap_panes, menu_item_enabled_p): New arg NOTREAL. (Fx_popup_menu): Pass new arg (1 if POSITION is nil). (menu_item_enabled_p): If NOTREAL, always return t. (single_keymap_panes) [!USE_X_TOOLKIT]: Append > to item_string if submenu. [USE_X_TOOLKIT]: Display submenus in Xt style. (menu_items): Record where submenus start and end. (menu_items_submenu_depth): New variable. (init_menu_items): Init it. (push_submenu_start, push_submenu_end): New functions. (grow_menu_items): New function. (push_menu_pane, push_menu_item): Use it. (push_menu_pane): Increment menu_items_n_panes only if depth is 0. (single_keymap_panes) [USE_X_TOOLKIT]: Record submenus in menu_items. (xmenu_show) [USE_X_TOOLKIT]: Give submenus to toolkit.
author Richard M. Stallman <rms@gnu.org>
date Thu, 10 Mar 1994 17:03:21 +0000
parents 01c57ae8ca57
children 1f9fa4022502
comparison
equal deleted inserted replaced
6290:6ecf8ea4bd8d 6291:38ec8e76594f
111 t, the pane name, the pane's prefix key. 111 t, the pane name, the pane's prefix key.
112 Then follow the pane's items, with 4 elements per item: 112 Then follow the pane's items, with 4 elements per item:
113 the item string, the enable flag, the item's value, 113 the item string, the enable flag, the item's value,
114 and the equivalent keyboard key's description string. 114 and the equivalent keyboard key's description string.
115 115
116 In some cases, multiple levels of menus may be described.
117 A single vector slot containing nil indicates the start of a submenu.
118 A single vector slot containing lambda indicates the end of a submenu.
119 The submenu follows a menu item which is the way to reach the submenu.
120
116 Using a Lisp vector to hold this information while we decode it 121 Using a Lisp vector to hold this information while we decode it
117 takes care of protecting all the data from GC. */ 122 takes care of protecting all the data from GC. */
118 123
119 #define MENU_ITEMS_PANE_NAME 1 124 #define MENU_ITEMS_PANE_NAME 1
120 #define MENU_ITEMS_PANE_PREFIX 2 125 #define MENU_ITEMS_PANE_PREFIX 2
132 static int menu_items_allocated; 137 static int menu_items_allocated;
133 138
134 /* This is the index in menu_items of the first empty slot. */ 139 /* This is the index in menu_items of the first empty slot. */
135 static int menu_items_used; 140 static int menu_items_used;
136 141
137 /* The number of panes currently recorded in menu_items. */ 142 /* The number of panes currently recorded in menu_items,
143 excluding those within submenus. */
138 static int menu_items_n_panes; 144 static int menu_items_n_panes;
145
146 /* Current depth within submenus. */
147 static int menu_items_submenu_depth;
139 148
140 /* Initialize the menu_items structure if we haven't already done so. 149 /* Initialize the menu_items structure if we haven't already done so.
141 Also mark it as currently empty. */ 150 Also mark it as currently empty. */
142 151
143 static void 152 static void
149 menu_items = Fmake_vector (make_number (menu_items_allocated), Qnil); 158 menu_items = Fmake_vector (make_number (menu_items_allocated), Qnil);
150 } 159 }
151 160
152 menu_items_used = 0; 161 menu_items_used = 0;
153 menu_items_n_panes = 0; 162 menu_items_n_panes = 0;
163 menu_items_submenu_depth = 0;
154 } 164 }
155 165
156 /* Call at the end of generating the data in menu_items. 166 /* Call at the end of generating the data in menu_items.
157 This fills in the number of items in the last pane. */ 167 This fills in the number of items in the last pane. */
158 168
174 menu_items = Qnil; 184 menu_items = Qnil;
175 menu_items_allocated = 0; 185 menu_items_allocated = 0;
176 } 186 }
177 } 187 }
178 188
189 /* Make the menu_items vector twice as large. */
190
191 static void
192 grow_menu_items ()
193 {
194 Lisp_Object old;
195 int old_size = menu_items_allocated;
196 old = menu_items;
197
198 menu_items_allocated *= 2;
199 menu_items = Fmake_vector (make_number (menu_items_allocated), Qnil);
200 bcopy (XVECTOR (old)->contents, XVECTOR (menu_items)->contents,
201 old_size * sizeof (Lisp_Object));
202 }
203
204 /* Begin a submenu. */
205
206 static void
207 push_submenu_start ()
208 {
209 if (menu_items_used + 1 > menu_items_allocated)
210 grow_menu_items ();
211
212 XVECTOR (menu_items)->contents[menu_items_used++] = Qnil;
213 menu_items_submenu_depth++;
214 }
215
216 /* End a submenu. */
217
218 static void
219 push_submenu_end ()
220 {
221 if (menu_items_used + 1 > menu_items_allocated)
222 grow_menu_items ();
223
224 XVECTOR (menu_items)->contents[menu_items_used++] = Qlambda;
225 menu_items_submenu_depth--;
226 }
227
179 /* Start a new menu pane in menu_items.. 228 /* Start a new menu pane in menu_items..
180 NAME is the pane name. PREFIX_VEC is a prefix key for this pane. */ 229 NAME is the pane name. PREFIX_VEC is a prefix key for this pane. */
181 230
182 static void 231 static void
183 push_menu_pane (name, prefix_vec) 232 push_menu_pane (name, prefix_vec)
184 Lisp_Object name, prefix_vec; 233 Lisp_Object name, prefix_vec;
185 { 234 {
186 if (menu_items_used + MENU_ITEMS_PANE_LENGTH > menu_items_allocated) 235 if (menu_items_used + MENU_ITEMS_PANE_LENGTH > menu_items_allocated)
187 { 236 grow_menu_items ();
188 Lisp_Object old; 237
189 int old_size = menu_items_allocated; 238 if (menu_items_submenu_depth == 0)
190 old = menu_items; 239 menu_items_n_panes++;
191
192 menu_items_allocated *= 2;
193 menu_items = Fmake_vector (make_number (menu_items_allocated), Qnil);
194 bcopy (XVECTOR (old)->contents, XVECTOR (menu_items)->contents,
195 old_size * sizeof (Lisp_Object));
196 }
197
198 menu_items_n_panes++;
199 XVECTOR (menu_items)->contents[menu_items_used++] = Qt; 240 XVECTOR (menu_items)->contents[menu_items_used++] = Qt;
200 XVECTOR (menu_items)->contents[menu_items_used++] = name; 241 XVECTOR (menu_items)->contents[menu_items_used++] = name;
201 XVECTOR (menu_items)->contents[menu_items_used++] = prefix_vec; 242 XVECTOR (menu_items)->contents[menu_items_used++] = prefix_vec;
202 } 243 }
203 244
210 static void 251 static void
211 push_menu_item (name, enable, key, equiv) 252 push_menu_item (name, enable, key, equiv)
212 Lisp_Object name, enable, key, equiv; 253 Lisp_Object name, enable, key, equiv;
213 { 254 {
214 if (menu_items_used + MENU_ITEMS_ITEM_LENGTH > menu_items_allocated) 255 if (menu_items_used + MENU_ITEMS_ITEM_LENGTH > menu_items_allocated)
215 { 256 grow_menu_items ();
216 Lisp_Object old;
217 int old_size = menu_items_allocated;
218 old = menu_items;
219
220 menu_items_allocated *= 2;
221 menu_items = Fmake_vector (make_number (menu_items_allocated), Qnil);
222 bcopy (XVECTOR (old)->contents, XVECTOR (menu_items)->contents,
223 old_size * sizeof (Lisp_Object));
224 }
225 257
226 XVECTOR (menu_items)->contents[menu_items_used++] = name; 258 XVECTOR (menu_items)->contents[menu_items_used++] = name;
227 XVECTOR (menu_items)->contents[menu_items_used++] = enable; 259 XVECTOR (menu_items)->contents[menu_items_used++] = enable;
228 XVECTOR (menu_items)->contents[menu_items_used++] = key; 260 XVECTOR (menu_items)->contents[menu_items_used++] = key;
229 XVECTOR (menu_items)->contents[menu_items_used++] = equiv; 261 XVECTOR (menu_items)->contents[menu_items_used++] = equiv;
317 { 349 {
318 return Qnil; 350 return Qnil;
319 } 351 }
320 352
321 /* Return non-nil if the command DEF is enabled when used as a menu item. 353 /* Return non-nil if the command DEF is enabled when used as a menu item.
322 This is based on looking for a menu-enable property. */ 354 This is based on looking for a menu-enable property.
355 If NOTREAL is set, don't bother really computing this. */
323 356
324 static Lisp_Object 357 static Lisp_Object
325 menu_item_enabled_p (def) 358 menu_item_enabled_p (def, notreal)
326 Lisp_Object def; 359 Lisp_Object def;
327 { 360 {
328 Lisp_Object enabled, tem; 361 Lisp_Object enabled, tem;
329 362
330 enabled = Qt; 363 enabled = Qt;
364 if (notreal)
365 return enabled;
331 if (XTYPE (def) == Lisp_Symbol) 366 if (XTYPE (def) == Lisp_Symbol)
332 { 367 {
333 /* No property, or nil, means enable. 368 /* No property, or nil, means enable.
334 Otherwise, enable if value is not nil. */ 369 Otherwise, enable if value is not nil. */
335 tem = Fget (def, Qmenu_enable); 370 tem = Fget (def, Qmenu_enable);
341 } 376 }
342 return enabled; 377 return enabled;
343 } 378 }
344 379
345 /* Look through KEYMAPS, a vector of keymaps that is NMAPS long, 380 /* Look through KEYMAPS, a vector of keymaps that is NMAPS long,
346 and generate menu panes for them in menu_items. */ 381 and generate menu panes for them in menu_items.
382 If NOTREAL is nonzero,
383 don't bother really computing whether an item is enabled. */
347 384
348 static void 385 static void
349 keymap_panes (keymaps, nmaps) 386 keymap_panes (keymaps, nmaps, notreal)
350 Lisp_Object *keymaps; 387 Lisp_Object *keymaps;
351 int nmaps; 388 int nmaps;
389 int notreal;
352 { 390 {
353 int mapno; 391 int mapno;
354 392
355 init_menu_items (); 393 init_menu_items ();
356 394
357 /* Loop over the given keymaps, making a pane for each map. 395 /* Loop over the given keymaps, making a pane for each map.
358 But don't make a pane that is empty--ignore that map instead. 396 But don't make a pane that is empty--ignore that map instead.
359 P is the number of panes we have made so far. */ 397 P is the number of panes we have made so far. */
360 for (mapno = 0; mapno < nmaps; mapno++) 398 for (mapno = 0; mapno < nmaps; mapno++)
361 single_keymap_panes (keymaps[mapno], Qnil, Qnil); 399 single_keymap_panes (keymaps[mapno], Qnil, Qnil, notreal);
362 400
363 finish_menu_items (); 401 finish_menu_items ();
364 } 402 }
365 403
366 /* This is a recursive subroutine of keymap_panes. 404 /* This is a recursive subroutine of keymap_panes.
367 It handles one keymap, KEYMAP. 405 It handles one keymap, KEYMAP.
368 The other arguments are passed along 406 The other arguments are passed along
369 or point to local variables of the previous function. */ 407 or point to local variables of the previous function.
408 If NOTREAL is nonzero,
409 don't bother really computing whether an item is enabled. */
370 410
371 static void 411 static void
372 single_keymap_panes (keymap, pane_name, prefix) 412 single_keymap_panes (keymap, pane_name, prefix, notreal)
373 Lisp_Object keymap; 413 Lisp_Object keymap;
374 Lisp_Object pane_name; 414 Lisp_Object pane_name;
375 Lisp_Object prefix; 415 Lisp_Object prefix;
416 int notreal;
376 { 417 {
377 Lisp_Object pending_maps; 418 Lisp_Object pending_maps;
378 Lisp_Object tail, item, item1, item_string, table; 419 Lisp_Object tail, item, item1, item_string, table;
379 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; 420 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
380 421
408 Protecting KEYMAP preserves everything we use; 449 Protecting KEYMAP preserves everything we use;
409 aside from that, must protect whatever might be 450 aside from that, must protect whatever might be
410 a string. Since there's no GCPRO5, we refetch 451 a string. Since there's no GCPRO5, we refetch
411 item_string instead of protecting it. */ 452 item_string instead of protecting it. */
412 GCPRO4 (keymap, pending_maps, def, descrip); 453 GCPRO4 (keymap, pending_maps, def, descrip);
413 enabled = menu_item_enabled_p (def); 454 enabled = menu_item_enabled_p (def, notreal);
455
414 UNGCPRO; 456 UNGCPRO;
415 457
416 item_string = XCONS (item1)->car; 458 item_string = XCONS (item1)->car;
417 459
418 tem = Fkeymapp (def); 460 tem = Fkeymapp (def);
419 if (XSTRING (item_string)->data[0] == '@' && !NILP (tem)) 461 if (XSTRING (item_string)->data[0] == '@' && !NILP (tem))
420 pending_maps = Fcons (Fcons (def, Fcons (item_string, XCONS (item)->car)), 462 pending_maps = Fcons (Fcons (def, Fcons (item_string, XCONS (item)->car)),
421 pending_maps); 463 pending_maps);
422 else 464 else
423 push_menu_item (item_string, enabled, XCONS (item)->car, 465 {
424 descrip); 466 Lisp_Object submap;
467 submap = get_keymap_1 (def, 0, 1);
468 #ifndef USE_X_TOOLKIT
469 /* Indicate visually that this is a submenu. */
470 if (!NILP (submap))
471 item_string = concat2 (item_string,
472 build_string (" >"));
473 #endif
474 push_menu_item (item_string, enabled, XCONS (item)->car,
475 descrip);
476 #ifdef USE_X_TOOLKIT
477 /* Display a submenu using the toolkit. */
478 if (! NILP (submap))
479 {
480 push_submenu_start ();
481 single_keymap_panes (submap, Qnil,
482 XCONS (item)->car, notreal);
483 push_submenu_end ();
484 }
485 #endif
486 }
425 } 487 }
426 } 488 }
427 } 489 }
428 else if (XTYPE (item) == Lisp_Vector) 490 else if (XTYPE (item) == Lisp_Vector)
429 { 491 {
453 Protecting KEYMAP preserves everything we use; 515 Protecting KEYMAP preserves everything we use;
454 aside from that, must protect whatever might be 516 aside from that, must protect whatever might be
455 a string. Since there's no GCPRO5, we refetch 517 a string. Since there's no GCPRO5, we refetch
456 item_string instead of protecting it. */ 518 item_string instead of protecting it. */
457 GCPRO4 (keymap, pending_maps, def, descrip); 519 GCPRO4 (keymap, pending_maps, def, descrip);
458 enabled = menu_item_enabled_p (def); 520 enabled = menu_item_enabled_p (def, notreal);
459 UNGCPRO; 521 UNGCPRO;
460 522
461 item_string = XCONS (item1)->car; 523 item_string = XCONS (item1)->car;
462 524
463 tem = Fkeymapp (def); 525 tem = Fkeymapp (def);
464 if (XSTRING (item_string)->data[0] == '@' && !NILP (tem)) 526 if (XSTRING (item_string)->data[0] == '@' && !NILP (tem))
465 pending_maps = Fcons (Fcons (def, Fcons (item_string, character)), 527 pending_maps = Fcons (Fcons (def, Fcons (item_string, character)),
466 pending_maps); 528 pending_maps);
467 else 529 else
468 push_menu_item (item_string, enabled, 530 {
469 character, descrip); 531 Lisp_Object submap;
532 submap = get_keymap_1 (def, 0, 1);
533 #ifndef USE_X_TOOLKIT
534 if (!NILP (submap))
535 item_string = concat2 (item_string,
536 build_string (" >"));
537 #endif
538 push_menu_item (item_string, enabled, character,
539 descrip);
540 #ifdef USE_X_TOOLKIT
541 if (! NILP (submap))
542 {
543 push_submenu_start ();
544 single_keymap_panes (submap, Qnil,
545 character, notreal);
546 push_submenu_end ();
547 }
548 #endif
549 }
470 } 550 }
471 } 551 }
472 } 552 }
473 } 553 }
474 } 554 }
475 555
476 /* Process now any submenus which want to be panes at this level. */ 556 /* Process now any submenus which want to be panes at this level. */
477 while (!NILP (pending_maps)) 557 while (!NILP (pending_maps))
478 { 558 {
479 Lisp_Object elt, eltcdr; 559 Lisp_Object elt, eltcdr, string;
480 elt = Fcar (pending_maps); 560 elt = Fcar (pending_maps);
481 eltcdr = XCONS (elt)->cdr; 561 eltcdr = XCONS (elt)->cdr;
482 single_keymap_panes (Fcar (elt), 562 string = XCONS (eltcdr)->car;
483 /* Fails to discard the @. */ 563 /* We no longer discard the @ from the beginning of the string here.
484 XCONS (eltcdr)->car, XCONS (eltcdr)->cdr); 564 Instead, we do this in xmenu_show. */
565 single_keymap_panes (Fcar (elt), string,
566 XCONS (eltcdr)->cdr, notreal);
485 pending_maps = Fcdr (pending_maps); 567 pending_maps = Fcdr (pending_maps);
486 } 568 }
487 } 569 }
488 570
489 /* Push all the panes and items of a menu decsribed by the 571 /* Push all the panes and items of a menu decsribed by the
579 Lisp_Object x, y, window; 661 Lisp_Object x, y, window;
580 int keymaps = 0; 662 int keymaps = 0;
581 int menubarp = 0; 663 int menubarp = 0;
582 struct gcpro gcpro1; 664 struct gcpro gcpro1;
583 665
584 check_x ();
585
586 if (! NILP (position)) 666 if (! NILP (position))
587 { 667 {
668 check_x ();
669
588 /* Decode the first argument: find the window and the coordinates. */ 670 /* Decode the first argument: find the window and the coordinates. */
589 if (EQ (position, Qt)) 671 if (EQ (position, Qt))
590 { 672 {
591 /* Use the mouse's current position. */ 673 /* Use the mouse's current position. */
592 FRAME_PTR new_f; 674 FRAME_PTR new_f;
666 /* We were given a keymap. Extract menu info from the keymap. */ 748 /* We were given a keymap. Extract menu info from the keymap. */
667 Lisp_Object prompt; 749 Lisp_Object prompt;
668 keymap = get_keymap (menu); 750 keymap = get_keymap (menu);
669 751
670 /* Extract the detailed info to make one pane. */ 752 /* Extract the detailed info to make one pane. */
671 keymap_panes (&menu, 1); 753 keymap_panes (&menu, 1, NILP (position));
672 754
673 /* Search for a string appearing directly as an element of the keymap. 755 /* Search for a string appearing directly as an element of the keymap.
674 That string is the title of the menu. */ 756 That string is the title of the menu. */
675 prompt = map_prompt (keymap); 757 prompt = map_prompt (keymap);
676 758
702 if (NILP (title) && !NILP (prompt)) 784 if (NILP (title) && !NILP (prompt))
703 title = prompt; 785 title = prompt;
704 } 786 }
705 787
706 /* Extract the detailed info to make one pane. */ 788 /* Extract the detailed info to make one pane. */
707 keymap_panes (maps, nmaps); 789 keymap_panes (maps, nmaps, NILP (position));
708 790
709 /* Make the title be the pane title of the first pane. */ 791 /* Make the title be the pane title of the first pane. */
710 if (!NILP (title) && menu_items_n_panes >= 0) 792 if (!NILP (title) && menu_items_n_panes >= 0)
711 XVECTOR (menu_items)->contents[MENU_ITEMS_PANE_NAME] = title; 793 XVECTOR (menu_items)->contents[MENU_ITEMS_PANE_NAME] = title;
712 794
1121 1203
1122 /* This is the menu bar item (if any) that led to this menu. */ 1204 /* This is the menu bar item (if any) that led to this menu. */
1123 widget_value *menubar_item = 0; 1205 widget_value *menubar_item = 0;
1124 1206
1125 widget_value *wv, *save_wv = 0, *first_wv = 0, *prev_wv = 0; 1207 widget_value *wv, *save_wv = 0, *first_wv = 0, *prev_wv = 0;
1208 widget_value **submenu_stack
1209 = (widget_value **) alloca (menu_items_used * sizeof (widget_value *));
1210 Lisp_Object *subprefix_stack
1211 = (Lisp_Object *) alloca (menu_items_used * sizeof (Lisp_Object));
1212 int submenu_depth = 0;
1126 1213
1127 /* Define a queue to save up for later unreading 1214 /* Define a queue to save up for later unreading
1128 all X events that don't pertain to the menu. */ 1215 all X events that don't pertain to the menu. */
1129 struct event_queue 1216 struct event_queue
1130 { 1217 {
1186 1273
1187 /* Loop over all panes and items, filling in the tree. */ 1274 /* Loop over all panes and items, filling in the tree. */
1188 i = 0; 1275 i = 0;
1189 while (i < menu_items_used) 1276 while (i < menu_items_used)
1190 { 1277 {
1191 if (EQ (XVECTOR (menu_items)->contents[i], Qt)) 1278 if (EQ (XVECTOR (menu_items)->contents[i], Qnil))
1279 {
1280 submenu_stack[submenu_depth++] = save_wv;
1281 save_wv = prev_wv;
1282 prev_wv = 0;
1283 i++;
1284 }
1285 else if (EQ (XVECTOR (menu_items)->contents[i], Qlambda))
1286 {
1287 prev_wv = save_wv;
1288 save_wv = submenu_stack[--submenu_depth];
1289 i++;
1290 }
1291 else if (EQ (XVECTOR (menu_items)->contents[i], Qt)
1292 && submenu_depth != 0)
1293 i += MENU_ITEMS_PANE_LENGTH;
1294 else if (EQ (XVECTOR (menu_items)->contents[i], Qt))
1192 { 1295 {
1193 /* Create a new pane. */ 1296 /* Create a new pane. */
1194 Lisp_Object pane_name, prefix; 1297 Lisp_Object pane_name, prefix;
1195 char *pane_string; 1298 char *pane_string;
1196 pane_name = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_NAME]; 1299 pane_name = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_NAME];
1197 prefix = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_PREFIX]; 1300 prefix = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_PREFIX];
1198 pane_string = (NILP (pane_name) 1301 pane_string = (NILP (pane_name)
1199 ? "" : (char *) XSTRING (pane_name)->data); 1302 ? "" : (char *) XSTRING (pane_name)->data);
1200 /* If there is just one pane, put all its items directly 1303 /* If there is just one top-level pane, put all its items directly
1201 under the top-level menu. */ 1304 under the top-level menu. */
1202 if (menu_items_n_panes == 1) 1305 if (menu_items_n_panes == 1)
1203 pane_string = ""; 1306 pane_string = "";
1204 1307
1205 /* If the pane has a meaningful name, 1308 /* If the pane has a meaningful name,
1400 i = 0; 1503 i = 0;
1401 while (i < menu_items_used) 1504 while (i < menu_items_used)
1402 { 1505 {
1403 Lisp_Object entry; 1506 Lisp_Object entry;
1404 1507
1405 if (EQ (XVECTOR (menu_items)->contents[i], Qt)) 1508 if (EQ (XVECTOR (menu_items)->contents[i], Qnil))
1509 {
1510 subprefix_stack[submenu_depth++] = prefix;
1511 prefix = entry;
1512 i++;
1513 }
1514 else if (EQ (XVECTOR (menu_items)->contents[i], Qlambda))
1515 {
1516 prefix = subprefix_stack[--submenu_depth];
1517 i++;
1518 }
1519 else if (EQ (XVECTOR (menu_items)->contents[i], Qt))
1406 { 1520 {
1407 prefix 1521 prefix
1408 = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_PREFIX]; 1522 = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_PREFIX];
1409 i += MENU_ITEMS_PANE_LENGTH; 1523 i += MENU_ITEMS_PANE_LENGTH;
1410 } 1524 }
1414 = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_VALUE]; 1528 = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_VALUE];
1415 if (menu_item_selection == &XVECTOR (menu_items)->contents[i]) 1529 if (menu_item_selection == &XVECTOR (menu_items)->contents[i])
1416 { 1530 {
1417 if (keymaps != 0) 1531 if (keymaps != 0)
1418 { 1532 {
1533 int j;
1534
1419 entry = Fcons (entry, Qnil); 1535 entry = Fcons (entry, Qnil);
1420 if (!NILP (prefix)) 1536 if (!NILP (prefix))
1421 entry = Fcons (prefix, entry); 1537 entry = Fcons (prefix, entry);
1538 for (j = submenu_depth - 1; j >= 0; j--)
1539 entry = Fcons (subprefix_stack[j], entry);
1422 } 1540 }
1423 return entry; 1541 return entry;
1424 } 1542 }
1425 i += MENU_ITEMS_ITEM_LENGTH; 1543 i += MENU_ITEMS_ITEM_LENGTH;
1426 } 1544 }