diff --git a/pom.xml b/pom.xml
index ad322fffe..cfda771f3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -34,7 +34,7 @@
2.6.2
- 2.0.0-alpha1
+ 2.0.0-alpha2
1.2.0
1.2.0
2.0.0-alpha1
diff --git a/src/main/java/org/cryptomator/ui/traymenu/AwtTrayMenuController.java b/src/main/java/org/cryptomator/ui/traymenu/AwtTrayMenuController.java
index 46ed63550..51b1dc46e 100644
--- a/src/main/java/org/cryptomator/ui/traymenu/AwtTrayMenuController.java
+++ b/src/main/java/org/cryptomator/ui/traymenu/AwtTrayMenuController.java
@@ -7,6 +7,7 @@ import org.cryptomator.integrations.common.Priority;
import org.cryptomator.integrations.tray.ActionItem;
import org.cryptomator.integrations.tray.SeparatorItem;
import org.cryptomator.integrations.tray.SubMenuItem;
+import org.cryptomator.integrations.tray.TrayIconLoader;
import org.cryptomator.integrations.tray.TrayMenuController;
import org.cryptomator.integrations.tray.TrayMenuException;
import org.cryptomator.integrations.tray.TrayMenuItem;
@@ -14,6 +15,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.awt.AWTException;
+import java.awt.Image;
import java.awt.Menu;
import java.awt.MenuItem;
import java.awt.PopupMenu;
@@ -25,6 +27,7 @@ import java.awt.event.MouseEvent;
import java.net.URI;
import java.util.Base64;
import java.util.List;
+import java.util.function.Consumer;
/**
* Responsible to manage the tray icon on macOS and Windows using AWT.
@@ -39,6 +42,7 @@ public class AwtTrayMenuController implements TrayMenuController {
private static final String DATA_URI_SCHEME = "data:image/png;base64,";
private final PopupMenu menu = new PopupMenu();
private TrayIcon trayIcon;
+ private Image image;
@CheckAvailability
public static boolean isAvailable() {
@@ -46,8 +50,9 @@ public class AwtTrayMenuController implements TrayMenuController {
}
@Override
- public void showTrayIcon(URI uri, Runnable defaultAction, String tooltip) throws TrayMenuException {
- var image = Toolkit.getDefaultToolkit().createImage(getImageBytes(uri));
+ public void showTrayIcon(Consumer iconLoader, Runnable defaultAction, String tooltip) throws TrayMenuException {
+ TrayIconLoader.PngData callback = this::updateTrayIconWithPngData;
+ iconLoader.accept(callback);
trayIcon = new TrayIcon(image, tooltip, menu);
trayIcon.setImageAutoSize(true);
@@ -63,9 +68,21 @@ public class AwtTrayMenuController implements TrayMenuController {
}
}
+ private void showTrayIconWithPngData(byte[] imageData) {
+ image = Toolkit.getDefaultToolkit().createImage(imageData);
+ }
+
@Override
- public void updateTrayIcon(URI uri) {
- var image = Toolkit.getDefaultToolkit().createImage(getImageBytes(uri));
+ public void updateTrayIcon(Consumer iconLoader) {
+ TrayIconLoader.PngData callback = this::updateTrayIconWithPngData;
+ iconLoader.accept(callback);
+ }
+
+ private void updateTrayIconWithPngData(byte[] imageData) {
+ if (trayIcon == null) {
+ throw new IllegalStateException("Failed to update the icon as it has not yet been added");
+ }
+ var image = Toolkit.getDefaultToolkit().createImage(imageData);
trayIcon.setImage(image);
}
@@ -104,9 +121,4 @@ public class AwtTrayMenuController implements TrayMenuController {
}
}
}
-
- private byte[] getImageBytes(URI uri) {
- var data = uri.toString().split(DATA_URI_SCHEME)[1];
- return Base64.getDecoder().decode(data);
- }
}
diff --git a/src/main/java/org/cryptomator/ui/traymenu/TrayMenuBuilder.java b/src/main/java/org/cryptomator/ui/traymenu/TrayMenuBuilder.java
index 4cbfa3cac..4431c1e07 100644
--- a/src/main/java/org/cryptomator/ui/traymenu/TrayMenuBuilder.java
+++ b/src/main/java/org/cryptomator/ui/traymenu/TrayMenuBuilder.java
@@ -7,6 +7,7 @@ import org.cryptomator.common.vaults.VaultListManager;
import org.cryptomator.integrations.tray.ActionItem;
import org.cryptomator.integrations.tray.SeparatorItem;
import org.cryptomator.integrations.tray.SubMenuItem;
+import org.cryptomator.integrations.tray.TrayIconLoader;
import org.cryptomator.integrations.tray.TrayMenuController;
import org.cryptomator.integrations.tray.TrayMenuException;
import org.cryptomator.integrations.tray.TrayMenuItem;
@@ -23,9 +24,7 @@ import javafx.beans.Observable;
import javafx.collections.ObservableList;
import java.io.IOException;
import java.io.UncheckedIOException;
-import java.net.URI;
import java.util.ArrayList;
-import java.util.Base64;
import java.util.List;
import java.util.Optional;
import java.util.ResourceBundle;
@@ -38,10 +37,6 @@ public class TrayMenuBuilder {
private static final String TRAY_ICON_UNLOCKED_MAC = "/img/tray_icon_unlocked_mac@2x.png";
private static final String TRAY_ICON = "/img/tray_icon.png";
private static final String TRAY_ICON_UNLOCKED = "/img/tray_icon_unlocked.png";
- private static final String TRAY_ICON_SVG = "tray_icon.svg";
- private static final String TRAY_ICON_UNLOCKED_SVG = "tray_icon_unlocked.svg";
- private static final String DATA_URI_SCHEME = "data:image/png;base64,";
- private static final String FILE_URI_SCHEME = "file:///";
private final ResourceBundle resourceBundle;
private final VaultService vaultService;
@@ -71,7 +66,12 @@ public class TrayMenuBuilder {
});
try {
- trayMenu.showTrayIcon(getAppropriateTrayIconImage(), this::showMainWindow, "Cryptomator");
+ trayMenu.showTrayIcon(loader -> {
+ switch (loader) {
+ case TrayIconLoader.PngData l -> l.loadPng(getAppropriateTrayIconImage());
+ case TrayIconLoader.FreedesktopIconName l -> l.lookupByName(getAppropriateTrayIconSVG());
+ }
+ }, this::showMainWindow, "Cryptomator");
trayMenu.onBeforeOpenMenu(() -> {
for (Vault vault : vaults) {
VaultListManager.redetermineVaultState(vault);
@@ -90,7 +90,12 @@ public class TrayMenuBuilder {
private void vaultListChanged(@SuppressWarnings("unused") Observable observable) {
assert Platform.isFxApplicationThread();
- trayMenu.updateTrayIcon(getAppropriateTrayIconImage());
+ trayMenu.updateTrayIcon(loader -> {
+ switch (loader) {
+ case TrayIconLoader.PngData l -> l.loadPng(getAppropriateTrayIconImage());
+ case TrayIconLoader.FreedesktopIconName l -> l.lookupByName(getAppropriateTrayIconSVG());
+ }
+ });
rebuildMenu();
}
@@ -161,16 +166,10 @@ public class TrayMenuBuilder {
appWindows.showPreferencesWindow(SelectedPreferencesTab.ANY);
}
- private URI getAppropriateTrayIconImage() {
+ private byte[] getAppropriateTrayIconImage() {
boolean isAnyVaultUnlocked = vaults.stream().anyMatch(Vault::isUnlocked);
String resourceName;
-
- if (SystemUtils.IS_OS_LINUX) {
- resourceName = isAnyVaultUnlocked ? TRAY_ICON_UNLOCKED_SVG : TRAY_ICON_SVG;
- return URI.create(FILE_URI_SCHEME + resourceName);
- }
-
if (SystemUtils.IS_OS_MAC_OSX) {
resourceName = isAnyVaultUnlocked ? TRAY_ICON_UNLOCKED_MAC : TRAY_ICON_MAC;
} else {
@@ -179,11 +178,15 @@ public class TrayMenuBuilder {
try (var image = getClass().getResourceAsStream(resourceName)) {
assert image != null;
- var imageBytes = image.readAllBytes();
- var data = Base64.getEncoder().encodeToString(imageBytes);
- return URI.create(DATA_URI_SCHEME + data);
+ return image.readAllBytes();
} catch (IOException e) {
throw new UncheckedIOException("Failed to load tray icon image: " + resourceName, e);
}
}
+
+ private String getAppropriateTrayIconSVG() {
+ boolean isAnyVaultUnlocked = vaults.stream().anyMatch(Vault::isUnlocked);
+
+ return isAnyVaultUnlocked ? "org.cryptomator.Cryptomator-unlocked" : "org.cryptomator.Cryptomator";
+ }
}