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; }