From 300a8115109d887211893063dd370cdf1ef573f2 Mon Sep 17 00:00:00 2001 From: Jan-Peter Klein Date: Mon, 2 Mar 2026 13:39:38 +0100 Subject: [PATCH 1/3] fix decrypt file name dialog to reuse one window per vault --- .../DecryptFileNamesViewController.java | 17 +++++++++++------ .../ui/decryptname/DecryptNameComponent.java | 8 ++++++++ .../VaultDetailUnlockedController.java | 8 +++++++- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/cryptomator/ui/decryptname/DecryptFileNamesViewController.java b/src/main/java/org/cryptomator/ui/decryptname/DecryptFileNamesViewController.java index 5450e1d48..516551a6f 100644 --- a/src/main/java/org/cryptomator/ui/decryptname/DecryptFileNamesViewController.java +++ b/src/main/java/org/cryptomator/ui/decryptname/DecryptFileNamesViewController.java @@ -97,8 +97,7 @@ public class DecryptFileNamesViewController implements FxController { }); cipherToCleartextTable.setOnDragDropped(event -> { if (event.getGestureSource() == null && event.getDragboard().hasFiles()) { - checkAndDecrypt(event.getDragboard().getFiles().stream().map(File::toPath).toList()); - cipherToCleartextTable.setItems(mapping); + decrypt(event.getDragboard().getFiles().stream().map(File::toPath).toList()); } }); cipherToCleartextTable.setOnDragExited(_ -> cipherToCleartextTable.setItems(mapping)); @@ -124,9 +123,7 @@ public class DecryptFileNamesViewController implements FxController { }); } }); - if (!initialList.isEmpty()) { - checkAndDecrypt(initialList); - } + decrypt(initialList); } private void copySingleCelltoClipboard() { @@ -149,10 +146,18 @@ public class DecryptFileNamesViewController implements FxController { fileChooser.setInitialDirectory(vault.getPath().toFile()); var ciphertextNodes = fileChooser.showOpenMultipleDialog(window); if (ciphertextNodes != null) { - checkAndDecrypt(ciphertextNodes.stream().map(File::toPath).toList()); + decrypt(ciphertextNodes.stream().map(File::toPath).toList()); } } + public void decrypt(List pathsToDecrypt) { + if (pathsToDecrypt.isEmpty()) { + return; + } + checkAndDecrypt(pathsToDecrypt); + cipherToCleartextTable.setItems(mapping); + } + private void checkAndDecrypt(List pathsToDecrypt) { mapping.clear(); //Assumption: All files are in the same directory diff --git a/src/main/java/org/cryptomator/ui/decryptname/DecryptNameComponent.java b/src/main/java/org/cryptomator/ui/decryptname/DecryptNameComponent.java index 7684d4286..e2b21b5b7 100644 --- a/src/main/java/org/cryptomator/ui/decryptname/DecryptNameComponent.java +++ b/src/main/java/org/cryptomator/ui/decryptname/DecryptNameComponent.java @@ -28,15 +28,23 @@ public interface DecryptNameComponent { @FxmlScene(FxmlFile.DECRYPTNAMES) Lazy decryptNamesView(); + DecryptFileNamesViewController controller(); + @DecryptNameWindow Vault vault(); default void showDecryptFileNameWindow() { + showDecryptFileNameWindow(List.of()); + } + + default void showDecryptFileNameWindow(List pathsToDecrypt) { Stage s = window(); s.setScene(decryptNamesView().get()); s.sizeToScene(); if (vault().isUnlocked()) { + controller().decrypt(pathsToDecrypt); s.show(); + s.requestFocus(); } else { LOG.error("Aborted showing DecryptFileName window: vault state is not {}, but {}.", VaultState.Value.UNLOCKED, vault().getState()); } diff --git a/src/main/java/org/cryptomator/ui/mainwindow/VaultDetailUnlockedController.java b/src/main/java/org/cryptomator/ui/mainwindow/VaultDetailUnlockedController.java index 42a8fda7e..bfc4750b5 100644 --- a/src/main/java/org/cryptomator/ui/mainwindow/VaultDetailUnlockedController.java +++ b/src/main/java/org/cryptomator/ui/mainwindow/VaultDetailUnlockedController.java @@ -64,6 +64,7 @@ public class VaultDetailUnlockedController implements FxController { private final DecryptNameComponent.Factory decryptNameWindowFactory; private final ResourceBundle resourceBundle; private final LoadingCache vaultStats; + private final LoadingCache decryptNameWindows; private final VaultStatisticsComponent.Builder vaultStatsBuilder; private final ObservableValue accessibleViaPath; private final ObservableValue accessibleViaUri; @@ -96,6 +97,7 @@ public class VaultDetailUnlockedController implements FxController { this.decryptNameWindowFactory = decryptNameWindowFactory; this.resourceBundle = resourceBundle; this.vaultStats = CacheBuilder.newBuilder().weakValues().build(CacheLoader.from(this::buildVaultStats)); + this.decryptNameWindows = CacheBuilder.newBuilder().weakValues().build(CacheLoader.from(this::buildDecryptNameWindow)); this.vaultStatsBuilder = vaultStatsBuilder; var mp = vault.flatMap(Vault::mountPointProperty); this.accessibleViaPath = mp.map(m -> m instanceof Mountpoint.WithPath).orElse(false); @@ -167,7 +169,7 @@ public class VaultDetailUnlockedController implements FxController { } private void showDecryptNameWindow(List pathsToDecrypt) { - decryptNameWindowFactory.create(vault.get(), mainWindow, pathsToDecrypt).showDecryptFileNameWindow(); + decryptNameWindows.getUnchecked(vault.get()).showDecryptFileNameWindow(pathsToDecrypt); } private boolean startsWithVaultAccessPoint(Path path) { @@ -220,6 +222,10 @@ public class VaultDetailUnlockedController implements FxController { return vaultStatsBuilder.vault(vault).build(); } + private DecryptNameComponent buildDecryptNameWindow(Vault vault) { + return decryptNameWindowFactory.create(vault, mainWindow, List.of()); + } + @FXML public void revealAccessLocation() { vaultService.reveal(vault.get()); From 9eca05aeb745de1e5454f5fe435672a575942b99 Mon Sep 17 00:00:00 2001 From: Jan-Peter Klein Date: Mon, 30 Mar 2026 12:15:09 +0200 Subject: [PATCH 2/3] address infeos review: drop paths injection, close on locked vault, clear mapping on close --- .../ui/decryptname/DecryptFileNamesViewController.java | 5 +++-- .../cryptomator/ui/decryptname/DecryptNameComponent.java | 7 ++----- .../ui/mainwindow/VaultDetailUnlockedController.java | 2 +- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/cryptomator/ui/decryptname/DecryptFileNamesViewController.java b/src/main/java/org/cryptomator/ui/decryptname/DecryptFileNamesViewController.java index 516551a6f..47f260ae2 100644 --- a/src/main/java/org/cryptomator/ui/decryptname/DecryptFileNamesViewController.java +++ b/src/main/java/org/cryptomator/ui/decryptname/DecryptFileNamesViewController.java @@ -68,12 +68,12 @@ public class DecryptFileNamesViewController implements FxController { public TableView cipherToCleartextTable; @Inject - public DecryptFileNamesViewController(@DecryptNameWindow Stage window, @DecryptNameWindow Vault vault, @DecryptNameWindow List pathsToDecrypt, ResourceBundle resourceBundle) { + public DecryptFileNamesViewController(@DecryptNameWindow Stage window, @DecryptNameWindow Vault vault, ResourceBundle resourceBundle) { this.window = window; this.vault = vault; this.resourceBundle = resourceBundle; this.mapping = new SimpleListProperty<>(FXCollections.observableArrayList()); - this.initialList = pathsToDecrypt; + this.initialList = List.of(); } @FXML @@ -124,6 +124,7 @@ public class DecryptFileNamesViewController implements FxController { } }); decrypt(initialList); + window.setOnHidden(_ -> mapping.clear()); } private void copySingleCelltoClipboard() { diff --git a/src/main/java/org/cryptomator/ui/decryptname/DecryptNameComponent.java b/src/main/java/org/cryptomator/ui/decryptname/DecryptNameComponent.java index e2b21b5b7..4abf7ee3f 100644 --- a/src/main/java/org/cryptomator/ui/decryptname/DecryptNameComponent.java +++ b/src/main/java/org/cryptomator/ui/decryptname/DecryptNameComponent.java @@ -33,10 +33,6 @@ public interface DecryptNameComponent { @DecryptNameWindow Vault vault(); - default void showDecryptFileNameWindow() { - showDecryptFileNameWindow(List.of()); - } - default void showDecryptFileNameWindow(List pathsToDecrypt) { Stage s = window(); s.setScene(decryptNamesView().get()); @@ -47,12 +43,13 @@ public interface DecryptNameComponent { s.requestFocus(); } else { LOG.error("Aborted showing DecryptFileName window: vault state is not {}, but {}.", VaultState.Value.UNLOCKED, vault().getState()); + s.close(); } } @Subcomponent.Factory interface Factory { - DecryptNameComponent create(@BindsInstance @DecryptNameWindow Vault vault, @BindsInstance @Named("windowOwner") Stage owner, @BindsInstance @DecryptNameWindow List pathsToDecrypt); + DecryptNameComponent create(@BindsInstance @DecryptNameWindow Vault vault, @BindsInstance @Named("windowOwner") Stage owner); } } diff --git a/src/main/java/org/cryptomator/ui/mainwindow/VaultDetailUnlockedController.java b/src/main/java/org/cryptomator/ui/mainwindow/VaultDetailUnlockedController.java index bfc4750b5..eadad0149 100644 --- a/src/main/java/org/cryptomator/ui/mainwindow/VaultDetailUnlockedController.java +++ b/src/main/java/org/cryptomator/ui/mainwindow/VaultDetailUnlockedController.java @@ -223,7 +223,7 @@ public class VaultDetailUnlockedController implements FxController { } private DecryptNameComponent buildDecryptNameWindow(Vault vault) { - return decryptNameWindowFactory.create(vault, mainWindow, List.of()); + return decryptNameWindowFactory.create(vault, mainWindow); } @FXML From 21cffb13c7c60a70c116c50a0248174c54c1daa1 Mon Sep 17 00:00:00 2001 From: Jan-Peter Klein Date: Mon, 30 Mar 2026 12:46:11 +0200 Subject: [PATCH 3/3] remove unused initialList field from DecryptFileNamesViewController --- .../ui/decryptname/DecryptFileNamesViewController.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/java/org/cryptomator/ui/decryptname/DecryptFileNamesViewController.java b/src/main/java/org/cryptomator/ui/decryptname/DecryptFileNamesViewController.java index 47f260ae2..b7c14199f 100644 --- a/src/main/java/org/cryptomator/ui/decryptname/DecryptFileNamesViewController.java +++ b/src/main/java/org/cryptomator/ui/decryptname/DecryptFileNamesViewController.java @@ -58,8 +58,6 @@ public class DecryptFileNamesViewController implements FxController { private final Stage window; private final Vault vault; private final ResourceBundle resourceBundle; - private final List initialList; - @FXML public TableColumn ciphertextColumn; @FXML @@ -73,7 +71,6 @@ public class DecryptFileNamesViewController implements FxController { this.vault = vault; this.resourceBundle = resourceBundle; this.mapping = new SimpleListProperty<>(FXCollections.observableArrayList()); - this.initialList = List.of(); } @FXML @@ -123,7 +120,6 @@ public class DecryptFileNamesViewController implements FxController { }); } }); - decrypt(initialList); window.setOnHidden(_ -> mapping.clear()); }