mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-05-20 11:41:26 +00:00
Code improvements continued
Discussion: https://github.com/cryptomator/integrations-linux/pull/18
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user