Children Will Play

December 7th, 2006

Mike Zornek’s Child’s Play Day is wrapping up, and despite relatively little organization, it looks like a major success. My newest customers alone brought in nearly $250, all of which has been sent directly to the charity. I know of at least two developers whose contributions will exceed $1000, so I’m sure the event will be unanimously declared a success, and will substantially improve the lives of some deserving kids this year.

Major kudos to Mike for putting this together! And many thanks to the people who bought FlexTime, FastScripts, or Clarion over the past 24 hours. You rock!

A Moment For James Kim

December 6th, 2006

It’s been heart-wrenching to follow the ups and downs of the James and Kati Kim family, who disappeared shortly after Thanksgiving and were missing for over a week before being found in the Oregon wilderness. While the sad story got a happy lift earlier this week with the discovery of Kati and the two children alive, James’s story came to an unhappy conclusion today when rescue workers found him, defeated by the woods he had gotten lost in.

It’s easy for me to empathize with James and his family, because he was “a lot like me” in some superficial but emotionally connective ways. He worked in the tech industry. In San Francisco. In a building across the street from where I used to work. With a lot of people who I know directly or indirectly. It was easy to envision myself driving along that mountain road and somehow letting one thing lead to another until the situation was dire. And that’s just too sad for words.

I was really hoping for a miracle.

It makes me appreciate the fragility of life, renews my respect for the wilderness, and encourages me to stop taking my own life for granted. And I want those near to me to keep living. Please.

More than that, James helps remind me how important everybody’s life is. Here’s a man I did not know, but whose story compelled me to hope beyond hope that he’d be found alive. All because the news stories and circumstances of his life made it easy for me to relate to him. Really easy. So I add my own condolences to the waves of concern for the Kim family, and hope in vain that nobody else dies before their time, at least for a while.

Child’s Play Day

December 6th, 2006

Mike Zornek had a brilliant idea for a way that independent software vendors could show a little holiday spirit this year. He’s put together a loose-knit collection of companies whose profits from sales tomorrow will be donated 100% to the Child’s Play Charity, which helps hospitals buy toys, books, and other entertainment for the kids under their care.

I love this charity idea because it gives small developers a chance to unite for a good cause, and because that cause is pretty universal and apolitical. Who doesn’t want sick kids to be as happy as possible?

I’m putting my products into the pool, so if you had any intention of buying them, do it tomorrow, December 7th, 2006. I appreciate that picking a 24 hour period and calling it “a day” can be tough to clarify internationally. So I’m interpreting it a little loosely and starting the “sale” right now. My online store includes a note explaining that the charity sales are in place, and I’ll take that notice down sometime after midnight tomorrow. While that notice is in effect you are guaranteed that 100% of your payments will go to the charity (i’m donating the difference in any PayPal or Kagi fees, so the total contribution will be exactly the cost of the product).

There are lots of other great companies participating, so if you’ve been considering any of the products on the list, tomorrow would be a great time to make the purchase!

iTunes Scripting Seizure

December 5th, 2006

I love iTunes, but it has a number of rough edges that leave me constantly praying that a major revision will come along one day soon. Most of my complaints have to do with it being simultaneously the “only way to manage music and podcasts on the Mac” and yet being frustratingly feature-incomplete in some important ways. For instance, it does a great job of downloading my podcasts, but neglects to put them on my iPod until I either unplug and replug it, or else manually select “Sync.” Inevitably, I end up thinking that since iTunes and my iPod have been making out all weekend, surely those new podcasts are on the iPod. It’s not until I’m at the gym with nothing to listen to that I realize I’ve been sync-jacked!

But that’s a complaint for another time. Today I’d like to highlight an infuriating behavior that iTunes has, of blocking the processing of all incoming AppleEvents while its preferences dialog is being displayed. What does this mean in most practical terms? iTunes can’t respond to AppleScript while the Preferences window is open. So if you run some script that asks for the name of the current track, for instance, it will hang and give the running app a spinning beachball while you wonder what the heck is going on. Finally you switch to iTunes and realize that you were fiddling with preferences yesterday when you got distracted and switched to another application. Close the dialog, and life goes on as usual.

This is bad enough when it’s inflicted on yourself as the script author and user, but it’s worse when your script is either shared with other users, or included as part of the functional infrastructure for an application. With iTunes integration popping up everywhere, it stands to reason that any developer who uses AppleScript to achieve the integration runs the risk of answering support call from users who have run into this iTunes freeze-out behavior.

The solution? Apple should fix iTunes so it doesn’t freeze-out AppleEvent processing while displaying the Preferences dialog.

The solution for people who live in the real world? We have a few techniques to choose from.

Time Out Gracefully

The first is to use AppleScript’s “with timeout” clause to seriously shorten the length of time it will hang out waiting for iTunes to wake up. We can pick a relatively short period of time in seconds that still constitutes an eternity in scripting time:

try
	with timeout of 2 seconds
		activate application "iTunes"
	end timeout
on error
	display dialog "iTunes is Frozen, try closing the Preferences window!"
end try

Go ahead, try it with the iTunes Preferences window open. This eliminates the outright freeze that users would experience otherwise.

But it feels risky to estimate with confidence the precise number of seconds that is “long enough, but not too long.” Maybe the user just has a really slow Mac, or something unusual happens to slow things down one out of ten times. For many iTunes scripting purposes, activating iTunes and bringing it to the front is part of the procedure. If iTunes is frontmost, then the user will see that the Preferences dialog is open and (hopefully) intuit that they must dismiss the dialog to let the scripted action carry on. The problem is, merely activating iTunes with AppleScript requires that it respond to AppleEvents! As the example script above shows, we can’t even bring it forward when it’s frozen. Or can we?

Blame It On iTunes

We know the user can bring it forward, so how do we simulate that from a script? If we keep iTunes itself out of the scripting loop, we can enlist the services of the system to change the frontmost application:

tell application "System Events"
	set frontmost of application process "iTunes" to true
end tell

Try this script with iTunes Preferences open and you’ll see that it zips to the fore, regardless of the frozen state. By putting this script command first in your iTunes-activating script, you can ensure that users will at least be confronted by the offending Preferences window, instead of staring at a spinning beachball in your application.

Not Give A Damn

Finally, we have the option of sort of throwing our scripting requests out to the world with little regard for their success or failure. For programmer types you can think of this as roughly equivalent to weak-linking a particular system API. If something neat can be done, fine we want it. Otherwise, we’ll keep running business as usual. The “ignoring application responses” clause tells AppleScript to send events but to disregard responses. For instance, the following script asks iTunes to skip to the next track, but shed no tears if that can’t be done right this second:

ignoring application responses
	tell application "iTunes" to next track
end ignoring

The big negative here of course is the script gives no feedback to the user about the success or failure of the intended action. It also silently queues up an action that might disturb the user later. For instance, when she switches to iTunes and closes the Preferences dialog, suddenly her favorite song gets skipped over.

In Closing

As I said, the solution here is for iTunes to grow up and be a real 21st Century application. At least in terms of modelessness. But for anybody trying to work around the failings of iTunes or other event-blocking applications, I hope these tips will come in handy.