I've been playing recently with a time-keeping tool, written in XUL, open in a popup window. The application is pretty simple, just allowing me to enter a list of tasks, and keep track of how long I've had any task selected. Being in a popup allows me to quickly change tasks and keep a much more accurate log of my time.
I was having a problem though, because clicking links from emails or IMs would open up into my popup window, and not a new tab in Firefox, making me lose my data. Nathan suggested XULRunner, and after losing my data 3 more times, I broke down and figured out how to set it up. XULRunner is a command-line app to run XUL applications, essentially starting another gecko instance and running your code in that. That way Outlook won't think that's a good place to load windows, and if Firefox crashes, my XULRunner instance is still fine and dandy.
Documentation on XULRunner is a bit scant, but googling revealed a xulmine sample, and from that I was able to reverse engineer what the hell XULRunner wanted me to do. And, now that I review some of these links, I see Darin has more information about XULRunner than I thought.
As a convention, emphasized words are variables, and should be replaced with a value that makes sense for your application.
Set up your application like so:
/applicationName /chrome /applicationName your app files chrome.manifest /defaults /preferences prefs.js application.ini
appName=myXulApp mkdir -p $appName/chrome/$appName touch $appName/chrome/chrome.manifest mkdir -p $appName/defaults/preferences touch $appName/defaults/preferences/prefs.js touch $appName/application.ini
There are more complicated ways to do it, but this seems to be the bare bones. Now let's set up all the configuration files.
application.ini
XULRunner works by reading an application.ini
file, and then
loading things up by looking at specific directories. Here's a sample
application.ini
:
[App] Vendor=company Name=applicationName Version=0.1 BuildID=20050506 [Gecko] MinVersion=1.8 MaxVersion=1.8
The important bit is the [Gecko]
section. The [App]
section is nice, but doesn't seem to serve any essential function. The
[Gecko]
part tells XULRunner what versions of Gecko can be used
with your app, and XULRunner will fail if those lines aren't there.
prefs.js
This is a preferences file, where you set initial values of things, either gecko engine settings or application specific settings. All we need here is:
pref("toolkit.defaultChromeURI", "chrome://<em>applicationName</em>/content/<em>startPage</em>.xul");
The startPage is what XUL page you want to view initially.
chrome.manifest
This file performs the mapping between a chrome:// url and your application files:
content <em>applicationName</em> file:<em>applicationName</em>/
That effectively tells XULRunner to look at applicationName/ in the
chrome directory when it encounters a
chrome://<em>applicationName</em>/content/
URI.
Most XUL apps I've seen are distributed as a .jar file, rather than a
subfolder of chrome/ with all the files scattered about.
Having your application unpacked is much easier for development, but when you do
want to deploy it as a jar:
chrome.manifest
to point to
applicationName.jar:
content <em>applicationName</em> jar:<em>applicationName</em>.jar!/
The jar:
protocol tells XULRunner that this is a jar file, the
the !
after the filename tells it to look inside the jar file.
Now all the prep work has been done, and your application is ready to be run. After you download XULRunner, this is just a matter of a command line:
xulrunner application.ini
Your startPage.xul should open up in a window, like any other desktop app.
To get a XUL app working with XUL Runner, you need 3 config files in
3 different formats. That's kinda messed up. To be fair, the
chrome.manifest
format is something used for Firefox extensions, so
it makes sense to re-use that functionality, but needing to specify your start
page in prefs.js
seems arbitrary. There are some proposals for a
different method of XUL Application
Packaging, but that's about a week old right now, and there's no code to
support it.
A XULRunner-based app seems like a good solution when you want to avoid
Firefox. I want to avoid Firefox because of outlook, but in general I don't
see much of an advantage over just making an extension, its just a series of
trade offs.
The big internal app we're writing will likely remain as a Firefox extension, but going through this process has certainly taught me a lot more about how to organize XUL apps. I wonder if you could munge XULRunner config files to point to a Firefox extension? Then you could auto-update with Firefox, and still get the benefits of XULRunner.
Friday, May 06, 2005 3:29 PM