diff options
Diffstat (limited to 'src/newt/classes')
15 files changed, 221 insertions, 179 deletions
diff --git a/src/newt/classes/com/jogamp/newt/Display.java b/src/newt/classes/com/jogamp/newt/Display.java index c618405c2..382a5d583 100644 --- a/src/newt/classes/com/jogamp/newt/Display.java +++ b/src/newt/classes/com/jogamp/newt/Display.java @@ -78,7 +78,7 @@ public abstract class Display { * Stop the running EDT in case this display is destroyed already.<br> * @return true if EDT has been stopped (destroyed but running), otherwise false. */ - public abstract boolean validateEDT(); + public abstract boolean validateEDTStopped(); /** * @return true if the native display handle is valid and ready to operate, diff --git a/src/newt/classes/com/jogamp/newt/Window.java b/src/newt/classes/com/jogamp/newt/Window.java index f63c03738..8a43ef153 100644 --- a/src/newt/classes/com/jogamp/newt/Window.java +++ b/src/newt/classes/com/jogamp/newt/Window.java @@ -351,10 +351,27 @@ public interface Window extends NativeWindow, WindowClosingProtocol { * @param newParent The new parent NativeWindow. If null, this Window becomes a top level window. * * @return The issued reparent action type (strategy) as defined in Window.ReparentAction + * @see #reparentWindow(NativeWindow, int, int, boolean) */ ReparentOperation reparentWindow(NativeWindow newParent); - ReparentOperation reparentWindow(NativeWindow newParent, boolean forceDestroyCreate); + /** + * Change this window's parent window.<br> + * <P> + * In case the old parent is not null and a Window, + * this window is removed from it's list of children.<br> + * In case the new parent is not null and a Window, + * this window is added to it's list of children.<br></P> + * + * @param newParent The new parent NativeWindow. If null, this Window becomes a top level window. + * @param x new top-level position, use -1 for default position. + * @param y new top-level position, use -1 for default position. + * @param forceDestroyCreate if true, uses re-creation strategy for reparenting, default is <code>false</code>. + * + * @return The issued reparent action type (strategy) as defined in Window.ReparentAction + * @see #reparentWindow(NativeWindow) + */ + ReparentOperation reparentWindow(NativeWindow newParent, int x, int y, boolean forceDestroyCreate); /** * Enable or disable fullscreen mode for this window. diff --git a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java index 55f5f0533..73b3bc368 100644 --- a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java +++ b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java @@ -272,10 +272,15 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto System.err.println("NewtCanvasAWT.FocusProperty: "+evt.getPropertyName()+", src "+evt.getSource()+", "+oldF+" -> "+newF+", isParent "+isParent+", isFS "+isFullscreen); } if(isParent && !isFullscreen) { - if(oldF == NewtCanvasAWT.this && newF == null) { + if(newF == NewtCanvasAWT.this) { + if(DEBUG) { + System.err.println("NewtCanvasAWT.FocusProperty: AWT focus -> NEWT focus traversal"); + } + requestFocusNEWTChild(); + } else if(oldF == NewtCanvasAWT.this && newF == null) { // focus traversal to NEWT - NOP if(DEBUG) { - System.err.println("NewtCanvasAWT.FocusProperty: NEWT focus traversal"); + System.err.println("NewtCanvasAWT.FocusProperty: NEWT focus"); } } else if(null != newF && newF != NewtCanvasAWT.this) { // focus traversal to another AWT component @@ -292,6 +297,17 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto private final FocusPropertyChangeListener focusPropertyChangeListener = new FocusPropertyChangeListener(); private volatile KeyboardFocusManager keyboardFocusManager = null; + private final void requestFocusNEWTChild() { + if(null!=newtChild) { + newtChild.setFocusAction(null); + if(isOnscreen) { + KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner(); + } + newtChild.requestFocus(); + newtChild.setFocusAction(focusAction); + } + } + /** * Sets a new NEWT child, provoking reparenting. * <p> @@ -582,16 +598,22 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto final Graphics2D g2d = (Graphics2D)graphics; try { printAWTTiles.setupGraphics2DAndClipBounds(g2d, getWidth(), getHeight()); - try { - final TileRenderer tileRenderer = printAWTTiles.renderer; - if( DEBUG ) { - System.err.println("AWT print.0: "+tileRenderer); + final TileRenderer tileRenderer = printAWTTiles.renderer; + if( DEBUG ) { + System.err.println("AWT print.0: "+tileRenderer); + } + if( !tileRenderer.eot() ) { + try { + do { + tileRenderer.display(); + } while ( !tileRenderer.eot() ); + if( DEBUG ) { + System.err.println("AWT print.1: "+printAWTTiles); + } + tileRenderer.reset(); + } finally { + printAWTTiles.resetGraphics2D(); } - do { - tileRenderer.display(); - } while ( !tileRenderer.eot() ); - } finally { - printAWTTiles.resetGraphics2D(); } } catch (NoninvertibleTransformException nte) { System.err.println("Catched: Inversion failed of: "+g2d.getTransform()); @@ -602,50 +624,6 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto } } - private final void requestFocusNEWTChild() { - if(null!=newtChild) { - newtChild.setFocusAction(null); - if(isOnscreen) { - KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner(); - } - newtChild.requestFocus(); - newtChild.setFocusAction(focusAction); - } - } - - @Override - public void requestFocus() { - super.requestFocus(); - requestFocusNEWTChild(); - } - - @Override - public boolean requestFocus(boolean temporary) { - final boolean res = super.requestFocus(temporary); - if(res) { - requestFocusNEWTChild(); - } - return res; - } - - @Override - public boolean requestFocusInWindow() { - final boolean res = super.requestFocusInWindow(); - if(res) { - requestFocusNEWTChild(); - } - return res; - } - - @Override - public boolean requestFocusInWindow(boolean temporary) { - final boolean res = super.requestFocusInWindow(temporary); - if(res) { - requestFocusNEWTChild(); - } - return res; - } - private final boolean validateComponent(boolean attachNewtChild) { if( Beans.isDesignTime() || !isDisplayable() ) { return false; diff --git a/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtApplet1Run.java b/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtApplet1Run.java index 83a129455..c7153840f 100644 --- a/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtApplet1Run.java +++ b/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtApplet1Run.java @@ -252,9 +252,9 @@ public class JOGLNewtApplet1Run extends Applet { System.err.println("GLWindow: "+glWindow); } base.start(); - if( null != newtCanvasAWT && - newtCanvasAWT.isOffscreenLayerSurfaceEnabled() && - 0 != ( JAWTUtil.JAWT_OSX_CALAYER_QUIRK_POSITION & JAWTUtil.getOSXCALayerQuirks() ) ) { + if( null != newtCanvasAWT && + newtCanvasAWT.isOffscreenLayerSurfaceEnabled() && + 0 != ( JAWTUtil.JAWT_OSX_CALAYER_QUIRK_POSITION & JAWTUtil.getOSXCALayerQuirks() ) ) { // force relayout final int cW = newtCanvasAWT.getWidth(); final int cH = newtCanvasAWT.getHeight(); diff --git a/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtAppletBase.java b/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtAppletBase.java index 25ddfad48..1004adb8e 100644 --- a/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtAppletBase.java +++ b/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtAppletBase.java @@ -33,6 +33,7 @@ import java.security.PrivilegedAction; import javax.media.nativewindow.NativeWindow; import javax.media.nativewindow.WindowClosingProtocol.WindowClosingMode; +import javax.media.nativewindow.util.InsetsImmutable; import javax.media.opengl.FPSCounter; import javax.media.opengl.GL; import javax.media.opengl.GLAutoDrawable; @@ -301,7 +302,17 @@ public class JOGLNewtAppletBase implements KeyListener, GLEventListener { if(null == glWindow.getParent()) { glWindow.reparentWindow(awtParent); } else { - glWindow.reparentWindow(null); + final InsetsImmutable insets = glWindow.getInsets(); + final int x, y; + if ( 0 >= insets.getTopHeight() ) { + // fail safe .. + x = 32; + y = 32; + } else { + x = insets.getLeftWidth(); + y = insets.getTopHeight(); + } + glWindow.reparentWindow(null, x, y, false /* forceDestroyCreate */); glWindow.setDefaultCloseOperation( glClosable ? WindowClosingMode.DISPOSE_ON_CLOSE : WindowClosingMode.DO_NOTHING_ON_CLOSE ); } } diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java index 45ab2a44c..eace0f2af 100644 --- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java +++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java @@ -390,8 +390,8 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind } @Override - public final ReparentOperation reparentWindow(NativeWindow newParent, boolean forceDestroyCreate) { - return window.reparentWindow(newParent, forceDestroyCreate); + public final ReparentOperation reparentWindow(NativeWindow newParent, int x, int y, boolean forceDestroyCreate) { + return window.reparentWindow(newParent, x, y, forceDestroyCreate); } @Override diff --git a/src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java b/src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java index 47dfca0f3..2fa83e0e2 100644 --- a/src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java +++ b/src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java @@ -346,7 +346,7 @@ public class NewtCanvasSWT extends Canvas implements WindowClosingProtocol { { final Display newtDisplay = newtChild.getScreen().getDisplay(); final EDTUtil edtUtil = new SWTEDTUtil(newtDisplay, getDisplay()); - edtUtil.restart(); + edtUtil.start(); newtDisplay.setEDTUtil( edtUtil ); } diff --git a/src/newt/classes/com/jogamp/newt/util/EDTUtil.java b/src/newt/classes/com/jogamp/newt/util/EDTUtil.java index e86df2084..52ca95682 100644 --- a/src/newt/classes/com/jogamp/newt/util/EDTUtil.java +++ b/src/newt/classes/com/jogamp/newt/util/EDTUtil.java @@ -65,10 +65,10 @@ public interface EDTUtil { public void setPollPeriod(long ms); /** - * Starts or restarts the EDT. + * Starts the EDT after it's creation or after {@link #invokeStop(boolean, Runnable) stopping}. * <p> - * If the EDT is running, it must be stopped first via {@link #invokeStop(boolean, Runnable)} - * and the caller should wait until it's stopped via {@link #waitUntilStopped()}. + * If the EDT is running, it must be {@link #invokeStop(boolean, Runnable) stopped} first + * and the caller should wait {@link #waitUntilStopped() until it's stopped}. * </p> * * @return true if EDT has been successfully restarted, otherwise false @@ -77,7 +77,7 @@ public interface EDTUtil { * @see #invokeStop(boolean, java.lang.Runnable) * @see #waitUntilStopped() */ - public boolean restart() throws IllegalStateException; + public boolean start() throws IllegalStateException; /** * Returns true if the current thread is the event dispatch thread (EDT). @@ -130,7 +130,7 @@ public interface EDTUtil { * <li>All previous queued tasks will be finished.</li> * <li>No new tasks are allowed, an Exception is thrown.</li> * <li>Can be issued from within EDT, ie from within an enqueued task.</li> - * <li>{@link #restart()} may follow immediately, ie creating a new EDT</li> + * <li>{@link #start()} may follow immediately, ie creating a new EDT</li> * </ul> * </p> * @return true if <code>task</code> has been executed or queued for later execution, otherwise false diff --git a/src/newt/classes/jogamp/newt/DefaultEDTUtil.java b/src/newt/classes/jogamp/newt/DefaultEDTUtil.java index 5794d4ae9..3d1037ad5 100644 --- a/src/newt/classes/jogamp/newt/DefaultEDTUtil.java +++ b/src/newt/classes/jogamp/newt/DefaultEDTUtil.java @@ -77,7 +77,7 @@ public class DefaultEDTUtil implements EDTUtil { } @Override - public final boolean restart() throws IllegalStateException { + public final boolean start() throws IllegalStateException { synchronized(edtLock) { if( edt.isRunning() ) { throw new IllegalStateException("EDT still running and not subject to stop. Curr "+Thread.currentThread().getName()+", EDT "+edt.getName()+", isRunning "+edt.isRunning+", shouldStop "+edt.shouldStop); @@ -135,6 +135,10 @@ public class DefaultEDTUtil implements EDTUtil { @Override public final boolean invokeStop(boolean wait, Runnable task) { + if(DEBUG) { + System.err.println(Thread.currentThread()+": Default-EDT.invokeStop wait "+wait); + Thread.dumpStack(); + } return invokeImpl(wait, task, true); } diff --git a/src/newt/classes/jogamp/newt/DisplayImpl.java b/src/newt/classes/jogamp/newt/DisplayImpl.java index 8f792b23c..0f47c87a0 100644 --- a/src/newt/classes/jogamp/newt/DisplayImpl.java +++ b/src/newt/classes/jogamp/newt/DisplayImpl.java @@ -170,7 +170,7 @@ public abstract class DisplayImpl extends Display { if(NewtFactory.useEDT()) { def = new DefaultEDTUtil(Thread.currentThread().getThreadGroup(), "Display-"+getFQName(), dispatchMessagesRunnable); if(DEBUG) { - System.err.println("Display.createNative("+getFQName()+") Create EDTUtil: "+def.getClass().getName()); + System.err.println("Display.createEDTUtil("+getFQName()+"): "+def.getClass().getName()); } } else { def = null; @@ -181,21 +181,18 @@ public abstract class DisplayImpl extends Display { @Override public synchronized EDTUtil setEDTUtil(final EDTUtil usrEDTUtil) { final EDTUtil oldEDTUtil = edtUtil; - final EDTUtil newEDTUtil; if( null != usrEDTUtil && usrEDTUtil == oldEDTUtil ) { if( DEBUG ) { System.err.println("Display.setEDTUtil: "+usrEDTUtil+" - keep!"); } - newEDTUtil = oldEDTUtil; - } else { - if(DEBUG) { - final String msg = ( null == usrEDTUtil ) ? "default" : "custom"; - System.err.println("Display.setEDTUtil("+msg+"): "+oldEDTUtil+" -> "+usrEDTUtil); - } - stopEDT( oldEDTUtil, null ); - newEDTUtil = ( null == usrEDTUtil ) ? createEDTUtil() : usrEDTUtil; + return oldEDTUtil; + } + if(DEBUG) { + final String msg = ( null == usrEDTUtil ) ? "default" : "custom"; + System.err.println("Display.setEDTUtil("+msg+"): "+oldEDTUtil+" -> "+usrEDTUtil); } - edtUtil = newEDTUtil; + stopEDT( oldEDTUtil, null ); + edtUtil = ( null == usrEDTUtil ) ? createEDTUtil() : usrEDTUtil; return oldEDTUtil; } @@ -224,31 +221,30 @@ public abstract class DisplayImpl extends Display { public void runOnEDTIfAvail(boolean wait, final Runnable task) { final EDTUtil _edtUtil = edtUtil; - if( null != _edtUtil && !_edtUtil.isCurrentThreadEDT() ) { - if( !_edtUtil.isRunning() ) { // start EDT if not running yet - synchronized( this ) { - if( !_edtUtil.isRunning() ) { // // volatile dbl-checked-locking OK - _edtUtil.restart(); - if( DEBUG ) { - System.err.println("Info: EDT started "+Thread.currentThread().getName()+", "+this); - Thread.dumpStack(); - } + if( !_edtUtil.isRunning() ) { // start EDT if not running yet + synchronized( this ) { + if( !_edtUtil.isRunning() ) { // // volatile dbl-checked-locking OK + if( DEBUG ) { + System.err.println("Info: EDT start "+Thread.currentThread().getName()+", "+this); + Thread.dumpStack(); } + _edtUtil.start(); } } - if( !_edtUtil.invoke(wait, task) ) { - if( DEBUG ) { - System.err.println("Warning: invoke(wait "+wait+", ..) on EDT failed .. invoke on current thread "+Thread.currentThread().getName()); - Thread.dumpStack(); - } - task.run(); + } + if( !_edtUtil.isCurrentThreadEDT() ) { + if( _edtUtil.invoke(wait, task) ) { + return; // done + } + if( DEBUG ) { + System.err.println("Warning: invoke(wait "+wait+", ..) on EDT failed .. invoke on current thread "+Thread.currentThread().getName()); + Thread.dumpStack(); } - } else { - task.run(); } + task.run(); } - public boolean validateEDT() { + public boolean validateEDTStopped() { if( 0==refCount && null == aDevice ) { final EDTUtil _edtUtil = edtUtil; if( null != _edtUtil && _edtUtil.isRunning() ) { diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java index caa461e41..b7357863f 100644 --- a/src/newt/classes/jogamp/newt/WindowImpl.java +++ b/src/newt/classes/jogamp/newt/WindowImpl.java @@ -154,7 +154,6 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer private boolean fullscreen = false, brokenFocusChange = false; private List<MonitorDevice> fullscreenMonitors = null; private boolean fullscreenUseMainMonitor = true; - private boolean fullscreenUseSpanningMode = true; // spanning mode: fake full screen, only on certain platforms private boolean autoPosition = true; // default: true (allow WM to choose top-level position, if not set by user) private int nfs_width, nfs_height, nfs_x, nfs_y; // non fullscreen client-area size/pos w/o insets @@ -273,7 +272,6 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer fullscreen = false; fullscreenMonitors = null; fullscreenUseMainMonitor = true; - fullscreenUseSpanningMode = false; hasFocus = false; parentWindowHandle = 0; } @@ -416,7 +414,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } if(postParentlockFocus) { // harmonize focus behavior for all platforms: focus on creation - requestFocusInt(isFullscreen() /* skipFocusAction */); + requestFocusInt(isFullscreen() /* skipFocusAction if fullscreen */); ((DisplayImpl) screen.getDisplay()).dispatchMessagesNative(); // status up2date } if(DEBUG_IMPLEMENTATION) { @@ -1035,7 +1033,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer removeScreenReference(); Display dpy = screen.getDisplay(); if(null != dpy) { - dpy.validateEDT(); + dpy.validateEDTStopped(); } // send synced destroyed notification @@ -1051,7 +1049,6 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer fullscreen = false; fullscreenMonitors = null; fullscreenUseMainMonitor = true; - fullscreenUseSpanningMode = false; hasFocus = false; parentWindowHandle = 0; @@ -1115,12 +1112,15 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } private class ReparentAction implements Runnable { - NativeWindow newParentWindow; + final NativeWindow newParentWindow; + final int topLevelX, topLevelY; boolean forceDestroyCreate; ReparentOperation operation; - private ReparentAction(NativeWindow newParentWindow, boolean forceDestroyCreate) { + private ReparentAction(NativeWindow newParentWindow, int topLevelX, int topLevelY, boolean forceDestroyCreate) { this.newParentWindow = newParentWindow; + this.topLevelX = topLevelX; + this.topLevelY = topLevelY; this.forceDestroyCreate = forceDestroyCreate | DEBUG_TEST_REPARENT_INCOMPATIBLE; this.operation = ReparentOperation.ACTION_INVALID; // ensure it's set } @@ -1147,10 +1147,13 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer private void reparent() { // mirror pos/size so native change notification can get overwritten - int x = getX(); - int y = getY(); - int width = getWidth(); - int height = getHeight(); + final int oldX = getX(); + final int oldY = getY(); + final int oldWidth = getWidth(); + final int oldHeight = getHeight(); + final int x, y; + int width = oldWidth; + int height = oldHeight; boolean wasVisible; final RecursiveLock _lock = windowLock; @@ -1171,10 +1174,12 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer long newParentWindowHandle = 0 ; if(DEBUG_IMPLEMENTATION) { - System.err.println("Window.reparent: START ("+getThreadName()+") valid "+isNativeValid()+", windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle)+", visible "+wasVisible+", old parentWindow: "+Display.hashCodeNullSafe(parentWindow)+", new parentWindow: "+Display.hashCodeNullSafe(newParentWindow)+", forceDestroyCreate "+forceDestroyCreate+", "+x+"/"+y+" "+width+"x"+height); + System.err.println("Window.reparent: START ("+getThreadName()+") valid "+isNativeValid()+", windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle)+", visible "+wasVisible+", old parentWindow: "+Display.hashCodeNullSafe(parentWindow)+", new parentWindow: "+Display.hashCodeNullSafe(newParentWindow)+", forceDestroyCreate "+forceDestroyCreate); } if(null!=newParentWindow) { + // REPARENT TO CHILD WINDOW + // reset position to 0/0 within parent space x = 0; y = 0; @@ -1236,12 +1241,19 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer operation = ReparentOperation.ACTION_NOP; } } else { - if( null != parentWindow ) { + // REPARENT TO TOP-LEVEL WINDOW + if( 0 <= topLevelX && 0 <= topLevelY ) { + x = topLevelX; + y = topLevelY; + } else if( null != parentWindow ) { // child -> top // put client to current parent+child position final Point p = getLocationOnScreen(null); x = p.getX(); y = p.getY(); + } else { + x = oldX; + y = oldY; } // Case: Top Window @@ -1267,18 +1279,15 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer if ( ReparentOperation.ACTION_INVALID == operation ) { throw new NativeWindowException("Internal Error: reparentAction not set"); } - + + if(DEBUG_IMPLEMENTATION) { + System.err.println("Window.reparent: ACTION ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+" new parentWindowHandle "+toHexString(newParentWindowHandle)+", reparentAction "+operation+", pos/size "+x+"/"+y+" "+width+"x"+height+", visible "+wasVisible); + } + if( ReparentOperation.ACTION_NOP == operation ) { - if(DEBUG_IMPLEMENTATION) { - System.err.println("Window.reparent: NO CHANGE ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+" new parentWindowHandle "+toHexString(newParentWindowHandle)+", visible "+wasVisible); - } return; } - if(DEBUG_IMPLEMENTATION) { - System.err.println("Window.reparent: ACTION ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+" new parentWindowHandle "+toHexString(newParentWindowHandle)+", reparentAction "+operation+", visible "+wasVisible); - } - // rearrange window tree if(null!=parentWindow && parentWindow instanceof Window) { ((Window)parentWindow).removeChild(WindowImpl.this); @@ -1288,19 +1297,13 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer ((Window)parentWindow).addChild(WindowImpl.this); } - if( ReparentOperation.ACTION_NATIVE_CREATION_PENDING == operation ) { - // make size and position persistent for proper recreation - definePosition(x, y); - defineSize(width, height); - return; - } - if( ReparentOperation.ACTION_NATIVE_REPARENTING == operation ) { final DisplayImpl display = (DisplayImpl) screen.getDisplay(); display.dispatchMessagesNative(); // status up2date - if(wasVisible) { - setVisibleImpl(false, x, y, width, height); + // TOP -> CLIENT: !visible first (fixes X11 unsuccessful return to parent window) + if( null != parentWindow && wasVisible && NativeWindowFactory.TYPE_X11 == NativeWindowFactory.getNativeWindowType(true) ) { + setVisibleImpl(false, oldX, oldY, oldWidth, oldHeight); WindowImpl.this.waitForVisible(false, false); // FIXME: Some composite WM behave slacky .. give 'em chance to change state -> invisible, // even though we do exactly that (KDE+Composite) @@ -1340,7 +1343,10 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer ok = WindowImpl.this.waitForSize(width, height, false, TIMEOUT_NATIVEWINDOW); } if(ok) { - requestFocusInt(false /* skipFocusAction */); + ok = WindowImpl.this.waitForPosition(true, x, y, TIMEOUT_NATIVEWINDOW); + } + if(ok) { + requestFocusInt( 0 == parentWindowHandle /* skipFocusAction if top-level */); display.dispatchMessagesNative(); // status up2date } } @@ -1361,10 +1367,18 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer destroy( wasVisible ); operation = ReparentOperation.ACTION_NATIVE_CREATION ; } + } else { + // Case + // ACTION_NATIVE_CREATION + // ACTION_NATIVE_CREATION_PENDING; + + // make size and position persistent for proper [re]creation + definePosition(x, y); + defineSize(width, height); } if(DEBUG_IMPLEMENTATION) { - System.err.println("Window.reparentWindow: END-1 ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+", visible: "+visible+", parentWindowHandle "+toHexString(parentWindowHandle)+", parentWindow "+ Display.hashCodeNullSafe(parentWindow)+" "+getX()+"/"+getY()+" "+getWidth()+"x"+getHeight()); + System.err.println("Window.reparent: END-1 ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+", visible: "+visible+", parentWindowHandle "+toHexString(parentWindowHandle)+", parentWindow "+ Display.hashCodeNullSafe(parentWindow)+" "+getX()+"/"+getY()+" "+getWidth()+"x"+getHeight()); } } finally { if(null!=lifecycleHook) { @@ -1388,7 +1402,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } } if(DEBUG_IMPLEMENTATION) { - System.err.println("Window.reparentWindow: END-X ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+", visible: "+visible+", parentWindowHandle "+toHexString(parentWindowHandle)+", parentWindow "+ Display.hashCodeNullSafe(parentWindow)+" "+getX()+"/"+getY()+" "+getWidth()+"x"+getHeight()); + System.err.println("Window.reparent: END-X ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+", visible: "+visible+", parentWindowHandle "+toHexString(parentWindowHandle)+", parentWindow "+ Display.hashCodeNullSafe(parentWindow)+" "+getX()+"/"+getY()+" "+getWidth()+"x"+getHeight()); } } } @@ -1399,9 +1413,10 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer _lock.lock(); try { if(DEBUG_IMPLEMENTATION) { - System.err.println("Window.reparentWindow: ReparentActionRecreate ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+", visible: "+visible+", parentWindowHandle "+toHexString(parentWindowHandle)+", parentWindow "+Display.hashCodeNullSafe(parentWindow)); + System.err.println("Window.reparent: ReparentActionRecreate ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+", visible: "+visible+", parentWindowHandle "+toHexString(parentWindowHandle)+", parentWindow "+Display.hashCodeNullSafe(parentWindow)); } - setVisible(true); // native creation + setVisibleActionImpl(true); // native creation + requestFocusInt( 0 == parentWindowHandle /* skipFocusAction if top-level */); } finally { _lock.unlock(); } @@ -1411,11 +1426,12 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer @Override public final ReparentOperation reparentWindow(NativeWindow newParent) { - return reparentWindow(newParent, false); + return reparentWindow(newParent, -1, -1, false); } - public ReparentOperation reparentWindow(NativeWindow newParent, boolean forceDestroyCreate) { - final ReparentAction reparentAction = new ReparentAction(newParent, forceDestroyCreate); + @Override + public ReparentOperation reparentWindow(NativeWindow newParent, int x, int y, boolean forceDestroyCreate) { + final ReparentAction reparentAction = new ReparentAction(newParent, x, y, forceDestroyCreate); runOnEDTIfAvail(true, reparentAction); return reparentAction.getOp(); } @@ -1803,7 +1819,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer private void requestFocusInt(boolean skipFocusAction) { if( skipFocusAction || !focusAction() ) { if(DEBUG_IMPLEMENTATION) { - System.err.println("Window.RequestFocusInt: forcing - ("+getThreadName()+"): "+hasFocus+" -> true - windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle)); + System.err.println("Window.RequestFocusInt: forcing - ("+getThreadName()+"): skipFocusAction "+skipFocusAction+", focus "+hasFocus+" -> true - windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle)); } requestFocusImpl(true); } @@ -1903,6 +1919,11 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer // set current state WindowImpl.this.fullscreen = fullscreen; + final int oldX = getX(); + final int oldY = getY(); + final int oldWidth = getWidth(); + final int oldHeight = getHeight(); + int x,y,w,h; final RectangleImmutable sviewport = screen.getViewport(); @@ -1920,23 +1941,20 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer viewport = MonitorDevice.unionOfViewports(new Rectangle(), fullscreenMonitors); if( isReconfigureFlagSupported(FLAG_IS_FULLSCREEN_SPAN) && ( fullscreenMonitors.size() > 1 || sviewport.compareTo(viewport) > 0 ) ) { - fullscreenUseSpanningMode = true; fs_span_flag = FLAG_IS_FULLSCREEN_SPAN; } else { - fullscreenUseSpanningMode = false; fs_span_flag = 0; } - nfs_x = getX(); - nfs_y = getY(); - nfs_width = getWidth(); - nfs_height = getHeight(); + nfs_x = oldX; + nfs_y = oldY; + nfs_width = oldWidth; + nfs_height = oldHeight; x = viewport.getX(); y = viewport.getY(); w = viewport.getWidth(); h = viewport.getHeight(); } else { fullscreenUseMainMonitor = true; - fullscreenUseSpanningMode = false; fullscreenMonitors = null; fs_span_flag = 0; viewport = null; @@ -1962,16 +1980,25 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer if(DEBUG_IMPLEMENTATION) { System.err.println("Window fs: "+fullscreen+" "+x+"/"+y+" "+w+"x"+h+", "+isUndecorated()+ ", virtl-screenSize: "+sviewport+", monitorsViewport "+viewport+ - ", spanning "+fullscreenUseSpanningMode+" @ "+Thread.currentThread().getName()); + ", spanning "+(0!=fs_span_flag)+" @ "+Thread.currentThread().getName()); } final DisplayImpl display = (DisplayImpl) screen.getDisplay(); display.dispatchMessagesNative(); // status up2date final boolean wasVisible = isVisible(); - + // Lock parentWindow only during reparenting (attempt) final NativeWindow parentWindowLocked; if( null != parentWindow ) { + // fullscreen off: !visible first (fixes X11 unsuccessful return to parent window) + if( !fullscreen && wasVisible && NativeWindowFactory.TYPE_X11 == NativeWindowFactory.getNativeWindowType(true) ) { + setVisibleImpl(false, oldX, oldY, oldWidth, oldHeight); + WindowImpl.this.waitForVisible(false, false); + // FIXME: Some composite WM behave slacky .. give 'em chance to change state -> invisible, + // even though we do exactly that (KDE+Composite) + try { Thread.sleep(100); } catch (InterruptedException e) { } + display.dispatchMessagesNative(); // status up2date + } parentWindowLocked = parentWindow; if( NativeSurface.LOCK_SURFACE_NOT_READY >= parentWindowLocked.lockSurface() ) { throw new NativeWindowException("Parent surface lock: not ready: "+parentWindow); @@ -1982,7 +2009,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer try { reconfigureWindowImpl(x, y, w, h, getReconfigureFlags( ( ( null != parentWindowLocked ) ? FLAG_CHANGE_PARENTING : 0 ) | - fs_span_flag | FLAG_CHANGE_FULLSCREEN | FLAG_CHANGE_DECORATION, wasVisible) ); + fs_span_flag | FLAG_CHANGE_FULLSCREEN | FLAG_CHANGE_DECORATION, isVisible()) ); } finally { if(null!=parentWindowLocked) { parentWindowLocked.unlockSurface(); @@ -1992,11 +2019,19 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer if(wasVisible) { setVisibleImpl(true, x, y, w, h); - WindowImpl.this.waitForVisible(true, false); - display.dispatchMessagesNative(); // status up2date - WindowImpl.this.waitForSize(w, h, false, TIMEOUT_NATIVEWINDOW); + boolean ok = 0 <= WindowImpl.this.waitForVisible(true, false); + if(ok) { + ok = WindowImpl.this.waitForSize(w, h, false, TIMEOUT_NATIVEWINDOW); + } + if(ok && !fullscreen) { + ok = WindowImpl.this.waitForPosition(true, x, y, TIMEOUT_NATIVEWINDOW); + } + if(ok) { + requestFocusInt(fullscreen /* skipFocusAction if fullscreen */); + display.dispatchMessagesNative(); // status up2date + } if(DEBUG_IMPLEMENTATION) { - System.err.println("Window fs done: " + WindowImpl.this); + System.err.println("Window fs done: ok " + ok + ", " + WindowImpl.this); } } } finally { @@ -2021,13 +2056,12 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer synchronized(fullScreenAction) { fullscreenMonitors = monitors; fullscreenUseMainMonitor = useMainMonitor; - fullscreenUseSpanningMode = false; if( fullScreenAction.init(fullscreen) ) { if(fullScreenAction.fsOn() && isOffscreenInstance(WindowImpl.this, parentWindow)) { // enable fullscreen on offscreen instance if(null != parentWindow) { nfs_parent = parentWindow; - reparentWindow(null, true); + reparentWindow(null, -1, -1, true /* forceDestroyCreate */); } else { throw new InternalError("Offscreen instance w/o parent unhandled"); } @@ -2037,13 +2071,9 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer if(!fullScreenAction.fsOn() && null != nfs_parent) { // disable fullscreen on offscreen instance - reparentWindow(nfs_parent, true); + reparentWindow(nfs_parent, -1, -1, true /* forceDestroyCreate */); nfs_parent = null; } - - if( fullscreen && isVisible() ) { // force focus on fullscreen - requestFocus(true /* wait */, true /* skipFocusAction */, true /* force */); - } } return this.fullscreen; } diff --git a/src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java b/src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java index 80c72c008..02f4be0cd 100644 --- a/src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java +++ b/src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java @@ -68,7 +68,7 @@ public class AWTEDTUtil implements EDTUtil { } @Override - public final boolean restart() throws IllegalStateException { + public final boolean start() throws IllegalStateException { synchronized(edtLock) { if( nedt.isRunning() ) { throw new IllegalStateException("EDT still running and not subject to stop. Curr "+Thread.currentThread().getName()+", NEDT "+nedt.getName()+", isRunning "+nedt.isRunning+", shouldStop "+nedt.shouldStop+", on AWT-EDT "+EventQueue.isDispatchThread()); diff --git a/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java index 6aebf0410..08638d868 100644 --- a/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java +++ b/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java @@ -159,14 +159,17 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl @Override protected void setTitleImpl(final String title) { - OSXUtil.RunOnMainThread(false, new Runnable() { - public void run() { - setTitle0(getWindowHandle(), title); - } } ); + OSXUtil.RunOnMainThread(false, new Runnable() { + public void run() { + setTitle0(getWindowHandle(), title); + } } ); } @Override protected void requestFocusImpl(final boolean force) { + if(DEBUG_IMPLEMENTATION) { + System.err.println("MacWindow: requestFocusImpl(), isOffscreenInstance "+isOffscreenInstance); + } if(!isOffscreenInstance) { OSXUtil.RunOnMainThread(false, new Runnable() { public void run() { @@ -414,13 +417,15 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl short _keySym = KeyEvent.NULL_CHAR != keySymChar ? KeyEvent.utf16ToVKey(keySymChar) : KeyEvent.VK_UNDEFINED; keySym = KeyEvent.VK_UNDEFINED != _keySym ? _keySym : keyCode; } - /* { + /** + { final boolean isModifierKeyCode = KeyEvent.isModifierKey(keyCode); System.err.println("*** handleKeyEvent: event "+KeyEvent.getEventTypeString(eventType)+ ", keyCode 0x"+Integer.toHexString(_keyCode)+" -> 0x"+Integer.toHexString(keyCode)+ ", keySymChar '"+keySymChar+"', 0x"+Integer.toHexString(keySymChar)+" -> 0x"+Integer.toHexString(keySym)+ ", mods "+toHexString(modifiers)+ - ", was: pressed "+isKeyPressed(keyCode)+", isModifierKeyCode "+isModifierKeyCode); + ", was: pressed "+isKeyPressed(keyCode)+", isModifierKeyCode "+isModifierKeyCode+ + ", nativeValid "+isNativeValid()+", isOffscreen "+isOffscreenInstance); } */ // OSX delivery order is PRESSED (t0), RELEASED (t1) and TYPED (t2) -> NEWT order: PRESSED (t0) and RELEASED (t1) @@ -452,27 +457,28 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl final PointImmutable pS, final int width, final int height, final boolean fullscreen, final boolean visible, final boolean alwaysOnTop) { + final long parentWinHandle = getParentWindowHandle(); + final long preWinHandle = getWindowHandle(); + 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); + ", alwaysOnTop "+alwaysOnTop+", preWinHandle "+toHexString(preWinHandle)+", parentWin "+toHexString(parentWinHandle)+ + ", surfaceHandle "+toHexString(surfaceHandle)); // Thread.dumpStack(); } try { - final long parentWin = getParentWindowHandle(); - if( 0 != getWindowHandle() ) { - final long thisWin = getWindowHandle(); + if( 0 != preWinHandle ) { setWindowHandle(0); - if( 0 == surfaceHandle ) { throw new NativeWindowException("Internal Error - create w/ window, but no Newt NSView"); } OSXUtil.RunOnMainThread(false, new Runnable() { public void run() { - changeContentView0(parentWin, thisWin, 0); - close0( thisWin ); + changeContentView0(parentWinHandle, preWinHandle, 0); + close0( preWinHandle ); } } ); } else { if( 0 != surfaceHandle ) { @@ -494,13 +500,13 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl setWindowHandle( newWin ); final boolean isOpaque = getGraphicsConfiguration().getChosenCapabilities().isBackgroundOpaque() && !offscreenInstance; - // Non blocking initialization on main-thread! - OSXUtil.RunOnMainThread(false, new Runnable() { + // Blocking initialization on main-thread! + OSXUtil.RunOnMainThread(true, new Runnable() { public void run() { - initWindow0( parentWin, newWin, pS.getX(), pS.getY(), width, height, + initWindow0( parentWinHandle, newWin, pS.getX(), pS.getY(), width, height, isOpaque, fullscreen, visible && !offscreenInstance, surfaceHandle); if( offscreenInstance ) { - orderOut0(0!=parentWin ? parentWin : newWin); + orderOut0(0!=parentWinHandle ? parentWinHandle : newWin); } else { setTitle0(newWin, getTitle()); setAlwaysOnTop0(getWindowHandle(), alwaysOnTop); diff --git a/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java index 4786ea04f..806dd270c 100644 --- a/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java +++ b/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java @@ -163,7 +163,7 @@ public class WindowDriver extends WindowImpl { _y = y; } if( 0 != ( FLAG_CHANGE_FULLSCREEN & flags ) ) { - if( 0 != ( FLAG_IS_FULLSCREEN & flags) && 0 != ( FLAG_IS_FULLSCREEN_SPAN & flags) && 0 == ( FLAG_IS_ALWAYSONTOP & flags) ) { + if( 0 != ( FLAG_IS_FULLSCREEN & flags) && 0 == ( FLAG_IS_ALWAYSONTOP & flags) ) { tempFSAlwaysOnTop = true; flags |= FLAG_IS_ALWAYSONTOP; if(DEBUG_IMPLEMENTATION) { diff --git a/src/newt/classes/jogamp/newt/swt/SWTEDTUtil.java b/src/newt/classes/jogamp/newt/swt/SWTEDTUtil.java index d46562050..6024195e3 100644 --- a/src/newt/classes/jogamp/newt/swt/SWTEDTUtil.java +++ b/src/newt/classes/jogamp/newt/swt/SWTEDTUtil.java @@ -77,7 +77,7 @@ public class SWTEDTUtil implements EDTUtil { } @Override - public final boolean restart() throws IllegalStateException { + public final boolean start() throws IllegalStateException { final boolean swtDisposed = swtDisplay.isDisposed(); synchronized(edtLock) { if( nedt.isRunning() ) { |