* 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).
This commit is contained in:
Adrian Robert 2009-02-07 11:04:22 +00:00
parent 8434d0b8c0
commit 3175b12ae7
3 changed files with 43 additions and 32 deletions

View file

@ -1,3 +1,16 @@
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

View file

@ -73,6 +73,7 @@
/* 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. */
@ -1495,6 +1496,7 @@ - (NSRect) frame
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;
@ -1554,6 +1556,8 @@ - (NSRect) frame
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];
{
@ -1567,6 +1571,7 @@ - (NSRect) frame
[dialog close];
[[FRAME_NS_VIEW (SELECTED_FRAME ()) window] makeKeyWindow];
UNBLOCK_INPUT;
return tem;
}
@ -1872,27 +1877,21 @@ - (void)dealloc
- (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;

View file

@ -4037,7 +4037,8 @@ - (void)logNotification: (NSNotification *)notification
- (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];
@ -4081,8 +4082,19 @@ - (void)sendEvent: (NSEvent *)theEvent
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];
@ -4199,28 +4211,15 @@ - (NSApplicationTerminateReply)applicationShouldTerminate: (id)sender
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 */
}