]> code.delx.au - gnu-emacs/blobdiff - src/nsmenu.m
Remove separate pool for popup dialogs (bug#23856)
[gnu-emacs] / src / nsmenu.m
index 26fe26e5e0d811a74edfc1b239a3f1e13292ff8f..83ded6daca3bf7e030c36ae88cd7bf09ad129e77 100644 (file)
@@ -1,12 +1,12 @@
 /* NeXT/Open/GNUstep and MacOSX Cocoa menu and toolbar module.
-   Copyright (C) 2007-2015 Free Software Foundation, Inc.
+   Copyright (C) 2007-2016 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
 GNU Emacs is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
+the Free Software Foundation, either version 3 of the License, or (at
+your option) any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -45,13 +45,6 @@ Carbon version by Yamamoto Mitsuharu. */
 #include <sys/types.h>
 #endif
 
-#if 0
-int menu_trace_num = 0;
-#define NSTRACE(x)        fprintf (stderr, "%s:%d: [%d] " #x "\n",        \
-                                __FILE__, __LINE__, ++menu_trace_num)
-#else
-#define NSTRACE(x)
-#endif
 
 #if 0
 /* Include lisp -> C common menu parsing code */
@@ -121,7 +114,7 @@ ns_update_menubar (struct frame *f, bool deep_p, EmacsMenu *submenu)
   long t;
 #endif
 
-  NSTRACE (ns_update_menubar);
+  NSTRACE ("ns_update_menubar");
 
   if (f != SELECTED_FRAME ())
       return;
@@ -143,12 +136,6 @@ ns_update_menubar (struct frame *f, bool deep_p, EmacsMenu *submenu)
       menu = [[EmacsMenu alloc] initWithTitle: ns_app_name];
       needsSet = YES;
     }
-  else
-    {  /* close up anything on there */
-      id attMenu = [menu attachedMenu];
-      if (attMenu != nil)
-        [attMenu close];
-    }
 
 #if NSMENUPROFILE
   ftime (&tb);
@@ -801,6 +788,8 @@ ns_menu_show (struct frame *f, int x, int y, int menuflags,
   widget_value *wv, *first_wv = 0;
   bool keymaps = (menuflags & MENU_KEYMAPS);
 
+  NSTRACE ("ns_menu_show");
+
   block_input ();
 
   p.x = x; p.y = y;
@@ -1003,10 +992,20 @@ free_frame_tool_bar (struct frame *f)
    -------------------------------------------------------------------------- */
 {
   EmacsView *view = FRAME_NS_VIEW (f);
+
+  NSTRACE ("free_frame_tool_bar");
+
   block_input ();
   view->wait_for_tool_bar = NO;
-  [[view toolbar] setVisible: NO];
+
   FRAME_TOOLBAR_HEIGHT (f) = 0;
+
+  /* Note: This trigger an animation, which calls windowDidResize
+     repeatedly. */
+  f->output_data.ns->in_animation = 1;
+  [[view toolbar] setVisible: NO];
+  f->output_data.ns->in_animation = 0;
+
   unblock_input ();
 }
 
@@ -1022,6 +1021,8 @@ update_frame_tool_bar (struct frame *f)
   EmacsToolbar *toolbar = [view toolbar];
   int oldh;
 
+  NSTRACE ("update_frame_tool_bar");
+
   if (view == nil || toolbar == nil) return;
   block_input ();
 
@@ -1101,7 +1102,11 @@ update_frame_tool_bar (struct frame *f)
     }
 
   if (![toolbar isVisible])
+    {
+      f->output_data.ns->in_animation = 1;
       [toolbar setVisible: YES];
+      f->output_data.ns->in_animation = 0;
+    }
 
 #ifdef NS_IMPL_COCOA
   if ([toolbar changed])
@@ -1155,6 +1160,8 @@ update_frame_tool_bar (struct frame *f)
 
 - initForView: (EmacsView *)view withIdentifier: (NSString *)identifier
 {
+  NSTRACE ("[EmacsToolbar initForView: withIdentifier:]");
+
   self = [super initWithIdentifier: identifier];
   emacsView = view;
   [self setDisplayMode: NSToolbarDisplayModeIconOnly];
@@ -1169,6 +1176,8 @@ update_frame_tool_bar (struct frame *f)
 
 - (void)dealloc
 {
+  NSTRACE ("[EmacsToolbar dealloc]");
+
   [prevIdentifiers release];
   [activeIdentifiers release];
   [identifierToItem release];
@@ -1177,6 +1186,8 @@ update_frame_tool_bar (struct frame *f)
 
 - (void) clearActive
 {
+  NSTRACE ("[EmacsToolbar clearActive]");
+
   [prevIdentifiers release];
   prevIdentifiers = [activeIdentifiers copy];
   [activeIdentifiers removeAllObjects];
@@ -1186,6 +1197,8 @@ update_frame_tool_bar (struct frame *f)
 
 - (void) clearAll
 {
+  NSTRACE ("[EmacsToolbar clearAll]");
+
   [self clearActive];
   while ([[self items] count] > 0)
     [self removeItemAtIndex: 0];
@@ -1193,6 +1206,8 @@ update_frame_tool_bar (struct frame *f)
 
 - (BOOL) changed
 {
+  NSTRACE ("[EmacsToolbar changed]");
+
   return [activeIdentifiers isEqualToArray: prevIdentifiers] &&
     enablement == prevEnablement ? NO : YES;
 }
@@ -1203,6 +1218,8 @@ update_frame_tool_bar (struct frame *f)
                         helpText: (const char *)help
                          enabled: (BOOL)enabled
 {
+  NSTRACE ("[EmacsToolbar addDisplayItemWithImage: ...]");
+
   /* 1) come up w/identifier */
   NSString *identifier
     = [NSString stringWithFormat: @"%lu", (unsigned long)[img hash]];
@@ -1236,6 +1253,7 @@ update_frame_tool_bar (struct frame *f)
    all items to enabled state (for some reason). */
 - (void)validateVisibleItems
 {
+  NSTRACE ("[EmacsToolbar validateVisibleItems]");
 }
 
 
@@ -1245,12 +1263,16 @@ update_frame_tool_bar (struct frame *f)
       itemForItemIdentifier: (NSString *)itemIdentifier
   willBeInsertedIntoToolbar: (BOOL)flag
 {
+  NSTRACE ("[EmacsToolbar toolbar: ...]");
+
   /* look up NSToolbarItem by identifier and return... */
   return [identifierToItem objectForKey: itemIdentifier];
 }
 
 - (NSArray *)toolbarDefaultItemIdentifiers: (NSToolbar *)toolbar
 {
+  NSTRACE ("[EmacsToolbar toolbarDefaultItemIdentifiers:]");
+
   /* return entire set.. */
   return activeIdentifiers;
 }
@@ -1258,11 +1280,21 @@ update_frame_tool_bar (struct frame *f)
 /* for configuration palette (not yet supported) */
 - (NSArray *)toolbarAllowedItemIdentifiers: (NSToolbar *)toolbar
 {
+  NSTRACE ("[EmacsToolbar toolbarAllowedItemIdentifiers:]");
+
   /* return entire set... */
   return activeIdentifiers;
   //return [identifierToItem allKeys];
 }
 
+- (void)setVisible:(BOOL)shown
+{
+  NSTRACE ("[EmacsToolbar setVisible:%d]", shown);
+
+  [super setVisible:shown];
+}
+
+
 /* optional and unneeded */
 /* - toolbarWillAddItem: (NSNotification *)notification { } */
 /* - toolbarDidRemoveItem: (NSNotification *)notification { } */
@@ -1388,29 +1420,19 @@ update_frame_tool_bar (struct frame *f)
 
    ========================================================================== */
 
-struct Popdown_data
-{
-  NSAutoreleasePool *pool;
-  EmacsDialogPanel *dialog;
-};
-
 static void
 pop_down_menu (void *arg)
 {
-  struct Popdown_data *unwind_data = arg;
+  EmacsDialogPanel *panel = arg;
 
-  block_input ();
   if (popup_activated_flag)
     {
-      EmacsDialogPanel *panel = unwind_data->dialog;
+      block_input ();
       popup_activated_flag = 0;
       [panel close];
-      [unwind_data->pool release];
       [[FRAME_NS_VIEW (SELECTED_FRAME ()) window] makeKeyWindow];
+      unblock_input ();
     }
-
-  xfree (unwind_data);
-  unblock_input ();
 }
 
 
@@ -1418,12 +1440,11 @@ Lisp_Object
 ns_popup_dialog (struct frame *f, Lisp_Object header, Lisp_Object contents)
 {
   id dialog;
-  Lisp_Object window, tem, title;
+  Lisp_Object tem, title;
   NSPoint p;
   BOOL isQ;
-  NSAutoreleasePool *pool;
 
-  NSTRACE (x-popup-dialog);
+  NSTRACE ("ns_popup_dialog");
 
   isQ = NILP (header);
 
@@ -1441,18 +1462,13 @@ ns_popup_dialog (struct frame *f, Lisp_Object header, Lisp_Object contents)
     contents = list2 (title, Fcons (build_string ("Ok"), Qt));
 
   block_input ();
-  pool = [[NSAutoreleasePool alloc] init];
   dialog = [[EmacsDialogPanel alloc] initFromContents: contents
                                            isQuestion: isQ];
 
   {
     ptrdiff_t specpdl_count = SPECPDL_INDEX ();
-    struct Popdown_data *unwind_data = xmalloc (sizeof (*unwind_data));
-
-    unwind_data->pool = pool;
-    unwind_data->dialog = dialog;
 
-    record_unwind_protect_ptr (pop_down_menu, unwind_data);
+    record_unwind_protect_ptr (pop_down_menu, dialog);
     popup_activated_flag = 1;
     tem = [dialog runDialogAt: p];
     unbind_to (specpdl_count, Qnil);  /* calls pop_down_menu */
@@ -1506,7 +1522,11 @@ ns_popup_dialog (struct frame *f, Lisp_Object header, Lisp_Object contents)
   area.size.width = ICONSIZE;
   area.size.height= ICONSIZE;
   img = [[NSImage imageNamed: @"NSApplicationIcon"] copy];
+#ifdef NS_IMPL_COCOA
+#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6
   [img setScalesWhenResized: YES];
+#endif
+#endif
   [img setSize: NSMakeSize (ICONSIZE, ICONSIZE)];
   imgView = [[NSImageView alloc] initWithFrame: area];
   [imgView setImage: img];