From 5e6acd58bb499bfc7199683d6faae810b96847f7 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Tue, 11 Oct 2011 23:53:01 +0200 Subject: NEWT/OSX: Fix erroneous child Window position and top-parent visibility - Regardless whether the window is a top-level or child window, we set it's position w/ absolut left-bottom coordinated. To do so even for an AWT parent component, we retrieve the screen position by traversing through the AWT tree and adding up each parent's rel. position, since the native view only reflects the AWT frame. Note: OSX does not use native views for each AWT component. - In case we reparent child -> top, we cannot orderOut() the ex parent, but need to just call orderBack(..), otherwise the whole ex-parent frame gets hidden. - In case we close a child window (and reparent child -> top), we need to remove the parent/child relation and orderOut(..) before close(..), otherwise the window artifact is left behind. --- .../nativewindow/jawt/macosx/MacOSXJAWTWindow.java | 2 +- .../jogamp/newt/driver/macosx/MacWindow.java | 65 ++++++-------- src/newt/native/MacWindow.m | 98 ++++++++++++++-------- 3 files changed, 91 insertions(+), 74 deletions(-) diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java index d0152ce4e..d4f6a95d4 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java +++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java @@ -54,7 +54,7 @@ import jogamp.nativewindow.jawt.JAWTFactory; import jogamp.nativewindow.jawt.JAWTWindow; import jogamp.nativewindow.jawt.JAWT_DrawingSurface; import jogamp.nativewindow.jawt.JAWT_DrawingSurfaceInfo; -import jogamp.nativewindow.macosx.OSXUtil; +// import jogamp.nativewindow.macosx.OSXUtil; public class MacOSXJAWTWindow extends JAWTWindow { diff --git a/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java b/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java index b34f9a26c..a3470da6c 100644 --- a/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java +++ b/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java @@ -182,7 +182,7 @@ public class MacWindow extends WindowImpl { } protected void requestFocusImpl(boolean reparented) { - makeKeyAndOrderFront0(getWindowHandle()); + makeKeyAndOrderFront0(getWindowHandle()); } protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) { @@ -193,22 +193,23 @@ public class MacWindow extends WindowImpl { // client position -> top-level window position _x -= i.getLeftWidth() ; _y -= i.getTopHeight() ; - if( 0 > _x ) { _x = 0; } - if( 0 > _y ) { _y = 0; } if(DEBUG_IMPLEMENTATION) { System.err.println("MacWindow reconfig (insets: "+i+"): "+x+"/"+y+" -> "+_x+"/"+_y); } } + // min val is 0 + _x=Math.max(_x, 0); + _y=Math.max(_y, 0); { // On MacOSX the absolute position is required to position - // a window - even for a child window! + // a window - even a child window! final NativeWindow parent = getParent(); if( null != parent && 0 != parent.getWindowHandle() ) { final Point p = parent.getLocationOnScreen(null); _x += p.getX(); _y += p.getY(); if(DEBUG_IMPLEMENTATION) { - System.err.println("MacWindow reconfig (parent abs pos: "+p+"): "+x+"/"+y+" -> "+_x+"/"+_y); + System.err.println("MacWindow reconfig (parent: "+p+"): "+x+"/"+y+" -> "+_x+"/"+_y); } } } @@ -220,33 +221,26 @@ public class MacWindow extends WindowImpl { if( getWindowHandle() == 0 ) { if( 0 != ( FLAG_IS_VISIBLE & flags) ) { - // FIXME: for some reason we do not need (or can use) - // the absolute position at creation time .. need to determine the reason/mechanics. - createWindow(false, x, y, width, height, 0 != ( FLAG_IS_FULLSCREEN & flags)); + createWindow(false, _x, _y, width, height, 0 != ( FLAG_IS_FULLSCREEN & flags)); this.x = x; this.y = y; + makeKeyAndOrderFront0(getWindowHandle()); visibleChanged(false, true); // no native event .. } /* else { ?? } */ } else { - if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) { - if( 0 != ( FLAG_IS_VISIBLE & flags) ) { - makeKeyAndOrderFront0(getWindowHandle()); - visibleChanged(false, true); // no native event .. - enqueueWindowEvent(false, WindowEvent.EVENT_WINDOW_GAINED_FOCUS); - } else { - orderOut0(getWindowHandle()); - visibleChanged(false, false); // no native event .. - enqueueWindowEvent(false, WindowEvent.EVENT_WINDOW_LOST_FOCUS); - } - } else if( 0 != ( FLAG_CHANGE_DECORATION & flags) || - 0 != ( FLAG_CHANGE_PARENTING & flags) || - 0 != ( FLAG_CHANGE_FULLSCREEN & flags) ) { - // FIXME: for some reason we do not need (or can use) - // the absolute position at creation time .. need to determine the reason/mechanics. - createWindow(true, x, y, width, height, 0 != ( FLAG_IS_FULLSCREEN & flags)); + if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) && 0 == ( FLAG_IS_VISIBLE & flags) ) { + orderOut0(getWindowHandle()); + visibleChanged(false, false); // no native event .. + enqueueWindowEvent(false, WindowEvent.EVENT_WINDOW_LOST_FOCUS); + } + if( 0 != ( FLAG_CHANGE_DECORATION & flags) || + 0 != ( FLAG_CHANGE_PARENTING & flags) || + 0 != ( FLAG_CHANGE_FULLSCREEN & flags) ) { + createWindow(true, _x, _y, width, height, 0 != ( FLAG_IS_FULLSCREEN & flags)); + if(isVisible()) { flags |= FLAG_CHANGE_VISIBILITY; } } if(x>=0 && y>=0) { - setFrameTopLeftPoint0(getParentWindowHandle(), getWindowHandle(), _x, _y); + setFrameTopLeftPoint0(getParentWindowHandle(), getWindowHandle(), _x, _y, width, height); this.x = x; this.y = y; enqueueWindowEvent(false, WindowEvent.EVENT_WINDOW_MOVED); @@ -257,6 +251,11 @@ public class MacWindow extends WindowImpl { this.height = height; enqueueWindowEvent(false, WindowEvent.EVENT_WINDOW_RESIZED); } + if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) && 0 != ( FLAG_IS_VISIBLE & flags) ) { + makeKeyAndOrderFront0(getWindowHandle()); + visibleChanged(false, true); // no native event .. + enqueueWindowEvent(false, WindowEvent.EVENT_WINDOW_GAINED_FOCUS); + } setAlwaysOnTop0(getWindowHandle(), 0 != ( FLAG_IS_ALWAYSONTOP & flags)); } return true; @@ -370,18 +369,6 @@ public class MacWindow extends WindowImpl { return; } - x=(x>=0)?x:this.x; - y=(x>=0)?y:this.y; - width=(width>0)?width:this.width; - height=(height>0)?height:this.height; - - final NativeWindow parent = getParent(); - if(null != parent) { - final Point p = parent.getLocationOnScreen(null); - x += p.getX(); - y += p.getY(); - } - try { if(0!=getWindowHandle()) { // save the view .. close the window @@ -409,7 +396,6 @@ public class MacWindow extends WindowImpl { } surfaceHandle = contentView0(getWindowHandle()); setTitle0(getWindowHandle(), getTitle()); - makeKeyAndOrderFront0(getWindowHandle()); } catch (Exception ie) { ie.printStackTrace(); } @@ -433,12 +419,13 @@ public class MacWindow extends WindowImpl { int screen_idx, long view); private native void makeKeyAndOrderFront0(long window); private native void makeKey0(long window); + /** in case of a child window, it actually only issues orderBack(..) */ private native void orderOut0(long window); private native void close0(long window); private native void setTitle0(long window, String title); private native long contentView0(long window); private native long changeContentView0(long parentWindowOrViewHandle, long window, long view); private native void setContentSize0(long window, int w, int h); - private native void setFrameTopLeftPoint0(long parentWindowHandle, long window, int x, int y); + private native void setFrameTopLeftPoint0(long parentWindowHandle, long window, int x, int y, int w, int h); private native void setAlwaysOnTop0(long window, boolean atop); } diff --git a/src/newt/native/MacWindow.m b/src/newt/native/MacWindow.m index 335a1fd65..8d4a5ce4b 100644 --- a/src/newt/native/MacWindow.m +++ b/src/newt/native/MacWindow.m @@ -51,20 +51,32 @@ static NSString* jstringToNSString(JNIEnv* env, jstring jstr) return str; } -static void setFrameTopLeftPoint(NSWindow* pWin, NSWindow* mWin, jint x, jint y) { +static void setFrameTopLeftPoint(NSWindow* pWin, NSWindow* mWin, jint x, jint y, jint w, jint h) { + NSScreen* screen = [NSScreen mainScreen]; NSRect screenRect = [screen frame]; + NSPoint pS = NSMakePoint(screenRect.origin.x + x, screenRect.origin.y + screenRect.size.height - y - h); + + DBG_PRINT( "setFrameTopLeftPoint screen %lf/%lf %lfx%lf, top-left %d/%d -> 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); + +#ifdef VERBOSE_ON + if(NULL != pWin) { + NSView* pView = [pWin contentView]; + NSRect pViewFrame = [pView frame]; + DBG_PRINT( "setFrameTopLeftPoint pViewFrame %lf/%lf %lfx%lf\n", + pViewFrame.origin.x, pViewFrame.origin.y, pViewFrame.size.width, pViewFrame.size.height); + + NSPoint pS0; + pS0.x = 0; pS0.y = 0; + // pS = [win convertRectToScreen: r]; // 10.7 + pS0 = [pWin convertBaseToScreen: pS0]; + DBG_PRINT( "setFrameTopLeftPoint (parent) base 0/0 -> screen: %lf/%lf\n", pS0.x, pS0.y); + } +#endif - DBG_PRINT( "setFrameTopLeftPoint screen %lf/%lf %lfx%lf\n", - screenRect.origin.x, - screenRect.origin.y, - screenRect.size.width, - screenRect.size.height); - - NSPoint pt = NSMakePoint(screenRect.origin.x + x, screenRect.origin.y + screenRect.size.height - y); - - DBG_PRINT( "setFrameTopLeftPoint -> %lf/%lf\n", pt.x, pt.y); - [mWin setFrameTopLeftPoint: pt]; + [mWin setFrameOrigin: pS]; } static NewtView * changeContentView(JNIEnv *env, jobject javaWindowObject, NSWindow *pwin, NSView *pview, NSWindow *win, NewtView *newView) { @@ -274,7 +286,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_MacWindow_createWindow0 NSWindow* myWindow = [[[NewtMacWindow alloc] initWithContentRect: rect styleMask: (NSUInteger) styleMask backing: (NSBackingStoreType) bufferingType - screen: myScreen] retain]; + defer: NO screen: myScreen] retain]; NSObject *nsParentObj = (NSObject*) ((intptr_t) parent); NSWindow* parentWindow = NULL; @@ -315,7 +327,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); + setFrameTopLeftPoint(parentWindow, myWindow, x, y, w, h); NS_DURING // Available >= 10.5 - Makes the menubar disapear @@ -388,14 +400,19 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_orderOut0 (JNIEnv *env, jobject unused, jlong window) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - NSWindow* win = (NSWindow*) ((intptr_t) window); + NSWindow* mWin = (NSWindow*) ((intptr_t) window); + NSWindow* pWin = [mWin parentWindow]; - DBG_PRINT( "orderOut0 - window: %p (START)\n", win); + DBG_PRINT( "orderOut0 - window: (parent %p) %p (START)\n", pWin, mWin); - // [win performSelectorOnMainThread:@selector(orderOut:) withObject:win waitUntilDone:NO]; - [win orderOut: win]; + // [mWin performSelectorOnMainThread:@selector(orderOut:) withObject:mWin waitUntilDone:NO]; + if(NULL == pWin) { + [mWin orderOut: mWin]; + } else { + [mWin orderBack: mWin]; + } - DBG_PRINT( "orderOut0 - window: %p (END)\n", win); + DBG_PRINT( "orderOut0 - window: (parent %p) %p (END)\n", pWin, mWin); [pool release]; } @@ -409,24 +426,29 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_close0 (JNIEnv *env, jobject unused, jlong window) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - NSWindow* win = (NSWindow*) ((intptr_t) window); - NSView* view = [win contentView]; - DBG_PRINT( "*************** windowClose.0: 0x%p\n", (void *)win); + NSWindow* mWin = (NSWindow*) ((intptr_t) window); + NSView* mView = [mWin contentView]; + NSWindow* pWin = [mWin parentWindow]; + DBG_PRINT( "*************** windowClose.0: %p (parent %p)\n", mWin, pWin); NS_DURING - if(NULL!=view) { + if(NULL!=mView) { // Available >= 10.5 - Makes the menubar disapear - if([view isInFullScreenMode]) { - [view exitFullScreenModeWithOptions: NULL]; + if([mView isInFullScreenMode]) { + [mView exitFullScreenModeWithOptions: NULL]; } } NS_HANDLER NS_ENDHANDLER - DBG_PRINT( "*************** windowClose.2: 0x%p\n", (void *)win); - [win performSelectorOnMainThread:@selector(close:) withObject:nil waitUntilDone:NO]; - // [win close] + if(NULL!=pWin) { + [mWin setParentWindow: nil]; + [pWin removeChildWindow: mWin]; + } + [mWin orderOut: mWin]; + [mWin performSelectorOnMainThread:@selector(close:) withObject:nil waitUntilDone:NO]; + // [mWin close] - DBG_PRINT( "*************** windowClose.X: 0x%p\n", (void *)win); + DBG_PRINT( "*************** windowClose.X: %p (parent %p)\n", mWin, pWin); [pool release]; } @@ -538,17 +560,25 @@ 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) + (JNIEnv *env, jobject unused, jlong parent, jlong window, jint x, jint y, jint w, jint h) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - NSWindow* pwin = (NSWindow*) ((intptr_t) parent); - NSWindow* win = (NSWindow*) ((intptr_t) window); + NSWindow* mWin = (NSWindow*) ((intptr_t) window); + + NSObject *nsParentObj = (NSObject*) ((intptr_t) parent); + NSWindow* pWin = NULL; + if( nsParentObj != NULL && [nsParentObj isKindOfClass:[NSWindow class]] ) { + pWin = (NSWindow*) nsParentObj; + } else if( nsParentObj != NULL && [nsParentObj isKindOfClass:[NSView class]] ) { + NSView* pView = (NSView*) nsParentObj; + pWin = [pView window]; + } - DBG_PRINT( "setFrameTopLeftPoint0 - window: %p (START)\n", win); + DBG_PRINT( "setFrameTopLeftPoint0 - window: %p, parent %p (START)\n", mWin, pWin); - setFrameTopLeftPoint(pwin, win, x, y); + setFrameTopLeftPoint(pWin, mWin, x, y, w, h); - DBG_PRINT( "setFrameTopLeftPoint0 - window: %p (END)\n", win); + DBG_PRINT( "setFrameTopLeftPoint0 - window: %p, parent %p (END)\n", mWin, pWin); [pool release]; } -- cgit v1.2.3