Fix OS X CALayer positioning and workaround Java 7 bug
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7172187
This commit is contained in:
parent
5628e751bf
commit
f528f38c60
|
@ -32,6 +32,11 @@
|
|||
package org.lwjgl.opengl;
|
||||
|
||||
import java.awt.Canvas;
|
||||
import java.awt.event.ComponentEvent;
|
||||
import java.awt.event.ComponentListener;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Container;
|
||||
import java.awt.Component;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.lwjgl.LWJGLException;
|
||||
|
@ -62,11 +67,85 @@ abstract class MacOSXCanvasPeerInfo extends MacOSXPeerInfo {
|
|||
forceCALayer = false;
|
||||
}
|
||||
|
||||
window_handle = nInitHandle(awt_surface.lockAndGetHandle(component), getHandle(), window_handle, forceCALayer);
|
||||
Insets insets = getInsets(component);
|
||||
|
||||
int top = insets != null ? insets.top : 0;
|
||||
int left = insets != null ? insets.left : 0;
|
||||
|
||||
window_handle = nInitHandle(awt_surface.lockAndGetHandle(component), getHandle(), window_handle, forceCALayer, component.getX()-left, component.getY()-top);
|
||||
|
||||
if (javaVersion.startsWith("1.7")) {
|
||||
// fix for CALayer position not covering Canvas due to a Java 7 bug
|
||||
// http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7172187
|
||||
addComponentListener(component);
|
||||
}
|
||||
}
|
||||
private static native ByteBuffer nInitHandle(ByteBuffer surface_buffer, ByteBuffer peer_info_handle, ByteBuffer window_handle, boolean forceCALayer) throws LWJGLException;
|
||||
|
||||
private void addComponentListener(final Canvas component) {
|
||||
|
||||
ComponentListener[] components = component.getComponentListeners();
|
||||
|
||||
// avoid adding duplicate listners by checking if one has already been added
|
||||
for (int i = 0; i < components.length; i++) {
|
||||
ComponentListener c = components[i];
|
||||
if (c.toString() == "CanvasPeerInfoListener") {
|
||||
return; // already contains the listner below return without adding
|
||||
}
|
||||
}
|
||||
|
||||
ComponentListener comp = new ComponentListener() {
|
||||
public void componentHidden(ComponentEvent e) {
|
||||
|
||||
}
|
||||
|
||||
public void componentMoved(ComponentEvent e) {
|
||||
Insets insets = getInsets(component);
|
||||
|
||||
int top = insets != null ? insets.top : 0;
|
||||
int left = insets != null ? insets.left : 0;
|
||||
|
||||
nSetLayerPosition(getHandle(), component.getX()-left, component.getY()-top);
|
||||
}
|
||||
|
||||
public void componentResized(ComponentEvent e) {
|
||||
Insets insets = getInsets(component);
|
||||
|
||||
int top = insets != null ? insets.top : 0;
|
||||
int left = insets != null ? insets.left : 0;
|
||||
|
||||
nSetLayerPosition(getHandle(), component.getX()-left, component.getY()-top);
|
||||
}
|
||||
|
||||
public void componentShown(ComponentEvent e) {
|
||||
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "CanvasPeerInfoListener";
|
||||
}
|
||||
};
|
||||
|
||||
component.addComponentListener(comp);
|
||||
}
|
||||
|
||||
private static native ByteBuffer nInitHandle(ByteBuffer surface_buffer, ByteBuffer peer_info_handle, ByteBuffer window_handle, boolean forceCALayer, int x, int y) throws LWJGLException;
|
||||
|
||||
private static native void nSetLayerPosition(ByteBuffer peer_info_handle, int x, int y);
|
||||
|
||||
protected void doUnlock() throws LWJGLException {
|
||||
awt_surface.unlock();
|
||||
}
|
||||
|
||||
private Insets getInsets(Canvas component) {
|
||||
Component parent = component.getParent();
|
||||
|
||||
while (parent != null) {
|
||||
if (parent instanceof Container) {
|
||||
return ((Container)parent).getInsets();
|
||||
}
|
||||
parent = parent.getParent();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
#include "common_tools.h"
|
||||
|
||||
JNIEXPORT jobject JNICALL Java_org_lwjgl_opengl_MacOSXCanvasPeerInfo_nInitHandle
|
||||
(JNIEnv *env, jclass clazz, jobject lock_buffer_handle, jobject peer_info_handle, jobject window_handle, jboolean forceCALayer) {
|
||||
(JNIEnv *env, jclass clazz, jobject lock_buffer_handle, jobject peer_info_handle, jobject window_handle, jboolean forceCALayer, jint x, jint y) {
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
MacOSXPeerInfo *peer_info = (MacOSXPeerInfo *)(*env)->GetDirectBufferAddress(env, peer_info_handle);
|
||||
|
@ -78,6 +78,9 @@ JNIEXPORT jobject JNICALL Java_org_lwjgl_opengl_MacOSXCanvasPeerInfo_nInitHandle
|
|||
peer_info->glLayer->canvasBounds = (JAWT_Rectangle)surface->dsi->bounds;
|
||||
peer_info->window_info = (MacOSXWindowInfo *)(*env)->GetDirectBufferAddress(env, window_handle);
|
||||
peer_info->glLayer->window_info = peer_info->window_info;
|
||||
|
||||
// ensure the CALayer size is correct, needed for Java 7+
|
||||
peer_info->glLayer.frame = CGRectMake(x, y, peer_info->glLayer->canvasBounds.width, peer_info->glLayer->canvasBounds.height);
|
||||
|
||||
[peer_info->glLayer performSelectorOnMainThread:@selector(createWindow:) withObject:peer_info->pixel_format waitUntilDone:YES];
|
||||
|
||||
|
@ -99,6 +102,17 @@ JNIEXPORT jobject JNICALL Java_org_lwjgl_opengl_MacOSXCanvasPeerInfo_nInitHandle
|
|||
return NULL;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_MacOSXCanvasPeerInfo_nSetLayerPosition
|
||||
(JNIEnv *env, jclass clazz, jobject peer_info_handle, jint x, jint y) {
|
||||
MacOSXPeerInfo *peer_info = (MacOSXPeerInfo *)(*env)->GetDirectBufferAddress(env, peer_info_handle);
|
||||
|
||||
if (peer_info->glLayer != nil) {
|
||||
NSPoint point = NSMakePoint(x, y);
|
||||
NSValue *value = [NSValue valueWithPoint:point];
|
||||
[peer_info->glLayer performSelectorOnMainThread:@selector(updatePosition:) withObject:value waitUntilDone:NO];
|
||||
}
|
||||
}
|
||||
|
||||
@implementation GLLayer
|
||||
|
||||
- (void) attachLayer {
|
||||
|
@ -113,8 +127,10 @@ JNIEXPORT jobject JNICALL Java_org_lwjgl_opengl_MacOSXCanvasPeerInfo_nInitHandle
|
|||
if (surfaceLayers.layer != self) {
|
||||
surfaceLayers.layer = self;
|
||||
|
||||
// ensure the CALayer size is correct, needed for Java 7+
|
||||
self.frame = CGRectMake(0, 0, [self getWidth], [self getHeight]);
|
||||
// flip CALayer y position, needed for Java 7 workaround
|
||||
self.frame = CGRectMake(self.frame.origin.x,
|
||||
self.superlayer.bounds.size.height - self.frame.origin.y - self.frame.size.height,
|
||||
self.frame.size.width, self.frame.size.height);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -135,9 +151,9 @@ JNIEXPORT jobject JNICALL Java_org_lwjgl_opengl_MacOSXCanvasPeerInfo_nInitHandle
|
|||
[self removeFromSuperlayer];
|
||||
}
|
||||
|
||||
- (void)setNeedsLayout {
|
||||
// make sure the CALayer remains in bottom corner during resize
|
||||
self.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
|
||||
- (void)updatePosition:(NSValue*)value {
|
||||
NSPoint point = [value pointValue];
|
||||
self.position = CGPointMake(point.x, self.superlayer.bounds.size.height - point.y - self.bounds.size.height);
|
||||
}
|
||||
|
||||
- (int) getWidth {
|
||||
|
|
Loading…
Reference in New Issue