src/java.desktop/share/classes/java/awt/SequencedEvent.java
changeset 52558 08a0bf1592bd
parent 49299 719064f540f3
child 58309 c6f8b2c3dc66
--- a/src/java.desktop/share/classes/java/awt/SequencedEvent.java	Wed Nov 14 09:31:38 2018 -0800
+++ b/src/java.desktop/share/classes/java/awt/SequencedEvent.java	Fri Nov 09 10:34:19 2018 -0300
@@ -27,6 +27,7 @@
 
 import java.security.AccessController;
 import java.security.PrivilegedAction;
+import java.util.Iterator;
 import java.util.LinkedList;
 import sun.awt.AWTAccessor;
 import sun.awt.AppContext;
@@ -56,6 +57,7 @@
     private final AWTEvent nested;
     private AppContext appContext;
     private boolean disposed;
+    private final LinkedList<AWTEvent> pendingEvents = new LinkedList<>();
 
     private static boolean fxAppThreadIsDispatchThread;
     private Thread fxCheckSequenceThread;
@@ -81,6 +83,35 @@
         });
     }
 
+    private static final class SequencedEventsFilter implements EventFilter {
+        private final SequencedEvent currentSequencedEvent;
+        private SequencedEventsFilter(SequencedEvent currentSequencedEvent) {
+            this.currentSequencedEvent = currentSequencedEvent;
+        }
+        @Override
+        public FilterAction acceptEvent(AWTEvent ev) {
+            if (ev.getID() == ID) {
+                // Move forward dispatching only if the event is previous
+                // in SequencedEvent.list. Otherwise, hold it for reposting later.
+                synchronized (SequencedEvent.class) {
+                    Iterator<SequencedEvent> it = list.iterator();
+                    while (it.hasNext()) {
+                        SequencedEvent iev = it.next();
+                        if (iev.equals(currentSequencedEvent)) {
+                            break;
+                        } else if (iev.equals(ev)) {
+                            return FilterAction.ACCEPT;
+                        }
+                    }
+                }
+            } else if (ev.getID() == SentEvent.ID) {
+                return FilterAction.ACCEPT;
+            }
+            currentSequencedEvent.pendingEvents.add(ev);
+            return FilterAction.REJECT;
+        }
+    }
+
     /**
      * Constructs a new SequencedEvent which will dispatch the specified
      * nested event.
@@ -135,7 +166,8 @@
                     if (Thread.currentThread() instanceof EventDispatchThread) {
                         EventDispatchThread edt = (EventDispatchThread)
                                 Thread.currentThread();
-                        edt.pumpEvents(ID, () -> !SequencedEvent.this.isFirstOrDisposed());
+                        edt.pumpEventsForFilter(() -> !SequencedEvent.this.isFirstOrDisposed(),
+                                new SequencedEventsFilter(this));
                     } else {
                         if (fxAppThreadIsDispatchThread) {
                             fxCheckSequenceThread.start();
@@ -239,10 +271,6 @@
             }
             disposed = true;
         }
-        // Wake myself up
-        if (appContext != null) {
-            SunToolkit.postEvent(appContext, new SentEvent());
-        }
 
         SequencedEvent next = null;
 
@@ -263,5 +291,9 @@
         if (next != null && next.appContext != null) {
             SunToolkit.postEvent(next.appContext, new SentEvent());
         }
+
+        for(AWTEvent e : pendingEvents) {
+            SunToolkit.postEvent(appContext, e);
+        }
     }
 }