From 1a1557cd9e31bd7975d858b7b2d49e586805bba4 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Tue, 19 Mar 2013 05:27:59 +0100 Subject: OSX/NEWT: NSWindow/NSView Ops on main-thread w/o blocking - Part2 Continues commit 81cbcdc8469143587b2044661dd613c798ae02ba Perform on main-thread invocation from Java, allowing to issue visibleChanged(..) after creation/visible calls. This fixes the 'Visibility not reached ..' regressions. --- .../jogamp/newt/driver/macosx/WindowDriver.java | 112 ++++++++++++++------- src/newt/native/MacWindow.m | 67 ++++++------ 2 files changed, 117 insertions(+), 62 deletions(-) (limited to 'src/newt') diff --git a/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java index d3a92e023..a15c9cded 100644 --- a/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java +++ b/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java @@ -142,23 +142,35 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl sscSurfaceHandle = surfaceHandle; if (isNativeValid()) { if (0 != sscSurfaceHandle) { - orderOut0( 0 != getParentWindowHandle() ? getParentWindowHandle() : getWindowHandle() ); + OSXUtil.RunOnMainThread(false, new Runnable() { + public void run() { + orderOut0( 0 != getParentWindowHandle() ? getParentWindowHandle() : getWindowHandle() ); + } } ); } /** this is done by recreation! else if (isVisible()){ - orderFront0( 0!=getParentWindowHandle() ? getParentWindowHandle() : getWindowHandle() ); + OSXUtil.RunOnMainThread(false, new Runnable() { + public void run() { + orderFront0( 0!=getParentWindowHandle() ? getParentWindowHandle() : getWindowHandle() ); + } } ); } */ } } @Override protected void setTitleImpl(final String title) { - setTitle0(getWindowHandle(), title); + OSXUtil.RunOnMainThread(false, new Runnable() { + public void run() { + setTitle0(getWindowHandle(), title); + } } ); } @Override - protected void requestFocusImpl(boolean force) { + protected void requestFocusImpl(final boolean force) { if(!isOffscreenInstance) { - requestFocus0(getWindowHandle(), force); + OSXUtil.RunOnMainThread(false, new Runnable() { + public void run() { + requestFocus0(getWindowHandle(), force); + } } ); } else { focusChanged(false, true); } @@ -170,7 +182,10 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl System.err.println("MacWindow: clearFocus(), isOffscreenInstance "+isOffscreenInstance); } if(!isOffscreenInstance) { - resignFocus0(getWindowHandle()); + OSXUtil.RunOnMainThread(false, new Runnable() { + public void run() { + resignFocus0(getWindowHandle()); + } } ); } else { focusChanged(false, false); } @@ -247,41 +262,52 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) && 0 == ( FLAG_IS_VISIBLE & flags) ) { if ( !isOffscreenInstance ) { - orderOut0(getWindowHandle()); + OSXUtil.RunOnMainThread(false, new Runnable() { + public void run() { + orderOut0(getWindowHandle()); + visibleChanged(true, false); + } } ); + } else { + visibleChanged(true, false); } - // no native event .. - visibleChanged(true, false); } if( 0 == getWindowHandle() && 0 != ( FLAG_IS_VISIBLE & flags) || 0 != ( FLAG_CHANGE_DECORATION & flags) || 0 != ( FLAG_CHANGE_PARENTING & flags) || 0 != ( FLAG_CHANGE_FULLSCREEN & flags) ) { + final boolean setVisible = 0 != ( FLAG_IS_VISIBLE & flags); if(isOffscreenInstance) { - createWindow(true, 0 != getWindowHandle(), pClientLevelOnSreen, 64, 64, false); + createWindow(true, 0 != getWindowHandle(), pClientLevelOnSreen, 64, 64, false, setVisible, false); } else { - createWindow(false, 0 != getWindowHandle(), pClientLevelOnSreen, width, height, 0 != ( FLAG_IS_FULLSCREEN & flags)); + createWindow(false, 0 != getWindowHandle(), pClientLevelOnSreen, width, height, + 0 != ( FLAG_IS_FULLSCREEN & flags), setVisible, 0 != ( FLAG_IS_ALWAYSONTOP & flags)); + } + } else { + if( width>0 && height>0 ) { + if( !isOffscreenInstance ) { + OSXUtil.RunOnMainThread(false, new Runnable() { + public void run() { + setWindowClientTopLeftPointAndSize0(getWindowHandle(), pClientLevelOnSreen.getX(), pClientLevelOnSreen.getY(), width, height); + } } ); + } // else offscreen size is realized via recreation + // no native event (fullscreen, some reparenting) + positionChanged(true, x, y); + sizeChanged(true, width, height, false); + } + if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) && 0 != ( FLAG_IS_VISIBLE & flags) ) { + if( !isOffscreenInstance ) { + OSXUtil.RunOnMainThread(false, new Runnable() { + public void run() { + orderFront0(getWindowHandle()); + visibleChanged(true, true); + } } ); + } else { + visibleChanged(true, true); + } } - if(isVisible()) { flags |= FLAG_CHANGE_VISIBILITY; } - } else if( width>0 && height>0 ) { if( !isOffscreenInstance ) { - OSXUtil.RunOnMainThread(false, new Runnable() { - public void run() { - setWindowClientTopLeftPointAndSize0(getWindowHandle(), pClientLevelOnSreen.getX(), pClientLevelOnSreen.getY(), width, height); - } } ); - } // else offscreen size is realized via recreation - // no native event (fullscreen, some reparenting) - positionChanged(true, x, y); - sizeChanged(true, width, height, false); - } - if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) && 0 != ( FLAG_IS_VISIBLE & flags) ) { - if( !isOffscreenInstance ) { - orderFront0(getWindowHandle()); + setAlwaysOnTop0(getWindowHandle(), 0 != ( FLAG_IS_ALWAYSONTOP & flags)); } - // no native event .. - visibleChanged(true, true); - } - if( !isOffscreenInstance ) { - setAlwaysOnTop0(getWindowHandle(), 0 != ( FLAG_IS_ALWAYSONTOP & flags)); } if(DEBUG_IMPLEMENTATION) { System.err.println("MacWindow reconfig.X: clientPos "+pClientLevelOnSreen+", "+width+"x"+height+" -> clientPos "+getLocationOnScreenImpl(0, 0)+", insets: "+getInsets()); @@ -406,11 +432,19 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl private void createWindow(final boolean offscreenInstance, final boolean recreate, final PointImmutable pS, final int width, final int height, - final boolean fullscreen) { + final boolean fullscreen, final boolean visible, final boolean alwaysOnTop) { if( 0 != getWindowHandle() && !recreate ) { return; } + + if(DEBUG_IMPLEMENTATION) { + System.err.println("MacWindow.createWindow on thread "+Thread.currentThread().getName()+ + ": offscreen "+offscreenInstance+", recreate "+recreate+ + ", pS "+pS+", "+width+"x"+height+", fullscreen "+fullscreen+", visible "+visible+ + ", alwaysOnTop "+alwaysOnTop); + // Thread.dumpStack(); + } try { final long parentWin = getParentWindowHandle(); @@ -451,12 +485,14 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl public void run() { initWindow0( parentWin, newWin, pS.getX(), pS.getY(), width, height, - isOpaque, fullscreen, offscreenInstance, getScreen().getIndex(), surfaceHandle); + isOpaque, fullscreen, visible, offscreenInstance, getScreen().getIndex(), surfaceHandle); if( offscreenInstance ) { orderOut0(0!=parentWin ? parentWin : newWin); } else { setTitle0(newWin, getTitle()); + setAlwaysOnTop0(getWindowHandle(), alwaysOnTop); } + visibleChanged(true, visible); } } ); } catch (Exception ie) { ie.printStackTrace(); @@ -468,22 +504,30 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl private native long createWindow0(int x, int y, int w, int h, boolean fullscreen, int windowStyle, int backingStoreType, int screen_idx, long view); /** Must be called on Main-Thread */ private native void initWindow0(long parentWindow, long window, int x, int y, int w, int h, - boolean opaque, boolean fullscreen, boolean offscreen, int screen_idx, long view); + boolean opaque, boolean fullscreen, boolean visible, boolean offscreen, + int screen_idx, long view); private native boolean lockSurface0(long window, long view); private native boolean unlockSurface0(long window, long view); + /** Must be called on Main-Thread */ private native void requestFocus0(long window, boolean force); + /** Must be called on Main-Thread */ private native void resignFocus0(long window); - /** in case of a child window, it actually only issues orderBack(..) */ + /** Must be called on Main-Thread. In case of a child window, it actually only issues orderBack(..) */ private native void orderOut0(long window); + /** Must be called on Main-Thread */ private native void orderFront0(long window); /** Must be called on Main-Thread */ private native void close0(long window); + /** Must be called on Main-Thread */ private native void setTitle0(long window, String title); private native long contentView0(long window); /** Must be called on Main-Thread */ private native void changeContentView0(long parentWindowOrView, long window, long view); + /** Must be called on Main-Thread */ private native void setWindowClientTopLeftPointAndSize0(long window, int x, int y, int w, int h); + /** Must be called on Main-Thread */ private native void setWindowClientTopLeftPoint0(long window, int x, int y); + /** Must be called on Main-Thread */ private native void setAlwaysOnTop0(long window, boolean atop); private static native Object getLocationOnScreen0(long windowHandle, int src_x, int src_y); private static native boolean setPointerVisible0(long windowHandle, boolean hasFocus, boolean visible); diff --git a/src/newt/native/MacWindow.m b/src/newt/native/MacWindow.m index db4420b49..e3f4eae34 100644 --- a/src/newt/native/MacWindow.m +++ b/src/newt/native/MacWindow.m @@ -62,30 +62,36 @@ static NSString* jstringToNSString(JNIEnv* env, jstring jstr) return str; } -static void setWindowClientTopLeftPoint(NewtMacWindow* mWin, jint x, jint y) { +static void setWindowClientTopLeftPoint(NewtMacWindow* mWin, jint x, jint y, BOOL doDisplay) { + DBG_PRINT( "setWindowClientTopLeftPoint.0 - window: %p %d/%d, display %d\n", mWin, (int)x, (int)y, (int)doDisplay); NSPoint pS = [mWin newtAbsClientTLWinPos2AbsBLScreenPos: NSMakePoint(x, y)]; + DBG_PRINT( "setWindowClientTopLeftPoint.1: %d/%d\n", (int)pS.x, (int)pS.y); + [mWin setFrameOrigin: pS]; + DBG_PRINT( "setWindowClientTopLeftPoint.X: %d/%d\n", (int)pS.x, (int)pS.y); - NSView* mView = [mWin contentView]; - [mWin invalidateCursorRectsForView: mView]; + if( doDisplay ) { + NSView* mView = [mWin contentView]; + [mWin invalidateCursorRectsForView: mView]; + } } static void setWindowClientTopLeftPointAndSize(NewtMacWindow* mWin, jint x, jint y, jint width, jint height, BOOL doDisplay) { - DBG_PRINT( "setWindowClientTopLeftPointAndSize.0 - window: %p %d/%d %dx%d\n", - mWin, (int)x, (int)y, (int)width, (int)height); + DBG_PRINT( "setWindowClientTopLeftPointAndSize.0 - window: %p %d/%d %dx%d, display %d\n", mWin, (int)x, (int)y, (int)width, (int)height, (int)doDisplay); NSSize clientSZ = NSMakeSize(width, height); NSPoint pS = [mWin newtAbsClientTLWinPos2AbsBLScreenPos: NSMakePoint(x, y) size: clientSZ]; NSSize topSZ = [mWin newtClientSize2TLSize: clientSZ]; NSRect rect = { pS, topSZ }; - - DBG_PRINT( "setWindowClientTopLeftPointAndSize.X: %d/%d %dx%d\n", - (int)rect.origin.x, (int)rect.origin.y, (int)rect.size.width, (int)rect.size.height); + DBG_PRINT( "setWindowClientTopLeftPointAndSize.1: %d/%d %dx%d\n", (int)rect.origin.x, (int)rect.origin.y, (int)rect.size.width, (int)rect.size.height); [mWin setFrame: rect display:doDisplay]; + DBG_PRINT( "setWindowClientTopLeftPointAndSize.X: %d/%d %dx%d\n", (int)rect.origin.x, (int)rect.origin.y, (int)rect.size.width, (int)rect.size.height); // -> display:YES - // NSView* mView = [mWin contentView]; - // [mWin invalidateCursorRectsForView: mView]; + // if( doDisplay ) { + // NSView* mView = [mWin contentView]; + // [mWin invalidateCursorRectsForView: mView]; + // } } #ifdef VERBOSE_ON @@ -665,19 +671,19 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_createWindow * * Class: jogamp_newt_driver_macosx_WindowDriver * Method: initWindow0 - * Signature: (JJIIIIZZZIIJ)V + * Signature: (JJIIIIZZZZIIJ)V */ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_initWindow0 (JNIEnv *env, jobject jthis, jlong parent, jlong window, jint x, jint y, jint w, jint h, - jboolean opaque, jboolean fullscreen, jboolean offscreen, jint screen_idx, jlong jview) + jboolean opaque, jboolean fullscreen, jboolean visible, jboolean offscreen, jint screen_idx, jlong jview) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; NewtMacWindow* myWindow = (NewtMacWindow*) ((intptr_t) window); NewtView* myView = (NewtView*) (intptr_t) jview ; - DBG_PRINT( "initWindow0 - %p (this), %p (parent), %p (window), %d/%d %dx%d, opaque %d, fs %d, offscreen %d, screenidx %d, view %p (START)\n", - (void*)(intptr_t)jthis, (void*)(intptr_t)parent, myWindow, (int)x, (int)y, (int)w, (int)h, (int) opaque, (int)fullscreen, - (int)offscreen, (int)screen_idx, myView); + DBG_PRINT( "initWindow0 - %p (this), %p (parent), %p (window), %d/%d %dx%d, opaque %d, fs %d, visible %d, offscreen %d, screenidx %d, view %p (START)\n", + (void*)(intptr_t)jthis, (void*)(intptr_t)parent, myWindow, (int)x, (int)y, (int)w, (int)h, + (int) opaque, (int)fullscreen, (int)visible, (int)offscreen, (int)screen_idx, myView); NSArray *screens = [NSScreen screens]; if(screen_idx<0) screen_idx=0; @@ -759,15 +765,22 @@ NS_ENDHANDLER DBG_PRINT( "initWindow0.%d - %p,%d view %p,%d, isVisible %d\n", dbgIdx++, myWindow, getRetainCount(myWindow), myView, getRetainCount(myView), [myWindow isVisible]); - // Immediately re-position the window based on an upper-left coordinate system + // Immediately re-position this window based on an upper-left coordinate system setWindowClientTopLeftPointAndSize(myWindow, x, y, w, h, NO); + DBG_PRINT( "initWindow0.%d - %p,%d view %p,%d, isVisible %d\n", + dbgIdx++, myWindow, getRetainCount(myWindow), myView, getRetainCount(myView), [myWindow isVisible]); + NS_DURING // concurrent view rendering // Available >= 10.6 - Makes the menubar disapear if ( [myWindow respondsToSelector:@selector(setAllowsConcurrentViewDrawing:)] ) { [myWindow setAllowsConcurrentViewDrawing: YES]; } + + DBG_PRINT( "initWindow0.%d - %p,%d view %p,%d, isVisible %d\n", + dbgIdx++, myWindow, getRetainCount(myWindow), myView, getRetainCount(myView), [myWindow isVisible]); + if ( [myView respondsToSelector:@selector(setCanDrawConcurrently:)] ) { [myView setCanDrawConcurrently: YES]; } @@ -778,7 +791,7 @@ NS_ENDHANDLER dbgIdx++, myWindow, getRetainCount(myWindow), myView, getRetainCount(myView), [myWindow isVisible]); // visible on front - if( JNI_FALSE == offscreen ) { + if( JNI_TRUE == visible && JNI_FALSE == offscreen ) { [myWindow orderFront: myWindow]; } @@ -861,7 +874,6 @@ NS_ENDHANDLER if(NULL!=pWin) { [mWin detachFromParent: pWin]; } - // [mWin performSelectorOnMainThread:@selector(orderOut:) withObject:mWin waitUntilDone:NO]; [mWin orderOut: mWin]; DBG_PRINT( "windowClose.1 - %p,%d view %p,%d, parent %p\n", @@ -870,7 +882,6 @@ NS_ENDHANDLER // Only release window, if release is not yet in process. // E.g. destroyNotifySent:=true set by NewtMacWindow::windowWillClose(), i.e. window-close was clicked. if(!destroyNotifySent) { - // [mWin performSelectorOnMainThread:@selector(release) withObject:nil waitUntilDone:NO]; [mWin release]; } @@ -930,8 +941,8 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_requestFocus0 DBG_PRINT( "requestFocus - window: %p, force %d, hasFocus %d (START)\n", mWin, force, hasFocus); [mWin makeFirstResponder: nil]; - [mWin performSelectorOnMainThread:@selector(orderFrontRegardless) withObject:nil waitUntilDone:NO]; - [mWin performSelectorOnMainThread:@selector(makeKeyWindow) withObject:nil waitUntilDone:NO]; + [mWin orderFrontRegardless]; + [mWin makeKeyWindow]; DBG_PRINT( "requestFocus - window: %p, force %d (END)\n", mWin, force); @@ -954,10 +965,10 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_resignFocus0 DBG_PRINT( "requestFocusParent0 - window: %p, parent %p, hasFocus %d (START)\n", mWin, pWin, hasFocus ); if( hasFocus ) { if(NULL != pWin) { - // [mWin performSelectorOnMainThread:@selector(makeFirstResponder:) withObject:pWin waitUntilDone:NO]; - [pWin performSelectorOnMainThread:@selector(makeKeyWindow) withObject:nil waitUntilDone:NO]; + // [mWin makeFirstResponder: pWin]; + [pWin makeKeyWindow]; } else { - [mWin performSelectorOnMainThread:@selector(resignKeyWindow) withObject:nil waitUntilDone:NO]; + [pWin resignKeyWindow]; } } DBG_PRINT( "requestFocusParent0 - window: %p (END)\n", mWin); @@ -978,7 +989,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_orderFront0 DBG_PRINT( "orderFront0 - window: %p (START)\n", win); - [win performSelectorOnMainThread:@selector(orderFrontRegardless) withObject:nil waitUntilDone:NO]; + [win orderFrontRegardless]; DBG_PRINT( "orderFront0 - window: %p (END)\n", win); @@ -1000,9 +1011,9 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_orderOut0 DBG_PRINT( "orderOut0 - window: (parent %p) %p (START)\n", pWin, mWin); if(NULL == pWin) { - [mWin performSelectorOnMainThread:@selector(orderOut:) withObject:mWin waitUntilDone:NO]; + [mWin orderOut: mWin]; } else { - [mWin performSelectorOnMainThread:@selector(orderBack:) withObject:mWin waitUntilDone:NO]; + [mWin orderBack: mWin]; } DBG_PRINT( "orderOut0 - window: (parent %p) %p (END)\n", pWin, mWin); @@ -1126,7 +1137,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setWindowClie DBG_PRINT( "setWindowClientTopLeftPoint - window: %p (START)\n", mWin); - setWindowClientTopLeftPoint(mWin, x, y); + setWindowClientTopLeftPoint(mWin, x, y, YES); DBG_PRINT( "setWindowClientTopLeftPoint - window: %p (END)\n", mWin); -- cgit v1.2.3