]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix that executing applescript may hang emacs uninterruptedly.
authorJan Djärv <jan.h.d@swipnet.se>
Sun, 14 Aug 2011 10:39:38 +0000 (12:39 +0200)
committerJan Djärv <jan.h.d@swipnet.se>
Sun, 14 Aug 2011 10:39:38 +0000 (12:39 +0200)
* nsfns.m (as_script, as_result, as_status): New static variables.
(ns_run_ascript): New function.
(Fns_do_applescript): Set variables as_*. Make an NSApplicationDefined
event with data2 set to NSAPP_DATA2_RUNASSCRIPT, post it and then start
the event loop.  Get status from as_status.

* nsterm.h (ns_run_ascript): Declare.
(NSAPP_DATA2_RUNASSCRIPT): Define.

* nsterm.m (sendEvent): If event is NSApplicationDefined and
data2 is NSAPP_DATA2_RUNASSCRIPT, call ns_run_ascript and then exit
the event loop (Bug#7276).

src/ChangeLog
src/nsfns.m
src/nsterm.h
src/nsterm.m

index 4b0ac4082a5b848ddf036dc47e0a1e91e5c9bee1..b0a0e03a8a7a956824fd015a3a8082daa98bb191 100644 (file)
@@ -1,3 +1,18 @@
+2011-08-14  Jan Djärv  <jan.h.d@swipnet.se>
+
+       * nsterm.h (ns_run_ascript): Declare.
+       (NSAPP_DATA2_RUNASSCRIPT): Define.
+
+       * nsfns.m (as_script, as_result, as_status): New static variables.
+       (ns_run_ascript): New function.
+       (Fns_do_applescript): Set variables as_*. Make an NSApplicationDefined
+       event with data2 set to NSAPP_DATA2_RUNASSCRIPT, post it and then start
+       the event loop.  Get status from as_status (Bug#7276).
+
+       * nsterm.m (sendEvent): If event is NSApplicationDefined and
+       data2 is NSAPP_DATA2_RUNASSCRIPT, call ns_run_ascript and then exit
+       the event loop (Bug#7276).
+
 2011-08-14  Andreas Schwab  <schwab@linux-m68k.org>
 
        * gnutls.c (QCgnutls_bootprop_priority)
index 85246a4c25f0b4c56c027e13a36184baec5ce8f3..a09011d84615e471142c1b9f939c160337d9c296 100644 (file)
@@ -97,6 +97,9 @@ Lisp_Object Fx_open_connection (Lisp_Object, Lisp_Object, Lisp_Object);
 
 extern BOOL ns_in_resize;
 
+/* Static variables to handle applescript execution.  */
+static Lisp_Object as_script, *as_result;
+static int as_status;
 
 /* ==========================================================================
 
@@ -2052,6 +2055,15 @@ ns_do_applescript (Lisp_Object script, Lisp_Object *result)
   return 0;
 }
 
+/* Helper function called from sendEvent to run applescript
+   from within the main event loop.  */
+
+void
+ns_run_ascript (void)
+{
+  as_status = ns_do_applescript (as_script, as_result);
+}
+
 DEFUN ("ns-do-applescript", Fns_do_applescript, Sns_do_applescript, 1, 1, 0,
        doc: /* Execute AppleScript SCRIPT and return the result.
 If compilation and execution are successful, the resulting script value
@@ -2061,12 +2073,37 @@ In case the execution fails, an error is signaled. */)
 {
   Lisp_Object result;
   int status;
+  NSEvent *nxev;
 
   CHECK_STRING (script);
   check_ns ();
 
   BLOCK_INPUT;
-  status = ns_do_applescript (script, &result);
+
+  as_script = script;
+  as_result = &result;
+
+  /* executing apple script requires the event loop to run, otherwise
+     errors aren't returned and executeAndReturnError hangs forever.
+     Post an event that runs applescript and then start the event loop.
+     The event loop is exited when the script is done.  */
+  nxev = [NSEvent otherEventWithType: NSApplicationDefined
+                            location: NSMakePoint (0, 0)
+                       modifierFlags: 0
+                           timestamp: 0
+                        windowNumber: [[NSApp mainWindow] windowNumber]
+                             context: [NSApp context]
+                             subtype: 0
+                               data1: 0
+                               data2: NSAPP_DATA2_RUNASSCRIPT];
+
+  [NSApp postEvent: nxev atStart: NO];
+  [NSApp run];
+
+  status = as_status;
+  as_status = 0;
+  as_script = Qnil;
+  as_result = 0;
   UNBLOCK_INPUT;
   if (status == 0)
     return result;
@@ -2670,4 +2707,7 @@ be used as the image of the icon representing the frame.  */);
   /* used only in fontset.c */
   check_window_system_func = check_ns;
 
+  as_status = 0;
+  as_script = Qnil;
+  as_result = 0;
 }
index 6ea9161c922ae2a11b8962bbcf5d53c2ad2ce9d3..902f35c96ea89eccc6d97f4ca0afb71e06a53d79 100644 (file)
@@ -795,6 +795,9 @@ extern void x_set_tool_bar_lines (struct frame *f,
 extern void x_activate_menubar (struct frame *);
 extern void free_frame_menubar (struct frame *);
 
+#define NSAPP_DATA2_RUNASSCRIPT 10
+extern void ns_run_ascript (void);
+
 extern void ns_init_paths (void);
 extern void syms_of_nsterm (void);
 extern void syms_of_nsfns (void);
index d4b1a3f8473fdada88ec89c4ed41a0ad859ccae1..582e53e202cb239d906e6186b92477e29d78f330 100644 (file)
@@ -4257,6 +4257,16 @@ ns_term_shutdown (int sig)
 /*  NSTRACE (sendEvent); */
 /*fprintf (stderr, "received event of type %d\t%d\n", type);*/
 
+#ifdef NS_IMPL_COCOA
+  if (type == NSApplicationDefined
+      && [theEvent data2] == NSAPP_DATA2_RUNASSCRIPT)
+    {
+      ns_run_ascript ();
+      [self stop: self];
+      return;
+    }
+#endif
+
   if (type == NSCursorUpdate && window == nil)
     {
       fprintf (stderr, "Dropping external cursor update event.\n");