Modifying Firefox's Context Menus

Because it's all about you

While I like the Firefox Web browser, there are a few things about it I'd change. For a start, I'd remove the “Set As Wallpaper...” context menu item. Not only do I never use it, I'd rather not have the option of invoking it by accident. Fortunately, it's not too hard to change Firefox's context menus.

Added 2009-04-24: If you don't want to bother with all this hoo-ha, get the Menu Editor plug-in.

You might want to print or copy these instructions to another application before you begin, as you'll need to restart Firefox for your changes to take effect.

What you'll need

  • Firefox installed (duh)
  • a utility that can search for a string of text across an entire directory tree
  • a plain text editor
  • a zip/unzip utility

Instructions

  1. Start Firefox.

  2. Make a note of the exact text of the offending menu item. In our case, it's “Set As Wallpaper...”.

  3. Stop Firefox.

  4. Search the firefox/chrome directory for the chosen menu item text. It may appear several times; the one you want associates the text with a command, such as <!ENTITY setWallpaperCmd.label "Set As Wallpaper...">. What you need is the internal name of the command, which immediately precedes .label.

  5. Search the jars for the command name (e.g., setWallpaperCmd). It'll probably be in either browser.jar or toolkit.jar.

  6. Back up the original jar file. If your changes break something, you'll need to be able to restore the original jar file. I usually leave the jar file in place, and tack .old onto its name.

  7. Copy the jar file to a temporary directory.

  8. Unzip it into separate files.

  9. Search the resulting directory tree for the command. It'll probably be in content/browser/browser.xul or content/global/bindings/tabbrowser.xml (for tab commands).

  10. Open the file in a text editor.

  11. Comment out the menu item with the command. Since this is XML, you have to comment out the whole <>-bracketed item by surrounding it with <!-- and -->. You can comment out other menu items (you can usually guess what an item does from the name of its command), and also reorder them to your taste.

    In one case I encountered (“Block Images from”), disabling a context menu item disabled other features as well.

  12. Save file.

  13. Rezip the directory tree (with a command like zip -r -0 browser.jar *.*). The original jar was created without compression, but Firefox works just fine with compressed jars.

  14. Move the new jar file to the firefox/chrome directory.

  15. Restart Firefox and test your changes. If there's a problem, return to step 10. When everything's fine, delete the files in the temporary directory.


Items I disable

In Firefox 1.0, I disable many items in browser.xul:

context-openlinkopen in new window
context-bookmarklinkbookmark link
context-sendlinksend link
context-copyemailemail link
context-copyimage-contentscopy image
context-sendimagesend image
context-setWallpaperset desktop wallpaper to image
context-reloadreload page
context-stopstop loading page
context-bookmarkpagebookmark page
context-sendpagesend page (and following menu separator)
context-viewbgimageview background image
context-selectallselect entire page
&showOnlyThisFrameCmd
&openFrameCmd
&reloadFrameCmd(and following menu separator)
&bookmarkFrameCmd
context-viewinfoview page info, which I never do

In tabbrowser.xul, which holds the context menus for tabs, I disable everything except closeTab and newTab.


Adding a new context menu item

Obsolence warning: the following code works in Firefox 1.0.x only. However, it might serve as a rough guide for your own customizations.

One thing Firefox lacks is a simple way to toggle a single preference. For example, I often toggle loading of offsite images. Sure, I could go through Tools/Options, but that takes four mouse clicks and requires me to hit four different targets, and doesn't tell me the state of the preference until after the second mouse click. Fortunately, Firefox's XUL is simple enough that hacking in a new context menu item for this is not too difficult.

First, you need to create a new context menu item. In browser.xul, find the menu with id="contentAreaContextMenu". Just before the closing </popup>, add the following:

      <menuseparator id="imageprefs"/>
      <menuitem id="context-blockoffsiteimages"
                label="Block offsite images"
                class="menuitem-iconic"
                oncommand="toggleOffsiteImages();"/>

The class menuitem-iconic allows the display of a check mark next to the item when it's enabled. The <menuseparator> element adds a separator before the new menu item.

Next, we must create the toggleOffsiteImages() function. Open browser.js in an editor and append the following:

function toggleOffsiteImages()
{
  gPrefService.setIntPref("network.image.imageBehavior",
                          1-gPrefService.getIntPref("network.image.imageBehavior"));
}

This does nothing more than flip the preference for loading offsite images. [Depending on the preference you want to change, you may need to use a different function than getIntPref(). Check the preference's type in about:config and find a matching type by perusing browser.js.]

We need to add a little bit of code to ensure that when the menu appears, the checked state of the "Block offsite images" item is correct. At the end of the initMiscItems block, add the following:

        var blockOffsiteImagesItem = document.getElementById("context-blockoffsiteimages");
        if (gPrefService.getIntPref("network.image.imageBehavior") == 1) {
          blockOffsiteImagesItem.setAttribute("checked", "true");
        }
        else {
          blockOffsiteImagesItem.removeAttribute("checked");
        }

Save the files and recreate the jar as above. Restart Firefox to see the new context menu item. Changing the preference now requires only two mouse clicks and hitting one target (which is at a fixed distance from the cursor, rather than the window, thus allowing muscle memory to be used). Plus, you learn the state of the preference after the first mouse click. That's a real usability improvement.

We should probably internationalize this, and do it with an overlay... but all I wanted was a quick’n’dirty fix, not a whole bloody extension!


Last updated 24 April 2009
http://www.rdrop.com/~half/Creations/Writings/TechNotes/firefox.menus.html
All contents ©2005 Mark L. Irons

Previous: Backup Strategy ··· Next: Mac Gotchas