The problem, in a nutshell, is that these dialog boxes steal keyboard focus. Sometimes it’s for a text field; sometimes it’s just for Full Keyboard Access (i.e., a button gets the focus—usually, these are alert boxes). Regardless of what control gets keyboard focus, it gets it by stealing it from your app, which is a problem if the user is typing when that happens. Most likely, either some text will go to the wrong place, or the dialog box will beep for every keystroke; either result will annoy the user.
We’ve had the same problem for a long time in Adium: we’ll throw up a dialog box, but the user is typing a message, and notices that half his message isn’t in the inputline. We believe we’ve fixed most of these, but we still get complaints about this problem from time to time.
Currently, we solve the problem by simply ordering the dialog front without making it key. This works for most people, but it doesn’t help people who really do need Full Keyboard Access, since you have to click on the dialog box to dismiss it (or make it key) if it isn’t key. We (by which I mean Mac programmers, not just Adium) need a better solution.
I propose an addition to NSAlert. Here’s how it would work:
- From the creation of the NSAlert instance, it watches for key events.
- When any key goes down, the alert resets the timer (if one is present) and sets a flag.
- When all keys are up, the alert creates and starts the timer (with an interval of, say, a couple of seconds).
- If you tell the alert to show, it checks the flag. If the flag is clear, it simply performs
makeKeyAndOrderFront:like usual. If the flag is set, it only orders front, and it sets a second flag.
- When the timer fires, the alert clears the first flag, and if the second flag is set, makes itself key.
From the user’s perspective, this results in the alert waiting a couple of seconds for them to pause in their typing before it takes keyboard focus.
Does anybody know of an existing free implementation of this, or plan to write it themselves?