(x_delete_terminal): Put previous change in #if 0 and
[bpt/emacs.git] / src / nsmenu.m
index b3c5680..aab3016 100644 (file)
@@ -73,6 +73,7 @@ EmacsMenu *mainMenu, *svcsMenu, *dockMenu;
 
 /* Nonzero means a menu is currently active.  */
 static int popup_activated_flag;
+static NSModalSession popupSession;
 
 /* NOTE: toolbar implementation is at end,
   following complete menu implementation. */
@@ -573,7 +574,10 @@ name_is_separator (name)
      since key equivalents are handled through emacs.
      On Leopard, even keystroke events generate SystemDefined events, but
      their subtype is 8. */
-  if ([event type] != NSSystemDefined || [event subtype] == 8)
+  if ([event type] != NSSystemDefined || [event subtype] == 8
+      /* Also, don't try this if from an event picked up asynchronously,
+         as lots of lisp evaluation happens in ns_update_menubar. */
+      || handling_signal != 0)
     return;
 /*fprintf (stderr, "Updating menu '%s'\n", [[self title] UTF8String]); NSLog (@"%@\n", event); */
   ns_update_menubar (frame, 1, self);
@@ -632,8 +636,11 @@ name_is_separator (name)
         title = @"< ? >";  /* (get out in the open so we know about it) */
 
       keyEq = [self parseKeyEquiv: wv->key];
+#ifdef NS_IMPL_COCOA
+      /* OS X just ignores modifier strings longer than one character */
       if (keyEquivModMask == 0)
         title = [title stringByAppendingFormat: @" (%@)", keyEq];
+#endif
 
       item = [self addItemWithTitle: (NSString *)title
                              action: @selector (menuDown:)
@@ -688,7 +695,7 @@ name_is_separator (name)
 
       if (wv->contents)
         {
-          EmacsMenu *submenu = [[EmacsMenu alloc] initWithTitle: @"Submenu"];
+          EmacsMenu *submenu = [[EmacsMenu alloc] initWithTitle: [item title]];
 
           [self setSubmenu: submenu forItem: item];
           [submenu fillWithWidgetValue: wv->contents];
@@ -1432,7 +1439,14 @@ update_frame_tool_bar (FRAME_PTR f)
 {
   NSString *str = [NSString stringWithUTF8String: text];
   NSRect r = [textField frame];
-  r.size.width = [[[textField font] screenFont] widthOfString: str] + 8;
+  NSSize textSize = [str sizeWithAttributes: 
+     [NSDictionary dictionaryWithObject: [[textField font] screenFont]
+                                forKey: NSFontAttributeName]];
+  NSSize padSize = [[[textField font] screenFont] 
+                    boundingRectForFont].size;
+  r.size.width = textSize.width + padSize.width/2;
+  r.size.height = textSize.height + padSize.height/2;
   [textField setFrame: r];
   [textField setStringValue: str];
 }
@@ -1485,6 +1499,24 @@ update_frame_tool_bar (FRAME_PTR f)
 
    ========================================================================== */
 
+
+static Lisp_Object
+pop_down_menu (Lisp_Object arg)
+{
+  struct Lisp_Save_Value *p = XSAVE_VALUE (arg);
+  if (popup_activated_flag)
+    {
+      popup_activated_flag = 0;
+      BLOCK_INPUT;
+      [NSApp endModalSession: popupSession];
+      [((EmacsDialogPanel *) (p->pointer)) close];
+      [[FRAME_NS_VIEW (SELECTED_FRAME ()) window] makeKeyWindow];
+      UNBLOCK_INPUT;
+    }
+  return Qnil;
+}
+
+
 Lisp_Object
 ns_popup_dialog (Lisp_Object position, Lisp_Object contents, Lisp_Object header)
 {
@@ -1537,15 +1569,19 @@ ns_popup_dialog (Lisp_Object position, Lisp_Object contents, Lisp_Object header)
 
   p.x = (int)f->left_pos + ((int)FRAME_COLUMN_WIDTH (f) * f->text_cols)/2;
   p.y = (int)f->top_pos + (FRAME_LINE_HEIGHT (f) * f->text_lines)/2;
+
+  BLOCK_INPUT;
   dialog = [[EmacsDialogPanel alloc] initFromContents: contents
                                            isQuestion: isQ];
-  popup_activated_flag = 1;
-  tem = [dialog runDialogAt: p];
-  popup_activated_flag = 0;
-
-  [dialog close];
+  {
+    int specpdl_count = SPECPDL_INDEX ();
+    record_unwind_protect (pop_down_menu, make_save_value (dialog, 0));
+    popup_activated_flag = 1;
+    tem = [dialog runDialogAt: p];
+    unbind_to (specpdl_count, Qnil);  /* calls pop_down_menu */
+  }
+  UNBLOCK_INPUT;
 
-  [[FRAME_NS_VIEW (SELECTED_FRAME ()) window] makeKeyWindow];
   return tem;
 }
 
@@ -1688,11 +1724,11 @@ void process_dialog (id window, Lisp_Object list)
       item = XCAR (list);
       if (XTYPE (item) == Lisp_String)
         {
-          [window addString: XSTRING (item)->data row: row++];
+          [window addString: SDATA (item) row: row++];
         }
       else if (XTYPE (item) == Lisp_Cons)
         {
-          [window addButton: XSTRING (XCAR (item))->data
+          [window addButton: SDATA (XCAR (item))
                       value: XCDR (item) row: row++];
         }
       else if (NILP (item))
@@ -1782,7 +1818,7 @@ void process_dialog (id window, Lisp_Object list)
 
   if (XTYPE (head) == Lisp_String)
       [title setStringValue:
-                 [NSString stringWithUTF8String: XSTRING (head)->data]];
+                 [NSString stringWithUTF8String: SDATA (head)]];
   else if (isQ == YES)
       [title setStringValue: @"Question"];
   else
@@ -1850,25 +1886,21 @@ void process_dialog (id window, Lisp_Object list)
 
 - (Lisp_Object)runDialogAt: (NSPoint)p
 {
-  NSEvent *e;
-  NSModalSession session;
   int ret;
 
-  [self center];  /*XXX p ignored? */
-  [self orderFront: NSApp];
-
-  session = [NSApp beginModalSessionForWindow: self];
-  while ((ret = [NSApp runModalSession: session]) == NSRunContinuesResponse)
+  /* initiate a session that will be ended by pop_down_menu */
+  popupSession = [NSApp beginModalSessionForWindow: self];
+  while (popup_activated_flag
+         && (ret = [NSApp runModalSession: popupSession])
+              == NSRunContinuesResponse)
     {
-    (e = [NSApp nextEventMatchingMask: NSAnyEventMask
-                            untilDate: [NSDate distantFuture]
-                               inMode: NSModalPanelRunLoopMode
-                              dequeue: NO]);
-/*fprintf (stderr, "ret = %d\te = %p\n", ret, e);*/
+      /* Run this for timers.el, indep of atimers; might not return.
+         TODO: use return value to avoid calling every iteration. */
+      timer_check (1);
+      [NSThread sleepUntilDate: [NSDate dateWithTimeIntervalSinceNow: 0.1]];
     }
-  [NSApp endModalSession: session];
 
-  {                            // FIXME: BIG UGLY HACK!!!
+  {                            /* FIXME: BIG UGLY HACK!!! */
       Lisp_Object tmp;
       *(EMACS_INT*)(&tmp) = ret;
       return tmp;
@@ -1878,7 +1910,6 @@ void process_dialog (id window, Lisp_Object list)
 @end
 
 
-
 /* ==========================================================================
 
     Lisp definitions