A Stroke Of Luck

April 9th, 2010

One of my customers reported a really subtle bug having to do with a keyboard shortcut for a command. I’m going to change some facts to protect the innocent, but imagine I got a report:

“Every time I press cmd-N to create a new document and start typing, instead of accepting the text, it just beeps at me.”

This seems impossible to me. Creating a new document and typing into it is fundamental to my product. Surely if it was broken I would know from my own daily testing of the application. I try diligently to reproduce it, but of course, I can’t. Create a new document. Start typing. Everything works, everybody’s happy. Except the person who reported the bug.

At some point in my tinkering I stumble upon the bug. Beep. I can’t type. There it is! What a drag. This application sucks!

Now that I’ve seen and heard the bug with my own eyes, I’m more committed than ever to fixing it. But how on earth did I do it? I try several more times and am unable to reproduce the problem.

I have only spotted the issue once in my dozens of trials, yet the customer claims it affects him every single time. What explains this? Maybe it simply doesn’t happen as often on my Mac as it does on his. My thoughts turn to the brute force of AppleScript. If this happens only once in a blue moon on my Mac, surely I can reproduce it by running a script that iterates the test conditions hundreds or thousands of times. I open AppleScript Editor and enter the following:

tell application "System Events"
	repeat 100 times
		keystroke "n" using command down
		keystroke "Testing typing"
	end repeat
end tell

Nothing! Even after running it 1000 times, nothing. How can this be? How could something so common for the customer, something that I saw myself once, be so difficult to reproduce on my Mac?

After playing around a bit more, I started to reproduce it more readily. What was happening? I couldn’t figure it out, but something “felt” a little different when I reproduced it. I thought carefully about the parameters of the bug, as exemplified (I thought) by my script:

  1. The command key is pressed.
  2. The N key is pressed.
  3. The N key is released.
  4. The command key is released.
  5. Typing into the new document is attempted.

I looked again at the script. Perhaps this “keystroke” command is not literal enough. For all I know it’s circumventing the normal key events that get generated when you type on the keyboard. On a lark, I modified the script to be more explicit:

tell application "System Events"
	repeat 100 times
		key down {command}
		key down  "n"
		key up "n"
		key up {command}
		key down "x"
		key up "x"
	end repeat
end tell

Here we have a more literal match with my analysis of what happens. Hold down the command key, press the N key, release, then type something. In this case I just type an x character because I figure any typing is enough to trigger the bug.

I ran this 100 times as well and no luck. The bug is simply not reproducible through scripting. I guess I’ll have to figure out what conditions are making it more likely for the customer to run into the bug. Maybe he has some 3rd party software that is interfering. Or … wait a minute.

tell application "System Events"
	repeat 100 times
		key down {command}
		key down  "n"
		key up {command}
		key up "n"
		key down "x"
		key up "x"
	end repeat
end tell

I ran the modified script and the bug immediately exhibited itself. So what changed? Look carefully and you’ll see that my previous script assumed that when a keyboard shortcut is pressed, there is a sort of nested symmetry to the order of pressing and releasing the keys. When I press keyboard shortcuts, I hold the modifier keys down throughout the stroke, and release only after the letter key has been released. But this customer has muscle memory that inclines him to instead release the keys in the order they were pressed. When he releases the N key, the command key has “long” since been released.

This subtle difference turns out to trigger a bug in my event monitoring code that, to make a long story short, robs first responder status from the default view in the document. So when he creates a new document, there is no first responder, and his typing just causes a bunch of beeps. When I create a new document, there’s always a first responder, so I don’t see the bug.

As difficult as this bug was to track down, it would have been near impossible without the theory testing, disproving, and ultimately proving tool of using AppleScript and System Events to zero on in the behavior. Sometimes when the steps a customer provides to reproduce a bug seem exactly the same as what you’re doing, you’re just not trying hard enough to find the difference.

When I Joined Apple

April 2nd, 2010

When I joined Apple in May, 1996, the company was filled with geniuses who were trying to invent the future. Despite that brilliance, Apple was failing. I came on board because I was young, had just started using a Macintosh, and I knew something great was happening. I was eager to find out what it was and, if possible, to help it grow.

I was lucky to join one of the most cavalier and competent teams in the company: the Mac OS system integration team. In a nutshell, we were in charge of the Mac OS System File, “System Enabler,” and other crucial bits that made your Mac a Mac. Whoo-hoo! Power! We made or broke your Mac experience, hopefully making more than breaking. I took my new job seriously and stepped carefully with every change. It felt great, and I cherished every contribution I made.

Later, I moved to the Mac OS X team and did similar work on the infrastructure of Mac OS X. In particular, with how it deals with older applications that rely on the “Carbon” framework. After years of using a custom Mac-only environment called MPW, I was using standard UNIX tools and building UNIX libraries. This felt awesome! I had grown up using an Amiga, then switched to Sun OS, where I spent a lot of time getting familiar with UNIX. There I was, and Apple decides to put the best UI in the world on top of Unix. I was in heaven.

While I was at Apple I saw a lot of failure. I saw the Newton fail. I saw Pippin fail. I saw PowerTalk fail. I saw Cyberdog fail. I saw Apple desperate to sell even a few hundred thousand Macs in a quarter. I saw the press lambast us and declare us dead. “Beleaguered” became an unfortunately common word in our office life.

But I kept looking around me, and I saw nothing but signs of success. I marveled at QuickTime, speech recognition, networking technologies like ZeroConf (Bonjour), and other things that have never seen the light of day. This company is awesome! I want to work here! They’re going to change the world!

Of course, they already had changed the world with the Apple II and the Macintosh, but as a young 20 year old, I was anticipating future growth. It was a bad time for Apple: competitors and the press were declaring our obsolescence. Michael Dell said we should give the money back to the shareholders and close the company. We persisted on a wing and a prayer, driven by Steve Jobs’s admonition that we could beat Dell. I believed in that mission, and I believe in it still.

In 2005, I wrote boldly about the end of Dell, and I have to confess I was a little over-ambitious. I could see a path where Apple would take Dell down faster than they have. I was wrong. Dell is still a strong  company. But that will change soon.

I joined Apple because they were threatening to change the world. I stayed on at Apple because they were changing the world. And I remain loyal to that company because, in spite of my absence, they have changed the world. In more ways than I can imagine, they’re inventing the future. And I’m along for the ride.

Dell is not changing the world, Microsoft is not changing the world. Hewlett-Packard is not changing the world.

Apple is changing the world, and damn it feels good to be part-Apple today.

FastScripts Plugin For Google Quick Search Box

March 24th, 2010

I love to be surprised by what customers manage to do with my products, so I was thrilled when Martin Kühl wrote to tell me about his GitHub project that provides a FastScripts plugin for Google Quick Search Box.

If you’re not familiar with Google Quick Search Box, it’s basically a Quicksilver-style launcher, which can open all manner of documents and also do Google searches for whatever you’re typing, all at once. With the addition of Martin’s FastScripts plugin, it also magically gains the ability to directly run FastScripts scripts.

So if I bring up the quick search box and start typing the name of one of my scripts, it shows up instantly:

Significantly, this is more meaningful than simply knowing about where the scripts are located, and running them. Martin mentioned to me that he was taking advantage of my “API” for accessing and running the scripts. Huh? What? I don’t have an API, do I? Oh yes, but of course! AppleScript itself! Martin used the fact that FastScripts exposes AppleScript access to its library of scripts, and for executing those scripts in the context of FastScripts. So when you select and run a script from the GQSB, it runs exactly as it would if you selected it from the FastScripts menu itself.

A clever piece of work by Martin that takes unexpected advantage of these hooks I put into FastScripts. If you use both FastScripts and GQSB, you might want to check his project out!

Surfing In Antarctica

March 15th, 2010

I hate the iPad! I love the iPad!

I object to Apple’s sometimes farcical behavior when it comes to App Store policies, rejections, exceptions, etc. But my feelings are extremely mixed. I love the hell out of my iPhone, and I pre-ordered an iPad at 8:30 AM on Friday. I believe Apple has a morsel of magical quicksilver in its palm. As with the iPhone, I’m coming along for the ride, whether or not I like the way they are driving.

The iPhone and iPad are compelling enough, so why haven’t I released any significant apps yet?  I still have several apps under development, but none of them is ready for mass consumption. Mainly because my Mac software takes priority for my attention, but also because I want to make sure I understand how software on touch devices should work before I tackle the problem.

I attended Apple’s iPhone Developer Tech Talk in New York in December. During the reception, I had the privilege of speaking briefly with Apple’s UI design rock-star evangelist, John Geleynse. I got to talking with him about the iPhone and its significance in the world:

“I’ve lost 20 pounds in the last 4 months,” I blurted out. “I don’t think I could have done it without the iPhone.”

I had downloaded an app called Lose It, and thanks to the ubiquity of the iPhone, I was able to use this simple calorie-counting aid to change my eating habits for several months. I was eager to share how this little app had changed my life. I struggled to make my point:

“The iPhone has changed everything. Surfers love waves, right? And they want to surf everywhere. But if you’re a surfer and you want to surf in Antarctica, you’re screwed. But if you had the right wetsuit, you could surf anywhere. You could surf in Antarctica!”

Mr. Geleynse indulged the metaphor, but seemed to be waiting for the punch line.

“So, I lost all this weight, and it wouldn’t have happened without the iPhone. Before the iPhone and before this app, losing weight to me was like surfing in Antarctica: I had no equipment, and no chance of survival.  The iPhone gave me the equipment not only to survive, but to know that survival was possible.”

This is what Apple does well. While the rest of the world iterates on existing solutions to known problems, Apple discovers and solves problems we didn’t even know we had. I didn’t realize that the lack of a ubiquitous, hand-held computer was limiting my abilities. I didn’t know what had been impossible would become possible.

Skeptics of Apple’s innovation tend to be stuck in that mode of thinking which judges solutions only in terms of known problems. Imagine the poor inventor of the scuba suit, who upon first showing his contraption to peers, may have been met with flat rejection: “It doesn’t look very comfortable.” True, the scuba makes for terrible evening wear … unless you’re throwing a party at the bottom of the ocean!

If you’re not looking beyond the horizon, if you don’t care to expand the reach of civilization, or to solve impossible problems, then you don’t need a scuba suit.

If you are looking for adventure, suit up. Antarctica on a surfboard? April 3.