diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index 357b2e3e4..e15900880 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -8,7 +8,7 @@ updates:
time: "06:00"
timezone: "UTC"
groups:
- all: # one PR for all dependencies
+ maven-dependencies:
patterns:
- "*"
@@ -17,7 +17,7 @@ updates:
schedule:
interval: "monthly"
groups:
- all: # one PR for all actions
+ github-actions:
patterns:
- "*"
labels:
diff --git a/dist/mac/resources/Cryptomator.icns b/dist/mac/resources/Cryptomator.icns
index 25da5b5be..79f5fdb39 100644
Binary files a/dist/mac/resources/Cryptomator.icns and b/dist/mac/resources/Cryptomator.icns differ
diff --git a/dist/win/contrib/patchWebDAV.bat b/dist/win/contrib/patchWebDAV.bat
index cc9f667dd..735cfb823 100644
--- a/dist/win/contrib/patchWebDAV.bat
+++ b/dist/win/contrib/patchWebDAV.bat
@@ -3,5 +3,5 @@
::REPLACE ME
cd %~dp0
-powershell -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Unrestricted -Command .\patchWebDAV.ps1^
+powershell -NoLogo -NoProfile -NonInteractive -ExecutionPolicy RemoteSigned -Command .\patchWebDAV.ps1^
-LoopbackAlias %LOOPBACK_ALIAS%
\ No newline at end of file
diff --git a/dist/win/contrib/version170-migrate-settings.bat b/dist/win/contrib/version170-migrate-settings.bat
index 345b01ad9..d94e062a1 100644
--- a/dist/win/contrib/version170-migrate-settings.bat
+++ b/dist/win/contrib/version170-migrate-settings.bat
@@ -2,4 +2,4 @@
:: see comments in file ./version170-migrate-settings.ps1
cd %~dp0
-powershell -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Unrestricted -Command .\version170-migrate-settings.ps1
\ No newline at end of file
+powershell -NoLogo -NoProfile -NonInteractive -ExecutionPolicy RemoteSigned -Command .\version170-migrate-settings.ps1
diff --git a/pom.xml b/pom.xml
index 24238b8bb..2592b8814 100644
--- a/pom.xml
+++ b/pom.xml
@@ -36,35 +36,42 @@
2.6.7
1.3.0
1.2.2
- 1.2.0
+ 1.2.1
1.3.0-beta6
3.0.0
2.0.0
2.0.3
- 3.12.0
- 2.45
+ 3.13.0
+ 2.47
2.2
- 32.0.1-jre
+ 32.1.2-jre
2.15.2
20.0.2
4.4.0
9.31
- 1.4.7
+ 1.4.11
2.0.7
- 0.5.1
- 1.7.0
+ 0.6.0
+ 1.8.2
- 5.9.3
- 5.3.1
+ 5.10.0
+ 5.5.0
2.2
- 23.0.0
- 8.1.2
- 0.8.9
+ 24.0.1
+ 8.4.0
+ 0.8.10
+ 2.2.0
+ 1.2.1
+ 3.11.0
+ 3.3.1
+ 3.6.0
+ 3.1.2
+ 3.3.0
@@ -240,7 +247,7 @@
com.google.jimfs
jimfs
- 1.2
+ 1.3.0
test
@@ -258,32 +265,32 @@
org.apache.maven.plugins
maven-compiler-plugin
- 3.10.1
+ ${mvn-compiler.version}
org.apache.maven.plugins
maven-resources-plugin
- 3.3.0
+ ${mvn-resources.version}
org.apache.maven.plugins
maven-dependency-plugin
- 3.3.0
+ ${mvn-dependency.version}
org.apache.maven.plugins
maven-surefire-plugin
- 3.0.0-M7
+ ${mvn-surefire.version}
org.codehaus.mojo
license-maven-plugin
- 2.0.0
+ ${license-generator.version}
org.apache.maven.plugins
maven-jar-plugin
- 3.3.0
+ ${mvn-jar.version}
org.jacoco
@@ -332,8 +339,22 @@
org.apache.maven.plugins
maven-surefire-plugin
+
+
+ me.fabriciorby
+ maven-surefire-junit5-tree-reporter
+ ${junit-tree-reporter.version}
+
+
--enable-preview
+ plain
+
+ true
+
+
+
diff --git a/src/main/java/org/cryptomator/common/settings/Settings.java b/src/main/java/org/cryptomator/common/settings/Settings.java
index fd9f01904..4e0e0df97 100644
--- a/src/main/java/org/cryptomator/common/settings/Settings.java
+++ b/src/main/java/org/cryptomator/common/settings/Settings.java
@@ -65,7 +65,6 @@ public class Settings {
public final IntegerProperty windowYPosition;
public final IntegerProperty windowWidth;
public final IntegerProperty windowHeight;
- public final StringProperty displayConfiguration;
public final StringProperty language;
public final StringProperty mountService;
public final StringProperty lastUpdateCheck;
@@ -103,7 +102,6 @@ public class Settings {
this.windowYPosition = new SimpleIntegerProperty(this, "windowYPosition", json.windowYPosition);
this.windowWidth = new SimpleIntegerProperty(this, "windowWidth", json.windowWidth);
this.windowHeight = new SimpleIntegerProperty(this, "windowHeight", json.windowHeight);
- this.displayConfiguration = new SimpleStringProperty(this, "displayConfiguration", json.displayConfiguration);
this.language = new SimpleStringProperty(this, "language", json.language);
this.mountService = new SimpleStringProperty(this, "mountService", json.mountService);
this.lastUpdateCheck = new SimpleStringProperty(this, "lastUpdateCheck", json.lastUpdateCheck);
@@ -131,7 +129,6 @@ public class Settings {
windowYPosition.addListener(this::somethingChanged);
windowWidth.addListener(this::somethingChanged);
windowHeight.addListener(this::somethingChanged);
- displayConfiguration.addListener(this::somethingChanged);
language.addListener(this::somethingChanged);
mountService.addListener(this::somethingChanged);
lastUpdateCheck.addListener(this::somethingChanged);
@@ -186,7 +183,6 @@ public class Settings {
json.windowYPosition = windowYPosition.get();
json.windowWidth = windowWidth.get();
json.windowHeight = windowHeight.get();
- json.displayConfiguration = displayConfiguration.get();
json.language = language.get();
json.mountService = mountService.get();
json.lastUpdateCheck = lastUpdateCheck.get();
diff --git a/src/main/java/org/cryptomator/common/settings/SettingsJson.java b/src/main/java/org/cryptomator/common/settings/SettingsJson.java
index 977e1d3cd..2c7c963da 100644
--- a/src/main/java/org/cryptomator/common/settings/SettingsJson.java
+++ b/src/main/java/org/cryptomator/common/settings/SettingsJson.java
@@ -31,9 +31,6 @@ class SettingsJson {
@JsonProperty("theme")
UiTheme theme = Settings.DEFAULT_THEME;
- @JsonProperty("displayConfiguration")
- String displayConfiguration;
-
@JsonProperty("keychainProvider")
String keychainProvider = Settings.DEFAULT_KEYCHAIN_PROVIDER;
diff --git a/src/main/java/org/cryptomator/ui/addvaultwizard/AddVaultModule.java b/src/main/java/org/cryptomator/ui/addvaultwizard/AddVaultModule.java
index 4a9dba7ad..62321277c 100644
--- a/src/main/java/org/cryptomator/ui/addvaultwizard/AddVaultModule.java
+++ b/src/main/java/org/cryptomator/ui/addvaultwizard/AddVaultModule.java
@@ -45,9 +45,8 @@ public abstract class AddVaultModule {
@Provides
@AddVaultWizardWindow
@AddVaultWizardScoped
- static Stage provideStage(StageFactory factory, @PrimaryStage Stage primaryStage, ResourceBundle resourceBundle) {
+ static Stage provideStage(StageFactory factory, @PrimaryStage Stage primaryStage) {
Stage stage = factory.create();
- stage.setTitle(resourceBundle.getString("addvaultwizard.title"));
stage.setResizable(false);
stage.initModality(Modality.WINDOW_MODAL);
stage.initOwner(primaryStage);
@@ -90,13 +89,6 @@ public abstract class AddVaultModule {
// ------------------
- @Provides
- @FxmlScene(FxmlFile.ADDVAULT_WELCOME)
- @AddVaultWizardScoped
- static Scene provideWelcomeScene(@AddVaultWizardWindow FxmlLoaderFactory fxmlLoaders) {
- return fxmlLoaders.createScene(FxmlFile.ADDVAULT_WELCOME);
- }
-
@Provides
@FxmlScene(FxmlFile.ADDVAULT_EXISTING)
@AddVaultWizardScoped
@@ -148,11 +140,6 @@ public abstract class AddVaultModule {
// ------------------
- @Binds
- @IntoMap
- @FxControllerKey(AddVaultWelcomeController.class)
- abstract FxController bindWelcomeController(AddVaultWelcomeController controller);
-
@Binds
@IntoMap
@FxControllerKey(ChooseExistingVaultController.class)
diff --git a/src/main/java/org/cryptomator/ui/addvaultwizard/AddVaultWelcomeController.java b/src/main/java/org/cryptomator/ui/addvaultwizard/AddVaultWelcomeController.java
deleted file mode 100644
index 3c13aeb75..000000000
--- a/src/main/java/org/cryptomator/ui/addvaultwizard/AddVaultWelcomeController.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package org.cryptomator.ui.addvaultwizard;
-
-import dagger.Lazy;
-import org.cryptomator.ui.common.FxController;
-import org.cryptomator.ui.common.FxmlFile;
-import org.cryptomator.ui.common.FxmlScene;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.inject.Inject;
-import javafx.scene.Scene;
-import javafx.stage.Stage;
-
-@AddVaultWizardScoped
-public class AddVaultWelcomeController implements FxController {
-
- private static final Logger LOG = LoggerFactory.getLogger(AddVaultWelcomeController.class);
- private final Stage window;
- private final Lazy chooseExistingVaultScene;
- private final Lazy createNewVaultScene;
-
- @Inject
- AddVaultWelcomeController(@AddVaultWizardWindow Stage window, @FxmlScene(FxmlFile.ADDVAULT_EXISTING) Lazy chooseExistingVaultScene, @FxmlScene(FxmlFile.ADDVAULT_NEW_NAME) Lazy createNewVaultScene) {
- this.window = window;
- this.chooseExistingVaultScene = chooseExistingVaultScene;
- this.createNewVaultScene = createNewVaultScene;
- }
-
- public void createNewVault() {
- LOG.debug("AddVaultWelcomeController.createNewVault()");
- window.setScene(createNewVaultScene.get());
- }
-
- public void chooseExistingVault() {
- LOG.debug("AddVaultWelcomeController.chooseExistingVault()");
- window.setScene(chooseExistingVaultScene.get());
- }
-}
diff --git a/src/main/java/org/cryptomator/ui/addvaultwizard/AddVaultWizardComponent.java b/src/main/java/org/cryptomator/ui/addvaultwizard/AddVaultWizardComponent.java
index 1253d8347..c67f999e8 100644
--- a/src/main/java/org/cryptomator/ui/addvaultwizard/AddVaultWizardComponent.java
+++ b/src/main/java/org/cryptomator/ui/addvaultwizard/AddVaultWizardComponent.java
@@ -12,6 +12,7 @@ import org.cryptomator.ui.common.FxmlScene;
import javafx.scene.Scene;
import javafx.stage.Stage;
+import java.util.ResourceBundle;
@AddVaultWizardScoped
@Subcomponent(modules = {AddVaultModule.class})
@@ -20,12 +21,23 @@ public interface AddVaultWizardComponent {
@AddVaultWizardWindow
Stage window();
- @FxmlScene(FxmlFile.ADDVAULT_WELCOME)
- Lazy scene();
+ @FxmlScene(FxmlFile.ADDVAULT_NEW_NAME)
+ Lazy sceneNew();
+ @FxmlScene(FxmlFile.ADDVAULT_EXISTING)
+ Lazy sceneExisting();
- default void showAddVaultWizard() {
+ default void showAddNewVaultWizard(ResourceBundle resourceBundle) {
Stage stage = window();
- stage.setScene(scene().get());
+ stage.setScene(sceneNew().get());
+ stage.setTitle(resourceBundle.getString("addvaultwizard.new.title"));
+ stage.sizeToScene();
+ stage.show();
+ }
+
+ default void showAddExistingVaultWizard(ResourceBundle resourceBundle) {
+ Stage stage = window();
+ stage.setScene(sceneExisting().get());
+ stage.setTitle(resourceBundle.getString("addvaultwizard.existing.title"));
stage.sizeToScene();
stage.show();
}
diff --git a/src/main/java/org/cryptomator/ui/addvaultwizard/ChooseExistingVaultController.java b/src/main/java/org/cryptomator/ui/addvaultwizard/ChooseExistingVaultController.java
index fe4ac3bd1..be9ea15c7 100644
--- a/src/main/java/org/cryptomator/ui/addvaultwizard/ChooseExistingVaultController.java
+++ b/src/main/java/org/cryptomator/ui/addvaultwizard/ChooseExistingVaultController.java
@@ -35,7 +35,6 @@ public class ChooseExistingVaultController implements FxController {
private static final Logger LOG = LoggerFactory.getLogger(ChooseExistingVaultController.class);
private final Stage window;
- private final Lazy welcomeScene;
private final Lazy successScene;
private final FxApplicationWindows appWindows;
private final ObjectProperty vaultPath;
@@ -45,9 +44,15 @@ public class ChooseExistingVaultController implements FxController {
private final ObservableValue screenshot;
@Inject
- ChooseExistingVaultController(@AddVaultWizardWindow Stage window, @FxmlScene(FxmlFile.ADDVAULT_WELCOME) Lazy welcomeScene, @FxmlScene(FxmlFile.ADDVAULT_SUCCESS) Lazy successScene, FxApplicationWindows appWindows, ObjectProperty vaultPath, @AddVaultWizardWindow ObjectProperty vault, VaultListManager vaultListManager, ResourceBundle resourceBundle, FxApplicationStyle applicationStyle) {
+ ChooseExistingVaultController(@AddVaultWizardWindow Stage window, //
+ @FxmlScene(FxmlFile.ADDVAULT_SUCCESS) Lazy successScene, //
+ FxApplicationWindows appWindows, //
+ ObjectProperty vaultPath, //
+ @AddVaultWizardWindow ObjectProperty vault, //
+ VaultListManager vaultListManager, //
+ ResourceBundle resourceBundle, //
+ FxApplicationStyle applicationStyle) {
this.window = window;
- this.welcomeScene = welcomeScene;
this.successScene = successScene;
this.appWindows = appWindows;
this.vaultPath = vaultPath;
@@ -70,11 +75,6 @@ public class ChooseExistingVaultController implements FxController {
return new Image((Objects.requireNonNull(getClass().getResource(imageResourcePath)).toString()));
}
- @FXML
- public void back() {
- window.setScene(welcomeScene.get());
- }
-
@FXML
public void chooseFileAndNext() {
FileChooser fileChooser = new FileChooser();
diff --git a/src/main/java/org/cryptomator/ui/addvaultwizard/CreateNewVaultNameController.java b/src/main/java/org/cryptomator/ui/addvaultwizard/CreateNewVaultNameController.java
index 2ca73e172..a80baef50 100644
--- a/src/main/java/org/cryptomator/ui/addvaultwizard/CreateNewVaultNameController.java
+++ b/src/main/java/org/cryptomator/ui/addvaultwizard/CreateNewVaultNameController.java
@@ -17,7 +17,6 @@ import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.stage.Stage;
import java.nio.file.Path;
-import java.util.ResourceBundle;
import java.util.regex.Pattern;
@AddVaultWizardScoped
@@ -27,16 +26,17 @@ public class CreateNewVaultNameController implements FxController {
public TextField textField;
private final Stage window;
- private final Lazy welcomeScene;
private final Lazy chooseLocationScene;
private final ObjectProperty vaultPath;
private final StringProperty vaultName;
private final BooleanBinding validVaultName;
@Inject
- CreateNewVaultNameController(@AddVaultWizardWindow Stage window, @FxmlScene(FxmlFile.ADDVAULT_WELCOME) Lazy welcomeScene, @FxmlScene(FxmlFile.ADDVAULT_NEW_LOCATION) Lazy chooseLocationScene, ObjectProperty vaultPath, @Named("vaultName") StringProperty vaultName, ResourceBundle resourceBundle) {
+ CreateNewVaultNameController(@AddVaultWizardWindow Stage window, //
+ @FxmlScene(FxmlFile.ADDVAULT_NEW_LOCATION) Lazy chooseLocationScene, //
+ ObjectProperty vaultPath, //
+ @Named("vaultName") StringProperty vaultName) {
this.window = window;
- this.welcomeScene = welcomeScene;
this.chooseLocationScene = chooseLocationScene;
this.vaultPath = vaultPath;
this.vaultName = vaultName;
@@ -58,11 +58,6 @@ public class CreateNewVaultNameController implements FxController {
}
}
- @FXML
- public void back() {
- window.setScene(welcomeScene.get());
- }
-
@FXML
public void next() {
window.setScene(chooseLocationScene.get());
diff --git a/src/main/java/org/cryptomator/ui/common/FxmlFile.java b/src/main/java/org/cryptomator/ui/common/FxmlFile.java
index cefd424ff..678795662 100644
--- a/src/main/java/org/cryptomator/ui/common/FxmlFile.java
+++ b/src/main/java/org/cryptomator/ui/common/FxmlFile.java
@@ -8,7 +8,6 @@ public enum FxmlFile {
ADDVAULT_NEW_PASSWORD("/fxml/addvault_new_password.fxml"), //
ADDVAULT_NEW_RECOVERYKEY("/fxml/addvault_new_recoverykey.fxml"), //
ADDVAULT_SUCCESS("/fxml/addvault_success.fxml"), //
- ADDVAULT_WELCOME("/fxml/addvault_welcome.fxml"), //
CHANGEPASSWORD("/fxml/changepassword.fxml"), //
CONVERTVAULT_HUBTOPASSWORD_START("/fxml/convertvault_hubtopassword_start.fxml"), //
CONVERTVAULT_HUBTOPASSWORD_CONVERT("/fxml/convertvault_hubtopassword_convert.fxml"), //
diff --git a/src/main/java/org/cryptomator/ui/error/ErrorController.java b/src/main/java/org/cryptomator/ui/error/ErrorController.java
index b25de6d84..3feb3ff44 100644
--- a/src/main/java/org/cryptomator/ui/error/ErrorController.java
+++ b/src/main/java/org/cryptomator/ui/error/ErrorController.java
@@ -47,14 +47,15 @@ public class ErrorController implements FxController {
private static final String REPORT_URL_FORMAT = "https://github.com/cryptomator/cryptomator/discussions/new?category=Errors&title=Error+%s&body=%s";
private static final String SEARCH_ERRORCODE_DELIM = " OR ";
private static final String REPORT_BODY_TEMPLATE = """
+
OS: %s / %s
App: %s / %s
-
-
-
-
+ Description:
+
+
+ Details:
""";
diff --git a/src/main/java/org/cryptomator/ui/mainwindow/MainWindowSceneFactory.java b/src/main/java/org/cryptomator/ui/mainwindow/MainWindowSceneFactory.java
index f93f4109d..d78192186 100644
--- a/src/main/java/org/cryptomator/ui/mainwindow/MainWindowSceneFactory.java
+++ b/src/main/java/org/cryptomator/ui/mainwindow/MainWindowSceneFactory.java
@@ -16,6 +16,7 @@ import javafx.stage.Stage;
public class MainWindowSceneFactory extends DefaultSceneFactory {
protected static final KeyCodeCombination SHORTCUT_N = new KeyCodeCombination(KeyCode.N, KeyCombination.SHORTCUT_DOWN);
+ protected static final KeyCodeCombination SHORTCUT_O = new KeyCodeCombination(KeyCode.O, KeyCombination.SHORTCUT_DOWN);
private final Lazy mainWindowTitleController;
private final Lazy vaultListController;
@@ -34,6 +35,7 @@ public class MainWindowSceneFactory extends DefaultSceneFactory {
} else {
scene.getAccelerators().put(SHORTCUT_W, mainWindowTitleController.get()::close);
}
- scene.getAccelerators().put(SHORTCUT_N, vaultListController.get()::didClickAddVault);
+ scene.getAccelerators().put(SHORTCUT_N, vaultListController.get()::didClickAddNewVault);
+ scene.getAccelerators().put(SHORTCUT_O, vaultListController.get()::didClickAddExistingVault);
}
}
diff --git a/src/main/java/org/cryptomator/ui/mainwindow/ResizeController.java b/src/main/java/org/cryptomator/ui/mainwindow/ResizeController.java
index 1b3f1b69f..b136fa55c 100644
--- a/src/main/java/org/cryptomator/ui/mainwindow/ResizeController.java
+++ b/src/main/java/org/cryptomator/ui/mainwindow/ResizeController.java
@@ -6,7 +6,6 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
-import javafx.beans.binding.Bindings;
import javafx.beans.binding.BooleanBinding;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
@@ -15,6 +14,7 @@ import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Region;
import javafx.stage.Screen;
import javafx.stage.Stage;
+import javafx.stage.WindowEvent;
@MainWindow
public class ResizeController implements FxController {
@@ -53,48 +53,70 @@ public class ResizeController implements FxController {
public void initialize() {
LOG.trace("init ResizeController");
- if (neverTouched()) {
- settings.displayConfiguration.set(getMonitorSizes());
- return;
- } else {
- if (didDisplayConfigurationChange()) {
- //If the position is illegal, then the window appears on the main screen in the middle of the window.
- Rectangle2D primaryScreenBounds = Screen.getPrimary().getBounds();
- window.setX((primaryScreenBounds.getWidth() - window.getMinWidth()) / 2);
- window.setY((primaryScreenBounds.getHeight() - window.getMinHeight()) / 2);
- window.setWidth(window.getMinWidth());
- window.setHeight(window.getMinHeight());
- } else {
- window.setHeight(settings.windowHeight.get() > window.getMinHeight() ? settings.windowHeight.get() : window.getMinHeight());
- window.setWidth(settings.windowWidth.get() > window.getMinWidth() ? settings.windowWidth.get() : window.getMinWidth());
- window.setX(settings.windowXPosition.get());
- window.setY(settings.windowYPosition.get());
- }
+ if (!neverTouched()) {
+ window.setHeight(settings.windowHeight.get() > window.getMinHeight() ? settings.windowHeight.get() : window.getMinHeight());
+ window.setWidth(settings.windowWidth.get() > window.getMinWidth() ? settings.windowWidth.get() : window.getMinWidth());
+ window.setX(settings.windowXPosition.get());
+ window.setY(settings.windowYPosition.get());
}
- savePositionalSettings();
+
+ window.setOnShowing(this::checkDisplayBounds);
}
private boolean neverTouched() {
return (settings.windowHeight.get() == 0) && (settings.windowWidth.get() == 0) && (settings.windowXPosition.get() == 0) && (settings.windowYPosition.get() == 0);
}
- private boolean didDisplayConfigurationChange() {
- String currentDisplayConfiguration = getMonitorSizes();
- String settingsDisplayConfiguration = settings.displayConfiguration.get();
- boolean configurationHasChanged = !settingsDisplayConfiguration.equals(currentDisplayConfiguration);
- if (configurationHasChanged) settings.displayConfiguration.set(currentDisplayConfiguration);
- return configurationHasChanged;
+ private boolean isWithinDisplayBounds() {
+ // (x1, y1) is the top left corner of the window, (x2, y2) is the bottom right corner
+ final double slack = 10;
+ final double width = window.getWidth() - 2 * slack;
+ final double height = window.getHeight() - 2 * slack;
+ final double x1 = window.getX() + slack;
+ final double y1 = window.getY() + slack;
+ final double x2 = x1 + width;
+ final double y2 = y1 + height;
+
+ final ObservableList screens = Screen.getScreensForRectangle(x1, y1, width, height);
+
+ // Find the total visible area of the window
+ double visibleArea = 0;
+ for (Screen screen : screens) {
+ Rectangle2D bounds = screen.getVisualBounds();
+
+ double xOverlap = Math.min(x2, bounds.getMaxX()) - Math.max(x1, bounds.getMinX());
+ double yOverlap = Math.min(y2, bounds.getMaxY()) - Math.max(y1, bounds.getMinY());
+
+ visibleArea += xOverlap * yOverlap;
+ }
+
+ final double windowArea = width * height;
+
+ // Within bounds if the visible area matches the window area
+ return visibleArea == windowArea;
}
- private String getMonitorSizes() {
- ObservableList screens = Screen.getScreens();
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < screens.size(); i++) {
- Rectangle2D screenBounds = screens.get(i).getBounds();
- if (!sb.isEmpty()) sb.append(" ");
- sb.append("displayId: " + i + ", " + screenBounds.getWidth() + "x" + screenBounds.getHeight() + ";");
+ private void checkDisplayBounds(WindowEvent evt) {
+
+ // Minimizing a window in Windows and closing it could result in an out of bounds position at (x, y) = (-32000, -32000)
+ // See https://devblogs.microsoft.com/oldnewthing/20041028-00/?p=37453
+ // If the position is (-32000, -32000), restore to the last saved position
+ if (window.getX() == -32000 && window.getY() == -32000) {
+ window.setX(settings.windowXPosition.get());
+ window.setY(settings.windowYPosition.get());
+ window.setWidth(settings.windowWidth.get());
+ window.setHeight(settings.windowHeight.get());
+ }
+
+ if (!isWithinDisplayBounds()) {
+ // If the position is illegal, then the window appears on the main screen in the middle of the window.
+ Rectangle2D primaryScreenBounds = Screen.getPrimary().getBounds();
+ window.setX((primaryScreenBounds.getWidth() - window.getMinWidth()) / 2);
+ window.setY((primaryScreenBounds.getHeight() - window.getMinHeight()) / 2);
+ window.setWidth(window.getMinWidth());
+ window.setHeight(window.getMinHeight());
+ savePositionalSettings();
}
- return sb.toString();
}
private void startResize(MouseEvent evt) {
@@ -183,5 +205,4 @@ public class ResizeController implements FxController {
public boolean isShowResizingArrows() {
return showResizingArrows.get();
}
-
}
\ No newline at end of file
diff --git a/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java b/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java
index f0aadfdfc..357222b33 100644
--- a/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java
+++ b/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java
@@ -20,7 +20,9 @@ import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
+import javafx.event.Event;
import javafx.fxml.FXML;
+import javafx.scene.control.Button;
import javafx.scene.control.ListView;
import javafx.scene.input.ContextMenuEvent;
import javafx.scene.input.DragEvent;
@@ -34,6 +36,7 @@ import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.EnumSet;
+import java.util.ResourceBundle;
import java.util.Set;
import java.util.stream.Collectors;
@@ -59,12 +62,21 @@ public class VaultListController implements FxController {
private final RemoveVaultComponent.Builder removeVaultDialogue;
private final VaultListManager vaultListManager;
private final BooleanProperty draggingVaultOver = new SimpleBooleanProperty();
+ private final ResourceBundle resourceBundle;
public ListView vaultList;
public StackPane root;
+ public Button addVaultBtn;
@Inject
- VaultListController(@MainWindow Stage mainWindow, ObservableList vaults, ObjectProperty selectedVault, VaultListCellFactory cellFactory, AddVaultWizardComponent.Builder addVaultWizard, RemoveVaultComponent.Builder removeVaultDialogue, VaultListManager vaultListManager) {
+ VaultListController(@MainWindow Stage mainWindow, //
+ ObservableList vaults, //
+ ObjectProperty selectedVault, //
+ VaultListCellFactory cellFactory, //
+ AddVaultWizardComponent.Builder addVaultWizard, //
+ RemoveVaultComponent.Builder removeVaultDialogue, //
+ VaultListManager vaultListManager, //
+ ResourceBundle resourceBundle) {
this.mainWindow = mainWindow;
this.vaults = vaults;
this.selectedVault = selectedVault;
@@ -72,6 +84,7 @@ public class VaultListController implements FxController {
this.addVaultWizard = addVaultWizard;
this.removeVaultDialogue = removeVaultDialogue;
this.vaultListManager = vaultListManager;
+ this.resourceBundle = resourceBundle;
this.emptyVaultList = Bindings.isEmpty(vaults);
@@ -127,6 +140,15 @@ public class VaultListController implements FxController {
root.setOnDragOver(this::handleDragEvent);
root.setOnDragDropped(this::handleDragEvent);
root.setOnDragExited(this::handleDragEvent);
+
+ addVaultBtn.addEventFilter(ContextMenuEvent.CONTEXT_MENU_REQUESTED, Event::consume);
+ }
+
+ @FXML
+ private void showMenu() {
+ double screenX = addVaultBtn.localToScreen(addVaultBtn.getBoundsInLocal()).getMinX();
+ double screenY = addVaultBtn.localToScreen(addVaultBtn.getBoundsInLocal()).getMaxY();
+ addVaultBtn.getContextMenu().show(addVaultBtn, screenX, screenY);
}
private void deselect(MouseEvent released) {
@@ -144,8 +166,13 @@ public class VaultListController implements FxController {
}
@FXML
- public void didClickAddVault() {
- addVaultWizard.build().showAddVaultWizard();
+ public void didClickAddNewVault() {
+ addVaultWizard.build().showAddNewVaultWizard(resourceBundle);
+ }
+
+ @FXML
+ public void didClickAddExistingVault() {
+ addVaultWizard.build().showAddExistingVaultWizard(resourceBundle);
}
private void pressedShortcutToRemoveVault() {
diff --git a/src/main/resources/css/dark_theme.css b/src/main/resources/css/dark_theme.css
index 45cadba93..beb50f6bc 100644
--- a/src/main/resources/css/dark_theme.css
+++ b/src/main/resources/css/dark_theme.css
@@ -795,6 +795,16 @@
-fx-scale-shape: false;
}
+/*******************************************************************************
+ * *
+ * Add Vault - MenuItem *
+ * *
+ ******************************************************************************/
+
+.add-vault-menu-item {
+ -fx-padding: 4px 8px;
+}
+
/*******************************************************************************
* *
* ProgressBar *
diff --git a/src/main/resources/css/light_theme.css b/src/main/resources/css/light_theme.css
index c3c0faaa9..a494269b7 100644
--- a/src/main/resources/css/light_theme.css
+++ b/src/main/resources/css/light_theme.css
@@ -794,6 +794,16 @@
-fx-scale-shape: false;
}
+/*******************************************************************************
+ * *
+ * Add Vault - MenuItem *
+ * *
+ ******************************************************************************/
+
+.add-vault-menu-item {
+ -fx-padding: 4px 8px;
+}
+
/*******************************************************************************
* *
* ProgressBar *
diff --git a/src/main/resources/fxml/addvault_existing.fxml b/src/main/resources/fxml/addvault_existing.fxml
index c46ad6355..200eae4f9 100644
--- a/src/main/resources/fxml/addvault_existing.fxml
+++ b/src/main/resources/fxml/addvault_existing.fxml
@@ -24,9 +24,8 @@
-
+
-
diff --git a/src/main/resources/fxml/addvault_new_name.fxml b/src/main/resources/fxml/addvault_new_name.fxml
index 185f80ed4..0b983c4a0 100644
--- a/src/main/resources/fxml/addvault_new_name.fxml
+++ b/src/main/resources/fxml/addvault_new_name.fxml
@@ -68,9 +68,8 @@
-
+
-
diff --git a/src/main/resources/fxml/addvault_welcome.fxml b/src/main/resources/fxml/addvault_welcome.fxml
deleted file mode 100644
index d86162020..000000000
--- a/src/main/resources/fxml/addvault_welcome.fxml
+++ /dev/null
@@ -1,44 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/main/resources/fxml/vault_list.fxml b/src/main/resources/fxml/vault_list.fxml
index 80f29f2f7..146fa877c 100644
--- a/src/main/resources/fxml/vault_list.fxml
+++ b/src/main/resources/fxml/vault_list.fxml
@@ -8,6 +8,8 @@
+
+
-