diff options
author | Sven Gothel <[email protected]> | 2020-01-13 06:52:22 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2020-01-13 06:52:22 +0100 |
commit | 12bbb049b716282321c979ae78918801ef071884 (patch) | |
tree | 39693b99cb6506603fb90dc7c04c6484cc3c1b2b /src/newt/native | |
parent | e3e671e3ca63235830a2ebf7875650a4c86ce18e (diff) |
Bug 1421, Bug 1358, Bug 969, Bug 672: Fix NEWT's coordinate conversion on MacOS (fixes NewtCanvasSWT on SWT positioning)
Newt's OSX Window consist out of NSView wrapped up within its own NSWindow.
It's position is being set via its NSWindow's client-area position on screen (frame),
which we derive from NSView's client-area position.
When NEWT reparents into a new 'window',
on OSX it uses the parent's NSView and its NSWindow
to attach its own NSView and NSWindow as a subview and childwindow.
SWT's OSX implementation uses NSView's for each Compositor,
but an individual NSWindow is only established for the Shell (Window).
An oversight in Nativewindow and NEWT's coordinate translation:
'top-left view <-> top-left screen'
by missing the 'view <-> window' translation caused this whole issue.
The oversight occured as NEWT's 'view <-> window' translation
had no impact due to its 1-view to 1-window mapping.
Fixing the coordinate translation resolves the mess
for SWT and for potential other toolkits on OSX.
NewtCanvasSWT behaves same on OSX as on X11 etc finally.
Diffstat (limited to 'src/newt/native')
-rw-r--r-- | src/newt/native/MacNewtNSWindow.h | 6 | ||||
-rw-r--r-- | src/newt/native/MacNewtNSWindow.m | 78 | ||||
-rw-r--r-- | src/newt/native/MacWindow.m | 6 |
3 files changed, 51 insertions, 39 deletions
diff --git a/src/newt/native/MacNewtNSWindow.h b/src/newt/native/MacNewtNSWindow.h index d55c8b060..5a0963133 100644 --- a/src/newt/native/MacNewtNSWindow.h +++ b/src/newt/native/MacNewtNSWindow.h @@ -172,9 +172,9 @@ CGDirectDisplayID NewtScreen_getCGDirectDisplayIDByNSScreen(NSScreen *screen); - (void) attachToParent: (NSWindow*) parent; - (void) detachFromParent: (NSWindow*) parent; -- (NSPoint) newtAbsClientTLWinPos2AbsBLScreenPos: (NSPoint) p; -- (NSPoint) newtAbsClientTLWinPos2AbsBLScreenPos: (NSPoint) p size: (NSSize) nsz; -- (NSPoint) newtRelClientTLWinPos2AbsBLScreenPos: (NSPoint) p; +- (NSPoint) newtTLScreenPos2BLScreenPos: (NSPoint) p; +- (NSPoint) newtTLScreenPos2BLScreenPos: (NSPoint) p size: (NSSize) nsz; +- (NSPoint) newtTLViewPos2BLScreenPos: (NSPoint) p; - (NSSize) newtClientSize2TLSize: (NSSize) nsz; - (NSPoint) getLocationOnScreen: (NSPoint) p; diff --git a/src/newt/native/MacNewtNSWindow.m b/src/newt/native/MacNewtNSWindow.m index f93e1aa86..6a2426950 100644 --- a/src/newt/native/MacNewtNSWindow.m +++ b/src/newt/native/MacNewtNSWindow.m @@ -695,18 +695,20 @@ static jmethodID windowRepaintID = NULL; // NewtCommon_ReleaseJNIEnv(shallBeDetached); } +/** + * Converts bottom-left screen point 'p' to top-left view point. + */ - (NSPoint) screenPos2NewtClientWinPos: (NSPoint) p { NSRect viewFrame = [self frame]; - NSRect r; - r.origin.x = p.x; - r.origin.y = p.y; - r.size.width = 0; - r.size.height = 0; - // NSRect rS = [[self window] convertRectFromScreen: r]; // 10.7 - NSPoint oS = [[self window] convertScreenToBase: r.origin]; - oS.y = viewFrame.size.height - oS.y; // y-flip + NSPoint oS = NSMakePoint(p.x, p.y); + oS = [[self window] convertScreenToBase: oS]; // BL-screen -> BL-window + [self convertPoint: oS fromView:nil]; // BL-window -> BL-view + if( ![self isFlipped] ) { + // y-flip for 0/0 top-left: BL-view -> TL-view + oS.y = viewFrame.size.height - oS.y; + } return oS; } @@ -1020,25 +1022,27 @@ NS_ENDHANDLER } /** + * Converts top-left screen point to bottom-left screen point. * p abs screen position of client-area pos w/ top-left origin, using contentView's client NSSize * returns: abs screen position w/ bottom-left origin */ -- (NSPoint) newtAbsClientTLWinPos2AbsBLScreenPos: (NSPoint) p +- (NSPoint) newtTLScreenPos2BLScreenPos: (NSPoint) p { NSView* mView = [self contentView]; NSRect mViewFrame = [mView frame]; - return [self newtAbsClientTLWinPos2AbsBLScreenPos: p size: mViewFrame.size]; + return [self newtTLScreenPos2BLScreenPos: p size: mViewFrame.size]; } /** + * Converts top-left screen point to bottom-left screen point. * p abs screen position of client-area pos w/ top-left origin, using given client NSSize * returns: abs screen position w/ bottom-left origin */ -- (NSPoint) newtAbsClientTLWinPos2AbsBLScreenPos: (NSPoint) p size: (NSSize) nsz +- (NSPoint) newtTLScreenPos2BLScreenPos: (NSPoint) p size: (NSSize) nsz { int totalHeight = nsz.height + cachedInsets[3]; // height + insets.bottom - DBG_PRINT( "newtAbsClientTLWinPos2AbsBLScreenPos: point-in[%d/%d], size-in[%dx%d], insets bottom %d -> totalHeight %d\n", + DBG_PRINT( "newtTLScreenPos2BLScreenPos: point-in[%d/%d], size-in[%dx%d], insets bottom %d -> totalHeight %d\n", (int)p.x, (int)p.y, (int)nsz.width, (int)nsz.height, cachedInsets[3], totalHeight); NSScreen* screen = [self screen]; @@ -1048,7 +1052,7 @@ NS_ENDHANDLER NSRect frameBL = [screen frame]; // origin bottom-left NSPoint r = NSMakePoint(p.x, frameBL.origin.y + frameBL.size.height - ( p.y - frameTL.origin.y ) - totalHeight); // y-flip from TL-screen -> BL-screen - DBG_PRINT( "newtAbsClientTLWinPos2AbsBLScreenPos: screen tl[%d/%d %dx%d] bl[%d/%d %dx%d -> %d/%d\n", + DBG_PRINT( "newtTLScreenPos2BLScreenPos: screen tl[%d/%d %dx%d] bl[%d/%d %dx%d -> %d/%d\n", (int)frameTL.origin.x, (int)frameTL.origin.y, (int)frameTL.size.width, (int)frameTL.size.height, (int)frameBL.origin.x, (int)frameBL.origin.y, (int)frameBL.size.width, (int)frameBL.size.height, (int)r.x, (int)r.y); @@ -1057,25 +1061,33 @@ NS_ENDHANDLER } /** + * Converts top-left view point to bottom-left screen point. * p rel client window position w/ top-left origin * returns: abs screen position w/ bottom-left origin */ -- (NSPoint) newtRelClientTLWinPos2AbsBLScreenPos: (NSPoint) p +- (NSPoint) newtTLViewPos2BLScreenPos: (NSPoint) p { - NSRect winFrame = [self frame]; - NSView* mView = [self contentView]; NSRect mViewFrame = [mView frame]; - NSPoint r = NSMakePoint(winFrame.origin.x + p.x, - winFrame.origin.y + ( mViewFrame.size.height - p.y ) ); // y-flip in view - - DBG_PRINT( "newtRelClientTLWinPos2AbsBLScreenPos: point-in[%d/%d], winFrame[%d/%d %dx%d], viewFrame[%d/%d %dx%d] -> %d/%d\n", - (int)p.x, (int)p.y, - (int)winFrame.origin.x, (int)winFrame.origin.y, (int)winFrame.size.width, (int)winFrame.size.height, - (int)mViewFrame.origin.x, (int)mViewFrame.origin.y, (int)mViewFrame.size.width, (int)mViewFrame.size.height, - (int)r.x, (int)r.y); + NSPoint oS = NSMakePoint(p.x, p.y); + if( ![mView isFlipped] ) { + // y-flip for 0/0 top-left: BL-view -> TL-view + oS.y = mViewFrame.size.height - oS.y; + } + oS = [mView convertPoint: oS toView:nil]; // BL-view -> BL-window + oS = [self convertBaseToScreen: oS]; // BL-window -> BL-screen +#ifdef VERBOSE_ON + { + NSRect winFrame = [self frame]; - return r; + DBG_PRINT( "newtTLViewPos2BLScreenPos: point-in[%d/%d], winFrame[%d/%d %dx%d], viewFrame[%d/%d %dx%d] -> %d/%d\n", + (int)p.x, (int)p.y, + (int)winFrame.origin.x, (int)winFrame.origin.y, (int)winFrame.size.width, (int)winFrame.size.height, + (int)mViewFrame.origin.x, (int)mViewFrame.origin.y, (int)mViewFrame.size.width, (int)mViewFrame.size.height, + (int)oS.x, (int)oS.y); + } +#endif + return oS; } - (NSSize) newtClientSize2TLSize: (NSSize) nsz @@ -1085,7 +1097,6 @@ NS_ENDHANDLER } /** - * y-flips input / output * p rel client window position w/ top-left origin * returns: location in 0/0 top-left space. */ @@ -1093,13 +1104,14 @@ NS_ENDHANDLER { 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 - r.size.width = 0; - r.size.height = 0; - // NSRect rS = [self convertRectToScreen: r]; // 10.7 - NSPoint oS = [self convertBaseToScreen: r.origin]; // BL-screen + + NSPoint oS = NSMakePoint(p.x, p.y); + if( ![view isFlipped] ) { + // y-flip for 0/0 top-left: TL-view -> BL-view + oS.y = viewFrame.size.height - oS.y; + } + oS = [view convertPoint: oS toView:nil]; // BL-view -> BL-window + oS = [self convertBaseToScreen: oS]; // BL-window -> BL-screen NSScreen* screen = [self screen]; CGDirectDisplayID display = NewtScreen_getCGDirectDisplayIDByNSScreen(screen); diff --git a/src/newt/native/MacWindow.m b/src/newt/native/MacWindow.m index 064fe435a..ee87ca4ad 100644 --- a/src/newt/native/MacWindow.m +++ b/src/newt/native/MacWindow.m @@ -66,7 +66,7 @@ static NSString* jstringToNSString(JNIEnv* env, jstring jstr) static void setWindowClientTopLeftPoint(NewtNSWindow* 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)]; + NSPoint pS = [mWin newtTLScreenPos2BLScreenPos: NSMakePoint(x, y)]; DBG_PRINT( "setWindowClientTopLeftPoint.1: %d/%d\n", (int)pS.x, (int)pS.y); [mWin setFrameOrigin: pS]; @@ -81,7 +81,7 @@ static void setWindowClientTopLeftPoint(NewtNSWindow* mWin, jint x, jint y, BOOL static void setWindowClientTopLeftPointAndSize(NewtNSWindow* mWin, jint x, jint y, jint width, jint height, BOOL doDisplay) { 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]; + NSPoint pS = [mWin newtTLScreenPos2BLScreenPos: NSMakePoint(x, y) size: clientSZ]; NSSize topSZ = [mWin newtClientSize2TLSize: clientSZ]; NSRect rect = { pS, topSZ }; 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); @@ -1564,7 +1564,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_warpPointer0 return; } NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - [nView setMousePosition: [mWin newtRelClientTLWinPos2AbsBLScreenPos: NSMakePoint(x, y)]]; + [nView setMousePosition: [mWin newtTLViewPos2BLScreenPos: NSMakePoint(x, y)]]; [pool release]; } |