+2009-02-07 Adrian Robert <Adrian.B.Robert@gmail.com>
+
+ * nsterm.m (EmacsApp-sendEvent:): Defer NSApplicationDefined event
+ when modal window is active. (Bug #2152)
+ (applicationShouldTerminate:): Remove now-unneeded while loop
+ around NSRunAlertPanel.
+
+ * nsmenu.m (popupSession): New file-global variable.
+ (pop_down_menu): End the popupSession before closing dialog.
+ (ns_popup_dialog): BLOCK_INPUT around dialog presentation.
+ (EmacsDialogPanel-runDialogAt:): Don't place window (superfluous),
+ don't query NSApp for events (just sleep instead).
+
2009-02-07 Eli Zaretskii <eliz@gnu.org>
* coding.c (syms_of_coding) <translation-table-for-input>: Modify
/* 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. */
struct Lisp_Save_Value *p = XSAVE_VALUE (arg);
popup_activated_flag = 0;
BLOCK_INPUT;
+ [NSApp endModalSession: popupSession];
[((EmacsDialogPanel *) (p->pointer)) close];
[[FRAME_NS_VIEW (SELECTED_FRAME ()) window] makeKeyWindow];
UNBLOCK_INPUT;
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];
{
[dialog close];
[[FRAME_NS_VIEW (SELECTED_FRAME ()) window] makeKeyWindow];
+ UNBLOCK_INPUT;
return tem;
}
- (Lisp_Object)runDialogAt: (NSPoint)p
{
- NSEvent *e;
- NSModalSession session;
int ret;
- [self center]; /*XXX p ignored? */
- [self orderFront: NSApp];
-
- session = [NSApp beginModalSessionForWindow: self];
+ popupSession = [NSApp beginModalSessionForWindow: self];
while (popup_activated_flag
- && (ret = [NSApp runModalSession: session]) == NSRunContinuesResponse)
+ && (ret = [NSApp runModalSession: popupSession])
+ == NSRunContinuesResponse)
{
- timer_check (1); // for timers.el, indep of atimers; might not return
- e = [NSApp nextEventMatchingMask: NSAnyEventMask
- untilDate: [NSDate dateWithTimeIntervalSinceNow: 1]
- 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];
+ [NSApp endModalSession: popupSession];
- { // FIXME: BIG UGLY HACK!!!
+ { /* FIXME: BIG UGLY HACK!!! */
Lisp_Object tmp;
*(EMACS_INT*)(&tmp) = ret;
return tmp;
- (void)sendEvent: (NSEvent *)theEvent
/* --------------------------------------------------------------------------
- Events posted by ns_send_appdefined interrupt the run loop here
+ Called when NSApp is running for each event received. Used to stop
+ the loop when we choose, since there's no way to just run one iteration.
-------------------------------------------------------------------------- */
{
int type = [theEvent type];
if (type == NSApplicationDefined)
{
- last_appdefined_event = theEvent;
- [self stop: self];
+ /* Events posted by ns_send_appdefined interrupt the run loop here.
+ But, if a modal window is up, an appdefined can still come through,
+ (e.g., from a makeKeyWindow event) but stopping self also stops the
+ modal loop. Just defer it until later. */
+ if ([NSApp modalWindow] == nil)
+ {
+ last_appdefined_event = theEvent;
+ [self stop: self];
+ }
+ else
+ {
+ send_appdefined = YES;
+ }
}
[super sendEvent: theEvent];
if (ns_shutdown_properly || NILP (ns_confirm_quit))
return NSTerminateNow;
- /* XXX: This while() loop is needed because if the user switches to another
- application while the panel is up, it is taken down w/a return value
- of NSRunStoppedResponse, and the event queue gets messed up.
- In this case resend the appdefined and put up the window again. */
- while (1) {
ret = NSRunAlertPanel([[NSProcessInfo processInfo] processName],
[NSString stringWithUTF8String:"Exit requested. Would you like to Save Buffers and Exit, or Cancel the request?"],
@"Save Buffers and Exit", @"Cancel", nil);
if (ret == NSAlertDefaultReturn)
- {
- send_appdefined = YES;
- ns_send_appdefined(-1);
return NSTerminateNow;
- }
else if (ret == NSAlertAlternateReturn)
- {
- send_appdefined = YES;
- ns_send_appdefined(-1);
return NSTerminateCancel;
- }
- }
+ return NSTerminateNow; /* just in case */
}