Scroll Un2 The Year 2007

Friday, March 30th, 2007

(with apologies to Prince)

So lately I’ve been getting asked about what I’ve been working on, and why I’ve been so absent from the “real world”. Usually, I just wince and then say “um… Scrollbars. Basically rewriting them.” That sounds overly simplistic, but it’s really not. Bug 370439 is literally titled “Rewrite native scrollbars to use nsITheme.” In case you don’t know what that means, let me explain.

In Firefox 2 (but also any other application based on Gecko 1.8.1, such as Thunderbird), when we need a scrollbar on the Mac, an actual native scrollbar widget is created, superseding the Gecko implementation. The operating system handles all the drawing and events, all we have to do is forward clicks to it. The problem with this approach is two-fold:

  1. It doesn’t work very well.
  2. It’s completely different from the way scrollbars are done everywhere else.

This strange way of doing things means Mac scrollbars don’t currently don’t obey clipping or z-ordering or transparency correctly. This is very bad.

As I said earlier, scrollbars are currently implemented by creating a native widget, to which events are forwarded. In Gecko terms, this means creating a new frame type for scrollbars. Even if scrollbars didn’t have the problems they do, this would also not entirely desirable, since there already exists another way to draw scrollbars. As far as I know, every other platform, except Mac OS X, uses this magical API.

Enter nsITheme! nsITheme is an interface for drawing and controlling the display of various widget types. It’s used on other platforms to get manage native look & feel, and in Firefox 3, Mac widgets use it pretty extensively. It’s how we’re going to get those lovely native form widgets. We love nsITheme.

So five weeks ago I started working on this scrollbars rewrite, and now it’s nearly done. All that’s left is a maddening bug where Gecko and Aqua can’t quite agree on the size of the thumb—the big blue part on Mac OS X. If Gecko thinks the thumb is smaller than it actually is displayed, it won’t redraw the portion outside where it thinks the thumb is, causing a trail. Every time I think I’ve got it solved, I find another edge case. I can’t wait to put the entire thing behind me.