This is a true story about fixing a bug.
Our hero is New Zealand-based Mozilla hacker Cameron McCormack. Cameron knew about this bug in the first place because someone (Marco De Vitis, to be specific) took the time to report it at bugzilla.mozilla.org. It’s bug 434494.
I chatted with Cameron about the bug and what happened next.
<jorendorff> So this bug is about what happens when you have no windows open and you hit Cmd+K <heycam> right <jorendorff> which I guess only really happens on the mac, right? <heycam> yeah <heycam> where closing all the browser windows doesn't quit the app
It’s normal on the Mac for an application to stay open when its last window is closed. So in Firefox on the Mac, if you close all your tabs, Firefox is still there, and you can open a new browser window from the menu or by using a keyboard shortcut. Cmd+K is the shortcut for the search bar.
<jorendorff> OK. So Cmd+K creates a new window in that case, and the bug was, sometimes it would focus the search box as desired, sometimes the location bar instead.
<jorendorff> how did you track it down? <heycam> I *think* I searched for where the location bar got its focus, first
(Cameron doesn’t remember clearly because it was a month or two ago. More about that in part 2.)
<heycam> ok <heycam> http://mxr.mozilla.org/mozilla-central/source/browser/base/content/browser.js#1485 <heycam> so that's the only line that focuses the url bar <heycam> (it seems) <jorendorff> aha
Well there you go. Focus the URL bar. There’s your bug, right?
But this can’t be the whole story, because in other circumstances, Cmd+K works. Somewhere there must be code for focusing the search bar that isn’t being called or isn’t working properly in this case. Cameron had no idea where that code might be.
So he went to mxr.mozilla.org and searched for it.
<heycam> that's right <heycam> there's a file that has a whole bunch of keyboard mappings to actions <heycam> something.inc <heycam> browser-sets.inc <jorendorff> http://mxr.mozilla.org/mozilla-central/source/browser/base/content/browser-sets.inc <heycam> yeah <heycam> I still have no idea how all the xul things fit together <heycam> but having found this file, I could see that it associates Cmd+K with a "command" <heycam> Tools:Search <heycam> http://mxr.mozilla.org/mozilla-central/source/browser/base/content/browser-sets.inc#230
<heycam> and then my thinking is "what defines commands" <heycam> so I'd grep that directory for Tools:Search <heycam> $ cd browser/base/content <heycam> $ grep Tools:Search * <heycam> browser-menubar.inc: command="Tools:Search"/> <heycam> browser-sets.inc: <command id="Tools:Search" oncommand="BrowserSearch.webSearch();"/> <heycam> browser-sets.inc: <key id="key_search" key="&searchFocus.commandkey;" command="Tools:Search" modifiers="accel"/> <heycam> browser-sets.inc: <key id="key_search2" key="&findOnCmd.commandkey;" command="Tools:Search" modifiers="accel,alt"/> <heycam> browser-sets.inc: <key id="key_search2" key="&searchFocusUnix.commandkey;" command="Tools:Search" modifiers="accel"/> <heycam> that <command> element looks right <heycam> that gets us to the webSearch function in browser.js
webSearch function. It also lives in browser.js, it turns out.
<jorendorff> so now we know two things <jorendorff> We know where focusing on the search bar is supposed to happen (and roughly what pointers the system is chasing to get from Cmd+K to this JS function) <jorendorff> we also know there's some other code in browser.js that focuses on the url bar. <heycam> right <jorendorff> and the hunch is then "i bet both are happening"? <heycam> both are happening, but in an order that's not fixed <jorendorff> now what? <heycam> I may have put some debugging code in to make sure that both are running, not sure <heycam> like an alert or something <jorendorff> That was the next thing I was going to ask about. <heycam> without knowing how chrome js works, it's hard to know how to even do simple printf debugging <jorendorff> Of course anybody reading this--certainly if they happen to be running Firefox 4 on mac -- would like to watch this happening <heycam> yeah
Would you? Maybe we’ll do that in part 2.
<heycam> will you be making a guided tutorial to fixing this bug? <jorendorff> Weelll, It depends on how much time I end up with :-\ <heycam> I think UI stuff is a great place for new people to start working on, because it's very immediate <heycam> and you can see if things are working or not <jorendorff> i agree! <heycam> but, there's an awful lot of complexity in there <jorendorff> well, that's how it is <heycam> undocumented too <jorendorff> but what you're showing people is how to ignore things rather than get overwhelmed <jorendorff> this is valuable <heycam> yeah, I think that's the key <heycam> ignoring things, plowing on <heycam> and if you miss important things, others will let you know <heycam> that's how I try to approach areas I'm unfamiliar with <heycam> I'll have a bash at it, post it for review, and learn what things I didn't know from review comments <jorendorff> as in this case <heycam> yeah <jorendorff> but that gets ahead of the story
We’ll get there in part 2.
Now about that life lesson.
You probably noticed Cameron has been tracking down the problem by randomly searching the code for words that might be relevant. This might not seem worth documenting. In fact it may seem a little embarrassing—you mean he didn’t know the code well enough to figure out where the bug was using only his enormous brain? But this is exactly what I think is most important about this story. What Cameron is doing requires some programming chops, and it requires the ability to navigate undocumented monster-infested waters—but it’s not magic.
You could do this.
Maybe you are not an expert in everything. Maybe (like me) you’re a shy person working in a complicated world with incomplete knowledge. How can you function like that? How do you know if you have anything to contribute? How can you get involved in new things?
Step 1: Don’t panic.
- search for the answer
- try something and see what happens
- ask someone
To be continued.
Update: Part 2 is up.