[Top][All Lists]
[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;
}