SUGGESTED FIX
--- old/src/share/classes/javax/swing/RepaintManager.java 2008-07-16 16:18:02.000000000 +0400
+++ new/src/share/classes/javax/swing/RepaintManager.java 2008-07-16 16:18:02.000000000 +0400
@@ -717,8 +717,12 @@
private Map<Component,Rectangle>
updateWindows(Map<Component,Rectangle> dirtyComponents)
{
+ Toolkit toolkit = Toolkit.getDefaultToolkit();
+
if (!AWTUtilities.isTranslucencySupported(
- AWTUtilities.Translucency.PERPIXEL_TRANSLUCENT))
+ AWTUtilities.Translucency.PERPIXEL_TRANSLUCENT) ||
+ !(toolkit instanceof SunToolkit &&
+ ((SunToolkit)toolkit).needUpdateWindow()))
{
return dirtyComponents;
}
@@ -1327,10 +1331,11 @@
if (paintManager == null) {
PaintManager paintManager = null;
if (doubleBufferingEnabled && !nativeDoubleBuffering) {
+ Toolkit toolkit = Toolkit.getDefaultToolkit();
switch (bufferStrategyType) {
case BUFFER_STRATEGY_NOT_SPECIFIED:
- if (((SunToolkit)Toolkit.getDefaultToolkit()).
- useBufferPerWindow()) {
+ if (toolkit instanceof SunToolkit &&
+ ((SunToolkit)toolkit).useBufferPerWindow()) {
paintManager = new BufferStrategyPaintManager();
}
break;
--- old/src/share/classes/sun/awt/SunToolkit.java 2008-07-16 16:18:03.000000000 +0400
+++ new/src/share/classes/sun/awt/SunToolkit.java 2008-07-16 16:18:03.000000000 +0400
@@ -1997,6 +1997,17 @@
return c != null && AWTUtilities.getWindowOpacity((Window)c) < 1.0f;
}
+ /**
+ * Returns whether the native system requires using the peer.updateWindow()
+ * method to update the contents of a non-opaque window, or if usual
+ * painting procedures are sufficient. The default return value covers
+ * the X11 systems. On MS Windows this method is overriden in WToolkit
+ * to return true.
+ */
+ public boolean needUpdateWindow() {
+ return false;
+ }
+
///////////////////////////////////////////////////////////////////////////
//
// The following methods help set and identify whether a particular
--- old/src/windows/classes/sun/awt/windows/WToolkit.java 2008-07-16 16:18:03.000000000 +0400
+++ new/src/windows/classes/sun/awt/windows/WToolkit.java 2008-07-16 16:18:03.000000000 +0400
@@ -1012,4 +1012,11 @@
//XXX: worth checking if 8-bit? Anyway, it doesn't hurt.
return true;
}
+
+ // On MS Windows one must use the peer.updateWindow() to implement
+ // non-opaque windows.
+ @Override
+ public boolean needUpdateWindow() {
+ return true;
+ }
}
|
|
|
EVALUATION
The suggested fix introduces the sun.awt.SunToolkit.needUpdateWindow() method. If this method returns false, the RepaintManager.updateWindows() method simply returns the initial dirtyComponents map. If needUpdateWindow() returns true, then the updateWindow() works as usual.
|
|
|
EVALUATION
This issue is reproducible with Swing frames only. If the application uses AWT frames, everything works fine.
I've manually extracted the method that applies translucency-related changes to the frame when making it non-opaque. In this case the effect could not be reproduced: the frame bacame translucent and visible.
Hence, the most probable reason for this issue tp appear is some code that checks whether the window is opaque or not. The only such location is the javax.swing.RepaintManager.updateWindows() method. Last time it got changed as a part of the fix for CR 6687141. With this fix this method started to remove the components belonging to a non-opaque frame from the dirtyComponents map. Indeed, on MS Windows platform this should not hurt because all the components get repainted whith the updateWindow() method. However, on X11 platform this does not work correctly, because updateWindow() does nothing on these platforms: we expect that what Swing paints gets directly to the X11 window, and hence appears on the screen. Excluding the components from the dirtyComponents map excludes them from repainting, and therefore nothing gets painted on the screen. So, this seems to be a regression of 6687141.
|
|
|
EVALUATION
Note that simply undoing the fix for 6687141 would not work as it would
break the windows side, not to mention the double-repainting which severely
degrades perforance since the second time the rendering is done to a
GDI surface. Please consider changing the way translucent windows repainted
to be consistent, or perhaps change updateWindow to return a status of whether
it actually did something, and do "normal" swing repainting in case it didn't.
|
|
|
|