Open Bug 448992 Opened 11 years ago Updated 8 years ago

Some toolbar scripts that use UI Scripting take forever/timeout/fail

Categories

(Camino Graveyard :: OS Integration, defect)

PowerPC
macOS
defect
Not set

Tracking

(Not tracked)

People

(Reporter: alqahira, Unassigned)

Details

(Keywords: testcase)

Attachments

(2 files)

When running the attached AppleScript (or its .scpt version) from Script Editor or from the toolbar, execution is fast; the prefs window opens almost instantaneously.

However, when uncommenting the commented-out line, execution slows down to a crawl as a toolbar script (so much that even the prefs window now takes forever to open now), while execution remains speedy when running the script via Script Editor.  Sometimes you'll even seen Camino beachball.

STR:

1. Have UI scripting (System Prefs: Universal Access: Enable access for assistive devices) enabled, since the testcase won't check for you.
2. Add the script to your toolbar
3. Run
4. Uncomment the "click button line"
5. Run again
Not sure if this sample is catching the right part of the execution or not; it seems to finish sampling before the prefs window shows....
I can also trigger the problem with the following reduced case:

  tell application "System Events"
    tell process "Camino"
      get window 1
    end tell
  end tell

I think anything that actually hits Camino's UI will stall it.  Note that Camino doesn't stall when the script runs from other processes, such as Script Editor.  I'll bet the script and the UI are competing for the main run loop's time.  If that's true, running scripts in a separate thread would fix it.  That's a bit of a can of worms, but it may be necessary.  I'd try a quick, naive threaded approach and see if the problem goes away.  If so, the fun begins.
PX on the 2.1 list (but to be honest, unless Peter shows up with a patch, it's a minus).
Flags: camino2.1?
So, NSAppleScript always has to be run on the main thread (and, it seems, in general, AppleScript is not thread-safe).

Given that, I think maybe the best solution here is to create a separate helper app ("CaminoToolbarScriptRunner.app") and have it do what ToolbarScriptItem's |runScript:| does now (some additional refactoring is surely required).  The other drawback to this is that there's the perf hit of launching that other app.

Oh, hmm; I wonder if we could just replace one NSAppleScript for script-running in |runScript:| with NSTask or something doing osascript?  Not sure how we'd do the error-handling, and we'd still have the perf hit of calling osascript (is that any worse than the current perf hit of NSAppleScript?) but that overall would be simpler/far less refactoring than a completely separate helper app.

There may also be some behavior differences we'd have to check for (user interaction, display dialog, supported AS filetypes), too, but it might be worth checking out.

(It's possible some other methods like NDAppleScriptObject might do what we want, but that isn't at all clear to me: http://www.cocoabuilder.com/archive/cocoa/163902-nsapplescript-not-in-the-main-thread.html)
(In reply to comment #5)
> Oh, hmm; I wonder if we could just replace one NSAppleScript for
> script-running in |runScript:| with NSTask or something doing osascript? 
>
> There may also be some behavior differences we'd have to check for (user
> interaction, display dialog, supported AS filetypes), too, but it might be
> worth checking out.

osascript does not allow direct user interaction (so having a script directly call "display dialog" wouldn't work), but inside of an application's tell block things seem OK here.  That might be a safe "breakage" tradeoff to fix this bug--but I'd like to have run through a more extensive check of things based on existing toolbar scripts--and it's probably too risky to try right before 2.1 :(
Flags: camino2.1? → camino2.1-
http://lists.apple.com/archives/applescript-implementors/2011/Jun/msg00012.html

> I execute my applescript in a separate utility task via an NSAppleEventDescriptor category using :
>
> theEvent = [self appleEventWithEventClass:kCoreEventClass eventID:kAEOpenApplication targetDescriptor:aTargetDescriptor returnID:kAutoGenerateReturnID transactionID:kAnyTransactionID];

Not sure if that is helpful here or not…
You need to log in before you can comment on or make changes to this bug.