diff options
author | Sven Gothel <[email protected]> | 2011-10-12 11:04:33 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2011-10-12 11:04:33 +0200 |
commit | 7b8e2ef59e08f288adc68f12a3e066476c86de52 (patch) | |
tree | ad88893da683549cb807c824dfb2f0c5c0176120 /src/newt/native | |
parent | 4d0c6cfe9abd8036c00e09e280605d7c5acbbf93 (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.m | 82 | ||||
-rw-r--r-- | src/newt/native/NewtMacWindow.h | 5 | ||||
-rw-r--r-- | src/newt/native/NewtMacWindow.m | 56 |
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); |