*** empty log message ***
[bpt/emacs.git] / src / macmenu.c
index b412429..b8cfd6a 100644 (file)
@@ -1,12 +1,12 @@
 /* Menu support for GNU Emacs on Mac OS.
    Copyright (C) 2000, 2001, 2002, 2003, 2004,
-                 2005, 2006 Free Software Foundation, Inc.
+                 2005, 2006, 2007 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 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
 any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
@@ -259,6 +259,9 @@ static int menu_items_n_panes;
 /* Current depth within submenus.  */
 static int menu_items_submenu_depth;
 
+/* Nonzero means a menu is currently active.  */
+static int popup_activated_flag;
+
 /* This is set nonzero after the user activates the menu bar, and set
    to zero again after the menu bars are redisplayed by prepare_menu_bar.
    While it is nonzero, all calls to set_frame_menubar go deep.
@@ -1008,6 +1011,11 @@ for instance using the window manager, then this produces a quit and
       DialogItemIndex item_hit;
       Lisp_Object tem;
 
+      /* Force a redisplay before showing the dialog.  If a frame is
+        created just before showing the dialog, its contents may not
+        have been fully drawn.  */
+      Fredisplay (Qt);
+
       tem = Fstring_match (concat3 (build_string ("\\("),
                                    call0 (intern ("sentence-end")),
                                    build_string ("\\)\n")),
@@ -1141,7 +1149,9 @@ x_activate_menubar (f)
   set_frame_menubar (f, 0, 1);
   BLOCK_INPUT;
 
+  popup_activated_flag = 1;
   menu_choice = MenuSelect (saved_menu_event_location);
+  popup_activated_flag = 0;
   menu_id = HiWord (menu_choice);
   menu_item = LoWord (menu_choice);
 
@@ -2012,9 +2022,8 @@ mac_menu_show (f, x, y, for_click, keymaps, title, error)
      char **error;
 {
   int i;
-  UInt32 refcon;
   int menu_item_choice;
-  int menu_item_selection;
+  UInt32 menu_item_selection;
   MenuHandle menu;
   Point pos;
   widget_value *wv, *save_wv = 0, *first_wv = 0, *prev_wv = 0;
@@ -2229,7 +2238,6 @@ mac_menu_show (f, x, y, for_click, keymaps, title, error)
   LocalToGlobal (&pos);
 
   /* No selection has been chosen yet.  */
-  menu_item_choice = 0;
   menu_item_selection = 0;
 
   record_unwind_protect (pop_down_menu, make_save_value (f, 0));
@@ -2239,21 +2247,21 @@ mac_menu_show (f, x, y, for_click, keymaps, title, error)
   install_menu_quit_handler (MAC_MENU_POPUP_SUB, menu);
 
   /* Display the menu.  */
+  popup_activated_flag = 1;
   menu_item_choice = PopUpMenuSelect (menu, pos.v, pos.h, 0);
-  menu_item_selection = LoWord (menu_item_choice);
+  popup_activated_flag = 0;
 
   /* Get the refcon to find the correct item */
-  if (menu_item_selection)
+  if (menu_item_choice)
     {
       MenuHandle sel_menu = GetMenuHandle (HiWord (menu_item_choice));
-      if (sel_menu) {
-       GetMenuItemRefCon (sel_menu, menu_item_selection, &refcon);
-      }
+
+      if (sel_menu)
+       GetMenuItemRefCon (sel_menu, LoWord (menu_item_choice),
+                          &menu_item_selection);
     }
-  else if (! for_click)
-    /* Make "Cancel" equivalent to C-g unless this menu was popped up by
-       a mouse press.  */
-    Fsignal (Qquit, Qnil);
+
+  unbind_to (specpdl_count, Qnil);
 
   /* Find the selected item, and its pane, to return
      the proper value.  */
@@ -2290,7 +2298,7 @@ mac_menu_show (f, x, y, for_click, keymaps, title, error)
            {
              entry
                = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_VALUE];
-             if ((int) (EMACS_INT) refcon == i)
+             if (menu_item_selection == i)
                {
                  if (keymaps != 0)
                    {
@@ -2313,8 +2321,6 @@ mac_menu_show (f, x, y, for_click, keymaps, title, error)
     /* Make "Cancel" equivalent to C-g.  */
     Fsignal (Qquit, Qnil);
 
-  unbind_to (specpdl_count, Qnil);
-
   return Qnil;
 }
 \f
@@ -2386,10 +2392,12 @@ mac_handle_dialog_event (next_handler, event, data)
                                           typeUInt32, NULL, sizeof (UInt32),
                                           NULL, &key_code);
                if (err == noErr)
-                 if (mac_quit_char_key_p (modifiers, key_code))
-                   err = QuitAppModalLoopForWindow (window);
-                 else
-                   err = eventNotHandledErr;
+                 {
+                   if (mac_quit_char_key_p (modifiers, key_code))
+                     err = QuitAppModalLoopForWindow (window);
+                   else
+                     err = eventNotHandledErr;
+                 }
              }
              break;
            }
@@ -2460,11 +2468,11 @@ create_and_show_dialog (f, first_wv)
   SetRect (&empty_rect, 0, 0, 0, 0);
 
   /* Create dialog window.  */
-  err = CreateNewWindow (kMovableAlertWindowClass,
+  err = CreateNewWindow (kMovableModalWindowClass,
                         kWindowStandardHandlerAttribute,
                         &empty_rect, &window);
   if (err == noErr)
-    err = SetThemeWindowBackground (window, kThemeBrushAlertBackgroundActive,
+    err = SetThemeWindowBackground (window, kThemeBrushMovableModalBackground,
                                    true);
   if (err == noErr)
     err = SetWindowTitleWithCFString (window, (dialog_name[0] == 'Q'
@@ -2491,7 +2499,13 @@ create_and_show_dialog (f, first_wv)
          if (err == noErr)
            {
              if (!wv->enabled)
-               err = DisableControl (buttons[i]);
+               {
+#ifdef MAC_OSX
+                 err = DisableControl (buttons[i]);
+#else
+                 err = DeactivateControl (buttons[i]);
+#endif
+               }
              else if (default_button == NULL)
                default_button = buttons[i];
            }
@@ -2934,6 +2948,11 @@ mac_dialog_show (f, keymaps, title, header, error_name)
     first_wv = wv;
   }
 
+  /* Force a redisplay before showing the dialog.  If a frame is created
+     just before showing the dialog, its contents may not have been fully
+     drawn.  */
+  Fredisplay (Qt);
+
   /* Actually create the dialog.  */
 #if TARGET_API_MAC_CARBON
   menu_item_selection = create_and_show_dialog (f, first_wv);
@@ -3216,6 +3235,14 @@ dispose_menus (kind, id)
 
 #endif /* HAVE_MENUS */
 
+/* Detect if a menu is currently active.  */
+
+int
+popup_activated ()
+{
+  return popup_activated_flag;
+}
+
 /* The following is used by delayed window autoselection.  */
 
 DEFUN ("menu-or-popup-active-p", Fmenu_or_popup_active_p, Smenu_or_popup_active_p, 0, 0, 0,