--- old/src/macosx/classes/sun/lwawt/LWWindowPeer.java 2012-10-23 16:28:58.452696200 +0400 +++ new/src/macosx/classes/sun/lwawt/LWWindowPeer.java 2012-10-23 16:28:58.249895800 +0400 @@ -598,29 +598,21 @@ } /** - * Called by the delegate when any part of the window should be repainted. + * Called by the {@code PlatformWindow} when any part of the window should + * be repainted. */ - public void notifyExpose(final int x, final int y, final int w, final int h) { - // TODO: there's a serious problem with Swing here: it handles - // the exposition internally, so SwingPaintEventDispatcher always - // return null from createPaintEvent(). However, we flush the - // back buffer here unconditionally, so some flickering may appear. - // A possible solution is to split postPaintEvent() into two parts, - // and override that part which is only called after if - // createPaintEvent() returned non-null value and flush the buffer - // from the overridden method - flushOnscreenGraphics(); - repaintPeer(new Rectangle(x, y, w, h)); + public final void notifyExpose(final Rectangle r) { + repaintPeer(r); } /** - * Called by the delegate when this window is moved/resized by user. - * There's no notifyReshape() in LWComponentPeer as the only + * Called by the {@code PlatformWindow} when this window is moved/resized by + * user. There's no notifyReshape() in LWComponentPeer as the only * components which could be resized by user are top-level windows. */ public final void notifyReshape(int x, int y, int w, int h) { - boolean moved = false; - boolean resized = false; + final boolean moved; + final boolean resized; synchronized (getStateLock()) { moved = (x != sysX) || (y != sysY); resized = (w != sysW) || (h != sysH); @@ -644,12 +636,13 @@ flushOnscreenGraphics(); } - // Third, COMPONENT_MOVED/COMPONENT_RESIZED events + // Third, COMPONENT_MOVED/COMPONENT_RESIZED/PAINT events if (moved) { handleMove(x, y, true); } if (resized) { - handleResize(w, h,true); + handleResize(w, h, true); + repaintPeer(); } } --- old/src/macosx/classes/sun/lwawt/macosx/CPlatformView.java 2012-10-23 16:29:00.402699600 +0400 +++ new/src/macosx/classes/sun/lwawt/macosx/CPlatformView.java 2012-10-23 16:29:00.199899300 +0400 @@ -26,7 +26,6 @@ package sun.lwawt.macosx; import java.awt.*; -import java.awt.event.*; import java.awt.image.VolatileImage; import sun.awt.CGraphicsConfig; @@ -202,12 +201,11 @@ event.getCharactersIgnoringModifiers(), event.getKeyCode(), true); } + /** + * Called by the native delegate in layer backed view mode or in the simple + * NSView mode. See NSView.drawRect(). + */ private void deliverWindowDidExposeEvent() { - Rectangle r = peer.getBounds(); - peer.notifyExpose(0, 0, r.width, r.height); - } - - private void deliverWindowDidExposeEvent(float x, float y, float w, float h) { - peer.notifyExpose((int)x, (int)y, (int)w, (int)h); + peer.notifyExpose(peer.getSize()); } } --- old/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java 2012-10-23 16:29:02.243502900 +0400 +++ new/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java 2012-10-23 16:29:02.040702500 +0400 @@ -46,7 +46,7 @@ import com.apple.laf.ClientPropertyApplicator.Property; import com.sun.awt.AWTUtilities; -public class CPlatformWindow extends CFRetainedResource implements PlatformWindow { +public final class CPlatformWindow extends CFRetainedResource implements PlatformWindow { private native long nativeCreateNSWindow(long nsViewPtr, long styleBits, double x, double y, double w, double h); private static native void nativeSetNSWindowStyleBits(long nsWindowPtr, int mask, int data); private static native void nativeSetNSWindowMenuBar(long nsWindowPtr, long menuBarPtr); @@ -199,7 +199,7 @@ // In order to keep it up-to-date we will update them on // 1) setting native bounds via nativeSetBounds() call // 2) getting notification from the native level via deliverMoveResizeEvent() - private Rectangle nativeBounds; + private Rectangle nativeBounds = new Rectangle(0, 0, 0, 0); private volatile boolean isFullScreenMode = false; private Window target; @@ -869,6 +869,12 @@ } } + private void flushBuffers() { + if (isVisible() && !nativeBounds.isEmpty()) { + LWCToolkit.getLWCToolkit().flushPendingEventsOnAppkit(target); + } + } + /************************************************************* * Callbacks from the AWTWindow and AWTView objc classes. *************************************************************/ @@ -886,10 +892,16 @@ // move/resize notifications contain a bounds smaller than // the whole screen and therefore we ignore the native notifications // and the content view itself creates correct synthetic notifications - if (isFullScreenMode) return; + if (isFullScreenMode) { + return; + } + final Rectangle oldB = nativeBounds; nativeBounds = new Rectangle(x, y, width, height); peer.notifyReshape(x, y, width, height); + if (!oldB.getSize().equals(nativeBounds.getSize()) ) { + flushBuffers(); + } //TODO validateSurface already called from notifyReshape validateSurface(); } --- old/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java 2012-10-23 16:29:04.162306200 +0400 +++ new/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java 2012-10-23 16:29:03.959505900 +0400 @@ -150,6 +150,10 @@ }); } + public static LWCToolkit getLWCToolkit() { + return (LWCToolkit)Toolkit.getDefaultToolkit(); + } + @Override protected PlatformWindow createPlatformWindow(PeerType peerType) { if (peerType == PeerType.EMBEDDEDFRAME) { @@ -407,7 +411,6 @@ return BUTTONS; } - @Override public boolean isTraySupported() { return true; @@ -489,6 +492,22 @@ synchronized(ret) { return ret[0]; } } + /** + * Just a wrapper for LWCToolkit.invokeAndWait. Posts an empty event to the + * appropriate event queue and waits for it to finish. + */ + public static void flushPendingEventsOnAppkit(final Component component) { + try { + invokeAndWait(new Runnable() { + @Override + public synchronized void run() { + } + }, component); + } catch (Exception e) { + e.printStackTrace(); + } + } + // Kicks an event over to the appropriate eventqueue and waits for it to finish // To avoid deadlocking, we manually run the NSRunLoop while waiting // Any selector invoked using ThreadUtilities performOnMainThread will be processed in doAWTRunLoop --- old/src/macosx/native/sun/awt/AWTView.m 2012-10-23 16:29:06.034309500 +0400 +++ new/src/macosx/native/sun/awt/AWTView.m 2012-10-23 16:29:05.831509200 +0400 @@ -86,11 +86,14 @@ if (windowLayer != nil) { self.cglLayer = windowLayer; + //Layer hosting view + [self setLayer: cglLayer]; [self setWantsLayer: YES]; - [self.layer addSublayer: (CALayer *)cglLayer]; - [self setLayerContentsRedrawPolicy: NSViewLayerContentsRedrawDuringViewResize]; - [self setLayerContentsPlacement: NSViewLayerContentsPlacementTopLeft]; - [self setAutoresizingMask: NSViewHeightSizable | NSViewWidthSizable]; + //Layer backed view + //[self.layer addSublayer: (CALayer *)cglLayer]; + //[self setLayerContentsRedrawPolicy: NSViewLayerContentsRedrawDuringViewResize]; + //[self setLayerContentsPlacement: NSViewLayerContentsPlacementTopLeft]; + //[self setAutoresizingMask: NSViewHeightSizable | NSViewWidthSizable]; #ifdef REMOTELAYER CGLLayer *parentLayer = (CGLLayer*)self.cglLayer; --- old/src/macosx/native/sun/java2d/opengl/CGLLayer.m 2012-10-23 16:29:07.968712900 +0400 +++ new/src/macosx/native/sun/java2d/opengl/CGLLayer.m 2012-10-23 16:29:07.765912600 +0400 @@ -57,9 +57,10 @@ // NOTE: async=YES means that the layer is re-cached periodically self.asynchronous = FALSE; - self.autoresizingMask = kCALayerWidthSizable | kCALayerHeightSizable; self.contentsGravity = kCAGravityTopLeft; - self.needsDisplayOnBoundsChange = YES; + //Layer backed view + //self.needsDisplayOnBoundsChange = YES; + //self.autoresizingMask = kCALayerWidthSizable | kCALayerHeightSizable; textureID = 0; // texture will be created by rendering pipe target = 0; @@ -109,6 +110,10 @@ glDisable(target); } +-(BOOL)canDrawInCGLContext:(CGLContextObj)glContext pixelFormat:(CGLPixelFormatObj)pixelFormat forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp{ + return textureID == 0 ? NO : YES; +} + -(void)drawInCGLContext:(CGLContextObj)glContext pixelFormat:(CGLPixelFormatObj)pixelFormat forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp { AWT_ASSERT_APPKIT_THREAD;