title: Why doesn't GWT let us add key event handlers on document element?
body: <p>I know there's <code>FocusPanel</code> on which I can attach such handlers, but in my experience this component does not behave that well. So I'd like to avoid it as much as possible.</p>
  
  <p>So I'm wondering why there's no way to attach key handlers on document too? According to <a href="http://www.quirksmode.org/dom/events/keys.html" rel="nofollow">quirksmode.org</a> it works cross-browser, so this shouldn't be a concern.</p>
  
  <p>I've also tried writing some JSNI code to do this myself, which works ok for most cases. However, if there's any other widget that listens for the same event as me on document, and that widget lets the event propagate, I can do pretty much nothing with the event that reached the document, because it's marked as dead and an exception will be thrown whenever I try to access data on that event.</p>
  
  <p>Here's my code so far:</p>
  
  <pre><code>public class RichDocument implements HasKeyPressHandlers, HasKeyDownHandlers,
      HasKeyUpHandlers, HasClickHandlers {
  
    private static final RichDocument instance = new RichDocument();
  
    public static RichDocument get() {
      return instance;
    }
  
    private final EventBus eventBus = new SimpleEventBus();
  
    private RichDocument() {
      startListening();
    }
  
    @Override
    public HandlerRegistration addClickHandler(ClickHandler handler) {
      return eventBus.addHandler(ClickEvent.getType(), handler);
    }
  
    @Override
    public HandlerRegistration addKeyDownHandler(KeyDownHandler handler) {
      return eventBus.addHandler(KeyDownEvent.getType(), handler);
    }
  
    @Override
    public HandlerRegistration addKeyPressHandler(KeyPressHandler handler) {
      return eventBus.addHandler(KeyPressEvent.getType(), handler);
    }
  
    @Override
    public HandlerRegistration addKeyUpHandler(KeyUpHandler handler) {
      return eventBus.addHandler(KeyUpEvent.getType(), handler);
    }
  
    @Override
    public void fireEvent(GwtEvent&lt;?&gt; event) {
      eventBus.fireEvent(event);
    }
  
    private native void startListening()/*-{
      var self = this;
  
      var fire = function (event) {
        event = event || $wnd.event;
        @com.google.gwt.event.dom.client.DomEvent::fireNativeEvent(Lcom/google/gwt/dom/client/NativeEvent;Lcom/google/gwt/event/shared/HasHandlers;)(event, self);
      };
  
      if ($wnd.document.addEventListener) {
        $wnd.document.addEventListener("click", fire, false);
        $wnd.document.addEventListener("keydown", fire, false);
        $wnd.document.addEventListener("keypress", fire, false);
        $wnd.document.addEventListener("keyup", fire, false);
      } else {
        $wnd.document.attachEvent("onclick", fire);
        $wnd.document.attachEvent("onkeydown", fire);
        $wnd.document.attachEvent("onkeypress", fire);
        $wnd.document.attachEvent("onkeyup", fire);
      }
    }-*/;
  }
  </code></pre>