summaryrefslogtreecommitdiff
path: root/src/haikumenu.c
diff options
context:
space:
mode:
authorPo Lu <luangruo@yahoo.com>2022-03-09 06:58:01 +0000
committerPo Lu <luangruo@yahoo.com>2022-03-09 06:58:01 +0000
commitf599b58afebcbc5a0e5bde9358eca6bba51ab81a (patch)
treee0610821e7a0c9447da043582a6bd49773422fab /src/haikumenu.c
parente8d35b98bb2fd685c83bb9e9da60c00eb7967d5d (diff)
downloademacs-f599b58afebcbc5a0e5bde9358eca6bba51ab81a.tar.gz
Don't update Haiku menu bar if nothing changed
* haikumenu.c (set_frame_menubar): If Lisp-level contents didn't change, refrain from actually updating the menu bar.
Diffstat (limited to 'src/haikumenu.c')
-rw-r--r--src/haikumenu.c61
1 files changed, 44 insertions, 17 deletions
diff --git a/src/haikumenu.c b/src/haikumenu.c
index 2f75a5dd03e..8da00ffcb05 100644
--- a/src/haikumenu.c
+++ b/src/haikumenu.c
@@ -508,6 +508,10 @@ set_frame_menubar (struct frame *f, bool deep_p)
int previous_menu_items_used = f->menu_bar_items_used;
Lisp_Object *previous_items
= alloca (previous_menu_items_used * sizeof *previous_items);
+ int count;
+ ptrdiff_t subitems, i;
+ int *submenu_start, *submenu_end, *submenu_n_panes;
+ Lisp_Object *submenu_names;
XSETFRAME (Vmenu_updating_frame, f);
@@ -552,6 +556,7 @@ set_frame_menubar (struct frame *f, bool deep_p)
do always reinitialize them. */
if (first_time_p)
previous_menu_items_used = 0;
+
buffer = XWINDOW (FRAME_SELECTED_WINDOW (f))->contents;
specbind (Qinhibit_quit, Qt);
/* Don't let the debugger step into this code
@@ -587,29 +592,23 @@ set_frame_menubar (struct frame *f, bool 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;
- init_menu_items ();
- int i;
- int count = BMenu_count_items (mbar);
- int subitems = ASIZE (items) / 4;
-
- int *submenu_start, *submenu_end, *submenu_n_panes;
- Lisp_Object *submenu_names;
-
+ subitems = ASIZE (items) / 4;
submenu_start = alloca ((subitems + 1) * sizeof *submenu_start);
submenu_end = alloca (subitems * sizeof *submenu_end);
submenu_n_panes = alloca (subitems * sizeof *submenu_n_panes);
submenu_names = alloca (subitems * sizeof (Lisp_Object));
- for (i = 0; i < subitems; ++i)
+ init_menu_items ();
+ for (i = 0; i < subitems; i++)
{
Lisp_Object key, string, maps;
- key = AREF (items, i * 4);
- string = AREF (items, i * 4 + 1);
- maps = AREF (items, i * 4 + 2);
-
+ key = AREF (items, 4 * i);
+ string = AREF (items, 4 * i + 1);
+ maps = AREF (items, 4 * i + 2);
if (NILP (string))
break;
@@ -617,16 +616,44 @@ set_frame_menubar (struct frame *f, bool deep_p)
string = ENCODE_UTF_8 (string);
submenu_start[i] = menu_items_used;
+
menu_items_n_panes = 0;
parse_single_submenu (key, string, maps);
submenu_n_panes[i] = menu_items_n_panes;
+
submenu_end[i] = menu_items_used;
submenu_names[i] = string;
}
- finish_menu_items ();
+
submenu_start[i] = -1;
+ finish_menu_items ();
+
+ set_buffer_internal_1 (prev);
+
+ FRAME_OUTPUT_DATA (f)->menu_up_to_date_p = 1;
+
+ /* If there has been no change in the Lisp-level contents
+ of the menu bar, skip redisplaying it. Just exit. */
+
+ /* Compare the new menu items with the ones computed last time. */
+ for (i = 0; i < previous_menu_items_used; i++)
+ if (menu_items_used == i
+ || (!EQ (previous_items[i], AREF (menu_items, i))))
+ break;
+ if (i == menu_items_used && i == previous_menu_items_used && i != 0)
+ {
+ /* The menu items have not changed. Don't bother updating
+ the menus in any form, since it would be a no-op. */
+ discard_menu_items ();
+ unbind_to (specpdl_count, Qnil);
+ return;
+ }
+
+ /* Convert menu_items into widget_value trees
+ to display the menu. This cannot evaluate Lisp code. */
block_input ();
+ count = BMenu_count_items (mbar);
for (i = 0; submenu_start[i] >= 0; ++i)
{
void *mn = NULL;
@@ -642,12 +669,12 @@ set_frame_menubar (struct frame *f, bool deep_p)
}
unblock_input ();
- set_buffer_internal_1 (prev);
-
- FRAME_OUTPUT_DATA (f)->menu_up_to_date_p = 1;
+ /* The menu items are different, so store them in the frame. */
fset_menu_bar_vector (f, menu_items);
f->menu_bar_items_used = menu_items_used;
}
+
+ /* This undoes save_menu_items. */
unbind_to (specpdl_count, Qnil);
}