8029250: [macosx] There is no tray icon shown in the system tray area when case starts
Reviewed-by: serb, sveerabhadra
--- 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;
+ }
+ }
}