From cdc043012645736bd36b6d2cc38347b4b35dafd8 Mon Sep 17 00:00:00 2001 From: Artem Ananiev Date: Fri, 19 Dec 2008 16:04:04 +0300 Subject: [PATCH] 6773985: OutOfMemory (PermGen space) under Linux / Firefox when switching bw. applets XEmbedClientHelper is uninstalled when its embedded frame is disposed. Reviewed-by: dcherepanov, ant --- .../sun/awt/X11/XEmbedClientHelper.java | 60 +++++++++++++++---- .../sun/awt/X11/XEmbeddedFramePeer.java | 22 ++++++- 2 files changed, 70 insertions(+), 12 deletions(-) diff --git a/jdk/src/solaris/classes/sun/awt/X11/XEmbedClientHelper.java b/jdk/src/solaris/classes/sun/awt/X11/XEmbedClientHelper.java index 139f375fa40..8be2390754c 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XEmbedClientHelper.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XEmbedClientHelper.java @@ -31,6 +31,9 @@ import sun.awt.SunToolkit; 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 @@ import java.awt.Container; 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 class XEmbedClientHelper extends XEmbedHelper implements XEventDispatcher } 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 @@ public class XEmbedClientHelper extends XEmbedHelper implements XEventDispatcher } 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) { diff --git a/jdk/src/solaris/classes/sun/awt/X11/XEmbeddedFramePeer.java b/jdk/src/solaris/classes/sun/awt/X11/XEmbeddedFramePeer.java index 90eb7ff8ddc..892d7c94e99 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XEmbeddedFramePeer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XEmbeddedFramePeer.java @@ -63,7 +63,10 @@ public class XEmbeddedFramePeer extends XFramePeer { 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 @@ public class XEmbeddedFramePeer extends XFramePeer { } } + @Override + public void dispose() { + if (embedder != null) { + // uninstall X11 event dispatcher + embedder.setClient(null); + } + super.dispose(); + } + public void updateMinimumSize() { } @@ -249,6 +261,14 @@ public class XEmbeddedFramePeer extends XFramePeer { // 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(); }