diff options
author | Sven Gothel <[email protected]> | 2012-05-01 09:21:14 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2012-05-01 09:21:14 +0200 |
commit | 4e0eb391d6c64f956ea5c87c0385ab48a24b2175 (patch) | |
tree | 69f0f45c73fc7fe2a95a678e75fa5fb4262911db /src/newt/classes/jogamp | |
parent | 5742b1faa210401470032ef129e56a83c47fd046 (diff) |
Fix Bug 560 and NEWT window closing behavior in general for all platforms.
- NEWT/WindowImpl:
- 'void windowDestroyNotify()' -> 'boolean windowDestroyNotify(boolean force)', allowing to signal a forced close,
as well as replying whether the window has been closed. (called by native code)
- destroy(): set states before releasing the window lock
- NEWT/X11: Pass windowDeleteAtom for reconfigure window, in case of reparenting child to top-level
- NEWT/OSX:
- Add 'BOOL windowShouldClose()' impl., ie. having a chance to reject the close attempt
- Common impl. for 'windowShouldClose' and 'windowWillClose' -> 'windowClosingImpl'
utilizing new 'windowDestroyNotify' code (see above).
Fixes bug 560.
- NEWT/JOGLNewtApplet1Run: Refine out-of browser window behavior for window-close button
- default: move NEWT window back to browser parent
- closeable: close NEWT window
- jogl-test-applets: Add NApplet-Closeable test (Applet out-of browser window is closable)
Diffstat (limited to 'src/newt/classes/jogamp')
4 files changed, 43 insertions, 26 deletions
diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java index 3d465e45c..5e393f7c5 100644 --- a/src/newt/classes/jogamp/newt/WindowImpl.java +++ b/src/newt/classes/jogamp/newt/WindowImpl.java @@ -66,6 +66,7 @@ import javax.media.nativewindow.NativeWindow; import javax.media.nativewindow.NativeWindowException; import javax.media.nativewindow.NativeWindowFactory; import javax.media.nativewindow.SurfaceUpdatedListener; +import javax.media.nativewindow.WindowClosingProtocol; import javax.media.nativewindow.util.DimensionImmutable; import javax.media.nativewindow.util.Insets; import javax.media.nativewindow.util.InsetsImmutable; @@ -428,12 +429,12 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer * The implementation should invoke the referenced java state callbacks * to notify this Java object of state changes.</p> * - * @see #windowDestroyNotify() + * @see #windowDestroyNotify(boolean) * @see #focusChanged(boolean, boolean) * @see #visibleChanged(boolean, boolean) * @see #sizeChanged(int,int) * @see #positionChanged(boolean,int, int) - * @see #windowDestroyNotify() + * @see #windowDestroyNotify(boolean) */ protected abstract void createNativeImpl(); @@ -908,16 +909,18 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer System.err.println("Window.destroy() END "+getThreadName()/*+", "+WindowImpl.this*/); } } finally { + // update states before release window lock + setWindowHandle(0); + visible = false; + fullscreen = false; + hasFocus = false; + parentWindowHandle = 0; + windowLock.unlock(); } if(animatorPaused) { lifecycleHook.resumeRenderingAction(); } - setWindowHandle(0); - visible = false; - fullscreen = false; - hasFocus = false; - parentWindowHandle = 0; // these refs shall be kept alive - resurrection via setVisible(true) /** @@ -1525,8 +1528,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer /** * If set to true, the default value, this NEWT Window implementation will - * handle the destruction (ie {@link #destroy()} call) within {@link #windowDestroyNotify()} implementation.<br> - * If set to false, it's up to the caller/owner to handle destruction within {@link #windowDestroyNotify()}. + * handle the destruction (ie {@link #destroy()} call) within {@link #windowDestroyNotify(boolean)} implementation.<br> + * If set to false, it's up to the caller/owner to handle destruction within {@link #windowDestroyNotify(boolean)}. */ public void setHandleDestroyNotify(boolean b) { handleDestroyNotify = b; @@ -2498,21 +2501,34 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } } - protected void windowDestroyNotify() { + /** + * Triggered by implementation's WM events or programmatically + * + * @param force if true, overrides {@link #setDefaultCloseOperation(int)} with {@link WindowClosingProtocol#DISPOSE_ON_CLOSE} + * and hence force destruction. Otherwise is follows the user settings. + * @return true if this window is no more valid and hence has been destroyed, otherwise false. + */ + protected boolean windowDestroyNotify(boolean force) { if(DEBUG_IMPLEMENTATION) { - System.err.println("Window.windowDestroyNotify START "+getThreadName()); + System.err.println("Window.windowDestroyNotify(force: "+force+") START "+getThreadName()+": "+this); + } + if(force) { + setDefaultCloseOperation(WindowClosingProtocol.DISPOSE_ON_CLOSE); } // send synced destroy notifications enqueueWindowEvent(true, WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY); - if(handleDestroyNotify && DISPOSE_ON_CLOSE == defaultCloseOperation) { + if(handleDestroyNotify && DISPOSE_ON_CLOSE == getDefaultCloseOperation()) { destroy(); } + + final boolean destroyed = !isNativeValid(); if(DEBUG_IMPLEMENTATION) { - System.err.println("Window.windowDestroyeNotify END "+getThreadName()); + System.err.println("Window.windowDestroyNotify(force: "+force+") END "+getThreadName()+": destroyed "+destroyed+", "+this); } + return destroyed; } public void windowRepaint(int x, int y, int width, int height) { diff --git a/src/newt/classes/jogamp/newt/driver/android/AndroidWindow.java b/src/newt/classes/jogamp/newt/driver/android/AndroidWindow.java index 4547db831..63d5f7003 100644 --- a/src/newt/classes/jogamp/newt/driver/android/AndroidWindow.java +++ b/src/newt/classes/jogamp/newt/driver/android/AndroidWindow.java @@ -329,8 +329,7 @@ public class AndroidWindow extends jogamp.newt.WindowImpl implements Callback2 { if(0!=surfaceHandle && androidFormat != aFormat ) { // re-create Log.d(MD.TAG, "surfaceChanged (destroy old)"); - windowDestroyNotify(); - if(isNativeValid()) { + if(!windowDestroyNotify(true)) { destroy(); } surfaceHandle = 0; @@ -371,7 +370,7 @@ public class AndroidWindow extends jogamp.newt.WindowImpl implements Callback2 { public void surfaceDestroyed(SurfaceHolder holder) { Log.d(MD.TAG, "surfaceDestroyed"); - windowDestroyNotify(); + windowDestroyNotify(true); // actually too late .. however .. } public void surfaceRedrawNeeded(SurfaceHolder holder) { diff --git a/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java b/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java index c926d44ee..b45c60e69 100644 --- a/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java +++ b/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java @@ -77,19 +77,19 @@ public class MacWindow extends WindowImpl implements SurfaceChangeable, DriverCl protected void closeNativeImpl() { try { if(DEBUG_IMPLEMENTATION) { System.err.println("MacWindow.CloseAction "+Thread.currentThread().getName()); } - if (getWindowHandle() != 0) { - close0(getWindowHandle()); + final long handle = getWindowHandle(); + setWindowHandle(0); + surfaceHandle = 0; + sscSurfaceHandle = 0; + isOffscreenInstance = false; + if (0 != handle) { + close0(handle); } } catch (Throwable t) { if(DEBUG_IMPLEMENTATION) { Exception e = new Exception("Warning: closeNative failed - "+Thread.currentThread().getName(), t); e.printStackTrace(); } - } finally { - setWindowHandle(0); - surfaceHandle = 0; - sscSurfaceHandle = 0; - isOffscreenInstance = false; } } diff --git a/src/newt/classes/jogamp/newt/driver/x11/X11Window.java b/src/newt/classes/jogamp/newt/driver/x11/X11Window.java index 703b18272..143b94a57 100644 --- a/src/newt/classes/jogamp/newt/driver/x11/X11Window.java +++ b/src/newt/classes/jogamp/newt/driver/x11/X11Window.java @@ -117,8 +117,10 @@ public class X11Window extends WindowImpl { // client position -> top-level window position x -= i.getLeftWidth() ; y -= i.getTopHeight() ; - } - reconfigureWindow0( getDisplayEDTHandle(), getScreenIndex(), getParentWindowHandle(), getWindowHandle(), + } + final X11Display display = (X11Display) getScreen().getDisplay(); + reconfigureWindow0( getDisplayEDTHandle(), getScreenIndex(), + getParentWindowHandle(), getWindowHandle(), display.getWindowDeleteAtom(), x, y, width, height, flags); return true; @@ -243,7 +245,7 @@ public class X11Window extends WindowImpl { int x, int y, int width, int height, boolean autoPosition, int flags); private native void CloseWindow0(long display, long windowHandle, long javaObjectAtom, long windowDeleteAtom); private native void reconfigureWindow0(long display, int screen_index, long parentWindowHandle, long windowHandle, - int x, int y, int width, int height, int flags); + long windowDeleteAtom, int x, int y, int width, int height, int flags); private native void requestFocus0(long display, long windowHandle, boolean force); private static native void setTitle0(long display, long windowHandle, String title); |