From 0bd9e7825679dc169a69d92daeee98c9f16e3031 Mon Sep 17 00:00:00 2001 From: Alan Third Date: Thu, 3 Jun 2021 23:15:17 +0100 Subject: Fix GNUstep build warnings * src/nsterm.h ([EmacsWindow orderedIndex]): * src/nsterm.m ([EmacsWindow orderedIndex]): Implement orderedIndex for use under GNUstep. * src/nsmenu.m (free_frame_menubar): (ns_update_menubar): ([EmacsMenu addSubmenuWithTitle:]): ([EmacsMenu addItemWithWidgetValue:attributes:]): Cast return values to correct types. ([EmacsMenu fillWithWidgetValue:]): Move variable definition inside relevant #ifdef block. ([EmacsMenu menuWillOpen:]): ([EmacsMenu menuDidClose:]): ([EmacsMenu confinementRectForMenu:onScreen:]): ([EmacsMenu menu:willHighlightItem:]): New functions to silence build warnings. * src/nsfont.m (nsfont_open): Remove pointless fabs call. --- src/nsmenu.m | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) (limited to 'src/nsmenu.m') diff --git a/src/nsmenu.m b/src/nsmenu.m index 24aa5a0ac11..1d3e1aca0c0 100644 --- a/src/nsmenu.m +++ b/src/nsmenu.m @@ -73,7 +73,7 @@ free_frame_menubar (struct frame *f) id menu = [NSApp mainMenu]; for (int i = [menu numberOfItems] - 1 ; i >= 0; i--) { - NSMenuItem *item = [menu itemAtIndex:i]; + NSMenuItem *item = (NSMenuItem *)[menu itemAtIndex:i]; NSString *title = [item title]; if ([ns_app_name isEqualToString:title]) @@ -358,7 +358,7 @@ ns_update_menubar (struct frame *f, bool deep_p) if (i < [menu numberOfItems]) { NSString *titleStr = [NSString stringWithUTF8String: wv->name]; - NSMenuItem *item = [menu itemAtIndex:i]; + NSMenuItem *item = (NSMenuItem *)[menu itemAtIndex:i]; submenu = (EmacsMenu*)[item submenu]; [item setTitle:titleStr]; @@ -368,8 +368,10 @@ ns_update_menubar (struct frame *f, bool deep_p) else submenu = [menu addSubmenuWithTitle: wv->name]; +#ifdef NS_IMPL_COCOA if ([[submenu title] isEqualToString:@"Help"]) [NSApp setHelpMenu:submenu]; +#endif if (deep_p) [submenu fillWithWidgetValue: wv->contents]; @@ -472,7 +474,7 @@ set_frame_menubar (struct frame *f, bool deep_p) if (menu_separator_name_p (wv->name)) { - item = [NSMenuItem separatorItem]; + item = (NSMenuItem *)[NSMenuItem separatorItem]; } else { @@ -534,7 +536,7 @@ set_frame_menubar (struct frame *f, bool deep_p) needsUpdate = YES; } - +#ifdef NS_IMPL_COCOA typedef struct { const char *from, *to; } subst_t; @@ -591,17 +593,18 @@ prettify_key (const char *key) xfree (buf); return SSDATA (result); } +#endif /* NS_IMPL_COCOA */ - (void)fillWithWidgetValue: (void *)wvptr { widget_value *first_wv = (widget_value *)wvptr; - NSFont *menuFont = [NSFont menuFontOfSize:0]; NSDictionary *attributes = nil; #ifdef NS_IMPL_COCOA /* Cocoa doesn't allow multi-key sequences in its menu display, so work around it by using tabs to split the title into two columns. */ + NSFont *menuFont = [NSFont menuFontOfSize:0]; NSDictionary *font_attribs = @{NSFontAttributeName: menuFont}; CGFloat maxNameWidth = 0; CGFloat maxKeyWidth = 0; @@ -672,9 +675,9 @@ prettify_key (const char *key) - (EmacsMenu *)addSubmenuWithTitle: (const char *)title { NSString *titleStr = [NSString stringWithUTF8String: title]; - NSMenuItem *item = [self addItemWithTitle: titleStr - action: (SEL)nil /*@selector (menuDown:) */ - keyEquivalent: @""]; + NSMenuItem *item = (NSMenuItem *)[self addItemWithTitle: titleStr + action: (SEL)nil + keyEquivalent: @""]; EmacsMenu *submenu = [[EmacsMenu alloc] initWithTitle: titleStr]; [self setSubmenu: submenu forItem: item]; [submenu release]; @@ -711,6 +714,26 @@ prettify_key (const char *key) : Qnil; } +#ifdef NS_IMPL_GNUSTEP +/* 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 +{ +} +#endif + @end /* EmacsMenu */ -- cgit v1.2.3 From 434c059d83b03b42e8b6f51fc6991980f06eb4b8 Mon Sep 17 00:00:00 2001 From: Alan Third Date: Thu, 10 Jun 2021 23:52:19 +0100 Subject: 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(-) (limited to 'src/nsmenu.m') 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 @@ ns_update_menubar (struct frame *f, bool deep_p) { 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 @@ ns_update_menubar (struct frame *f, bool deep_p) 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 @@ prettify_key (const char *key) } #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 { } -- cgit v1.2.3 From 0b5cf4850990ff7b32264d2a174843fe72203cd0 Mon Sep 17 00:00:00 2001 From: Alan Third Date: Sat, 12 Jun 2021 12:52:15 +0100 Subject: Move NS port toolbar handling to the window * src/nsmenu.m (free_frame_tool_bar): (update_frame_tool_bar): Remove wait_for_tool_bar and get the toolbar from the window. * src/nsterm.h (EmacsView): Remove toolbar and wait_for_tool_bar. * src/nsterm.m (ns_update_begin): ([EmacsView windowDidEnterFullScreen]): ([EmacsView windowDidExitFullScreen]): Get the toolbar from the window, not the view. ([EmacsView dealloc]): Remove toolbar from view. ([EmacsView createToolbar:]): Move method to EmacsWindow. ([EmacsView initFrameFromEmacs:]): Don't create toolbar here any more. ([EmacsView toolbar]): Remove method. ([EmacsWindow initWithEmacsFrame:fullscreen:screen:]): Create toolbar here. ([EmacsWindow createToolbar:]): Moved from EmacsView. ([EmacsWindow dealloc]): Make sure we clean up the toolbar after closing the window. --- src/nsmenu.m | 16 +++--------- src/nsterm.h | 4 --- src/nsterm.m | 84 +++++++++++++++++++++++++++--------------------------------- 3 files changed, 42 insertions(+), 62 deletions(-) (limited to 'src/nsmenu.m') diff --git a/src/nsmenu.m b/src/nsmenu.m index 1b03fe91a8b..673c0423d04 100644 --- a/src/nsmenu.m +++ b/src/nsmenu.m @@ -991,12 +991,11 @@ free_frame_tool_bar (struct frame *f) NSTRACE ("free_frame_tool_bar"); block_input (); - view->wait_for_tool_bar = NO; /* Note: This triggers an animation, which calls windowDidResize repeatedly. */ f->output_data.ns->in_animation = 1; - [[view toolbar] setVisible: NO]; + [[[view window] toolbar] setVisible: NO]; f->output_data.ns->in_animation = 0; unblock_input (); @@ -1009,12 +1008,12 @@ update_frame_tool_bar (struct frame *f) -------------------------------------------------------------------------- */ { int i, k = 0; - EmacsView *view = FRAME_NS_VIEW (f); - EmacsToolbar *toolbar = [view toolbar]; + NSWindow *window = [FRAME_NS_VIEW (f) window]; + EmacsToolbar *toolbar = (EmacsToolbar *)[window toolbar]; NSTRACE ("update_frame_tool_bar"); - if (view == nil || toolbar == nil) return; + if (window == nil || toolbar == nil) return; block_input (); #ifdef NS_IMPL_COCOA @@ -1120,13 +1119,6 @@ update_frame_tool_bar (struct frame *f) [newDict release]; } #endif - - if (view->wait_for_tool_bar && FRAME_TOOLBAR_HEIGHT (f) > 0) - { - view->wait_for_tool_bar = NO; - [view setNeedsDisplay: YES]; - } - unblock_input (); } diff --git a/src/nsterm.h b/src/nsterm.h index 40206cc4ded..f7ab8236b4c 100644 --- a/src/nsterm.h +++ b/src/nsterm.h @@ -453,9 +453,7 @@ typedef id instancetype; @public struct frame *emacsframe; int scrollbarsNeedingUpdate; - EmacsToolbar *toolbar; NSRect ns_userRect; - BOOL wait_for_tool_bar; } /* AppKit-side interface */ @@ -469,9 +467,7 @@ typedef id instancetype; /* Emacs-side interface */ - (instancetype) initFrameFromEmacs: (struct frame *) f; -- (void) createToolbar: (struct frame *)f; - (void) setWindowClosing: (BOOL)closing; -- (EmacsToolbar *) toolbar; - (void) deleteWorkingText; - (void) handleFS; - (void) setFSValue: (int)value; diff --git a/src/nsterm.m b/src/nsterm.m index b8b306e685a..ba334d5fe90 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -1026,7 +1026,7 @@ ns_update_begin (struct frame *f) { // Fix reappearing tool bar in fullscreen for Mac OS X 10.7 BOOL tbar_visible = FRAME_EXTERNAL_TOOL_BAR (f) ? YES : NO; - NSToolbar *toolbar = [FRAME_NS_VIEW (f) toolbar]; + NSToolbar *toolbar = [[FRAME_NS_VIEW (f) window] toolbar]; if (! tbar_visible != ! [toolbar isVisible]) [toolbar setVisible: tbar_visible]; } @@ -1745,9 +1745,6 @@ ns_set_undecorated (struct frame *f, Lisp_Object new_value, Lisp_Object old_valu newWindow = [[EmacsWindow alloc] initWithEmacsFrame:f]; - if (!FRAME_UNDECORATED (f)) - [view createToolbar: f]; - if ([oldWindow isKeyWindow]) [newWindow makeKeyAndOrderFront:NSApp]; @@ -6074,7 +6071,6 @@ not_in_argv (NSString *arg) name:NSViewFrameDidChangeNotification object:nil]; - [toolbar release]; if (fs_state == FULLSCREEN_BOTH) [nonfs_window release]; [super dealloc]; @@ -7155,34 +7151,6 @@ not_in_argv (NSString *arg) } -- (void)createToolbar: (struct frame *)f -{ - EmacsView *view = (EmacsView *)FRAME_NS_VIEW (f); - NSWindow *window = [view window]; - - toolbar = [[EmacsToolbar alloc] initForView: self withIdentifier: - [NSString stringWithFormat: @"Emacs Frame %d", - ns_window_num]]; - [toolbar setVisible: NO]; - [window setToolbar: toolbar]; - - /* Don't set frame garbaged until tool bar is up to date? - This avoids an extra clear and redraw (flicker) at frame creation. */ - if (FRAME_EXTERNAL_TOOL_BAR (f)) wait_for_tool_bar = YES; - else wait_for_tool_bar = NO; - - -#ifdef NS_IMPL_COCOA - { - NSButton *toggleButton; - toggleButton = [window standardWindowButton: NSWindowToolbarButton]; - [toggleButton setTarget: self]; - [toggleButton setAction: @selector (toggleToolbar: )]; - } -#endif -} - - - (instancetype) initFrameFromEmacs: (struct frame *)f { NSTRACE ("[EmacsView initFrameFromEmacs:]"); @@ -7234,10 +7202,6 @@ not_in_argv (NSString *arg) if (ns_drag_types) [self registerForDraggedTypes: ns_drag_types]; - /* toolbar support */ - if (! FRAME_UNDECORATED (f)) - [self createToolbar: f]; - #if !defined (NS_IMPL_COCOA) \ || MAC_OS_X_VERSION_MIN_REQUIRED <= 1090 #if MAC_OS_X_VERSION_MAX_ALLOWED > 1090 @@ -7517,7 +7481,7 @@ not_in_argv (NSString *arg) [NSApp setPresentationOptions: options]; } #endif - [toolbar setVisible:tbar_visible]; + [[[self window]toolbar] setVisible:tbar_visible]; } } @@ -7560,12 +7524,12 @@ not_in_argv (NSString *arg) #endif if (FRAME_EXTERNAL_TOOL_BAR (emacsframe)) { - [toolbar setVisible:YES]; + [[[self window] toolbar] setVisible:YES]; update_frame_tool_bar (emacsframe); [[self window] display]; } else - [toolbar setVisible:NO]; + [[[self window] toolbar] setVisible:NO]; if (next_maximized != -1) [[self window] performZoom:self]; @@ -7864,12 +7828,6 @@ not_in_argv (NSString *arg) } -- (EmacsToolbar *)toolbar -{ - return toolbar; -} - - /* This gets called on toolbar button click. */ - (instancetype)toolbarClicked: (id)item { @@ -8421,6 +8379,10 @@ not_in_argv (NSString *arg) if ([col alphaComponent] != (EmacsCGFloat) 1.0) [self setOpaque:NO]; + /* toolbar support */ + if (! FRAME_UNDECORATED (f)) + [self createToolbar:f]; + /* macOS Sierra automatically enables tabbed windows. We can't allow this to be enabled until it's available on a Free system. Currently it only happens by accident and is buggy anyway. */ @@ -8434,6 +8396,36 @@ not_in_argv (NSString *arg) } +- (void)createToolbar: (struct frame *)f +{ + EmacsView *view = (EmacsView *)FRAME_NS_VIEW (f); + + EmacsToolbar *toolbar = [[EmacsToolbar alloc] + initForView:view + withIdentifier:[NSString stringWithLispString:f->name]]; + [self setToolbar:toolbar]; + + update_frame_tool_bar (f); + +#ifdef NS_IMPL_COCOA + { + NSButton *toggleButton; + toggleButton = [self standardWindowButton:NSWindowToolbarButton]; + [toggleButton setTarget:view]; + [toggleButton setAction:@selector (toggleToolbar:)]; + } +#endif +} + +- (void)dealloc +{ + NSTRACE ("[EmacsWindow dealloc]"); + + /* We need to release the toolbar ourselves. */ + [[self toolbar] release]; + [super dealloc]; +} + - (NSInteger) borderWidth { return NSWidth ([self frame]) - NSWidth ([[self contentView] frame]); -- cgit v1.2.3 From 12c5ca4d825496b3c7304b75ab82a6fabdc2023d Mon Sep 17 00:00:00 2001 From: Alan Third Date: Wed, 23 Jun 2021 16:07:12 +0100 Subject: Fix some macOS problems * src/nsmenu.m (update_frame_tool_bar): Make sure the toolbar isn't displayed when it's not supposed to be. * src/nsterm.m ([EmacsView layoutSublayersOfLayer:]): Reinstate code intended to prevent a crash when running redisplay. --- src/nsmenu.m | 4 ++-- src/nsterm.m | 17 ++++++----------- 2 files changed, 8 insertions(+), 13 deletions(-) (limited to 'src/nsmenu.m') diff --git a/src/nsmenu.m b/src/nsmenu.m index 673c0423d04..bb0dd2634d8 100644 --- a/src/nsmenu.m +++ b/src/nsmenu.m @@ -1089,10 +1089,10 @@ update_frame_tool_bar (struct frame *f) #undef TOOLPROP } - if (![toolbar isVisible]) + if ([toolbar isVisible] != FRAME_EXTERNAL_TOOL_BAR (f)) { f->output_data.ns->in_animation = 1; - [toolbar setVisible: YES]; + [toolbar setVisible: FRAME_EXTERNAL_TOOL_BAR (f)]; f->output_data.ns->in_animation = 0; } diff --git a/src/nsterm.m b/src/nsterm.m index 29a86e41484..3676418c9b9 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -7945,20 +7945,15 @@ not_in_argv (NSString *arg) crashes. I think it's because this code will always be run within the run loop and for whatever reason processing input is dangerous. This technique was stolen wholesale from - nsmenu.m and seems to work. - - FIXME: I can't provoke a crash using layoutSublayersOfLayer, - however I can't understand why it would be different from - viewWillDraw. I'll leave this commented out for now, but if - nobody reports a crash it can be removed. */ - // bool owfi = waiting_for_input; - // waiting_for_input = 0; - // block_input (); + nsmenu.m and seems to work. */ + bool owfi = waiting_for_input; + waiting_for_input = 0; + block_input (); redisplay (); - // unblock_input (); - // waiting_for_input = owfi; + unblock_input (); + waiting_for_input = owfi; } } #endif -- cgit v1.2.3