packages: icedtea6/icedtea6.spec, icedtea6/icedtea6-system_tray.patch (NEW)...

jajcus jajcus at pld-linux.org
Sat Nov 27 20:32:29 CET 2010


Author: jajcus                       Date: Sat Nov 27 19:32:29 2010 GMT
Module: packages                      Tag: HEAD
---- Log message:
- added patch fixing system tray support in most window managers
- Release: 1

---- Files affected:
packages/icedtea6:
   icedtea6.spec (1.68 -> 1.69) , icedtea6-system_tray.patch (NONE -> 1.1)  (NEW)

---- Diffs:

================================================================
Index: packages/icedtea6/icedtea6.spec
diff -u packages/icedtea6/icedtea6.spec:1.68 packages/icedtea6/icedtea6.spec:1.69
--- packages/icedtea6/icedtea6.spec:1.68	Fri Nov 26 20:28:44 2010
+++ packages/icedtea6/icedtea6.spec	Sat Nov 27 20:32:23 2010
@@ -22,7 +22,7 @@
 Summary(pl.UTF-8):	Kod OpenJDK i GNU Classpath
 Name:		icedtea6
 Version:	1.8.3
-Release:	0.1
+Release:	1
 License:	GPL v2
 Group:		Development/Languages/Java
 Source0:	http://icedtea.classpath.org/download/source/%{name}-%{version}.tar.gz
@@ -41,6 +41,7 @@
 Patch2:		%{name}-no_dtdtype_patch.patch
 Patch3:		%{name}-rpath.patch
 Patch4:		%{name}-libpath.patch
+Patch5:		%{name}-system_tray.patch
 URL:		http://icedtea.classpath.org/wiki/Main_Page
 BuildRequires:	alsa-lib-devel
 %{!?with_bootstrap:BuildRequires:	ant-nodeps}
@@ -395,6 +396,7 @@
 
 %prep
 %setup -q
+
 %patch0 -p1
 
 # workaround for an ECJ bug
@@ -407,6 +409,10 @@
 
 %patch4 -p1
 
+# patches to applied to the extracted sources
+mkdir -p pld-patches
+cp "%{PATCH5}" pld-patches
+
 # let the build system extract the sources where it wants them
 mkdir drops
 ln -s %{SOURCE1} .
@@ -446,7 +452,8 @@
 	--with-xalan2-serializer-jar=%{_javadir}/serializer.jar \
 	--with-rhino=%{_javadir}/js.jar
 
-%{__make} extract extract-ecj
+%{__make} extract extract-ecj \
+	DISTRIBUTION_PATCHES="$(echo pld-patches/*.patch)"
 
 %if %{with bootstrap}
 # Cannot do that as patch, as the sources are prepared by make
@@ -457,6 +464,7 @@
 sed -i -e's/dpkg-architecture/dpkg-architecture__/' openjdk*/*/make/common/shared/Platform.gmk
 
 %{__make} -j1 \
+	DISTRIBUTION_PATCHES="$(echo pld-patches/*.patch)" \
 	PRINTF=/bin/printf
 
 %install
@@ -874,6 +882,10 @@
 All persons listed below can be reached at <cvs_login>@pld-linux.org
 
 $Log$
+Revision 1.69  2010/11/27 19:32:23  jajcus
+- added patch fixing system tray support in most window managers
+- Release: 1
+
 Revision 1.68  2010/11/26 19:28:44  arekm
 - javaws man page exists on x86_64, too
 

================================================================
Index: packages/icedtea6/icedtea6-system_tray.patch
diff -u /dev/null packages/icedtea6/icedtea6-system_tray.patch:1.1
--- /dev/null	Sat Nov 27 20:32:29 2010
+++ packages/icedtea6/icedtea6-system_tray.patch	Sat Nov 27 20:32:23 2010
@@ -0,0 +1,364 @@
+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
+--- openjdk.orig/jdk/src/share/classes/java/awt/SystemTray.java	2010-02-17 04:14:21.000000000 +0100
++++ openjdk/jdk/src/share/classes/java/awt/SystemTray.java	2010-11-27 19:29:43.661160073 +0100
+@@ -125,6 +125,8 @@
+ 
+     transient private SystemTrayPeer peer;
+ 
++    private static final TrayIcon[] EMPTY_TRAY_ARRAY = new TrayIcon[0];
++
+     /**
+      * Private <code>SystemTray</code> constructor.
+      *
+@@ -164,16 +166,14 @@
+         if (GraphicsEnvironment.isHeadless()) {
+             throw new HeadlessException();
+         }
++
++        initializeSystemTrayIfNeeded();
++
+         if (!isSupported()) {
+             throw new UnsupportedOperationException(
+                 "The system tray is not supported on the current platform.");
+         }
+ 
+-        synchronized (SystemTray.class) {
+-            if (systemTray == null) {
+-                systemTray = new SystemTray();
+-            }
+-        }
+         return systemTray;
+     }
+ 
+@@ -203,15 +203,18 @@
+      * functionality is supported for the current platform
+      */
+     public static boolean isSupported() {
+-        if (Toolkit.getDefaultToolkit() instanceof SunToolkit) {
+-
+-            return ((SunToolkit)Toolkit.getDefaultToolkit()).isTraySupported();
+-
+-        } else if (Toolkit.getDefaultToolkit() instanceof HeadlessToolkit) {
+-
+-            return ((HeadlessToolkit)Toolkit.getDefaultToolkit()).isTraySupported();
++        Toolkit toolkit = Toolkit.getDefaultToolkit();
++        if (toolkit instanceof SunToolkit) {
++            // connecting tray to native resource
++            initializeSystemTrayIfNeeded();
++            return ((SunToolkit)toolkit).isTraySupported();
++        } else if (toolkit instanceof HeadlessToolkit) {
++            // skip initialization as the init routine
++            // throws HeadlessException
++            return ((HeadlessToolkit)toolkit).isTraySupported();
++        } else {
++            return false;
+         }
+-        return false;
+     }
+ 
+     /**
+@@ -323,7 +326,7 @@
+         if (icons != null) {
+             return (TrayIcon[])icons.toArray(new TrayIcon[icons.size()]);
+         }
+-        return new TrayIcon[0];
++        return EMPTY_TRAY_ARRAY;
+     }
+ 
+     /**
+@@ -343,19 +346,32 @@
+     }
+ 
+     /**
+-     * Adds a {@code PropertyChangeListener} to the listener list for a
+-     * specific property. Currently supported property:
+-     * <ul>
+-     *    <li>{@code trayIcons}<p>
+-     *        <p>
+-     *        This {@code SystemTray}'s array of {@code TrayIcon}s.
+-     *        The array is accessed via {@link SystemTray#getTrayIcons}.<br>
+-     *        This property is changed when a {@code TrayIcon} is added to
+-     *        (or removed from) the {@code SystemTray}.<br> For example, this property
+-     *        is changed when the native {@code SystemTray} becomes unavailable on the
+-     *        desktop<br> and the {@code TrayIcon}s are automatically removed.</li>
+-     * </ul>
+-     * <p>
++     * Adds a {@code PropertyChangeListener} to the list of listeners for the
++     * specific property. The following properties are currently supported:
++     * <p> </p>
++     * <table border=1 summary="SystemTray properties">
++     * <tr>
++     *    <th>Property</th>
++     *    <th>Description</th>
++     * </tr>
++     * <tr>
++     *    <td>{@code trayIcons}</td>
++     *    <td>The {@code SystemTray}'s array of {@code TrayIcon} objects.
++     *        The array is accessed via the {@link #getTrayIcons} method.<br>
++     *        This property is changed when a tray icon is added to (or removed
++     *        from) the system tray.<br> For example, this property is changed
++     *        when the system tray becomes unavailable on the desktop<br>
++     *        and the tray icons are automatically removed.</td>
++     * </tr>
++     * <tr>
++     *    <td>{@code systemTray}</td>
++     *    <td>This property contains {@code SystemTray} instance when the system tray
++     *        is available or <code>null</code> otherwise.<br> This property is changed
++     *        when the system tray becomes available or unavailable on the desktop.<br>
++     *        The property is accessed by the {@link #getSystemTray} method.</td>
++     * </tr>
++     * </table>
++     * <p> </p>
+      * The {@code listener} listens to property changes only in this context.
+      * <p>
+      * If {@code listener} is {@code null}, no exception is thrown
+@@ -462,7 +478,12 @@
+ 
+     synchronized void addNotify() {
+         if (peer == null) {
+-            peer = ((SunToolkit)Toolkit.getDefaultToolkit()).createSystemTray(this);
++            Toolkit toolkit = Toolkit.getDefaultToolkit();
++            if (toolkit instanceof SunToolkit) {
++                peer = ((SunToolkit)Toolkit.getDefaultToolkit()).createSystemTray(this);
++            } else if (toolkit instanceof HeadlessToolkit) {
++                peer = ((HeadlessToolkit)Toolkit.getDefaultToolkit()).createSystemTray(this);
++            }
+         }
+     }
+ 
+@@ -472,4 +493,12 @@
+             security.checkPermission(SecurityConstants.ACCESS_SYSTEM_TRAY_PERMISSION);
+         }
+     }
++
++    private static void initializeSystemTrayIfNeeded() {
++        synchronized (SystemTray.class) {
++            if (systemTray == null) {
++                systemTray = new SystemTray();
++            }
++        }
++    }
+ }
+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
+--- openjdk.orig/jdk/src/solaris/classes/sun/awt/X11/XMSelection.java	2010-02-17 04:14:46.000000000 +0100
++++ openjdk/jdk/src/solaris/classes/sun/awt/X11/XMSelection.java	2010-11-27 19:29:43.661160073 +0100
+@@ -254,7 +254,7 @@
+     }
+ 
+     public synchronized void removeSelectionListener(XMSelectionListener listener) {
+-        if (listeners == null) {
++        if (listeners != null) {
+             listeners.remove(listener);
+         }
+     }
+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
+--- openjdk.orig/jdk/src/solaris/classes/sun/awt/X11/XSystemTrayPeer.java	2010-02-17 04:14:46.000000000 +0100
++++ openjdk/jdk/src/solaris/classes/sun/awt/X11/XSystemTrayPeer.java	2010-11-27 19:29:43.661160073 +0100
+@@ -27,47 +27,94 @@
+ 
+ import java.awt.*;
+ import java.awt.peer.SystemTrayPeer;
++import java.lang.reflect.Method;
++import java.lang.reflect.InvocationTargetException;
++import java.util.logging.Logger;
++import sun.awt.SunToolkit;
++import sun.awt.AppContext;
++
++public class XSystemTrayPeer implements SystemTrayPeer, XMSelectionListener {
++    private static final Logger log = Logger.getLogger("sun.awt.X11.XSystemTrayPeer");
+ 
+-public class XSystemTrayPeer implements SystemTrayPeer {
+     SystemTray target;
+-    long tray_owner;
+     static XSystemTrayPeer peerInstance; // there is only one SystemTray peer per application
+ 
+-    final static XAtom _NET_SYSTEM_TRAY = XAtom.get("_NET_SYSTEM_TRAY_S0");
+-    final static XAtom _XEMBED_INFO = XAtom.get("_XEMBED_INFO");
+-    final static XAtom _NET_SYSTEM_TRAY_OPCODE = XAtom.get("_NET_SYSTEM_TRAY_OPCODE");
+-    final static XAtom _NET_WM_ICON = XAtom.get("_NET_WM_ICON");
+-    final static long SYSTEM_TRAY_REQUEST_DOCK = 0;
++    private volatile boolean available;
++    private final XMSelection selection = new XMSelection("_NET_SYSTEM_TRAY");
++
++    private static final Method firePropertyChangeMethod =
++        XToolkit.getMethod(SystemTray.class, "firePropertyChange", new Class[] {String.class, Object.class, Object.class});
++    private static final Method addNotifyMethod = XToolkit.getMethod(TrayIcon.class, "addNotify", null);
++    private static final Method removeNotifyMethod = XToolkit.getMethod(TrayIcon.class, "removeNotify", null);
++
++    private static final int SCREEN = 0;
++    private static final String SYSTEM_TRAY_PROPERTY_NAME = "systemTray";
++    private static final XAtom _NET_SYSTEM_TRAY = XAtom.get("_NET_SYSTEM_TRAY_S" + SCREEN);
++    private static final XAtom _XEMBED_INFO = XAtom.get("_XEMBED_INFO");
++    private static final XAtom _NET_SYSTEM_TRAY_OPCODE = XAtom.get("_NET_SYSTEM_TRAY_OPCODE");
++    private static final XAtom _NET_WM_ICON = XAtom.get("_NET_WM_ICON");
++    private static final long SYSTEM_TRAY_REQUEST_DOCK = 0;
+ 
+     XSystemTrayPeer(SystemTray target) {
+         this.target = target;
+         peerInstance = this;
+ 
+-        XToolkit.awtLock();
+-        try {
+-            tray_owner = XlibWrapper.XGetSelectionOwner(XToolkit.getDisplay(), _NET_SYSTEM_TRAY.getAtom());
+-        } finally {
+-            XToolkit.awtUnlock();
++        selection.addSelectionListener(this);
++
++        long selection_owner = selection.getOwner(SCREEN);
++        available = (selection_owner != XConstants.None);
++
++        log.fine(" check if system tray is available. selection owner: " + selection_owner);
++    }
++
++    public void ownerChanged(int screen, XMSelection sel, long newOwner, long data, long timestamp) {
++        if (screen != SCREEN) {
++            return;
++        }
++        if (!available) {
++            available = true;
++            firePropertyChange(SYSTEM_TRAY_PROPERTY_NAME, null, target);
++        } else {
++            removeTrayPeers();
+         }
++        createTrayPeers();
++    }
++
++    public void ownerDeath(int screen, XMSelection sel, long deadOwner) {
++        if (screen != SCREEN) {
++            return;
++        }
++        if (available) {
++            available = false;
++            firePropertyChange(SYSTEM_TRAY_PROPERTY_NAME, target, null);
++            removeTrayPeers();
++        }
++    }
++
++    public void selectionChanged(int screen, XMSelection sel, long owner, XPropertyEvent event) {
+     }
+ 
+     public Dimension getTrayIconSize() {
+         return new Dimension(XTrayIconPeer.TRAY_ICON_HEIGHT, XTrayIconPeer.TRAY_ICON_WIDTH);
+     }
+ 
++    boolean isAvailable() {
++        return available;
++    }
++
++    void dispose() {
++        selection.removeSelectionListener(this);
++    }
++
+     // ***********************************************************************
+     // ***********************************************************************
+ 
+     void addTrayIcon(XTrayIconPeer tiPeer) throws AWTException {
+-        tray_owner = 0;
+-        XToolkit.awtLock();
+-        try {
+-            tray_owner = XlibWrapper.XGetSelectionOwner(XToolkit.getDisplay(), _NET_SYSTEM_TRAY.getAtom());
+-        } finally {
+-            XToolkit.awtUnlock();
+-        }
++        long selection_owner = selection.getOwner(SCREEN);
+ 
+-        if (tray_owner == 0) {
++        log.fine(" send SYSTEM_TRAY_REQUEST_DOCK message to owner: " + selection_owner);
++
++        if (selection_owner == XConstants.None) {
+             throw new AWTException("TrayIcon couldn't be displayed.");
+         }
+ 
+@@ -77,7 +124,7 @@
+ 
+         _XEMBED_INFO.setAtomData(tray_window, data_ptr, data.length);
+ 
+-        sendMessage(tray_owner, SYSTEM_TRAY_REQUEST_DOCK, tray_window, 0, 0);
++        sendMessage(selection_owner, SYSTEM_TRAY_REQUEST_DOCK, tray_window, 0, 0);
+     }
+ 
+     void sendMessage(long win, long msg, long data1, long data2, long data3) {
+@@ -109,4 +156,51 @@
+     static XSystemTrayPeer getPeerInstance() {
+         return peerInstance;
+     }
++
++    private void firePropertyChange(final String propertyName, final Object oldValue, final Object newValue) {
++        Runnable runnable = new Runnable() {
++                public void run() {
++                    Object[] args = new Object[] {propertyName, oldValue, newValue};
++                    invokeMethod(firePropertyChangeMethod, target, args);
++                }
++            };
++        invokeOnEachAppContext(runnable);
++    }
++
++    private void createTrayPeers() {
++        invokeOnEachTrayIcon(addNotifyMethod);
++    }
++
++    private void removeTrayPeers() {
++        invokeOnEachTrayIcon(removeNotifyMethod);
++    }
++
++    private void invokeOnEachTrayIcon(final Method method) {
++        Runnable runnable = new Runnable() {
++                public void run() {
++                    TrayIcon[] icons = target.getTrayIcons();
++                    for (TrayIcon ti : icons) {
++                        invokeMethod(method, ti, (Object[]) null);
++                    }
++                }
++            };
++        invokeOnEachAppContext(runnable);
++    }
++
++    private void invokeMethod(Method method, Object obj, Object[] args) {
++        try{
++            method.invoke(obj, args);
++        } catch (InvocationTargetException e){
++            e.printStackTrace();
++        } catch (IllegalAccessException e) {
++            e.printStackTrace();
++        }
++    }
++
++    private void invokeOnEachAppContext(Runnable runnable) {
++        for (AppContext appContext : AppContext.getAppContexts()) {
++            SunToolkit.invokeLaterOnAppContext(appContext, runnable);
++        }
++    }
++
+ }
+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
+--- openjdk.orig/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java	2010-11-27 18:09:50.051823664 +0100
++++ openjdk/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java	2010-11-27 19:30:50.372032878 +0100
+@@ -300,6 +300,14 @@
+                 }
+             }
+         });
++        Runtime.getRuntime().addShutdownHook(new Thread() {
++            public void run() {
++                XSystemTrayPeer peer = XSystemTrayPeer.getPeerInstance();
++                if (peer != null) {
++                    peer.dispose();
++                }
++            }
++        });
+     }
+ 
+     static String getCorrectXIDString(String val) {
+@@ -1066,10 +1074,9 @@
+     }
+ 
+     public boolean isTraySupported() {
+-        int wm = XWM.getWMID();
+-        if (wm == XWM.METACITY_WM || wm == XWM.KDE2_WM)
+-        {
+-            return true;
++        XSystemTrayPeer peer = XSystemTrayPeer.getPeerInstance();
++        if (peer != null) {
++            return peer.isAvailable();
+         }
+         return false;
+     }
================================================================

---- CVS-web:
    http://cvs.pld-linux.org/cgi-bin/cvsweb.cgi/packages/icedtea6/icedtea6.spec?r1=1.68&r2=1.69&f=u



More information about the pld-cvs-commit mailing list