From 08e3161a51ae1547c486d6603059711370d11118 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jan=20Dj=C3=A4rv?= Date: Sun, 14 Aug 2011 12:39:38 +0200 Subject: [PATCH] Fix that executing applescript may hang emacs uninterruptedly. * 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 | 15 +++++++++++++++ src/nsfns.m | 42 +++++++++++++++++++++++++++++++++++++++++- src/nsterm.h | 3 +++ src/nsterm.m | 10 ++++++++++ 4 files changed, 69 insertions(+), 1 deletion(-) diff --git a/src/ChangeLog b/src/ChangeLog index 4b0ac4082a5..b0a0e03a8a7 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,18 @@ +2011-08-14 Jan Djärv + + * 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 * gnutls.c (QCgnutls_bootprop_priority) diff --git a/src/nsfns.m b/src/nsfns.m index 85246a4c25f..a09011d8461 100644 --- a/src/nsfns.m +++ b/src/nsfns.m @@ -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; } diff --git a/src/nsterm.h b/src/nsterm.h index 6ea9161c922..902f35c96ea 100644 --- a/src/nsterm.h +++ b/src/nsterm.h @@ -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); diff --git a/src/nsterm.m b/src/nsterm.m index d4b1a3f8473..582e53e202c 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -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"); -- 2.39.2