diff options
author | Sven Gothel <[email protected]> | 2011-10-20 20:52:46 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2011-10-20 20:52:46 +0200 |
commit | 627083adaf1b38c17f42c72650c47103f17313ce (patch) | |
tree | 01d9651be896fb17e9e050856d976089e9cb4e9a /src/newt/native | |
parent | e9890fee4c2aa296aff2af5ff555908c6362fc5f (diff) |
NEWT/OSX: Attempt to stabilize native parenting (ie w/ AWT) ; Add windowRepaint() callback
- act on positionChanged(..) only for realized windows,
otherwise we could end in an AWT deadlock (AWT parent window).
- add view parenting calls (addSubView/removeFromSuperview)
- attachToParent after view configuration
- allow concurrently view draw
- add windowRepaint() callback (native -> java)
- add more debug tracing
Diffstat (limited to 'src/newt/native')
-rw-r--r-- | src/newt/native/MacWindow.m | 130 | ||||
-rw-r--r-- | src/newt/native/NewtMacWindow.h | 22 | ||||
-rw-r--r-- | src/newt/native/NewtMacWindow.m | 97 |
3 files changed, 161 insertions, 88 deletions
diff --git a/src/newt/native/MacWindow.m b/src/newt/native/MacWindow.m index 6564fe430..b59429ffd 100644 --- a/src/newt/native/MacWindow.m +++ b/src/newt/native/MacWindow.m @@ -66,9 +66,12 @@ static void setFrameTopLeftPoint(NSWindow* pWin, NewtMacWindow* mWin, jint x, ji [mWin invalidateCursorRectsForView: mView]; } -static NewtView * changeContentView(JNIEnv *env, jobject javaWindowObject, NSWindow *pwin, NSView *pview, NSWindow *win, NewtView *newView) { +static NewtView * changeContentView(JNIEnv *env, jobject javaWindowObject, NSWindow *pwin, NSView *pview, NewtMacWindow *win, NewtView *newView) { NSView* oldNSView = [win contentView]; NewtView* oldView = NULL; + int dbgIdx = 1; + + DBG_PRINT( "changeContentView.%d win %p, view %p, parent[win %p, view %p]\n", dbgIdx++, win, newView, pwin, pview); if(NULL!=oldNSView) { NS_DURING @@ -86,11 +89,13 @@ NS_ENDHANDLER [oldView setJavaWindowObject: NULL]; [oldView setDestroyNotifySent: false]; } - /** FIXME: Tried child window: auto clip or message reception .. if(NULL!=pwin) { [oldView removeFromSuperview]; - } */ + } } + DBG_PRINT( "changeContentView.%d isHidden %d, isHiddenOrHasHiddenAncestor: %d\n", dbgIdx++, + [newView isHidden], [newView isHiddenOrHasHiddenAncestor]); + if(NULL!=newView) { jobject globJavaWindowObject = (*env)->NewGlobalRef(env, javaWindowObject); [newView setJavaWindowObject: globJavaWindowObject]; @@ -108,16 +113,21 @@ NS_ENDHANDLER [newView setJVMVersion: jvmVersion]; } - /** FIXME: Tried child window: auto clip or message reception .. + DBG_PRINT( "changeContentView.%d\n", dbgIdx++); + if(NULL!=pwin) { [pview addSubview: newView positioned: NSWindowAbove relativeTo: nil]; - } */ + } } + DBG_PRINT( "changeContentView.%d isHidden %d, isHiddenOrHasHiddenAncestor: %d\n", dbgIdx++, + [newView isHidden], [newView isHiddenOrHasHiddenAncestor]); + [win setContentView: newView]; + DBG_PRINT( "changeContentView.%d\n", dbgIdx++); // make sure the insets are updated in the java object - NewtMacWindow* newtw = (NewtMacWindow*)win; - [newtw updateInsets: env]; + [win updateInsets: env]; + DBG_PRINT( "changeContentView.%d\n", dbgIdx++); return oldView; } @@ -313,16 +323,16 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_MacWindow_createWindow0 } else { DBG_PRINT( "createWindow0 - Parent is neither NSWindow nor NSView : %p\n", nsParentObj); } - if(NULL!=parentWindow) { - [parentWindow addChildWindow: myWindow ordered: NSWindowAbove]; - [myWindow setParentWindow: parentWindow]; - } + DBG_PRINT( "createWindow0 - is visible.1: %d\n", [myWindow isVisible]); + int dbgIdx = 1; if(opaque) { [myWindow setOpaque: YES]; + DBG_PRINT( "createWindow0.%d\n", dbgIdx++); if (!fullscreen) { [myWindow setShowsResizeIndicator: YES]; } + DBG_PRINT( "createWindow0.%d\n", dbgIdx++); } else { [myWindow setOpaque: NO]; [myWindow setBackgroundColor: [NSColor clearColor]]; @@ -330,22 +340,37 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_MacWindow_createWindow0 // specify we want mouse-moved events [myWindow setAcceptsMouseMovedEvents:YES]; + DBG_PRINT( "createWindow0.%d\n", dbgIdx++); // Use given NewtView or allocate an NewtView if NULL if(NULL == myView) { myView = [[NewtView alloc] initWithFrame: rect] ; DBG_PRINT( "createWindow0 - new own view: %p\n", myView); + } else { + DBG_PRINT( "createWindow0 - use given view: %p\n", myView); } + DBG_PRINT( "createWindow0 - is visible.%d: %d\n", dbgIdx++, [myWindow isVisible]); + // Set the content view (void) changeContentView(env, jthis, parentWindow, parentView, myWindow, myView); + DBG_PRINT( "createWindow0.%d\n", dbgIdx++); + + if(NULL!=parentWindow) { + [myWindow attachToParent: parentWindow]; + } + // Immediately re-position the window based on an upper-left coordinate system setFrameTopLeftPoint(parentWindow, myWindow, x, y); - // force surface creation - [myView lockFocus]; - [myView unlockFocus]; + // force surface creation (causes an AWT parent to fail .. some times) + // [myView lockFocus]; + // [myView unlockFocus]; + + // concurrent view rendering + [myWindow setAllowsConcurrentViewDrawing: YES]; + [myView setCanDrawConcurrently: YES]; // visible on front [myWindow orderFront: myWindow]; @@ -371,6 +396,43 @@ NS_ENDHANDLER } /* + * Class: jogamp_newt_driver_macosx_MacWindow + * Method: close0 + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_close0 + (JNIEnv *env, jobject unused, jlong window) +{ + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + NSWindow* mWin = (NSWindow*) ((intptr_t) window); + NSView* mView = [mWin contentView]; + NSWindow* pWin = [mWin parentWindow]; + 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 + + if(NULL!=pWin) { + [mWin detachFromParent: pWin]; + } + [mWin orderOut: mWin]; + + [mWin close]; // performs release! + + DBG_PRINT( "*************** windowClose.X: %p (parent %p)\n", mWin, pWin); + + [pool release]; +} + +/* * Class: Java_jogamp_newt_driver_macosx_MacWindow * Method: lockSurface0 * Signature: (J)Z @@ -475,44 +537,6 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_orderOut0 /* * Class: jogamp_newt_driver_macosx_MacWindow - * Method: close0 - * Signature: (J)V - */ -JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_close0 - (JNIEnv *env, jobject unused, jlong window) -{ - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - NSWindow* mWin = (NSWindow*) ((intptr_t) window); - NSView* mView = [mWin contentView]; - NSWindow* pWin = [mWin parentWindow]; - 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 - - if(NULL!=pWin) { - [mWin setParentWindow: nil]; - [pWin removeChildWindow: mWin]; - } - [mWin orderOut: mWin]; - - [mWin close]; // performs release! - - DBG_PRINT( "*************** windowClose.X: %p (parent %p)\n", mWin, pWin); - - [pool release]; -} - -/* - * Class: jogamp_newt_driver_macosx_MacWindow * Method: setTitle0 * Signature: (JLjava/lang/String;)V */ @@ -564,7 +588,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_MacWindow_changeContentVi { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - NSWindow* win = (NewtMacWindow*) ((intptr_t) window); + NewtMacWindow* win = (NewtMacWindow*) ((intptr_t) window); NewtView* newView = (NewtView *) ((intptr_t) jview); DBG_PRINT( "changeContentView0 - window: %p (START)\n", win); diff --git a/src/newt/native/NewtMacWindow.h b/src/newt/native/NewtMacWindow.h index 648b68275..e649fdb13 100644 --- a/src/newt/native/NewtMacWindow.h +++ b/src/newt/native/NewtMacWindow.h @@ -80,6 +80,10 @@ - (void) rightMouseDown: (NSEvent*) theEvent; - (void) resetCursorRects; +- (void) viewWillDraw; +- (void) drawRect:(NSRect)dirtyRect; +- (void) viewDidHide; +- (void) viewDidUnhide; - (BOOL) acceptsFirstResponder; @end @@ -101,6 +105,16 @@ + (BOOL) initNatives: (JNIEnv*) env forClass: (jobject) clazz; +- (id) initWithContentRect: (NSRect) contentRect + styleMask: (NSUInteger) windowStyle + backing: (NSBackingStoreType) bufferingType + defer: (BOOL) deferCreation + screen:(NSScreen *)screen; + +- (void) updateInsets: (JNIEnv*) env; +- (void) attachToParent: (NSWindow*) parent; +- (void) detachFromParent: (NSWindow*) parent; + - (NSPoint) newtScreenWinPos2OSXScreenPos: (NSPoint) p; - (NSPoint) newtClientWinPos2OSXScreenPos: (NSPoint) p; - (NSPoint) getLocationOnScreen: (NSPoint) p; @@ -111,8 +125,6 @@ - (void) setMouseConfined:(BOOL)v; - (void) setMousePosition:(NSPoint)p; -- (void) updateInsets: (JNIEnv*) env; - - (BOOL) becomeFirstResponder; - (BOOL) resignFirstResponder; - (void) becomeKeyWindow; @@ -122,10 +134,4 @@ - (void) windowDidResignKey: (NSNotification *) notification; - (void) sendFocusLost; -- (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 5a49bca51..dc11fd61b 100644 --- a/src/newt/native/NewtMacWindow.m +++ b/src/newt/native/NewtMacWindow.m @@ -84,6 +84,7 @@ static jmethodID visibleChangedID = NULL; static jmethodID positionChangedID = NULL; static jmethodID focusChangedID = NULL; static jmethodID windowDestroyNotifyID = NULL; +static jmethodID windowRepaintID = NULL; #define USE_SENDIO_DIRECT 1 @@ -175,13 +176,36 @@ static jmethodID windowDestroyNotifyID = NULL; return myCursor; } -- (void)viewWillDraw +- (void) viewWillDraw { DBG_PRINT("*************** viewWillDraw: 0x%p\n", javaWindowObject); [super viewWillDraw]; } -- (void)viewDidHide +- (void) drawRect:(NSRect)dirtyRect +{ + DBG_PRINT("*************** dirtyRect: 0x%p %lf/%lf %lfx%lf\n", + javaWindowObject, dirtyRect.origin.x, dirtyRect.origin.y, dirtyRect.size.width, dirtyRect.size.height); + + int shallBeDetached = 0; + JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached); + if(NULL==env) { + NSLog(@"viewDidHide: null JNIEnv"); + return; + } + + NSRect viewFrame = [self frame]; + + (*env)->CallVoidMethod(env, javaWindowObject, windowRepaintID, JNI_FALSE, + dirtyRect.origin.x, viewFrame.size.height - dirtyRect.origin.y, + dirtyRect.size.width, dirtyRect.size.height); + + if (shallBeDetached) { + (*jvmHandle)->DetachCurrentThread(jvmHandle); + } +} + +- (void) viewDidHide { int shallBeDetached = 0; JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached); @@ -199,7 +223,7 @@ static jmethodID windowDestroyNotifyID = NULL; [super viewDidHide]; } -- (void)viewDidUnhide +- (void) viewDidUnhide { int shallBeDetached = 0; JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached); @@ -217,7 +241,7 @@ static jmethodID windowDestroyNotifyID = NULL; [super viewDidUnhide]; } -- (BOOL)acceptsFirstResponder +- (BOOL) acceptsFirstResponder { return YES; } @@ -238,15 +262,41 @@ static jmethodID windowDestroyNotifyID = NULL; positionChangedID = (*env)->GetMethodID(env, clazz, "positionChanged", "(ZII)V"); focusChangedID = (*env)->GetMethodID(env, clazz, "focusChanged", "(ZZ)V"); windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "()V"); + windowRepaintID = (*env)->GetMethodID(env, clazz, "windowRepaint", "(ZIIII)V"); enqueueRequestFocusID = (*env)->GetMethodID(env, clazz, "enqueueRequestFocus", "(Z)V"); if (enqueueMouseEventID && sendMouseEventID && enqueueKeyEventID && sendKeyEventID && sizeChangedID && visibleChangedID && insetsChangedID && - positionChangedID && focusChangedID && windowDestroyNotifyID && enqueueRequestFocusID) + positionChangedID && focusChangedID && windowDestroyNotifyID && enqueueRequestFocusID && windowRepaintID) { return YES; } return NO; } +- (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: 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 + mouseConfined = NO; + mouseVisible = YES; + mouseInside = NO; + cursorIsHidden = NO; + return res; +} + - (void) updateInsets: (JNIEnv*) env { NSView* nsview = [self contentView]; @@ -275,29 +325,22 @@ static jmethodID windowDestroyNotifyID = NULL; (*env)->CallVoidMethod(env, javaWindowObject, insetsChangedID, JNI_FALSE, cachedInsets[0], cachedInsets[1], cachedInsets[2], cachedInsets[3]); } -- (id) initWithContentRect: (NSRect) contentRect - styleMask: (NSUInteger) windowStyle - backing: (NSBackingStoreType) bufferingType - defer: (BOOL) deferCreation - screen:(NSScreen *)screen +- (void) attachToParent: (NSWindow*) parent { - id res = [super initWithContentRect: contentRect - styleMask: windowStyle - backing: bufferingType - 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 - mouseConfined = NO; - mouseVisible = YES; - mouseInside = NO; - cursorIsHidden = NO; - return res; + DBG_PRINT( "attachToParent.1\n"); + [parent addChildWindow: self ordered: NSWindowAbove]; + DBG_PRINT( "attachToParent.2\n"); + [self setParentWindow: parent]; + DBG_PRINT( "attachToParent.X\n"); +} + +- (void) detachFromParent: (NSWindow*) parent +{ + DBG_PRINT( "detachFromParent.1\n"); + [self setParentWindow: nil]; + DBG_PRINT( "detachFromParent.2\n"); + [parent removeChildWindow: self]; + DBG_PRINT( "detachFromParent.X\n"); } /** |