aboutsummaryrefslogtreecommitdiffstats
path: root/src/newt/native
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2011-10-12 11:04:33 +0200
committerSven Gothel <[email protected]>2011-10-12 11:04:33 +0200
commit7b8e2ef59e08f288adc68f12a3e066476c86de52 (patch)
treead88893da683549cb807c824dfb2f0c5c0176120 /src/newt/native
parent4d0c6cfe9abd8036c00e09e280605d7c5acbbf93 (diff)
Newt/OSX: Fix top/child positioning, positionChanged(), rely on native pos/size notifications
Newt/MacWindow - remove redundant manual window-move/set-size code - Use local getLocationOnScreen(..), fixes positionChanged(..) - setFrameTopLeftPoint(..) use totalHeight (w/ insets) - create: don't 'retain' the window reference (ref counter) - close: release view, - cache insets - to be used @ create
Diffstat (limited to 'src/newt/native')
-rw-r--r--src/newt/native/MacWindow.m82
-rw-r--r--src/newt/native/NewtMacWindow.h5
-rw-r--r--src/newt/native/NewtMacWindow.m56
3 files changed, 111 insertions, 32 deletions
diff --git a/src/newt/native/MacWindow.m b/src/newt/native/MacWindow.m
index d8839abe0..f480103f2 100644
--- a/src/newt/native/MacWindow.m
+++ b/src/newt/native/MacWindow.m
@@ -43,6 +43,12 @@
#import <stdio.h>
+static const char * const ClazzNamePoint = "javax/media/nativewindow/util/Point";
+static const char * const ClazzAnyCstrName = "<init>";
+static const char * const ClazzNamePointCstrSignature = "(II)V";
+static jclass pointClz = NULL;
+static jmethodID pointCstr = NULL;
+
static NSString* jstringToNSString(JNIEnv* env, jstring jstr)
{
const jchar* jstrChars = (*env)->GetStringChars(env, jstr, NULL);
@@ -51,17 +57,21 @@ static NSString* jstringToNSString(JNIEnv* env, jstring jstr)
return str;
}
-static void setFrameTopLeftPoint(NSWindow* pWin, NSWindow* mWin, jint x, jint y, jint w, jint h) {
+static void setFrameTopLeftPoint(NSWindow* pWin, NSWindow* mWin, jint x, jint y, jint totalHeight) {
NSScreen* screen = [NSScreen mainScreen];
- NSRect screenRect = [screen frame];
- NSPoint pS = NSMakePoint(screenRect.origin.x + x, screenRect.origin.y + screenRect.size.height - y - h);
+ NSRect screenTotal = [screen frame];
- DBG_PRINT( "setFrameTopLeftPoint screen %lf/%lf %lfx%lf, win top-left %d/%d -> scrn bottom-left %lf/%lf\n",
- screenRect.origin.x, screenRect.origin.y, screenRect.size.width, screenRect.size.height,
- (int)x, (int)y, pS.x, pS.y);
+ NSPoint pS = NSMakePoint(screenTotal.origin.x + x, screenTotal.origin.y + screenTotal.size.height - y - totalHeight);
#ifdef VERBOSE_ON
+ NSMenu * menu = [NSApp mainMenu];
+ int menuHeight = [NSMenu menuBarVisible] ? (int) [menu menuBarHeight] : 0;
+
+ DBG_PRINT( "setFrameTopLeftPoint screen %lf/%lf %lfx%lf, menuHeight %d, win top-left %d/%d totalHeight %d -> scrn bottom-left %lf/%lf\n",
+ screenTotal.origin.x, screenTotal.origin.y, screenTotal.size.width, screenTotal.size.height, menuHeight,
+ (int)x, (int)y, (int)totalHeight, pS.x, pS.y);
+
if(NULL != pWin) {
NSView* pView = [pWin contentView];
NSRect pViewFrame = [pView frame];
@@ -241,6 +251,22 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_MacWindow_initIDs0
if(initialized) return JNI_TRUE;
initialized = 1;
+ jclass c;
+ c = (*env)->FindClass(env, ClazzNamePoint);
+ if(NULL==c) {
+ NewtCommon_FatalError(env, "FatalError Java_jogamp_newt_driver_macosx_MacWindow_initIDs0: can't find %s", ClazzNamePoint);
+ }
+ pointClz = (jclass)(*env)->NewGlobalRef(env, c);
+ (*env)->DeleteLocalRef(env, c);
+ if(NULL==pointClz) {
+ NewtCommon_FatalError(env, "FatalError Java_jogamp_newt_driver_macosx_MacWindow_initIDs0: can't use %s", ClazzNamePoint);
+ }
+ pointCstr = (*env)->GetMethodID(env, pointClz, ClazzAnyCstrName, ClazzNamePointCstrSignature);
+ if(NULL==pointCstr) {
+ NewtCommon_FatalError(env, "FatalError Java_jogamp_newt_driver_macosx_MacWindow_initIDs0: can't fetch %s.%s %s",
+ ClazzNamePoint, ClazzAnyCstrName, ClazzNamePointCstrSignature);
+ }
+
// Need this when debugging, as it is necessary to attach gdb to
// the running java process -- "gdb java" doesn't work
// printf("Going to sleep for 10 seconds\n");
@@ -283,10 +309,12 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_MacWindow_createWindow0
}
// Allocate the window
- NSWindow* myWindow = [[[NewtMacWindow alloc] initWithContentRect: rect
+ NewtMacWindow* myWindow = [[NewtMacWindow alloc] initWithContentRect: rect
styleMask: (NSUInteger) styleMask
backing: (NSBackingStoreType) bufferingType
- defer: NO screen: myScreen] retain];
+ defer: NO
+ screen: myScreen];
+ [myWindow setReleasedWhenClosed: YES]; // default
NSObject *nsParentObj = (NSObject*) ((intptr_t) parent);
NSWindow* parentWindow = NULL;
@@ -327,7 +355,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_MacWindow_createWindow0
(void) changeContentView(env, jthis, parentWindow, parentView, myWindow, myView);
// Immediately re-position the window based on an upper-left coordinate system
- setFrameTopLeftPoint(parentWindow, myWindow, x, y, w, h);
+ setFrameTopLeftPoint(parentWindow, myWindow, x, y, h+myWindow->cachedInsets[2]+myWindow->cachedInsets[3]); // h+insets[top+bottom]
NS_DURING
// Available >= 10.5 - Makes the menubar disapear
@@ -429,13 +457,15 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_close0
NSWindow* mWin = (NSWindow*) ((intptr_t) window);
NSView* mView = [mWin contentView];
NSWindow* pWin = [mWin parentWindow];
- DBG_PRINT( "*************** windowClose.0: %p (parent %p)\n", mWin, pWin);
+ DBG_PRINT( "*************** windowClose.0: %p (view %p, parent %p)\n", mWin, mView, pWin);
NS_DURING
if(NULL!=mView) {
// Available >= 10.5 - Makes the menubar disapear
if([mView isInFullScreenMode]) {
[mView exitFullScreenModeWithOptions: NULL];
}
+ [mWin setContentView: nil];
+ [mView release];
}
NS_HANDLER
NS_ENDHANDLER
@@ -445,10 +475,12 @@ NS_ENDHANDLER
[pWin removeChildWindow: mWin];
}
[mWin orderOut: mWin];
- [mWin performSelectorOnMainThread:@selector(close:) withObject:nil waitUntilDone:NO];
- // [mWin close]
+
+ // [mWin performSelectorOnMainThread:@selector(close:) withObject:nil waitUntilDone:NO];
+ [mWin close]; // performs release!
DBG_PRINT( "*************** windowClose.X: %p (parent %p)\n", mWin, pWin);
+
[pool release];
}
@@ -560,7 +592,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_setContentSize0
* Signature: (JJII)V
*/
JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_setFrameTopLeftPoint0
- (JNIEnv *env, jobject unused, jlong parent, jlong window, jint x, jint y, jint w, jint h)
+ (JNIEnv *env, jobject unused, jlong parent, jlong window, jint x, jint y, jint totalHeight)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSWindow* mWin = (NSWindow*) ((intptr_t) window);
@@ -576,7 +608,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_setFrameTopLeftP
DBG_PRINT( "setFrameTopLeftPoint0 - window: %p, parent %p (START)\n", mWin, pWin);
- setFrameTopLeftPoint(pWin, mWin, x, y, w, h);
+ setFrameTopLeftPoint(pWin, mWin, x, y, totalHeight);
DBG_PRINT( "setFrameTopLeftPoint0 - window: %p, parent %p (END)\n", mWin, pWin);
@@ -607,3 +639,25 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_setAlwaysOnTop0
[pool release];
}
+/*
+ * Class: jogamp_newt_driver_macosx_MacWindow
+ * Method: getLocationOnScreen0
+ * Signature: (JII)Ljavax/media/nativewindow/util/Point;
+ */
+JNIEXPORT jobject JNICALL Java_jogamp_newt_driver_macosx_MacWindow_getLocationOnScreen0
+ (JNIEnv *env, jclass unused, jlong win, jint src_x, jint src_y)
+{
+ NSObject *nsObj = (NSObject*) ((intptr_t) win);
+ NewtMacWindow * mWin = NULL;
+
+ if( [nsObj isKindOfClass:[NewtMacWindow class]] ) {
+ mWin = (NewtMacWindow*) nsObj;
+ } else {
+ NewtCommon_throwNewRuntimeException(env, "not NewtMacWindow %p\n", nsObj);
+ }
+
+ NSPoint p0 = { src_x, src_y };
+ p0 = [mWin getLocationOnScreen: p0];
+ return (*env)->NewObject(env, pointClz, pointCstr, (jint)p0.x, (jint)p0.y);
+}
+
diff --git a/src/newt/native/NewtMacWindow.h b/src/newt/native/NewtMacWindow.h
index a8931d6fc..911abb8aa 100644
--- a/src/newt/native/NewtMacWindow.h
+++ b/src/newt/native/NewtMacWindow.h
@@ -79,15 +79,20 @@
@interface NewtMacWindow : NSWindow
#endif
{
+@public
+ int cachedInsets[4]; // l, r, t, b
}
+ (BOOL) initNatives: (JNIEnv*) env forClass: (jobject) clazz;
+- (NSPoint) getLocationOnScreen: (NSPoint) p;
+
- (void) updateInsets: (JNIEnv*) env;
- (id) initWithContentRect: (NSRect) contentRect
styleMask: (NSUInteger) windowStyle
backing: (NSBackingStoreType) bufferingType
+ defer: (BOOL) deferCreation
screen:(NSScreen *)screen;
@end
diff --git a/src/newt/native/NewtMacWindow.m b/src/newt/native/NewtMacWindow.m
index eb1426dc2..a44914c97 100644
--- a/src/newt/native/NewtMacWindow.m
+++ b/src/newt/native/NewtMacWindow.m
@@ -197,6 +197,29 @@ static jmethodID windowDestroyNotifyID = NULL;
return NO;
}
+- (NSPoint) getLocationOnScreen: (NSPoint) p
+{
+ /**
+ * return location in 0/0 top-left space,
+ * OSX is 0/0 bottom-left space naturally
+ */
+ NSScreen* screen = [self screen];
+ NSRect screenRect = [screen frame];
+
+ NSView* view = [self contentView];
+ NSRect viewFrame = [view frame];
+
+ NSRect r;
+ r.origin.x = p.x;
+ r.origin.y = viewFrame.size.height - p.y; // y-flip for 0/0 top-left
+ r.size.width = 0;
+ r.size.height = 0;
+ // NSRect rS = [win convertRectToScreen: r]; // 10.7
+ NSPoint oS = [self convertBaseToScreen: r.origin];
+ oS.y = screenRect.origin.y + screenRect.size.height - oS.y;
+ return oS;
+}
+
- (void) updateInsets: (JNIEnv*) env
{
NSView* nsview = [self contentView];
@@ -215,29 +238,34 @@ static jmethodID windowDestroyNotifyID = NULL;
// note: this is a simplistic implementation which doesn't take
// into account DPI and scaling factor
CGFloat l = contentRect.origin.x - frameRect.origin.x;
- jint top = (jint)(frameRect.size.height - contentRect.size.height);
- jint left = (jint)l;
- jint bottom = (jint)(contentRect.origin.y - frameRect.origin.y);
- jint right = (jint)(frameRect.size.width - (contentRect.size.width + l));
+ cachedInsets[0] = (int)l; // l
+ cachedInsets[1] = (int)(frameRect.size.width - (contentRect.size.width + l)); // r
+ cachedInsets[2] = (jint)(frameRect.size.height - contentRect.size.height); // t
+ cachedInsets[3] = (jint)(contentRect.origin.y - frameRect.origin.y); // b
- DBG_PRINT( "updateInsets: [ l %d, r %d, t %d, b %d ]\n", (int)left, (int)right, (int)top, (int)bottom);
+ DBG_PRINT( "updateInsets: [ l %d, r %d, t %d, b %d ]\n", cachedInsets[0], cachedInsets[1], cachedInsets[2], cachedInsets[3]);
- (*env)->CallVoidMethod(env, javaWindowObject, insetsChangedID, JNI_TRUE, left, right, top, bottom);
+ (*env)->CallVoidMethod(env, javaWindowObject, insetsChangedID, JNI_TRUE, cachedInsets[0], cachedInsets[1], cachedInsets[2], cachedInsets[3]);
}
- (id) initWithContentRect: (NSRect) contentRect
styleMask: (NSUInteger) windowStyle
backing: (NSBackingStoreType) bufferingType
+ defer: (BOOL) deferCreation
screen:(NSScreen *)screen
{
id res = [super initWithContentRect: contentRect
styleMask: windowStyle
backing: bufferingType
- defer: YES
+ defer: deferCreation
screen: screen];
// Why is this necessary? Without it we don't get any of the
// delegate methods like resizing and window movement.
[self setDelegate: self];
+ cachedInsets[0] = 0; // l
+ cachedInsets[1] = 0; // r
+ cachedInsets[2] = 0; // t
+ cachedInsets[3] = 0; // b
return res;
}
@@ -517,17 +545,9 @@ static jint mods2JavaMods(NSUInteger mods)
return;
}
- NSRect rect = [self frame];
- NSScreen* screen = NULL;
- NSRect screenRect;
- NSPoint pt;
-
- screen = [self screen];
- // this allows for better compatibility with awt behavior
- screenRect = [screen frame];
- pt = NSMakePoint(rect.origin.x, screenRect.origin.y + screenRect.size.height - rect.origin.y - rect.size.height);
-
- (*env)->CallVoidMethod(env, javaWindowObject, positionChangedID, JNI_TRUE, (jint) pt.x, (jint) pt.y);
+ NSPoint p0 = { 0, 0 };
+ p0 = [self getLocationOnScreen: p0];
+ (*env)->CallVoidMethod(env, javaWindowObject, positionChangedID, JNI_TRUE, (jint) p0.x, (jint) p0.y);
if (shallBeDetached) {
(*jvmHandle)->DetachCurrentThread(jvmHandle);