8029250: [macosx] There is no tray icon shown in the system tray area when case starts
authormhalder
Mon, 11 Jun 2018 14:06:58 +0530
changeset 50649 9cf90ac8dbf7
parent 50648 2eb666723f65
child 50650 b57c4a6581fd
8029250: [macosx] There is no tray icon shown in the system tray area when case starts Reviewed-by: serb, sveerabhadra
src/java.desktop/macosx/classes/sun/lwawt/macosx/CImage.java
src/java.desktop/macosx/classes/sun/lwawt/macosx/CTrayIcon.java
--- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CImage.java	Sun Jun 10 18:04:43 2018 -0700
+++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CImage.java	Mon Jun 11 14:06:58 2018 +0530
@@ -74,10 +74,17 @@
 
     // This is used to create a CImage from a Image
     public static CImage createFromImage(final Image image) {
-        return getCreator().createFromImage(image);
+        return getCreator().createFromImage(image, null);
+    }
+
+    // This is used to create a CImage from a Image
+    public static CImage createFromImage(final Image image, CTrayIcon.IconObserver observer) {
+        return getCreator().createFromImage(image, observer);
     }
 
     public static class Creator {
+        CTrayIcon.IconObserver observer;
+
         Creator() { }
 
         // This is used to create a CImage with an NSImage pointer. It MUST be a CFRetained
@@ -124,7 +131,7 @@
             return createImageUsingNativeSize(nativeCreateNSImageFromImageName(name));
         }
 
-        private static int[] imageToArray(Image image, boolean prepareImage) {
+        private static int[] imageToArray(Image image, boolean prepareImage, CTrayIcon.IconObserver observer) {
             if (image == null) return null;
 
             if (prepareImage && !(image instanceof BufferedImage)) {
@@ -153,14 +160,14 @@
             BufferedImage bimg = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB_PRE);
             Graphics2D g2 = bimg.createGraphics();
             g2.setComposite(AlphaComposite.Src);
-            g2.drawImage(image, 0, 0, null);
+            g2.drawImage(image, 0, 0, observer);
             g2.dispose();
 
             return ((DataBufferInt)bimg.getRaster().getDataBuffer()).getData();
         }
 
         public byte[] getPlatformImageBytes(final Image image) {
-            int[] buffer = imageToArray(image, false);
+            int[] buffer = imageToArray(image, false, null);
 
             if (buffer == null) {
                 return null;
@@ -178,22 +185,27 @@
 
         // This is used to create a CImage from a Image
         public CImage createFromImage(final Image image) {
-            return createFromImage(image, true);
+            return createFromImage(image, true, null);
+        }
+
+        // This is used to create a CImage from a Image
+        public CImage createFromImage(final Image image, CTrayIcon.IconObserver observer) {
+            return createFromImage(image, true, observer);
         }
 
         public CImage createFromImageImmediately(final Image image) {
-            return createFromImage(image, false);
+            return createFromImage(image, false, null);
         }
 
         // This is used to create a CImage from a Image
-        private CImage createFromImage(final Image image, final boolean prepareImage) {
+        private CImage createFromImage(final Image image, final boolean prepareImage, CTrayIcon.IconObserver observer) {
             if (image instanceof MultiResolutionImage) {
                 List<Image> resolutionVariants
                         = ((MultiResolutionImage) image).getResolutionVariants();
                 return createFromImages(resolutionVariants, prepareImage);
             }
 
-            int[] buffer = imageToArray(image, prepareImage);
+            int[] buffer = imageToArray(image, prepareImage, observer);
             if (buffer == null) {
                 return null;
             }
@@ -218,7 +230,7 @@
             num = 0;
 
             for (final Image img : images) {
-                buffers[num] = imageToArray(img, prepareImage);
+                buffers[num] = imageToArray(img, prepareImage, null);
                 if (buffers[num] == null) {
                     // Unable to process the image
                     continue;
--- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CTrayIcon.java	Sun Jun 10 18:04:43 2018 -0700
+++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CTrayIcon.java	Mon Jun 11 14:06:58 2018 +0530
@@ -43,6 +43,7 @@
 import java.awt.event.MouseEvent;
 import java.awt.geom.Point2D;
 import java.awt.image.BufferedImage;
+import java.awt.image.ImageObserver;
 import java.awt.peer.TrayIconPeer;
 
 import javax.swing.Icon;
@@ -61,6 +62,7 @@
     // Component target. Because TrayIcon isn't Component's subclass,
     // we use this dummy frame instead
     private final Frame dummyFrame;
+    IconObserver observer = new IconObserver();
 
     // A bitmask that indicates what mouse buttons produce MOUSE_CLICKED events
     // on MOUSE_RELEASE. Click events are only generated if there were no drag
@@ -143,7 +145,7 @@
         CImage cimage = null;
         if (icon != null) {
             BufferedImage image = scaleIcon(icon, 0.75);
-            cimage = CImage.getCreator().createFromImage(image);
+            cimage = CImage.getCreator().createFromImage(image, null);
         }
         if (cimage != null) {
             cimage.execute(imagePtr -> {
@@ -184,9 +186,14 @@
 
     @Override
     public void updateImage() {
+
         Image image = target.getImage();
-        if (image == null) return;
+        if (image != null) {
+            updateNativeImage(image);
+        }
+    }
 
+    void updateNativeImage(Image image) {
         MediaTracker tracker = new MediaTracker(new Button(""));
         tracker.addImage(image, 0);
         try {
@@ -199,7 +206,7 @@
             return;
         }
 
-        CImage cimage = CImage.getCreator().createFromImage(image);
+        CImage cimage = CImage.getCreator().createFromImage(image, observer);
         boolean imageAutoSize = target.isImageAutoSize();
         cimage.execute(imagePtr -> {
             execute(ptr -> {
@@ -346,5 +353,25 @@
             return UIManager.getIcon("OptionPane.informationIcon");
         }
     }
+
+    class IconObserver implements ImageObserver {
+        @Override
+        public boolean imageUpdate(Image image, int flags, int x, int y, int width, int height) {
+            if (image != target.getImage()) // if the image has been changed
+            {
+                return false;
+            }
+            if ((flags & (ImageObserver.FRAMEBITS | ImageObserver.ALLBITS |
+                          ImageObserver.WIDTH | ImageObserver.HEIGHT)) != 0)
+            {
+                SunToolkit.executeOnEventHandlerThread(target, new Runnable() {
+                            public void run() {
+                                updateNativeImage(image);
+                            }
+                        });
+            }
+            return (flags & ImageObserver.ALLBITS) == 0;
+        }
+    }
 }