提交 2ca4e6ac 编写于 作者: A art

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
上级 70df236a
...@@ -31,6 +31,9 @@ import sun.awt.SunToolkit; ...@@ -31,6 +31,9 @@ import sun.awt.SunToolkit;
import java.awt.Component; import java.awt.Component;
import java.awt.Container; import java.awt.Container;
import sun.awt.X11GraphicsConfig;
import sun.awt.X11GraphicsDevice;
/** /**
* Helper class implementing XEmbed protocol handling routines(client side) * Helper class implementing XEmbed protocol handling routines(client side)
* Window which wants to participate in a protocol should create an instance, * Window which wants to participate in a protocol should create an instance,
...@@ -39,20 +42,34 @@ import java.awt.Container; ...@@ -39,20 +42,34 @@ import java.awt.Container;
public class XEmbedClientHelper extends XEmbedHelper implements XEventDispatcher { public class XEmbedClientHelper extends XEmbedHelper implements XEventDispatcher {
private static final Logger xembedLog = Logger.getLogger("sun.awt.X11.xembed.XEmbedClientHelper"); 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 boolean active;
private long server;
private boolean applicationActive; private boolean applicationActive;
XEmbedClientHelper() { XEmbedClientHelper() {
super(); super();
} }
void install(XEmbeddedFramePeer embedded) { void setClient(XEmbeddedFramePeer client) {
this.embedded = embedded; 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); void install() {
XToolkit.addEventDispatcher(embedded.getWindow(), this); if (xembedLog.isLoggable(Level.FINE)) {
xembedLog.fine("Installing xembedder on " + embedded);
}
long[] info = new long[] { XEMBED_VERSION, XEMBED_MAPPED }; long[] info = new long[] { XEMBED_VERSION, XEMBED_MAPPED };
long data = Native.card32ToData(info); long data = Native.card32ToData(info);
try { try {
...@@ -155,7 +172,24 @@ public class XEmbedClientHelper extends XEmbedHelper implements XEventDispatcher ...@@ -155,7 +172,24 @@ public class XEmbedClientHelper extends XEmbedHelper implements XEventDispatcher
} }
public void handleReparentNotify(XEvent xev) { public void handleReparentNotify(XEvent xev) {
XReparentEvent re = xev.get_xreparent(); 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() { boolean requestFocus() {
if (active && embedded.focusAllowedFor()) { if (active && embedded.focusAllowedFor()) {
...@@ -201,12 +235,16 @@ public class XEmbedClientHelper extends XEmbedHelper implements XEventDispatcher ...@@ -201,12 +235,16 @@ public class XEmbedClientHelper extends XEmbedHelper implements XEventDispatcher
} }
void registerAccelerator(AWTKeyStroke stroke, int id) { void registerAccelerator(AWTKeyStroke stroke, int id) {
long sym = getX11KeySym(stroke); if (active) {
long mods = getX11Mods(stroke); long sym = getX11KeySym(stroke);
sendMessage(server, XEMBED_REGISTER_ACCELERATOR, id, sym, mods); long mods = getX11Mods(stroke);
sendMessage(server, XEMBED_REGISTER_ACCELERATOR, id, sym, mods);
}
} }
void unregisterAccelerator(int id) { 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) { long getX11KeySym(AWTKeyStroke stroke) {
......
...@@ -63,7 +63,10 @@ public class XEmbeddedFramePeer extends XFramePeer { ...@@ -63,7 +63,10 @@ public class XEmbeddedFramePeer extends XFramePeer {
void postInit(XCreateWindowParams params) { void postInit(XCreateWindowParams params) {
super.postInit(params); super.postInit(params);
if (embedder != null) { if (embedder != null) {
embedder.install(this); // install X11 event dispatcher
embedder.setClient(this);
// reparent to XEmbed server
embedder.install();
} else if (getParentWindowHandle() != 0) { } else if (getParentWindowHandle() != 0) {
XToolkit.awtLock(); XToolkit.awtLock();
try { try {
...@@ -77,6 +80,15 @@ public class XEmbeddedFramePeer extends XFramePeer { ...@@ -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() { public void updateMinimumSize() {
} }
...@@ -249,6 +261,14 @@ public class XEmbeddedFramePeer extends XFramePeer { ...@@ -249,6 +261,14 @@ public class XEmbeddedFramePeer extends XFramePeer {
// XEmbed. // XEmbed.
updateDropTarget(); updateDropTarget();
} }
void notifyStopped() {
if (embedder != null && embedder.isActive()) {
for (int i = strokes.size() - 1; i >= 0; i--) {
embedder.unregisterAccelerator(i);
}
}
}
long getFocusTargetWindow() { long getFocusTargetWindow() {
return getWindow(); return getWindow();
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册