/* NeXT/Open/GNUstep and MacOSX Cocoa menu and toolbar module.
- Copyright (C) 2007-2012 Free Software Foundation, Inc.
+ Copyright (C) 2007-2013 Free Software Foundation, Inc.
This file is part of GNU Emacs.
/* This should be the first include, as it may set up #defines affecting
interpretation of even the system includes. */
#include <config.h>
-#include <setjmp.h>
#include "lisp.h"
#include "window.h"
========================================================================== */
-/* FIXME: not currently used, but should normalize with other terms. */
-void
-x_activate_menubar (struct frame *f)
-{
- fprintf (stderr, "XXX: Received x_activate_menubar event.\n");
-}
-
-
/* Supposed to discard menubar and free storage. Since we share the
menubar among frames and update its context for the focused window,
there is nothing to do here. */
/* --------------------------------------------------------------------------
Update menubar. Three cases:
- 1) deep_p = 0, submenu = nil: Fresh switch onto a frame -- either set up
+ 1) ! deep_p, submenu = nil: Fresh switch onto a frame -- either set up
just top-level menu strings (OS X), or goto case (2) (GNUstep).
- 2) deep_p = 1, submenu = nil: Recompute all submenus.
- 3) deep_p = 1, submenu = non-nil: Update contents of a single submenu.
+ 2) deep_p, submenu = nil: Recompute all submenus.
+ 3) deep_p, submenu = non-nil: Update contents of a single submenu.
-------------------------------------------------------------------------- */
void
-ns_update_menubar (struct frame *f, int deep_p, EmacsMenu *submenu)
+ns_update_menubar (struct frame *f, bool deep_p, EmacsMenu *submenu)
{
NSAutoreleasePool *pool;
id menu = [NSApp mainMenu];
static EmacsMenu *last_submenu = nil;
BOOL needsSet = NO;
const char *submenuTitle = [[submenu title] UTF8String];
- extern int waiting_for_input;
- int owfi;
+ bool owfi;
Lisp_Object items;
widget_value *wv, *first_wv, *prev_wv = 0;
int i;
long t;
#endif
- NSTRACE (set_frame_menubar);
+ NSTRACE (ns_update_menubar);
if (f != SELECTED_FRAME ())
return;
XSETFRAME (Vmenu_updating_frame, f);
/*fprintf (stderr, "ns_update_menubar: frame: %p\tdeep: %d\tsub: %p\n", f, deep_p, submenu); */
- BLOCK_INPUT;
+ block_input ();
pool = [[NSAutoreleasePool alloc] init];
/* Menu may have been created automatically; if so, discard it. */
/* Fully parse one or more of the submenus. */
int n = 0;
int *submenu_start, *submenu_end;
- int *submenu_top_level_items, *submenu_n_panes;
+ bool *submenu_top_level_items;
+ int *submenu_n_panes;
struct buffer *prev = current_buffer;
Lisp_Object buffer;
ptrdiff_t specpdl_count = SPECPDL_INDEX ();
= alloca (previous_menu_items_used * sizeof *previous_items);
/* lisp preliminaries */
- buffer = XWINDOW (FRAME_SELECTED_WINDOW (f))->buffer;
+ buffer = XWINDOW (FRAME_SELECTED_WINDOW (f))->contents;
specbind (Qinhibit_quit, Qt);
specbind (Qdebug_on_next_call, Qnil);
record_unwind_save_match_data ();
discard_menu_items ();
unbind_to (specpdl_count, Qnil);
[pool release];
- UNBLOCK_INPUT;
+ unblock_input ();
return;
}
discard_menu_items ();
unbind_to (specpdl_count, Qnil);
[pool release];
- UNBLOCK_INPUT;
+ unblock_input ();
return;
}
}
{
free_menubar_widget_value_tree (first_wv);
[pool release];
- UNBLOCK_INPUT;
+ unblock_input ();
return;
}
{
free_menubar_widget_value_tree (first_wv);
[pool release];
- UNBLOCK_INPUT;
+ unblock_input ();
return;
}
}
[NSApp setMainMenu: menu];
[pool release];
- UNBLOCK_INPUT;
+ unblock_input ();
}
frame's menus have changed, and the *step representation should be updated
from Lisp. */
void
-set_frame_menubar (struct frame *f, int first_time, int deep_p)
+set_frame_menubar (struct frame *f, bool first_time, bool deep_p)
{
ns_update_menubar (f, deep_p, nil);
}
+void
+x_activate_menubar (struct frame *f)
+{
+ NSArray *a = [[NSApp mainMenu] itemArray];
+ /* Update each submenu separately so ns_update_menubar doesn't reset
+ the delegate. */
+ int i = 0;
+ while (i < [a count])
+ {
+ EmacsMenu *menu = (EmacsMenu *)[[a objectAtIndex:i] submenu];
+ const char *title = [[menu title] UTF8String];
+ if (strcmp (title, ns_get_pending_menu_title ()) == 0)
+ {
+ ns_update_menubar (f, true, menu);
+ break;
+ }
+ ++i;
+ }
+ ns_check_pending_open_menu ();
+}
+
+
+
/* ==========================================================================
trackingMenu = ([notification name] == NSMenuDidBeginTrackingNotification
? 1 : 0);
}
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+- (void)menuWillOpen:(NSMenu *)menu
+{
+ ns_check_menu_open (menu);
+}
+#endif
+
#endif
/* delegate method called when a submenu is being opened: run a 'deep' call
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)
+ if (trackingMenu == 0)
return;
/*fprintf (stderr, "Updating menu '%s'\n", [[self title] UTF8String]); NSLog (@"%@\n", event); */
- ns_update_menubar (frame, 1, self);
+#if ! defined(NS_IMPL_COCOA) || \
+ MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5
+ /* 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);
+#endif
}
#ifdef NS_IMPL_GNUSTEP
if ([[self window] isVisible])
[self sizeToFit];
-#else
-#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_2
- if ([self supermenu] == nil)
- [self sizeToFit];
-#endif
#endif
}
/* run a menu in popup mode */
- (Lisp_Object)runMenuAt: (NSPoint)p forFrame: (struct frame *)f
- keymaps: (int)keymaps
+ keymaps: (bool)keymaps
{
EmacsView *view = FRAME_NS_VIEW (f);
NSEvent *e, *event;
========================================================================== */
Lisp_Object
-ns_menu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps,
+ns_menu_show (FRAME_PTR f, int x, int y, bool for_click, bool keymaps,
Lisp_Object title, const char **error)
{
EmacsMenu *pmenu;
#if 0
/* FIXME: a couple of one-line differences prevent reuse */
- wv = digest_single_submenu (0, menu_items_used, Qnil);
+ wv = digest_single_submenu (0, menu_items_used, 0);
#else
{
widget_value *save_wv = 0, *prev_wv = 0;
Under NS we just hide the toolbar until it might be needed again.
-------------------------------------------------------------------------- */
{
- BLOCK_INPUT;
+ block_input ();
[[FRAME_NS_VIEW (f) toolbar] setVisible: NO];
FRAME_TOOLBAR_HEIGHT (f) = 0;
- UNBLOCK_INPUT;
+ unblock_input ();
}
void
NSWindow *window = [view window];
EmacsToolbar *toolbar = [view toolbar];
- BLOCK_INPUT;
+ block_input ();
[toolbar clearActive];
/* update EmacsToolbar as in GtkUtils, build items list */
FRAME_TOOLBAR_HEIGHT (f) =
NSHeight ([window frameRectForContentRect: NSMakeRect (0, 0, 0, 0)])
- FRAME_NS_TITLEBAR_HEIGHT (f);
- UNBLOCK_INPUT;
+ if (FRAME_TOOLBAR_HEIGHT (f) < 0) // happens if frame is fullscreen.
+ FRAME_TOOLBAR_HEIGHT (f) = 0;
+ unblock_input ();
}
wr.size = [textField frame].size;
[win setFrame: wr display: YES];
+ [win setLevel: NSPopUpMenuWindowLevel];
[win orderFront: self];
[win display];
timer = [NSTimer scheduledTimerWithTimeInterval: (float)seconds target: self
static Lisp_Object
pop_down_menu (Lisp_Object arg)
{
- struct Lisp_Save_Value *p = XSAVE_VALUE (arg);
- struct Popdown_data *unwind_data = (struct Popdown_data *) p->pointer;
+ struct Popdown_data *unwind_data = XSAVE_POINTER (arg, 0);
- BLOCK_INPUT;
+ block_input ();
if (popup_activated_flag)
{
EmacsDialogPanel *panel = unwind_data->dialog;
}
xfree (unwind_data);
- UNBLOCK_INPUT;
+ unblock_input ();
return Qnil;
}
NSTRACE (x-popup-dialog);
- check_ns ();
+ check_window_system ();
isQ = NILP (header);
the dialog. */
contents = Fcons (title, Fcons (Fcons (build_string ("Ok"), Qt), Qnil));
- BLOCK_INPUT;
+ block_input ();
pool = [[NSAutoreleasePool alloc] init];
dialog = [[EmacsDialogPanel alloc] initFromContents: contents
isQuestion: isQ];
unwind_data->pool = pool;
unwind_data->dialog = dialog;
- record_unwind_protect (pop_down_menu, make_save_value (unwind_data, 0));
+ record_unwind_protect (pop_down_menu, make_save_pointer (unwind_data));
popup_activated_flag = 1;
tem = [dialog runDialogAt: p];
unbind_to (specpdl_count, Qnil); /* calls pop_down_menu */
}
- UNBLOCK_INPUT;
+ unblock_input ();
return tem;
}
}
-
+
- (void)timeout_handler: (NSTimer *)timedEntry
{
NSEvent *nxev = [NSEvent otherEventWithType: NSApplicationDefined