OpenJDK / jdk8u / jdk8u / jdk
changeset 882:d5bf2dd61ed5
6773985: OutOfMemory (PermGen space) under Linux / Firefox when switching bw. applets
Summary: XEmbedClientHelper is uninstalled when its embedded frame is disposed.
Reviewed-by: dcherepanov, ant
author | art |
---|---|
date | Fri, 19 Dec 2008 16:04:04 +0300 |
parents | 9daa41eca0d9 |
children | 63d087cacbf9 |
files | src/solaris/classes/sun/awt/X11/XEmbedClientHelper.java src/solaris/classes/sun/awt/X11/XEmbeddedFramePeer.java |
diffstat | 2 files changed, 70 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- a/src/solaris/classes/sun/awt/X11/XEmbedClientHelper.java Wed Nov 26 16:25:16 2008 +0300 +++ b/src/solaris/classes/sun/awt/X11/XEmbedClientHelper.java Fri Dec 19 16:04:04 2008 +0300 @@ -31,6 +31,9 @@ import java.awt.Component; import java.awt.Container; +import sun.awt.X11GraphicsConfig; +import sun.awt.X11GraphicsDevice; + /** * Helper class implementing XEmbed protocol handling routines(client side) * Window which wants to participate in a protocol should create an instance, @@ -39,20 +42,34 @@ public class XEmbedClientHelper extends XEmbedHelper implements XEventDispatcher { private static final Logger xembedLog = Logger.getLogger("sun.awt.X11.xembed.XEmbedClientHelper"); - private XEmbeddedFramePeer embedded; + private XEmbeddedFramePeer embedded; // XEmbed client + private long server; // XEmbed server + private boolean active; - private long server; private boolean applicationActive; XEmbedClientHelper() { super(); } - void install(XEmbeddedFramePeer embedded) { - this.embedded = embedded; + void setClient(XEmbeddedFramePeer client) { + if (xembedLog.isLoggable(Level.FINE)) { + xembedLog.fine("XEmbed client: " + client); + } + if (embedded != null) { + XToolkit.removeEventDispatcher(embedded.getWindow(), this); + active = false; + } + embedded = client; + if (embedded != null) { + XToolkit.addEventDispatcher(embedded.getWindow(), this); + } + } - if (xembedLog.isLoggable(Level.FINE)) xembedLog.fine("Installing xembedder on " + embedded); - XToolkit.addEventDispatcher(embedded.getWindow(), this); + void install() { + if (xembedLog.isLoggable(Level.FINE)) { + xembedLog.fine("Installing xembedder on " + embedded); + } long[] info = new long[] { XEMBED_VERSION, XEMBED_MAPPED }; long data = Native.card32ToData(info); try { @@ -155,7 +172,24 @@ } public void handleReparentNotify(XEvent xev) { XReparentEvent re = xev.get_xreparent(); - server = re.get_parent(); + long newParent = re.get_parent(); + if (active) { + // unregister accelerators, etc. for old parent + embedded.notifyStopped(); + // check if newParent is a root window + X11GraphicsConfig gc = (X11GraphicsConfig)embedded.getGraphicsConfiguration(); + X11GraphicsDevice gd = (X11GraphicsDevice)gc.getDevice(); + if ((newParent == XlibUtil.getRootWindow(gd.getScreen())) || + (newParent == XToolkit.getDefaultRootWindow())) + { + // reparenting to root means XEmbed termination + active = false; + } else { + // continue XEmbed with a new parent + server = newParent; + embedded.notifyStarted(); + } + } } boolean requestFocus() { if (active && embedded.focusAllowedFor()) { @@ -201,12 +235,16 @@ } void registerAccelerator(AWTKeyStroke stroke, int id) { - long sym = getX11KeySym(stroke); - long mods = getX11Mods(stroke); - sendMessage(server, XEMBED_REGISTER_ACCELERATOR, id, sym, mods); + if (active) { + long sym = getX11KeySym(stroke); + long mods = getX11Mods(stroke); + sendMessage(server, XEMBED_REGISTER_ACCELERATOR, id, sym, mods); + } } void unregisterAccelerator(int id) { - sendMessage(server, XEMBED_UNREGISTER_ACCELERATOR, id, 0, 0); + if (active) { + sendMessage(server, XEMBED_UNREGISTER_ACCELERATOR, id, 0, 0); + } } long getX11KeySym(AWTKeyStroke stroke) {
--- a/src/solaris/classes/sun/awt/X11/XEmbeddedFramePeer.java Wed Nov 26 16:25:16 2008 +0300 +++ b/src/solaris/classes/sun/awt/X11/XEmbeddedFramePeer.java Fri Dec 19 16:04:04 2008 +0300 @@ -63,7 +63,10 @@ void postInit(XCreateWindowParams params) { super.postInit(params); if (embedder != null) { - embedder.install(this); + // install X11 event dispatcher + embedder.setClient(this); + // reparent to XEmbed server + embedder.install(); } else if (getParentWindowHandle() != 0) { XToolkit.awtLock(); try { @@ -77,6 +80,15 @@ } } + @Override + public void dispose() { + if (embedder != null) { + // uninstall X11 event dispatcher + embedder.setClient(null); + } + super.dispose(); + } + public void updateMinimumSize() { } @@ -249,6 +261,14 @@ // XEmbed. updateDropTarget(); } + void notifyStopped() { + if (embedder != null && embedder.isActive()) { + for (int i = strokes.size() - 1; i >= 0; i--) { + embedder.unregisterAccelerator(i); + } + } + } + long getFocusTargetWindow() { return getWindow(); }