aboutsummaryrefslogtreecommitdiffstats
path: root/src/newt/classes/jogamp
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2013-02-28 00:39:28 +0100
committerSven Gothel <[email protected]>2013-02-28 00:39:28 +0100
commit808a9a27a8c1c9e0a6701a8dd81d51f8daa8129d (patch)
tree35bf5791a829b59f1abe436abb176df7fffb045f /src/newt/classes/jogamp
parentaf384debfdf354d98e3d0d0c6e0c5cf5a967904e (diff)
Fix NEWT/AWT WindowClosing Unit Tests ; Review/Cleanup NEWT WindowClosing mechanism
Due to a NEWT WindowClosing event regression cause by NewtCanvasAWT changes a review of our WindowClosing event mechanism was required. Important cleanups are marked w/ '(*)' below. I would have preferred to change the 'WindowListener.windowDestroyNotify(WindowEvent)' method to pass a WindowCloseEvent object exposing more information like toolkit or programmatic destruction and passing whether a 'closing' or 'nop' action will be performed based on the WindowClosingMode. For now I postponed this idea .. since it would change the API again, but may reconsider it after merging the Android 'closing' patch. - InputEvent.consumedTag -> NEWTEvent.consumedTag - Window - (*) Promote setWindowDestroyNotifyAction(Runnable) to public, former WindowImpl.setHandleDestroyNotify(boolean). Using a Runnable action for WindowImpl.windowDestroyNotify(boolean) allows a setting defined alternative for destroy() and gets rid of [ab]using WindowListener.windowDestroyNotify(WindowEvent) for lifecycle actions. Used in: - GLWindow - GLAutoDrawableDelegate impl. - WindowImpl - Respect NEWTEvent.consumedTag for WindowEvents as well - (*) Impl. setHandleDestroyNotify(boolean) (see above) - (*) destroy() simply sends out pre- and post- destruction Window events, where windowDestroyNotify(boolean) sends out the pre-destruction event if NOP. - (*) windowDestroyNotify(boolean) is public now, allowing other impl. details to follow proper destruction using handleDestroyNotify Runnable (-> NewtCanvasAWT). - AWTWindowClosingProtocol: - addClosingListenerOneShot() -> addClosingListener() - calling addClosingListener() at addNotify() - calling removeClosingListener() at removeNotify() - AWTWindowClosingProtocol ctor taking NOP runnable, allowing to send WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY at WindowClosingMode.DO_NOTHING_ON_CLOSE - add/remove listener on AWT-EDT - AWTWindowAdapter - Add 'removeWindowClosingFrom(..)', allowing to remove window closing event fwd. - Also fwd windowClosed in window closing fwd'ing. - NewtCanvasAWT - (*) Utilize AWTWindowClosingProtocol NOP runnable (see above) to fwd closing-NOP event to NEWT - (*) Unify remove/destroy code in destroyImpl(..) - !removeNotify -> destroy NEWT child programatic or as toolkit event - removeNotify || windowClosing -> destroy jawtWindow - (*) Remove AWTWindowAdapter/AWTParentWindowAdapter's windowClosingListener, since we utilize AWTWindowClosingProtocol - DisplayImpl - Adding 'final void dispatchMessage(final NEWTEvent event)' allowing to remove the NEWTEventTask wrapping for no reason in enqueueEvent(..) if on EDT and waiting.
Diffstat (limited to 'src/newt/classes/jogamp')
-rw-r--r--src/newt/classes/jogamp/newt/DisplayImpl.java26
-rw-r--r--src/newt/classes/jogamp/newt/WindowImpl.java72
-rw-r--r--src/newt/classes/jogamp/newt/awt/event/AWTParentWindowAdapter.java4
-rw-r--r--src/newt/classes/jogamp/newt/driver/awt/WindowDriver.java5
4 files changed, 62 insertions, 45 deletions
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..66ca3e07d 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();
}
@@ -1549,14 +1552,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 +2210,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 +2339,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 +2445,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 +2475,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
new NativeWindowException("Unexpected window event type "
+ e.getEventType());
}
+ consumed = NEWTEvent.consumedTag == e.getAttachment();
}
}
@@ -2615,32 +2616,45 @@ 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);
+ System.err.println("Window.windowDestroyNotify(force: "+force+", mode "+defMode+" -> "+mode+") "+getThreadName()+": "+this);
}
-
- // send synced destroy notifications
- enqueueWindowEvent(true, WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY);
-
- if(handleDestroyNotify && WindowClosingMode.DISPOSE_ON_CLOSE == getDefaultCloseOperation()) {
- destroy();
+
+ 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);
}
final boolean destroyed = !isNativeValid();
if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window.windowDestroyNotify(force: "+force+") END "+getThreadName()+": destroyed "+destroyed+", "+this);
- }
+ System.err.println("Window.windowDestroyNotify(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/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) {