]> git.eshelyaron.com Git - emacs.git/commitdiff
* nsterm.m (EmacsApp-sendEvent:): Defer NSApplicationDefined event
authorAdrian Robert <Adrian.B.Robert@gmail.com>
Sat, 7 Feb 2009 11:04:22 +0000 (11:04 +0000)
committerAdrian Robert <Adrian.B.Robert@gmail.com>
Sat, 7 Feb 2009 11:04:22 +0000 (11:04 +0000)
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).

src/ChangeLog
src/nsmenu.m
src/nsterm.m

index 67ef7ad46a51877be314a31b4fcfa473a941e4dc..280af6c8b427988276da9e86025905484f1b3c44 100644 (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
index c6d4c21a17996a0bf893372cfa512f38e6f4e338..f6b2075a8415b8d6c9d7afc58a8537e1ffc3df1f 100644 (file)
@@ -73,6 +73,7 @@ EmacsMenu *mainMenu, *svcsMenu, *dockMenu;
 
 /* 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 @@ pop_down_menu (Lisp_Object arg)
   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 @@ 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];
   {
@@ -1567,6 +1571,7 @@ ns_popup_dialog (Lisp_Object position, Lisp_Object contents, Lisp_Object header)
 
   [dialog close];
   [[FRAME_NS_VIEW (SELECTED_FRAME ()) window] makeKeyWindow];
+  UNBLOCK_INPUT;
 
   return tem;
 }
@@ -1872,27 +1877,21 @@ void process_dialog (id window, Lisp_Object list)
 
 - (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;
index 2ef3a3ec90670b194561de4ebb6cc525862448fe..b674edae5800a9288ca2327e8e422b377c1d7f3c 100644 (file)
@@ -4037,7 +4037,8 @@ ns_term_shutdown (int sig)
 
 - (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 @@ ns_term_shutdown (int sig)
 
   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 @@ ns_term_shutdown (int sig)
   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 */
 }