App lifecycle fixes

This commit is contained in:
Sebastian Stenzel
2020-02-13 16:29:49 +01:00
parent 62676d5a83
commit e1f44fb48a
6 changed files with 55 additions and 48 deletions
@@ -1,16 +1,17 @@
package org.cryptomator.ui.launcher;
import java.nio.file.Path;
import java.util.Collection;
import java.util.stream.Stream;
public class AppLaunchEvent {
private final Stream<Path> pathsToOpen;
private final EventType type;
private final Collection<Path> pathsToOpen;
public enum EventType {REVEAL_APP, OPEN_FILE}
public AppLaunchEvent(EventType type, Stream<Path> pathsToOpen) {
public AppLaunchEvent(EventType type, Collection<Path> pathsToOpen) {
this.type = type;
this.pathsToOpen = pathsToOpen;
}
@@ -19,7 +20,7 @@ public class AppLaunchEvent {
return type;
}
public Stream<Path> getPathsToOpen() {
public Collection<Path> getPathsToOpen() {
return pathsToOpen;
}
}
@@ -15,6 +15,7 @@ import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import java.awt.Desktop;
import java.awt.EventQueue;
import java.awt.desktop.QuitResponse;
import java.util.EnumSet;
import java.util.EventObject;
@@ -31,14 +32,14 @@ public class AppLifecycleListener {
private final FxApplicationStarter fxApplicationStarter;
private final CountDownLatch shutdownLatch;
private final ObservableList<Vault> vaults;
private final AtomicBoolean allowSuddenTermination;
private final AtomicBoolean allowQuitWithoutPrompt;
@Inject
AppLifecycleListener(FxApplicationStarter fxApplicationStarter, @Named("shutdownLatch") CountDownLatch shutdownLatch, ShutdownHook shutdownHook, ObservableList<Vault> vaults) {
this.fxApplicationStarter = fxApplicationStarter;
this.shutdownLatch = shutdownLatch;
this.vaults = vaults;
this.allowSuddenTermination = new AtomicBoolean(true);
this.allowQuitWithoutPrompt = new AtomicBoolean(true);
vaults.addListener(this::vaultListChanged);
// register preferences shortcut
@@ -51,11 +52,6 @@ public class AppLifecycleListener {
Desktop.getDesktop().setQuitHandler(this::handleQuitRequest);
}
// allow sudden termination
if (Desktop.getDesktop().isSupported(Desktop.Action.APP_SUDDEN_TERMINATION)) {
Desktop.getDesktop().enableSuddenTermination();
}
shutdownHook.runOnShutdown(this::forceUnmountRemainingVaults);
}
@@ -66,7 +62,7 @@ public class AppLifecycleListener {
handleQuitRequest(null, new QuitResponse() {
@Override
public void performQuit() {
shutdownLatch.countDown();
System.exit(0);
}
@Override
@@ -76,18 +72,37 @@ public class AppLifecycleListener {
});
}
private void handleQuitRequest(@SuppressWarnings("unused") EventObject e, QuitResponse response) {
QuitResponse decoratedQuitResponse = decorateQuitResponse(response);
if (allowQuitWithoutPrompt.get()) {
decoratedQuitResponse.performQuit();
} else {
fxApplicationStarter.get(true).thenAccept(app -> app.showQuitWindow(decoratedQuitResponse));
}
}
private QuitResponse decorateQuitResponse(QuitResponse originalQuitResponse) {
return new QuitResponse() {
@Override
public void performQuit() {
Platform.exit(); // will be no-op, if JavaFX never started.
shutdownLatch.countDown(); // main thread is waiting for this latch
EventQueue.invokeLater(originalQuitResponse::performQuit); // this will eventually call System.exit(0)
}
@Override
public void cancelQuit() {
originalQuitResponse.cancelQuit();
}
};
}
private void vaultListChanged(@SuppressWarnings("unused") Observable observable) {
assert Platform.isFxApplicationThread();
boolean allVaultsAllowTermination = vaults.stream().map(Vault::getState).allMatch(STATES_ALLOWING_TERMINATION::contains);
boolean suddenTerminationChanged = allowSuddenTermination.compareAndSet(!allVaultsAllowTermination, allVaultsAllowTermination);
if (suddenTerminationChanged && Desktop.getDesktop().isSupported(Desktop.Action.APP_SUDDEN_TERMINATION)) {
if (allVaultsAllowTermination) {
Desktop.getDesktop().enableSuddenTermination();
LOG.debug("sudden termination enabled");
} else {
Desktop.getDesktop().disableSuddenTermination();
LOG.debug("sudden termination disabled");
}
boolean suddenTerminationChanged = allowQuitWithoutPrompt.compareAndSet(!allVaultsAllowTermination, allVaultsAllowTermination);
if (suddenTerminationChanged) {
LOG.debug("Allow quitting without prompt: {}", allVaultsAllowTermination);
}
}
@@ -95,14 +110,6 @@ public class AppLifecycleListener {
fxApplicationStarter.get(true).thenAccept(app -> app.showPreferencesWindow(SelectedPreferencesTab.ANY));
}
private void handleQuitRequest(@SuppressWarnings("unused") EventObject e, QuitResponse response) {
if (allowSuddenTermination.get()) {
response.performQuit(); // really?
} else {
fxApplicationStarter.get(true).thenAccept(app -> app.showQuitWindow(response));
}
}
private void forceUnmountRemainingVaults() {
for (Vault vault : vaults) {
if (vault.isUnlocked()) {