From 12a21bbb71fb2169450bf70861da1ba38a65ff1b Mon Sep 17 00:00:00 2001 From: JaniruTEC Date: Thu, 17 Feb 2022 02:37:25 +0100 Subject: [PATCH 01/15] Added "--version" (short: "-v") --- .../org/cryptomator/launcher/Cryptomator.java | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/cryptomator/launcher/Cryptomator.java b/src/main/java/org/cryptomator/launcher/Cryptomator.java index 5502d804a..337d1af22 100644 --- a/src/main/java/org/cryptomator/launcher/Cryptomator.java +++ b/src/main/java/org/cryptomator/launcher/Cryptomator.java @@ -20,7 +20,7 @@ import org.slf4j.LoggerFactory; import javax.inject.Inject; import javax.inject.Named; import javax.inject.Singleton; -import java.io.IOException; +import java.util.Arrays; import java.util.List; import java.util.Optional; import java.util.concurrent.CountDownLatch; @@ -54,6 +54,21 @@ public class Cryptomator { } public static void main(String[] args) { + var printVersion = Optional.ofNullable(args) // + .stream() //Streams either one element (the args-array) or zero elements + .flatMap(Arrays::stream) // + .anyMatch(arg -> "-v".equals(arg) || "--version".equals(arg)); + + if(printVersion) { + var appVer = Optional.ofNullable(System.getProperty("cryptomator.appVersion")); + var buildNumber = Optional.ofNullable(System.getProperty("cryptomator.buildNumber")); + + //Reduce noise for parsers by using System.out directly + System.out.printf("Cryptomator version %s (build %s)%n", appVer.orElse(""), buildNumber.orElse("")); + System.exit(0); + return; + } + int exitCode = CRYPTOMATOR_COMPONENT.application().run(args); LOG.info("Exit {}", exitCode); System.exit(exitCode); // end remaining non-daemon threads. From 9ed7438f0529e8cb984d19966b8b5720c0e57d3d Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Tue, 5 Apr 2022 07:55:14 +0200 Subject: [PATCH 02/15] bump zxcvbn4j version, fixes #979 --- pom.xml | 2 +- .../org/cryptomator/ui/common/PasswordStrengthUtilTest.java | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index bee198a77..6518a2d53 100644 --- a/pom.xml +++ b/pom.xml @@ -44,7 +44,7 @@ 31.1-jre 2.41 2.9.0 - 1.5.2 + 1.6.0 1.7.36 1.2.11 diff --git a/src/test/java/org/cryptomator/ui/common/PasswordStrengthUtilTest.java b/src/test/java/org/cryptomator/ui/common/PasswordStrengthUtilTest.java index a6e4e27af..fe3ba8846 100644 --- a/src/test/java/org/cryptomator/ui/common/PasswordStrengthUtilTest.java +++ b/src/test/java/org/cryptomator/ui/common/PasswordStrengthUtilTest.java @@ -22,7 +22,6 @@ public class PasswordStrengthUtilTest { } @Test - @Disabled("waiting on upstream fix") // https://github.com/nulab/zxcvbn4j/issues/54 public void testIssue979() { PasswordStrengthUtil util = new PasswordStrengthUtil(Mockito.mock(ResourceBundle.class), Mockito.mock(Environment.class)); int result1 = util.computeRate("backed derrick buckling mountains glove client procedures desire destination sword hidden ram"); From 78a50548abc5ca89fbec2631c0d69ec0aa8db5ea Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Tue, 5 Apr 2022 09:19:58 +0200 Subject: [PATCH 03/15] optionally allow extended key validation in `RecoveryKeyFactory#validateRecoveryKey` --- .../ui/recoverykey/RecoveryKeyFactory.java | 25 ++++++++++++++++--- .../recoverykey/RecoveryKeyFactoryTest.java | 18 +++++++++++++ 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyFactory.java b/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyFactory.java index 311f5746e..a1180dd9f 100644 --- a/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyFactory.java +++ b/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyFactory.java @@ -7,6 +7,7 @@ import org.cryptomator.cryptolib.api.CryptoException; import org.cryptomator.cryptolib.api.InvalidPassphraseException; import org.cryptomator.cryptolib.api.Masterkey; import org.cryptomator.cryptolib.common.MasterkeyFileAccess; +import org.jetbrains.annotations.Nullable; import javax.inject.Inject; import javax.inject.Singleton; @@ -16,6 +17,7 @@ import java.nio.file.Path; import java.nio.file.StandardCopyOption; import java.util.Arrays; import java.util.Collection; +import java.util.function.Predicate; import static org.cryptomator.common.Constants.MASTERKEY_BACKUP_SUFFIX; import static org.cryptomator.common.Constants.MASTERKEY_FILENAME; @@ -102,12 +104,29 @@ public class RecoveryKeyFactory { * @return true if this seems to be a legitimate recovery key */ public boolean validateRecoveryKey(String recoveryKey) { + return validateRecoveryKey(recoveryKey, null); + } + + /** + * Checks whether a String is a syntactically correct recovery key with a valid checksum and passes the extended validation. + * + * @param recoveryKey A word sequence which might be a recovery key + * @param extendedValidation Additional verification of the decoded key (optional) + * @return true if this seems to be a legitimate recovery key and passes the extended validation + */ + public boolean validateRecoveryKey(String recoveryKey, @Nullable Predicate extendedValidation) { + byte[] key = new byte[0]; try { - byte[] key = decodeRecoveryKey(recoveryKey); - Arrays.fill(key, (byte) 0x00); - return true; + key = decodeRecoveryKey(recoveryKey); + if (extendedValidation != null) { + return extendedValidation.test(key); + } else { + return true; + } } catch (IllegalArgumentException e) { return false; + } finally { + Arrays.fill(key, (byte) 0x00); } } diff --git a/src/test/java/org/cryptomator/ui/recoverykey/RecoveryKeyFactoryTest.java b/src/test/java/org/cryptomator/ui/recoverykey/RecoveryKeyFactoryTest.java index c9061451e..ea5d0fd3a 100644 --- a/src/test/java/org/cryptomator/ui/recoverykey/RecoveryKeyFactoryTest.java +++ b/src/test/java/org/cryptomator/ui/recoverykey/RecoveryKeyFactoryTest.java @@ -7,10 +7,13 @@ import org.cryptomator.cryptolib.common.MasterkeyFileAccess; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; import org.mockito.Mockito; import java.io.IOException; import java.nio.file.Path; +import java.util.function.Predicate; public class RecoveryKeyFactoryTest { @@ -75,4 +78,19 @@ public class RecoveryKeyFactoryTest { Assertions.assertTrue(result); } + @ParameterizedTest(name = "success = {0}") + @DisplayName("validateRecoveryKey() with extended validation") + @ValueSource(booleans = {true, false}) + public void testValidateValidateRecoveryKeyWithValidKey(boolean extendedValidationResult) { + Predicate validator = Mockito.mock(Predicate.class); + Mockito.doReturn(extendedValidationResult).when(validator).test(Mockito.any()); + boolean result = inTest.validateRecoveryKey(""" + pathway lift abuse plenty export texture gentleman landscape beyond ceiling around leaf cafe charity \ + border breakdown victory surely computer cat linger restrict infer crowd live computer true written amazed \ + investor boot depth left theory snow whereby terminal weekly reject happiness circuit partial cup ad \ + """, validator); + Mockito.verify(validator).test(Mockito.any()); + Assertions.assertEquals(extendedValidationResult, result); + } + } \ No newline at end of file From d861ef0d22afa23683814fc54fdc703328b11898 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Tue, 5 Apr 2022 09:21:33 +0200 Subject: [PATCH 04/15] Make use of extended validation to prevent applying a recovery key that didn't sign the vault config --- .../ui/recoverykey/RecoveryKeyModule.java | 15 +++++++++ .../RecoveryKeyRecoverController.java | 33 +++++++++++++++++-- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyModule.java b/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyModule.java index b30167e73..0522e3a8d 100644 --- a/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyModule.java +++ b/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyModule.java @@ -4,7 +4,9 @@ import dagger.Binds; import dagger.Module; import dagger.Provides; import dagger.multibindings.IntoMap; +import org.cryptomator.common.Nullable; import org.cryptomator.common.vaults.Vault; +import org.cryptomator.cryptofs.VaultConfig; import org.cryptomator.ui.common.DefaultSceneFactory; import org.cryptomator.ui.common.FxController; import org.cryptomator.ui.common.FxControllerKey; @@ -22,12 +24,25 @@ import javafx.beans.property.StringProperty; import javafx.scene.Scene; import javafx.stage.Modality; import javafx.stage.Stage; +import java.io.IOException; import java.util.Map; import java.util.ResourceBundle; @Module abstract class RecoveryKeyModule { + @Provides + @Nullable + @RecoveryKeyWindow + @RecoveryKeyScoped + static VaultConfig.UnverifiedVaultConfig vaultConfig(@RecoveryKeyWindow Vault vault) { + try { + return vault.getVaultConfigCache().get(); + } catch (IOException e) { + return null; + } + } + @Provides @RecoveryKeyWindow @RecoveryKeyScoped diff --git a/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyRecoverController.java b/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyRecoverController.java index 7e40a833b..e05a73169 100644 --- a/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyRecoverController.java +++ b/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyRecoverController.java @@ -3,10 +3,16 @@ package org.cryptomator.ui.recoverykey; import com.google.common.base.CharMatcher; import com.google.common.base.Strings; import dagger.Lazy; +import org.cryptomator.common.Nullable; import org.cryptomator.common.vaults.Vault; +import org.cryptomator.cryptofs.VaultConfig; +import org.cryptomator.cryptofs.VaultConfigLoadException; +import org.cryptomator.cryptofs.VaultKeyInvalidException; 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.beans.binding.Bindings; @@ -24,10 +30,12 @@ import java.util.Optional; @RecoveryKeyScoped public class RecoveryKeyRecoverController implements FxController { - private final static CharMatcher ALLOWED_CHARS = CharMatcher.inRange('a', 'z').or(CharMatcher.is(' ')); + private static final Logger LOG = LoggerFactory.getLogger(RecoveryKeyCreationController.class); + private static final CharMatcher ALLOWED_CHARS = CharMatcher.inRange('a', 'z').or(CharMatcher.is(' ')); private final Stage window; private final Vault vault; + private final VaultConfig.UnverifiedVaultConfig unverifiedVaultConfig; private final StringProperty recoveryKey; private final RecoveryKeyFactory recoveryKeyFactory; private final BooleanBinding validRecoveryKey; @@ -37,9 +45,10 @@ public class RecoveryKeyRecoverController implements FxController { public TextArea textarea; @Inject - public RecoveryKeyRecoverController(@RecoveryKeyWindow Stage window, @RecoveryKeyWindow Vault vault, @RecoveryKeyWindow StringProperty recoveryKey, RecoveryKeyFactory recoveryKeyFactory, @FxmlScene(FxmlFile.RECOVERYKEY_RESET_PASSWORD) Lazy resetPasswordScene) { + public RecoveryKeyRecoverController(@RecoveryKeyWindow Stage window, @RecoveryKeyWindow Vault vault, @RecoveryKeyWindow @Nullable VaultConfig.UnverifiedVaultConfig unverifiedVaultConfig, @RecoveryKeyWindow StringProperty recoveryKey, RecoveryKeyFactory recoveryKeyFactory, @FxmlScene(FxmlFile.RECOVERYKEY_RESET_PASSWORD) Lazy resetPasswordScene) { this.window = window; this.vault = vault; + this.unverifiedVaultConfig = unverifiedVaultConfig; this.recoveryKey = recoveryKey; this.recoveryKeyFactory = recoveryKeyFactory; this.validRecoveryKey = Bindings.createBooleanBinding(this::isValidRecoveryKey, recoveryKey); @@ -96,6 +105,20 @@ public class RecoveryKeyRecoverController implements FxController { window.setScene(resetPasswordScene.get()); } + private boolean checkKeyAgainstVaultConfig(byte[] key) { + try { + var config = unverifiedVaultConfig.verify(key, unverifiedVaultConfig.allegedVaultVersion()); + LOG.info("Provided recovery key matches vault config signature for vault {}", config.getId()); + return true; + } catch (VaultKeyInvalidException e) { + LOG.debug("Provided recovery key does not match vault config signature."); + return false; + } catch (VaultConfigLoadException e) { + LOG.error("Failed to parse vault config", e); + return false; + } + } + /* Getter/Setter */ public Vault getVault() { @@ -107,7 +130,11 @@ public class RecoveryKeyRecoverController implements FxController { } public boolean isValidRecoveryKey() { - return recoveryKeyFactory.validateRecoveryKey(recoveryKey.get()); + if (unverifiedVaultConfig != null) { + return recoveryKeyFactory.validateRecoveryKey(recoveryKey.get(), this::checkKeyAgainstVaultConfig); + } else { + return recoveryKeyFactory.validateRecoveryKey(recoveryKey.get()); + } } public TextFormatter getRecoveryKeyTextFormatter() { From d308ee626a211cf034669f24822c866bf33fea80 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Tue, 5 Apr 2022 09:27:44 +0200 Subject: [PATCH 05/15] more descriptive name [ci skip] --- .../org/cryptomator/ui/recoverykey/RecoveryKeyFactoryTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/org/cryptomator/ui/recoverykey/RecoveryKeyFactoryTest.java b/src/test/java/org/cryptomator/ui/recoverykey/RecoveryKeyFactoryTest.java index ea5d0fd3a..82928f11c 100644 --- a/src/test/java/org/cryptomator/ui/recoverykey/RecoveryKeyFactoryTest.java +++ b/src/test/java/org/cryptomator/ui/recoverykey/RecoveryKeyFactoryTest.java @@ -78,7 +78,7 @@ public class RecoveryKeyFactoryTest { Assertions.assertTrue(result); } - @ParameterizedTest(name = "success = {0}") + @ParameterizedTest(name = "passing validation = {0}") @DisplayName("validateRecoveryKey() with extended validation") @ValueSource(booleans = {true, false}) public void testValidateValidateRecoveryKeyWithValidKey(boolean extendedValidationResult) { From 12d38335d841ea9b9775b58e76fc4bdec3921927 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Sat, 9 Apr 2022 15:05:05 +0200 Subject: [PATCH 06/15] increase width of preferences window, which should fix #2107 --- src/main/resources/fxml/preferences.fxml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/fxml/preferences.fxml b/src/main/resources/fxml/preferences.fxml index 4eaf3d45c..e89cd7f81 100644 --- a/src/main/resources/fxml/preferences.fxml +++ b/src/main/resources/fxml/preferences.fxml @@ -9,7 +9,7 @@ fx:controller="org.cryptomator.ui.preferences.PreferencesController" minWidth="-Infinity" maxWidth="-Infinity" - prefWidth="500" + prefWidth="650" tabMinWidth="60" tabClosingPolicy="UNAVAILABLE" tabDragPolicy="FIXED"> From 9b00cd923c4b72af1d83131f4e2efb38bd1c01b0 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Sat, 9 Apr 2022 15:13:53 +0200 Subject: [PATCH 07/15] moved interface settings to separate preferences tab --- .../GeneralPreferencesController.java | 127 +------------- .../InterfacePreferencesController.java | 156 ++++++++++++++++++ .../ui/preferences/PreferencesController.java | 8 +- .../ui/preferences/PreferencesModule.java | 5 + .../preferences/SelectedPreferencesTab.java | 5 + src/main/resources/fxml/preferences.fxml | 8 + .../resources/fxml/preferences_general.fxml | 21 --- .../resources/fxml/preferences_interface.fxml | 44 +++++ src/main/resources/i18n/strings.properties | 2 + 9 files changed, 227 insertions(+), 149 deletions(-) create mode 100644 src/main/java/org/cryptomator/ui/preferences/InterfacePreferencesController.java create mode 100644 src/main/resources/fxml/preferences_interface.fxml diff --git a/src/main/java/org/cryptomator/ui/preferences/GeneralPreferencesController.java b/src/main/java/org/cryptomator/ui/preferences/GeneralPreferencesController.java index 3ebdad4a4..f2b7ef3b7 100644 --- a/src/main/java/org/cryptomator/ui/preferences/GeneralPreferencesController.java +++ b/src/main/java/org/cryptomator/ui/preferences/GeneralPreferencesController.java @@ -1,37 +1,25 @@ package org.cryptomator.ui.preferences; -import com.google.common.base.Strings; import org.cryptomator.common.Environment; -import org.cryptomator.common.LicenseHolder; import org.cryptomator.common.settings.Settings; -import org.cryptomator.common.settings.UiTheme; import org.cryptomator.integrations.autostart.AutoStartProvider; import org.cryptomator.integrations.autostart.ToggleAutoStartFailedException; import org.cryptomator.integrations.keychain.KeychainAccessProvider; -import org.cryptomator.launcher.SupportedLanguages; import org.cryptomator.ui.common.FxController; import org.cryptomator.ui.fxapp.FxApplicationWindows; -import org.cryptomator.ui.traymenu.TrayMenuComponent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.inject.Inject; import javafx.application.Application; import javafx.beans.binding.Bindings; -import javafx.beans.property.ObjectProperty; -import javafx.beans.value.ObservableValue; import javafx.fxml.FXML; -import javafx.geometry.NodeOrientation; import javafx.scene.control.CheckBox; import javafx.scene.control.ChoiceBox; -import javafx.scene.control.RadioButton; -import javafx.scene.control.Toggle; import javafx.scene.control.ToggleGroup; import javafx.stage.Stage; import javafx.util.StringConverter; -import java.util.Locale; import java.util.Optional; -import java.util.ResourceBundle; import java.util.Set; @PreferencesScoped @@ -41,39 +29,23 @@ public class GeneralPreferencesController implements FxController { private final Stage window; private final Settings settings; - private final boolean trayMenuInitialized; - private final boolean trayMenuSupported; private final Optional autoStartProvider; - private final ObjectProperty selectedTabProperty; - private final LicenseHolder licenseHolder; - private final ResourceBundle resourceBundle; private final Application application; private final Environment environment; private final Set keychainAccessProviders; private final FxApplicationWindows appWindows; - public ChoiceBox themeChoiceBox; public ChoiceBox keychainBackendChoiceBox; - public CheckBox showMinimizeButtonCheckbox; - public CheckBox showTrayIconCheckbox; public CheckBox startHiddenCheckbox; - public ChoiceBox preferredLanguageChoiceBox; public CheckBox debugModeCheckbox; public CheckBox autoStartCheckbox; public ToggleGroup nodeOrientation; - public RadioButton nodeOrientationLtr; - public RadioButton nodeOrientationRtl; @Inject - GeneralPreferencesController(@PreferencesWindow Stage window, Settings settings, TrayMenuComponent trayMenu, Optional autoStartProvider, Set keychainAccessProviders, ObjectProperty selectedTabProperty, LicenseHolder licenseHolder, ResourceBundle resourceBundle, Application application, Environment environment, FxApplicationWindows appWindows) { + GeneralPreferencesController(@PreferencesWindow Stage window, Settings settings, Optional autoStartProvider, Set keychainAccessProviders, Application application, Environment environment, FxApplicationWindows appWindows) { this.window = window; this.settings = settings; - this.trayMenuInitialized = trayMenu.isInitialized(); - this.trayMenuSupported = trayMenu.isSupported(); this.autoStartProvider = autoStartProvider; this.keychainAccessProviders = keychainAccessProviders; - this.selectedTabProperty = selectedTabProperty; - this.licenseHolder = licenseHolder; - this.resourceBundle = resourceBundle; this.application = application; this.environment = environment; this.appWindows = appWindows; @@ -81,32 +53,12 @@ public class GeneralPreferencesController implements FxController { @FXML public void initialize() { - themeChoiceBox.getItems().addAll(UiTheme.applicableValues()); - if (!themeChoiceBox.getItems().contains(settings.theme().get())) { - settings.theme().set(UiTheme.LIGHT); - } - themeChoiceBox.valueProperty().bindBidirectional(settings.theme()); - themeChoiceBox.setConverter(new UiThemeConverter(resourceBundle)); - - showMinimizeButtonCheckbox.selectedProperty().bindBidirectional(settings.showMinimizeButton()); - - showTrayIconCheckbox.selectedProperty().bindBidirectional(settings.showTrayIcon()); - startHiddenCheckbox.selectedProperty().bindBidirectional(settings.startHidden()); - preferredLanguageChoiceBox.getItems().add(null); - preferredLanguageChoiceBox.getItems().addAll(SupportedLanguages.LANGUAGAE_TAGS); - preferredLanguageChoiceBox.valueProperty().bindBidirectional(settings.languageProperty()); - preferredLanguageChoiceBox.setConverter(new LanguageTagConverter(resourceBundle)); - debugModeCheckbox.selectedProperty().bindBidirectional(settings.debugMode()); autoStartProvider.ifPresent(autoStart -> autoStartCheckbox.setSelected(autoStart.isEnabled())); - nodeOrientationLtr.setSelected(settings.userInterfaceOrientation().get() == NodeOrientation.LEFT_TO_RIGHT); - nodeOrientationRtl.setSelected(settings.userInterfaceOrientation().get() == NodeOrientation.RIGHT_TO_LEFT); - nodeOrientation.selectedToggleProperty().addListener(this::toggleNodeOrientation); - var keychainSettingsConverter = new KeychainProviderClassNameConverter(keychainAccessProviders); keychainBackendChoiceBox.getItems().addAll(keychainAccessProviders); keychainBackendChoiceBox.setValue(keychainSettingsConverter.fromString(settings.keychainProvider().get())); @@ -114,29 +66,10 @@ public class GeneralPreferencesController implements FxController { Bindings.bindBidirectional(settings.keychainProvider(), keychainBackendChoiceBox.valueProperty(), keychainSettingsConverter); } - - public boolean isTrayMenuInitialized() { - return trayMenuInitialized; - } - - public boolean isTrayMenuSupported() { - return trayMenuSupported; - } - public boolean isAutoStartSupported() { return autoStartProvider.isPresent(); } - private void toggleNodeOrientation(@SuppressWarnings("unused") ObservableValue observable, @SuppressWarnings("unused") Toggle oldValue, Toggle newValue) { - if (nodeOrientationLtr.equals(newValue)) { - settings.userInterfaceOrientation().set(NodeOrientation.LEFT_TO_RIGHT); - } else if (nodeOrientationRtl.equals(newValue)) { - settings.userInterfaceOrientation().set(NodeOrientation.RIGHT_TO_LEFT); - } else { - LOG.warn("Unexpected toggle option {}", newValue); - } - } - @FXML public void toggleAutoStart() { autoStartProvider.ifPresent(autoStart -> { @@ -155,16 +88,6 @@ public class GeneralPreferencesController implements FxController { }); } - public LicenseHolder getLicenseHolder() { - return licenseHolder; - } - - - @FXML - public void showContributeTab() { - selectedTabProperty.set(SelectedPreferencesTab.CONTRIBUTE); - } - @FXML public void showLogfileDirectory() { environment.getLogDir().ifPresent(logDirPath -> application.getHostServices().showDocument(logDirPath.toUri().toString())); @@ -172,53 +95,7 @@ public class GeneralPreferencesController implements FxController { /* Helper classes */ - private static class UiThemeConverter extends StringConverter { - - private final ResourceBundle resourceBundle; - - UiThemeConverter(ResourceBundle resourceBundle) { - this.resourceBundle = resourceBundle; - } - - @Override - public String toString(UiTheme impl) { - return resourceBundle.getString(impl.getDisplayName()); - } - - @Override - public UiTheme fromString(String string) { - throw new UnsupportedOperationException(); - } - - } - - private static class LanguageTagConverter extends StringConverter { - - private final ResourceBundle resourceBundle; - - LanguageTagConverter(ResourceBundle resourceBundle) { - this.resourceBundle = resourceBundle; - } - - @Override - public String toString(String tag) { - if (tag == null) { - return resourceBundle.getString("preferences.general.language.auto"); - } else { - var locale = Locale.forLanguageTag(tag); - var lang = locale.getDisplayLanguage(locale); - var region = locale.getDisplayCountry(locale); - return lang + (Strings.isNullOrEmpty(region) ? "" : " (" + region + ")"); - } - } - - @Override - public String fromString(String displayLanguage) { - throw new UnsupportedOperationException(); - } - } - - private class KeychainProviderDisplayNameConverter extends StringConverter { + private static class KeychainProviderDisplayNameConverter extends StringConverter { @Override public String toString(KeychainAccessProvider provider) { diff --git a/src/main/java/org/cryptomator/ui/preferences/InterfacePreferencesController.java b/src/main/java/org/cryptomator/ui/preferences/InterfacePreferencesController.java new file mode 100644 index 000000000..076331940 --- /dev/null +++ b/src/main/java/org/cryptomator/ui/preferences/InterfacePreferencesController.java @@ -0,0 +1,156 @@ +package org.cryptomator.ui.preferences; + +import com.google.common.base.Strings; +import org.cryptomator.common.LicenseHolder; +import org.cryptomator.common.settings.Settings; +import org.cryptomator.common.settings.UiTheme; +import org.cryptomator.launcher.SupportedLanguages; +import org.cryptomator.ui.common.FxController; +import org.cryptomator.ui.traymenu.TrayMenuComponent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.inject.Inject; +import javafx.beans.property.ObjectProperty; +import javafx.beans.value.ObservableValue; +import javafx.fxml.FXML; +import javafx.geometry.NodeOrientation; +import javafx.scene.control.CheckBox; +import javafx.scene.control.ChoiceBox; +import javafx.scene.control.RadioButton; +import javafx.scene.control.Toggle; +import javafx.scene.control.ToggleGroup; +import javafx.util.StringConverter; +import java.util.Locale; +import java.util.ResourceBundle; + +@PreferencesScoped +public class InterfacePreferencesController implements FxController { + + private static final Logger LOG = LoggerFactory.getLogger(InterfacePreferencesController.class); + + private final Settings settings; + private final boolean trayMenuInitialized; + private final boolean trayMenuSupported; + private final ObjectProperty selectedTabProperty; + private final LicenseHolder licenseHolder; + private final ResourceBundle resourceBundle; + public ChoiceBox themeChoiceBox; + public CheckBox showMinimizeButtonCheckbox; + public CheckBox showTrayIconCheckbox; + public ChoiceBox preferredLanguageChoiceBox; + public ToggleGroup nodeOrientation; + public RadioButton nodeOrientationLtr; + public RadioButton nodeOrientationRtl; + + @Inject + InterfacePreferencesController(Settings settings, TrayMenuComponent trayMenu, ObjectProperty selectedTabProperty, LicenseHolder licenseHolder, ResourceBundle resourceBundle) { + this.settings = settings; + this.trayMenuInitialized = trayMenu.isInitialized(); + this.trayMenuSupported = trayMenu.isSupported(); + this.selectedTabProperty = selectedTabProperty; + this.licenseHolder = licenseHolder; + this.resourceBundle = resourceBundle; + } + + @FXML + public void initialize() { + themeChoiceBox.getItems().addAll(UiTheme.applicableValues()); + if (!themeChoiceBox.getItems().contains(settings.theme().get())) { + settings.theme().set(UiTheme.LIGHT); + } + themeChoiceBox.valueProperty().bindBidirectional(settings.theme()); + themeChoiceBox.setConverter(new UiThemeConverter(resourceBundle)); + + showMinimizeButtonCheckbox.selectedProperty().bindBidirectional(settings.showMinimizeButton()); + + showTrayIconCheckbox.selectedProperty().bindBidirectional(settings.showTrayIcon()); + + preferredLanguageChoiceBox.getItems().add(null); + preferredLanguageChoiceBox.getItems().addAll(SupportedLanguages.LANGUAGAE_TAGS); + preferredLanguageChoiceBox.valueProperty().bindBidirectional(settings.languageProperty()); + preferredLanguageChoiceBox.setConverter(new LanguageTagConverter(resourceBundle)); + + nodeOrientationLtr.setSelected(settings.userInterfaceOrientation().get() == NodeOrientation.LEFT_TO_RIGHT); + nodeOrientationRtl.setSelected(settings.userInterfaceOrientation().get() == NodeOrientation.RIGHT_TO_LEFT); + nodeOrientation.selectedToggleProperty().addListener(this::toggleNodeOrientation); + } + + + public boolean isTrayMenuInitialized() { + return trayMenuInitialized; + } + + public boolean isTrayMenuSupported() { + return trayMenuSupported; + } + + private void toggleNodeOrientation(@SuppressWarnings("unused") ObservableValue observable, @SuppressWarnings("unused") Toggle oldValue, Toggle newValue) { + if (nodeOrientationLtr.equals(newValue)) { + settings.userInterfaceOrientation().set(NodeOrientation.LEFT_TO_RIGHT); + } else if (nodeOrientationRtl.equals(newValue)) { + settings.userInterfaceOrientation().set(NodeOrientation.RIGHT_TO_LEFT); + } else { + LOG.warn("Unexpected toggle option {}", newValue); + } + } + + public LicenseHolder getLicenseHolder() { + return licenseHolder; + } + + + @FXML + public void showContributeTab() { + selectedTabProperty.set(SelectedPreferencesTab.CONTRIBUTE); + } + + /* Helper classes */ + + private static class UiThemeConverter extends StringConverter { + + private final ResourceBundle resourceBundle; + + UiThemeConverter(ResourceBundle resourceBundle) { + this.resourceBundle = resourceBundle; + } + + @Override + public String toString(UiTheme impl) { + return resourceBundle.getString(impl.getDisplayName()); + } + + @Override + public UiTheme fromString(String string) { + throw new UnsupportedOperationException(); + } + + } + + private static class LanguageTagConverter extends StringConverter { + + private final ResourceBundle resourceBundle; + + LanguageTagConverter(ResourceBundle resourceBundle) { + this.resourceBundle = resourceBundle; + } + + @Override + public String toString(String tag) { + if (tag == null) { + return resourceBundle.getString("preferences.general.language.auto"); + } else { + var locale = Locale.forLanguageTag(tag); + var lang = locale.getDisplayLanguage(locale); + var region = locale.getDisplayCountry(locale); + return lang + (Strings.isNullOrEmpty(region) ? "" : " (" + region + ")"); + } + } + + @Override + public String fromString(String displayLanguage) { + throw new UnsupportedOperationException(); + } + } + +} diff --git a/src/main/java/org/cryptomator/ui/preferences/PreferencesController.java b/src/main/java/org/cryptomator/ui/preferences/PreferencesController.java index 276794753..caaaf7d80 100644 --- a/src/main/java/org/cryptomator/ui/preferences/PreferencesController.java +++ b/src/main/java/org/cryptomator/ui/preferences/PreferencesController.java @@ -24,6 +24,7 @@ public class PreferencesController implements FxController { private final BooleanBinding updateAvailable; public TabPane tabPane; public Tab generalTab; + public Tab interfaceTab; public Tab volumeTab; public Tab updatesTab; public Tab contributeTab; @@ -50,10 +51,11 @@ public class PreferencesController implements FxController { private Tab getTabToSelect(SelectedPreferencesTab selectedTab) { return switch (selectedTab) { - case UPDATES -> updatesTab; - case VOLUME -> volumeTab; - case CONTRIBUTE -> contributeTab; case GENERAL -> generalTab; + case INTERFACE -> interfaceTab; + case VOLUME -> volumeTab; + case UPDATES -> updatesTab; + case CONTRIBUTE -> contributeTab; case ABOUT -> aboutTab; case ANY -> updateAvailable.get() ? updatesTab : generalTab; }; diff --git a/src/main/java/org/cryptomator/ui/preferences/PreferencesModule.java b/src/main/java/org/cryptomator/ui/preferences/PreferencesModule.java index 189666591..858f8f1d8 100644 --- a/src/main/java/org/cryptomator/ui/preferences/PreferencesModule.java +++ b/src/main/java/org/cryptomator/ui/preferences/PreferencesModule.java @@ -64,6 +64,11 @@ abstract class PreferencesModule { @FxControllerKey(GeneralPreferencesController.class) abstract FxController bindGeneralPreferencesController(GeneralPreferencesController controller); + @Binds + @IntoMap + @FxControllerKey(InterfacePreferencesController.class) + abstract FxController bindInterfacePreferencesController(InterfacePreferencesController controller); + @Binds @IntoMap @FxControllerKey(UpdatesPreferencesController.class) diff --git a/src/main/java/org/cryptomator/ui/preferences/SelectedPreferencesTab.java b/src/main/java/org/cryptomator/ui/preferences/SelectedPreferencesTab.java index 892d16a8c..00b519493 100644 --- a/src/main/java/org/cryptomator/ui/preferences/SelectedPreferencesTab.java +++ b/src/main/java/org/cryptomator/ui/preferences/SelectedPreferencesTab.java @@ -11,6 +11,11 @@ public enum SelectedPreferencesTab { */ GENERAL, + /** + * Show interface tab + */ + INTERFACE, + /** * Show volume tab */ diff --git a/src/main/resources/fxml/preferences.fxml b/src/main/resources/fxml/preferences.fxml index e89cd7f81..c96eb5395 100644 --- a/src/main/resources/fxml/preferences.fxml +++ b/src/main/resources/fxml/preferences.fxml @@ -22,6 +22,14 @@ + + + + + + + + diff --git a/src/main/resources/fxml/preferences_general.fxml b/src/main/resources/fxml/preferences_general.fxml index 1e3be74c6..fdb3af4a4 100644 --- a/src/main/resources/fxml/preferences_general.fxml +++ b/src/main/resources/fxml/preferences_general.fxml @@ -20,29 +20,8 @@ - - - - - - - - - - - - - diff --git a/src/main/resources/fxml/preferences_interface.fxml b/src/main/resources/fxml/preferences_interface.fxml new file mode 100644 index 000000000..1240d40fc --- /dev/null +++ b/src/main/resources/fxml/preferences_interface.fxml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/i18n/strings.properties b/src/main/resources/i18n/strings.properties index 4c2ab688c..ac84325e3 100644 --- a/src/main/resources/i18n/strings.properties +++ b/src/main/resources/i18n/strings.properties @@ -208,6 +208,8 @@ preferences.general.keychainBackend=Store passwords with preferences.general.interfaceOrientation=Interface Orientation preferences.general.interfaceOrientation.ltr=Left to Right preferences.general.interfaceOrientation.rtl=Right to Left +## Interface +preferences.interface=Interface ## Volume preferences.volume=Virtual Drive preferences.volume.type=Volume Type From 3b8f2adedf7a08b923dac67fb7e5acbb0f54b7bd Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Sat, 9 Apr 2022 15:18:44 +0200 Subject: [PATCH 08/15] increased margins and spacings --- src/main/resources/fxml/preferences_about.fxml | 2 +- src/main/resources/fxml/preferences_contribute.fxml | 2 +- src/main/resources/fxml/preferences_general.fxml | 5 ++--- src/main/resources/fxml/preferences_interface.fxml | 4 ++-- src/main/resources/fxml/preferences_updates.fxml | 4 ++-- src/main/resources/fxml/preferences_volume.fxml | 4 ++-- 6 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/main/resources/fxml/preferences_about.fxml b/src/main/resources/fxml/preferences_about.fxml index cfa8ec010..0601dd410 100644 --- a/src/main/resources/fxml/preferences_about.fxml +++ b/src/main/resources/fxml/preferences_about.fxml @@ -13,7 +13,7 @@ fx:controller="org.cryptomator.ui.preferences.AboutController" spacing="18"> - + diff --git a/src/main/resources/fxml/preferences_contribute.fxml b/src/main/resources/fxml/preferences_contribute.fxml index bfe91d0eb..b9196123d 100644 --- a/src/main/resources/fxml/preferences_contribute.fxml +++ b/src/main/resources/fxml/preferences_contribute.fxml @@ -15,7 +15,7 @@ fx:controller="org.cryptomator.ui.preferences.SupporterCertificateController" spacing="18"> - + diff --git a/src/main/resources/fxml/preferences_general.fxml b/src/main/resources/fxml/preferences_general.fxml index fdb3af4a4..3ed224a29 100644 --- a/src/main/resources/fxml/preferences_general.fxml +++ b/src/main/resources/fxml/preferences_general.fxml @@ -5,19 +5,18 @@ - + spacing="9"> - + diff --git a/src/main/resources/fxml/preferences_interface.fxml b/src/main/resources/fxml/preferences_interface.fxml index 1240d40fc..b802dd1b2 100644 --- a/src/main/resources/fxml/preferences_interface.fxml +++ b/src/main/resources/fxml/preferences_interface.fxml @@ -12,12 +12,12 @@ + spacing="9"> - + diff --git a/src/main/resources/fxml/preferences_updates.fxml b/src/main/resources/fxml/preferences_updates.fxml index 0b176dfb3..08e0a958a 100644 --- a/src/main/resources/fxml/preferences_updates.fxml +++ b/src/main/resources/fxml/preferences_updates.fxml @@ -11,12 +11,12 @@ + spacing="9"> - + diff --git a/src/main/resources/fxml/preferences_volume.fxml b/src/main/resources/fxml/preferences_volume.fxml index 1fa2ac222..24929eaf2 100644 --- a/src/main/resources/fxml/preferences_volume.fxml +++ b/src/main/resources/fxml/preferences_volume.fxml @@ -10,9 +10,9 @@ + spacing="9"> - + From c8e131c49f0e03380e2581d764869e548b80507a Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Sat, 9 Apr 2022 15:25:27 +0200 Subject: [PATCH 09/15] reordered controls --- src/main/resources/fxml/preferences_general.fxml | 15 +++++++++------ .../resources/fxml/preferences_interface.fxml | 11 ++++++----- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/main/resources/fxml/preferences_general.fxml b/src/main/resources/fxml/preferences_general.fxml index 3ed224a29..fcf7b32ff 100644 --- a/src/main/resources/fxml/preferences_general.fxml +++ b/src/main/resources/fxml/preferences_general.fxml @@ -8,6 +8,7 @@ + - + - - - - + - + + + + + + diff --git a/src/main/resources/fxml/preferences_interface.fxml b/src/main/resources/fxml/preferences_interface.fxml index b802dd1b2..54f5b54c1 100644 --- a/src/main/resources/fxml/preferences_interface.fxml +++ b/src/main/resources/fxml/preferences_interface.fxml @@ -26,19 +26,20 @@ + + + + - - - From a8e73350a68082bee4615f17b12ccebc6ef4f798 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Sat, 9 Apr 2022 15:30:16 +0200 Subject: [PATCH 10/15] renamed translation keys --- .../cryptomator/common/settings/UiTheme.java | 6 ++--- .../InterfacePreferencesController.java | 2 +- .../resources/fxml/preferences_interface.fxml | 16 ++++++------- src/main/resources/i18n/strings.properties | 24 +++++++++---------- 4 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/main/java/org/cryptomator/common/settings/UiTheme.java b/src/main/java/org/cryptomator/common/settings/UiTheme.java index 62fe714e4..24e73dad6 100644 --- a/src/main/java/org/cryptomator/common/settings/UiTheme.java +++ b/src/main/java/org/cryptomator/common/settings/UiTheme.java @@ -3,9 +3,9 @@ package org.cryptomator.common.settings; import org.apache.commons.lang3.SystemUtils; public enum UiTheme { - LIGHT("preferences.general.theme.light"), // - DARK("preferences.general.theme.dark"), // - AUTOMATIC("preferences.general.theme.automatic"); + LIGHT("preferences.interface.theme.light"), // + DARK("preferences.interface.theme.dark"), // + AUTOMATIC("preferences.interface.theme.automatic"); public static UiTheme[] applicableValues() { if (SystemUtils.IS_OS_MAC || SystemUtils.IS_OS_WINDOWS) { diff --git a/src/main/java/org/cryptomator/ui/preferences/InterfacePreferencesController.java b/src/main/java/org/cryptomator/ui/preferences/InterfacePreferencesController.java index 076331940..dd463b9e3 100644 --- a/src/main/java/org/cryptomator/ui/preferences/InterfacePreferencesController.java +++ b/src/main/java/org/cryptomator/ui/preferences/InterfacePreferencesController.java @@ -138,7 +138,7 @@ public class InterfacePreferencesController implements FxController { @Override public String toString(String tag) { if (tag == null) { - return resourceBundle.getString("preferences.general.language.auto"); + return resourceBundle.getString("preferences.interface.language.auto"); } else { var locale = Locale.forLanguageTag(tag); var lang = locale.getDisplayLanguage(locale); diff --git a/src/main/resources/fxml/preferences_interface.fxml b/src/main/resources/fxml/preferences_interface.fxml index 54f5b54c1..49dd94801 100644 --- a/src/main/resources/fxml/preferences_interface.fxml +++ b/src/main/resources/fxml/preferences_interface.fxml @@ -21,25 +21,25 @@ - - - - + - + diff --git a/src/main/resources/i18n/strings.properties b/src/main/resources/i18n/strings.properties index ac84325e3..0ea837435 100644 --- a/src/main/resources/i18n/strings.properties +++ b/src/main/resources/i18n/strings.properties @@ -191,25 +191,25 @@ health.fix.failTip=Fix failed, see log for details preferences.title=Preferences ## General preferences.general=General -preferences.general.theme=Look & Feel -preferences.general.theme.automatic=Automatic -preferences.general.theme.light=Light -preferences.general.theme.dark=Dark -preferences.general.unlockThemes=Unlock dark mode -preferences.general.showMinimizeButton=Show minimize button -preferences.general.showTrayIcon=Show tray icon (requires restart) preferences.general.startHidden=Hide window when starting Cryptomator -preferences.general.language=Language (requires restart) -preferences.general.language.auto=System Default preferences.general.debugLogging=Enable debug logging preferences.general.debugDirectory=Reveal log files preferences.general.autoStart=Launch Cryptomator on system start preferences.general.keychainBackend=Store passwords with -preferences.general.interfaceOrientation=Interface Orientation -preferences.general.interfaceOrientation.ltr=Left to Right -preferences.general.interfaceOrientation.rtl=Right to Left ## Interface preferences.interface=Interface +preferences.interface.theme=Look & Feel +preferences.interface.theme.automatic=Automatic +preferences.interface.theme.dark=Dark +preferences.interface.theme.light=Light +preferences.interface.unlockThemes=Unlock dark mode +preferences.interface.language=Language (requires restart) +preferences.interface.language.auto=System Default +preferences.interface.interfaceOrientation=Interface Orientation +preferences.interface.interfaceOrientation.ltr=Left to Right +preferences.interface.interfaceOrientation.rtl=Right to Left +preferences.interface.showMinimizeButton=Show minimize button +preferences.interface.showTrayIcon=Show tray icon (requires restart) ## Volume preferences.volume=Virtual Drive preferences.volume.type=Volume Type From 9a9ef6c58377db0ca33e09c78dbe54c96f662835 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Mon, 11 Apr 2022 09:23:53 +0200 Subject: [PATCH 11/15] updated license file [ci skip] --- src/main/resources/license/THIRD-PARTY.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/license/THIRD-PARTY.txt b/src/main/resources/license/THIRD-PARTY.txt index db0c76ced..5de1f62ad 100644 --- a/src/main/resources/license/THIRD-PARTY.txt +++ b/src/main/resources/license/THIRD-PARTY.txt @@ -75,7 +75,7 @@ Cryptomator uses 40 third-party dependencies under the following licenses: - java jwt (com.auth0:java-jwt:3.19.1 - https://github.com/auth0/java-jwt) - jnr-x86asm (com.github.jnr:jnr-x86asm:1.0.2 - http://github.com/jnr/jnr-x86asm) - jnr-fuse (com.github.serceman:jnr-fuse:0.5.7 - https://github.com/SerCeMan/jnr-fuse) - - zxcvbn4j (com.nulab-inc:zxcvbn:1.5.2 - https://github.com/nulab/zxcvbn4j) + - zxcvbn4j (com.nulab-inc:zxcvbn:1.6.0 - https://github.com/nulab/zxcvbn4j) - SLF4J API Module (org.slf4j:slf4j-api:1.7.36 - http://www.slf4j.org) The BSD 2-Clause License: - EasyBind (com.tobiasdiez:easybind:2.2 - https://github.com/tobiasdiez/EasyBind) From 69f3a2bd5abcaf00944ac39391a96325af40049c Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Mon, 11 Apr 2022 09:35:35 +0200 Subject: [PATCH 12/15] log errors when showing main window --- src/main/java/org/cryptomator/ui/fxapp/FxApplication.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java b/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java index 55f76d321..1f1927c5d 100644 --- a/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java +++ b/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java @@ -61,6 +61,9 @@ public class FxApplication { stage.setIconified(true); } } + }).exceptionally(error -> { + LOG.error("Failed to show main window", error); + return null; }); launchEventHandler.startHandlingLaunchEvents(); From 9c26d177337a85838de72bb90947102e14b68947 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Mon, 11 Apr 2022 09:36:34 +0200 Subject: [PATCH 13/15] log durations of application start --- src/main/java/org/cryptomator/launcher/Cryptomator.java | 6 ++++-- .../org/cryptomator/launcher/CryptomatorComponent.java | 7 +++++++ src/main/java/org/cryptomator/ui/fxapp/FxApplication.java | 8 +++++++- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/cryptomator/launcher/Cryptomator.java b/src/main/java/org/cryptomator/launcher/Cryptomator.java index 90f391ec6..6499856af 100644 --- a/src/main/java/org/cryptomator/launcher/Cryptomator.java +++ b/src/main/java/org/cryptomator/launcher/Cryptomator.java @@ -27,9 +27,10 @@ import java.util.concurrent.Executors; @Singleton public class Cryptomator { + private static final long STARTUP_TIME = System.currentTimeMillis(); // DaggerCryptomatorComponent gets generated by Dagger. // Run Maven and include target/generated-sources/annotations in your IDE. - private static final CryptomatorComponent CRYPTOMATOR_COMPONENT = DaggerCryptomatorComponent.create(); + private static final CryptomatorComponent CRYPTOMATOR_COMPONENT = DaggerCryptomatorComponent.factory().create(STARTUP_TIME); private static final Logger LOG = LoggerFactory.getLogger(Cryptomator.class); private final LoggerConfiguration logConfig; @@ -63,6 +64,7 @@ public class Cryptomator { */ private int run(String[] args) { logConfig.init(); + LOG.debug("Dagger graph initialized after {}ms", System.currentTimeMillis() - STARTUP_TIME); LOG.info("Starting Cryptomator {} on {} {} ({})", env.getAppVersion().orElse("SNAPSHOT"), SystemUtils.OS_NAME, SystemUtils.OS_VERSION, SystemUtils.OS_ARCH); debugMode.initialize(); supportedLanguages.applyPreferred(); @@ -112,7 +114,7 @@ public class Cryptomator { @Override public void start(Stage primaryStage) { - LOG.info("JavaFX application started."); + LOG.info("JavaFX runtime started after {}ms", System.currentTimeMillis() - STARTUP_TIME); FxApplicationComponent component = CRYPTOMATOR_COMPONENT.fxAppComponentBuilder() // .fxApplication(this) // .primaryStage(primaryStage) // diff --git a/src/main/java/org/cryptomator/launcher/CryptomatorComponent.java b/src/main/java/org/cryptomator/launcher/CryptomatorComponent.java index b43c0eca0..8c6443717 100644 --- a/src/main/java/org/cryptomator/launcher/CryptomatorComponent.java +++ b/src/main/java/org/cryptomator/launcher/CryptomatorComponent.java @@ -1,10 +1,12 @@ package org.cryptomator.launcher; +import dagger.BindsInstance; import dagger.Component; import org.cryptomator.common.CommonsModule; import org.cryptomator.logging.LoggerModule; import org.cryptomator.ui.fxapp.FxApplicationComponent; +import javax.inject.Named; import javax.inject.Singleton; @Singleton @@ -15,4 +17,9 @@ public interface CryptomatorComponent { FxApplicationComponent.Builder fxAppComponentBuilder(); + @Component.Factory + interface Factory { + CryptomatorComponent create(@BindsInstance @Named("startupTime") long startupTime); + } + } diff --git a/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java b/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java index 1f1927c5d..fd9326c3d 100644 --- a/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java +++ b/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java @@ -7,16 +7,20 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.inject.Inject; +import javax.inject.Named; import javafx.application.Platform; import javafx.stage.Stage; import javafx.stage.StageStyle; import java.awt.SystemTray; +import java.io.IOException; +import java.io.UncheckedIOException; @FxApplicationScoped public class FxApplication { private static final Logger LOG = LoggerFactory.getLogger(FxApplication.class); + private final long startupTime; private final Settings settings; private final AppLaunchEventHandler launchEventHandler; private final Lazy trayMenu; @@ -26,7 +30,8 @@ public class FxApplication { private final AutoUnlocker autoUnlocker; @Inject - FxApplication(Settings settings, AppLaunchEventHandler launchEventHandler, Lazy trayMenu, FxApplicationWindows appWindows, FxApplicationStyle applicationStyle, FxApplicationTerminator applicationTerminator, AutoUnlocker autoUnlocker) { + FxApplication(@Named("startupTime") long startupTime, Settings settings, AppLaunchEventHandler launchEventHandler, Lazy trayMenu, FxApplicationWindows appWindows, FxApplicationStyle applicationStyle, FxApplicationTerminator applicationTerminator, AutoUnlocker autoUnlocker) { + this.startupTime = startupTime; this.settings = settings; this.launchEventHandler = launchEventHandler; this.trayMenu = trayMenu; @@ -61,6 +66,7 @@ public class FxApplication { stage.setIconified(true); } } + LOG.debug("Main window initialized after {}ms", System.currentTimeMillis() - startupTime); }).exceptionally(error -> { LOG.error("Failed to show main window", error); return null; From 79e1285b387e4741fe2552471468f74bcbbb9395 Mon Sep 17 00:00:00 2001 From: Tobias Hagemann Date: Mon, 11 Apr 2022 10:48:47 +0200 Subject: [PATCH 14/15] increased margins and spacings even further --- src/main/resources/fxml/preferences_about.fxml | 4 ++-- src/main/resources/fxml/preferences_contribute.fxml | 4 ++-- src/main/resources/fxml/preferences_general.fxml | 8 ++++---- src/main/resources/fxml/preferences_interface.fxml | 10 +++++----- src/main/resources/fxml/preferences_updates.fxml | 6 +++--- src/main/resources/fxml/preferences_volume.fxml | 10 +++++----- 6 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/main/resources/fxml/preferences_about.fxml b/src/main/resources/fxml/preferences_about.fxml index 0601dd410..ce2a31e4e 100644 --- a/src/main/resources/fxml/preferences_about.fxml +++ b/src/main/resources/fxml/preferences_about.fxml @@ -11,9 +11,9 @@ + spacing="24"> - + diff --git a/src/main/resources/fxml/preferences_contribute.fxml b/src/main/resources/fxml/preferences_contribute.fxml index b9196123d..55d40b495 100644 --- a/src/main/resources/fxml/preferences_contribute.fxml +++ b/src/main/resources/fxml/preferences_contribute.fxml @@ -13,9 +13,9 @@ + spacing="24"> - + diff --git a/src/main/resources/fxml/preferences_general.fxml b/src/main/resources/fxml/preferences_general.fxml index fcf7b32ff..6d2b68447 100644 --- a/src/main/resources/fxml/preferences_general.fxml +++ b/src/main/resources/fxml/preferences_general.fxml @@ -12,26 +12,26 @@ + spacing="12"> - + - + - + diff --git a/src/main/resources/fxml/preferences_interface.fxml b/src/main/resources/fxml/preferences_interface.fxml index 49dd94801..6cb9b7d73 100644 --- a/src/main/resources/fxml/preferences_interface.fxml +++ b/src/main/resources/fxml/preferences_interface.fxml @@ -12,26 +12,26 @@ + spacing="12"> - + - + - + - +