X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/b87c4ff2817e71ca71b028792200b1e069a95e04..d3155315c85212f224fc5df0239182dafdfd6284:/src/nsmenu.m diff --git a/src/nsmenu.m b/src/nsmenu.m index 3ed1734d22..b5cb64d68e 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-2013 Free Software Foundation, Inc. + Copyright (C) 2007-2015 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -59,12 +59,6 @@ int menu_trace_num = 0; #include "nsmenu_common.c" #endif -extern Lisp_Object Qundefined, Qmenu_enable, Qmenu_bar_update_hook; -extern Lisp_Object QCtoggle, QCradio; - -Lisp_Object Qdebug_on_next_call; -extern Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map; - extern long context_menu_value; EmacsMenu *mainMenu, *svcsMenu, *dockMenu; @@ -266,12 +260,8 @@ ns_update_menubar (struct frame *f, bool deep_p, EmacsMenu *submenu) /* parse stage 2: insert into lucid 'widget_value' structures [comments in other terms say not to evaluate lisp code here] */ - wv = xmalloc_widget_value (); - wv->name = "menubar"; - wv->value = 0; - wv->enabled = 1; + wv = make_widget_value ("menubar", NULL, true, Qnil); wv->button_type = BUTTON_TYPE_NONE; - wv->help = Qnil; first_wv = wv; for (i = 0; i < 4*n; i += 4) @@ -378,12 +368,8 @@ ns_update_menubar (struct frame *f, bool deep_p, EmacsMenu *submenu) int n; Lisp_Object string; - wv = xmalloc_widget_value (); - wv->name = "menubar"; - wv->value = 0; - wv->enabled = 1; + wv = make_widget_value ("menubar", NULL, true, Qnil); wv->button_type = BUTTON_TYPE_NONE; - wv->help = Qnil; first_wv = wv; /* Make widget-value tree w/ just the top level menu bar strings */ @@ -439,12 +425,8 @@ ns_update_menubar (struct frame *f, bool deep_p, EmacsMenu *submenu) memcpy (previous_strings[i/4], SDATA (string), min (10, SBYTES (string) + 1)); - wv = xmalloc_widget_value (); - wv->name = SSDATA (string); - wv->value = 0; - wv->enabled = 1; + wv = make_widget_value (SSDATA (string), NULL, true, Qnil); wv->button_type = BUTTON_TYPE_NONE; - wv->help = Qnil; wv->call_data = (void *) (intptr_t) (-1); #ifdef NS_IMPL_COCOA @@ -504,11 +486,9 @@ void x_activate_menubar (struct frame *f) { #ifdef NS_IMPL_COCOA -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 ns_update_menubar (f, true, nil); ns_check_pending_open_menu (); #endif -#endif } @@ -553,24 +533,15 @@ x_activate_menubar (struct frame *f) 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); -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 if (! trackingMenu) ns_check_menu_open (nil); -#endif } -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 - (void)menuWillOpen:(NSMenu *)menu { ++trackingMenu; @@ -591,7 +562,6 @@ extern NSString *NSMenuDidBeginTrackingNotification; { --trackingMenu; } -#endif /* OSX >= 10.5 */ #endif /* NS_IMPL_COCOA */ @@ -620,8 +590,7 @@ extern NSString *NSMenuDidBeginTrackingNotification; if (trackingMenu == 0) return; /*fprintf (stderr, "Updating menu '%s'\n", [[self title] UTF8String]); NSLog (@"%@\n", event); */ -#if (! defined (NS_IMPL_COCOA) \ - || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5) +#ifdef NS_IMPL_GNUSTEP /* Don't know how to do this for anything other than OSX >= 10.5 This is wrong, as it might run Lisp code in the event loop. */ ns_update_menubar (frame, true, self); @@ -718,9 +687,7 @@ extern NSString *NSMenuDidBeginTrackingNotification; { NSMenuItem *item = [self itemAtIndex: n]; NSString *title = [item title]; - if (([title length] == 0 /* OSX 10.5 */ - || [ns_app_name isEqualToString: title] /* from 10.6 on */ - || [@"Apple" isEqualToString: title]) /* older */ + if ([ns_app_name isEqualToString: title] && ![item isSeparatorItem]) continue; [self removeItemAtIndex: n]; @@ -824,7 +791,7 @@ extern NSString *NSMenuDidBeginTrackingNotification; ========================================================================== */ Lisp_Object -ns_menu_show (struct frame *f, int x, int y, bool for_click, bool keymaps, +ns_menu_show (struct frame *f, int x, int y, int menuflags, Lisp_Object title, const char **error) { EmacsMenu *pmenu; @@ -832,18 +799,15 @@ ns_menu_show (struct frame *f, int x, int y, bool for_click, bool keymaps, Lisp_Object tem; ptrdiff_t specpdl_count = SPECPDL_INDEX (); widget_value *wv, *first_wv = 0; + bool keymaps = (menuflags & MENU_KEYMAPS); block_input (); p.x = x; p.y = y; /* now parse stage 2 as in ns_update_menubar */ - wv = xmalloc_widget_value (); - wv->name = "contextmenu"; - wv->value = 0; - wv->enabled = 1; + wv = make_widget_value ("contextmenu", NULL, true, Qnil); wv->button_type = BUTTON_TYPE_NONE; - wv->help = Qnil; first_wv = wv; #if 0 @@ -914,18 +878,14 @@ ns_menu_show (struct frame *f, int x, int y, bool for_click, bool keymaps, with its items as a submenu beneath it. */ if (!keymaps && strcmp (pane_string, "")) { - wv = xmalloc_widget_value (); + wv = make_widget_value (pane_string, NULL, true, Qnil); if (save_wv) save_wv->next = wv; else first_wv->contents = wv; - wv->name = pane_string; if (keymaps && !NILP (prefix)) wv->name++; - wv->value = 0; - wv->enabled = 1; wv->button_type = BUTTON_TYPE_NONE; - wv->help = Qnil; save_wv = wv; prev_wv = 0; } @@ -963,20 +923,18 @@ ns_menu_show (struct frame *f, int x, int y, bool for_click, bool keymaps, } #endif /* not HAVE_MULTILINGUAL_MENU */ - wv = xmalloc_widget_value (); + wv = make_widget_value (SSDATA (item_name), NULL, !NILP (enable), + STRINGP (help) ? help : Qnil); if (prev_wv) prev_wv->next = wv; else save_wv->contents = wv; - wv->name = SSDATA (item_name); if (!NILP (descrip)) wv->key = SSDATA (descrip); - wv->value = 0; /* If this item has a null value, make the call_data null so that it won't display a box when the mouse is on it. */ wv->call_data = !NILP (def) ? aref_addr (menu_items, i) : 0; - wv->enabled = !NILP (enable); if (NILP (type)) wv->button_type = BUTTON_TYPE_NONE; @@ -989,11 +947,6 @@ ns_menu_show (struct frame *f, int x, int y, bool for_click, bool keymaps, wv->selected = !NILP (selected); - if (! STRINGP (help)) - help = Qnil; - - wv->help = help; - prev_wv = wv; i += MENU_ITEMS_ITEM_LENGTH; @@ -1004,24 +957,19 @@ ns_menu_show (struct frame *f, int x, int y, bool for_click, bool keymaps, if (!NILP (title)) { - widget_value *wv_title = xmalloc_widget_value (); - widget_value *wv_sep = xmalloc_widget_value (); + widget_value *wv_title; + widget_value *wv_sep = make_widget_value ("--", NULL, false, Qnil); /* Maybe replace this separator with a bitmap or owner-draw item so that it looks better. Having two separators looks odd. */ - wv_sep->name = "--"; wv_sep->next = first_wv->contents; - wv_sep->help = Qnil; #ifndef HAVE_MULTILINGUAL_MENU if (STRING_MULTIBYTE (title)) title = ENCODE_MENU_STRING (title); #endif - - wv_title->name = SSDATA (title); - wv_title->enabled = NO; + wv_title = make_widget_value (SSDATA (title), NULL, false, Qnil); wv_title->button_type = BUTTON_TYPE_NONE; - wv_title->help = Qnil; wv_title->next = wv_sep; first_wv->contents = wv_title; } @@ -1054,8 +1002,10 @@ free_frame_tool_bar (struct frame *f) Under NS we just hide the toolbar until it might be needed again. -------------------------------------------------------------------------- */ { + EmacsView *view = FRAME_NS_VIEW (f); block_input (); - [[FRAME_NS_VIEW (f) toolbar] setVisible: NO]; + view->wait_for_tool_bar = NO; + [[view toolbar] setVisible: NO]; FRAME_TOOLBAR_HEIGHT (f) = 0; unblock_input (); } @@ -1070,9 +1020,13 @@ update_frame_tool_bar (struct frame *f) EmacsView *view = FRAME_NS_VIEW (f); NSWindow *window = [view window]; EmacsToolbar *toolbar = [view toolbar]; + int oldh; + if (view == nil || toolbar == nil) return; block_input (); + oldh = FRAME_TOOLBAR_HEIGHT (f); + #ifdef NS_IMPL_COCOA [toolbar clearActive]; #else @@ -1096,7 +1050,7 @@ update_frame_tool_bar (struct frame *f) /* Check if this is a separator. */ if (EQ (TOOLPROP (TOOL_BAR_ITEM_TYPE), Qt)) { - /* Skip separators. Newer OSX don't show them, and on GNUStep they + /* Skip separators. Newer OSX don't show them, and on GNUstep they are wide as a button, thus overflowing the toolbar most of the time. */ continue; @@ -1176,9 +1130,18 @@ update_frame_tool_bar (struct frame *f) FRAME_TOOLBAR_HEIGHT (f) = NSHeight ([window frameRectForContentRect: NSMakeRect (0, 0, 0, 0)]) - FRAME_NS_TITLEBAR_HEIGHT (f); - if (FRAME_TOOLBAR_HEIGHT (f) < 0) // happens if frame is fullscreen. - FRAME_TOOLBAR_HEIGHT (f) = 0; - unblock_input (); + if (FRAME_TOOLBAR_HEIGHT (f) < 0) // happens if frame is fullscreen. + FRAME_TOOLBAR_HEIGHT (f) = 0; + + if (oldh != FRAME_TOOLBAR_HEIGHT (f)) + [view updateFrameSize:YES]; + if (view->wait_for_tool_bar && FRAME_TOOLBAR_HEIGHT (f) > 0) + { + view->wait_for_tool_bar = NO; + [view setNeedsDisplay: YES]; + } + + unblock_input (); } @@ -1452,11 +1415,10 @@ pop_down_menu (void *arg) Lisp_Object -ns_popup_dialog (Lisp_Object position, Lisp_Object contents, Lisp_Object header) +ns_popup_dialog (struct frame *f, Lisp_Object header, Lisp_Object contents) { id dialog; - Lisp_Object window, tem, title; - struct frame *f; + Lisp_Object tem, title; NSPoint p; BOOL isQ; NSAutoreleasePool *pool; @@ -1465,41 +1427,6 @@ ns_popup_dialog (Lisp_Object position, Lisp_Object contents, Lisp_Object header) isQ = NILP (header); - if (EQ (position, Qt) - || (CONSP (position) && (EQ (XCAR (position), Qmenu_bar) - || EQ (XCAR (position), Qtool_bar)))) - { - window = selected_window; - } - else if (CONSP (position)) - { - Lisp_Object tem; - tem = Fcar (position); - if (XTYPE (tem) == Lisp_Cons) - window = Fcar (Fcdr (position)); - else - { - tem = Fcar (Fcdr (position)); /* EVENT_START (position) */ - window = Fcar (tem); /* POSN_WINDOW (tem) */ - } - } - else if (WINDOWP (position) || FRAMEP (position)) - { - window = position; - } - else - window = Qnil; - - if (FRAMEP (window)) - f = XFRAME (window); - else if (WINDOWP (window)) - { - CHECK_LIVE_WINDOW (window); - f = XFRAME (WINDOW_FRAME (XWINDOW (window))); - } - else - CHECK_WINDOW (window); - check_window_system (f); p.x = (int)f->left_pos + ((int)FRAME_COLUMN_WIDTH (f) * f->text_cols)/2; @@ -1579,7 +1506,11 @@ ns_popup_dialog (Lisp_Object position, Lisp_Object contents, Lisp_Object header) area.size.width = ICONSIZE; area.size.height= ICONSIZE; img = [[NSImage imageNamed: @"NSApplicationIcon"] copy]; +#ifdef NS_IMPL_COCOA +#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6 [img setScalesWhenResized: YES]; +#endif +#endif [img setSize: NSMakeSize (ICONSIZE, ICONSIZE)]; imgView = [[NSImageView alloc] initWithFrame: area]; [imgView setImage: img]; @@ -1919,34 +1850,6 @@ DEFUN ("ns-reset-menu", Fns_reset_menu, Sns_reset_menu, 0, 0, 0, } -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. -This is normally a mouse button event or a window or frame. -If POSITION is t, it means to use the frame the mouse is on. -The dialog box appears in the middle of the specified frame. - -CONTENTS specifies the alternatives to display in the dialog box. -It is a list of the form (DIALOG ITEM1 ITEM2...). -Each ITEM is a cons cell (STRING . VALUE). -The return value is VALUE from the chosen item. - -An ITEM may also be just a string--that makes a nonselectable item. -An ITEM may also be nil--that means to put all preceding items -on the left of the dialog box and all following items on the right. -\(By default, approximately half appear on each side.) - -If HEADER is non-nil, the frame title for the box is "Information", -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. */) - (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) @@ -1964,14 +1867,12 @@ void syms_of_nsmenu (void) { #ifndef NS_IMPL_COCOA - /* Don't know how to keep track of this in Next/Open/Gnustep. Always + /* 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); - Qdebug_on_next_call = intern_c_string ("debug-on-next-call"); - staticpro (&Qdebug_on_next_call); + DEFSYM (Qdebug_on_next_call, "debug-on-next-call"); }