Key Bindings in RAP

Support for key bindings (bug 282449) has been one of the most requested features for RAP. So I’m happy to say that since 1.4 M5, RAP implements the JFace key bindings API, provides the org.eclipse.ui.bindings extension point, and enables most of the default workbench key bindings. As a result, you can now use most* of the key shortcuts of your application also in the browser–if your application uses the workbench. But many use RAP without using the workbench. So how can you enable key bindings in a plain RWT application?

In M7, we now introduce a simple way of doing this. Let’s first have a look on how you would implement a key binding in SWT. You would have to register a global listener for key events on the display like this:

display.addFilter( SWT.KeyDown, new Listener() {
  public void handleEvent( Event event ) {
    if( event.stateMask == 0 && event.keyCode == SWT.ESCAPE ) {
      // handle escape key
    }
  }
} );

Well, you can now use the same code in RWT.

But there’s one more thing to it: RWT is a client-server architecture and we don’t want the browser client to send a request for each and every key stroke. The server should only be notified when the user presses one of the key sequences that we are really interested in. Therefore, we have to inform the client, which key sequences should be active. This information can now be attached to the display using Display.setData() with the new constant RWT.ACTIVE_KEYS as property key. The value of this property must be an array of strings, each one representing a single active key sequence. The syntax is the same that you know from key binding extensions for the workbench. So if you want to enable some simple key bindings like, for example, “c” for compose and “x” for delete, and maybe some more advanced key sequences like “Ctrl+F11″ for power-users, you could write something like this:

display.setData( RWT.ACTIVE_KEYS, new String[] { "C", "X", "CTRL+F11" } );
display.addFilter( SWT.KeyDown, new Listener() {
  public void handleEvent( Event event ) {
    if( event.stateMask == 0 && event.character == 'C' ) {
      handleCompose();
    } else if( event.stateMask == 0 && event.character == 'X' ) {
      handleDelete();
    } else if( event.stateMask == SWT.CTRL && event.keyCode == SWT.F11 ) {
      doSomeAdvancedStuff();
    }
  }
} );

Only the first line is RAP-specific. So for a single-sourcing RWT/SWT application, you only have to care about the constant. I’m sure you have an idea how to do that. M7 will be available on May 7–easy to remember.

*) Some shortcuts may be reserved by some browsers and cannot be used. Other shortcuts will override browser actions, like Ctrl-N (new window) Ctrl-T (new tab) etc. You also may not like to disable C&P in form fields by adding key bindings for Ctrl-C etc. So you have to choose your web key bindings wisely… Ah, and sequences of key strokes like Ctrl+X T are not yet supported.

5 Responses to “Key Bindings in RAP”

  1. Sebastien says:

    Very interesting post.

    Is there a similar optimization for KeyListeners defined on Control?

  2. Ralf Sternberg says:

    Hi Sebastien,

    this solution is currently only implemented for system-wide key events in order to support key bindings.

    However, I think I agree that it could make sense to extend this mechanism to Controls, using Widget#setData() with the same constant. Please feel free to open an enhancement request if you have a use case:

    http://eclipse.org/rap/bugs/

  3. Sebastien says:

    Hi Ralf,

    Thanks for your quick answer I created the enhancement request:
    Bug 346597 – Support RWT.ACTIVE_KEYS to optimize KeyListener on Widget

  4. Ralf Sternberg says:

    Thanks, Sebastien. That’s an interesting proposal. We’ll discuss it for 1.5.

5 responses so far

Written by . Published in Categories: EclipseSource News, Planet Eclipse