Display panes are standard integration points to attach Songbird add-ons to. Though arbitrary XUL can be overlaid as before, targeting specific display panes simplifies the integration with Songbird's default user interface and providers the user with a consistent and flexible way to customize the layout of the location and display of individual add-ons. 
Prior knowledge of developing Songbird add-ons is recommended for this tutorial. By the end of this article, you should know how to adapt an existing add-on to use Songbird's display panes.
If you haven't developed Songbird add-ons before, please see our additional developer resources and articles at the Songbird Developer Center.
A screenshot of a cluttered Songbird instance with all three display panes visible is shown here. The user is able to toggle the visibility of display panes and select their content using the View Menu (shown above). All three display panes can be dynamically resized by the user using standard splitters with grippies.
Though Songbird's basic layout (and the Rubberducky feather) implements three basic display panes, Songbird Feather developers may implement as many display panes as they like, or not implement any at all. It is likely, however, that most Feathers will support the three default display panes for maximum compatibility, and for the purpose of this guide, we will limit the scope of our discussion accordingly.
Songbird's three display panes are named after their respective window locations:
servicepane) display pane is anchored to the bottom of the servicepane. It can be resized vertically, and may typically be used to display album art or photos. In the figure, it is highlighted in purple.contentpane) display pane occupies the bottom space below the browser. It is present in both Library and Web Browser views. It is larger and can be used to show any kind of contextual information. In the figure, it is highlighted in green.sidebar) display pane occupies the entire space to the right of the browser, and everything underneath the faceplate/dashboard. It too can be used for contextual information, and in the figure above it is the one highlighted in red.
To actually attach your add-on to one of the display panes, your add-on should register itself with the Display Pane manager. There are currently two methods for doing this. The more straight-forward way is to do the attachment via your add-on's install.rdf file. The second method is done in Javascript, and can be more dynamic in that you can vary attachment points and registration at runtime. The following two sections illustrate both methods of attachment for the same Flickr add-on which utilizes display panes for Songbird 0.4.
The simpler method is to declare your add-on's display pane attachment via the install.rdf file. The different tags are described below in the Attachment Parameters section, since they are shared with the Javascript method. Don't forget to make sure your install.rdf includes the songbird xmlns.
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-rdf#"
xmlns:songbird="http://www.songbirdnest.com/2007/addon-metadata-rdf#">
.
.
.
<songbird:displayPanes>
<Description>
<songbird:displayPane>
<Description>
<songbird:contentUrl>chrome://songbird-flickr/content/flickr.xul</songbird:contentUrl>
<songbird:contentTitle>Flickr</songbird:contentTitle>
<songbird:contentIcon>http://flickr.com/favicon.ico</songbird:contentIcon>
<songbird:defaultWidth>350</songbird:defaultWidth>
<songbird:defaultHeight>400</songbird:defaultHeight>
<songbird:suggestedContentGroups>contentpane</songbird:suggestedContentGroups>
<songbird:showOnInstall>true</songbird:showOnInstall>
</Description>
</songbird:displayPane>
</Description>
</songbird:displayPanes>
A helpful resource for catching errors in the install.rdf file is the W3C's RDF validator.
NOTE: It is highly recommended that display panes be registered using the install.rdf method described in the previous section. Add-ons that register display panes via install.rdf are detected when uploaded to the add-ons site and featured on the display panes index.
Registering and attaching your add-on via Javascript can be more dynamic in that it's done at runtime. This enables your add-on to check for preferences, or the presence of other features/add-ons/configuration before deciding whether to register, and to which display pane to register against. To do this you will want to have your add-on first overlay the main Songbird window via the chrome.manifest:
content songbird-mashtape chrome/content/ overlay windowtype:Songbird:Main chrome://songbird-mashtape/content/extension.xul
This extension.xul XUL file should then load up Javascript that then registers your add-on with the Display Pane Manager:
// Get a reference to the Display Pane Manager
var paneMgr = Components.classes["@songbirdnest.com/Songbird/DisplayPane/Manager;1"]
.getService(Components.interfaces.sbIDisplayPaneManager);
// Register our add-on
paneMgr.registerContent("chrome://songbird-flickr/content/flickr.xul",
"Flickr",
"http://flickr.com/favicon.ico",
350,
400,
"contentpane",
true);
As you can see, registerContent() takes a series of arguments. These are the same as for the install.rdf method of attachment and are described below.
install.rdf argument | registerContent() parameter # | Value |
|---|---|---|
| contentURL | 1 | URL path to the XUL for your add-on |
| contentTitle | 2 | The title for your content, shown in the dropdown menus the user selects from the picker (corner of the pane) or via the View menu. In the View Menu screenshot shown above, this would be "Flickr", "Wikipedia", or "mashTape" |
| contentIcon | 3 | URL path to the icon representing your add-on. This is a 16x16 icon in any Gecko-renderable format (.ico, .png, or .gif are common formats) |
| defaultWidth | 4 | The default width of your add-on. This is the width applied in a width-constrained display panel, e.g. sidebar. |
| defaultHeight | 5 | The default height of your add-on. This is the height applied in a height-constrained display panel, e.g. contentpane. |
| suggestedContentGroups | 6 | The list of content groups that this add-on may be displayed in. Multiple value should be separated by a semi-colon (";"). In the Gonzo layout, the available display panes are: contentpane, sidebar, and servicepane. |
| showOnInstall | 7 | A boolean flagging whether or not your add-on should be displayed automatically upon installation. Songbird will walk down the list supplied in suggestedContentGroups until it finds the first valid content group to display the add-on in. |
You can see the public interface to the Display Pane Manager for more details.
This example takes the context of migrating an existing add-on (mashTape). Previous to Songbird 0.4, mashTape relied on overlaying the Songbird Library window. To achieve this, its chrome.manifest looked like:
content songbird-mashtape chrome/content/ locale songbird-mashtape en-US chrome/locale/en-US/ skin songbird-mashtape classic/1.0 chrome/skin/ overlay windowtype:Songbird:Library chrome://songbird-mashtape/content/overlayLibrary.xul overlay chrome://browser/content/preferences/preferences.xul chrome://songbird-mashtape/content/preferences.xul
You can see where it overlaid windowtype:Songbird:Library on line 5. The layout of mashTape clearly lends itself well to being overlaid in the contentpane display pane. Our first step is to change the chrome.manifest to change where and how we overlay. Following the example given above, we'll change our overlay to be windowtype:Songbird:Main:
content songbird-mashtape chrome/content/
locale songbird-mashtape en-US chrome/locale/en-US/
skin songbird-mashtape classic/1.0 chrome/skin/
overlay windowtype:Songbird:Main chrome://songbird-mashtape/content/extension.xul
overlay chrome://browser/content/preferences/preferences.xul chrome://songbird-mashtape/content/prefsOverlay.xul
Here you can see we've not only changed the ID we're overlaying (from Library to Main), but we're also loading up a new chrome file. This new chrome, extension.xul, is very simple and serves merely to load the Javascript that registers our add-on with the display pane:
<?xml version="1.0" encoding="UTF-8"?> <overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" id="songbird_mashtape_overlay"> <script type="application/x-javascript"> var paneMgr = Components.classes ["@songbirdnest.com/Songbird/DisplayPane/Manager;1"]. getService(Components.interfaces.sbIDisplayPaneManager); paneMgr.registerContent( "chrome://songbird-mashtape/content/mashTape.xul", "mashTape", "chrome://songbird-mashtape/content/favicon.png", 237, 237, "contentpane", true); </script> </overlay>
As you can see, it's pretty simple and follows the display pane registration code given above. mashTape.xul is then our main add-on XUL layout. This can be your standard XUL layout. A trimmed down sample is here:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE window SYSTEM "chrome://songbird-mashtape/locale/overlay.dtd" >
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://songbird/skin/songbird.css" type="text/css"?>
<?xml-stylesheet href="chrome://songbird/content/bindings/bindings.css"
type="text/css"?>
<?xml-stylesheet href="chrome://songbird-mashtape/skin/styles.css"
type="text/css"?>
<page title="mashTape web mashups"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:xbl="http://www.mozilla.org/xbl">
<label value="Yay for display panes." />
</page>
The only thing that needed to be done to convert mashTape to use the display pane from its previous behaviour was merely changing it to use <page> instead of <window> for its overlay tag.
Certain Javascript calls that rely on access to the window object won't quite work how you expect. Since the add-on is attached to the display pane, window will refer to the display pane window - and not the global main Songbird window. For instance, Javascript trying to do the following will fail:
window.open("http://songbirdnest.com");
Instead, you should first get a reference to the top/main Songbird window. From there you can access the gBrowser variable which represents the global browser variable which allows you to access loadOneTab() which will open the specified URL in a new tab in the browser.
top.gBrowser.loadOneTab("http://songbirdnest.com");
Another caveat is that your add-on's XUL page will be completely unloaded when the user hides the display pane or chooses a different add-on to display. If you want your add-on to always be running, you'll need to continue overlaying the main Songbird window as usual. You can still take advantage of display panes to attach UI elements by having your add-on overlay window:Songbird:main, and having it register independent XUL pages to display in the display panes while defining additional code to always be running in the XUL that overlays window:Songbird:main.