/* NeXT/Open/GNUstep and MacOSX Cocoa menu and toolbar module.
- Copyright (C) 2007-2011 Free Software Foundation, Inc.
+ Copyright (C) 2007-2012 Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include "lisp.h"
#include "window.h"
+#include "character.h"
#include "buffer.h"
#include "keymap.h"
#include "coding.h"
static int popup_activated_flag;
static NSModalSession popupSession;
+/* Nonzero means we are tracking and updating menus. */
+static int trackingMenu;
+
+
/* NOTE: toolbar implementation is at end,
following complete menu implementation. */
int *submenu_top_level_items, *submenu_n_panes;
struct buffer *prev = current_buffer;
Lisp_Object buffer;
- int specpdl_count = SPECPDL_INDEX ();
+ ptrdiff_t specpdl_count = SPECPDL_INDEX ();
int previous_menu_items_used = f->menu_bar_items_used;
Lisp_Object *previous_items
= (Lisp_Object *) alloca (previous_menu_items_used
items = FRAME_MENU_BAR_ITEMS (f);
if (NILP (items))
{
+ free_menubar_widget_value_tree (first_wv);
[pool release];
UNBLOCK_INPUT;
return;
if (i == n)
{
+ free_menubar_widget_value_tree (first_wv);
[pool release];
UNBLOCK_INPUT;
return;
wv->enabled = 1;
wv->button_type = BUTTON_TYPE_NONE;
wv->help = Qnil;
- wv->call_data = (void *) (EMACS_INT) (-1);
+ wv->call_data = (void *) (intptr_t) (-1);
#ifdef NS_IMPL_COCOA
/* we'll update the real copy under app menu when time comes */
frame = f;
}
+#ifdef NS_IMPL_COCOA
+#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5
+extern NSString *NSMenuDidBeginTrackingNotification;
+#endif
+#endif
+
+#ifdef NS_IMPL_COCOA
+-(void)trackingNotification:(NSNotification *)notification
+{
+ /* Update menu in menuNeedsUpdate only while tracking menus. */
+ trackingMenu = ([notification name] == NSMenuDidBeginTrackingNotification
+ ? 1 : 0);
+}
+#endif
/* delegate method called when a submenu is being opened: run a 'deep' call
to set_frame_menubar */
- (void)menuNeedsUpdate: (NSMenu *)menu
{
- NSEvent *event;
if (!FRAME_LIVE_P (frame))
return;
- event = [[FRAME_NS_VIEW (frame) window] currentEvent];
- /* HACK: Cocoa/Carbon will request update on every keystroke
+
+ /* Cocoa/Carbon will request update on every keystroke
via IsMenuKeyEvent -> CheckMenusForKeyEvent. These are not needed
since key equivalents are handled through emacs.
- On Leopard, even keystroke events generate SystemDefined events, but
- their subtype is 8. */
- if ([event type] != NSSystemDefined || [event subtype] == 8
+ On Leopard, even keystroke events generate SystemDefined event.
+ Third-party applications that enhance mouse / trackpad
+ interaction, or also VNC/Remote Desktop will send events
+ of type AppDefined rather than SysDefined.
+ Menus will fail to show up if they haven't been initialized.
+ AppDefined events may lack timing data.
+
+ Thus, we rely on the didBeginTrackingNotification notification
+ as above to indicate the need for updates.
+ From 10.6 on, we could also use -[NSMenu propertiesToUpdate]: In the
+ key press case, NSMenuPropertyItemImage (e.g.) won't be set.
+ */
+ if (trackingMenu == 0
/* Also, don't try this if from an event picked up asynchronously,
as lots of lisp evaluation happens in ns_update_menubar. */
|| handling_signal != 0)
EmacsMenu *pmenu;
NSPoint p;
Lisp_Object window, tem, keymap;
- int specpdl_count = SPECPDL_INDEX ();
+ ptrdiff_t specpdl_count = SPECPDL_INDEX ();
widget_value *wv, *first_wv = 0;
p.x = x; p.y = y;
BOOL enabled_p = !NILP (TOOLPROP (TOOL_BAR_ITEM_ENABLED_P));
BOOL selected_p = !NILP (TOOLPROP (TOOL_BAR_ITEM_SELECTED_P));
int idx;
- int img_id;
+ ptrdiff_t img_id;
struct image *img;
Lisp_Object image;
Lisp_Object helpObj;
[textField setEditable: NO];
[textField setSelectable: NO];
- [textField setBordered: YES];
- [textField setBezeled: YES];
+ [textField setBordered: NO];
+ [textField setBezeled: NO];
[textField setDrawsBackground: YES];
win = [[NSWindow alloc]
styleMask: 0
backing: NSBackingStoreBuffered
defer: YES];
+ [win setHasShadow: YES];
[win setReleasedWhenClosed: NO];
[win setDelegate: self];
[[win contentView] addSubview: textField];
- (void) setText: (char *)text
{
NSString *str = [NSString stringWithUTF8String: text];
- NSRect r = [textField frame];
- NSSize textSize = [str sizeWithAttributes:
- [NSDictionary dictionaryWithObject: [[textField font] screenFont]
- forKey: NSFontAttributeName]];
- NSSize padSize = [[[textField font] screenFont]
- boundingRectForFont].size;
-
- r.size.width = textSize.width + padSize.width/2;
- r.size.height = textSize.height + padSize.height/2;
- [textField setFrame: r];
+ NSRect r = [textField frame];
+ NSSize tooltipDims;
+
[textField setStringValue: str];
+ tooltipDims = [[textField cell] cellSize];
+
+ r.size.width = tooltipDims.width;
+ r.size.height = tooltipDims.height;
+ [textField setFrame: r];
}
- (void) showAtX: (int)x Y: (int)y for: (int)seconds
ns_popup_dialog (Lisp_Object position, Lisp_Object contents, Lisp_Object header)
{
id dialog;
- Lisp_Object window, tem;
+ Lisp_Object window, tem, title;
struct frame *f;
NSPoint p;
BOOL isQ;
p.x = (int)f->left_pos + ((int)FRAME_COLUMN_WIDTH (f) * f->text_cols)/2;
p.y = (int)f->top_pos + (FRAME_LINE_HEIGHT (f) * f->text_lines)/2;
+ title = Fcar (contents);
+ CHECK_STRING (title);
+
+ if (NILP (Fcar (Fcdr (contents))))
+ /* No buttons specified, add an "Ok" button so users can pop down
+ the dialog. */
+ contents = Fcons (title, Fcons (Fcons (build_string ("Ok"), Qt), Qnil));
+
BLOCK_INPUT;
dialog = [[EmacsDialogPanel alloc] initFromContents: contents
isQuestion: isQ];
{
- int specpdl_count = SPECPDL_INDEX ();
+ ptrdiff_t specpdl_count = SPECPDL_INDEX ();
record_unwind_protect (pop_down_menu, make_save_value (dialog, 0));
popup_activated_flag = 1;
tem = [dialog runDialogAt: p];
void
syms_of_nsmenu (void)
{
+#ifndef NS_IMPL_COCOA
+ /* Don't know how to keep track of this in Next/Open/Gnustep. Always
+ update menus there. */
+ trackingMenu = 1;
+#endif
defsubr (&Sx_popup_dialog);
defsubr (&Sns_reset_menu);
defsubr (&Smenu_or_popup_active_p);