Tutorials > " . "XUL Tutorial"; $pagetitle="7.3 - Keyboard Shortcuts"; $customsidebar = "xultu-sidebar.php"; include "header.php"; ?>

Keyboard Shortcuts

You could use keyboard event handlers to respond to the keyboard. However, it would be tedious to do that for every button and menu item.

Creating a Keyboard Shortcut

XUL provides methods in which you can define keyboard shortcuts. We've already seen in the section on menus that we can define an attribute called accesskey which specifies the key which a user can press to activate the menu or menu item. In the example below, the File menu can be selected by pressing Alt and F (or some other key combination for a specific platform). Once the File menu is open, the Close menu item can be selected by pressing C.

Example 7.3.1: Source View
<menubar id="sample-menubar">
  <menu id="file-menu" label="File" accesskey="f">
    <menupopup id="file-popup">
      <menuitem id="close-command" label="Close" accesskey="c"/>
    </menupopup>
  </menu>
</menubar>

You can also use the accesskey attribute on buttons. When the key is pressed in this case, the button is selected.

You might want to set up more general keyboard shortcuts however. For example, pressing Contol+C to copy text to the clipboard. Although shortcuts such as this might not always be valid, they will usually work any time the window is open. Usually, a keyboard shortcut will be allowed at any time and you can check to see whether it should do something using a script. For example, copying text to the clipboard should only work when some text is selected.

XUL provides an element, key, which lets you define a keyboard shortcut for a window. It has attributes to specify the key that should be pressed and what modifier keys (such as Shift or Control) need to be pressed. An example is shown below:

<keyset>
  <key id="sample-key" modifiers="shift" key="R"/>
</keyset>

This sample defines a keyboard shortcut that is activated when the user presses the Shift key and R. The key attribute (note that it has the same name as the element itself) can be used to indicate which key should be pressed, in this case R. You could add any character for this attribute to require that key to be pressed. The modifiers that must be pressed are indicated with the modifiers attribute. It is a space-separated list of modifier keys, which are listed below.

Your keyboard won't necessary have all of the keys, in which case they will be mapped to modifier keys that you do have.

The key element must be placed inside a keyset element. This element is designed for holding a set of key elements, which serves to group all of the key definitions in one place in a file. Any key elements outside of a keyset element will not work.

Each platform generally uses a different key for keyboard shortcuts. For example, Windows uses the Control key and the Macintosh uses the Command key. It would be inconvenient to define separate key elements for each platform. Luckily, there is a solution. The modifier accel refers to the special platform-specific key used for shortcuts. If works just like the other modifiers, but won't be the same on every platform.

Here are some additional examples:

<keyset>
  <key id="copy-key" modifiers="control" key="C"/>
  <key id="explore-key" modifiers="control alt" key="E"/>
  <key id="paste-key" modifiers="accel" key="V"/>
</keyset>

The key attribute is used to specify the key that must be pressed. However, there will also be cases where you want to refer to keys that cannot be specified with a character (such as the Enter key or the function keys). The key attribute can only be used for printable characters. Another attribute, keycode can be used for non-printable characters.

The keycode attribute should be set to a special code which represents the key you want. A table of the keys is listed below. Not all of the keys are available on all keyboards.

VK_CANCELVK_BACKVK_TABVK_CLEAR
VK_RETURNVK_ENTERVK_SHIFTVK_CONTROL
VK_ALTVK_PAUSEVK_CAPS_LOCKVK_ESCAPE
VK_SPACEVK_PAGE_UPVK_PAGE_DOWNVK_END
VK_HOMEVK_LEFTVK_UPVK_RIGHT
VK_DOWNVK_PRINTSCREENVK_INSERTVK_DELETE
VK_0VK_1VK_2VK_3
VK_4VK_5VK_6VK_7
VK_8VK_9VK_SEMICOLONVK_EQUALS
VK_AVK_BVK_CVK_D
VK_EVK_FVK_GVK_H
VK_IVK_JVK_KVK_L
VK_MVK_NVK_OVK_P
VK_QVK_RVK_SVK_T
VK_UVK_VVK_WVK_X
VK_YVK_ZVK_NUMPAD0VK_NUMPAD1
VK_NUMPAD2VK_NUMPAD3VK_NUMPAD4VK_NUMPAD5
VK_NUMPAD6VK_NUMPAD7VK_NUMPAD8VK_NUMPAD9
VK_MULTIPLYVK_ADDVK_SEPARATORVK_SUBTRACT
VK_DECIMALVK_DIVIDEVK_F1VK_F2
VK_F3VK_F4VK_F5VK_F6
VK_F7VK_F8VK_F9VK_F10
VK_F11VK_F12VK_F13VK_F14
VK_F15VK_F16VK_F17VK_F18
VK_F19VK_F20VK_F21VK_F22
VK_F23VK_F24VK_NUM_LOCKVK_SCROLL_LOCK
VK_COMMAVK_PERIODVK_SLASHVK_BACK_QUOTE
VK_OPEN_BRACKETVK_BACK_SLASHVK_CLOSE_BRACKETVK_QUOTE
VK_HELP   

For example, to create a shortcut that is activated when the user presses Alt and F5, do the following:

<keyset>
  <key id="test-key" modifiers="alt" keycode="VK_F5"/>
</keyset>

The example below demonstrates some more keyboard shortcuts:

<keyset>
  <key id="copy-key" modifiers="accel" key="C"/>
  <key id="find-key" keycode="VK_F3"/>
  <key id="switch-key" modifiers="control alt" key="1"/>
</keyset>

The first key is invoked when the user presses their platform-specific shortcut key and C. The second is invoked when the user presses F3. The third is invoked on a press of the Control key, the Alt key and 1. If you wanted to distinguish between keys on the main part of the keyboard and the numeric keypad, use the VK_NUMPAD keys (such as VK_NUMPAD1).

Using the Keyboard Shortcuts

Now that we know how to define keyboard shortcuts, we'll find out how we can use them. There are two ways. The first is the simplest and just requires that you use the regular key event handlers on the key element. When the user presses the key, the script will be invoked. An example is shown below:

<keyset>
  <key id="copy-key" modifiers="accel" key="C" onkeypress="DoCopy();"/>
</keyset>

The function DoCopy will be called when the user presses the keys specified by the key element, which in this example, are the keys for copying to the clipboard (such as Control+C). This will work as long as the window is open. The DoCopy function should check to see if text is selected and then copy the text to the clipboard. Note that textboxes have the clipboard shortcuts built-in so you don't have to implement them yourself.

You can also use the keyup and keydown event handlers.

If you are assigning a keyboard shortcut that performs a command that also exists on a menu, you can associate the key element directly with the menu command. To do this, add a key attribute on the menuitem. Set its value to the id of the key that you want to use. The example below demonstrates this.

Example 7.3.2: Source View
<keyset>
  <key id="paste-key" modifiers="accel" key="V"
          oncommand="alert('Paste invoked')"/>
</keyset>

<menubar id="sample-menubar">
  <menu id="edit-menu" label="Edit" accesskey="e">
    <menupopup id="edit-popup">
      <menuitem id="paste-command" accesskey="p" key="paste-key" label="Paste"
                   oncommand="alert('Paste invoked')"/>
    </menupopup>
  </menu>
</menubar>

The menuitem's key attribute, which here is paste-key is equal to the id of the defined key. You can use this for additional keys as well to define keyboard shortcuts for any number of menu items.

You'll also notice in the image that text has been placed next to the Paste menu command to indicate that Control and the V key can be pressed to invoke the menu command. This is added for you based on the modifiers on the key element. Keyboard shortcuts attached to menus will work even if the menu is not open.

One additional feature of key definitions is that you can disable them easily. To do this add a disabled attribute to the key element and set it to the value true. This disables the keyboard shortcut so that it cannot be invoked. It is useful to change the disabled attribute using a script.

Key Example

Let's add keyboard shortcuts to the find files dialog. We'll add four of them, one for each of the Cut, Copy, and Paste commands and also one for the Close command when the user presses Escape.

<keyset>
  <key id="cut_cmd" modifiers="accel" key="X"/>
  <key id="copy_cmd" modifiers="accel" key="C"/>
  <key id="paste_cmd" modifiers="accel" key="V"/>
  <key id="close_cmd" keycode="VK_ESCAPE" oncommand="window.close();"/>
</keyset>

<vbox flex="1">
 <toolbox>
  <menubar id="findfiles-menubar">
   <menu id="file-menu" label="File" accesskey="f">
     <menupopup id="file-popup">
       <menuitem label="Open Search..." accesskey="o"/>
       <menuitem label="Save Search..." accesskey="s"/>
       <menuseparator/>
       <menuitem label="Close" accesskey="c" key="close_cmd"
         oncommand="window.close();"/>
     </menupopup>
   </menu>
   <menu id="edit-menu" label="Edit" accesskey="e">
     <menupopup id="edit-popup">
       <menuitem label="Cut" accesskey="t" key="cut_cmd"/>
       <menuitem label="Copy" accesskey="c" key="copy_cmd"/>
       <menuitem label="Paste" accesskey="p" key="paste_cmd" disabled="true"/>
     </menupopup>
   </menu>

Now we can use those shortcuts to activate the commands. Of course, the clipboard commands don't do anything anyway, as we haven't written those scripts.


(Next) Next, we'll find out how to handle focus and the selection.

Examples: 7.3.1 7.3.2

Find files example so far: Source View