equal
deleted
inserted
replaced
25 |
25 |
26 package java.awt; |
26 package java.awt; |
27 |
27 |
28 import java.security.AccessController; |
28 import java.security.AccessController; |
29 import java.security.PrivilegedAction; |
29 import java.security.PrivilegedAction; |
|
30 import java.util.Iterator; |
30 import java.util.LinkedList; |
31 import java.util.LinkedList; |
31 import sun.awt.AWTAccessor; |
32 import sun.awt.AWTAccessor; |
32 import sun.awt.AppContext; |
33 import sun.awt.AppContext; |
33 import sun.awt.SunToolkit; |
34 import sun.awt.SunToolkit; |
34 |
35 |
54 private static final LinkedList<SequencedEvent> list = new LinkedList<>(); |
55 private static final LinkedList<SequencedEvent> list = new LinkedList<>(); |
55 |
56 |
56 private final AWTEvent nested; |
57 private final AWTEvent nested; |
57 private AppContext appContext; |
58 private AppContext appContext; |
58 private boolean disposed; |
59 private boolean disposed; |
|
60 private final LinkedList<AWTEvent> pendingEvents = new LinkedList<>(); |
59 |
61 |
60 private static boolean fxAppThreadIsDispatchThread; |
62 private static boolean fxAppThreadIsDispatchThread; |
61 private Thread fxCheckSequenceThread; |
63 private Thread fxCheckSequenceThread; |
62 static { |
64 static { |
63 AWTAccessor.setSequencedEventAccessor(new AWTAccessor.SequencedEventAccessor() { |
65 AWTAccessor.setSequencedEventAccessor(new AWTAccessor.SequencedEventAccessor() { |
77 fxAppThreadIsDispatchThread = |
79 fxAppThreadIsDispatchThread = |
78 "true".equals(System.getProperty("javafx.embed.singleThread")); |
80 "true".equals(System.getProperty("javafx.embed.singleThread")); |
79 return null; |
81 return null; |
80 } |
82 } |
81 }); |
83 }); |
|
84 } |
|
85 |
|
86 private static final class SequencedEventsFilter implements EventFilter { |
|
87 private final SequencedEvent currentSequencedEvent; |
|
88 private SequencedEventsFilter(SequencedEvent currentSequencedEvent) { |
|
89 this.currentSequencedEvent = currentSequencedEvent; |
|
90 } |
|
91 @Override |
|
92 public FilterAction acceptEvent(AWTEvent ev) { |
|
93 if (ev.getID() == ID) { |
|
94 // Move forward dispatching only if the event is previous |
|
95 // in SequencedEvent.list. Otherwise, hold it for reposting later. |
|
96 synchronized (SequencedEvent.class) { |
|
97 Iterator<SequencedEvent> it = list.iterator(); |
|
98 while (it.hasNext()) { |
|
99 SequencedEvent iev = it.next(); |
|
100 if (iev.equals(currentSequencedEvent)) { |
|
101 break; |
|
102 } else if (iev.equals(ev)) { |
|
103 return FilterAction.ACCEPT; |
|
104 } |
|
105 } |
|
106 } |
|
107 } else if (ev.getID() == SentEvent.ID) { |
|
108 return FilterAction.ACCEPT; |
|
109 } |
|
110 currentSequencedEvent.pendingEvents.add(ev); |
|
111 return FilterAction.REJECT; |
|
112 } |
82 } |
113 } |
83 |
114 |
84 /** |
115 /** |
85 * Constructs a new SequencedEvent which will dispatch the specified |
116 * Constructs a new SequencedEvent which will dispatch the specified |
86 * nested event. |
117 * nested event. |
133 if (getFirst() != this) { |
164 if (getFirst() != this) { |
134 if (EventQueue.isDispatchThread()) { |
165 if (EventQueue.isDispatchThread()) { |
135 if (Thread.currentThread() instanceof EventDispatchThread) { |
166 if (Thread.currentThread() instanceof EventDispatchThread) { |
136 EventDispatchThread edt = (EventDispatchThread) |
167 EventDispatchThread edt = (EventDispatchThread) |
137 Thread.currentThread(); |
168 Thread.currentThread(); |
138 edt.pumpEvents(ID, () -> !SequencedEvent.this.isFirstOrDisposed()); |
169 edt.pumpEventsForFilter(() -> !SequencedEvent.this.isFirstOrDisposed(), |
|
170 new SequencedEventsFilter(this)); |
139 } else { |
171 } else { |
140 if (fxAppThreadIsDispatchThread) { |
172 if (fxAppThreadIsDispatchThread) { |
141 fxCheckSequenceThread.start(); |
173 fxCheckSequenceThread.start(); |
142 try { |
174 try { |
143 // check if event is dispatched or disposed |
175 // check if event is dispatched or disposed |
237 KeyboardFocusManager.getCurrentKeyboardFocusManager(). |
269 KeyboardFocusManager.getCurrentKeyboardFocusManager(). |
238 setCurrentSequencedEvent(null); |
270 setCurrentSequencedEvent(null); |
239 } |
271 } |
240 disposed = true; |
272 disposed = true; |
241 } |
273 } |
242 // Wake myself up |
|
243 if (appContext != null) { |
|
244 SunToolkit.postEvent(appContext, new SentEvent()); |
|
245 } |
|
246 |
274 |
247 SequencedEvent next = null; |
275 SequencedEvent next = null; |
248 |
276 |
249 synchronized (SequencedEvent.class) { |
277 synchronized (SequencedEvent.class) { |
250 SequencedEvent.class.notifyAll(); |
278 SequencedEvent.class.notifyAll(); |
261 } |
289 } |
262 // Wake up waiting threads |
290 // Wake up waiting threads |
263 if (next != null && next.appContext != null) { |
291 if (next != null && next.appContext != null) { |
264 SunToolkit.postEvent(next.appContext, new SentEvent()); |
292 SunToolkit.postEvent(next.appContext, new SentEvent()); |
265 } |
293 } |
|
294 |
|
295 for(AWTEvent e : pendingEvents) { |
|
296 SunToolkit.postEvent(appContext, e); |
|
297 } |
266 } |
298 } |
267 } |
299 } |