X-Git-Url: https://git.hcoop.net/bpt/emacs.git/blobdiff_plain/76b6f7075970e492eba3cf3f4411fcfc4ff3bdcd..0613f5d515c2f7fe7930ad5f7d3e177e1fd3b44c:/src/nsmenu.m diff --git a/src/nsmenu.m b/src/nsmenu.m index 3d190a9b25..e5b9379258 100644 --- a/src/nsmenu.m +++ b/src/nsmenu.m @@ -1,5 +1,5 @@ /* NeXT/Open/GNUstep and MacOSX Cocoa menu and toolbar module. - Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc. + Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -24,6 +24,7 @@ Carbon version by Yamamoto Mitsuharu. */ /* This should be the first include, as it may set up #defines affecting interpretation of even the system includes. */ #include "config.h" +#include #include "lisp.h" #include "window.h" @@ -35,10 +36,14 @@ Carbon version by Yamamoto Mitsuharu. */ #include "nsterm.h" #include "termhooks.h" #include "keyboard.h" +#include "menu.h" -/* for profiling */ +#define NSMENUPROFILE 0 + +#if NSMENUPROFILE #include #include +#endif #define MenuStagger 10.0 @@ -59,8 +64,6 @@ int menu_trace_num = 0; extern Lisp_Object Qundefined, Qmenu_enable, Qmenu_bar_update_hook; extern Lisp_Object QCtoggle, QCradio; -extern Lisp_Object Vmenu_updating_frame; - Lisp_Object Qdebug_on_next_call; extern Lisp_Object Voverriding_local_map, Voverriding_local_map_menu_flag, Qoverriding_local_map, Qoverriding_terminal_local_map; @@ -70,6 +73,7 @@ EmacsMenu *mainMenu, *svcsMenu, *dockMenu; /* Nonzero means a menu is currently active. */ static int popup_activated_flag; +static NSModalSession popupSession; /* NOTE: toolbar implementation is at end, following complete menu implementation. */ @@ -82,7 +86,7 @@ static int popup_activated_flag; ========================================================================== */ -/*23: FIXME: not currently used, but should normalize with other terms. */ +/* FIXME: not currently used, but should normalize with other terms. */ void x_activate_menubar (struct frame *f) { @@ -114,7 +118,6 @@ popup_activated () 2) deep_p = 1, submenu = nil: Recompute all submenus. 3) deep_p = 1, submenu = non-nil: Update contents of a single submenu. -------------------------------------------------------------------------- */ -/*#define NSMENUPROFILE 1 */ void ns_update_menubar (struct frame *f, int deep_p, EmacsMenu *submenu) { @@ -129,7 +132,7 @@ ns_update_menubar (struct frame *f, int deep_p, EmacsMenu *submenu) widget_value *wv, *first_wv, *prev_wv = 0; int i; -#ifdef NSMENUPROFILE +#if NSMENUPROFILE struct timeb tb; long t; #endif @@ -153,7 +156,7 @@ ns_update_menubar (struct frame *f, int deep_p, EmacsMenu *submenu) if (menu == nil) { - menu = [[EmacsMenu alloc] initWithTitle: @"Emacs"]; + menu = [[EmacsMenu alloc] initWithTitle: ns_app_name]; needsSet = YES; } else @@ -163,21 +166,11 @@ ns_update_menubar (struct frame *f, int deep_p, EmacsMenu *submenu) [attMenu close]; } -#ifdef NSMENUPROFILE +#if NSMENUPROFILE ftime (&tb); t = -(1000*tb.time+tb.millitm); #endif - /* widget_value is a straightforward object translation of emacs's - Byzantine lisp menu structures */ - wv = xmalloc_widget_value (); - wv->name = "Emacs"; - wv->value = 0; - wv->enabled = 1; - wv->button_type = BUTTON_TYPE_NONE; - wv->help = Qnil; - first_wv = wv; - #ifdef NS_IMPL_GNUSTEP deep_p = 1; /* until GNUstep NSMenu implements the Panther delegation model */ #endif @@ -226,8 +219,8 @@ ns_update_menubar (struct frame *f, int deep_p, EmacsMenu *submenu) /* Save the frame's previous menu bar contents data */ if (previous_menu_items_used) - bcopy (XVECTOR (f->menu_bar_vector)->contents, previous_items, - previous_menu_items_used * sizeof (Lisp_Object)); + memcpy (previous_items, XVECTOR (f->menu_bar_vector)->contents, + previous_menu_items_used * sizeof (Lisp_Object)); /* parse stage 1: extract from lisp */ save_menu_items (); @@ -329,7 +322,7 @@ ns_update_menubar (struct frame *f, int deep_p, EmacsMenu *submenu) { /* No change.. */ -#ifdef NSMENUPROFILE +#if NSMENUPROFILE ftime (&tb); t += 1000*tb.time+tb.millitm; fprintf (stderr, "NO CHANGE! CUTTING OUT after %ld msec.\n", t); @@ -396,6 +389,14 @@ ns_update_menubar (struct frame *f, int deep_p, EmacsMenu *submenu) int n; Lisp_Object string; + wv = xmalloc_widget_value (); + wv->name = "menubar"; + wv->value = 0; + wv->enabled = 1; + wv->button_type = BUTTON_TYPE_NONE; + wv->help = Qnil; + first_wv = wv; + /* Make widget-value tree w/ just the top level menu bar strings */ items = FRAME_MENU_BAR_ITEMS (f); if (NILP (items)) @@ -480,7 +481,7 @@ ns_update_menubar (struct frame *f, int deep_p, EmacsMenu *submenu) free_menubar_widget_value_tree (first_wv); -#ifdef NSMENUPROFILE +#if NSMENUPROFILE ftime (&tb); t += 1000*tb.time+tb.millitm; fprintf (stderr, "Menu update took %ld msec.\n", t); @@ -565,13 +566,19 @@ name_is_separator (name) to set_frame_menubar */ - (void)menuNeedsUpdate: (NSMenu *)menu { - NSEvent *event = [[FRAME_NS_VIEW (frame) window] currentEvent]; + NSEvent *event; + if (!FRAME_LIVE_P (frame)) + return; + event = [[FRAME_NS_VIEW (frame) window] currentEvent]; /* HACK: 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) + if ([event type] != NSSystemDefined || [event subtype] == 8 + /* 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) return; /*fprintf (stderr, "Updating menu '%s'\n", [[self title] UTF8String]); NSLog (@"%@\n", event); */ ns_update_menubar (frame, 1, self); @@ -587,22 +594,29 @@ name_is_separator (name) } -/* parse a wdiget_value's key rep (examples: 's-p', 's-S', '(C-x C-s)', '') - into an accelerator string */ +/* Parse a widget_value's key rep (examples: 's-p', 's-S', '(C-x C-s)', '') + into an accelerator string. We are only able to display a single character + for an accelerator, together with an optional modifier combination. (Under + Carbon more control was possible, but in Cocoa multi-char strings passed to + NSMenuItem get ignored. For now we try to display a super-single letter + combo, and return the others as strings to be appended to the item title. + (This is signaled by setting keyEquivModMask to 0 for now.) */ -(NSString *)parseKeyEquiv: (char *)key { char *tpos = key; - keyEquivModMask = 0; - /* currently we just parse 'super' combinations; - later we'll set keyEquivModMask */ + keyEquivModMask = NSCommandKeyMask; + if (!key || !strlen (key)) return @""; while (*tpos == ' ' || *tpos == '(') tpos++; - if (*tpos != 's'/* || tpos[3] != ')'*/) - return @""; - return [NSString stringWithFormat: @"%c", tpos[2]]; + if ((*tpos == 's') && (*(tpos+1) == '-')) + { + return [NSString stringWithFormat: @"%c", tpos[2]]; + } + keyEquivModMask = 0; /* signal */ + return [NSString stringWithUTF8String: tpos]; } @@ -624,12 +638,16 @@ name_is_separator (name) title = @"< ? >"; /* (get out in the open so we know about it) */ keyEq = [self parseKeyEquiv: wv->key]; +#ifdef NS_IMPL_COCOA + /* OS X just ignores modifier strings longer than one character */ + if (keyEquivModMask == 0) + title = [title stringByAppendingFormat: @" (%@)", keyEq]; +#endif item = [self addItemWithTitle: (NSString *)title action: @selector (menuDown:) keyEquivalent: keyEq]; - if (keyEquivModMask) - [item setKeyEquivalentModifierMask: keyEquivModMask]; + [item setKeyEquivalentModifierMask: keyEquivModMask]; [item setEnabled: wv->enabled]; @@ -640,7 +658,7 @@ name_is_separator (name) else [item setState: NSOffState]; - [item setTag: (int)wv->call_data]; + [item setTag: (NSInteger)wv->call_data]; } return item; @@ -648,7 +666,7 @@ name_is_separator (name) /* convenience */ --(void) clear +-(void)clear { int n; @@ -656,7 +674,9 @@ name_is_separator (name) { NSMenuItem *item = [self itemAtIndex: n]; NSString *title = [item title]; - if (([title length] == 0 || [@"Apple" isEqualToString: title]) + if (([title length] == 0 /* OSX 10.5 */ + || [ns_app_name isEqualToString: title] /* from 10.6 on */ + || [@"Apple" isEqualToString: title]) /* older */ && ![item isSeparatorItem]) continue; [self removeItemAtIndex: n]; @@ -679,7 +699,7 @@ name_is_separator (name) if (wv->contents) { - EmacsMenu *submenu = [[EmacsMenu alloc] initWithTitle: @"Submenu"]; + EmacsMenu *submenu = [[EmacsMenu alloc] initWithTitle: [item title]]; [self setSubmenu: submenu forItem: item]; [submenu fillWithWidgetValue: wv->contents]; @@ -750,188 +770,17 @@ name_is_separator (name) ========================================================================== */ -static Lisp_Object -cleanup_popup_menu (Lisp_Object arg) -{ - discard_menu_items (); - return Qnil; -} - - -static Lisp_Object -ns_popup_menu (Lisp_Object position, Lisp_Object menu) +Lisp_Object +ns_menu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps, + Lisp_Object title, char **error) { EmacsMenu *pmenu; - struct frame *f = NULL; NSPoint p; - Lisp_Object window, x, y, tem, keymap, title; - struct gcpro gcpro1; - int specpdl_count = SPECPDL_INDEX (), specpdl_count2; - char *error_name = NULL; - int keymaps = 0; + Lisp_Object window, tem, keymap; + int specpdl_count = SPECPDL_INDEX (); widget_value *wv, *first_wv = 0; - NSTRACE (ns_popup_menu); - - if (!NILP (position)) - { - check_ns (); - - if (EQ (position, Qt) - || (CONSP (position) && (EQ (XCAR (position), Qmenu_bar) - || EQ (XCAR (position), Qtool_bar)))) - { - /* Use the mouse's current position. */ - struct frame *new_f = SELECTED_FRAME (); - - if (FRAME_TERMINAL (new_f)->mouse_position_hook) - (*FRAME_TERMINAL (new_f)->mouse_position_hook) - (&new_f, 0, 0, 0, &x, &y, 0); - if (new_f != 0) - XSETFRAME (window, new_f); - else - { - window = selected_window; - x = make_number (0); - y = make_number (0); - } - } - else - { - CHECK_CONS (position); - tem = Fcar (position); - if (XTYPE (tem) == Lisp_Cons) - { - window = Fcar (Fcdr (position)); - x = Fcar (tem); - y = Fcar (Fcdr (tem)); - } - else - { - tem = Fcar (Fcdr (position)); - window = Fcar (tem); - tem = Fcar (Fcdr (Fcdr (tem))); - x = Fcar (tem); - y = Fcdr (tem); - } - } - - CHECK_NUMBER (x); - CHECK_NUMBER (y); - - if (FRAMEP (window)) - { - f = XFRAME (window); - - p.x = 0; - p.y = 0; - } - else - { - struct window *win = XWINDOW (window); - CHECK_LIVE_WINDOW (window); - f = XFRAME (WINDOW_FRAME (win)); - p.x = FRAME_COLUMN_WIDTH (f) * WINDOW_LEFT_EDGE_COL (win); - p.y = FRAME_LINE_HEIGHT (f) * WINDOW_TOP_EDGE_LINE (win); - } - - p.x += XINT (x); p.y += XINT (y); - - XSETFRAME (Vmenu_updating_frame, f); - } - else - { /* no position given */ - /* FIXME: if called during dump, we need to stop precomputation of - key equivalents (see below) because the keydefs in ns-win.el have - not been loaded yet. */ - if (noninteractive) - return Qnil; - Vmenu_updating_frame = Qnil; - } - - /* now parse the lisp menus */ - record_unwind_protect (unuse_menu_items, Qnil); - title = Qnil; - GCPRO1 (title); - - /* Decode the menu items from what was specified. */ - - keymap = get_keymap (menu, 0, 0); - if (CONSP (keymap)) - { - /* We were given a keymap. Extract menu info from the keymap. */ - Lisp_Object prompt; - - /* Extract the detailed info to make one pane. */ - keymap_panes (&menu, 1, NILP (position)); - - /* Search for a string appearing directly as an element of the keymap. - That string is the title of the menu. */ - prompt = Fkeymap_prompt (keymap); - title = NILP (prompt) ? build_string ("Select") : prompt; - - /* Make that be the pane title of the first pane. */ - if (!NILP (prompt) && menu_items_n_panes >= 0) - XVECTOR (menu_items)->contents[MENU_ITEMS_PANE_NAME] = prompt; - - keymaps = 1; - } - else if (CONSP (menu) && KEYMAPP (XCAR (menu))) - { - /* We were given a list of keymaps. */ - int nmaps = XFASTINT (Flength (menu)); - Lisp_Object *maps - = (Lisp_Object *) alloca (nmaps * sizeof (Lisp_Object)); - int i; - - title = Qnil; - - /* The first keymap that has a prompt string - supplies the menu title. */ - for (tem = menu, i = 0; CONSP (tem); tem = XCDR (tem)) - { - Lisp_Object prompt; - - maps[i++] = keymap = get_keymap (XCAR (tem), 1, 0); - - prompt = Fkeymap_prompt (keymap); - if (NILP (title) && !NILP (prompt)) - title = prompt; - } - - /* Extract the detailed info to make one pane. */ - keymap_panes (maps, nmaps, NILP (position)); - - /* Make the title be the pane title of the first pane. */ - if (!NILP (title) && menu_items_n_panes >= 0) - XVECTOR (menu_items)->contents[MENU_ITEMS_PANE_NAME] = title; - - keymaps = 1; - } - else - { - /* We were given an old-fashioned menu. */ - title = Fcar (menu); - CHECK_STRING (title); - - list_of_panes (Fcdr (menu)); - - keymaps = 0; - } - - unbind_to (specpdl_count, Qnil); - - /* If no position given, that was a signal to just precompute and cache - key equivalents, which was a side-effect of what we just did. */ - if (NILP (position)) - { - discard_menu_items (); - UNGCPRO; - return Qnil; - } - - record_unwind_protect (cleanup_popup_menu, Qnil); - BLOCK_INPUT; + p.x = x; p.y = y; /* now parse stage 2 as in ns_update_menubar */ wv = xmalloc_widget_value (); @@ -942,8 +791,6 @@ ns_popup_menu (Lisp_Object position, Lisp_Object menu) wv->help = Qnil; first_wv = wv; - specpdl_count2 = SPECPDL_INDEX (); - #if 0 /* FIXME: a couple of one-line differences prevent reuse */ wv = digest_single_submenu (0, menu_items_used, Qnil); @@ -1129,25 +976,17 @@ ns_popup_menu (Lisp_Object position, Lisp_Object menu) [NSString stringWithUTF8String: SDATA (title)]]; [pmenu fillWithWidgetValue: first_wv->contents]; free_menubar_widget_value_tree (first_wv); - unbind_to (specpdl_count2, Qnil); + unbind_to (specpdl_count, Qnil); popup_activated_flag = 1; tem = [pmenu runMenuAt: p forFrame: f keymaps: keymaps]; popup_activated_flag = 0; [[FRAME_NS_VIEW (SELECTED_FRAME ()) window] makeKeyWindow]; - UNBLOCK_INPUT; - discard_menu_items (); - unbind_to (specpdl_count, Qnil); - UNGCPRO; - - if (error_name) error (error_name); return tem; } - - /* ========================================================================== Toolbar: externally-called functions @@ -1160,7 +999,10 @@ free_frame_tool_bar (FRAME_PTR f) Under NS we just hide the toolbar until it might be needed again. -------------------------------------------------------------------------- */ { + BLOCK_INPUT; [[FRAME_NS_VIEW (f) toolbar] setVisible: NO]; + FRAME_TOOLBAR_HEIGHT (f) = 0; + UNBLOCK_INPUT; } void @@ -1170,8 +1012,11 @@ update_frame_tool_bar (FRAME_PTR f) -------------------------------------------------------------------------- */ { int i; - EmacsToolbar *toolbar = [FRAME_NS_VIEW (f) toolbar]; + EmacsView *view = FRAME_NS_VIEW (f); + NSWindow *window = [view window]; + EmacsToolbar *toolbar = [view toolbar]; + BLOCK_INPUT; [toolbar clearActive]; /* update EmacsToolbar as in GtkUtils, build items list */ @@ -1255,6 +1100,10 @@ update_frame_tool_bar (FRAME_PTR f) [newDict release]; } + FRAME_TOOLBAR_HEIGHT (f) = + NSHeight ([window frameRectForContentRect: NSMakeRect (0, 0, 0, 0)]) + - FRAME_NS_TITLEBAR_HEIGHT (f); + UNBLOCK_INPUT; } @@ -1316,7 +1165,7 @@ update_frame_tool_bar (FRAME_PTR f) item = [[[NSToolbarItem alloc] initWithItemIdentifier: identifier] autorelease]; [item setImage: img]; - [item setToolTip: [NSString stringWithCString: help]]; + [item setToolTip: [NSString stringWithUTF8String: help]]; [item setTarget: emacsView]; [item setAction: @selector (toolbarClicked:)]; } @@ -1423,7 +1272,14 @@ update_frame_tool_bar (FRAME_PTR f) { NSString *str = [NSString stringWithUTF8String: text]; NSRect r = [textField frame]; - r.size.width = [[[textField font] screenFont] widthOfString: str] + 8; + 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]; [textField setStringValue: str]; } @@ -1476,6 +1332,24 @@ update_frame_tool_bar (FRAME_PTR f) ========================================================================== */ + +static Lisp_Object +pop_down_menu (Lisp_Object arg) +{ + struct Lisp_Save_Value *p = XSAVE_VALUE (arg); + if (popup_activated_flag) + { + popup_activated_flag = 0; + BLOCK_INPUT; + [NSApp endModalSession: popupSession]; + [((EmacsDialogPanel *) (p->pointer)) close]; + [[FRAME_NS_VIEW (SELECTED_FRAME ()) window] makeKeyWindow]; + UNBLOCK_INPUT; + } + return Qnil; +} + + Lisp_Object ns_popup_dialog (Lisp_Object position, Lisp_Object contents, Lisp_Object header) { @@ -1491,7 +1365,9 @@ ns_popup_dialog (Lisp_Object position, Lisp_Object contents, Lisp_Object header) isQ = NILP (header); - if (EQ (position, Qt)) + if (EQ (position, Qt) + || (CONSP (position) && (EQ (XCAR (position), Qmenu_bar) + || EQ (XCAR (position), Qtool_bar)))) { window = selected_window; } @@ -1507,34 +1383,38 @@ ns_popup_dialog (Lisp_Object position, Lisp_Object contents, Lisp_Object header) window = Fcar (tem); /* POSN_WINDOW (tem) */ } } - else if (FRAMEP (position)) + else if (WINDOWP (position) || FRAMEP (position)) { window = position; } else - { - CHECK_LIVE_WINDOW (position); - window = position; - } - + window = Qnil; + if (FRAMEP (window)) f = XFRAME (window); - else + else if (WINDOWP (window)) { CHECK_LIVE_WINDOW (window); f = XFRAME (WINDOW_FRAME (XWINDOW (window))); } + else + CHECK_WINDOW (window); + 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; + + BLOCK_INPUT; dialog = [[EmacsDialogPanel alloc] initFromContents: contents isQuestion: isQ]; - popup_activated_flag = 1; - tem = [dialog runDialogAt: p]; - popup_activated_flag = 0; - - [dialog close]; + { + int specpdl_count = SPECPDL_INDEX (); + record_unwind_protect (pop_down_menu, make_save_value (dialog, 0)); + popup_activated_flag = 1; + tem = [dialog runDialogAt: p]; + unbind_to (specpdl_count, Qnil); /* calls pop_down_menu */ + } + UNBLOCK_INPUT; - [[FRAME_NS_VIEW (SELECTED_FRAME ()) window] makeKeyWindow]; return tem; } @@ -1564,7 +1444,7 @@ ns_popup_dialog (Lisp_Object position, Lisp_Object contents, Lisp_Object header) #define TEXTHEIGHT 20.0 #define MINCELLWIDTH 90.0 -- initWithContentRect: (NSRect)contentRect styleMask: (unsigned int)aStyle +- initWithContentRect: (NSRect)contentRect styleMask: (NSUInteger)aStyle backing: (NSBackingStoreType)backingType defer: (BOOL)flag { NSSize spacing = {SPACER, SPACER}; @@ -1610,7 +1490,7 @@ ns_popup_dialog (Lisp_Object position, Lisp_Object contents, Lisp_Object header) area.size.height= TEXTHEIGHT; command = [[[NSTextField alloc] initWithFrame: area] autorelease]; [[self contentView] addSubview: command]; - [command setStringValue: @"Emacs"]; + [command setStringValue: ns_app_name]; [command setDrawsBackground: NO]; [command setBezeled: NO]; [command setSelectable: NO]; @@ -1677,11 +1557,11 @@ void process_dialog (id window, Lisp_Object list) item = XCAR (list); if (XTYPE (item) == Lisp_String) { - [window addString: XSTRING (item)->data row: row++]; + [window addString: SDATA (item) row: row++]; } else if (XTYPE (item) == Lisp_Cons) { - [window addButton: XSTRING (XCAR (item))->data + [window addButton: SDATA (XCAR (item)) value: XCDR (item) row: row++]; } else if (NILP (item)) @@ -1771,7 +1651,7 @@ void process_dialog (id window, Lisp_Object list) if (XTYPE (head) == Lisp_String) [title setStringValue: - [NSString stringWithUTF8String: XSTRING (head)->data]]; + [NSString stringWithUTF8String: SDATA (head)]]; else if (isQ == YES) [title setStringValue: @"Question"]; else @@ -1839,25 +1719,22 @@ void process_dialog (id window, Lisp_Object list) - (Lisp_Object)runDialogAt: (NSPoint)p { - NSEvent *e; - NSModalSession session; - int ret; - - [self center]; /*XXX p ignored? */ - [self orderFront: NSApp]; - - session = [NSApp beginModalSessionForWindow: self]; - while ((ret = [NSApp runModalSession: session]) == NSRunContinuesResponse) + NSInteger ret; + extern EMACS_TIME timer_check (int do_it_now); /* TODO: add to a header */ + + /* initiate a session that will be ended by pop_down_menu */ + popupSession = [NSApp beginModalSessionForWindow: self]; + while (popup_activated_flag + && (ret = [NSApp runModalSession: popupSession]) + == NSRunContinuesResponse) { - (e = [NSApp nextEventMatchingMask: NSAnyEventMask - untilDate: [NSDate distantFuture] - inMode: NSEventTrackingRunLoopMode - dequeue: NO]); -/*fprintf (stderr, "ret = %d\te = %p\n", ret, e); */ + /* Run this for timers.el, indep of atimers; might not return. + TODO: use return value to avoid calling every iteration. */ + timer_check (1); + [NSThread sleepUntilDate: [NSDate dateWithTimeIntervalSinceNow: 0.1]]; } - [NSApp endModalSession: session]; - { // FIXME: BIG UGLY HACK!!! + { /* FIXME: BIG UGLY HACK!!! */ Lisp_Object tmp; *(EMACS_INT*)(&tmp) = ret; return tmp; @@ -1867,7 +1744,6 @@ void process_dialog (id window, Lisp_Object list) @end - /* ========================================================================== Lisp definitions @@ -1876,53 +1752,13 @@ void process_dialog (id window, Lisp_Object list) DEFUN ("ns-reset-menu", Fns_reset_menu, Sns_reset_menu, 0, 0, 0, doc: /* Cause the NS menu to be re-calculated. */) - () + (void) { set_frame_menubar (SELECTED_FRAME (), 1, 0); return Qnil; } -DEFUN ("x-popup-menu", Fx_popup_menu, Sx_popup_menu, 2, 2, 0, - doc: /* Pop up a deck-of-cards menu and return user's selection. -POSITION is a position specification. This is either a mouse button event -or a list ((XOFFSET YOFFSET) WINDOW) -where XOFFSET and YOFFSET are positions in pixels from the top left -corner of WINDOW. (WINDOW may be a window or a frame object.) -This controls the position of the top left of the menu as a whole. -If POSITION is t, it means to use the current mouse position. - -MENU is a specifier for a menu. For the simplest case, MENU is a keymap. -The menu items come from key bindings that have a menu string as well as -a definition; actually, the \"definition\" in such a key binding looks like -\(STRING . REAL-DEFINITION). To give the menu a title, put a string into -the keymap as a top-level element. - -If REAL-DEFINITION is nil, that puts a nonselectable string in the menu. -Otherwise, REAL-DEFINITION should be a valid key binding definition. - -You can also use a list of keymaps as MENU. - Then each keymap makes a separate pane. - -When MENU is a keymap or a list of keymaps, the return value is the -list of events corresponding to the user's choice. Note that -`x-popup-menu' does not actually execute the command bound to that -sequence of events. - -Alternatively, you can specify a menu of multiple panes - with a list of the form (TITLE PANE1 PANE2...), -where each pane is a list of form (TITLE ITEM1 ITEM2...). -Each ITEM is normally a cons cell (STRING . VALUE); -but a string can appear as an item--that makes a nonselectable line -in the menu. -With this form of menu, the return value is VALUE from the chosen item. */) - (position, menu) - Lisp_Object position, menu; -{ - return ns_popup_menu (position, menu); -} - - DEFUN ("x-popup-dialog", Fx_popup_dialog, Sx_popup_dialog, 2, 3, 0, doc: /* Pop up a dialog box and return user's selection. POSITION specifies which frame to use. @@ -1946,15 +1782,14 @@ otherwise it is "Question". If the user gets rid of the dialog box without making a valid choice, for instance using the window manager, then this produces a quit and `x-popup-dialog' does not return. */) - (position, contents, header) - Lisp_Object position, contents, header; + (Lisp_Object position, Lisp_Object contents, Lisp_Object header) { return ns_popup_dialog (position, contents, header); } DEFUN ("menu-or-popup-active-p", Fmenu_or_popup_active_p, Smenu_or_popup_active_p, 0, 0, 0, doc: /* Return t if a menu or popup dialog is active. */) - () + (void) { return popup_activated () ? Qt : Qnil; } @@ -1968,12 +1803,9 @@ DEFUN ("menu-or-popup-active-p", Fmenu_or_popup_active_p, Smenu_or_popup_active_ void syms_of_nsmenu () { - defsubr (&Sx_popup_menu); defsubr (&Sx_popup_dialog); defsubr (&Sns_reset_menu); defsubr (&Smenu_or_popup_active_p); - staticpro (&menu_items); - menu_items = Qnil; Qdebug_on_next_call = intern ("debug-on-next-call"); staticpro (&Qdebug_on_next_call);