emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] Changes to emacs/src/macmenu.c


From: Jan Djärv
Subject: [Emacs-diffs] Changes to emacs/src/macmenu.c
Date: Mon, 06 Jun 2005 16:24:13 -0400

Index: emacs/src/macmenu.c
diff -c emacs/src/macmenu.c:1.27 emacs/src/macmenu.c:1.28
*** emacs/src/macmenu.c:1.27    Sat Jun  4 08:06:57 2005
--- emacs/src/macmenu.c Mon Jun  6 20:24:13 2005
***************
*** 1356,1361 ****
--- 1356,1423 ----
  }
  
  
+ /* Event handler function that pops down a menu on C-g.  We can only pop
+    down menus if CancelMenuTracking is present (OSX 10.3 or later).  */
+ 
+ #ifdef HAVE_CANCELMENUTRACKING
+ static pascal OSStatus
+ menu_quit_handler (nextHandler, theEvent, userData)
+      EventHandlerCallRef nextHandler;
+      EventRef theEvent;
+      void* userData;
+ {
+   UInt32 keyCode;
+   UInt32 keyModifiers;
+   extern int mac_quit_char_modifiers;
+   extern int mac_quit_char_keycode;
+ 
+   GetEventParameter (theEvent, kEventParamKeyCode,
+                      typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode);
+ 
+   GetEventParameter (theEvent, kEventParamKeyModifiers,
+                      typeUInt32, NULL, sizeof(UInt32),
+                      NULL, &keyModifiers);
+ 
+   if (keyCode == mac_quit_char_keycode
+       && keyModifiers == mac_quit_char_modifiers)
+     {
+       MenuRef menu = userData != 0
+         ? (MenuRef)userData : AcquireRootMenu ();
+ 
+       CancelMenuTracking (menu, true, 0);
+       if (!userData) ReleaseMenu (menu);
+       return noErr;
+     }
+ 
+   return CallNextEventHandler (nextHandler, theEvent);
+ }
+ #endif /* HAVE_CANCELMENUTRACKING */
+ 
+ /* Add event handler for MENU_HANDLE so we can detect C-g.
+    If MENU_HANDLE is NULL, install handler for all menus in the menu bar.
+    If CancelMenuTracking isn't available, do nothing.  */
+ 
+ static void
+ install_menu_quit_handler (MenuHandle menu_handle)
+ {
+ #ifdef HAVE_CANCELMENUTRACKING
+   EventHandlerUPP handler = NewEventHandlerUPP(menu_quit_handler);
+   UInt32 numTypes = 1;
+   EventTypeSpec typesList[] = { { kEventClassKeyboard, kEventRawKeyDown } };
+   int i = MIN_MENU_ID;
+   MenuHandle menu = menu_handle ? menu_handle : GetMenuHandle (i);
+     
+   while (menu != NULL)
+     {
+       InstallMenuEventHandler (menu, handler, GetEventTypeCount (typesList),
+                                typesList, menu_handle, NULL);
+       if (menu_handle) break;
+       menu = GetMenuHandle (++i);
+     }
+   DisposeEventHandlerUPP (handler);
+ #endif /* HAVE_CANCELMENUTRACKING */
+ }
+ 
  /* Set the contents of the menubar widgets of frame F.
     The argument FIRST_TIME is currently ignored;
     it is set the first time this is called, from initialize_frame_menubar.  */
***************
*** 1575,1580 ****
--- 1637,1644 ----
  
    DrawMenuBar ();
  
+   /* Add event handler so we can detect C-g. */
+   install_menu_quit_handler (NULL);
    free_menubar_widget_value_tree (first_wv);
  
    UNBLOCK_INPUT;
***************
*** 1606,1612 ****
  }
  
  
! /* mac_menu_show actually displays a menu using the panes and items in
     menu_items and returns the value selected from it; we assume input
     is blocked by the caller.  */
  
--- 1670,1712 ----
  }
  
  
! static Lisp_Object
! pop_down_menu (arg)
!      Lisp_Object arg;
! {
!   struct Lisp_Save_Value *p1 = XSAVE_VALUE (Fcar (arg));
!   struct Lisp_Save_Value *p2 = XSAVE_VALUE (Fcdr (arg));
!   
!   FRAME_PTR f = p1->pointer;
!   MenuHandle *menu = p2->pointer;
! 
!   BLOCK_INPUT;
! 
!   /* Must reset this manually because the button release event is not
!      passed to Emacs event loop. */
!   FRAME_MAC_DISPLAY_INFO (f)->grabbed = 0;
! 
!   /* delete all menus */
!   {
!     int i = MIN_POPUP_SUBMENU_ID;
!     MenuHandle submenu = GetMenuHandle (i);
!     while (submenu != NULL)
!       {
!       DeleteMenu (i);
!       DisposeMenu (submenu);
!       submenu = GetMenuHandle (++i);
!       }
!   }
! 
!   DeleteMenu (POPUP_SUBMENU_ID);
!   DisposeMenu (*menu);
! 
!   UNBLOCK_INPUT;
! 
!   return Qnil;
! }
! 
! /* Mac_menu_show actually displays a menu using the panes and items in
     menu_items and returns the value selected from it; we assume input
     is blocked by the caller.  */
  
***************
*** 1644,1649 ****
--- 1744,1750 ----
      = (Lisp_Object *) alloca (menu_items_used * sizeof (Lisp_Object));
    int submenu_depth = 0;
    int first_pane;
+   int specpdl_count = SPECPDL_INDEX ();
  
    *error = NULL;
  
***************
*** 1817,1823 ****
        title = ENCODE_MENU_STRING (title);
  #endif
        wv_title->name = (char *) SDATA (title);
!       wv_title->enabled = TRUE;
        wv_title->title = TRUE;
        wv_title->button_type = BUTTON_TYPE_NONE;
        wv_title->help = Qnil;
--- 1918,1924 ----
        title = ENCODE_MENU_STRING (title);
  #endif
        wv_title->name = (char *) SDATA (title);
!       wv_title->enabled = FALSE;
        wv_title->title = TRUE;
        wv_title->button_type = BUTTON_TYPE_NONE;
        wv_title->help = Qnil;
***************
*** 1830,1835 ****
--- 1931,1940 ----
    submenu_id = MIN_POPUP_SUBMENU_ID;
    fill_submenu (menu, first_wv->contents);
  
+   /* Free the widget_value objects we used to specify the
+      contents.  */
+   free_menubar_widget_value_tree (first_wv);
+ 
    /* Adjust coordinates to be root-window-relative.  */
    pos.h = x;
    pos.v = y;
***************
*** 1844,1854 ****
  
    InsertMenu (menu, -1);
  
    /* Display the menu.  */
    menu_item_choice = PopUpMenuSelect (menu, pos.v, pos.h, 0);
    menu_item_selection = LoWord (menu_item_choice);
  
!   /* Get the refcon to find the correct item*/
    if (menu_item_selection)
      {
        MenuHandle sel_menu = GetMenuHandle (HiWord (menu_item_choice));
--- 1949,1966 ----
  
    InsertMenu (menu, -1);
  
+   record_unwind_protect (pop_down_menu,
+                          Fcons (make_save_value (f, 0),
+                                 make_save_value (&menu, 0)));
+ 
+   /* Add event handler so we can detect C-g. */
+   install_menu_quit_handler (menu);
+   
    /* Display the menu.  */
    menu_item_choice = PopUpMenuSelect (menu, pos.v, pos.h, 0);
    menu_item_selection = LoWord (menu_item_choice);
  
!   /* Get the refcon to find the correct item */
    if (menu_item_selection)
      {
        MenuHandle sel_menu = GetMenuHandle (HiWord (menu_item_choice));
***************
*** 1856,1890 ****
        GetMenuItemRefCon (sel_menu, menu_item_selection, &refcon);
        }
      }
! 
! #if 0
!   /* Clean up extraneous mouse events which might have been generated
!      during the call.  */
!   discard_mouse_events ();
! #endif
! 
!   /* Must reset this manually because the button release event is not
!      passed to Emacs event loop. */
!   FRAME_MAC_DISPLAY_INFO (f)->grabbed = 0;
! 
!   /* Free the widget_value objects we used to specify the
!      contents.  */
!   free_menubar_widget_value_tree (first_wv);
! 
!   /* delete all menus */
!   {
!     int i = MIN_POPUP_SUBMENU_ID;
!     MenuHandle submenu = GetMenuHandle (i);
!     while (submenu != NULL)
!       {
!       DeleteMenu (i);
!       DisposeMenu (submenu);
!       submenu = GetMenuHandle (++i);
!       }
!   }
! 
!   DeleteMenu (POPUP_SUBMENU_ID);
!   DisposeMenu (menu);
  
    /* Find the selected item, and its pane, to return
       the proper value.  */
--- 1968,1977 ----
        GetMenuItemRefCon (sel_menu, menu_item_selection, &refcon);
        }
      }
!   else if (! for_click)
!     /* Make "Cancel" equivalent to C-g unless this menu was popped up by
!        a mouse press.  */
!     Fsignal (Qquit, Qnil);
  
    /* Find the selected item, and its pane, to return
       the proper value.  */
***************
*** 1944,1949 ****
--- 2031,2038 ----
      /* Make "Cancel" equivalent to C-g.  */
      Fsignal (Qquit, Qnil);
  
+   unbind_to (specpdl_count, Qnil);
+ 
    return Qnil;
  }
  




reply via email to

[Prev in Thread] Current Thread [Next in Thread]