src/macosx/classes/com/apple/eawt/_AppEventHandler.java
Print this page
*** 1,7 ****
/*
! * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
--- 1,7 ----
/*
! * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
*** 29,38 ****
--- 29,40 ----
import java.awt.event.WindowEvent;
import java.io.File;
import java.net.*;
import java.util.*;
import java.util.List;
+ import sun.awt.AppContext;
+ import sun.awt.SunToolkit;
import com.apple.eawt.AppEvent.*;
class _AppEventHandler {
private static final int NOTIFY_ABOUT = 1;
*** 267,283 ****
handler.handleOpenApp();
}
}
class _AppReOpenedDispatcher extends _AppEventMultiplexor<AppReOpenedListener> {
! void performOnListeners(final List<AppReOpenedListener> listeners, final _NativeEvent event) {
final AppReOpenedEvent e = new AppReOpenedEvent();
- for (final AppReOpenedListener listener : listeners) {
listener.appReOpened(e);
}
}
- }
class _AppForegroundDispatcher extends _BooleanAppEventMultiplexor<AppForegroundListener, AppForegroundEvent> {
AppForegroundEvent createEvent(final boolean isTrue) { return new AppForegroundEvent(); }
void performFalseEventOn(final AppForegroundListener listener, final AppForegroundEvent e) {
--- 269,283 ----
handler.handleOpenApp();
}
}
class _AppReOpenedDispatcher extends _AppEventMultiplexor<AppReOpenedListener> {
! void performOnListener(AppReOpenedListener listener, final _NativeEvent event) {
final AppReOpenedEvent e = new AppReOpenedEvent();
listener.appReOpened(e);
}
}
class _AppForegroundDispatcher extends _BooleanAppEventMultiplexor<AppForegroundListener, AppForegroundEvent> {
AppForegroundEvent createEvent(final boolean isTrue) { return new AppForegroundEvent(); }
void performFalseEventOn(final AppForegroundListener listener, final AppForegroundEvent e) {
*** 413,466 ****
return (T)args[i];
}
}
abstract class _AppEventMultiplexor<L> {
! final List<L> _listeners = new ArrayList<L>(0);
boolean nativeListenerRegistered;
// called from AppKit Thread-0
void dispatch(final _NativeEvent event, final Object... args) {
! // grab a local ref to the listeners
! final List<L> localListeners;
synchronized (this) {
! if (_listeners.size() == 0) return;
! localListeners = new ArrayList<L>(_listeners);
}
! EventQueue.invokeLater(new Runnable() {
public void run() {
! performOnListeners(localListeners, event);
}
});
}
synchronized void addListener(final L listener) {
if (!nativeListenerRegistered) {
registerNativeListener();
nativeListenerRegistered = true;
}
- _listeners.add(listener);
}
synchronized void removeListener(final L listener) {
! _listeners.remove(listener);
}
! abstract void performOnListeners(final List<L> listeners, final _NativeEvent event);
void registerNativeListener() { }
}
abstract class _BooleanAppEventMultiplexor<L, E> extends _AppEventMultiplexor<L> {
@Override
! void performOnListeners(final List<L> listeners, final _NativeEvent event) {
final boolean isTrue = Boolean.TRUE.equals(event.get(0));
final E e = createEvent(isTrue);
if (isTrue) {
! for (final L listener : listeners) performTrueEventOn(listener, e);
} else {
! for (final L listener : listeners) performFalseEventOn(listener, e);
}
}
abstract E createEvent(final boolean isTrue);
abstract void performTrueEventOn(final L listener, final E e);
--- 413,483 ----
return (T)args[i];
}
}
abstract class _AppEventMultiplexor<L> {
! private final Map<L, AppContext> listenerToAppContext =
! new IdentityHashMap<L, AppContext>();
boolean nativeListenerRegistered;
// called from AppKit Thread-0
void dispatch(final _NativeEvent event, final Object... args) {
! // grab a local ref to the listeners and its contexts as an array of the map's entries
! final ArrayList<Map.Entry<L, AppContext>> localEntries;
synchronized (this) {
! if (listenerToAppContext.size() == 0) {
! return;
! }
! localEntries = new ArrayList<Map.Entry<L, AppContext>>(listenerToAppContext.size());
! localEntries.addAll(listenerToAppContext.entrySet());
}
! for (final Map.Entry<L, AppContext> e : localEntries) {
! final L listener = e.getKey();
! final AppContext listenerContext = e.getValue();
! SunToolkit.invokeLaterOnAppContext(listenerContext, new Runnable() {
public void run() {
! performOnListener(listener, event);
}
});
}
+ }
synchronized void addListener(final L listener) {
+ setListenerContext(listener, AppContext.getAppContext());
+
if (!nativeListenerRegistered) {
registerNativeListener();
nativeListenerRegistered = true;
}
}
synchronized void removeListener(final L listener) {
! listenerToAppContext.remove(listener);
}
! abstract void performOnListener(L listener, final _NativeEvent event);
void registerNativeListener() { }
+
+ private void setListenerContext(L listener, AppContext listenerContext) {
+ if (listenerContext == null) {
+ throw new RuntimeException(
+ "Attempting to add a listener from a thread group without AppContext");
+ }
+ listenerToAppContext.put(listener, AppContext.getAppContext());
+ }
}
abstract class _BooleanAppEventMultiplexor<L, E> extends _AppEventMultiplexor<L> {
@Override
! void performOnListener(L listener, final _NativeEvent event) {
final boolean isTrue = Boolean.TRUE.equals(event.get(0));
final E e = createEvent(isTrue);
if (isTrue) {
! performTrueEventOn(listener, e);
} else {
! performFalseEventOn(listener, e);
}
}
abstract E createEvent(final boolean isTrue);
abstract void performTrueEventOn(final L listener, final E e);
*** 477,517 ****
*
* User code is not (and should not be) run under any synchronized lock.
*/
abstract class _AppEventDispatcher<H> {
H _handler;
// called from AppKit Thread-0
void dispatch(final _NativeEvent event) {
- EventQueue.invokeLater(new Runnable() {
- public void run() {
// grab a local ref to the handler
final H localHandler;
synchronized (_AppEventDispatcher.this) {
localHandler = _handler;
}
- // invoke the handler outside of the synchronized block
if (localHandler == null) {
performDefaultAction(event);
} else {
performUsing(localHandler, event);
}
- }
});
}
synchronized void setHandler(final H handler) {
this._handler = handler;
// if a new handler is installed, block addition of legacy ApplicationListeners
if (handler == legacyHandler) return;
legacyHandler.blockLegacyAPI();
}
void performDefaultAction(final _NativeEvent event) { } // by default, do nothing
abstract void performUsing(final H handler, final _NativeEvent event);
}
abstract class _QueuingAppEventDispatcher<H> extends _AppEventDispatcher<H> {
List<_NativeEvent> queuedEvents = new LinkedList<_NativeEvent>();
--- 494,547 ----
*
* User code is not (and should not be) run under any synchronized lock.
*/
abstract class _AppEventDispatcher<H> {
H _handler;
+ AppContext handlerContext;
// called from AppKit Thread-0
void dispatch(final _NativeEvent event) {
// grab a local ref to the handler
final H localHandler;
+ final AppContext localHandlerContext;
synchronized (_AppEventDispatcher.this) {
localHandler = _handler;
+ localHandlerContext = handlerContext;
}
if (localHandler == null) {
performDefaultAction(event);
} else {
+ SunToolkit.invokeLaterOnAppContext(localHandlerContext, new Runnable() {
+ public void run() {
performUsing(localHandler, event);
}
});
}
+ }
synchronized void setHandler(final H handler) {
this._handler = handler;
+ setHandlerContext(AppContext.getAppContext());
+
// if a new handler is installed, block addition of legacy ApplicationListeners
if (handler == legacyHandler) return;
legacyHandler.blockLegacyAPI();
}
void performDefaultAction(final _NativeEvent event) { } // by default, do nothing
abstract void performUsing(final H handler, final _NativeEvent event);
+
+ protected void setHandlerContext(AppContext ctx) {
+ if (ctx == null) {
+ throw new RuntimeException(
+ "Attempting to set a handler from a thread group without AppContext");
+ }
+
+ handlerContext = ctx;
+ }
}
abstract class _QueuingAppEventDispatcher<H> extends _AppEventDispatcher<H> {
List<_NativeEvent> queuedEvents = new LinkedList<_NativeEvent>();
*** 529,538 ****
--- 559,570 ----
}
synchronized void setHandler(final H handler) {
this._handler = handler;
+ setHandlerContext(AppContext.getAppContext());
+
// dispatch any events in the queue
if (queuedEvents != null) {
// grab a local ref to the queue, so the real one can be nulled out
final java.util.List<_NativeEvent> localQueuedEvents = queuedEvents;
queuedEvents = null;