EVALUATION
this is a regression cused by fix for 6518077 (Modal dialogs open slowly with JRE 1.6.0 sun.awt.X11.XToolkit)
mappedWindowsCount field was added to avoid unnecessary XQueryTree() in collerctJavaToplevels().
But actually XQueryTree() returns all childs, not only mapped.
And when we show a modal dialog we call XDialogPeer.blockWindows() to block all toplevel it should block. In this methods we try to collect all java toplevels we have
(XWindowPeer.collectJavaToplevels()), since the dialog itself is not mapped yet
mappedWindowCount is less then actual number of toplevels we can find useing XQueryTree(),
so we collect no all toplevels and missed one will not be blocked at all.
And when we will try to unblock it we got NPE :(
So, to fix the problem we should not use nu,ber of mapped toplevels, but just number of
toplevels (there is windows Set in XWindowPeer which could be used for this).
|
SUGGESTED FIX
+++ XWindowPeer.java 2007-04-19 19:22:27.000000000 +0400
@@ -56,12 +56,12 @@
private static final Logger focusLog = Logger.getLogger("sun.awt.X11.focus.XWindowPeer");
private static final Logger insLog = Logger.getLogger("sun.awt.X11.insets.XWindowPeer");
private static final Logger grabLog = Logger.getLogger("sun.awt.X11.grab.XWindowPeer");
private static final Logger iconLog = Logger.getLogger("sun.awt.X11.icon.XWindowPeer");
- private static Set windows = new HashSet();
- private static int mappedWindowsCount = 0;
+ // should be synchronized on awtLock
+ private static Set<XWindowPeer> windows = new HashSet<XWindowPeer>();
static XAtom wm_protocols;
static XAtom wm_delete_window;
static XAtom wm_take_focus;
@@ -139,27 +139,26 @@
params.putIfNull(BIT_GRAVITY, Integer.valueOf(NorthWestGravity));
savedState = WithdrawnState;
XA_NET_WM_STATE = XAtom.get("_NET_WM_STATE");
- windows.add(this);
-
winAttr = new XWindowAttributesData();
insets = new Insets(0,0,0,0);
params.put(OVERRIDE_REDIRECT, Boolean.valueOf(isOverrideRedirect()));
- XToolkit.awtLock();
+ SunToolkit.awtLock();
try {
+ windows.add(this);
if (wm_protocols == null) {
wm_protocols = XAtom.get("WM_PROTOCOLS");
wm_delete_window = XAtom.get("WM_DELETE_WINDOW");
wm_take_focus = XAtom.get("WM_TAKE_FOCUS");
}
}
finally {
- XToolkit.awtUnlock();
+ SunToolkit.awtUnlock();
}
cachedFocusableWindow = isFocusableWindow();
Font f = target.getFont();
if (f == null) {
@@ -857,16 +856,13 @@
//
// make new hash of toplevels of all windows from 'windows' hash.
// FIXME: do not call them "toplevel" as it is misleading.
//
HashSet toplevels = new HashSet();
- Iterator it = windows.iterator();
- XWindowPeer xp = null;
long topl = 0, mytopl = 0;
- while( it.hasNext() ) {
- xp = (XWindowPeer)(it.next());
+ for (XWindowPeer xp : windows) {
topl = getToplevelWindow( xp.getWindow() );
if( xp.equals( this ) ) {
mytopl = topl;
}
if( topl > 0 )
@@ -1074,11 +1070,16 @@
return XWM.getWMID() == XWM.OPENLOOK_WM &&
winAttr.nativeDecor == false;
}
public void dispose() {
- windows.remove(this);
+ SunToolkit.awtLock();
+ try {
+ windows.remove(this);
+ } finally {
+ SunToolkit.awtUnlock();
+ }
if (warningWindow != null) {
warningWindow.destroy();
}
removeRootPropertyEventDispatcher();
mustControlStackPosition = false;
@@ -1151,11 +1152,10 @@
isBeforeFirstMapNotify = false;
updateAlwaysOnTop();
synchronized (getStateLock()) {
if (!isMapped) {
- mappedWindowsCount++;
isMapped = true;
}
}
}
@@ -1166,11 +1166,10 @@
// So we also check for the property later in MapNotify. See 6480534.
isUnhiding |= isWMStateNetHidden();
synchronized (getStateLock()) {
if (isMapped) {
- mappedWindowsCount--;
isMapped = false;
}
}
}
@@ -1306,11 +1305,12 @@
v.add(rootWindow);
}
} else {
v.add(XToolkit.getDefaultRootWindow());
}
- while ((v.size() > 0) && (javaToplevels.size() < mappedWindowsCount)) {
+ final int windowsCount = windows.size();
+ while ((v.size() > 0) && (javaToplevels.size() < windowsCount)) {
long win = v.remove(0);
XQueryTree qt = new XQueryTree(win);
try {
if (qt.execute() != 0) {
int nchildren = qt.get_nchildren();
|