mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-16 00:01:05 -08:00
(restore_menu_items, save_menu_items): New fns.
(set_frame_menubar): Use save_menu_items. Save updated vector in the frame before unwinding it. Don't use unuse_menu_items. Don't use discard_menu_items. (digest_single_submenu): Abort if an item is not in a pane. (init_menu_items): Put the error check at the top.
This commit is contained in:
parent
6588243de7
commit
1fc4d4635c
1 changed files with 52 additions and 8 deletions
60
src/xmenu.c
60
src/xmenu.c
|
|
@ -266,14 +266,15 @@ menubar_id_to_frame (id)
|
|||
static void
|
||||
init_menu_items ()
|
||||
{
|
||||
if (!NILP (menu_items_inuse))
|
||||
error ("Trying to use a menu from within a menu-entry");
|
||||
|
||||
if (NILP (menu_items))
|
||||
{
|
||||
menu_items_allocated = 60;
|
||||
menu_items = Fmake_vector (make_number (menu_items_allocated), Qnil);
|
||||
}
|
||||
|
||||
if (!NILP (menu_items_inuse))
|
||||
error ("Trying to use a menu from within a menu-entry");
|
||||
menu_items_inuse = Qt;
|
||||
menu_items_used = 0;
|
||||
menu_items_n_panes = 0;
|
||||
|
|
@ -310,6 +311,39 @@ discard_menu_items ()
|
|||
xassert (NILP (menu_items_inuse));
|
||||
}
|
||||
|
||||
/* This undoes save_menu_items, and it is called by the specpdl unwind
|
||||
mechanism. */
|
||||
|
||||
static Lisp_Object
|
||||
restore_menu_items (saved)
|
||||
Lisp_Object saved;
|
||||
{
|
||||
menu_items = XCAR (saved);
|
||||
menu_items_inuse = (! NILP (menu_items) ? Qt : Qnil);
|
||||
menu_items_allocated = (VECTORP (menu_items) ? ASIZE (menu_items) : 0);
|
||||
saved = XCDR (saved);
|
||||
menu_items_used = XINT (XCAR (saved));
|
||||
saved = XCDR (saved);
|
||||
menu_items_n_panes = XINT (XCAR (saved));
|
||||
saved = XCDR (saved);
|
||||
menu_items_submenu_depth = XINT (XCAR (saved));
|
||||
}
|
||||
|
||||
/* Push the whole state of menu_items processing onto the specpdl.
|
||||
It will be restored when the specpdl is unwound. */
|
||||
|
||||
static void
|
||||
save_menu_items ()
|
||||
{
|
||||
Lisp_Object saved = list4 (!NILP (menu_items_inuse) ? menu_items : Qnil,
|
||||
make_number (menu_items_used),
|
||||
make_number (menu_items_n_panes),
|
||||
make_number (menu_items_submenu_depth));
|
||||
record_unwind_protect (restore_menu_items, saved);
|
||||
menu_items_inuse = Qnil;
|
||||
menu_items = Qnil;
|
||||
}
|
||||
|
||||
/* Make the menu_items vector twice as large. */
|
||||
|
||||
static void
|
||||
|
|
@ -320,6 +354,7 @@ grow_menu_items ()
|
|||
old = menu_items;
|
||||
|
||||
menu_items_allocated *= 2;
|
||||
|
||||
menu_items = Fmake_vector (make_number (menu_items_allocated), Qnil);
|
||||
bcopy (XVECTOR (old)->contents, XVECTOR (menu_items)->contents,
|
||||
old_size * sizeof (Lisp_Object));
|
||||
|
|
@ -1728,6 +1763,7 @@ digest_single_submenu (start, end, top_level_items)
|
|||
int i;
|
||||
int submenu_depth = 0;
|
||||
widget_value **submenu_stack;
|
||||
int panes_seen = 0;
|
||||
|
||||
submenu_stack
|
||||
= (widget_value **) alloca (menu_items_used * sizeof (widget_value *));
|
||||
|
|
@ -1774,6 +1810,8 @@ digest_single_submenu (start, end, top_level_items)
|
|||
Lisp_Object pane_name, prefix;
|
||||
char *pane_string;
|
||||
|
||||
panes_seen++;
|
||||
|
||||
pane_name = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_NAME];
|
||||
prefix = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_PREFIX];
|
||||
|
||||
|
|
@ -1821,6 +1859,10 @@ digest_single_submenu (start, end, top_level_items)
|
|||
Lisp_Object item_name, enable, descrip, def, type, selected;
|
||||
Lisp_Object help;
|
||||
|
||||
/* All items should be contained in panes. */
|
||||
if (panes_seen == 0)
|
||||
abort ();
|
||||
|
||||
item_name = AREF (menu_items, i + MENU_ITEMS_ITEM_NAME);
|
||||
enable = AREF (menu_items, i + MENU_ITEMS_ITEM_ENABLE);
|
||||
descrip = AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY);
|
||||
|
|
@ -2046,7 +2088,6 @@ set_frame_menubar (f, first_time, deep_p)
|
|||
specbind (Qdebug_on_next_call, Qnil);
|
||||
|
||||
record_unwind_save_match_data ();
|
||||
record_unwind_protect (unuse_menu_items, Qnil);
|
||||
if (NILP (Voverriding_local_map_menu_flag))
|
||||
{
|
||||
specbind (Qoverriding_terminal_local_map, Qnil);
|
||||
|
|
@ -2074,6 +2115,8 @@ set_frame_menubar (f, first_time, deep_p)
|
|||
|
||||
/* Fill in menu_items with the current menu bar contents.
|
||||
This can evaluate Lisp code. */
|
||||
save_menu_items ();
|
||||
|
||||
menu_items = f->menu_bar_vector;
|
||||
menu_items_allocated = VECTORP (menu_items) ? ASIZE (menu_items) : 0;
|
||||
submenu_start = (int *) alloca (XVECTOR (items)->size * sizeof (int *));
|
||||
|
|
@ -2133,7 +2176,6 @@ set_frame_menubar (f, first_time, deep_p)
|
|||
}
|
||||
|
||||
set_buffer_internal_1 (prev);
|
||||
unbind_to (specpdl_count, Qnil);
|
||||
|
||||
/* If there has been no change in the Lisp-level contents
|
||||
of the menu bar, skip redisplaying it. Just exit. */
|
||||
|
|
@ -2146,10 +2188,15 @@ set_frame_menubar (f, first_time, deep_p)
|
|||
{
|
||||
free_menubar_widget_value_tree (first_wv);
|
||||
discard_menu_items ();
|
||||
|
||||
unbind_to (specpdl_count, Qnil);
|
||||
return;
|
||||
}
|
||||
|
||||
f->menu_bar_vector = menu_items;
|
||||
f->menu_bar_items_used = menu_items_used;
|
||||
|
||||
unbind_to (specpdl_count, Qnil);
|
||||
|
||||
/* Now GC cannot happen during the lifetime of the widget_value,
|
||||
so it's safe to store data from a Lisp_String. */
|
||||
wv = first_wv->contents;
|
||||
|
|
@ -2164,9 +2211,6 @@ set_frame_menubar (f, first_time, deep_p)
|
|||
wv = wv->next;
|
||||
}
|
||||
|
||||
f->menu_bar_vector = menu_items;
|
||||
f->menu_bar_items_used = menu_items_used;
|
||||
discard_menu_items ();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue