From 434c059d83b03b42e8b6f51fc6991980f06eb4b8 Mon Sep 17 00:00:00 2001 From: Alan Third Date: Thu, 10 Jun 2021 23:52:19 +0100 Subject: [PATCH] Fix GNUstep menu update crashes * src/nsmenu.m (ns_update_menubar): close the submenus before modifying them. ([EmacsMenu close]): Make sure to close all submenus. --- src/nsmenu.m | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/nsmenu.m b/src/nsmenu.m index 1d3e1aca0c0..1b03fe91a8b 100644 --- a/src/nsmenu.m +++ b/src/nsmenu.m @@ -359,7 +359,11 @@ { NSString *titleStr = [NSString stringWithUTF8String: wv->name]; NSMenuItem *item = (NSMenuItem *)[menu itemAtIndex:i]; - submenu = (EmacsMenu*)[item submenu]; + submenu = (EmacsMenu *)[item submenu]; + +#ifdef NS_IMPL_GNUSTEP + [submenu close]; +#endif [item setTitle:titleStr]; [submenu setTitle:titleStr]; @@ -382,6 +386,12 @@ while (i < [menu numberOfItems]) { /* Remove any extra items. */ +#ifdef NS_IMPL_GNUSTEP + NSMenuItem *item = (NSMenuItem *)[menu itemAtIndex:i]; + EmacsMenu *submenu = (EmacsMenu *)[item submenu]; + [submenu close]; +#endif + [menu removeItemAtIndex:i]; } @@ -715,20 +725,38 @@ - (Lisp_Object)runMenuAt: (NSPoint)p forFrame: (struct frame *)f } #ifdef NS_IMPL_GNUSTEP +- (void) close +{ + /* Close all the submenus. This has the unfortunate side-effect of + breaking tear-off menus, however if we don't do this then we get + a crash when the menus are removed during updates. */ + for (int i = 0 ; i < [self numberOfItems] ; i++) + { + NSMenuItem *item = [self itemAtIndex:i]; + if ([item hasSubmenu]) + [(EmacsMenu *)[item submenu] close]; + } + + [super close]; +} + /* GNUstep seems to have a number of required methods in NSMenuDelegate that are optional in Cocoa. */ - (void) menuWillOpen:(NSMenu *)menu { } + - (void) menuDidClose:(NSMenu *)menu { } + - (NSRect)confinementRectForMenu:(NSMenu *)menu onScreen:(NSScreen *)screen { return NSZeroRect; } + - (void)menu:(NSMenu *)menu willHighlightItem:(NSMenuItem *)item { }