The Wayback Machine - https://web.archive.org/web/20081227015944/http://boomswaggerboom.wordpress.com:80/
Boom Swagger Boom











{November 26, 2008}   Gecko NPAPI Plugins Update

Yesterday I became the owner of Gecko’s NPAPI plugin module. Johnny Stenback, the previous owner, remains on as a peer. Given that change, now seems like a good time for an update on plugin module priorities. My current priorities are related to testing, accessibility, and code cleanup.

Automated testing for NPAPI plugin functionality has been highly requested for a while. In bug 386676 I posted a patch that allows for plugin mochitests. The first test gives us coverage for a basic plugin load plus basic npruntime calls into and out of a plugin. As soon as that lands I hope we’ll be adding many more plugin tests and expanding our testing capabilities.

I am working on solutions to two major accessibility bugs, as discussed in this post. We need to allow plugins to reject keyboard events so keyboard commands for things like close-window can work while a plugin has focus, and we need to allow for changing focus from a plugin to other content via the keyboard. Work is slow but steady, things should speed up as other things like testing fall into place.

Gecko’s plugin module is in need of some general TLC. This includes code formatting, dead code removal, renaming/re-factoring for readability, general ugly/outdated code auditing, and sample modernization. I landed some of that already and I’m hoping to land a bunch more over the coming months.

I’m not ready to write about longer-term priorities yet, things like out-of-process plugins. We are thinking about them though, I’ll have more information in January or February. In the mean time I’m looking forward to making a lot of progress on things that will make the bigger changes easier to digest.



{November 9, 2008}   Sunday in NYC

New York is a fantastic city. I spend a fair amount of time there and today was just such a nice day I feel like writing about it.

I woke up this morning at a friend’s place in Spanish Harlem, the sun shining brightly through the windows - it was a beautiful day. We walked to a bakery and got coffee and croissants, then we walked to a nearby park and watched a largely Puerto Rican baseball game for an hour while we drank our coffee. The players were probably 14 years old and having a lot of fun. A guy rode by on a bicycle flying about ten Puerto Rican flags, honking a little horn constantly and smiling at everybody.

After the game I walked South, from E 112th & 2nd to around E 78th & Madison. It is a nice walk, interesting because you get to see the transition from Spanish Harlem to the wealthy Upper East Side. My friend is a teacher and she was recently talking to her kids about health. She suggested focusing on what food is readily available on each block of the walk. Nutrient value, pricing, cuisine diversity… speaks volumes.

Madison Avenue on the Upper East Side has a lot of fashionable clothing stores and some great people-watching. I ended up having lunch with Hal Hackady at a diner near there, where he introduced me to rice pudding with whipped cream and chocolate sauce and gave me some good advice about new strolls through Central Park. Hal also drew a picture of me on a napkin while I was staring off at something:

Drawing of Josh by Hal

I like that he didn’t use a clean napkin.

After Hal and I parted ways I headed into Central Park and watched people sail little boats in the pool near 75th on the East side of the park. It is a busy part of the park on weekends, but sitting there on weekdays can be really peaceful.



{November 2, 2008}   New Mac OS X Widget Peers

I’ve added two new peers to the “Widget - Mac” module (Cocoa widgets), Steven Michaud and Markus Stange. They have both done great things for the module and working with them is a pleasure. Steven has contributed a huge number of fixes for tough bugs over the past two years, focusing on event handling, plugin interaction, and crash debugging. Markus joined us earlier this year and has gotten up to speed very quickly. He has contributed many fixes focusing on theme and OS integration issues.

Thanks Steven and Markus!



Recently I have been doing some work to make life easier for NPAPI plugin developers. As part of that effort I started to revive our NPAPI SDK and rewrite some of our sample code. Today I’m going to explain how to write an NPAPI plugin for Mac OS X, based on the basic sample plugin in our SDK. It is actually pretty easy now. You can have one built and running in the browser in minutes.

The sample code I’m going to be referencing today can be found here:

http://mxr.mozilla.org/mozilla-central/source/modules/plugin/sdk/samples/basic/mac/

We decided to commit that sample under a BSD-style license which means you can use it for anything, even if you don’t plan to release source code. This is unfortunately common for NPAPI plugins.

If you check out the Mozilla source code in Mac OS X, you can simply open “BasicPlugin.xcodeproj” and hit build and you’re done. A “build” directory will be created next to “BasicPlugin.xcodeproj”, and if you built in release mode that will contain a “Release” directory with the plugin inside it. Copy that plugin into one of the following two locations and it’ll work:

/Library/Internet\ Plugins/
~/Library/Internet\ Plugins/

Just modify the basic sample plugin to do whatever you want.

Now I’ll explain some things that might not be obvious if you were trying to get such a plugin building on your own.

The plugin communicates its MIME and extension information using the “Info.plist” file which is packaged in the plugin bundle. Just read the file to see how that is done. The plugin also communicates its bundle type in that file, under the key “CFBundlePackageType” - the type is “BRPL”. If the type is not an NPAPI plugin type, the bundle won’t load as an NPAPI plugin. You can just always use “BRPL”.

I made a GCC preprocessor definition in the project file, “XP_MACOSX=1″. This is used by the NPAPI headers, if you don’t define it they won’t be interpreted correctly on Mac OS X. This is easy to miss in the sample project file build settings.

Symbol visibility is a common problem area for people trying to get NPAPI plugins working. Some symbols must be visible as standard C symbols so the browser can find them, which (always?) means simply prefixed with an underscore (Foo() = _Foo). There are three symbols that need to be visible as standard C symbols on Mac OS X - “NP_Initialize”, “NP_GetEntryPoints”, and “NP_Shutdown”. Our sample plugin is written entirely in standard C and uses a standard Xcode build configuration so by default all of its symbols are C-style and visible. If you wanted to implement your plugin in C++ (.cpp) or Obj-C++ (.mm), you would have to do this:

#pragma GCC visibility push(default)
extern “C”
{
NPError NP_Initialize(NPNetscapeFuncs *browserFuncs);
NPError NP_GetEntryPoints(NPPluginFuncs *pluginFuncs);
void NP_Shutdown(void);
}
#pragma GCC visibility pop

You can check to see if your symbols are visible and in standard C naming format using the “nm” utility on Mac OS X, targeted at the plugin binary. The results should look like this:

[josh@denmark MacOS] nm BasicPlugin

00000810 T _NP_GetEntryPoints
000007fa T _NP_Initialize
000008a0 T _NP_Shutdown

This basic knowledge should get new NPAPI plugin developers pretty far on Mac OS X. Soon I’ll write up the same thing for getting an NPAPI plugin working on Linux/UNIX systems.



I’ll be giving a talk about the Mozilla project at Independents Hall in Philadelphia on Wednesday, September 17th, at 6:30 PM. The talk will include an overview of Mozilla’s software development process and our organization.

Independents Hall is located at 32 Strawberry Street in Old City Philadelphia.



{September 11, 2008}   NPAPI Plugin Bugs, Accessibility

I want to talk a little bit about Mozilla NPAPI plugin bugs 78414 and 93149. I’m surprised by the fact that more people don’t complain about them given how irritating they are, particularly on Linux and Windows. We have an ugly hack on Mac OS X that mitigates the problem so it isn’t as much of an issue there, but the hack violates NPAPI and it’d be nice to not have to use it.

Here’s how annoying these bugs are, you have to use Windows or Linux for this example to work:

1. Open a new window in Firefox.
2. Go to a YouTube video, I suggest this one (I wouldn’t rickroll you, pinky swear!).
3. Click in the plugin, either on the video or the pause button or wherever.
4. Hit ctrl-w in an attempt to close the window.

Surprise! The plugin ate the keyboard command and the window is still open. It’ll eat tab key presses too, so you can’t tab focus away from the plugin. I don’t know how Windows and Linux users can stand this. At least on Mac OS X we let any keyboard commands in the native menu bar have first crack, and if they don’t do anything then we let the plugin have the event. This is a problematic and incomplete solution though, I won’t get into it here except to say that doing the same thing on Windows and Linux would be nasty. We need to fix the problem the right way, which will probably be a bit of a slog because it’ll most likely require changes to NPAPI and a fair amount of discussion between browser and plugin vendors.

In addition to being irritating, these bugs are problematic in terms of Section 508 compliance, which “requires that Federal agencies’ electronic and information technology is accessible to people with disabilities.” They can go on any list of reasons for federal agencies not to use Mozilla products.

We’re going to be looking into fixing these bugs soon, stay tuned…



Kelsey and I have a radio show called “Hey Paisley” on Thursday nights from 8-10 PM Eastern. That’s 5-7 PM Pacific. I forgot to write about this before, the fun has been going on all summer! We play music from a variety of genres like indie rock, folk, hard rock, punk, electronic, soul, and hip-hop. Essentially, whatever we like. The only thing the songs have in common is that they’re all really great.

You can listen at 103.3 FM from the outskirts of New York, NY, through Philadelphia, PA, and into Wilmington, DE. That’s 14,000 watts of stereo power, making WPRB one of the strongest community radio stations in the world!

You can also listen online at wprb.com, just click “listen now.”



{June 15, 2008}   Gecko 1.9.1 Mac OS X Plans

We’ve started working on Gecko 1.9.1 for Mac OS X. It is early in the development cycle and things could change, but I want to give people an idea of what we’re planning on doing as of now.

Aside from the usual bug squashing, we’re going to focus on minimizing Carbon usage and getting ready for 64-bit. Gecko 1.9.0 is generally Cocoa-based but it still contains a modest amount of Carbon and other code that is not 64-bit-ready. We’re probably not going to be Carbon-free or 64-bit-ready for the Gecko 1.9.1 release, but we can make a lot of progress.

  • I’m adding support for NPAPI plugin event model negotiation and the Cocoa event model in bug 435041. This will allow for Carbon-free plugins and is major step towards 64-bit Gecko on Mac OS X.
  • I’m working on new file system interaction code for Mac OS X in bug 438694. The goal of this work is modern and clean 64-bit-ready code that uses supported APIs.
  • I’m also hoping to rewrite our print dialog implementation in Cocoa. It is one of the few components that are still completely Carbon-based.

We’ll also be doing some long-overdue general cleanup and performance work.

  • I have rewritten much of our native menu code in bug 433952. We’re doing this to improve code size, code clarity and run-time speed. The new implementation is completely decomtaminated, ~700 lines of code lighter, better organized and much easier to understand. In the future we will be able to make changes and fix bugs much faster. It will also be easier to port this new implementation to other platforms that want native menus, such as mobile GTK.
  • Our child view and top-level window code is very complicated - some of that we can’t help, but there are steps we could take to make it easier to understand and work with. I’m hoping to do some re-factoring and documentation work for Gecko 1.9.1.
  • We’re planning to expand our widget testing framework to include things like focus testing and more advanced key handling tests.

There will probably not be many new Mac-specific platform features added to Gecko 1.9.1, but there are at least a couple of nice ones on the way.

  • Atul Varma is adding support for HTML data on the system clipboard in bug 428096.
  • James Bunton and others have worked together in bug 125995 to add support for taking proxy settings from Mac OS X network preferences.


Josh and his grandfather RolandFirefox 3 will be released soon (get the RC here). While the release contains a huge number of new features and performance improvements for all platforms, it is particularly significant for Mac OS X users. We rewrote most of the Mac OS X code that was behind Firefox 2 in order to benefit from modern Apple technologies and fix long-standing bugs. Once you try it I think you’ll agree that the results are astounding. I’d like to explain what exactly we did in this rewrite, how Firefox 3 for Mac OS X is different “under the hood.”

Before I start, I need to explain Gecko vs. Firefox for anyone who doesn’t already know. Gecko is the engine behind Firefox. It provides the capabilities that we use to build Firefox. Under the umbrella of Mozilla, Gecko is actually a much bigger project in technical terms than Firefox is. For example, there is much more Gecko code than there is code specific to Firefox, which is an application we built on top of Gecko. Firefox and Gecko have different version numbers - Firefox 2 uses Gecko 1.8.1 and Firefox 3 uses Gecko 1.9. This post is about changes we made in Gecko 1.9, the engine behind Firefox 3.

The biggest change is that Gecko 1.9 is based on Cocoa instead of Carbon on Mac OS X. There has always been a lot of confusion about what this means, particularly since Gecko 1.9 also happens to include Aqua form controls. It may seem strange to some, but Gecko’s new Cocoa underpinnings and its Aqua form controls are almost completely unrelated.

There are only 2 types of Cocoa objects at the heart of Gecko 1.9 on Mac OS X (let’s forget about the menu bar at the top of the screen for now). Cocoa’s NSWindow allows us to make and control a window on the screen and Cocoa’s NSView allows us to draw things into a window. Those two objects also allow us to get most of the events we need to know about from the operating system (such as key and mouse events). We do not use actual Cocoa buttons or any other Cocoa controls within any Gecko 1.9 windows. The context menus, dropdown menus, the toolbar, the search bar, the buttons and text fields within web pages - they are not actual Cocoa controls. For example, instead of using actual Cocoa buttons for “Submit” buttons we just draw the image of an Aqua “Submit” button into an NSView, one of the basic Cocoa objects we use. Gecko 1.9 has Aqua form controls because we now draw images of Aqua form controls when appropriate, not because we use actual Cocoa controls. The reason we don’t use actual Cocoa controls isn’t because we are lazy or we can’t figure out how to use them or because we are constrained by our cross-platform requirements - Apple’s WebKit doesn’t use actual Cocoa controls for things like “Submit” buttons or popup buttons in web pages either, at least not the last time I checked. IE for Windows is in the same boat. The reason Gecko 1.9 doesn’t use Cocoa controls is for the sake of flexibility - form control behavior and appearance can be changed significantly via HTML, CSS, and JavaScript. Actual Cocoa controls are simply not flexible enough to do all of the things that people want to be able to do with controls on the web.

So if we didn’t get Aqua form controls out of the deal why did we do the Cocoa rewrite? First of all, Apple has deprecated much of Carbon already1 and has made it clear that Cocoa is the future for Mac OS X applications. Apple is investing heavily in Cocoa, which benefits us if we use Cocoa. Cocoa also gives us access to great features that would be more difficult or impossible to take advantage of through Carbon. For example, with Cocoa we were able to relatively easily draw using CoreGraphics instead of the ancient Quickdraw API (more on this later). Secondly, the Cocoa way of doing things matches up with the Gecko way of doing things better than Carbon did. Our Cocoa code is easier to understand and maintain because of this2. This will result in faster development and fewer bugs in the long run. In fact, we actually added more capabilities to Firefox 3’s Gecko 1.9 (such as transparent windows, unified toolbar windows, and an alert service) than we have ever added in any release of Gecko since Firefox 1.0. This is in addition to doing a huge amount of work just to re-implement many of the features that Gecko 1.8.1 had already implemented in Carbon!

Another major under-the-hood change in Gecko 1.9 for Mac OS X is drawing via CoreGraphics and ATSUI instead of Quickdraw. Like much of Carbon, Quickdraw is deprecated and does not exist in 64-bit Mac OS X. Gecko 1.9 uses the Cairo library on all platforms, and Cairo draws with CoreGraphics and ATSUI on Mac OS X. The CoreGraphics drawing API is modern and hardware accelerated, a huge improvement over Quickdraw in terms of speed, capabilities, and code clarity. In addition to using CoreGraphics ourselves, we have made it possible for plugins to use CoreGraphics via NPAPI Drawing Models3. Flash is already prepared to take advantage of this new capability in Gecko 1.9! As for text, using ATSUI allowed us to improve our text kerning and ligature capabilities. It also gives us better glyph cluster positioning, which is good for Indic languages and languages that use exotic combining marks.

I hope this helps to shed some light on why Firefox 3 is a particularly significant upgrade for Mac OS X users. I’m really proud of what we accomplished with this release, it was ambitious and things worked out well. Kinks remain as with all major revisions, we’ll be addressing those quickly in minor updates to Firefox 3.

==

1 While the deprecated Carbon API is still available for 32-bit applications like Firefox 3, it simply won’t be available to 64-bit applications. Firefox 3 for Mac OS X will not be available in 64-bit but we’re preparing for 64-bit by removing code that won’t work in 64-bit.
2 It might be true that on the whole our Cocoa implementation is more complex than our Carbon implementation was, but that is because our Cocoa implementation does far more than our Carbon implementation ever did. The Cocoa code is still more readable and maintainable.
3 See the NPAPI Drawing Models spec. http://wiki.mozilla.org/Mac:NPAPI_Drawing_Models



If you’ve participated in or followed Mozilla’s Firefox 3 development over the past month you’re probably aware that we had a bunch of issues with key handling come up at the very end of our development cycle. In the interest of giving others an opportunity to learn from our mistakes and to generally communicate what happened, I’ve agreed to write up a summary of the development team’s postmortem discussion about our recent key issues.

“Key hell” started when I fixed bug 398514, a significant rewrite of our key event flow, and Masayuki Nakano started fixing a major bug concerning key command event mapping on international keyboard layouts (more on Masayuki’s fix later). Prior to my patch we let Mac OS X match keyboard commands to native menu items and then executed associated DOM command nodes based on the operating system matching. The up side of that is that the operating system does all the mapping of key commands to their menu items, the down side is that nothing but the command node associated with the menu item ever sees the event. After my patch we ignored the operating system’s invocation of native menu items in favor of allowing the key event to flow normally through Gecko. This fixed a lot of important bugs, I can’t believe we got away with pigeon-holing key equiv events for so long. The problem is that we were now in charge of mapping key events to their commands. For US English this is pretty simple mapping and it works without special treatment, I didn’t notice any problems because I use US English. When I tested with other keyboard layouts I tested text in text fields - I didn’t test many keyboard commands. My bad #1, but I wasn’t aware of the fact that key commands have certain types of complex mappings under different keyboard layouts and circumstances.

Coincidentally, this problem came up for different reasons on Windows and Linux right before I exposed it on Mac OS X. Masayuki had already started working on a fix because of Windows and Linux. By the time we had sorted through bug reports and figured out what was going on with non-US-English keyboard commands on Mac OS X Masayuki was half way to a fix. This ordeal would have been much worse without that stroke of good luck. Masayuki is a talented guy that understands far more about international keyboard layouts and input than I do, I was pretty happy he was already on the problem.

Masayuki’s patch(es) attempted to solve a very complex problem. The problem has a huge number of edge cases under different keyboard layouts and the process of finding and fixing cases that we hadn’t covered yet dragged out until today. I don’t think any particular engineer is to blame for this, the extended timeline for fixing regressions was the result of late detection and a lack of automated test coverage.

We should have discovered this problem much earlier than we did. I suspect that we finally discovered it as a result of heavy beta usage, especially among international users. User testing is great but it is a perk - not something to be relied upon. We also would have found out about this earlier had I committed my major patch for bug 398514 earlier. We had good reasons for making that change so late, but having good reasons doesn’t shield us from the consequences. At best it just makes the consequences easier to swallow.

The other major factor contributing to this debacle was a lack of automated testing until too late. With a decent test suite we could have found out about most of this much earlier. Even after we found out about the problem it took us too long to get tests in place to aid in avoiding regressions in the fix process. Eventually Roc wrote up a great test system (based on synthesized native events) and that has helped a lot. We’ve since added a bunch more tests to his original set and we’ll be adding many more. If you only take away one thing from all of this writing I hope it is the value of tests - we could have saved a huge amount of time by getting those in place earlier.

There was one other last-minute problem with key handling that got confused with the situation I described above, though it is really a completely separate issue. Mac OS X sends key events into Cocoa apps via confusing and inconsistent paths (performKeyEquivalent: vs. keyDown:, either or both in different orders, plus sometimes we don’t get key up events via keyUp:, sometimes we get key up events but they come in via a second call to performKeyEquivalent:, what a mess Apple!). The circumstances that led to issues with this being a problem at the last minute were basically the same as for the other issues I described.

A big thank-you goes out to Robert O’Callahan, Karl Tomlinson, Matthew Gregan, and Masayuki for working so hard to get this situation under control over the past week. Everyone worked together really well, it was some impressive teamwork.



et cetera