Hacking Chrome with Git

Motivations

I spent some time hacking around in Chrome the other day because I have been extremely frustrated with the behavior of the downloads bar in the Mac version of Chrome. When the user initiates a download, it appends the downloads bar to the bottom of your current window, causing your window to grow by the height of the download bar.

This behavior really bothers me, since I have my window set up with about 10px of padding around all sides so I can easily see my IM window and other things that I have docked to the top/side of my desktop. When Chrome grows the window, I have to manually shrink it and then scoot the window away from the title bar again. Then, when I close the downloads tab, I need to make the window bigger so there isn’t an enormous gap below the browser window.

I submitted a bug report about this issue, but a member of the Chrome team explains that they consider this to be the correct behavior:

This is by design, as we do not want to change the size of the web content. We do attempt to restore the original window size when you close the download shelf, although that logic seems to break at times (see Issue 39266).

If that’s their position, then fine, though it does contradict other behavior of Chrome’s. Chrome will, for instance, not enlarge the window when they display the “do you want Chrome to remember your password” alert bar and other similar things. It simply pushes the content down a small amount and then pulls it back up when you close the alert. This is far preferable to me over messing with the size of my window.

The Fix

Well, Chrome is open source, so I decided that if they won’t fix it, I would. At least for my build, anyways. Turns out that it’s a one-line patch to a single controller file. Here they check to see if the view that’s initiating a redraw is the download shelf or the bookmark bar. If it is, they add the height to the view to the window. In this case, I just removed the condition for the download shelf and voila!

How I built Chrome

Hopefully I can save you some time if you’d like to perform similar surgery to your copy of Chrome. It took me a few tries to get everything right, due to some incorrect documentation and the enormous size of the Chrome checkout. Naturally I want to use git, since it’ll make my patch sets so much easier to maintain. These instructions show you how to build a specific release version with your patches using git. This assumes you’re building 5.0.375.17. Substitute a different version if you’d like.

  1. Follow the Chrome Git instructions steps 1-3. You’ll need to install depot tools as indicated in step 2.
  2. Instead of using the URL specified in step 4, use http://src.chromium.org/svn/releases/5.0.375.17, or another version of your choice.
  3. cd into ./src
  4. git config --add svn-remote.375.url http://src.chromium.org/svn/branches/375/src
  5. git config --add svn-remote.375.fetch :refs/remotes/375
  6. git svn fetch 375 (this fetches branch 375 into your local git repo)
  7. Look in http://src.chromium.org/svn/releases/5.0.375.17/DEPS and find in the deps dict where there is src alone. In this case, the value is /branches/375/src@45275. This means that version 375.17 is svn commit 45275. Remember that number.
  8. git checkout refs/remotes/375
  9. git log and search for 45275. Once you find the commit, note the git sha hash. In this case, it is 1bb2782587c269be10f842a468e2d26b38003daa.
  10. git checkout -b 375.17 1bb2782587c269be10f842a468e2d26b38003daa (make a checkout of the exact version of the release)
  11. Do steps 5-6 of the Chrome git instructions.
  12. Apply your patches

You now have a specific version of Chrome and all its dependencies checked out and ready to build. You can now follow the Mac OS X build instructions, or just open src/chrome/chrome.xcodeproj and choose “chrome” from the build menu in the upper left. Choose “Release” if you want to build Chrome for actual use. Note that this took over an hour on my fancy new i7 MacBook Pro with 4GB of RAM. It also used enough resources that my computer was nearly unusable for part of the compile.

Chrome Build Process

A few notes about the Chrome build process: The git repo stores only the code for the browser itself. General libraries, both Google internal and external, are fetched by using the gclient sync command. This is somewhat similar to git submodules, in that it allows Google to pin specific revisions of dependencies to a release. The DEPS file stores all the revisions of the external repositories that are necessary to duplicate a build. The tricky part was to make sure that the git checkout and the dependencies both corresponded to the same release version.

I haven’t yet had to switch my build to use a different release. As soon as that happens, I will update this page to give instructions on how to do so.

Download

If you’d like, you can download a copy of the current dev channel of Chromium with my fix applied. Or you can follow the instructions above and patch it yourself.

The Future

The Chrome guys are working on eliminating the http:// scheme from standard HTTP urls. It turns out that this caused a lot of bugs when they released it into the dev channel so they reverted the change, but they have said that they will eventually revive this “feature”. I found it really annoying and my custom chrome build will likely do away with http hiding once it becomes part of Chrome. I’m happy to work with someone who’s also annoyed by this to set up an automatic build to release a new dev channel build with custom patches to fix some of these “features”… Let me know.

Brandon Dimcheff
Brandon Dimcheff
Chief Architect

Brandon Dimcheff is a software engineer born and raised in Ann Arbor, Michigan. He uses go for his day job, has fallen in love with Kubernetes, is an aspiring functional programming language nerd, and is an advocate of open source.