Browse Source

Code improvements continued
Discussion: https://github.com/cryptomator/integrations-linux/pull/18

Ralph Plawetzki 1 year ago
parent
commit
948a62b482

+ 1 - 1
pom.xml

@@ -34,7 +34,7 @@
 
 		<!-- cryptomator dependencies -->
 		<cryptomator.cryptofs.version>2.6.2</cryptomator.cryptofs.version>
-		<cryptomator.integrations.version>2.0.0-alpha1</cryptomator.integrations.version>
+		<cryptomator.integrations.version>2.0.0-alpha2</cryptomator.integrations.version>
 		<cryptomator.integrations.win.version>1.2.0</cryptomator.integrations.win.version>
 		<cryptomator.integrations.mac.version>1.2.0</cryptomator.integrations.mac.version>
 		<cryptomator.integrations.linux.version>2.0.0-alpha1</cryptomator.integrations.linux.version>

+ 21 - 9
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<TrayIconLoader> 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<TrayIconLoader> 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);
-	}
 }

+ 21 - 18
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";
+	}
 }