MacFAQ

(Note this document has NOT been reviewed for accuracy or completeness.)

Special Build Notes

  • Enable LibXUL.

In your .mozconfig for custom builds of XULRunner, add --enable-libxul.

  • If you've completed a XULRunner build, you should copy or symlink the dist/XUL.framework directory to /Library/Frameworks. Note that in order to copy the framework while keeping the relative soft-links in the framework, do something like:
    • % ( cd dist ; gnutar cf - XUL.framework | ( cd /Library/Frameworks ; gnutar xf - ))

Installing Your Application

Your application must be installed as a XULRunner app before you can open it. To do this, type:

xulrunner-bin --install-app /path/to/appdir

Note the path to your application must end with the directory containing application.ini; you should NOT reference application.ini in this command.

This command will place a copy of your application in /Applications/(Vendor)/(Name) , where (Vendor) is the Vendor field in your application.ini and (Name) is the Name field.

Opening Your Application

For ordinary work, you can just navigate via Finder to /Applications/(Vendor)/(Name).app and open the application.

For command-line work, you would call on:

/Applications/(Vendor)/(Name).app/Contents/MacOS/xulrunner

UI notes

  • Menus
    • To enable your application quit command to work with the application menu (the one to the right of the blue apple), you need to give your quit menu item an ID of "menu_FileQuitItem".
    • To enable the Mac "About" menu make sure that you use "aboutName" as the id for your menu item
    • To enable the Mac "Preferences" menu make sure that you use "menu_preferences" as the id for your options/preferences menu item
  • Toolbars
    • Mac windows have a small "jelly bean" button in the top right corner. This button is used to show/hide the toolbar. The toolkit will automatically enable this behavior if you add class="chromeclass-toolbar" to your <toolbar> element.

Commandline Support

Commandline handlers work great on the Mac IF it's a cold start. Here's how to implement command-line trapping when the app is already running, without getting into AppleEvents or c++ code. This is implemented in a pseudo "hidden window" technique and parsing the window arguments instead of command-line handlers and some of the toolkit singleton window code.

  • Taking advantage of the core code "OpenURL" from "nsCommandLineServiceMac.cpp", you'll see that it looks for "browser.chromeURL" before defaulting to navigator.xul, and this IS called when an XULRunner app is already running, so:
  • next take the code below and drop it in, to create the hiddenWindow.xul

(Note: the debug function and nsICommandLine try/catch can be removed, all you need is the window.arguments[0])

<?xml version="1.0"?>

<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
        id="myXUL_hidden" windowtype="myXUL:hiddenwindow"
        title="" width="0" height="0"
        persist="screenX screenY width height sizemode" >

  <!-- Load the Mozilla helpers -->
  <script type="application/javascript" src="chrome://global/content/nsUserSettings.js" />

  <script><![CDATA[
    function debug(aLogString) {
      var mConsoleService = Components.classes["@mozilla.org/consoleservice;1"]
                              .getService(Components.interfaces.nsIConsoleService)

      mConsoleService.logStringMessage("myXUL: " + aLogString + "\n");
    }

    function checkOtherWindows() {
      var singletonWindowType = nsPreferences.copyUnicharPref("toolkit.singletonWindowType");
      var windowMediator = Components.classes["@mozilla.org/appshell/window-mediator;1"]
                             .getService(Components.interfaces.nsIWindowMediator);
      var win = windowMediator.getMostRecentWindow(singletonWindowType);
      if (win) {
         window.close();
         win.focus();
      }
    }

    if (window.arguments && window.arguments[0]){
      try {
        var cmdLine = window.arguments[0]
                          .QueryInterface(Components.interfaces.nsICommandLine);
        for (var i = 0; i < cmdLine.length; ++i) {
          debug(cmdLine.getArgument(i))
        }
      } catch(ex) {
        debug(window.arguments[0])
        // Do something with window.arguments[0]
        //nsPreferences.setUnicharPref("myXUL.cmdLineValue", window.arguments[0])
      }

      window.addEventListener("load", checkOtherWindows , false);
    }
  ]]></script>

</window>