7154778: [macosx] NSView-based implementation of sun.awt.EmbeddedFrame

The new implementation of EmbeddedFrame to support SWT_AWT Bridge

Reviewed-by: anthony, serb, leonidr
This commit is contained in:
Petr Pchelko 2012-12-11 19:45:00 +04:00 committed by Sergey Bylokhov
parent 0b8ff32553
commit c745a7e923
21 changed files with 616 additions and 120 deletions

View File

@ -210,9 +210,9 @@ public abstract class LWToolkit extends SunToolkit implements Runnable {
* and DialogPeer interfaces.
*/
private LWWindowPeer createDelegatedPeer(Window target, PlatformComponent platformComponent,
PlatformWindow platformWindow)
PlatformWindow platformWindow, LWWindowPeer.PeerType peerType)
{
LWWindowPeer peer = new LWWindowPeer(target, platformComponent, platformWindow);
LWWindowPeer peer = new LWWindowPeer(target, platformComponent, platformWindow, peerType);
targetCreatedPeer(target, peer);
peer.initialize();
return peer;
@ -222,22 +222,29 @@ public abstract class LWToolkit extends SunToolkit implements Runnable {
public WindowPeer createWindow(Window target) {
PlatformComponent platformComponent = createPlatformComponent();
PlatformWindow platformWindow = createPlatformWindow(LWWindowPeer.PeerType.SIMPLEWINDOW);
return createDelegatedPeer(target, platformComponent, platformWindow);
return createDelegatedPeer(target, platformComponent, platformWindow, LWWindowPeer.PeerType.SIMPLEWINDOW);
}
@Override
public FramePeer createFrame(Frame target) {
PlatformComponent platformComponent = createPlatformComponent();
PlatformWindow platformWindow = createPlatformWindow(LWWindowPeer.PeerType.FRAME);
return createDelegatedPeer(target, platformComponent, platformWindow);
return createDelegatedPeer(target, platformComponent, platformWindow, LWWindowPeer.PeerType.FRAME);
}
public LWWindowPeer createEmbeddedFrame(CEmbeddedFrame target) {
PlatformComponent platformComponent = createPlatformComponent();
PlatformWindow platformWindow = createPlatformWindow(LWWindowPeer.PeerType.EMBEDDEDFRAME);
return createDelegatedPeer(target, platformComponent, platformWindow);
PlatformWindow platformWindow = createPlatformWindow(LWWindowPeer.PeerType.EMBEDDED_FRAME);
return createDelegatedPeer(target, platformComponent, platformWindow, LWWindowPeer.PeerType.EMBEDDED_FRAME);
}
public LWWindowPeer createEmbeddedFrame(CViewEmbeddedFrame target) {
PlatformComponent platformComponent = createPlatformComponent();
PlatformWindow platformWindow = createPlatformWindow(LWWindowPeer.PeerType.VIEW_EMBEDDED_FRAME);
return createDelegatedPeer(target, platformComponent, platformWindow, LWWindowPeer.PeerType.VIEW_EMBEDDED_FRAME);
}
CPrinterDialogPeer createCPrinterDialog(CPrinterDialog target) {
PlatformComponent platformComponent = createPlatformComponent();
PlatformWindow platformWindow = createPlatformWindow(LWWindowPeer.PeerType.DIALOG);
@ -254,7 +261,7 @@ public abstract class LWToolkit extends SunToolkit implements Runnable {
PlatformComponent platformComponent = createPlatformComponent();
PlatformWindow platformWindow = createPlatformWindow(LWWindowPeer.PeerType.DIALOG);
return createDelegatedPeer(target, platformComponent, platformWindow);
return createDelegatedPeer(target, platformComponent, platformWindow, LWWindowPeer.PeerType.DIALOG);
}
@Override

View File

@ -47,7 +47,8 @@ public class LWWindowPeer
SIMPLEWINDOW,
FRAME,
DIALOG,
EMBEDDEDFRAME
EMBEDDED_FRAME,
VIEW_EMBEDDED_FRAME
}
private static final PlatformLogger focusLog = PlatformLogger.getLogger("sun.lwawt.focus.LWWindowPeer");
@ -108,6 +109,8 @@ public class LWWindowPeer
private volatile boolean textured;
private final PeerType peerType;
/**
* Current modal blocker or null.
*
@ -116,10 +119,11 @@ public class LWWindowPeer
private LWWindowPeer blocker;
public LWWindowPeer(Window target, PlatformComponent platformComponent,
PlatformWindow platformWindow)
PlatformWindow platformWindow, PeerType peerType)
{
super(target, platformComponent);
this.platformWindow = platformWindow;
this.peerType = peerType;
Window owner = target.getOwner();
LWWindowPeer ownerPeer = (owner != null) ? (LWWindowPeer)owner.getPeer() : null;
@ -275,6 +279,11 @@ public class LWWindowPeer
@Override
public void setBounds(int x, int y, int w, int h, int op) {
if((op & NO_EMBEDDED_CHECK) == 0 && getPeerType() == PeerType.VIEW_EMBEDDED_FRAME) {
return;
}
if ((op & SET_CLIENT_SIZE) != 0) {
// SET_CLIENT_SIZE is only applicable to window peers, so handle it here
// instead of pulling 'insets' field up to LWComponentPeer
@ -1210,6 +1219,10 @@ public class LWWindowPeer
return this == grabbingWindow;
}
public PeerType getPeerType() {
return peerType;
}
@Override
public String toString() {
return super.toString() + " [target is " + getTarget() + "]";

View File

@ -151,4 +151,6 @@ public interface PlatformWindow {
public long getLayerPtr();
public LWWindowPeer getPeer();
public boolean isUnderMouse();
}

View File

@ -26,7 +26,6 @@
package sun.lwawt.macosx;
import java.awt.Window;
import sun.lwawt.LWMouseInfoPeer;
import sun.lwawt.LWWindowPeer;
@ -41,10 +40,6 @@ public class CMouseInfoPeer extends LWMouseInfoPeer
return false;
}
LWWindowPeer peer = (LWWindowPeer)w.getPeer();
CPlatformWindow platformWindow = (CPlatformWindow)peer.getPlatformWindow();
return nativeIsWindowUnderMouse(platformWindow.getNSWindowPtr());
return ((LWWindowPeer)w.getPeer()).getPlatformWindow().isUnderMouse();
}
private static native boolean nativeIsWindowUnderMouse(long ptr);
}

View File

@ -25,16 +25,13 @@
package sun.lwawt.macosx;
import sun.lwawt.PlatformWindow;
import sun.lwawt.LWWindowPeer;
import sun.java2d.opengl.CGLLayer;
import sun.java2d.SurfaceData;
import sun.awt.CausedFocusEvent;
import java.awt.*;
import sun.awt.CausedFocusEvent;
import sun.java2d.SurfaceData;
import sun.java2d.opengl.CGLLayer;
import sun.lwawt.LWWindowPeer;
import sun.lwawt.LWWindowPeer.PeerType;
import sun.lwawt.PlatformWindow;
import sun.util.logging.PlatformLogger;
/*
@ -134,6 +131,7 @@ public class CPlatformEmbeddedFrame implements PlatformWindow {
// This method should be properly implemented for applets.
// It returns null just as a stub.
@Override
public PlatformWindow getTopmostPlatformWindowUnderMouse() { return null; }
@Override
@ -192,4 +190,13 @@ public class CPlatformEmbeddedFrame implements PlatformWindow {
@Override
public void setModalBlocked(boolean blocked) {}
/*
* The method could not be implemented due to CALayer restrictions.
* The exeption enforce clients not to use it.
*/
@Override
public boolean isUnderMouse() {
throw new RuntimeException("Not implemented");
}
}

View File

@ -26,8 +26,11 @@
package sun.lwawt.macosx;
import java.awt.*;
import java.awt.geom.Rectangle2D;
import java.awt.image.VolatileImage;
import sun.awt.CGraphicsConfig;
import sun.awt.CGraphicsEnvironment;
import sun.lwawt.LWWindowPeer;
import sun.lwawt.macosx.event.NSEvent;
@ -37,6 +40,10 @@ import sun.java2d.opengl.CGLSurfaceData;
public class CPlatformView extends CFRetainedResource {
private native long nativeCreateView(int x, int y, int width, int height, long windowLayerPtr);
private static native void nativeSetAutoResizable(long awtView, boolean toResize);
private static native int nativeGetNSViewDisplayID(long awtView);
private static native Rectangle2D nativeGetLocationOnScreen(long awtView);
private static native boolean nativeIsViewUnderMouse(long ptr);
private LWWindowPeer peer;
private SurfaceData surfaceData;
@ -59,7 +66,7 @@ public class CPlatformView extends CFRetainedResource {
public long getAWTView() {
return ptr;
}
}
public boolean isOpaque() {
return !peer.isTranslucent();
@ -158,10 +165,46 @@ public class CPlatformView extends CFRetainedResource {
}
}
public void setAutoResizable(boolean toResize) {
nativeSetAutoResizable(this.getAWTView(), toResize);
}
public boolean isUnderMouse() {
return nativeIsViewUnderMouse(getAWTView());
}
public GraphicsDevice getGraphicsDevice() {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
CGraphicsEnvironment cge = (CGraphicsEnvironment)ge;
int displayID = nativeGetNSViewDisplayID(getAWTView());
GraphicsDevice gd = cge.getScreenDevice(displayID);
if (gd == null) {
// this could possibly happen during device removal
// use the default screen device in this case
gd = ge.getDefaultScreenDevice();
}
return gd;
}
public Point getLocationOnScreen() {
Rectangle r = nativeGetLocationOnScreen(this.getAWTView()).getBounds();
return new Point(r.x, r.y);
}
// ----------------------------------------------------------------------
// NATIVE CALLBACKS
// ----------------------------------------------------------------------
/*
* The callback is called only in the embedded case when the view is
* automatically resized by the superview.
* In normal mode this method is never called.
*/
private void deliverResize(int x, int y, int w, int h) {
peer.notifyReshape(x, y, w, h);
}
private void deliverMouseEvent(NSEvent event) {
int x = event.getX();
int y = getBounds().height - event.getY();

View File

@ -64,8 +64,6 @@ public final class CPlatformWindow extends CFRetainedResource implements Platfor
private static native void nativeDispose(long nsWindowPtr);
private static native CPlatformWindow nativeGetTopmostPlatformWindowUnderMouse();
private static native int nativeGetNSWindowDisplayID(long nsWindowPtr);
// Loger to report issues happened during execution but that do not affect functionality
private static final PlatformLogger logger = PlatformLogger.getLogger("sun.lwawt.macosx.CPlatformWindow");
private static final PlatformLogger focusLogger = PlatformLogger.getLogger("sun.lwawt.macosx.focus.CPlatformWindow");
@ -211,9 +209,8 @@ public final class CPlatformWindow extends CFRetainedResource implements Platfor
private CPlatformResponder responder;
private volatile boolean zoomed = false; // from native perspective
public CPlatformWindow(final PeerType peerType) {
public CPlatformWindow() {
super(0, true);
assert (peerType == PeerType.SIMPLEWINDOW || peerType == PeerType.DIALOG || peerType == PeerType.FRAME);
}
/*
@ -429,16 +426,7 @@ public final class CPlatformWindow extends CFRetainedResource implements Platfor
@Override
public GraphicsDevice getGraphicsDevice() {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
CGraphicsEnvironment cge = (CGraphicsEnvironment)ge;
int displayID = nativeGetNSWindowDisplayID(getNSWindowPtr());
GraphicsDevice gd = cge.getScreenDevice(displayID);
if (gd == null) {
// this could possibly happen during device removal
// use the default screen device in this case
gd = ge.getDefaultScreenDevice();
}
return gd;
return contentView.getGraphicsDevice();
}
@Override // PlatformWindow
@ -833,6 +821,11 @@ public final class CPlatformWindow extends CFRetainedResource implements Platfor
return peer;
}
@Override
public boolean isUnderMouse() {
return contentView.isUnderMouse();
}
public CPlatformView getContentView() {
return contentView;
}

View File

@ -41,7 +41,7 @@ public class CPrinterDialogPeer extends LWWindowPeer {
public CPrinterDialogPeer(CPrinterDialog target, PlatformComponent platformComponent,
PlatformWindow platformWindow)
{
super(target, platformComponent, platformWindow);
super(target, platformComponent, platformWindow, LWWindowPeer.PeerType.DIALOG);
//super(target);
fTarget = target;
super.initialize();

View File

@ -0,0 +1,102 @@
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.lwawt.macosx;
import java.awt.AWTKeyStroke;
import java.awt.Toolkit;
import java.lang.reflect.InvocationTargetException;
import sun.awt.EmbeddedFrame;
import sun.lwawt.LWToolkit;
import sun.lwawt.LWWindowPeer;
/*
* The CViewEmbeddedFrame class is used in the SWT_AWT bridge.
* This is a part of public API and should not be renamed or moved
*/
public class CViewEmbeddedFrame extends EmbeddedFrame {
private final long nsViewPtr;
private boolean isActive = false;
public CViewEmbeddedFrame(long nsViewPtr) {
this.nsViewPtr = nsViewPtr;
}
@SuppressWarnings("deprecation")
@Override
public void addNotify() {
if (getPeer() == null) {
LWToolkit toolkit = (LWToolkit) Toolkit.getDefaultToolkit();
setPeer(toolkit.createEmbeddedFrame(this));
}
super.addNotify();
}
public long getEmbedderHandle() {
return nsViewPtr;
}
@Override
public void registerAccelerator(AWTKeyStroke awtks) {
}
@Override
public void unregisterAccelerator(AWTKeyStroke awtks) {
}
public boolean isParentWindowActive() {
return isActive;
}
/*
* Synthetic event delivery for focus management
*/
@Override
public void synthesizeWindowActivation(boolean activated) {
if (isActive != activated) {
isActive = activated;
((LWWindowPeer)getPeer()).notifyActivation(activated, null);
}
}
/*
* Initializes the embedded frame bounds and validates a component.
* Designed to be called from the main thread
* This method should be called once from the initialization of the SWT_AWT Bridge
*/
@SuppressWarnings("deprecation")
public void validateWithBounds(final int x, final int y, final int width, final int height) {
try {
LWCToolkit.invokeAndWait(new Runnable() {
@Override
public void run() {
((LWWindowPeer) getPeer()).setBoundsPrivate(0, 0, width, height);
validate();
setVisible(true);
}
}, null);
} catch (InterruptedException | InvocationTargetException ex) {}
}
}

View File

@ -0,0 +1,211 @@
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.lwawt.macosx;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.GraphicsDevice;
import java.awt.Insets;
import java.awt.MenuBar;
import java.awt.Point;
import java.awt.Window;
import sun.awt.CausedFocusEvent.Cause;
import sun.java2d.SurfaceData;
import sun.lwawt.LWWindowPeer;
import sun.lwawt.PlatformWindow;
public class CViewPlatformEmbeddedFrame implements PlatformWindow {
private CPlatformView view;
private LWWindowPeer peer;
private CViewEmbeddedFrame target;
private CPlatformResponder responder;
@Override // PlatformWindow
public void initialize(Window target, final LWWindowPeer peer, PlatformWindow owner) {
this.peer = peer;
this.target = (CViewEmbeddedFrame) target;
responder = new CPlatformResponder(peer, false);
view = new CPlatformView();
view.initialize(peer, responder);
CWrapper.NSView.addSubview(this.target.getEmbedderHandle(), view.getAWTView());
view.setAutoResizable(true);
}
public long getNSViewPtr() {
return view.getAWTView();
}
@Override
public long getLayerPtr() {
return view.getWindowLayerPtr();
}
@Override
public LWWindowPeer getPeer() {
return peer;
}
@Override
public void dispose() {
CWrapper.NSView.removeFromSuperview(view.getAWTView());
view.dispose();
}
@Override
public void setVisible(boolean visible) {
CWrapper.NSView.setHidden(view.getAWTView(), !visible);
}
@Override
public void setTitle(String title) {
}
@Override
public void setBounds(int x, int y, int w, int h) {
view.setBounds(x, y, w, h);
peer.notifyReshape(x, y, w, h);
}
@Override
public GraphicsDevice getGraphicsDevice() {
return view.getGraphicsDevice();
}
@Override
public Point getLocationOnScreen() {
return view.getLocationOnScreen();
}
@Override
public Insets getInsets() {
return new Insets(0, 0, 0, 0);
}
@Override
public FontMetrics getFontMetrics(Font f) {
throw new RuntimeException("Not implemented");
}
@Override
public SurfaceData getScreenSurface() {
return view.getSurfaceData();
}
@Override
public SurfaceData replaceSurfaceData() {
return view.replaceSurfaceData();
}
@Override
public void setModalBlocked(boolean blocked) {
}
@Override
public void toFront() {
}
@Override
public void toBack() {
}
@Override
public void setMenuBar(MenuBar mb) {
}
@Override
public void setAlwaysOnTop(boolean value) {
}
@Override
public PlatformWindow getTopmostPlatformWindowUnderMouse() {
return null;
}
@Override
public void updateFocusableWindowState() {
}
@Override
public boolean rejectFocusRequest(Cause cause) {
return false;
}
@Override
public boolean requestWindowFocus() {
return true;
}
@Override
public boolean isActive() {
return target.isParentWindowActive();
}
@Override
public void setResizable(boolean resizable) {
}
@Override
public void setSizeConstraints(int minW, int minH, int maxW, int maxH) {
}
@Override
public Graphics transformGraphics(Graphics g) {
return g;
}
@Override
public void updateIconImages() {
}
@Override
public void setOpacity(float opacity) {
}
@Override
public void setOpaque(boolean isOpaque) {
}
@Override
public void enterFullScreenMode() {
}
@Override
public void exitFullScreenMode() {
}
@Override
public void setWindowState(int windowState) {
}
@Override
public boolean isUnderMouse() {
return view.isUnderMouse();
}
}

View File

@ -85,6 +85,8 @@ public final class CWrapper {
public static native void enterFullScreenMode(long view);
public static native void exitFullScreenMode(long view);
public static native void setHidden(long view, boolean hidden);
}
public static final class NSObject {

View File

@ -156,10 +156,13 @@ public final class LWCToolkit extends LWToolkit {
@Override
protected PlatformWindow createPlatformWindow(PeerType peerType) {
if (peerType == PeerType.EMBEDDEDFRAME) {
if (peerType == PeerType.EMBEDDED_FRAME) {
return new CPlatformEmbeddedFrame();
} else if (peerType == PeerType.VIEW_EMBEDDED_FRAME) {
return new CViewPlatformEmbeddedFrame();
} else {
return new CPlatformWindow(peerType);
assert (peerType == PeerType.SIMPLEWINDOW || peerType == PeerType.DIALOG || peerType == PeerType.FRAME);
return new CPlatformWindow();
}
}

View File

@ -99,17 +99,16 @@ Java_sun_lwawt_macosx_CPlatformComponent_nativeCreateComponent
__block AWTSurfaceLayers *surfaceLayers = nil;
JNF_COCOA_ENTER(env);
AWT_ASSERT_NOT_APPKIT_THREAD;
[JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
AWT_ASSERT_APPKIT_THREAD;
CALayer *windowLayer = jlong_to_ptr(windowLayerPtr);
surfaceLayers = [[AWTSurfaceLayers alloc] initWithWindowLayer: windowLayer];
CFRetain(surfaceLayers);
[surfaceLayers release];
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
AWT_ASSERT_APPKIT_THREAD;
CALayer *windowLayer = jlong_to_ptr(windowLayerPtr);
surfaceLayers = [[AWTSurfaceLayers alloc] initWithWindowLayer: windowLayer];
CFRetain(surfaceLayers);
[surfaceLayers release];
}];
JNF_COCOA_EXIT(env);
return ptr_to_jlong(surfaceLayers);
@ -126,12 +125,13 @@ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformComponent_nativeSetBounds
JNF_COCOA_ENTER(env);
AWTSurfaceLayers *surfaceLayers = OBJC(surfaceLayersPtr);
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
AWT_ASSERT_APPKIT_THREAD;
CGRect rect = CGRectMake(x, y, width, height);
[surfaceLayers setBounds: rect];
}];
}];
JNF_COCOA_EXIT(env);
}

View File

@ -83,6 +83,7 @@ AWT_ASSERT_APPKIT_THREAD;
mouseIsOver = NO;
[self resetTrackingArea];
[self setAutoresizesSubviews:NO];
if (windowLayer != nil) {
self.cglLayer = windowLayer;
@ -174,6 +175,11 @@ AWT_ASSERT_APPKIT_THREAD;
* Automatically triggered functions.
*/
- (void)resizeWithOldSuperviewSize:(NSSize)oldBoundsSize {
[super resizeWithOldSuperviewSize: oldBoundsSize];
[self deliverResize: [self frame]];
}
/*
* MouseEvents support
*/
@ -437,6 +443,18 @@ AWT_ASSERT_APPKIT_THREAD;
}
}
-(void) deliverResize: (NSRect) rect {
jint x = (jint) rect.origin.x;
jint y = (jint) rect.origin.y;
jint w = (jint) rect.size.width;
jint h = (jint) rect.size.height;
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_CLASS_CACHE(jc_PlatformView, "sun/lwawt/macosx/CPlatformView");
static JNF_MEMBER_CACHE(jm_deliverResize, jc_PlatformView, "deliverResize", "(IIII)V");
JNFCallVoidMethod(env, m_cPlatformView, jm_deliverResize, x,y,w,h);
}
- (void) drawRect:(NSRect)dirtyRect {
AWT_ASSERT_APPKIT_THREAD;
@ -1220,21 +1238,19 @@ Java_sun_lwawt_macosx_CPlatformView_nativeCreateView
__block AWTView *newView = nil;
JNF_COCOA_ENTER(env);
AWT_ASSERT_NOT_APPKIT_THREAD;
NSRect rect = NSMakeRect(originX, originY, width, height);
jobject cPlatformView = (*env)->NewGlobalRef(env, obj);
[JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
AWT_ASSERT_APPKIT_THREAD;
CALayer *windowLayer = jlong_to_ptr(windowLayerPtr);
AWTView *view = [[AWTView alloc] initWithRect:rect
platformView:cPlatformView
windowLayer:windowLayer];
CFRetain(view);
[view release]; // GC
newView = view;
}];
@ -1242,3 +1258,125 @@ JNF_COCOA_EXIT(env);
return ptr_to_jlong(newView);
}
/*
* Class: sun_lwawt_macosx_CPlatformView
* Method: nativeSetAutoResizable
* Signature: (JZ)V;
*/
JNIEXPORT void JNICALL
Java_sun_lwawt_macosx_CPlatformView_nativeSetAutoResizable
(JNIEnv *env, jclass cls, jlong viewPtr, jboolean toResize)
{
JNF_COCOA_ENTER(env);
NSView *view = (NSView *)jlong_to_ptr(viewPtr);
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
AWT_ASSERT_APPKIT_THREAD;
if (toResize) {
[view setAutoresizingMask: NSViewHeightSizable | NSViewWidthSizable];
} else {
[view setAutoresizingMask: NSViewMinYMargin | NSViewMaxXMargin];
}
if ([view superview] != nil) {
[[view superview] setAutoresizesSubviews:(BOOL)toResize];
}
}];
JNF_COCOA_EXIT(env);
}
/*
* Class: sun_lwawt_macosx_CPlatformView
* Method: nativeGetNSViewDisplayID
* Signature: (J)I;
*/
JNIEXPORT jint JNICALL
Java_sun_lwawt_macosx_CPlatformView_nativeGetNSViewDisplayID
(JNIEnv *env, jclass cls, jlong viewPtr)
{
__block jint ret; //CGDirectDisplayID
JNF_COCOA_ENTER(env);
NSView *view = (NSView *)jlong_to_ptr(viewPtr);
NSWindow *window = [view window];
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
AWT_ASSERT_APPKIT_THREAD;
ret = (jint)[[AWTWindow getNSWindowDisplayID_AppKitThread: window] intValue];
}];
JNF_COCOA_EXIT(env);
return ret;
}
/*
* Class: sun_lwawt_macosx_CPlatformView
* Method: nativeGetLocationOnScreen
* Signature: (J)Ljava/awt/Rectangle;
*/
JNIEXPORT jobject JNICALL
Java_sun_lwawt_macosx_CPlatformView_nativeGetLocationOnScreen
(JNIEnv *env, jclass cls, jlong viewPtr)
{
jobject jRect = NULL;
JNF_COCOA_ENTER(env);
__block NSRect rect = NSZeroRect;
NSView *view = (NSView *)jlong_to_ptr(viewPtr);
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
AWT_ASSERT_APPKIT_THREAD;
NSRect viewBounds = [view bounds];
NSRect frameInWindow = [view convertRect:viewBounds toView:nil];
rect = [[view window] convertRectToScreen:frameInWindow];
NSRect screenRect = [[NSScreen mainScreen] frame];
//Convert coordinates to top-left corner origin
rect.origin.y = screenRect.size.height - rect.origin.y - viewBounds.size.height;
}];
jRect = NSToJavaRect(env, rect);
JNF_COCOA_EXIT(env);
return jRect;
}
/*
* Class: sun_lwawt_macosx_CPlatformView
* Method: nativeIsViewUnderMouse
* Signature: (J)Z;
*/
JNIEXPORT jboolean JNICALL Java_sun_lwawt_macosx_CPlatformView_nativeIsViewUnderMouse
(JNIEnv *env, jclass clazz, jlong viewPtr)
{
__block jboolean underMouse = JNI_FALSE;
JNF_COCOA_ENTER(env);
NSView *nsView = OBJC(viewPtr);
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
AWT_ASSERT_APPKIT_THREAD;
NSPoint ptWindowCoords = [[nsView window] mouseLocationOutsideOfEventStream];
NSPoint ptViewCoords = [nsView convertPoint:ptWindowCoords fromView:nil];
underMouse = [nsView hitTest:ptViewCoords] != nil;
}];
JNF_COCOA_EXIT(env);
return underMouse;
}

View File

@ -1154,34 +1154,6 @@ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSynthesizeMou
JNF_COCOA_EXIT(env);
}
/*
* Class: sun_lwawt_macosx_CPlatformWindow
* Method: nativeGetDisplayID_AppKitThread
* Signature: (J)I
*/
JNIEXPORT jint JNICALL
Java_sun_lwawt_macosx_CPlatformWindow_nativeGetNSWindowDisplayID
(JNIEnv *env, jclass clazz, jlong windowPtr)
{
__block jint ret; // CGDirectDisplayID
JNF_COCOA_ENTER(env);
NSWindow *window = OBJC(windowPtr);
if ([NSThread isMainThread]) {
ret = (jint)[[AWTWindow getNSWindowDisplayID_AppKitThread: window] intValue];
} else {
[JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
ret = (jint)[[AWTWindow getNSWindowDisplayID_AppKitThread: window] intValue];
}];
}
JNF_COCOA_EXIT(env);
return ret;
}
/*
* Class: sun_lwawt_macosx_CPlatformWindow
* Method: _toggleFullScreenMode
@ -1203,27 +1175,6 @@ JNF_COCOA_ENTER(env);
JNF_COCOA_EXIT(env);
}
JNIEXPORT jboolean JNICALL Java_sun_lwawt_macosx_CMouseInfoPeer_nativeIsWindowUnderMouse
(JNIEnv *env, jclass clazz, jlong windowPtr)
{
__block jboolean underMouse = JNI_FALSE;
JNF_COCOA_ENTER(env);
AWT_ASSERT_NOT_APPKIT_THREAD;
NSWindow *nsWindow = OBJC(windowPtr);
[JNFRunLoop performOnMainThreadWaiting:YES withBlock:^() {
AWT_ASSERT_APPKIT_THREAD;
NSPoint pt = [nsWindow mouseLocationOutsideOfEventStream];
underMouse = [[nsWindow contentView] hitTest:pt] != nil;
}];
JNF_COCOA_EXIT(env);
return underMouse;
}
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetEnabled
(JNIEnv *env, jclass clazz, jlong windowPtr, jboolean isEnabled)
{

View File

@ -123,14 +123,15 @@ Java_sun_lwawt_macosx_CCursorManager_nativeGetCursorPosition
jobject jpt = NULL;
JNF_COCOA_ENTER(env);
AWT_ASSERT_NOT_APPKIT_THREAD;
__block NSPoint pt = NSZeroPoint;
[JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
AWT_ASSERT_APPKIT_THREAD;
pt = ConvertNSScreenPoint(env, [NSEvent mouseLocation]);
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
AWT_ASSERT_APPKIT_THREAD;
pt = ConvertNSScreenPoint(env, [NSEvent mouseLocation]);
}];
jpt = NSToJavaPoint(env, pt);
JNF_COCOA_EXIT(env);

View File

@ -650,6 +650,26 @@ JNF_COCOA_EXIT(env);
return windowPtr;
}
/*
* Class: sun_lwawt_macosx_CWrapper$NSView
* Method: setHidden
* Signature: (JZ)V
*/
JNIEXPORT jlong JNICALL
Java_sun_lwawt_macosx_CWrapper_00024NSView_setHidden
(JNIEnv *env, jclass cls, jlong viewPtr, jboolean toHide)
{
JNF_COCOA_ENTER(env);
NSView *view = (NSView *)jlong_to_ptr(viewPtr);
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
[view setHidden:(BOOL)toHide];
}];
JNF_COCOA_EXIT(env);
}
/*
* Class: sun_lwawt_macosx_CWrapper$NSScreen
* Method: frame

View File

@ -95,7 +95,7 @@ AWT_ASSERT_APPKIT_THREAD;
CFRelease(busyObserver);
CFRelease(notBusyObserver);
if (!headless) setBusy(YES);
// Set the java name of the AppKit main thread appropriately.
@ -367,7 +367,8 @@ AWT_ASSERT_APPKIT_THREAD;
CFRunLoopRef runLoop = [[NSRunLoop currentRunLoop] getCFRunLoop];
CFRunLoopRemoveObserver(runLoop, busyObserver, kCFRunLoopDefaultMode);
CFRunLoopRemoveObserver(runLoop, notBusyObserver, kCFRunLoopDefaultMode);
// We don't track if the runloop is busy, so set it free to let AWT finish when it needs
setBusy(NO);
busyObserver = NULL;
notBusyObserver = NULL;
} else {

View File

@ -151,16 +151,15 @@ Java_sun_java2d_opengl_CGLLayer_nativeCreateLayer
__block CGLLayer *layer = nil;
JNF_COCOA_ENTER(env);
AWT_ASSERT_NOT_APPKIT_THREAD;
JNFJObjectWrapper *javaLayer = [JNFJObjectWrapper wrapperWithJObject:obj withEnv:env];
[JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
AWT_ASSERT_APPKIT_THREAD;
layer = [[CGLLayer alloc] initWithJavaLayer: javaLayer];
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
AWT_ASSERT_APPKIT_THREAD;
layer = [[CGLLayer alloc] initWithJavaLayer: javaLayer];
}];
JNF_COCOA_EXIT(env);
return ptr_to_jlong(layer);

View File

@ -139,7 +139,7 @@ __attribute__((visibility("default")))
+ (JNIEnv*)getJNIEnvUncached;
+ (void)performOnMainThread:(SEL)aSelector onObject:(id)target withObject:(id)arg waitUntilDone:(BOOL)wait awtMode:(BOOL)inAWT;
+ (void)performOnMainThreadWaiting:(BOOL)wait block:(void (^)())block;
@end
void OSXAPP_SetJavaVM(JavaVM *vm);

View File

@ -245,6 +245,14 @@ AWT_ASSERT_APPKIT_THREAD;
}
}
+ (void)performOnMainThreadWaiting:(BOOL)wait block:(void (^)())block {
if ([NSThread isMainThread] && wait == YES) {
block();
} else {
[JNFRunLoop performOnMainThreadWaiting:wait withBlock:block];
}
}
@end