diff options
Diffstat (limited to 'src/newt')
19 files changed, 390 insertions, 174 deletions
diff --git a/src/newt/classes/com/jogamp/newt/Window.java b/src/newt/classes/com/jogamp/newt/Window.java index cc42465f1..ab1eef308 100644 --- a/src/newt/classes/com/jogamp/newt/Window.java +++ b/src/newt/classes/com/jogamp/newt/Window.java @@ -28,12 +28,15 @@ package com.jogamp.newt; +import com.jogamp.newt.event.WindowEvent; import com.jogamp.newt.event.WindowListener; import com.jogamp.newt.event.KeyListener; import com.jogamp.newt.event.KeyEvent; import com.jogamp.newt.event.InputEvent; import com.jogamp.newt.event.MouseListener; import jogamp.newt.Debug; +import jogamp.newt.WindowImpl; + import javax.media.nativewindow.CapabilitiesChooser; import javax.media.nativewindow.CapabilitiesImmutable; import javax.media.nativewindow.NativeWindow; @@ -104,14 +107,26 @@ public interface Window extends NativeWindow, WindowClosingProtocol { CapabilitiesImmutable getChosenCapabilities(); /** - * Destroy the Window and it's children, incl. native destruction.<br> - * The Window can be recreate via {@link #setVisible(boolean) setVisible(true)}. - * <p>Visibility is set to false.</p> + * {@inheritDoc} + * <p> + * Also iterates through this window's children and destroys them. + * </p> + * <p> + * Visibility is set to false. + * </p> + * <p> + * Method sends out {@link WindowEvent#EVENT_WINDOW_DESTROY_NOTIFY pre-} and + * {@link WindowEvent#EVENT_WINDOW_DESTROYED post-} destruction events + * to all of it's {@link WindowListener}. + * </p> * <p> * This method invokes {@link Screen#removeReference()} after it's own destruction,<br> * which will issue {@link Screen#destroy()} if the reference count becomes 0.<br> * This destruction sequence shall end up in {@link Display#destroy()}, if all reference counts become 0. * </p> + * <p> + * The Window can be recreate via {@link #setVisible(boolean) setVisible(true)}. + * </p> * @see #destroy() * @see #setVisible(boolean) */ @@ -119,6 +134,16 @@ public interface Window extends NativeWindow, WindowClosingProtocol { void destroy(); /** + * Set a custom action handling destruction issued by a {@link WindowImpl#windowDestroyNotify(boolean) toolkit triggered window destroy} + * replacing the default {@link #destroy()} action. + * <p> + * The custom action shall call {@link #destroy()} + * but may perform further tasks before and after. + * </p> + */ + void setWindowDestroyNotifyAction(Runnable r); + + /** * <code>setVisible</code> makes the window and children visible if <code>visible</code> is true, * otherwise the window and children becomes invisible. * <p> @@ -383,10 +408,13 @@ public interface Window extends NativeWindow, WindowClosingProtocol { // WindowListener // + /** + * Send a {@link WindowEvent} to all {@link WindowListener}. + * @param eventType a {@link WindowEvent} type, e.g. {@link WindowEvent#EVENT_WINDOW_REPAINT}. + */ public void sendWindowEvent(int eventType); /** - * * Appends the given {@link com.jogamp.newt.event.WindowListener} to the end of * the list. */ diff --git a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java index 3503dabd5..3c10859bf 100644 --- a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java +++ b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java @@ -51,6 +51,7 @@ import javax.swing.MenuSelectionManager; import jogamp.nativewindow.awt.AWTMisc; import jogamp.newt.Debug; +import jogamp.newt.WindowImpl; import jogamp.newt.awt.NewtFactoryAWT; import jogamp.newt.awt.event.AWTParentWindowAdapter; import jogamp.newt.driver.DriverClearFocus; @@ -59,9 +60,9 @@ import com.jogamp.nativewindow.awt.AWTWindowClosingProtocol; import com.jogamp.nativewindow.awt.JAWTWindow; import com.jogamp.newt.Display; import com.jogamp.newt.Window; -import com.jogamp.newt.event.InputEvent; import com.jogamp.newt.event.KeyEvent; import com.jogamp.newt.event.KeyListener; +import com.jogamp.newt.event.NEWTEvent; import com.jogamp.newt.event.WindowAdapter; import com.jogamp.newt.event.WindowEvent; import com.jogamp.newt.event.WindowListener; @@ -88,16 +89,22 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto private boolean newtChildAttached = false; private boolean isOnscreen = true; private WindowClosingMode newtChildCloseOp; - private AWTAdapter awtAdapter = null; + private AWTParentWindowAdapter awtAdapter = null; private AWTAdapter awtMouseAdapter = null; private AWTAdapter awtKeyAdapter = null; private AWTWindowClosingProtocol awtWindowClosingProtocol = new AWTWindowClosingProtocol(this, new Runnable() { public void run() { - NewtCanvasAWT.this.destroy(); + NewtCanvasAWT.this.destroyImpl(false /* removeNotify */, true /* windowClosing */); } - }); + }, new Runnable() { + public void run() { + if( newtChild != null ) { + newtChild.sendWindowEvent(WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY); + } + } + } ); /** * Instantiates a NewtCanvas without a NEWT child.<br> @@ -209,7 +216,7 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto } public void keyTyped(KeyEvent e) { if(suppress) { - e.setAttachment(InputEvent.consumedTag); + e.setAttachment(NEWTEvent.consumedTag); suppress = false; // reset } } @@ -239,7 +246,7 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto } } if(suppress) { - evt.setAttachment(InputEvent.consumedTag); + evt.setAttachment(NEWTEvent.consumedTag); } if(DEBUG) { System.err.println("NewtCanvasAWT.focusKey: XXX: "+ks); @@ -361,27 +368,17 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto ", displayable "+isDisplayable()+", cont "+AWTMisc.getContainer(this)); } } + awtWindowClosingProtocol.addClosingListener(); } @Override public void removeNotify() { + awtWindowClosingProtocol.removeClosingListener(); + if( Beans.isDesignTime() ) { super.removeNotify(); } else { - java.awt.Container cont = AWTMisc.getContainer(this); - if(DEBUG) { - System.err.println("NewtCanvasAWT.removeNotify: "+newtChild+", from "+cont); - } - // Detach OLS early.. - final OffscreenLayerSurface ols = NativeWindowFactory.getOffscreenLayerSurface(newtChild, true); - if(null != ols && ols.isSurfaceLayerAttached()) { - ols.detachSurfaceLayer(); - } - detachNewtChild(cont); // will destroy context (offscreen -> onscreen) and implicit detachSurfaceLayer (if still attached) - - NewtFactoryAWT.destroyNativeWindow(jawtWindow); - jawtWindow=null; - + destroyImpl(true /* removeNotify */, false /* windowClosing */); super.removeNotify(); } } @@ -397,20 +394,32 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto * @see Window#destroy() */ public final void destroy() { + destroyImpl(false /* removeNotify */, false /* windowClosing */); + } + + private final void destroyImpl(boolean removeNotify, boolean windowClosing) { if( null !=newtChild ) { java.awt.Container cont = AWTMisc.getContainer(this); if(DEBUG) { - System.err.println("NewtCanvasAWT.destroy(): "+newtChild+", from "+cont); + System.err.println("NewtCanvasAWT.destroy(removeNotify "+removeNotify+", windowClosing "+windowClosing+"): nw "+newtWinHandleToHexString(newtChild)+", from "+cont); } - // Detach OLS early.. - final OffscreenLayerSurface ols = NativeWindowFactory.getOffscreenLayerSurface(newtChild, true); - if(null != ols && ols.isSurfaceLayerAttached()) { - ols.detachSurfaceLayer(); - } - detachNewtChild(cont); // will destroy context (offscreen -> onscreen) and implicit detachSurfaceLayer (if still attached) - newtChild.destroy(); - newtChild=null; + detachNewtChild(cont); + + if( !removeNotify ) { + final Window cWin = newtChild; + final Window dWin = cWin.getDelegatedWindow(); + newtChild=null; + if( windowClosing && dWin instanceof WindowImpl ) { + ((WindowImpl)dWin).windowDestroyNotify(true); + } else { + cWin.destroy(); + } + } } + if( ( removeNotify || windowClosing ) && null!=jawtWindow) { + NewtFactoryAWT.destroyNativeWindow(jawtWindow); + jawtWindow=null; + } } @Override @@ -501,8 +510,6 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto return false; } - awtWindowClosingProtocol.addClosingListenerOneShot(); - if( attachNewtChild && !newtChildAttached && null != newtChild ) { attachNewtChild(cont); } @@ -535,11 +542,11 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto throw new InternalError("XXX"); } isOnscreen = jawtWindow.getGraphicsConfiguration().getChosenCapabilities().isOnscreen(); - awtAdapter = new AWTParentWindowAdapter(jawtWindow, newtChild).addTo(this); + awtAdapter = (AWTParentWindowAdapter) new AWTParentWindowAdapter(jawtWindow, newtChild).addTo(this); + awtAdapter.removeWindowClosingFrom(this); // we utilize AWTWindowClosingProtocol triggered destruction! newtChild.addWindowListener(clearAWTMenusOnNewtFocus); newtChild.setFocusAction(focusAction); // enable AWT focus traversal newtChildCloseOp = newtChild.setDefaultCloseOperation(WindowClosingMode.DO_NOTHING_ON_CLOSE); - awtWindowClosingProtocol.addClosingListenerOneShot(); keyboardFocusManager = KeyboardFocusManager.getCurrentKeyboardFocusManager(); keyboardFocusManager.addPropertyChangeListener("focusOwner", focusPropertyChangeListener); if(isOnscreen) { @@ -554,7 +561,6 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto newtChild.removeWindowListener(clearAWTMenusOnNewtFocus); newtChild.setFocusAction(null); newtChild.setDefaultCloseOperation(newtChildCloseOp); - awtWindowClosingProtocol.removeClosingListener(); } } } @@ -611,7 +617,14 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto newtChild.setFocusAction(null); // no AWT focus traversal .. configureNewtChild(false); newtChild.setVisible(false); - newtChild.reparentWindow(null); + + // Detach OLS early.. + final OffscreenLayerSurface ols = NativeWindowFactory.getOffscreenLayerSurface(newtChild, true); + if(null != ols && ols.isSurfaceLayerAttached()) { + ols.detachSurfaceLayer(); + } + newtChild.reparentWindow(null); // will destroy context (offscreen -> onscreen) and implicit detachSurfaceLayer (if still attached) + if(DEBUG) { System.err.println("NewtCanvasAWT.detachNewtChild.X: win "+newtWinHandleToHexString(newtChild)+", EDTUtil: cur "+newtChild.getScreen().getDisplay().getEDTUtil()+", comp "+this); } 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 07004503e..c3ad51c96 100755 --- a/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtAppletBase.java +++ b/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtAppletBase.java @@ -300,9 +300,7 @@ public class JOGLNewtAppletBase implements KeyListener, GLEventListener { glWindow.reparentWindow(awtParent); } else { glWindow.reparentWindow(null); - if(glClosable) { - glWindow.setDefaultCloseOperation(WindowClosingMode.DISPOSE_ON_CLOSE); - } + glWindow.setDefaultCloseOperation( glClosable ? WindowClosingMode.DISPOSE_ON_CLOSE : WindowClosingMode.DO_NOTHING_ON_CLOSE ); } } } diff --git a/src/newt/classes/com/jogamp/newt/event/InputEvent.java b/src/newt/classes/com/jogamp/newt/event/InputEvent.java index 9ef4de2b6..4920b59ea 100644 --- a/src/newt/classes/com/jogamp/newt/event/InputEvent.java +++ b/src/newt/classes/com/jogamp/newt/event/InputEvent.java @@ -81,11 +81,6 @@ public abstract class InputEvent extends NEWTEvent return 0; } - /** Object when attached via {@link #setAttachment(Object)} marks the event consumed, - * ie. stops propagating the event any further to the event listener. - */ - public static final Object consumedTag = new Object(); - protected InputEvent(short eventType, Object source, long when, int modifiers) { super(eventType, source, when); this.modifiers=modifiers; diff --git a/src/newt/classes/com/jogamp/newt/event/KeyEvent.java b/src/newt/classes/com/jogamp/newt/event/KeyEvent.java index f626fec38..5117ffe29 100644 --- a/src/newt/classes/com/jogamp/newt/event/KeyEvent.java +++ b/src/newt/classes/com/jogamp/newt/event/KeyEvent.java @@ -872,6 +872,11 @@ public class KeyEvent extends InputEvent public static final short VK_BEGIN = (short) 0xFF58; /** + * Constant for Keyboard became invisible, e.g. Android's soft keyboard Back button hit while keyboard is visible. + */ + public static final short VK_KEYBOARD_INVISIBLE = (short) 0xDEAD; + + /** * This value is used to indicate that the keyCode is unknown. * KEY_TYPED events do not have a keyCode value; this value * is used instead. diff --git a/src/newt/classes/com/jogamp/newt/event/MouseEvent.java b/src/newt/classes/com/jogamp/newt/event/MouseEvent.java index 23549533e..8ad1f3f24 100644 --- a/src/newt/classes/com/jogamp/newt/event/MouseEvent.java +++ b/src/newt/classes/com/jogamp/newt/event/MouseEvent.java @@ -70,7 +70,8 @@ public class MouseEvent extends InputEvent super(eventType, source, when, modifiers); this.x = new int[]{x}; this.y = new int[]{y}; - this.pressure = new float[]{0}; + this.pressure = new float[]{0f}; + this.maxPressure= 1.0f; this.pointerids = new short[]{-1}; this.clickCount=clickCount; this.button=button; @@ -78,8 +79,8 @@ public class MouseEvent extends InputEvent } public MouseEvent(short eventType, Object source, long when, - int modifiers, int[] x, int[] y, float[] pressure, short[] pointerids, short clickCount, short button, - float rotation) + int modifiers, int[] x, int[] y, float[] pressure, float maxPressure, short[] pointerids, short clickCount, + short button, float rotation) { super(eventType, source, when, modifiers); this.x = x; @@ -89,7 +90,11 @@ public class MouseEvent extends InputEvent pointerids.length != y.length) { throw new IllegalArgumentException("All multiple pointer arrays must be of same size"); } + if( 0.0f >= maxPressure ) { + throw new IllegalArgumentException("maxPressure must be > 0.0f"); + } this.pressure = pressure; + this.maxPressure= maxPressure; this.pointerids = pointerids; this.clickCount=clickCount; this.button=button; @@ -129,28 +134,59 @@ public class MouseEvent extends InputEvent } /** - * @return x-coord at index where index refers to the - * data coming from a pointer. + * @param index pointer-index within [0 .. {@link #getPointerCount()}-1] + * @return X-Coord associated with the pointer-index. * @see getPointerId(index) */ public int getX(int index) { return x[index]; } + /** + * @param index pointer-index within [0 .. {@link #getPointerCount()}-1] + * @return Y-Coord associated with the pointer-index. + * @see getPointerId(index) + */ public int getY(int index) { return y[index]; } - public float getPressure(){ - return pressure[0]; + /** + * @param normalized if true, method returns the normalized pressure, i.e. <code>pressure / maxPressure</code> + * @return The pressure associated with the pointer-index 0. + * The value of zero is return if not available. + * @see #getMaxPressure() + */ + public float getPressure(boolean normalized){ + return normalized ? pressure[0] / maxPressure : pressure[0]; + } + + /** + * Returns the maximum pressure known for the input device generating this event. + * <p> + * This value may be self calibrating on devices/OS, where no known maximum pressure is known. + * Hence subsequent events may return a higher value. + * </p> + * <p> + * Self calibrating maximum pressure is performed on: + * <ul> + * <li>Android</li> + * </ul> + * </p> + */ + public float getMaxPressure() { + return maxPressure; } /** - * @return the pressure associated with the pointer at index. - * the value of zero is return if not available. + * @param index pointer-index within [0 .. {@link #getPointerCount()}-1] + * @param normalized if true, method returns the normalized pressure, i.e. <code>pressure / maxPressure</code> + * @return The pressure associated with the pointer-index. + * The value of zero is return if not available. + * @see #getMaxPressure() */ - public float getPressure(int index){ - return pressure[index]; + public float getPressure(int index, boolean normalized){ + return normalized ? pressure[index] / maxPressure : pressure[index]; } /** @@ -199,8 +235,8 @@ public class MouseEvent extends InputEvent sb.append(", "); } sb.append(pointerids[i]).append(": ") - .append(x[i]).append(" / ").append(y[i]).append(" ") - .append(pressure[i]).append("p"); + .append(x[i]).append("/").append(y[i]).append(", ") + .append("p[").append(pressure[i]).append("/").append(maxPressure).append("=").append(pressure[i]/maxPressure).append("]"); } sb.append("]"); } @@ -225,6 +261,7 @@ public class MouseEvent extends InputEvent private final short clickCount, button; private final float wheelRotation; private final float pressure[]; + private final float maxPressure; private final short pointerids[]; public static final short EVENT_MOUSE_CLICKED = 200; diff --git a/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java b/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java index b8de6eb18..17210cef8 100644 --- a/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java +++ b/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java @@ -48,6 +48,12 @@ package com.jogamp.newt.event; */ @SuppressWarnings("serial") public class NEWTEvent extends java.util.EventObject { + /** + * Object when attached via {@link #setAttachment(Object)} marks the event consumed, + * ie. stops propagating the event any further to the <i>other</i> event listener. + */ + public static final Object consumedTag = new Object(); + private final short eventType; private final long when; private Object attachment; @@ -101,7 +107,7 @@ public class NEWTEvent extends java.util.EventObject { return sb.append("NEWTEvent[source:").append(getSource().getClass().getName()).append(", when:").append(getWhen()).append(" d ").append((System.currentTimeMillis()-getWhen())).append("ms]"); } - static String toHexString(short hex) { + public static String toHexString(short hex) { return "0x" + Integer.toHexString( (int)hex & 0x0000FFFF ); } } diff --git a/src/newt/classes/com/jogamp/newt/event/WindowListener.java b/src/newt/classes/com/jogamp/newt/event/WindowListener.java index 011e1f654..dde182510 100644 --- a/src/newt/classes/com/jogamp/newt/event/WindowListener.java +++ b/src/newt/classes/com/jogamp/newt/event/WindowListener.java @@ -36,6 +36,7 @@ package com.jogamp.newt.event; import javax.media.nativewindow.WindowClosingProtocol; +/** NEWT {@link WindowEvent} listener. */ public interface WindowListener extends NEWTEventListener { /** Window is resized, your application shall respect the new window dimension. A repaint is recommended. */ public void windowResized(WindowEvent e); @@ -53,7 +54,9 @@ public interface WindowListener extends NEWTEventListener { **/ public void windowDestroyNotify(WindowEvent e); - /** Window has been destroyed.*/ + /** + * Window has been destroyed. + */ public void windowDestroyed(WindowEvent e); /** Window gained focus. */ diff --git a/src/newt/classes/com/jogamp/newt/event/awt/AWTAdapter.java b/src/newt/classes/com/jogamp/newt/event/awt/AWTAdapter.java index 8991203d5..6de2eee45 100644 --- a/src/newt/classes/com/jogamp/newt/event/awt/AWTAdapter.java +++ b/src/newt/classes/com/jogamp/newt/event/awt/AWTAdapter.java @@ -181,8 +181,13 @@ public abstract class AWTAdapter implements java.util.EventListener /** @see #addTo(java.awt.Component) */ public abstract AWTAdapter removeFrom(java.awt.Component awtComponent); + /** + * Enqueues the event to the {@link #getNewtWindow()} is not null. + */ void enqueueEvent(boolean wait, com.jogamp.newt.event.NEWTEvent event) { - newtWindow.enqueueEvent(wait, event); + if( null != newtWindow ) { + newtWindow.enqueueEvent(wait, event); + } } } diff --git a/src/newt/classes/com/jogamp/newt/event/awt/AWTWindowAdapter.java b/src/newt/classes/com/jogamp/newt/event/awt/AWTWindowAdapter.java index 2d63ca455..e91bb2f82 100644 --- a/src/newt/classes/com/jogamp/newt/event/awt/AWTWindowAdapter.java +++ b/src/newt/classes/com/jogamp/newt/event/awt/AWTWindowAdapter.java @@ -66,13 +66,18 @@ public class AWTWindowAdapter return this; } - public AWTAdapter removeFrom(java.awt.Component awtComponent) { - awtComponent.removeFocusListener(this); - awtComponent.removeComponentListener(this); + public AWTAdapter removeWindowClosingFrom(java.awt.Component awtComponent) { java.awt.Window win = getWindow(awtComponent); if( null != win && null != windowClosingListener ) { win.removeWindowListener(windowClosingListener); } + return this; + } + + public AWTAdapter removeFrom(java.awt.Component awtComponent) { + awtComponent.removeFocusListener(this); + awtComponent.removeComponentListener(this); + removeWindowClosingFrom(awtComponent); if(awtComponent instanceof java.awt.Window) { ((java.awt.Window)awtComponent).removeWindowListener(this); } @@ -220,9 +225,16 @@ public class AWTWindowAdapter enqueueEvent(true, event); } } + public void windowClosed(java.awt.event.WindowEvent e) { + com.jogamp.newt.event.WindowEvent event = AWTNewtEventFactory.createWindowEvent(e, newtWindow); + if(null!=newtListener) { + ((com.jogamp.newt.event.WindowListener)newtListener).windowDestroyed(event); + } else { + enqueueEvent(true, event); + } + } public void windowActivated(java.awt.event.WindowEvent e) { } - public void windowClosed(java.awt.event.WindowEvent e) { } public void windowDeactivated(java.awt.event.WindowEvent e) { } public void windowDeiconified(java.awt.event.WindowEvent e) { } public void windowIconified(java.awt.event.WindowEvent e) { } diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java index 7fccb6622..ce50d95dd 100644 --- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java +++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java @@ -100,7 +100,10 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind protected GLWindow(Window window) { super(null, null, false /* always handle device lifecycle ourselves */); this.window = (WindowImpl) window; - this.window.setHandleDestroyNotify(false); + this.window.setWindowDestroyNotifyAction( new Runnable() { + public void run() { + defaultWindowDestroyNotifyOp(); + } } ); window.addWindowListener(new WindowAdapter() { @Override public void windowRepaint(WindowUpdateEvent e) { @@ -112,10 +115,6 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind defaultWindowResizedOp(getWidth(), getHeight()); } - @Override - public void windowDestroyNotify(WindowEvent e) { - defaultWindowDestroyNotifyOp(); - } }); this.window.setLifecycleHook(new GLLifecycleHook()); } @@ -390,6 +389,11 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind } @Override + public void setWindowDestroyNotifyAction(Runnable r) { + window.setWindowDestroyNotifyAction(r); + } + + @Override public final void setVisible(boolean visible) { window.setVisible(visible); } diff --git a/src/newt/classes/jogamp/newt/DisplayImpl.java b/src/newt/classes/jogamp/newt/DisplayImpl.java index 20b915cae..d4842ba2f 100644 --- a/src/newt/classes/jogamp/newt/DisplayImpl.java +++ b/src/newt/classes/jogamp/newt/DisplayImpl.java @@ -370,15 +370,8 @@ public abstract class DisplayImpl extends Display { DisplayImpl.this.dispatchMessages(); } }; - final void dispatchMessage(final NEWTEventTask eventTask) { - final NEWTEvent event = eventTask.get(); + final void dispatchMessage(final NEWTEvent event) { try { - if(null == event) { - // Ooops ? - System.err.println("Warning: event of eventTask is NULL"); - Thread.dumpStack(); - return; - } final Object source = event.getSource(); if(source instanceof NEWTEventConsumer) { final NEWTEventConsumer consumer = (NEWTEventConsumer) source ; @@ -396,6 +389,21 @@ public abstract class DisplayImpl extends Display { } else { re = new RuntimeException(t); } + throw re; + } + } + + final void dispatchMessage(final NEWTEventTask eventTask) { + final NEWTEvent event = eventTask.get(); + try { + if(null == event) { + // Ooops ? + System.err.println("Warning: event of eventTask is NULL"); + Thread.dumpStack(); + return; + } + dispatchMessage(event); + } catch (RuntimeException re) { if( eventTask.isCallerWaiting() ) { // propagate exception to caller eventTask.setException(re); @@ -451,7 +459,7 @@ public abstract class DisplayImpl extends Display { // can't wait if we are on EDT or NEDT -> consume right away if(wait && edtUtil.isCurrentThreadEDTorNEDT() ) { - dispatchMessage(new NEWTEventTask(e, null)); + dispatchMessage(e); return; } diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java index 222a1173c..af0bde179 100644 --- a/src/newt/classes/jogamp/newt/WindowImpl.java +++ b/src/newt/classes/jogamp/newt/WindowImpl.java @@ -110,7 +110,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer private boolean pointerConfined = false; private LifecycleHook lifecycleHook = null; - private boolean handleDestroyNotify = true; + private Runnable windowDestroyNotifyAction = null; private FocusRunnable focusAction = null; private KeyListener keyboardFocusHandler = null; @@ -864,8 +864,12 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer _lock.lock(); try { if(DEBUG_IMPLEMENTATION) { - System.err.println("Window DestroyAction() "+getThreadName()); + System.err.println("Window DestroyAction() hasScreen "+(null != screen)+", isNativeValid "+isNativeValid()+" - "+getThreadName()); } + + // send synced destroy-notify notification + sendWindowEvent(WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY); + // Childs first .. synchronized(childWindowsLock) { if(childWindows.size()>0) { @@ -875,8 +879,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer while( clonedChildWindows.size() > 0 ) { NativeWindow nw = clonedChildWindows.remove(0); if(nw instanceof WindowImpl) { - ((WindowImpl)nw).sendWindowEvent(WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY); - ((WindowImpl)nw).destroy(); + ((WindowImpl)nw).windowDestroyNotify(true); } else { nw.destroy(); } @@ -889,21 +892,19 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer lifecycleHook.destroyActionInLock(); } - if( null != screen ) { - if( isNativeValid() ) { - screen.removeScreenModeListener(screenModeListenerImpl); - closeNativeImpl(); - final AbstractGraphicsDevice cfgADevice = config.getScreen().getDevice(); - if( cfgADevice != screen.getDisplay().getGraphicsDevice() ) { // don't pull display's device - cfgADevice.close(); // ensure a cfg's device is closed - } - setGraphicsConfiguration(null); - removeScreenReference(); - } - Display dpy = screen.getDisplay(); - if(null != dpy) { - dpy.validateEDT(); + if( isNativeValid() ) { + screen.removeScreenModeListener(screenModeListenerImpl); + closeNativeImpl(); + final AbstractGraphicsDevice cfgADevice = config.getScreen().getDevice(); + if( cfgADevice != screen.getDisplay().getGraphicsDevice() ) { // don't pull display's device + cfgADevice.close(); // ensure a cfg's device is closed } + setGraphicsConfiguration(null); + } + removeScreenReference(); + Display dpy = screen.getDisplay(); + if(null != dpy) { + dpy.validateEDT(); } // send synced destroyed notification @@ -1549,14 +1550,10 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer public Object getWrappedWindow() { return null; } - - /** - * If set to true, the default value, this NEWT Window implementation will - * 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; + + @Override + public void setWindowDestroyNotifyAction(Runnable r) { + windowDestroyNotifyAction = r; } /** @@ -2211,7 +2208,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer default: throw new NativeWindowException("Unexpected mouse event type " + e.getEventType()); } - consumed = InputEvent.consumedTag == e.getAttachment(); + consumed = NEWTEvent.consumedTag == e.getAttachment(); } } @@ -2340,7 +2337,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer default: throw new NativeWindowException("Unexpected key event type " + e.getEventType()); } - return InputEvent.consumedTag == e.getAttachment(); + return NEWTEvent.consumedTag == e.getAttachment(); } @SuppressWarnings("deprecation") @@ -2446,7 +2443,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer if(DEBUG_IMPLEMENTATION) { System.err.println("consumeWindowEvent: "+e+", visible "+isVisible()+" "+getX()+"/"+getY()+" "+getWidth()+"x"+getHeight()); } - for(int i = 0; i < windowListeners.size(); i++ ) { + boolean consumed = false; + for(int i = 0; !consumed && i < windowListeners.size(); i++ ) { WindowListener l = windowListeners.get(i); switch(e.getEventType()) { case WindowEvent.EVENT_WINDOW_RESIZED: @@ -2475,6 +2473,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer new NativeWindowException("Unexpected window event type " + e.getEventType()); } + consumed = NEWTEvent.consumedTag == e.getAttachment(); } } @@ -2615,32 +2614,52 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } /** - * Triggered by implementation's WM events or programmatically + * Triggered by implementation's WM events or programmatic while respecting {@link #getDefaultCloseOperation()}. * * @param force if true, overrides {@link #setDefaultCloseOperation(WindowClosingMode)} 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) { + public boolean windowDestroyNotify(boolean force) { + final WindowClosingMode defMode = getDefaultCloseOperation(); + final WindowClosingMode mode = force ? WindowClosingMode.DISPOSE_ON_CLOSE : defMode; if(DEBUG_IMPLEMENTATION) { - System.err.println("Window.windowDestroyNotify(force: "+force+") START "+getThreadName()+": "+this); - } - if(force) { - setDefaultCloseOperation(WindowClosingMode.DISPOSE_ON_CLOSE); - } - - // send synced destroy notifications - enqueueWindowEvent(true, WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY); - - if(handleDestroyNotify && WindowClosingMode.DISPOSE_ON_CLOSE == getDefaultCloseOperation()) { - destroy(); + System.err.println("Window.windowDestroyNotify(isNativeValid: "+isNativeValid()+", force: "+force+", mode "+defMode+" -> "+mode+") "+getThreadName()+": "+this); + // Thread.dumpStack(); } - final boolean destroyed = !isNativeValid(); + final boolean destroyed; + + if( isNativeValid() ) { + if( WindowClosingMode.DISPOSE_ON_CLOSE == mode ) { + if(force) { + setDefaultCloseOperation(mode); + } + try { + if( null == windowDestroyNotifyAction ) { + destroy(); + } else { + windowDestroyNotifyAction.run(); + } + } finally { + if(force) { + setDefaultCloseOperation(defMode); + } + } + } else { + // send synced destroy notifications + sendWindowEvent(WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY); + } + + destroyed = !isNativeValid(); + } else { + destroyed = true; + } if(DEBUG_IMPLEMENTATION) { - System.err.println("Window.windowDestroyNotify(force: "+force+") END "+getThreadName()+": destroyed "+destroyed+", "+this); - } + System.err.println("Window.windowDestroyNotify(isNativeValid: "+isNativeValid()+", force: "+force+", mode "+mode+") END "+getThreadName()+": destroyed "+destroyed+", "+this); + } + return destroyed; } diff --git a/src/newt/classes/jogamp/newt/awt/event/AWTParentWindowAdapter.java b/src/newt/classes/jogamp/newt/awt/event/AWTParentWindowAdapter.java index 701d9d60a..b348220d6 100644 --- a/src/newt/classes/jogamp/newt/awt/event/AWTParentWindowAdapter.java +++ b/src/newt/classes/jogamp/newt/awt/event/AWTParentWindowAdapter.java @@ -42,9 +42,7 @@ import com.jogamp.newt.event.awt.AWTWindowAdapter; * Specialized parent/client adapter, * where the NEWT child window really gets resized, * and the parent move window event gets discarded. */ -public class AWTParentWindowAdapter - extends AWTWindowAdapter - implements java.awt.event.HierarchyListener +public class AWTParentWindowAdapter extends AWTWindowAdapter implements java.awt.event.HierarchyListener { NativeWindow downstreamParent; diff --git a/src/newt/classes/jogamp/newt/driver/android/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/android/WindowDriver.java index a85febca0..c5371ae9c 100644 --- a/src/newt/classes/jogamp/newt/driver/android/WindowDriver.java +++ b/src/newt/classes/jogamp/newt/driver/android/WindowDriver.java @@ -30,6 +30,7 @@ package jogamp.newt.driver.android; import jogamp.common.os.android.StaticContext; import jogamp.newt.WindowImpl; +import jogamp.newt.driver.android.event.AndroidNewtEventFactory; import jogamp.newt.driver.android.event.AndroidNewtEventTranslator; import javax.media.nativewindow.Capabilities; @@ -65,6 +66,8 @@ import android.view.SurfaceHolder.Callback2; import android.view.ViewGroup; import android.view.inputmethod.InputMethodManager; import android.view.SurfaceView; +import android.view.KeyEvent; + public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 { static { @@ -573,10 +576,8 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 { @Override public final void surfaceDestroyed(SurfaceHolder holder) { Log.d(MD.TAG, "surfaceDestroyed - on thread "+Thread.currentThread().getName()); - if(WindowImpl.DEBUG_IMPLEMENTATION) { - Thread.dumpStack(); - } windowDestroyNotify(true); // actually too late .. however .. + Thread.dumpStack(); } @Override @@ -585,6 +586,27 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 { windowRepaint(0, 0, getWidth(), getHeight()); } + protected boolean handleKeyCodeBack(KeyEvent.DispatcherState state, android.view.KeyEvent event) { + if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) { + state.startTracking(event, this); + } else if (event.getAction() == KeyEvent.ACTION_UP && !event.isCanceled() && state.isTracking(event)) { + if( isKeyboardVisible() ) { + keyboardVisibilityChanged(false); + enqueueAKey2NKeyUpDown(event); + } else { + Log.d(MD.TAG, "handleKeyCodeBack : "+event); + windowDestroyNotify(true); + } + } + return false; // cont. processing + } + private void enqueueAKey2NKeyUpDown(android.view.KeyEvent aEvent) { + final com.jogamp.newt.event.KeyEvent eDown = AndroidNewtEventFactory.createKeyEvent(aEvent, com.jogamp.newt.event.KeyEvent.EVENT_KEY_PRESSED, this, true); + final com.jogamp.newt.event.KeyEvent eUp = AndroidNewtEventFactory.createKeyEvent(aEvent, com.jogamp.newt.event.KeyEvent.EVENT_KEY_RELEASED, this, true); + enqueueEvent(false, eDown); + enqueueEvent(false, eUp); + } + private boolean added2StaticViewGroup; private MSurfaceView androidView; private int nativeFormat; // chosen current native PixelFormat (suitable for EGL) @@ -600,6 +622,17 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 { setBackgroundDrawable(null); // setBackgroundColor(Color.TRANSPARENT); } + + @Override + public boolean onKeyPreIme(int keyCode, KeyEvent event) { + if ( event.getKeyCode() == KeyEvent.KEYCODE_BACK ) { + final KeyEvent.DispatcherState state = getKeyDispatcherState(); + if (state != null) { + return handleKeyCodeBack(state, event); + } + } + return false; // cont. processing + } } //---------------------------------------------------------------------- // Internals only diff --git a/src/newt/classes/jogamp/newt/driver/android/event/AndroidNewtEventFactory.java b/src/newt/classes/jogamp/newt/driver/android/event/AndroidNewtEventFactory.java index 22e2cbc51..1f78bd578 100644 --- a/src/newt/classes/jogamp/newt/driver/android/event/AndroidNewtEventFactory.java +++ b/src/newt/classes/jogamp/newt/driver/android/event/AndroidNewtEventFactory.java @@ -31,6 +31,7 @@ package jogamp.newt.driver.android.event; import com.jogamp.common.os.AndroidVersion; import com.jogamp.newt.Window; import com.jogamp.newt.event.InputEvent; +import com.jogamp.newt.event.NEWTEvent; public class AndroidNewtEventFactory { @@ -86,7 +87,7 @@ public class AndroidNewtEventFactory { return (short)0; } - private static final short aKeyCode2NewtKeyCode(int androidKeyCode) { + private static final short aKeyCode2NewtKeyCode(int androidKeyCode, boolean inclSysKeys) { if(android.view.KeyEvent.KEYCODE_0 <= androidKeyCode && androidKeyCode <= android.view.KeyEvent.KEYCODE_9) { return (short) ( com.jogamp.newt.event.KeyEvent.VK_0 + ( androidKeyCode - android.view.KeyEvent.KEYCODE_0 ) ); } @@ -122,11 +123,19 @@ public class AndroidNewtEventFactory { // case android.view.KeyEvent.KEYCODE_MUTE: ?? case android.view.KeyEvent.KEYCODE_PAGE_UP: return com.jogamp.newt.event.KeyEvent.VK_PAGE_UP; case android.view.KeyEvent.KEYCODE_PAGE_DOWN: return com.jogamp.newt.event.KeyEvent.VK_PAGE_DOWN; - // case android.view.KeyEvent.KEYCODE_HOME: return com.jogamp.newt.event.KeyEvent.VK_HOME; - // case android.view.KeyEvent.KEYCODE_BACK: return com.jogamp.newt.event.KeyEvent.VK_BACK_SPACE; case android.view.KeyEvent.KEYCODE_ESCAPE: return com.jogamp.newt.event.KeyEvent.VK_ESCAPE; case android.view.KeyEvent.KEYCODE_CTRL_LEFT: return com.jogamp.newt.event.KeyEvent.VK_CONTROL; case android.view.KeyEvent.KEYCODE_CTRL_RIGHT: return com.jogamp.newt.event.KeyEvent.VK_CONTROL; // ?? + case android.view.KeyEvent.KEYCODE_BACK: + if( inclSysKeys ) { + return com.jogamp.newt.event.KeyEvent.VK_KEYBOARD_INVISIBLE; + } + break; + case android.view.KeyEvent.KEYCODE_HOME: + if( inclSysKeys ) { + return com.jogamp.newt.event.KeyEvent.VK_HOME; + } + break; } return (short)0; } @@ -140,19 +149,7 @@ public class AndroidNewtEventFactory { return newtMods; } - private final NewtGestureListener gestureListener; - private final android.view.GestureDetector gestureDetector; - private final float touchSlop; - - public AndroidNewtEventFactory(android.content.Context context, android.os.Handler handler) { - gestureListener = new NewtGestureListener(); - gestureDetector = new android.view.GestureDetector(context, gestureListener, handler, false /* ignoreMultitouch */); - gestureDetector.setIsLongpressEnabled(false); // favor scroll event! - final android.view.ViewConfiguration configuration = android.view.ViewConfiguration.get(context); - touchSlop = configuration.getScaledTouchSlop(); - } - - public com.jogamp.newt.event.WindowEvent createWindowEvent(android.view.accessibility.AccessibilityEvent event, com.jogamp.newt.Window newtSource) { + public static com.jogamp.newt.event.WindowEvent createWindowEvent(android.view.accessibility.AccessibilityEvent event, com.jogamp.newt.Window newtSource) { final int aType = event.getEventType(); final short nType = aAccessibilityEventType2Newt(aType); @@ -163,33 +160,88 @@ public class AndroidNewtEventFactory { } - public com.jogamp.newt.event.KeyEvent createKeyEvent(int keyCode, android.view.KeyEvent event, com.jogamp.newt.Window newtSource) { - final short type = aKeyEventType2NewtEventType(event.getAction()); - if(Window.DEBUG_MOUSE_EVENT) { - System.err.println("createKeyEvent: type 0x"+Integer.toHexString(type)+", keyCode 0x"+Integer.toHexString(keyCode)+", "+event); + public static com.jogamp.newt.event.KeyEvent createKeyEvent(android.view.KeyEvent aEvent, com.jogamp.newt.Window newtSource, boolean inclSysKeys) { + final com.jogamp.newt.event.KeyEvent res; + final short newtType = aKeyEventType2NewtEventType(aEvent.getAction()); + if( (short)0 != newtType) { + final short newtKeyCode = aKeyCode2NewtKeyCode(aEvent.getKeyCode(), inclSysKeys); + res = createKeyEventImpl(aEvent, newtType, newtKeyCode, newtSource); + } else { + res = null; } - if( (short)0 != type) { - final short newtKeyCode = aKeyCode2NewtKeyCode(keyCode); - if( (short)0 != newtKeyCode ) { - final Object src = (null==newtSource)?null:(Object)newtSource; - final long unixTime = System.currentTimeMillis() + ( event.getEventTime() - android.os.SystemClock.uptimeMillis() ); - final int newtMods = aKeyModifiers2Newt(event.getMetaState()); - - return new com.jogamp.newt.event.KeyEvent( - type, src, unixTime, newtMods, newtKeyCode, newtKeyCode, event.getDisplayLabel()); - } + if(Window.DEBUG_KEY_EVENT) { + System.err.println("createKeyEvent0: "+aEvent+" -> "+res); } - return null; + return res; } - private int gestureScrollPointerDown = 0; + public static com.jogamp.newt.event.KeyEvent createKeyEvent(android.view.KeyEvent aEvent, short newtType, com.jogamp.newt.Window newtSource, boolean inclSysKeys) { + final short newtKeyCode = aKeyCode2NewtKeyCode(aEvent.getKeyCode(), inclSysKeys); + final com.jogamp.newt.event.KeyEvent res = createKeyEventImpl(aEvent, newtType, newtKeyCode, newtSource); + if(Window.DEBUG_KEY_EVENT) { + System.err.println("createKeyEvent1: newtType "+NEWTEvent.toHexString(newtType)+", "+aEvent+" -> "+res); + } + return res; + } + private static com.jogamp.newt.event.KeyEvent createKeyEventImpl(android.view.KeyEvent aEvent, short newtType, short newtKeyCode, com.jogamp.newt.Window newtSource) { + if( (short)0 != newtType && (short)0 != newtKeyCode ) { + final Object src = null==newtSource ? null : newtSource; + final long unixTime = System.currentTimeMillis() + ( aEvent.getEventTime() - android.os.SystemClock.uptimeMillis() ); + final int newtMods = aKeyModifiers2Newt(aEvent.getMetaState()); + + return new com.jogamp.newt.event.KeyEvent( + newtType, src, unixTime, newtMods, newtKeyCode, newtKeyCode, (char) aEvent.getUnicodeChar()); + } + return null; + } + + private static float maxPressure = 0.7f; // experienced maximum value (Amazon HD = 0.8f) + + /** + * Dynamic calibration of maximum MotionEvent pressure, starting from 0.7f + * <p> + * Specification says no pressure is 0.0f and + * normal pressure is 1.0f, where > 1.0f denominates very high pressure. + * </p> + * <p> + * Some devices exceed this spec, or better, most devices do. + * <ul> + * <li>Asus TF2*: Pressure always > 1.0f</li> + * <li>Amazon HD: Pressure always ≤ 0.8f</li> + * </ul> + * </p> + * + * @return + */ + public static float getMaxPressure() { + return maxPressure; + } + + private final NewtGestureListener gestureListener; + private final android.view.GestureDetector gestureDetector; + private final float touchSlop; + + public AndroidNewtEventFactory(android.content.Context context, android.os.Handler handler) { + gestureListener = new NewtGestureListener(); + gestureDetector = new android.view.GestureDetector(context, gestureListener, handler, false /* ignoreMultitouch */); + gestureDetector.setIsLongpressEnabled(false); // favor scroll event! + final android.view.ViewConfiguration configuration = android.view.ViewConfiguration.get(context); + touchSlop = configuration.getScaledTouchSlop(); + } + + private int gestureScrollPointerDown = 0; + public com.jogamp.newt.event.MouseEvent[] createMouseEvents(boolean isOnTouchEvent, android.view.MotionEvent event, com.jogamp.newt.Window newtSource) { if(Window.DEBUG_MOUSE_EVENT) { System.err.println("createMouseEvent: "+toString(event)); } + if( event.getPressure() > maxPressure ) { + maxPressure = event.getPressure(); + } + // // Prefilter Android Event (Gesture, ..) and determine final type // @@ -314,6 +366,9 @@ public class AndroidNewtEventFactory { y[j] = (int)event.getY(i); pressure[j] = event.getPressure(i); pointerIds[j] = (short)event.getPointerId(i); + if( pressure[j] > maxPressure ) { + maxPressure = pressure[j]; + } if(Window.DEBUG_MOUSE_EVENT) { System.err.println("createMouseEvent: ptr-data["+i+" -> "+j+"] "+x[j]+"/"+y[j]+", pressure "+pressure[j]+", id "+pointerIds[j]); } @@ -336,15 +391,15 @@ public class AndroidNewtEventFactory { final com.jogamp.newt.event.MouseEvent me1 = new com.jogamp.newt.event.MouseEvent( nType, src, unixTime, - modifiers, x, y, pressure, pointerIds, clickCount, - button, rotation); + modifiers, x, y, pressure, maxPressure, pointerIds, + clickCount, button, rotation); if( com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_RELEASED == nType ) { return new com.jogamp.newt.event.MouseEvent[] { me1, new com.jogamp.newt.event.MouseEvent( com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_CLICKED, - src, unixTime, modifiers, x, y, pressure, pointerIds, clickCount, - button, rotation) }; + src, unixTime, modifiers, x, y, pressure, maxPressure, pointerIds, + clickCount, button, rotation) }; } else { return new com.jogamp.newt.event.MouseEvent[] { me1 }; } diff --git a/src/newt/classes/jogamp/newt/driver/android/event/AndroidNewtEventTranslator.java b/src/newt/classes/jogamp/newt/driver/android/event/AndroidNewtEventTranslator.java index 2d972f752..93735863e 100644 --- a/src/newt/classes/jogamp/newt/driver/android/event/AndroidNewtEventTranslator.java +++ b/src/newt/classes/jogamp/newt/driver/android/event/AndroidNewtEventTranslator.java @@ -38,7 +38,7 @@ public class AndroidNewtEventTranslator implements View.OnKeyListener, View.OnTo @Override public boolean onKey(View v, int keyCode, android.view.KeyEvent event) { - final com.jogamp.newt.event.KeyEvent newtEvent = factory.createKeyEvent(keyCode, event, newtWindow); + final com.jogamp.newt.event.KeyEvent newtEvent = AndroidNewtEventFactory.createKeyEvent(event, newtWindow, false /* no system keys */); if(null != newtEvent) { newtWindow.enqueueEvent(false, newtEvent); return true; diff --git a/src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java b/src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java index 27d0f3506..cecb1dd7e 100644 --- a/src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java +++ b/src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java @@ -33,9 +33,9 @@ import java.awt.EventQueue; import javax.media.nativewindow.NativeWindowException; import com.jogamp.common.util.RunnableTask; +import com.jogamp.common.util.awt.AWTEDTExecutor; import com.jogamp.newt.util.EDTUtil; -import jogamp.common.awt.AWTEDTExecutor; import jogamp.newt.Debug; public class AWTEDTUtil implements EDTUtil { diff --git a/src/newt/classes/jogamp/newt/driver/awt/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/awt/WindowDriver.java index bee43a95e..0172309fb 100644 --- a/src/newt/classes/jogamp/newt/driver/awt/WindowDriver.java +++ b/src/newt/classes/jogamp/newt/driver/awt/WindowDriver.java @@ -256,10 +256,7 @@ public class WindowDriver extends WindowImpl { } @Override public void windowDestroyed(WindowEvent e) { - if(isNativeValid()) { - WindowDriver.this.windowDestroyNotify(true); - } - + // Not fwd by AWTWindowAdapter, synthesized by NEWT } @Override public void windowGainedFocus(WindowEvent e) { |