Quickly Find Project Files in Xcode

November 6th, 2005

I like the Search-Fieldy kind of thing in Xcode. If you select the top-level project item in the “Groups and Files”, and then enter something in the search box, it makes it really easy to pinpoint a particular file that is contained by your project.

Apple even gave this search box thingy a keyboard shortcut, and include a menu item in the View menu for accessing it: “Detail”. I don’t really get the name of that menu, but needless to say it will switch you over to the search box thingy whenever you invoke it.

Problem is, I am almost 100% likely to want to search my entire project when I switch to it, but Xcode doesn’t do this for me. I hit shortcut and then I inevitably have to go click the project icon in the outline view before switching back to the search box to enter text.

Using GUI Scripting, I was able to solve this dilemma by writing a small script that simply clicks the project item for me before switching to the search field. The script asks the “Groups and Files” outline view for the “first top level item whose name is the same as the name of the project.” I’m pretty sure this will always be the desired row of the column, even if you’ve done some funky reordering of items.

Click here to download: Find Project File

I used FastScripts to assign an Xcode-specific shortcut override. Now when I hit the Cmd-Opt-F shortcut for “Detail” it behaves as usual, but clicks the project icon for me on the way.

Update: Xcode’s “whose clause resolution” started flaking out and giving me false hits, so I decided to just rely on the Project item being the first item in the Files and Groups list. This has the added benefit of making the script a lot faster, but it means it won’t work if your Files and Groups list is customized with the project not at the top.

Startup School Podcast

November 3rd, 2005

A few weeks ago, a relatively low-key, one day convention took place in Cambridge, MA. The event, put on by the unconventional Y Combinator venture group, was dubbed “Startup School.” Essentially a one-day lecture series in which a number of high-caliber computer and business industry players gave short speeches and answered Q&A from an audience filled with aspiring startup founders.

Though I missed the event, I was lucky enough to meet up afterwards with some folks who attended, and got a sense for what the scene was like. It sounds like a lot of really ambitious and talented people were inspired to put their innovation caps on. What will come of this firebrand occasion? Only time will tell.

Luckily for the rest of us, the folks at Y Combinator have made audio recordings of all the speeches available in podcast format. The recording quality is good, though one major shortcoming is that most questions from the audience are not audible. This means you’ll experience moments of silence followed by a response from the speaker. Some of the speakers are kind enough to rephrase the questions before answering them.

I like these recordings not only because the collective wisdom of the speakers is easy to respect, but because the nature of the event seems to have lent a bit of an informal nature to the proceedings. I almost get the sense that the speakers had no idea that what they were saying was being recorded for eventual international broadcast. You get a sense of these speakers on a pretty social, everyday level. Check it out:

Startup School Podcast

Several hours of interesting computer-industry banter to help you while away those miles on the treadmill.

Thanks to Beau Hartshorne for the link!

Fixing Keychain – Look Ma, No Code!

November 3rd, 2005

While waiting for Apple to fix the many bugs that I described in my recent posting, I thought I’d hack in with Interface Builder and fix some of my gripes myself. For the benefit of anybody who shares my grievances, I describe the process here for fixing several of the problematic behaviors.

Note: This is risky business. Modifying system files. Don’t proceed with the operations described below unless you’re both exceedingly confident you will not make a mistake, and exceedingly confident you’ll be able to repair it when you do make a mistake. As a rule, modifying Apple’s products is a bad idea. The changes you make are liable to cause unforeseen side-effects, and will be obliterated by any update from Apple that replaces the affected files.

Think of the instructions below as a sort of entertainment fiction. You like to watch movies and read books where the characters steal, pillage, murder, take dangerous drugs, etc. Enjoy the thrill of my dangerous activities vicariously. And if you decide to mimic these bad habits in the privacy of your own house, don’t tell us about it! (Unless you have a really good idea).

Preparing to Hack

As with all modifications of Apple-provided applications, it’s a good idea to start by making a backup for safety’s sake. In the case of Keychain Access, you’ll discovery quickly that it’s not as simple as making a copy of the application in the Finder. It will warn you that “special permissions” prevent everything from being copied. There are two things at work here. First, the Keychain Access application and everything inside it is owned by root. Second, there are files inside the package with a “setuid” bit set, meaning that when they run, they get to inherit the privileges of root. To make this easy, I suggest in this case only backing up the “Resources” portion of the bundle, because that’s all I’m going to be modifying. You might get some complaints from Interface Builder that the nibs are “read only.” I just saved a copy and then copied the new nib into the English.lproj directory of Keychain Access.

Applying the Changes

Alleviating the broken “next responder” loop in the main Keychain window was as simple as defining an “initial first responder” for the window, and setting up an appropriate chain of “nextKeyView” connections. It seems that the responder chain as it ships from Apple is simply the default “emergency chain” fabricated by Cocoa when a developer doesn’t specify a particular chain. I decided to make mine start with the search field, and advance clockwise through the main table, “Category table” and “Keychain” table. The MasterView nib file contains the window whose contents can be fixed in this way.

While poking around in the MasterView nib, I also decided to change the keyboard shortcut for the “Info” button from Cmd-I to simply return. This has the effect of making the return key always open the item selected in the main table, which is fine because the return key doesn’t do anything special in the other tables in the window that can receive focus.

To give a keyboard shortcut to the “Show Secure Note” and “Show Password” items, I located the corresponding UI elements in the NoteEditor and PasswordEditor nibs. I gave them each the shortcut “Cmd-T” (for “Show Text”).

To alleviate the headaches of the “Save Changes” dialog’s missing keyboard shortcut for “No,” I only had to change the Localizable.strings value for that key from “No” to “Don’t Save,” which is probably what it should have been in the first place! Keychain Access uses NSBeginCriticalAlertSheet to display the Save Changes dialog, and as advertised, it will automatically accept Cmd-D as a synonym for clicking on the Don’t Save button. Sometimes “doing the standard thing” also means “doing the right thing,” and adds up to less work for a better product.

Now for the The Big Kahuna. The all-powerful “Allow Acccess” keychain authorization dialog. This bad boy’s unresponsiveness to keystrokes makes it the weak link in not only Keychain Access, but every other application that asks the user to approve a keychain fetch. Where does the Big Kahuna live? By running the command-line tool “fs_usage” while invoking the dialog, it’s easy to locate the nib in question. It looks like /System/Library/CoreServices/SecurityAgent.app/Contents/Resources/English.lproj/ConfirmAccess.nib is what we’re interested in. Again, the sensitive nature of this application means that I have to be careful to leave most of the existing app in place, while only backing up and modifying the resources.

Since I’m usually more interested in giving applications access “forever,” I not only added keyboard shortcuts, but moved things around a bit. I renamed the “Always Allow” item to “Allow Forever,” made it the default button, and moved it to the far-right. I gave the “Allow Once” button the simple shortcut of the “O” key. For some reason I was unable to give it a shortcut that requires the Cmd key to be held down. I’ll take what I can get! The resulting dialog looks like this:

And hallelujah! I can just “hit return” when it pops up.

The only item in my list of gripes which I haven’t been able to address in one way or another is the “Close All Windows” function. If Keychain Access were scriptable, it would be easy to write a script to workaround the problem, similarly to how I solved the problem in Terminal. As it is, I don’t expect to open up 500+ info winodws in Keychain Access in the near future, so I think I can live with that shortcoming.

Keychain Inaccessibility

November 3rd, 2005

Apple’s 10.4.3 update includes a nice surprise: the search field for the Keychain Access application is now case-insensitive! How many times I’ve fumed and fussed about this shortcoming. At last I can search for “etrade” and find a note called “ETrade info.”

Though vastly improved, by no means is the Keychain Access application perfect. In fact, this application and associated technologies are one of those “treasure troves” of undesirable behaviour. Often while looking more carefully at an unfortunate behavior, with the intention of reporting a bug, my attention ends up snowballing into a series of observations of how an application could be better designed.

With Keychain Access, a major area it is still lags in is the keyboard navigation department. Now that I can easily search my keychain items, it would be nice to be able to do so without ever reaching for the mouse. At this point I have a keyboard shortcut set up to open Keychain Access, and from within the application I can press Cmd-F to start a new search. But when I see the beautiful shining result in the filtered list, there’s no way to navigate back to it! Pressing Tab from the search field does exit the search field, but it switches focus to the “Keychains” sidebar table. Who wants to navigate to that? Pressing Tab again switches focus to the “Category” table. Arrow-keying through the various items in this table causes a live update of the main table, but no amount of tabbing will get you there. It’s a “next responder dead end!” (Radar 4327828).

Once I’m focused on the main table, there are other hiccups. It took me a while to figure out that I can in fact bring up the secure item’s “info dialog” by pressing Cmd-I. This shortcut is attached to little “i” button at the bottom of the screen, and unfortunately is not available from any menu item. The friendliest way to handle this would be to have the tableview interpret “return key” as a signal to “open the selection.” The return key is often interpreted as a request to either open or edit a selected item. In this case, by opening the Info dialog, it would do both. (Radar 4327871).

But anyway, at least I can get info! The fun stops there, however. I am looking at the info window, but the thing I want to see: the secure note, web password, whatever, is hidden from me. I can see the checkbox that needs to be clicked to reveal the secrets, but I soooo don’t want to reach for the mouse. There should be a “Show Secrets” keyboard shortcut for any secure item that has such a checkbox. (Radar 4327842).

In the process of trying to figure out whether there was a convenient shortcut for “show secrets” in the info dialog, I managed to stumble into accidentally editing the item. When I closed the item, a dialog came up asking me if I’d like to save the changes. I tried the typical “Don’t Save” shortcut: cmd-D. No such luck. The “Save” button is throbbing blue so its keyboard shortcut is taken care of, but the “No” button seems to require a manual mouse click. As a long-shot try, I press “Cmd-N” to match the “No” of the button’s text. At first this seems to work, but instead something very fishy happens. Pressing Cmd-N, even while being faced with a modal sheet in the Info dialog, invokes the application’s higher-level “New Keychain Item” functionality. The Info window and its pending sheet disappear and a sheet appears on the main window asking for details about my new item. I thought the window had been dismissed, but later I found it hiding behind the main keychain window. It had simply been ordered backward. The “Save Changes” dialog should support a keyboard shortcut for “Don’t Save.” (Radar 4327889).

Let’s assume all the above bugs get fixed, and I’m sitting pretty in Keychain Access land. I hit my Keychain Access keyboard shortcut, press cmd-F, search for “etrade,” navigate to the main table, press return to open the item, press a keyboard shortcut to reveal the secret password, and am faced with the “Keychain Access wants permission” dialog. First of all, isn’t this the Keychain Access application? I’ve just unlocked my whole keychain. We’re staring at my repository of goodies. Can’t you work out a deal or something? You seem to be “in good” with the Keychain. Once you show the secure text for an item, you can choose to “Always Allow,” but that only gives permission for that specific item! So you’ve got to enter the password and click “Always Allow” at least once for every freaking item in your keychain. There should at least be a preference for easily saying “Always give Keychain Access access to secure items.” (Radar 4327935).

I thought maybe I could do something spiffy like go in and manually set all of the items to allow Keychain Access to access them. Since you can “preload” this setting in the “Access Control” pane of an item’s info window, I thought maybe I could select all of my items and add the same access privilege for Keychain Access to them. Oops! I selected all 500+ items and hit Cmd-I. Now I’ve got 500+ Info windows cascading across my screen. To add insult to injury, Keychain Access doesn’t support a “Close All Windows” option, though quitting and relaunching did the trick. (Radar 4327956).

Having to give individual authorization to each and every item wouldn’t be so bad if the authorization dialog itself wasn’t so poorly keyboard-navigable. The dialog pops up, asks you to give authorization (by typing of course… at the keyboard!) and then you have to go over to the mouse to click either the “Deny,””Allow Once,” or “Allow Always” items. Gah! Presumably this is done to prevent somebody accidentally giving permission to a malicious application, but you’ve got to enter the password before doing so! That gives me plenty of opportunity to think twice before allowing or denying the action. At least the “Allow Once” button should be default and automatically clicked upon hitting return from the password dialog. The “Always Allow” button should ideally also have some keyboard shortcut. (Radar 4327981).