This commit is contained in:
crschnick
2024-04-06 12:36:25 +00:00
parent 9d2ba14caf
commit 0064569fb2
20 changed files with 169 additions and 107 deletions

View File

@@ -92,11 +92,6 @@ public interface BrowserAction {
.toList());
}
@Override
public boolean requiresFullDaemon() {
return true;
}
@Override
public boolean prioritizeLoading() {
return false;

View File

@@ -95,7 +95,7 @@ public abstract class StoreEntryComp extends SimpleComp {
wrapper.executeDefaultAction();
});
});
new ContextMenuAugment<>(mouseEvent -> mouseEvent.isSecondaryButtonDown(), null, () -> this.createContextMenu()).augment(new SimpleCompStructure<>(button));
new ContextMenuAugment<>(mouseEvent -> mouseEvent.getButton() == MouseButton.SECONDARY, null, () -> this.createContextMenu()).augment(button);
var loading = LoadingOverlayComp.noProgress(
Comp.of(() -> button),

View File

@@ -1,11 +1,16 @@
package io.xpipe.app.core;
import com.fasterxml.jackson.databind.jsontype.NamedType;
import io.xpipe.app.exchange.MessageExchangeImpls;
import io.xpipe.app.ext.DataStoreProvider;
import io.xpipe.app.ext.DataStoreProviders;
import io.xpipe.app.ext.ExtensionException;
import io.xpipe.app.ext.XPipeServiceProviders;
import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.app.issue.TrackEvent;
import io.xpipe.core.process.ProcessControlProvider;
import io.xpipe.core.util.JacksonMapper;
import io.xpipe.core.util.ModuleHelper;
import io.xpipe.core.util.ModuleLayerLoader;
import io.xpipe.core.util.XPipeInstallation;
import lombok.Getter;
import lombok.Value;
@@ -47,9 +52,24 @@ public class AppExtensionManager {
}
if (load) {
// INSTANCE.addNativeLibrariesToPath();
try {
XPipeServiceProviders.load(INSTANCE.extendedLayer);
ModuleLayerLoader.loadAll(INSTANCE.extendedLayer, true, t -> {
ErrorEvent.fromThrowable(t).handle();
});
ProcessControlProvider.init(INSTANCE.extendedLayer);
TrackEvent.info("Loading extension providers ...");
DataStoreProviders.init(INSTANCE.extendedLayer);
for (DataStoreProvider p : DataStoreProviders.getAll()) {
TrackEvent.trace("Loaded data store provider " + p.getId());
JacksonMapper.configure(objectMapper -> {
for (Class<?> storeClass : p.getStoreClasses()) {
objectMapper.registerSubtypes(new NamedType(storeClass));
}
});
}
ModuleLayerLoader.loadAll(INSTANCE.extendedLayer, false, t -> {
ErrorEvent.fromThrowable(t).handle();
});
MessageExchangeImpls.loadAll();
} catch (Throwable t) {
throw new ExtensionException(

View File

@@ -144,11 +144,6 @@ public interface ActionProvider {
.toList());
}
@Override
public boolean requiresFullDaemon() {
return true;
}
@Override
public boolean prioritizeLoading() {
return false;

View File

@@ -30,20 +30,15 @@ public interface PrefsChoiceValue extends Translatable {
}
}
@SuppressWarnings("unchecked")
static <T> List<T> getSupported(Class<T> type) {
try {
return (List<T>) type.getDeclaredField("SUPPORTED").get(null);
} catch (IllegalAccessException | NoSuchFieldException e) {
var all = getAll(type);
if (all == null) {
throw new AssertionError();
}
return all.stream()
.filter(t -> ((PrefsChoiceValue) t).isSelectable())
.toList();
var all = getAll(type);
if (all == null) {
throw new AssertionError();
}
return all.stream()
.filter(t -> ((PrefsChoiceValue) t).isSelectable())
.toList();
}
default boolean isAvailable() {

View File

@@ -35,11 +35,6 @@ public abstract class PrefsProvider {
.collect(Collectors.toList());
}
@Override
public boolean requiresFullDaemon() {
return true;
}
@Override
public boolean prioritizeLoading() {
return false;

View File

@@ -63,11 +63,6 @@ public abstract class ScanProvider {
.collect(Collectors.toList());
}
@Override
public boolean requiresFullDaemon() {
return true;
}
@Override
public boolean prioritizeLoading() {
return false;

View File

@@ -1,36 +0,0 @@
package io.xpipe.app.ext;
import com.fasterxml.jackson.databind.jsontype.NamedType;
import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.app.issue.TrackEvent;
import io.xpipe.core.process.ProcessControlProvider;
import io.xpipe.core.util.JacksonMapper;
import io.xpipe.core.util.ModuleLayerLoader;
public class XPipeServiceProviders {
public static void load(ModuleLayer layer) {
var hasDaemon = true;
ModuleLayerLoader.loadAll(layer, hasDaemon, true, t -> {
ErrorEvent.fromThrowable(t).handle();
});
ProcessControlProvider.init(layer);
TrackEvent.info("Loading extension providers ...");
DataStoreProviders.init(layer);
for (DataStoreProvider p : DataStoreProviders.getAll()) {
TrackEvent.trace("Loaded data store provider " + p.getId());
JacksonMapper.configure(objectMapper -> {
for (Class<?> storeClass : p.getStoreClasses()) {
objectMapper.registerSubtypes(new NamedType(storeClass));
}
});
}
ModuleLayerLoader.loadAll(layer, hasDaemon, false, t -> {
ErrorEvent.fromThrowable(t).handle();
});
TrackEvent.info("Finished loading extension providers");
}
}

View File

@@ -0,0 +1,40 @@
package io.xpipe.app.fxcomps.impl;
import io.xpipe.app.fxcomps.SimpleComp;
import io.xpipe.app.storage.DataStoreEntryRef;
import io.xpipe.app.util.StringSource;
import io.xpipe.core.store.ShellStore;
import javafx.beans.property.Property;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ObservableValue;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.layout.Region;
public class StringSourceComp extends SimpleComp {
private final Property<DataStoreEntryRef<? extends ShellStore>> fileSystem;
private final Property<StringSource> stringSource;
public <T extends ShellStore> StringSourceComp(ObservableValue<DataStoreEntryRef<T>> fileSystem, Property<StringSource> stringSource) {
this.stringSource = stringSource;
this.fileSystem = new SimpleObjectProperty<>();
fileSystem.subscribe(val -> {
this.fileSystem.setValue(val);
});
}
@Override
protected Region createSimple() {
var tab = new TabPane();
var inPlace = new SimpleObjectProperty<>(stringSource.getValue() instanceof StringSource.InPlace i ? i.get() : null);
var stringField = new TextAreaComp(inPlace);
tab.getTabs().add(new Tab());
var fs = stringSource.getValue() instanceof StringSource.File f ? f.getFile() : null;
var file = new SimpleObjectProperty<>(stringSource.getValue() instanceof StringSource.File f ? f.getFile() : null);
// new ContextualFileReferenceChoiceComp(fileSystem, file);
return null;
}
}

View File

@@ -30,6 +30,9 @@ public class TextFieldComp extends Comp<CompStructure<TextField>> {
value.setValue(val);
});
}
lastAppliedValue.addListener((c, o, n) -> {
currentValue.setValue(n);
});
}
@Override
@@ -39,7 +42,6 @@ public class TextFieldComp extends Comp<CompStructure<TextField>> {
currentValue.setValue(n != null && n.length() > 0 ? n : null);
});
lastAppliedValue.addListener((c, o, n) -> {
currentValue.setValue(n);
PlatformThread.runLaterIfNeeded(() -> {
// Check if control value is the same. Then don't set it as that might cause bugs
if (Objects.equals(text.getText(), n)

View File

@@ -144,6 +144,7 @@ public class AppPrefs {
new RdpCategory(),
new SyncCategory(),
new VaultCategory(),
new SshCategory(),
new LocalShellCategory(),
new SecurityCategory(),
new PasswordManagerCategory(),

View File

@@ -2,8 +2,6 @@ package io.xpipe.app.prefs;
import io.xpipe.app.fxcomps.Comp;
import io.xpipe.app.util.OptionsBuilder;
import io.xpipe.core.process.OsType;
import javafx.beans.property.SimpleBooleanProperty;
public class LocalShellCategory extends AppPrefsCategory {
@@ -18,9 +16,6 @@ public class LocalShellCategory extends AppPrefsCategory {
return new OptionsBuilder()
.addTitle("localShell")
.sub(new OptionsBuilder()
.nameAndDescription("useBundledTools")
.addToggle(prefs.useBundledTools)
.hide(new SimpleBooleanProperty(!OsType.getLocal().equals(OsType.WINDOWS)))
.nameAndDescription("useLocalFallbackShell")
.addToggle(prefs.useLocalFallbackShell))
.buildComp();

View File

@@ -0,0 +1,28 @@
package io.xpipe.app.prefs;
import io.xpipe.app.fxcomps.Comp;
import io.xpipe.app.util.OptionsBuilder;
import io.xpipe.core.process.OsType;
import javafx.beans.property.SimpleBooleanProperty;
public class SshCategory extends AppPrefsCategory {
@Override
protected String getId() {
return "ssh";
}
@Override
protected Comp<?> create() {
var prefs = AppPrefs.get();
return new OptionsBuilder()
.addTitle("sshConfiguration")
.sub(new OptionsBuilder()
.nameAndDescription("useBundledTools")
.addToggle(prefs.useBundledTools)
.hide(new SimpleBooleanProperty(!OsType.getLocal().equals(OsType.WINDOWS)))
.addComp(prefs.getCustomComp("x11WslInstance"))
.hide(new SimpleBooleanProperty(!OsType.getLocal().equals(OsType.WINDOWS))))
.buildComp();
}
}

View File

@@ -42,11 +42,6 @@ public abstract class LicenseProvider {
.orElseThrow(() -> ExtensionException.corrupt("Missing license provider"));
}
@Override
public boolean requiresFullDaemon() {
return true;
}
@Override
public boolean prioritizeLoading() {
return true;

View File

@@ -1,17 +1,14 @@
package io.xpipe.app.util;
import io.xpipe.app.core.check.AppSystemFontCheck;
import io.xpipe.app.fxcomps.util.PlatformThread;
import io.xpipe.app.issue.TrackEvent;
import io.xpipe.app.prefs.AppPrefs;
import io.xpipe.core.process.OsType;
import javafx.application.Platform;
import javafx.scene.input.Clipboard;
import lombok.Getter;
import lombok.Setter;
import java.awt.*;
import java.awt.datatransfer.StringSelection;
import java.util.Optional;
import java.util.concurrent.CountDownLatch;
@@ -28,15 +25,16 @@ public enum PlatformState {
private static Exception lastError;
public static void teardown() {
PlatformThread.runLaterIfNeededBlocking(() -> {
try {
// Fix to preserve clipboard contents after shutdown
var string = Clipboard.getSystemClipboard().getString();
var s = new StringSelection(string);
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(s, s);
} catch (IllegalStateException ignored) {
}
});
// This is bad and can get sometimes stuck
// PlatformThread.runLaterIfNeededBlocking(() -> {
// try {
// // Fix to preserve clipboard contents after shutdown
// var string = Clipboard.getSystemClipboard().getString();
// var s = new StringSelection(string);
// Toolkit.getDefaultToolkit().getSystemClipboard().setContents(s, s);
// } catch (IllegalStateException ignored) {
// }
// });
Platform.exit();
setCurrent(PlatformState.EXITED);

View File

@@ -0,0 +1,51 @@
package io.xpipe.app.util;
import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.app.storage.ContextualFileReference;
import io.xpipe.core.store.ShellStore;
import lombok.EqualsAndHashCode;
import lombok.Value;
public abstract class StringSource {
public abstract String get() throws Exception;
@Value
@EqualsAndHashCode(callSuper = true)
public static class InPlace extends StringSource {
String value;
@Override
public String get() {
return value;
}
}
@Value
@EqualsAndHashCode(callSuper = true)
public static class File extends StringSource {
ShellStore host;
ContextualFileReference file;
@Override
public String get() throws Exception {
if (host == null || file == null) {
return "";
}
try (var sc = host.control().start()) {
var path = file.toAbsoluteFilePath(sc);
if (!sc.getShellDialect().createFileExistsCommand(sc, path).executeAndCheck()) {
throw ErrorEvent.expected(
new IllegalArgumentException("File " + path + " does not exist"));
}
var abs = file.toAbsoluteFilePath(sc);
var content = sc.getShellDialect().getFileReadCommand(sc, abs).readStdoutOrThrow();
return content;
}
}
}
}

View File

@@ -79,11 +79,6 @@ public class ShellDialects {
OVH_BASTION = byId("ovhBastion");
}
@Override
public boolean requiresFullDaemon() {
return false;
}
@Override
public boolean prioritizeLoading() {
return true;

View File

@@ -6,14 +6,10 @@ import java.util.function.Consumer;
public interface ModuleLayerLoader {
static void loadAll(
ModuleLayer layer, boolean hasDaemon, boolean prioritization, Consumer<Throwable> errorHandler) {
ModuleLayer layer, boolean prioritization, Consumer<Throwable> errorHandler) {
ServiceLoader.load(layer, ModuleLayerLoader.class).stream().forEach(moduleLayerLoaderProvider -> {
var instance = moduleLayerLoaderProvider.get();
try {
if (instance.requiresFullDaemon() && !hasDaemon) {
return;
}
if (instance.prioritizeLoading() != prioritization) {
return;
}
@@ -27,7 +23,5 @@ public interface ModuleLayerLoader {
void init(ModuleLayer layer);
boolean requiresFullDaemon();
boolean prioritizeLoading();
}

View File

@@ -428,3 +428,5 @@ goodMorning=Good morning
goodAfternoon=Good afternoon
goodNight=Good night
addVisual=Visual ...
ssh=SSH
sshConfiguration=SSH Configuration

View File

@@ -287,3 +287,5 @@ vncUsername=Username
vncUsernameDescription=The optional VNC username
vncPassword=Password
vncPasswordDescription=The VNC password
x11WslInstance=X11 Forward WSL instance
x11WslInstanceDescription=The local Windows Subsystem for Linux distribution to use as an X11 server when using X11 forwarding in an SSH connection. This distribution must be a WSL2 distribution.\n\nRequires a restart to apply.