aboutsummaryrefslogtreecommitdiffstats
path: root/src/nsmenu.m
diff options
context:
space:
mode:
Diffstat (limited to 'src/nsmenu.m')
-rw-r--r--src/nsmenu.m83
1 files changed, 62 insertions, 21 deletions
diff --git a/src/nsmenu.m b/src/nsmenu.m
index 6a9ee7dd4f5..7a6434941d2 100644
--- a/src/nsmenu.m
+++ b/src/nsmenu.m
@@ -1,5 +1,5 @@
1/* NeXT/Open/GNUstep and MacOSX Cocoa menu and toolbar module. 1/* NeXT/Open/GNUstep and MacOSX Cocoa menu and toolbar module.
2 Copyright (C) 2007-2011 Free Software Foundation, Inc. 2 Copyright (C) 2007-2012 Free Software Foundation, Inc.
3 3
4This file is part of GNU Emacs. 4This file is part of GNU Emacs.
5 5
@@ -74,6 +74,10 @@ EmacsMenu *mainMenu, *svcsMenu, *dockMenu;
74static int popup_activated_flag; 74static int popup_activated_flag;
75static NSModalSession popupSession; 75static NSModalSession popupSession;
76 76
77/* Nonzero means we are tracking and updating menus. */
78static int trackingMenu;
79
80
77/* NOTE: toolbar implementation is at end, 81/* NOTE: toolbar implementation is at end,
78 following complete menu implementation. */ 82 following complete menu implementation. */
79 83
@@ -400,6 +404,7 @@ ns_update_menubar (struct frame *f, int deep_p, EmacsMenu *submenu)
400 items = FRAME_MENU_BAR_ITEMS (f); 404 items = FRAME_MENU_BAR_ITEMS (f);
401 if (NILP (items)) 405 if (NILP (items))
402 { 406 {
407 free_menubar_widget_value_tree (first_wv);
403 [pool release]; 408 [pool release];
404 UNBLOCK_INPUT; 409 UNBLOCK_INPUT;
405 return; 410 return;
@@ -427,6 +432,7 @@ ns_update_menubar (struct frame *f, int deep_p, EmacsMenu *submenu)
427 432
428 if (i == n) 433 if (i == n)
429 { 434 {
435 free_menubar_widget_value_tree (first_wv);
430 [pool release]; 436 [pool release];
431 UNBLOCK_INPUT; 437 UNBLOCK_INPUT;
432 return; 438 return;
@@ -543,21 +549,44 @@ set_frame_menubar (struct frame *f, int first_time, int deep_p)
543 frame = f; 549 frame = f;
544} 550}
545 551
552#ifdef NS_IMPL_COCOA
553#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5
554extern NSString *NSMenuDidBeginTrackingNotification;
555#endif
556#endif
557
558#ifdef NS_IMPL_COCOA
559-(void)trackingNotification:(NSNotification *)notification
560{
561 /* Update menu in menuNeedsUpdate only while tracking menus. */
562 trackingMenu = ([notification name] == NSMenuDidBeginTrackingNotification
563 ? 1 : 0);
564}
565#endif
546 566
547/* delegate method called when a submenu is being opened: run a 'deep' call 567/* delegate method called when a submenu is being opened: run a 'deep' call
548 to set_frame_menubar */ 568 to set_frame_menubar */
549- (void)menuNeedsUpdate: (NSMenu *)menu 569- (void)menuNeedsUpdate: (NSMenu *)menu
550{ 570{
551 NSEvent *event;
552 if (!FRAME_LIVE_P (frame)) 571 if (!FRAME_LIVE_P (frame))
553 return; 572 return;
554 event = [[FRAME_NS_VIEW (frame) window] currentEvent]; 573
555 /* HACK: Cocoa/Carbon will request update on every keystroke 574 /* Cocoa/Carbon will request update on every keystroke
556 via IsMenuKeyEvent -> CheckMenusForKeyEvent. These are not needed 575 via IsMenuKeyEvent -> CheckMenusForKeyEvent. These are not needed
557 since key equivalents are handled through emacs. 576 since key equivalents are handled through emacs.
558 On Leopard, even keystroke events generate SystemDefined events, but 577 On Leopard, even keystroke events generate SystemDefined event.
559 their subtype is 8. */ 578 Third-party applications that enhance mouse / trackpad
560 if ([event type] != NSSystemDefined || [event subtype] == 8 579 interaction, or also VNC/Remote Desktop will send events
580 of type AppDefined rather than SysDefined.
581 Menus will fail to show up if they haven't been initialized.
582 AppDefined events may lack timing data.
583
584 Thus, we rely on the didBeginTrackingNotification notification
585 as above to indicate the need for updates.
586 From 10.6 on, we could also use -[NSMenu propertiesToUpdate]: In the
587 key press case, NSMenuPropertyItemImage (e.g.) won't be set.
588 */
589 if (trackingMenu == 0
561 /* Also, don't try this if from an event picked up asynchronously, 590 /* Also, don't try this if from an event picked up asynchronously,
562 as lots of lisp evaluation happens in ns_update_menubar. */ 591 as lots of lisp evaluation happens in ns_update_menubar. */
563 || handling_signal != 0) 592 || handling_signal != 0)
@@ -1014,7 +1043,7 @@ update_frame_tool_bar (FRAME_PTR f)
1014 BOOL enabled_p = !NILP (TOOLPROP (TOOL_BAR_ITEM_ENABLED_P)); 1043 BOOL enabled_p = !NILP (TOOLPROP (TOOL_BAR_ITEM_ENABLED_P));
1015 BOOL selected_p = !NILP (TOOLPROP (TOOL_BAR_ITEM_SELECTED_P)); 1044 BOOL selected_p = !NILP (TOOLPROP (TOOL_BAR_ITEM_SELECTED_P));
1016 int idx; 1045 int idx;
1017 int img_id; 1046 ptrdiff_t img_id;
1018 struct image *img; 1047 struct image *img;
1019 Lisp_Object image; 1048 Lisp_Object image;
1020 Lisp_Object helpObj; 1049 Lisp_Object helpObj;
@@ -1228,8 +1257,8 @@ update_frame_tool_bar (FRAME_PTR f)
1228 1257
1229 [textField setEditable: NO]; 1258 [textField setEditable: NO];
1230 [textField setSelectable: NO]; 1259 [textField setSelectable: NO];
1231 [textField setBordered: YES]; 1260 [textField setBordered: NO];
1232 [textField setBezeled: YES]; 1261 [textField setBezeled: NO];
1233 [textField setDrawsBackground: YES]; 1262 [textField setDrawsBackground: YES];
1234 1263
1235 win = [[NSWindow alloc] 1264 win = [[NSWindow alloc]
@@ -1237,6 +1266,7 @@ update_frame_tool_bar (FRAME_PTR f)
1237 styleMask: 0 1266 styleMask: 0
1238 backing: NSBackingStoreBuffered 1267 backing: NSBackingStoreBuffered
1239 defer: YES]; 1268 defer: YES];
1269 [win setHasShadow: YES];
1240 [win setReleasedWhenClosed: NO]; 1270 [win setReleasedWhenClosed: NO];
1241 [win setDelegate: self]; 1271 [win setDelegate: self];
1242 [[win contentView] addSubview: textField]; 1272 [[win contentView] addSubview: textField];
@@ -1257,17 +1287,15 @@ update_frame_tool_bar (FRAME_PTR f)
1257- (void) setText: (char *)text 1287- (void) setText: (char *)text
1258{ 1288{
1259 NSString *str = [NSString stringWithUTF8String: text]; 1289 NSString *str = [NSString stringWithUTF8String: text];
1260 NSRect r = [textField frame]; 1290 NSRect r = [textField frame];
1261 NSSize textSize = [str sizeWithAttributes: 1291 NSSize tooltipDims;
1262 [NSDictionary dictionaryWithObject: [[textField font] screenFont] 1292
1263 forKey: NSFontAttributeName]];
1264 NSSize padSize = [[[textField font] screenFont]
1265 boundingRectForFont].size;
1266
1267 r.size.width = textSize.width + padSize.width/2;
1268 r.size.height = textSize.height + padSize.height/2;
1269 [textField setFrame: r];
1270 [textField setStringValue: str]; 1293 [textField setStringValue: str];
1294 tooltipDims = [[textField cell] cellSize];
1295
1296 r.size.width = tooltipDims.width;
1297 r.size.height = tooltipDims.height;
1298 [textField setFrame: r];
1271} 1299}
1272 1300
1273- (void) showAtX: (int)x Y: (int)y for: (int)seconds 1301- (void) showAtX: (int)x Y: (int)y for: (int)seconds
@@ -1340,7 +1368,7 @@ Lisp_Object
1340ns_popup_dialog (Lisp_Object position, Lisp_Object contents, Lisp_Object header) 1368ns_popup_dialog (Lisp_Object position, Lisp_Object contents, Lisp_Object header)
1341{ 1369{
1342 id dialog; 1370 id dialog;
1343 Lisp_Object window, tem; 1371 Lisp_Object window, tem, title;
1344 struct frame *f; 1372 struct frame *f;
1345 NSPoint p; 1373 NSPoint p;
1346 BOOL isQ; 1374 BOOL isQ;
@@ -1389,6 +1417,14 @@ ns_popup_dialog (Lisp_Object position, Lisp_Object contents, Lisp_Object header)
1389 p.x = (int)f->left_pos + ((int)FRAME_COLUMN_WIDTH (f) * f->text_cols)/2; 1417 p.x = (int)f->left_pos + ((int)FRAME_COLUMN_WIDTH (f) * f->text_cols)/2;
1390 p.y = (int)f->top_pos + (FRAME_LINE_HEIGHT (f) * f->text_lines)/2; 1418 p.y = (int)f->top_pos + (FRAME_LINE_HEIGHT (f) * f->text_lines)/2;
1391 1419
1420 title = Fcar (contents);
1421 CHECK_STRING (title);
1422
1423 if (NILP (Fcar (Fcdr (contents))))
1424 /* No buttons specified, add an "Ok" button so users can pop down
1425 the dialog. */
1426 contents = Fcons (title, Fcons (Fcons (build_string ("Ok"), Qt), Qnil));
1427
1392 BLOCK_INPUT; 1428 BLOCK_INPUT;
1393 dialog = [[EmacsDialogPanel alloc] initFromContents: contents 1429 dialog = [[EmacsDialogPanel alloc] initFromContents: contents
1394 isQuestion: isQ]; 1430 isQuestion: isQ];
@@ -1788,6 +1824,11 @@ DEFUN ("menu-or-popup-active-p", Fmenu_or_popup_active_p, Smenu_or_popup_active_
1788void 1824void
1789syms_of_nsmenu (void) 1825syms_of_nsmenu (void)
1790{ 1826{
1827#ifndef NS_IMPL_COCOA
1828 /* Don't know how to keep track of this in Next/Open/Gnustep. Always
1829 update menus there. */
1830 trackingMenu = 1;
1831#endif
1791 defsubr (&Sx_popup_dialog); 1832 defsubr (&Sx_popup_dialog);
1792 defsubr (&Sns_reset_menu); 1833 defsubr (&Sns_reset_menu);
1793 defsubr (&Smenu_or_popup_active_p); 1834 defsubr (&Smenu_or_popup_active_p);