/* 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. */
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);
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:)
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];
{
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];
}
========================================================================== */
+
+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)
{
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;
}
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))
if (XTYPE (head) == Lisp_String)
[title setStringValue:
- [NSString stringWithUTF8String: XSTRING (head)->data]];
+ [NSString stringWithUTF8String: SDATA (head)]];
else if (isQ == YES)
[title setStringValue: @"Question"];
else
- (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)
+ /* 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: NSModalPanelRunLoopMode
- 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;
@end
-
/* ==========================================================================
Lisp definitions