Esempio n. 1
0
  public boolean postProcessKeyEvent(KeyEvent e) {
    // Processing events only if we are in the focused window but
    // we are not focus owner since otherwise we will get
    // duplicate shortcut events in the client - one is from
    // activate_accelerator, another from forwarded event
    // FIXME: This is probably an incompatibility, protocol
    // doesn't say anything about disable accelerators when client
    // is focused.

    XWindowPeer parent = getToplevelXWindow();
    if (parent == null || !((Window) parent.getTarget()).isFocused() || target.isFocusOwner()) {
      return false;
    }

    boolean result = false;

    if (xembedLog.isLoggable(PlatformLogger.FINER)) xembedLog.finer("Post-processing event " + e);

    // Process ACCELERATORS
    AWTKeyStroke stroke = AWTKeyStroke.getAWTKeyStrokeForEvent(e);
    long accel_id = 0;
    boolean exists = false;
    synchronized (ACCEL_LOCK) {
      exists = accel_lookup.containsKey(stroke);
      if (exists) {
        accel_id = accel_lookup.get(stroke).longValue();
      }
    }
    if (exists) {
      if (xembedLog.isLoggable(PlatformLogger.FINE))
        xembedLog.fine("Activating accelerator " + accel_id);
      xembed.sendMessage(
          xembed.handle,
          XEMBED_ACTIVATE_ACCELERATOR,
          accel_id,
          0,
          0); // FIXME: How about overloaded?
      result = true;
    }

    // Process Grabs, unofficial GTK feature
    exists = false;
    GrabbedKey key = new GrabbedKey(e);
    synchronized (GRAB_LOCK) {
      exists = grabbed_keys.contains(key);
    }
    if (exists) {
      if (xembedLog.isLoggable(PlatformLogger.FINE)) xembedLog.fine("Forwarding grabbed key " + e);
      forwardKeyEvent(e);
      result = true;
    }

    return result;
  }
  /**
   * Need this method to detect when the focus may have chance to leave the focus cycle root which
   * is EmbeddedFrame. Mostly, the code here is copied from
   * DefaultKeyboardFocusManager.processKeyEvent with some minor modifications.
   */
  public boolean dispatchKeyEvent(KeyEvent e) {

    // We can't guarantee that this is called on the same AppContext as EmbeddedFrame
    // belongs to. That's why we can't use public methods to find current focus cycle
    // root. Instead, we access KFM's private field directly.
    if (currentCycleRoot == null) {
      currentCycleRoot =
          (Field)
              AccessController.doPrivileged(
                  new PrivilegedAction() {
                    public Object run() {
                      try {
                        Field unaccessibleRoot =
                            KeyboardFocusManager.class.getDeclaredField("currentFocusCycleRoot");
                        if (unaccessibleRoot != null) {
                          unaccessibleRoot.setAccessible(true);
                        }
                        return unaccessibleRoot;
                      } catch (NoSuchFieldException e1) {
                        assert false;
                      } catch (SecurityException e2) {
                        assert false;
                      }
                      return null;
                    }
                  });
    }

    Container currentRoot = null;
    if (currentCycleRoot != null) {
      try {
        // The field is static, so we can pass null to Field.get() as the argument.
        currentRoot = (Container) currentCycleRoot.get(null);
      } catch (IllegalAccessException e3) {
        // This is impossible: currentCycleRoot would be null if setAccessible failed.
        assert false;
      }
    }

    // if we are not in EmbeddedFrame's cycle, we should not try to leave.
    if (this != currentRoot) {
      return false;
    }

    // KEY_TYPED events cannot be focus traversal keys
    if (e.getID() == KeyEvent.KEY_TYPED) {
      return false;
    }

    if (!getFocusTraversalKeysEnabled() || e.isConsumed()) {
      return false;
    }

    AWTKeyStroke stroke = AWTKeyStroke.getAWTKeyStrokeForEvent(e);
    Set toTest;
    Component currentFocused = e.getComponent();

    Component last = getFocusTraversalPolicy().getLastComponent(this);
    toTest = getFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
    if (toTest.contains(stroke) && (currentFocused == last || last == null)) {
      if (traverseOut(FORWARD)) {
        e.consume();
        return true;
      }
    }

    Component first = getFocusTraversalPolicy().getFirstComponent(this);
    toTest = getFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
    if (toTest.contains(stroke) && (currentFocused == first || first == null)) {
      if (traverseOut(BACKWARD)) {
        e.consume();
        return true;
      }
    }
    return false;
  }