diff options
Diffstat (limited to 'src/nsmenu.m')
| -rw-r--r-- | src/nsmenu.m | 83 |
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 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
| @@ -74,6 +74,10 @@ EmacsMenu *mainMenu, *svcsMenu, *dockMenu; | |||
| 74 | static int popup_activated_flag; | 74 | static int popup_activated_flag; |
| 75 | static NSModalSession popupSession; | 75 | static NSModalSession popupSession; |
| 76 | 76 | ||
| 77 | /* Nonzero means we are tracking and updating menus. */ | ||
| 78 | static 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 | ||
| 554 | extern 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 | |||
| 1340 | ns_popup_dialog (Lisp_Object position, Lisp_Object contents, Lisp_Object header) | 1368 | ns_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_ | |||
| 1788 | void | 1824 | void |
| 1789 | syms_of_nsmenu (void) | 1825 | syms_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); |