summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Third <alan@idiocy.org>2020-12-28 15:02:39 +0000
committerAlan Third <alan@idiocy.org>2020-12-28 18:03:48 +0000
commit16458631d49a19bd496a45517264059383e18c18 (patch)
tree38e5daf188ebd437742c583df21aca6511ebf2be
parent5e1416fd0a41c4b7d13d3cd6ecedab48ae7b55b5 (diff)
downloademacs-16458631d49a19bd496a45517264059383e18c18.tar.gz
Fix crash in NS menu code
* src/nsmenu.m (ns_update_menubar): Don't assume that the top level menus are correct when populating the submenus. (free_frame_menubar): Clear the menu. ([EmacsMenu removeAllItems]): Actually remove all menu items.
-rw-r--r--src/nsmenu.m101
1 files changed, 46 insertions, 55 deletions
diff --git a/src/nsmenu.m b/src/nsmenu.m
index 3f0cd0c6ed4..23699627b15 100644
--- a/src/nsmenu.m
+++ b/src/nsmenu.m
@@ -65,11 +65,22 @@ static int popup_activated_flag;
/* Supposed to discard menubar and free storage. Since we share the
menubar among frames and update its context for the focused window,
- there is nothing to do here. */
+ we do not discard the menu. We do, however, want to remove any
+ existing menu items. */
void
free_frame_menubar (struct frame *f)
{
- return;
+ id menu = [NSApp mainMenu];
+ for (int i = [menu numberOfItems] - 1 ; i >= 0; i--)
+ {
+ NSMenuItem *item = [menu itemAtIndex:i];
+ NSString *title = [item title];
+
+ if ([ns_app_name isEqualToString:title])
+ continue;
+
+ [menu removeItemAtIndex:i];
+ }
}
@@ -108,7 +119,7 @@ ns_update_menubar (struct frame *f, bool deep_p)
NSTRACE ("ns_update_menubar");
- if (f != SELECTED_FRAME ())
+ if (f != SELECTED_FRAME () || FRAME_EXTERNAL_MENU_BAR (f) == 0)
return;
XSETFRAME (Vmenu_updating_frame, f);
/*fprintf (stderr, "ns_update_menubar: frame: %p\tdeep: %d\tsub: %p\n", f, deep_p, submenu); */
@@ -317,57 +328,44 @@ ns_update_menubar (struct frame *f, bool deep_p)
}
/* Now, update the NS menu. */
- if (deep_p)
- {
- /* This path is typically used when a menu has been clicked. I
- think Apple expect us to only update that one menu, however
- to update one we need to do the hard work of parsing the
- whole tree, so we may as well update them all. */
-#ifdef NS_IMPL_COCOA
- int i = 1;
-#else
- int i = 0;
-#endif
- for (wv = first_wv->contents; wv; wv = wv->next)
- {
- /* The contents of wv should match the top level menu. */
- EmacsMenu *submenu = (EmacsMenu*)[[menu itemAtIndex:i++] submenu];
+ i = 0;
- [submenu fillWithWidgetValue: wv->contents];
- }
+ /* Make sure we skip the "application" menu, which is always the
+ first entry in our top-level menu. */
+ if (i < [menu numberOfItems])
+ {
+ NSString *title = [[menu itemAtIndex:i] title];
+ if ([ns_app_name isEqualToString:title])
+ i += 1;
}
- else
+
+ for (wv = first_wv->contents; wv; wv = wv->next)
{
- /* Make sure we skip the "application" menu, which is always the
- first entry in our top-level menu. */
-#ifdef NS_IMPL_COCOA
- int i = 1;
-#else
- int i = 0;
-#endif
- for (wv = first_wv->contents; wv; wv = wv->next)
- {
- if (i < [menu numberOfItems])
- {
- NSString *titleStr = [NSString stringWithUTF8String: wv->name];
- NSMenuItem *item = [menu itemAtIndex:i];
- EmacsMenu *submenu = (EmacsMenu*)[item submenu];
+ EmacsMenu *submenu;
- [item setTitle:titleStr];
- [submenu setTitle:titleStr];
- [submenu removeAllItems];
- }
- else
- [menu addSubmenuWithTitle: wv->name];
+ if (i < [menu numberOfItems])
+ {
+ NSString *titleStr = [NSString stringWithUTF8String: wv->name];
+ NSMenuItem *item = [menu itemAtIndex:i];
+ submenu = (EmacsMenu*)[item submenu];
- i += 1;
+ [item setTitle:titleStr];
+ [submenu setTitle:titleStr];
+ [submenu removeAllItems];
}
+ else
+ submenu = [menu addSubmenuWithTitle: wv->name];
- while (i < [menu numberOfItems])
- {
- /* Remove any extra items. */
- [menu removeItemAtIndex:i];
- }
+ if (deep_p)
+ [submenu fillWithWidgetValue: wv->contents];
+
+ i += 1;
+ }
+
+ while (i < [menu numberOfItems])
+ {
+ /* Remove any extra items. */
+ [menu removeItemAtIndex:i];
}
@@ -541,14 +539,7 @@ set_frame_menubar (struct frame *f, bool first_time, bool deep_p)
int n;
for (n = [self numberOfItems]-1; n >= 0; n--)
- {
- NSMenuItem *item = [self itemAtIndex: n];
- NSString *title = [item title];
- if ([ns_app_name isEqualToString: title]
- && ![item isSeparatorItem])
- continue;
- [self removeItemAtIndex: n];
- }
+ [self removeItemAtIndex: n];
#endif
needsUpdate = YES;