Archive for September, 2009

Fennec – Let’s Build Some Add-ons

We’re in the last weeks of development before releasing Fennec 1.0 to the world. There has been a lot of great testing and feedback. I think we have a well defined set of things to work on for 1.0 and a good idea of what we want to look at for 1.0+.

However, there is one area I think we haven’t had enough testing and feedback – add-on development in Fennec. Add-on developers are a tricky bunch. They can make you re-think your architecture, brainstorm many new features and find lot’s of hidden bugs. We need more developers working on Fennec add-ons.

We have a small, but growing collection of Fennec-specific add-on developer resources. If you’re interested in building add-ons for Fennec, here’s a list of resources you might find helpful:

The documents have been, and will continue to be updated. Feel free to give feedback on any of the documents. What information or snippets are missing? Use comments, IRC channels (#mobile) or even file some bugs.

Fennec for Maemo and Fennec for Windows Mobile both support add-ons. In fact, the same add-on could be used on both platforms. So get out there are start building.

Oh, one thing I wanted to ask before you go. What features of a mobile device would make building mobile add-ons really kick ass? Support for geo-location? Accessing the camera? Making calls or sending SMS? Leave comments and please go into detail :)

Comments (10)

Fennec – Handling Add-on Options

The add-on (extension) mechanism built into the Mozilla platform is very powerful. One of the optional features is support for options (preferences) dialogs. As discussed in my last post, Fennec doesn’t like dialogs. In addition, Fennec has a simple, clean preference system. While designing the Fennec Add-ons Manager, we discussed how we would support add-on options. We didn’t want popup dialogs of random and complicated XUL.

After brainstorming a few ideas, we settled on a simple idea. Fennec uses special <setting> XUL tags to create it’s list of preferences. Add-ons would be forced to use the same tags. The options would be merged into the Fennec Add-on Manager, not displayed as a popup dialog. Of course, add-ons can support more than one application, so we needed to make sure that the options XUL for Fennec could coexist with the options XUL for other applications. Let’s take a look at how this all works:

Install Manifest

Add-ons use install.rdf to identify the XUL used for displaying the preferences. This is optional.

<em:optionsURL>chrome://myaddon/content/options.xul</em:optionsURL>

This is needed for any add-on that wants to use an options dialog.

Chrome Manifest

Add-ons use the chrome manifest to selectively override XUL, and other resources, between different applications using the application flags

override chrome://myaddon/content/options.xul chrome://myaddon/content/fennec-options.xul application={a23983c0-fd0e-11dc-95ff-0800200c9a66}

This will tell Mozilla to use fennec-options.xul anytime the options.xul resource is requested.

Options XUL

As I said, the XUL allowed for the Fennec options system is limited to a few new tags. Here is an example of a Fennec options dialog:


<?xml version="1.0"?>

<!DOCTYPE mydialog SYSTEM "chrome://myextension/locale/mydialog.dtd">

<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
  <setting pref="extensions.myaddon.debugging" type="boolint" on="1" off="2" title="Enable debugging"/>
  <setting pref="extensions.myaddon.profiling" type="bool" title="Enable profiling">
    Profiling can affect the performance of the application
  </setting>
  <setting pref="extensions.myaddon.logging" type="bool" title="Save logs"/>
  <setting pref="extensions.myaddon.logging.path" type="string" title="Log folder"/>
  <setting type="button" title="Clear logs">
    <button label="Clear" oncommand="MyAddon.clearLogs();"/>
  </setting>
</vbox>

Note that we don’t have any <script> support and we are limited to <setting> tags. The root <vbox> just acts as a container, it isn’t merged into the main window. Here is how the options look in Fennec:

As always, we appreciate your feedback. I’m in the process of updating the Fennec Best Practices documents with this information.

A big thank you goes out to Vivien Nicolas, a Mozilla intern in the Paris office, for turning my super-great design into a reality. Shaver told me there’d be days like this!

Comments (3)

Fennec – Prompts, Alerts and Dialogs – Oh My

If you’ve developed applications or extensions using the Mozilla platform, you know that there are tons of services and APIs available. We use those same capabilities when building Fennec. However, there are times when the default platform behavior is not desirable on mobile devices. When that happens, we could hack up our own system, or we could re-implement the platform APIs to suit our needs. We try to do the latter.

Here are some APIs that have been reimplemented in Fennec: nsIAlertsService, nsIPromptService, nsIDownloadManagerUI, and window.openDialog(). The primary reason all of these APIs have been reimplemented is that they open new XUL windows. We don’t like doing that in Fennec. Mostly because opening a XUL window is slow. But also because we love having tighter control over the look, feel and behavior of the UI elements.

Services

Since we re-implement the interfaces, nsIAlertsService, nsIPromptService and nsIDownloadManagerUI can be used just as they are on the desktop. The big difference is that none of them open new windows. The UI is embedded into the main window itself. It’s faster to display and easier to control and style the UI elements. In the case of the download manager, it’s designed to be embedded in the main window.

Dialogs

On the other hand, we couldn’t exactly match the way window.openDialog() worked, so we created a slightly different API: importDialog(). The big difference is that importDialog() actually merges the XUL dialog into the main window. It does not open a new XUL window.

importDialog(aSrc, aArguments);

  • aSrc: The chrome URL of the XUL dialog
  • aArguments: A JavaScript object used to pass data to the dialog

The XUL passed to importDialog() is very similar to XUL passed to window.openDialog(), with some limitations and caveats:

  • Only <dialog> top level elements are permitted
  • Scripts are loaded via an attribute on the <dialog> element, not via the <script> tag

Here is an example:


<?xml version="1.0"?>
<!DOCTYPE mydialog SYSTEM "chrome://myextension/locale/mydialog.dtd">
<dialog xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
      script="chrome://myextension/content/mydialog.js">
  
  <label id="mydialog-title" crop="center"/>

... some other widgets ...

  <hbox pack="center">
    <button label="&ok.label;" oncommand="myDialog.doSomething();"/>
  </hbox>
</dialog>

The XUL is merged into the existing window, almost like a XUL overlay. Because of this, element ID and JavaScript conflicts are possible, just like overlays. So be careful!

Obviously, add-on developers should use these features. We are looking for feedback as well. Perhaps we could get importDialog() working more like window.openDialog().

A big thank you goes out to Fabrice Desré for working on reimplementing nsIPromptService. He created some great building blocks for Fennec.

Comments (2)

Fennec – Of Screens and Orientation

Designing a portable application to run on many different mobile devices is a challenge. Screen sizes and pixel densities are different making it difficult to create the One Great Layout. In addition, mobile devices can change screen orientation, from portrait to landscape and back again.

This is one area where using a markup-based UI language like XUL, with it’s support for CSS, comes in handy. Currently, Fennec is being designed and tested to run on Nokia’s N810 & N900 devices, HTC’s Touch Pro and Samsung’s Omnia & Omnia II. Yes, Fennec can run on other Windows Mobile devices, but we don’t really test on every possible device… yet. Joel and the QA crew are working on that, but I digress.

Even with the target devices, we have several screen sizes, pixel densities and orientation requirements to support. Layout support in XUL and media query support in CSS really do the heavy lifting for us. The Fennec UI is the same on all these devices, but we have some layout constraints and CSS rules that allow us to morph the UI as the screen changes. Here are some of the ways we do it:

  • Use physical dimensions whenever possible. Padding and margins are set using millimeters, not pixels. This minimizes the need for special rules for every different screen size and pixel density. Also, the UI is designed for touch, and the current design size for a touchable UI element is ~7.5mm. Your finger doesn’t change sizes to match the screen :)
  • Use CSS media queries to switch between screen sizes and pixel densities. Large sized images can be used on large screens/densities, while smaller images can be used on smaller screens/densities. The result should be an image that is roughly the same physical size on either device.
  • Use CSS media queries and XUL box rules to flow the UI when the device is rotated. A toolbar that works well vertically in landscape orientation, probably needs to flow horizontally in portrait orientation. It’s all about maximizing the usable space.

Screen Size

Here is some example CSS we use for toggling between large and small screens/densities. As you can see, we use 400px as a cutoff:


/* high-res screens */
@media all and (min-device-width: 401px) {
  toolbarbutton {
    min-width: 64px !important; /* primary button size (match image pixels)*/
    min-height: 64px !important; /* primary button size (match image pixels) */
  }
}

/* low-res screens */
@media all and (max-device-width: 400px) {
  toolbarbutton {
    min-width: 36px !important; /* primary button size (match image pixels) */
    min-height: 36px !important; /* primary button size (match image pixels) */
  }
}

Orientation

The same kind of example, but this time for changing the direction of some UI elements when rotating the screen:


@media (orientation: landscape) {
  #panel-controls {
    -moz-box-orient: vertical;
    -moz-box-ordinal-group: 1; /* move to left of screen */
    -moz-box-pack: end; /* force children to align to bottom of screen */
  }
}

@media (orientation: portrait) {
  #panel-controls {
    -moz-box-orient: horizontal;
    -moz-box-ordinal-group: 1000; /* move to the bottom of the screen */
    -moz-box-pack: start; /* force children to align to left of screen */
  }
}

Landscape

Portrait

We also use the XUL box wrapping tip, I discussed previously, to allow elements to flow into multiple rows if there is not enough space to hold them in a single row.

If you’re developing add-ons for Fennec, please keep these situations in mind. Use the Fennec code as an example of how you can create a great user experience, regardless of screen size or orientation.

Comments (3)

Fennec – More Theme Goodness

Recently, we released Fennec Beta 3 for Maemo (Alpha 3 for Windows Mobile is very close). The new release has several internal changes that might be of interest to add-on developers – or people curious as to how the darn thing works.

Roy Frostig posted an nice article about the changes to the way we render web pages. The results are dramatic: panning is much smoother. The approach also gives us more ways to increase performance and user experience in the future by creating a great foundation.

We also landed what we hope is the final approach for styling the user interface. I previously posted about the affect of themes on performance and how that drives the decisions we make. We are still using the images-for-buttons approach, but we had a problem. Using images-for-buttons doesn’t work for buttons with text, which can be variable in size.

We decided to extend the image-for-buttons approach for all buttons, using the border-image CSS property. Now all of our buttons have a nice, consistent look. We still have performance concerns with border-image, but we should be able to squeeze more speed out of the code. We also use the border-image approach to improve the appearance of the toggle controls and the radio option controls.

New Toggles and Buttons

New Radios

In fact, add-ons can, and will in some cases, use the new button styles too. We are in the process of updating the Best Practices document with how to make use of the themes and styles.

Comments off

New Life for Old Projects

So much to do, so little time. My workspace is littered with projects I started but couldn’t find the time to keep going. It’s kinda sad and I do feel guilty.

Sometimes those projects find a new life. Recently, two of my old projects found new life: FizzyPop and js-ctypes are both active again.

Doug Warner has started building a Mozilla Project Wizard on the FizzyPop source code. Doug is requesting feedback for improvements. You can try it out here.

Dan Witte has started looking into moving js-ctypes into the Mozilla tree! There are also plans to add a nice JavaScript wrapper API around the XPCOM too.

I feel less guilty now.

Comments (4)