I’m guessing there isn’t a way to do this with Applescript alone, but I thought it would be worth asking anyway. Is there any way to have a window show if a certain key is held down when the app is launching? I have an app that never normally displays any windows and quits when it has finished its business, but it would be great to have a preferences window that would be displayed when a certain key, say the p key, is held down when launching the app.
If it can’t be done using just Applescript can anyone recommend how to do it using Cocoa?
No, this can not be done using just applescript. Applescript only has access to application keyboard events, which are not sent until the app is fully activated and launched. You’ll have to use carbon functions, which can access system events independent of your application’s events.
I would recommend using modifier keys instead of character keys to trigger hidden startup actions, because they do not cause events to be dispatched to your app. For example, let’s say you try to detect the ‘p’ key at startup. To ensure that your app detects the p key you’ll likely hold it down before you even click on the icon to launch the app. Then, you’ll probably hold it down during, and shortly after the app launches. During this entire time you’re holding down the p key, a continuous p key event is being dispatched to the system and also to the frontmost application. Before you app launches, the frontmost app gets the key event. After your app launches, your app gets the event. If there is a responder capable of receiving a key event in either app, it will get theses events and handle them as they would any other keyboard event. This could lead to some undesirable results. People are unlikely to want a long string of p’s unexpectedly entered into some random text field or view. This could be especially annoying if the first responding text field in your app is a user-entered string. Every time your prefs window opens at launch, the first available text field would automatically become first responder and it might erase the previous text and start typing p’s until you let go of the key. And, if there is no responder in either app that can handle a character key event it will beep continuously letting you know that you’re pressing key that’s not being processed by the app.
So as I said, I would recommend using modifier keys instead. You can capture the control, shift, option, and command keys, and none of them alone will cause keyboard events to be sent. Check out this post for instructions.
If you decide to use a character key, first consider my comments above and then do the following…
Add the cocoa files AppController.h and AppController.m to your project. See the comments in the ‘KeyWasPressed’ method for source attribution, as I didn’t write the code that tests for a particular key code myself. I left in his comments so you can get an idea of what the code is doing. There may be a prettier way of doing this, but I’ll leave that to you as an exercise.
Connect your application’s ‘will finish launching’ handler to your script, and use the following code…
on will finish launching theObject
set pKeyDown to (call method "isPKeyDown" of class "AppController") as boolean
if pKeyDown then show window "hiddenWindow"
end will finish launching
With a few adjustments to account for Xcode 3 that worked a treat! Thanks for the advice and the help - once again! You are a handy person to have around! I went for the modifier key. There was no particular reason to have a letter.