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 | |
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')
-rw-r--r-- | src/newt/classes/com/jogamp/newt/javafx/NewtCanvasJFX.java | 8 | ||||
-rw-r--r-- | src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java | 197 | ||||
-rw-r--r-- | src/newt/classes/jogamp/newt/WindowImpl.java | 2 | ||||
-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 |
6 files changed, 130 insertions, 167 deletions
diff --git a/src/newt/classes/com/jogamp/newt/javafx/NewtCanvasJFX.java b/src/newt/classes/com/jogamp/newt/javafx/NewtCanvasJFX.java index e04ed326d..73f181dcf 100644 --- a/src/newt/classes/com/jogamp/newt/javafx/NewtCanvasJFX.java +++ b/src/newt/classes/com/jogamp/newt/javafx/NewtCanvasJFX.java @@ -168,7 +168,7 @@ public class NewtCanvasJFX extends Canvas implements NativeWindowHolder, WindowC } private final void repaintAction(final boolean visible) { - if( visible && ( null != nativeWindow || validateNative(true /* completeReparent */) ) ) { + if( visible && validateNative(true /* completeReparent */) ) { if( newtChildReady ) { if( postSetSize ) { newtChild.setSize(clientArea.getWidth(), clientArea.getHeight()); @@ -322,10 +322,12 @@ public class NewtCanvasJFX extends Canvas implements NativeWindowHolder, WindowC } private final boolean validateNative(final boolean completeReparent) { + if( null != nativeWindow ) { + return true; // already valid + } if( null == parentWindow ) { return false; } - assert null == nativeWindow; updatePosSizeCheck(); if(0 >= clientArea.getWidth() || 0 >= clientArea.getHeight()) { return false; @@ -393,7 +395,7 @@ public class NewtCanvasJFX extends Canvas implements NativeWindowHolder, WindowC } // add new one, reparent only if ready newtChild = newChild; - if( null != newtChild && ( null != nativeWindow || validateNative(false /* completeReparent */) ) ) { + if( null != newtChild && validateNative(false /* completeReparent */) ) { reparentWindow( true ); } return prevChild; diff --git a/src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java b/src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java index c4b27a451..738155140 100644 --- a/src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java +++ b/src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java @@ -47,15 +47,12 @@ import com.jogamp.nativewindow.util.Point; import com.jogamp.opengl.GLCapabilities; import jogamp.nativewindow.macosx.OSXUtil; -import jogamp.nativewindow.windows.GDIUtil; -import jogamp.nativewindow.x11.X11Lib; import jogamp.newt.Debug; import jogamp.newt.swt.SWTEDTUtil; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.internal.DPIUtil; import org.eclipse.swt.widgets.Canvas; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Event; @@ -76,6 +73,7 @@ import com.jogamp.newt.util.EDTUtil; public class NewtCanvasSWT extends Canvas implements NativeWindowHolder, WindowClosingProtocol { private static final boolean DEBUG = Debug.debug("Window"); + private final int iHashCode; private final AbstractGraphicsScreen screen; private WindowClosingMode newtChildClosingMode = WindowClosingMode.DISPOSE_ON_CLOSE; @@ -115,6 +113,8 @@ public class NewtCanvasSWT extends Canvas implements NativeWindowHolder, WindowC return res[0]; } + private final String shortName() { return "NewtCanvasSWT("+toHexString(iHashCode)+")"; } + /** * Instantiates a NewtCanvas with a NEWT child. * @@ -129,11 +129,12 @@ public class NewtCanvasSWT extends Canvas implements NativeWindowHolder, WindowC */ public NewtCanvasSWT(final Composite parent, final int style, final Window child) { super(parent, style | SWT.NO_BACKGROUND); + iHashCode = this.hashCode(); SWTAccessor.setRealized(this, true); - clientAreaPixels = getClientArea2InPixels(); - clientAreaWindow = getClientArea2(); + clientAreaPixels = SWTAccessor.getClientAreaInPixels(this); + clientAreaWindow = getClientArea(); if( 0 < clientAreaWindow.width && 0 < clientAreaWindow.height ) { pixelScale[0] = clientAreaPixels.width / clientAreaWindow.width; pixelScale[1] = clientAreaPixels.height / clientAreaWindow.height; @@ -169,43 +170,65 @@ public class NewtCanvasSWT extends Canvas implements NativeWindowHolder, WindowC switch (event.type) { case SWT.Paint: if( DEBUG ) { - System.err.println("NewtCanvasSWT.Event.PAINT, "+event); + System.err.println(shortName()+".Event.PAINT, "+event); } - if( null != nativeWindow || validateNative() ) { - if( newtChildReady ) { - if( postSetSize ) { - newtChild.setSize(clientAreaWindow.width, clientAreaWindow.height); - postSetSize = false; - } - if( postSetPos ) { - newtChild.setPosition(clientAreaWindow.x, clientAreaWindow.y); - postSetPos = false; - } - newtChild.windowRepaint(0, 0, clientAreaPixels.width, clientAreaPixels.height); + if( validateNative() && newtChildReady ) { + if( postSetSize ) { + newtChild.setSize(clientAreaWindow.width, clientAreaWindow.height); + postSetSize = false; + } + if( postSetPos ) { + newtChild.setPosition(clientAreaWindow.x, clientAreaWindow.y); + postSetPos = false; } + newtChild.windowRepaint(0, 0, clientAreaPixels.width, clientAreaPixels.height); } break; case SWT.Move: if( DEBUG ) { - System.err.println("NewtCanvasSWT.Event.MOVE, "+event); + System.err.println(shortName()+".Event.MOVE, "+event); + } + break; + case SWT.Activate: // receives focus + if( DEBUG ) { + System.err.println(shortName()+".Event.ACTIVATE, "+event); + } + break; + case SWT.Deactivate: // lost focus + if( DEBUG ) { + System.err.println(shortName()+".Event.DEACTIVATE, "+event); + } + break; + case SWT.Show: + if( DEBUG ) { + System.err.println(shortName()+".Event.SHOW, "+event); + } + break; + case SWT.Hide: + if( DEBUG ) { + System.err.println(shortName()+".Event.HIDE, "+event); } - // updatePosSizeCheck(); break; case SWT.Resize: if( DEBUG ) { - System.err.println("NewtCanvasSWT.Event.RESIZE, "+event); + System.err.println(shortName()+".Event.RESIZE, "+event); + } + if( isNativeValid() ) { + // ensure this is being called if already valid + updatePosSizeCheck(); + } else { + validateNative(); } - updatePosSizeCheck(false /* updatePos */); break; case SWT.Dispose: if( DEBUG ) { - System.err.println("NewtCanvasSWT.Event.DISPOSE, "+event); + System.err.println(shortName()+".Event.DISPOSE, "+event); } NewtCanvasSWT.this.dispose(); break; default: if( DEBUG ) { - System.err.println("NewtCanvasSWT.Event.misc: "+event.type+", "+event); + System.err.println(shortName()+".Event.misc: "+event.type+", "+event); } } } @@ -214,72 +237,28 @@ public class NewtCanvasSWT extends Canvas implements NativeWindowHolder, WindowC addListener (SWT.Resize, listener); addListener (SWT.Paint, listener); addListener (SWT.Dispose, listener); - } - - private Rectangle getClientArea2() { - final Rectangle r = this.getClientArea(); - if( SWTAccessor.isOSX ) { - // On MacOS SWT implementation is as follows: - // Scrollable.getClientArea(): - // - Either using scrollView.contenview.bounds.position and scrollView.contentSize - // - Or using 0/0 and view.bounds.size - // - // Control's getSize() and getLocation() uses position and size of topView().frame() - // - final Rectangle parentClientArea = getParent().getClientArea(); - final org.eclipse.swt.graphics.Point l = getLocation(); - final org.eclipse.swt.graphics.Point s = getSize(); - if( DEBUG ) { - System.err.println("XXX parent.clientArea: "+parentClientArea); - System.err.println("XXX clientArea: "+r); - System.err.println("XXX location: "+l); - System.err.println("XXX size: "+s); - } - // Bug 1421 - // Subtracting parentClientArea's position fixes using: - // - CTabFolder parent: y-position no more pushed down about tab-height (parentClientArea.x/y) - // - SashForm parent: Offset is preserved, as it is not part of parentClientArea.x/y - // Notable, this almost mimics the original 'getClientArea()' but - // preserves SashForm's offset. - // - // The resulting offset still shows a 1-2 pixel x/y - // lower-left corner overlap .. - // Our GLCanvas doesn't show this behavior. - r.x = l.x - parentClientArea.x; // FIXME +1? - r.y = l.y - parentClientArea.y; // FIXME -1? - r.width = s.x; - r.height = s.y; - if( DEBUG ) { - System.err.println("XXX clientArea2:"+r); - } - } - return r; - } - private Rectangle getClientArea2InPixels() { - if( SWTAccessor.isOSX ) { - return DPIUtil.autoScaleUp(getClientArea2()); - } else { - // Essentially the same as: DPIUtil.autoScaleUp(getClientArea()) - return SWTAccessor.getClientAreaInPixels(this); - } + addListener (SWT.Show, listener); + addListener (SWT.Hide, listener); + addListener (SWT.Activate, listener); + addListener (SWT.Deactivate, listener); } @Override public void setBounds(final int x, final int y, final int width, final int height) { super.setBounds(x, y, width, height); if( DEBUG ) { - System.err.println("NewtCanvasSWT.setBounds: "+x+"/"+y+" "+width+"x"+height); - } - if( SWTAccessor.isOSX ) { - // Propagate the setBounds method coming from parent elements to this element - // and force newtChild to update its position (OSX only) - updatePosSizeCheck(true /* updatePos */); + System.err.println(shortName()+".setBounds: "+x+"/"+y+" "+width+"x"+height); } + updatePosSizeCheck(); } - /** assumes nativeWindow == null ! */ + protected final boolean isNativeValid() { return null != nativeWindow; } + protected final boolean validateNative() { - updatePosSizeCheck(false /* updatePos */); + if( null != nativeWindow ) { + return true; // already valid + } + updatePosSizeCheck(); final Rectangle nClientAreaWindow = clientAreaWindow; if(0 >= nClientAreaWindow.width || 0 >= nClientAreaWindow.height) { return false; @@ -291,7 +270,7 @@ public class NewtCanvasSWT extends Canvas implements NativeWindowHolder, WindowC final int visualID = SWTAccessor.getNativeVisualID(screen.getDevice(), nativeWindowHandle); final boolean visualIDValid = NativeWindowFactory.isNativeVisualIDValidForProcessing(visualID); if(DEBUG) { - System.err.println("NewtCanvasSWT.validateNative() windowHandle 0x"+Long.toHexString(nativeWindowHandle)+", visualID 0x"+Integer.toHexString(visualID)+", valid "+visualIDValid); + System.err.println(shortName()+".validateNative() windowHandle 0x"+Long.toHexString(nativeWindowHandle)+", visualID 0x"+Integer.toHexString(visualID)+", valid "+visualIDValid); } if( visualIDValid ) { /* Get the nativewindow-Graphics Device associated with this control (which is determined by the parent Composite). @@ -300,7 +279,7 @@ public class NewtCanvasSWT extends Canvas implements NativeWindowHolder, WindowC final GraphicsConfigurationFactory factory = GraphicsConfigurationFactory.getFactory(screen.getDevice(), caps); final AbstractGraphicsConfiguration config = factory.chooseGraphicsConfiguration( caps, caps, null, screen, visualID ); if(DEBUG) { - System.err.println("NewtCanvasSWT.validateNative() factory: "+factory+", windowHandle 0x"+Long.toHexString(nativeWindowHandle)+", visualID 0x"+Integer.toHexString(visualID)+", chosen config: "+config); + System.err.println(shortName()+".validateNative() factory: "+factory+", windowHandle 0x"+Long.toHexString(nativeWindowHandle)+", visualID 0x"+Integer.toHexString(visualID)+", chosen config: "+config); // Thread.dumpStack(); } if (null == config) { @@ -309,19 +288,14 @@ public class NewtCanvasSWT extends Canvas implements NativeWindowHolder, WindowC nativeWindow = new SWTNativeWindow(config, nativeWindowHandle); reparentWindow( true ); - if( SWTAccessor.isOSX && newtChildReady ) { - // initial positioning for OSX, called when the window is created - newtChild.setPosition(clientAreaWindow.x, clientAreaWindow.y); - } } - return null != nativeWindow; } - protected final void updatePosSizeCheck(final boolean updatePos) { + protected final void updatePosSizeCheck() { final Rectangle oClientAreaWindow = clientAreaWindow; - final Rectangle nClientAreaPixels = getClientArea2InPixels(); - final Rectangle nClientAreaWindow = getClientArea2(); + final Rectangle nClientAreaPixels = SWTAccessor.getClientAreaInPixels(this); + final Rectangle nClientAreaWindow = getClientArea(); final boolean sizeChanged, posChanged; { sizeChanged = nClientAreaWindow.width != oClientAreaWindow.width || nClientAreaWindow.height != oClientAreaWindow.height; @@ -340,15 +314,12 @@ public class NewtCanvasSWT extends Canvas implements NativeWindowHolder, WindowC } if(DEBUG) { final long nsh = newtChildReady ? newtChild.getSurfaceHandle() : 0; - System.err.println("NewtCanvasSWT.updatePosSizeCheck: sizeChanged "+sizeChanged+", posChanged "+posChanged+", updatePos "+updatePos+ + System.err.println(shortName()+".updatePosSizeCheck: sizeChanged "+sizeChanged+", posChanged "+posChanged+ ", ("+Thread.currentThread().getName()+"): newtChildReady "+newtChildReady+ ", pixel "+nClientAreaPixels.x+"/"+nClientAreaPixels.y+" "+nClientAreaPixels.width+"x"+nClientAreaPixels.height+ ", window "+nClientAreaWindow.x+"/"+nClientAreaWindow.y+" "+nClientAreaWindow.width+"x"+nClientAreaWindow.height+ ", scale "+pixelScale[0]+"/"+pixelScale[1]+ " - surfaceHandle 0x"+Long.toHexString(nsh)); - System.err.println("NewtCanvasSWT.updatePosSizeCheck.self: pixel-units pos "+SWTAccessor.getLocationInPixels(this)+", size "+SWTAccessor.getSizeInPixels(this)); - System.err.println("NewtCanvasSWT.updatePosSizeCheck.self: window-units pos "+this.getLocation()+", size "+this.getSize()); - System.err.println("NewtCanvasSWT.updatePosSizeCheck.self: LOS.0: "+SWTAccessor.getLocationOnScreen(new Point(), this)); } if( sizeChanged ) { if( newtChildReady ) { @@ -358,7 +329,7 @@ public class NewtCanvasSWT extends Canvas implements NativeWindowHolder, WindowC postSetSize = true; } } - if( updatePos && posChanged ) { + if( posChanged ) { if( newtChildReady ) { newtChild.setPosition(nClientAreaWindow.x, nClientAreaWindow.y); } else { @@ -366,7 +337,7 @@ public class NewtCanvasSWT extends Canvas implements NativeWindowHolder, WindowC } } if( DEBUG ) { - System.err.println("NewtCanvasSWT.updatePosSizeCheck.X END"); + System.err.println(shortName()+".updatePosSizeCheck.X END"); } } @@ -389,7 +360,7 @@ public class NewtCanvasSWT extends Canvas implements NativeWindowHolder, WindowC public void dispose() { if( null != newtChild ) { if(DEBUG) { - System.err.println("NewtCanvasSWT.dispose.0: EDTUtil cur "+newtChild.getScreen().getDisplay().getEDTUtil()+ + System.err.println(shortName()+".dispose.0: EDTUtil cur "+newtChild.getScreen().getDisplay().getEDTUtil()+ ",\n\t"+newtChild); } configureNewtChild(false); @@ -403,15 +374,6 @@ public class NewtCanvasSWT extends Canvas implements NativeWindowHolder, WindowC super.dispose(); } - private Point getParentLocationOnScreen() { - final org.eclipse.swt.graphics.Point[] parentLoc = new org.eclipse.swt.graphics.Point[] { null }; - SWTAccessor.invoke(true, new Runnable() { - public void run() { - parentLoc[0] = getParent().toDisplay(0,0); - } } ); - return new Point(parentLoc[0].x, parentLoc[0].y); - } - /** * {@inheritDoc} * @return this SWT Canvas {@link NativeWindow} representation, may be null in case it has not been realized @@ -464,7 +426,7 @@ public class NewtCanvasSWT extends Canvas implements NativeWindowHolder, WindowC public Window setNEWTChild(final Window newChild) { final Window prevChild = newtChild; if(DEBUG) { - System.err.println("NewtCanvasSWT.setNEWTChild.0: win "+newtWinHandleToHexString(prevChild)+" -> "+newtWinHandleToHexString(newChild)); + System.err.println(shortName()+".setNEWTChild.0: win "+newtWinHandleToHexString(prevChild)+" -> "+newtWinHandleToHexString(newChild)); } // remove old one if(null != newtChild) { @@ -507,12 +469,12 @@ public class NewtCanvasSWT extends Canvas implements NativeWindowHolder, WindowC return; // nop } if(DEBUG) { - System.err.println("NewtCanvasSWT.reparentWindow.0: add="+add+", win "+newtWinHandleToHexString(newtChild)+", EDTUtil: cur "+newtChild.getScreen().getDisplay().getEDTUtil()); + System.err.println(shortName()+".reparentWindow.0: add="+add+", win "+newtWinHandleToHexString(newtChild)+", EDTUtil: cur "+newtChild.getScreen().getDisplay().getEDTUtil()); } newtChild.setFocusAction(null); // no AWT focus traversal .. if(add) { - updatePosSizeCheck(false); + updatePosSizeCheck(); // set SWT EDT and start it { @@ -524,6 +486,7 @@ public class NewtCanvasSWT extends Canvas implements NativeWindowHolder, WindowC newtChild.setSize(clientAreaWindow.width, clientAreaWindow.height); newtChild.reparentWindow(nativeWindow, -1, -1, Window.REPARENT_HINT_BECOMES_VISIBLE); + newtChild.setPosition(clientAreaWindow.x, clientAreaWindow.y); newtChild.setVisible(true); configureNewtChild(true); newtChild.setSurfaceScale(pixelScale); // ensure this to be set after creation, otherwise updatePosSizeCheck is being used @@ -538,7 +501,7 @@ public class NewtCanvasSWT extends Canvas implements NativeWindowHolder, WindowC newtChild.reparentWindow(null, -1, -1, 0 /* hints */); } if(DEBUG) { - System.err.println("NewtCanvasSWT.reparentWindow.X: add="+add+", win "+newtWinHandleToHexString(newtChild)+", EDTUtil: cur "+newtChild.getScreen().getDisplay().getEDTUtil()); + System.err.println(shortName()+".reparentWindow.X: add="+add+", win "+newtWinHandleToHexString(newtChild)+", EDTUtil: cur "+newtChild.getScreen().getDisplay().getEDTUtil()); } } @@ -694,21 +657,7 @@ public class NewtCanvasSWT extends Canvas implements NativeWindowHolder, WindowC @Override public Point getLocationOnScreen(final Point point) { - final Point los; // client window location on screen - if( SWTAccessor.isOSX ) { - // top-level position -> client window position: OSX needs to add SWT parent position incl. insets - // Bug 969 comment 2: let getLOS provide the point where the child window may be placed - // from, as taken from SWT Control.toDisplay(); - los = getParentLocationOnScreen(); - } else if (SWTAccessor.isX11) { - final AbstractGraphicsScreen s = config.getScreen(); - los = X11Lib.GetRelativeLocation(s.getDevice().getHandle(), s.getIndex(), nativeWindowHandle, 0 /*root win*/, 0, 0); - } else if (SWTAccessor.isWindows) { - los = GDIUtil.GetRelativeLocation( nativeWindowHandle, 0 /*root win*/, 0, 0); - } else { - // fall-back to 0/0 - los = new Point(0, 0); - } + final Point los = NativeWindowFactory.getLocationOnScreen(this); // client window location on screen if(null!=point) { return point.translate(los); } else { diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java index 7c4769cf5..fbf448480 100644 --- a/src/newt/classes/jogamp/newt/WindowImpl.java +++ b/src/newt/classes/jogamp/newt/WindowImpl.java @@ -2912,7 +2912,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } // Let the window be positioned if !fullscreen and position changed or being a child window. if ( ( isReconfigureMaskSupported(STATE_MASK_REPOSITIONABLE) || !isNativeValid() ) && - !isFullscreen() && ( getX() != x || getY() != y || null != getParent() /* Bug 969 comment 2 */ ) + !isFullscreen() && ( getX() != x || getY() != y ) ) { if(isNativeValid()) { 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]; } |