Mercurial > hg > jdk9-shenandoah > jdk
changeset 2765:d32203d5a47c
6505819: Provide traverseIn method for sun.awt.EmbeddedFrame
Reviewed-by: dcherepanov, art
author | ant |
---|---|
date | Mon, 27 Sep 2010 16:11:58 +0400 |
parents | c12a03da538b |
children | d21c9804c512 |
files | src/share/classes/java/awt/KeyboardFocusManager.java src/share/classes/sun/awt/AWTAccessor.java src/share/classes/sun/awt/EmbeddedFrame.java src/solaris/classes/sun/awt/X11/XEmbeddedFrame.java src/solaris/classes/sun/awt/X11/XEmbeddedFramePeer.java src/windows/classes/sun/awt/windows/WEmbeddedFrame.java |
diffstat | 6 files changed, 110 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/classes/java/awt/KeyboardFocusManager.java Fri Sep 03 11:08:41 2010 +0400 +++ b/src/share/classes/java/awt/KeyboardFocusManager.java Mon Sep 27 16:11:58 2010 +0400 @@ -142,6 +142,9 @@ public void removeLastFocusRequest(Component heavyweight) { KeyboardFocusManager.removeLastFocusRequest(heavyweight); } + public void setMostRecentFocusOwner(Window window, Component component) { + KeyboardFocusManager.setMostRecentFocusOwner(window, component); + } } ); }
--- a/src/share/classes/sun/awt/AWTAccessor.java Fri Sep 03 11:08:41 2010 +0400 +++ b/src/share/classes/sun/awt/AWTAccessor.java Mon Sep 27 16:11:58 2010 +0400 @@ -344,6 +344,11 @@ * Removes the last focus request for the heavyweight from the queue. */ void removeLastFocusRequest(Component heavyweight); + + /* + * Sets the most recent focus owner in the window. + */ + void setMostRecentFocusOwner(Window window, Component component); } /*
--- a/src/share/classes/sun/awt/EmbeddedFrame.java Fri Sep 03 11:08:41 2010 +0400 +++ b/src/share/classes/sun/awt/EmbeddedFrame.java Mon Sep 27 16:11:58 2010 +0400 @@ -70,7 +70,10 @@ // JDK 1.1 compatibility private static final long serialVersionUID = 2967042741780317130L; - // Use these in traverseOut method to determine directions + /* + * The constants define focus traversal directions. + * Use them in {@code traverseIn}, {@code traverseOut} methods. + */ protected static final boolean FORWARD = true; protected static final boolean BACKWARD = false; @@ -284,6 +287,41 @@ } /** + * This method is called by the embedder when we should receive focus as element + * of the traversal chain. The method requests focus on: + * 1. the first Component of this EmbeddedFrame if user moves focus forward + * in the focus traversal cycle. + * 2. the last Component of this EmbeddedFrame if user moves focus backward + * in the focus traversal cycle. + * + * The direction parameter specifies which of the two mentioned cases is + * happening. Use FORWARD and BACKWARD constants defined in the EmbeddedFrame class + * to avoid confusing boolean values. + * + * A concrete implementation of this method is defined in the platform-dependent + * subclasses. + * + * @param direction FORWARD or BACKWARD + * @return true, if the EmbeddedFrame wants to get focus, false otherwise. + */ + public boolean traverseIn(boolean direction) { + Component comp = null; + + if (direction == FORWARD) { + comp = getFocusTraversalPolicy().getFirstComponent(this); + } else { + comp = getFocusTraversalPolicy().getLastComponent(this); + } + if (comp != null) { + // comp.requestFocus(); - Leads to a hung. + + AWTAccessor.getKeyboardFocusManagerAccessor().setMostRecentFocusOwner(this, comp); + synthesizeWindowActivation(true); + } + return (null != comp); + } + + /** * This method is called from dispatchKeyEvent in the following two cases: * 1. The focus is on the first Component of this EmbeddedFrame and we are * about to transfer the focus backward.
--- a/src/solaris/classes/sun/awt/X11/XEmbeddedFrame.java Fri Sep 03 11:08:41 2010 +0400 +++ b/src/solaris/classes/sun/awt/X11/XEmbeddedFrame.java Mon Sep 27 16:11:58 2010 +0400 @@ -28,9 +28,12 @@ import sun.awt.EmbeddedFrame; import java.awt.*; import java.awt.AWTKeyStroke; +import java.util.logging.Logger; public class XEmbeddedFrame extends EmbeddedFrame { + private static final Logger log = Logger.getLogger(XEmbeddedFrame.class.getName()); + long handle; public XEmbeddedFrame() { } @@ -70,6 +73,21 @@ this(handle, supportsXEmbed, false); } + /* + * The method shouldn't be called in case of active XEmbed. + */ + public boolean traverseIn(boolean direction) { + XEmbeddedFramePeer peer = (XEmbeddedFramePeer)getPeer(); + if (peer != null) { + if (peer.supportsXEmbed() && peer.isXEmbedActive()) { + log.fine("The method shouldn't be called when XEmbed is active!"); + } else { + return super.traverseIn(direction); + } + } + return false; + } + protected boolean traverseOut(boolean direction) { XEmbeddedFramePeer xefp = (XEmbeddedFramePeer) getPeer(); if (direction == FORWARD) { @@ -81,6 +99,20 @@ return true; } + /* + * The method shouldn't be called in case of active XEmbed. + */ + public void synthesizeWindowActivation(boolean doActivate) { + XEmbeddedFramePeer peer = (XEmbeddedFramePeer)getPeer(); + if (peer != null) { + if (peer.supportsXEmbed() && peer.isXEmbedActive()) { + log.fine("The method shouldn't be called when XEmbed is active!"); + } else { + peer.synthesizeFocusInOut(doActivate); + } + } + } + public void registerAccelerator(AWTKeyStroke stroke) { XEmbeddedFramePeer xefp = (XEmbeddedFramePeer) getPeer(); if (xefp != null) {
--- a/src/solaris/classes/sun/awt/X11/XEmbeddedFramePeer.java Fri Sep 03 11:08:41 2010 +0400 +++ b/src/solaris/classes/sun/awt/X11/XEmbeddedFramePeer.java Mon Sep 27 16:11:58 2010 +0400 @@ -35,6 +35,8 @@ import sun.awt.EmbeddedFrame; import sun.awt.SunToolkit; +import static sun.awt.X11.XConstants.*; + public class XEmbeddedFramePeer extends XFramePeer { private static final PlatformLogger xembedLog = PlatformLogger.getLogger("sun.awt.X11.xembed.XEmbeddedFramePeer"); @@ -305,4 +307,20 @@ EmbeddedFrame frame = (EmbeddedFrame)target; frame.notifyModalBlocked(blocker, blocked); } + + public void synthesizeFocusInOut(boolean doFocus) { + XFocusChangeEvent xev = new XFocusChangeEvent(); + + XToolkit.awtLock(); + try { + xev.set_type(doFocus ? FocusIn : FocusOut); + xev.set_window(getFocusProxy().getWindow()); + xev.set_mode(NotifyNormal); + XlibWrapper.XSendEvent(XToolkit.getDisplay(), getFocusProxy().getWindow(), false, + NoEventMask, xev.pData); + } finally { + XToolkit.awtUnlock(); + xev.dispose(); + } + } }
--- a/src/windows/classes/sun/awt/windows/WEmbeddedFrame.java Fri Sep 03 11:08:41 2010 +0400 +++ b/src/windows/classes/sun/awt/windows/WEmbeddedFrame.java Mon Sep 27 16:11:58 2010 +0400 @@ -191,9 +191,20 @@ public void activateEmbeddingTopLevel() { } - public void synthesizeWindowActivation(boolean doActivate) { - ((WEmbeddedFramePeer)getPeer()).synthesizeWmActivate(doActivate); + public void synthesizeWindowActivation(final boolean doActivate) { + if (!doActivate || EventQueue.isDispatchThread()) { + ((WEmbeddedFramePeer)getPeer()).synthesizeWmActivate(doActivate); + } else { + // To avoid focus concurrence b/w IE and EmbeddedFrame + // activation is postponed by means of posting it to EDT. + EventQueue.invokeLater(new Runnable() { + public void run() { + ((WEmbeddedFramePeer)getPeer()).synthesizeWmActivate(true); + } + }); + } } + public void registerAccelerator(AWTKeyStroke stroke) {} public void unregisterAccelerator(AWTKeyStroke stroke) {}