1 diff -durN -x '*~' -x '*.orig' -x '*.rej' openjdk.orig/jdk/src/share/classes/java/awt/SystemTray.java openjdk/jdk/src/share/classes/java/awt/SystemTray.java
2 --- openjdk.orig/jdk/src/share/classes/java/awt/SystemTray.java 2010-02-17 04:14:21.000000000 +0100
3 +++ openjdk/jdk/src/share/classes/java/awt/SystemTray.java 2010-11-27 19:29:43.661160073 +0100
6 transient private SystemTrayPeer peer;
8 + private static final TrayIcon[] EMPTY_TRAY_ARRAY = new TrayIcon[0];
11 * Private <code>SystemTray</code> constructor.
14 if (GraphicsEnvironment.isHeadless()) {
15 throw new HeadlessException();
18 + initializeSystemTrayIfNeeded();
21 throw new UnsupportedOperationException(
22 "The system tray is not supported on the current platform.");
25 - synchronized (SystemTray.class) {
26 - if (systemTray == null) {
27 - systemTray = new SystemTray();
34 * functionality is supported for the current platform
36 public static boolean isSupported() {
37 - if (Toolkit.getDefaultToolkit() instanceof SunToolkit) {
39 - return ((SunToolkit)Toolkit.getDefaultToolkit()).isTraySupported();
41 - } else if (Toolkit.getDefaultToolkit() instanceof HeadlessToolkit) {
43 - return ((HeadlessToolkit)Toolkit.getDefaultToolkit()).isTraySupported();
44 + Toolkit toolkit = Toolkit.getDefaultToolkit();
45 + if (toolkit instanceof SunToolkit) {
46 + // connecting tray to native resource
47 + initializeSystemTrayIfNeeded();
48 + return ((SunToolkit)toolkit).isTraySupported();
49 + } else if (toolkit instanceof HeadlessToolkit) {
50 + // skip initialization as the init routine
51 + // throws HeadlessException
52 + return ((HeadlessToolkit)toolkit).isTraySupported();
62 return (TrayIcon[])icons.toArray(new TrayIcon[icons.size()]);
64 - return new TrayIcon[0];
65 + return EMPTY_TRAY_ARRAY;
73 - * Adds a {@code PropertyChangeListener} to the listener list for a
74 - * specific property. Currently supported property:
76 - * <li>{@code trayIcons}<p>
78 - * This {@code SystemTray}'s array of {@code TrayIcon}s.
79 - * The array is accessed via {@link SystemTray#getTrayIcons}.<br>
80 - * This property is changed when a {@code TrayIcon} is added to
81 - * (or removed from) the {@code SystemTray}.<br> For example, this property
82 - * is changed when the native {@code SystemTray} becomes unavailable on the
83 - * desktop<br> and the {@code TrayIcon}s are automatically removed.</li>
86 + * Adds a {@code PropertyChangeListener} to the list of listeners for the
87 + * specific property. The following properties are currently supported:
89 + * <table border=1 summary="SystemTray properties">
92 + * <th>Description</th>
95 + * <td>{@code trayIcons}</td>
96 + * <td>The {@code SystemTray}'s array of {@code TrayIcon} objects.
97 + * The array is accessed via the {@link #getTrayIcons} method.<br>
98 + * This property is changed when a tray icon is added to (or removed
99 + * from) the system tray.<br> For example, this property is changed
100 + * when the system tray becomes unavailable on the desktop<br>
101 + * and the tray icons are automatically removed.</td>
104 + * <td>{@code systemTray}</td>
105 + * <td>This property contains {@code SystemTray} instance when the system tray
106 + * is available or <code>null</code> otherwise.<br> This property is changed
107 + * when the system tray becomes available or unavailable on the desktop.<br>
108 + * The property is accessed by the {@link #getSystemTray} method.</td>
112 * The {@code listener} listens to property changes only in this context.
114 * If {@code listener} is {@code null}, no exception is thrown
117 synchronized void addNotify() {
119 - peer = ((SunToolkit)Toolkit.getDefaultToolkit()).createSystemTray(this);
120 + Toolkit toolkit = Toolkit.getDefaultToolkit();
121 + if (toolkit instanceof SunToolkit) {
122 + peer = ((SunToolkit)Toolkit.getDefaultToolkit()).createSystemTray(this);
123 + } else if (toolkit instanceof HeadlessToolkit) {
124 + peer = ((HeadlessToolkit)Toolkit.getDefaultToolkit()).createSystemTray(this);
130 security.checkPermission(SecurityConstants.ACCESS_SYSTEM_TRAY_PERMISSION);
134 + private static void initializeSystemTrayIfNeeded() {
135 + synchronized (SystemTray.class) {
136 + if (systemTray == null) {
137 + systemTray = new SystemTray();
142 diff -durN -x '*~' -x '*.orig' -x '*.rej' openjdk.orig/jdk/src/solaris/classes/sun/awt/X11/XMSelection.java openjdk/jdk/src/solaris/classes/sun/awt/X11/XMSelection.java
143 --- openjdk.orig/jdk/src/solaris/classes/sun/awt/X11/XMSelection.java 2010-02-17 04:14:46.000000000 +0100
144 +++ openjdk/jdk/src/solaris/classes/sun/awt/X11/XMSelection.java 2010-11-27 19:29:43.661160073 +0100
148 public synchronized void removeSelectionListener(XMSelectionListener listener) {
149 - if (listeners == null) {
150 + if (listeners != null) {
151 listeners.remove(listener);
154 diff -durN -x '*~' -x '*.orig' -x '*.rej' openjdk.orig/jdk/src/solaris/classes/sun/awt/X11/XSystemTrayPeer.java openjdk/jdk/src/solaris/classes/sun/awt/X11/XSystemTrayPeer.java
155 --- openjdk.orig/jdk/src/solaris/classes/sun/awt/X11/XSystemTrayPeer.java 2010-02-17 04:14:46.000000000 +0100
156 +++ openjdk/jdk/src/solaris/classes/sun/awt/X11/XSystemTrayPeer.java 2010-11-27 19:29:43.661160073 +0100
160 import java.awt.peer.SystemTrayPeer;
161 +import java.lang.reflect.Method;
162 +import java.lang.reflect.InvocationTargetException;
163 +import java.util.logging.Logger;
164 +import sun.awt.SunToolkit;
165 +import sun.awt.AppContext;
167 +public class XSystemTrayPeer implements SystemTrayPeer, XMSelectionListener {
168 + private static final Logger log = Logger.getLogger("sun.awt.X11.XSystemTrayPeer");
170 -public class XSystemTrayPeer implements SystemTrayPeer {
173 static XSystemTrayPeer peerInstance; // there is only one SystemTray peer per application
175 - final static XAtom _NET_SYSTEM_TRAY = XAtom.get("_NET_SYSTEM_TRAY_S0");
176 - final static XAtom _XEMBED_INFO = XAtom.get("_XEMBED_INFO");
177 - final static XAtom _NET_SYSTEM_TRAY_OPCODE = XAtom.get("_NET_SYSTEM_TRAY_OPCODE");
178 - final static XAtom _NET_WM_ICON = XAtom.get("_NET_WM_ICON");
179 - final static long SYSTEM_TRAY_REQUEST_DOCK = 0;
180 + private volatile boolean available;
181 + private final XMSelection selection = new XMSelection("_NET_SYSTEM_TRAY");
183 + private static final Method firePropertyChangeMethod =
184 + XToolkit.getMethod(SystemTray.class, "firePropertyChange", new Class[] {String.class, Object.class, Object.class});
185 + private static final Method addNotifyMethod = XToolkit.getMethod(TrayIcon.class, "addNotify", null);
186 + private static final Method removeNotifyMethod = XToolkit.getMethod(TrayIcon.class, "removeNotify", null);
188 + private static final int SCREEN = 0;
189 + private static final String SYSTEM_TRAY_PROPERTY_NAME = "systemTray";
190 + private static final XAtom _NET_SYSTEM_TRAY = XAtom.get("_NET_SYSTEM_TRAY_S" + SCREEN);
191 + private static final XAtom _XEMBED_INFO = XAtom.get("_XEMBED_INFO");
192 + private static final XAtom _NET_SYSTEM_TRAY_OPCODE = XAtom.get("_NET_SYSTEM_TRAY_OPCODE");
193 + private static final XAtom _NET_WM_ICON = XAtom.get("_NET_WM_ICON");
194 + private static final long SYSTEM_TRAY_REQUEST_DOCK = 0;
196 XSystemTrayPeer(SystemTray target) {
197 this.target = target;
200 - XToolkit.awtLock();
202 - tray_owner = XlibWrapper.XGetSelectionOwner(XToolkit.getDisplay(), _NET_SYSTEM_TRAY.getAtom());
204 - XToolkit.awtUnlock();
205 + selection.addSelectionListener(this);
207 + long selection_owner = selection.getOwner(SCREEN);
208 + available = (selection_owner != XConstants.None);
210 + log.fine(" check if system tray is available. selection owner: " + selection_owner);
213 + public void ownerChanged(int screen, XMSelection sel, long newOwner, long data, long timestamp) {
214 + if (screen != SCREEN) {
219 + firePropertyChange(SYSTEM_TRAY_PROPERTY_NAME, null, target);
226 + public void ownerDeath(int screen, XMSelection sel, long deadOwner) {
227 + if (screen != SCREEN) {
232 + firePropertyChange(SYSTEM_TRAY_PROPERTY_NAME, target, null);
237 + public void selectionChanged(int screen, XMSelection sel, long owner, XPropertyEvent event) {
240 public Dimension getTrayIconSize() {
241 return new Dimension(XTrayIconPeer.TRAY_ICON_HEIGHT, XTrayIconPeer.TRAY_ICON_WIDTH);
244 + boolean isAvailable() {
249 + selection.removeSelectionListener(this);
252 // ***********************************************************************
253 // ***********************************************************************
255 void addTrayIcon(XTrayIconPeer tiPeer) throws AWTException {
257 - XToolkit.awtLock();
259 - tray_owner = XlibWrapper.XGetSelectionOwner(XToolkit.getDisplay(), _NET_SYSTEM_TRAY.getAtom());
261 - XToolkit.awtUnlock();
263 + long selection_owner = selection.getOwner(SCREEN);
265 - if (tray_owner == 0) {
266 + log.fine(" send SYSTEM_TRAY_REQUEST_DOCK message to owner: " + selection_owner);
268 + if (selection_owner == XConstants.None) {
269 throw new AWTException("TrayIcon couldn't be displayed.");
274 _XEMBED_INFO.setAtomData(tray_window, data_ptr, data.length);
276 - sendMessage(tray_owner, SYSTEM_TRAY_REQUEST_DOCK, tray_window, 0, 0);
277 + sendMessage(selection_owner, SYSTEM_TRAY_REQUEST_DOCK, tray_window, 0, 0);
280 void sendMessage(long win, long msg, long data1, long data2, long data3) {
282 static XSystemTrayPeer getPeerInstance() {
286 + private void firePropertyChange(final String propertyName, final Object oldValue, final Object newValue) {
287 + Runnable runnable = new Runnable() {
288 + public void run() {
289 + Object[] args = new Object[] {propertyName, oldValue, newValue};
290 + invokeMethod(firePropertyChangeMethod, target, args);
293 + invokeOnEachAppContext(runnable);
296 + private void createTrayPeers() {
297 + invokeOnEachTrayIcon(addNotifyMethod);
300 + private void removeTrayPeers() {
301 + invokeOnEachTrayIcon(removeNotifyMethod);
304 + private void invokeOnEachTrayIcon(final Method method) {
305 + Runnable runnable = new Runnable() {
306 + public void run() {
307 + TrayIcon[] icons = target.getTrayIcons();
308 + for (TrayIcon ti : icons) {
309 + invokeMethod(method, ti, (Object[]) null);
313 + invokeOnEachAppContext(runnable);
316 + private void invokeMethod(Method method, Object obj, Object[] args) {
318 + method.invoke(obj, args);
319 + } catch (InvocationTargetException e){
320 + e.printStackTrace();
321 + } catch (IllegalAccessException e) {
322 + e.printStackTrace();
326 + private void invokeOnEachAppContext(Runnable runnable) {
327 + for (AppContext appContext : AppContext.getAppContexts()) {
328 + SunToolkit.invokeLaterOnAppContext(appContext, runnable);
333 diff -durN -x '*~' -x '*.orig' -x '*.rej' openjdk.orig/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java openjdk/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java
334 --- openjdk.orig/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java 2010-11-27 18:09:50.051823664 +0100
335 +++ openjdk/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java 2010-11-27 19:30:50.372032878 +0100
340 + Runtime.getRuntime().addShutdownHook(new Thread() {
341 + public void run() {
342 + XSystemTrayPeer peer = XSystemTrayPeer.getPeerInstance();
343 + if (peer != null) {
350 static String getCorrectXIDString(String val) {
351 @@ -1066,10 +1074,9 @@
354 public boolean isTraySupported() {
355 - int wm = XWM.getWMID();
356 - if (wm == XWM.METACITY_WM || wm == XWM.KDE2_WM)
359 + XSystemTrayPeer peer = XSystemTrayPeer.getPeerInstance();
360 + if (peer != null) {
361 + return peer.isAvailable();