Jogamp
Bug 1247 - TestGearsNewtAWTWrapper fails AWT recreation case removeNotify -> addNotif...
authorSven Gothel <sgothel@jausoft.com>
Fri, 9 Oct 2015 04:14:00 +0000 (06:14 +0200)
committerSven Gothel <sgothel@jausoft.com>
Fri, 9 Oct 2015 04:14:00 +0000 (06:14 +0200)
AWTCanvas removeNotify didn't cause 'local' destruction of the NEWT window,
allowing a 'recreate' w/ subsequent addNotify.

This case has been hacked-into NEWT.AWT.WindowDriver + AWTCanvas:
  - suppression of window destroy events
  - keeping fields/states intact in NEWT.AWT.WindowDriver
  - propagating signals appropriately

Note: This is barely a working hack and not a fine piece of software :)

This AWT backend driver exists only due to historical reasons.

This hack simply proves that JAWTWindow works properly.

make/scripts/tests.sh
src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java
src/newt/classes/jogamp/newt/driver/awt/WindowDriver.java

index b584cfc..60ef1e9 100644 (file)
@@ -253,7 +253,7 @@ function jrun() {
     #D_ARGS="-Dnewt.debug.Window -Dnewt.debug.Window.KeyEvent"
     #D_ARGS="-Dnewt.debug.Window -Dnewt.debug.Window.MouseEvent -Dnewt.debug.Window.KeyEvent"
     #D_ARGS="-Dnewt.debug.Window"
-    D_ARGS="-Dnewt.debug.Window.visibility.failure.freeze"
+    #D_ARGS="-Dnewt.debug.Window.visibility.failure.freeze"
     #D_ARGS="-Xprof"
     #D_ARGS="-Dnativewindow.debug=all -Djogl.debug=all -Dnewt.debug=all"
     #D_ARGS="-Djogl.debug.GLCanvas -Djogl.debug.Java2D -Djogl.debug.GLJPanel"
@@ -474,7 +474,7 @@ function testawtswt() {
 #testawt com.jogamp.opengl.test.junit.jogl.demos.gl2.awt.TestGearsAWTAnalyzeBug455 $*
 #testawt com.jogamp.opengl.test.junit.jogl.demos.gl2.awt.TestGearsGLJPanelAWT $*
 #testawt com.jogamp.opengl.test.junit.jogl.demos.gl2.awt.TestGearsGLJPanelAWTBug450 $*
-#testawt com.jogamp.opengl.test.junit.jogl.demos.gl2.newt.TestGearsNewtAWTWrapper $*
+testawt com.jogamp.opengl.test.junit.jogl.demos.gl2.newt.TestGearsNewtAWTWrapper $*
 #testnoawt com.jogamp.opengl.test.junit.jogl.demos.gl2.newt.TestGearsNEWT $*
 #testnoawt com.jogamp.opengl.test.junit.jogl.demos.gl2.newt.TestTeapotNEWT $*
 #testnoawt com.jogamp.opengl.test.junit.jogl.demos.gl3.newt.TestGeomShader01TextureGL3NEWT $*
@@ -810,7 +810,7 @@ function testawtswt() {
 #   - setVisible(false) IconicState not listening to _NET_WM_STATE_HIDDEN; 
 #   - setVisible(true) not restoring from _NET_WM_STATE_HIDDEN
 #testnoawt com.jogamp.opengl.test.junit.newt.TestGLWindows00NEWT $*
-testnoawt com.jogamp.opengl.test.junit.newt.parenting.TestParenting01NEWT $*
+#testnoawt com.jogamp.opengl.test.junit.newt.parenting.TestParenting01NEWT $*
 
 #
 # NEWT Parenting (w/ NEWT, AWT or SWT)
index 8f9efdc..bdf7838 100644 (file)
@@ -165,6 +165,7 @@ public class AWTCanvas extends Canvas {
     if(null!=gc) {
         device = gc.getDevice();
     }
+    driver.localCreate();
     if(Window.DEBUG_IMPLEMENTATION) {
         System.err.println(getThreadName()+": AWTCanvas.addNotify.X");
     }
@@ -194,13 +195,13 @@ public class AWTCanvas extends Canvas {
           System.err.println(getThreadName()+": AWTCanvas.removeNotify.0: Created Config: "+awtConfig);
       }
       try {
-        dispose();
+        driver.localDestroy();
       } finally {
         super.removeNotify();
       }
   }
 
-  private void dispose() {
+  void dispose() {
     if( null != jawtWindow ) {
         jawtWindow.destroy();
         if(Window.DEBUG_IMPLEMENTATION) {
index 8399bdb..aa93dd9 100644 (file)
@@ -74,6 +74,8 @@ public class WindowDriver extends WindowImpl {
 
     public WindowDriver(final Container container) {
         super();
+        this.withinLocalDispose = false;
+        this.addWindowListener(0, new NEWTWindowListener());
         this.awtContainer = container;
         if(container instanceof Frame) {
             awtFrame = (Frame) container;
@@ -85,6 +87,7 @@ public class WindowDriver extends WindowImpl {
     /** same instance as container, just for impl. convenience */
     private Frame awtFrame = null;
     private AWTCanvas awtCanvas;
+    private volatile boolean withinLocalDispose;
 
     @Override
     protected void requestFocusImpl(final boolean reparented) {
@@ -112,64 +115,98 @@ public class WindowDriver extends WindowImpl {
 
     @Override
     protected void createNativeImpl() {
-        if(0!=getParentWindowHandle()) {
-            throw new RuntimeException("Window parenting not supported in AWT, use AWTWindow(Frame) cstr for wrapping instead");
-        }
-
-        if(null==awtContainer) {
-            awtFrame = new Frame();
-            awtContainer = awtFrame;
-            owningFrame=true;
+        if( withinLocalDispose ) {
+            setupHandleAndGC();
+            definePosition(getX(), getY()); // clear AUTOPOS
+            visibleChanged(false, true);
+            withinLocalDispose = false;
         } else {
-            owningFrame=false;
-            defineSize(awtContainer.getWidth(), awtContainer.getHeight());
-            definePosition(awtContainer.getX(), awtContainer.getY());
-        }
-        if(null!=awtFrame) {
-            awtFrame.setTitle(getTitle());
-        }
-        awtContainer.setLayout(new BorderLayout());
+            if(0!=getParentWindowHandle()) {
+                throw new RuntimeException("Window parenting not supported in AWT, use AWTWindow(Frame) cstr for wrapping instead");
+            }
 
-        if( null == awtCanvas ) {
-            awtCanvas = new AWTCanvas(capsRequested, WindowDriver.this.capabilitiesChooser, upstreamScalable);
+            if(null==awtContainer) {
+                awtFrame = new Frame();
+                awtContainer = awtFrame;
+                owningFrame=true;
+            } else {
+                owningFrame=false;
+                defineSize(awtContainer.getWidth(), awtContainer.getHeight());
+                definePosition(awtContainer.getX(), awtContainer.getY());
+            }
+            if(null!=awtFrame) {
+                awtFrame.setTitle(getTitle());
+            }
+            awtContainer.setLayout(new BorderLayout());
 
-            // canvas.addComponentListener(listener);
-            awtContainer.add(awtCanvas, BorderLayout.CENTER);
+            if( null == awtCanvas ) {
+                awtCanvas = new AWTCanvas(this, capsRequested, WindowDriver.this.capabilitiesChooser, upstreamScalable);
 
-            // via EDT ..
-            new AWTMouseAdapter(this).addTo(awtCanvas); // fwd all AWT Mouse events to here
-            new AWTKeyAdapter(this).addTo(awtCanvas); // fwd all AWT Key events to here
+                // canvas.addComponentListener(listener);
+                awtContainer.add(awtCanvas, BorderLayout.CENTER);
 
-            // direct w/o EDT
-            new AWTWindowAdapter(new LocalWindowListener(), this).addTo(awtCanvas); // fwd all AWT Window events to here
+                // via EDT ..
+                new AWTMouseAdapter(this).addTo(awtCanvas); // fwd all AWT Mouse events to here
+                new AWTKeyAdapter(this).addTo(awtCanvas); // fwd all AWT Key events to here
+
+                // direct w/o EDT
+                new AWTWindowAdapter(new AWTWindowListener(), this).addTo(awtCanvas); // fwd all AWT Window events to here
+            } else {
+                awtContainer.add(awtCanvas, BorderLayout.CENTER);
+            }
+            reconfigureWindowImpl(getX(), getY(), getWidth(), getHeight(), getReconfigureMask(CHANGE_MASK_VISIBILITY | CHANGE_MASK_DECORATION, true));
+            // throws exception if failed ..
+            // AWTCanvas -> localCreate -> setupHandleAndGC();
         }
+    }
 
-        reconfigureWindowImpl(getX(), getY(), getWidth(), getHeight(), getReconfigureMask(CHANGE_MASK_VISIBILITY | CHANGE_MASK_DECORATION, true));
-        // throws exception if failed ..
+    private void setupHandleAndGC() {
+        // reconfigureWindowImpl(getX(), getY(), getWidth(), getHeight(), getReconfigureMask(CHANGE_MASK_VISIBILITY | CHANGE_MASK_DECORATION, true));
+        if( null != awtCanvas ) {
+            final NativeWindow nw = awtCanvas.getNativeWindow();
+            if( null != nw ) {
+                setGraphicsConfiguration( awtCanvas.getAWTGraphicsConfiguration() );
+                setWindowHandle( nw.getWindowHandle() );
+            }
+        }
+    }
 
-        final NativeWindow nw = awtCanvas.getNativeWindow();
-        if( null != nw ) {
-            setGraphicsConfiguration( awtCanvas.getAWTGraphicsConfiguration() );
-            setWindowHandle( nw.getWindowHandle() );
+    void localCreate() {
+        if( withinLocalDispose ) {
+            setVisible(true);
+        } else {
+            setupHandleAndGC();
         }
     }
 
+    void localDestroy() {
+        this.withinLocalDispose = true;
+        super.destroy();
+    }
+
     @Override
     protected void closeNativeImpl() {
         setWindowHandle(0);
-        if(null!=awtContainer) {
-            awtContainer.setVisible(false);
-            awtContainer.remove(awtCanvas);
-            awtContainer.setEnabled(false);
-            awtCanvas.setEnabled(false);
-        }
-        if(owningFrame && null!=awtFrame) {
-            awtFrame.dispose();
-            owningFrame=false;
+        if( this.withinLocalDispose ) {
+            if(null!=awtCanvas) {
+                awtCanvas.dispose();
+            }
+        } else {
+            if(null!=awtContainer) {
+                awtContainer.setVisible(false);
+                awtContainer.remove(awtCanvas);
+                awtContainer.setEnabled(false);
+                awtCanvas.setEnabled(false);
+                awtCanvas.dispose();
+            }
+            if(owningFrame && null!=awtFrame) {
+                awtFrame.dispose();
+                owningFrame=false;
+            }
+            awtCanvas = null;
+            awtFrame = null;
+            awtContainer = null;
         }
-        awtCanvas = null;
-        awtFrame = null;
-        awtContainer = null;
     }
 
     @Override
@@ -266,6 +303,7 @@ public class WindowDriver extends WindowImpl {
         if( awtContainer.getX() != x || awtContainer.getY() != y ) {
             awtContainer.setLocation(x, y);
         }
+        definePosition(x, y);
 
         if( 0 != ( CHANGE_MASK_VISIBILITY & flags) ) {
             if( 0 != ( STATE_MASK_VISIBLE & flags ) ) {
@@ -280,6 +318,9 @@ public class WindowDriver extends WindowImpl {
             }
             visibleChanged(false, 0 != ( STATE_MASK_VISIBLE & flags));
         }
+        if( isVisible() ) {
+            windowRepaint(false, 0, 0, getSurfaceWidth(), getSurfaceHeight());
+        }
 
         return true;
     }
@@ -296,7 +337,7 @@ public class WindowDriver extends WindowImpl {
         return ( null != awtCanvas ) ? awtCanvas.getNativeWindow() : null;
     }
 
-    class LocalWindowListener implements com.jogamp.newt.event.WindowListener {
+    class AWTWindowListener implements com.jogamp.newt.event.WindowListener {
         @Override
         public void windowMoved(final com.jogamp.newt.event.WindowEvent e) {
             if(null!=awtContainer) {
@@ -339,4 +380,28 @@ public class WindowDriver extends WindowImpl {
             }
         }
     }
+    class NEWTWindowListener implements com.jogamp.newt.event.WindowListener {
+        @Override
+        public void windowMoved(final com.jogamp.newt.event.WindowEvent e) { }
+        @Override
+        public void windowResized(final com.jogamp.newt.event.WindowEvent e) { }
+        @Override
+        public void windowDestroyNotify(final WindowEvent e) {
+            if( withinLocalDispose ) {
+                e.setConsumed(true);
+            }
+        }
+        @Override
+        public void windowDestroyed(final WindowEvent e) {
+            if( withinLocalDispose ) {
+                e.setConsumed(true);
+            }
+        }
+        @Override
+        public void windowGainedFocus(final WindowEvent e) { }
+        @Override
+        public void windowLostFocus(final WindowEvent e) { }
+        @Override
+        public void windowRepaint(final WindowUpdateEvent e) { }
+    }
 }
http://JogAmp.org git info: FAQ, tutorial and man pages.