From ba83a9c23a50316c0f56c83bd6a1a4b928e3d704 Mon Sep 17 00:00:00 2001 From: crschnick Date: Wed, 17 Apr 2024 08:07:40 +0000 Subject: [PATCH] More desktop rework --- .../java/io/xpipe/app/core/mode/BaseMode.java | 3 + .../io/xpipe/app/core/mode/OperationMode.java | 8 +- .../io/xpipe/app/ext/DataStoreProvider.java | 10 +- .../io/xpipe/app/ext/DataStoreProviders.java | 22 ++- .../app/prefs/ExternalRdpClientType.java | 2 +- .../io/xpipe/app/storage/DataStorage.java | 8 -- .../io/xpipe/app/util/OptionsBuilder.java | 2 +- .../DesktopApplicationStoreProvider.java | 24 ++-- .../ext/base/desktop/DesktopBaseStore.java | 8 +- .../ext/base/desktop/DesktopCommandStore.java | 28 ++++ .../desktop/DesktopCommandStoreProvider.java | 129 ++++++++++++++++++ .../base/desktop/DesktopEnvironmentStore.java | 54 +++++--- .../DesktopEnvironmentStoreProvider.java | 35 ++++- .../script/SimpleScriptStoreProvider.java | 6 +- ext/base/src/main/java/module-info.java | 3 +- lang/base/strings/translations_en.properties | 8 +- lang/proc/strings/translations_en.properties | 5 +- lang/proc/texts/rdpTunnelHost_en.md | 4 +- 18 files changed, 286 insertions(+), 73 deletions(-) create mode 100644 ext/base/src/main/java/io/xpipe/ext/base/desktop/DesktopCommandStore.java create mode 100644 ext/base/src/main/java/io/xpipe/ext/base/desktop/DesktopCommandStoreProvider.java diff --git a/app/src/main/java/io/xpipe/app/core/mode/BaseMode.java b/app/src/main/java/io/xpipe/app/core/mode/BaseMode.java index 397219c0d..d3b8582d7 100644 --- a/app/src/main/java/io/xpipe/app/core/mode/BaseMode.java +++ b/app/src/main/java/io/xpipe/app/core/mode/BaseMode.java @@ -7,6 +7,7 @@ import io.xpipe.app.core.check.AppAvCheck; import io.xpipe.app.core.check.AppCertutilCheck; import io.xpipe.app.core.check.AppShellCheck; import io.xpipe.app.ext.ActionProvider; +import io.xpipe.app.ext.DataStoreProviders; import io.xpipe.app.issue.TrackEvent; import io.xpipe.app.prefs.AppPrefs; import io.xpipe.app.storage.DataStorage; @@ -62,6 +63,7 @@ public class BaseMode extends OperationMode { AppPrefs.initSharedRemote(); UnlockAlert.showIfNeeded(); DataStorage.init(); + DataStoreProviders.init(); AppFileWatcher.init(); FileBridge.init(); ActionProvider.initProviders(); @@ -77,6 +79,7 @@ public class BaseMode extends OperationMode { TrackEvent.info("Background mode shutdown started"); BrowserSessionModel.DEFAULT.reset(); StoreViewState.reset(); + DataStoreProviders.reset(); DataStorage.reset(); AppPrefs.reset(); AppResources.reset(); diff --git a/app/src/main/java/io/xpipe/app/core/mode/OperationMode.java b/app/src/main/java/io/xpipe/app/core/mode/OperationMode.java index 1c00845cc..80a60fbf8 100644 --- a/app/src/main/java/io/xpipe/app/core/mode/OperationMode.java +++ b/app/src/main/java/io/xpipe/app/core/mode/OperationMode.java @@ -1,11 +1,13 @@ package io.xpipe.app.core.mode; import io.xpipe.app.Main; -import io.xpipe.app.core.*; +import io.xpipe.app.core.App; +import io.xpipe.app.core.AppLogs; +import io.xpipe.app.core.AppProperties; +import io.xpipe.app.core.AppState; import io.xpipe.app.core.check.AppDebugModeCheck; import io.xpipe.app.core.check.AppTempCheck; import io.xpipe.app.core.check.AppUserDirectoryCheck; -import io.xpipe.app.ext.DataStoreProviders; import io.xpipe.app.issue.*; import io.xpipe.app.launcher.LauncherCommand; import io.xpipe.app.launcher.LauncherInput; @@ -166,8 +168,6 @@ public abstract class OperationMode { } } } - - DataStoreProviders.postInit(AppExtensionManager.getInstance().getExtendedLayer()); } catch (Throwable ex) { ErrorEvent.fromThrowable(ex).term().handle(); } diff --git a/app/src/main/java/io/xpipe/app/ext/DataStoreProvider.java b/app/src/main/java/io/xpipe/app/ext/DataStoreProvider.java index 65745fd8d..f784309d7 100644 --- a/app/src/main/java/io/xpipe/app/ext/DataStoreProvider.java +++ b/app/src/main/java/io/xpipe/app/ext/DataStoreProvider.java @@ -52,6 +52,10 @@ public interface DataStoreProvider { } } + default ActionProvider.Action activateAction(DataStoreEntry store) { + return null; + } + default ActionProvider.Action launchAction(DataStoreEntry store) { return null; } @@ -139,13 +143,13 @@ public interface DataStoreProvider { return null; } - default boolean init() { + default boolean preInit() { return true; } - default void postInit() {} + default void init() {} - default void storageInit() {} + default void reset() {} default boolean isShareableFromLocalMachine() { return false; diff --git a/app/src/main/java/io/xpipe/app/ext/DataStoreProviders.java b/app/src/main/java/io/xpipe/app/ext/DataStoreProviders.java index 7b62155f1..0990e19bc 100644 --- a/app/src/main/java/io/xpipe/app/ext/DataStoreProviders.java +++ b/app/src/main/java/io/xpipe/app/ext/DataStoreProviders.java @@ -16,12 +16,22 @@ public class DataStoreProviders { private static List ALL; - public static void postInit(ModuleLayer layer) { - ALL.forEach(p -> { + public static void init() { + DataStoreProviders.getAll().forEach(dataStoreProvider -> { try { - p.postInit(); - } catch (Throwable e) { - ErrorEvent.fromThrowable(e).handle(); + dataStoreProvider.init(); + } catch (Exception e) { + ErrorEvent.fromThrowable(e).omit().handle(); + } + }); + } + + public static void reset() { + DataStoreProviders.getAll().forEach(dataStoreProvider -> { + try { + dataStoreProvider.reset(); + } catch (Exception e) { + ErrorEvent.fromThrowable(e).omit().handle(); } }); } @@ -80,7 +90,7 @@ public class DataStoreProviders { .collect(Collectors.toList()); ALL.removeIf(p -> { try { - if (!p.init()) { + if (!p.preInit()) { return true; } diff --git a/app/src/main/java/io/xpipe/app/prefs/ExternalRdpClientType.java b/app/src/main/java/io/xpipe/app/prefs/ExternalRdpClientType.java index 6969fe99d..bfc8f0479 100644 --- a/app/src/main/java/io/xpipe/app/prefs/ExternalRdpClientType.java +++ b/app/src/main/java/io/xpipe/app/prefs/ExternalRdpClientType.java @@ -14,7 +14,7 @@ import java.util.function.Supplier; public interface ExternalRdpClientType extends PrefsChoiceValue { - ExternalRdpClientType MSTSC = new PathCheckType("app.mstsc", "mstsc.exe", true) { + ExternalRdpClientType MSTSC = new PathCheckType("app.mstsc", "mstsc.exe", false) { @Override public void launch(LaunchConfiguration configuration) throws Exception { diff --git a/app/src/main/java/io/xpipe/app/storage/DataStorage.java b/app/src/main/java/io/xpipe/app/storage/DataStorage.java index 7c0b3e07f..1c2c8f7c1 100644 --- a/app/src/main/java/io/xpipe/app/storage/DataStorage.java +++ b/app/src/main/java/io/xpipe/app/storage/DataStorage.java @@ -86,14 +86,6 @@ public abstract class DataStorage { INSTANCE = shouldPersist() ? new StandardStorage() : new ImpersistentStorage(); INSTANCE.load(); - - DataStoreProviders.getAll().forEach(dataStoreProvider -> { - try { - dataStoreProvider.storageInit(); - } catch (Exception e) { - ErrorEvent.fromThrowable(e).omit().handle(); - } - }); } public static void reset() { diff --git a/app/src/main/java/io/xpipe/app/util/OptionsBuilder.java b/app/src/main/java/io/xpipe/app/util/OptionsBuilder.java index 0c713373c..5aea3330e 100644 --- a/app/src/main/java/io/xpipe/app/util/OptionsBuilder.java +++ b/app/src/main/java/io/xpipe/app/util/OptionsBuilder.java @@ -204,7 +204,7 @@ public class OptionsBuilder { this.lastCompHeadReference = comp; } - public OptionsBuilder stringArea(Property prop, boolean lazy) { + public OptionsBuilder addStringArea(Property prop, boolean lazy) { var comp = new TextAreaComp(prop, lazy); pushComp(comp); props.add(prop); diff --git a/ext/base/src/main/java/io/xpipe/ext/base/desktop/DesktopApplicationStoreProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/desktop/DesktopApplicationStoreProvider.java index b9f2b4343..b46dbc14d 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/desktop/DesktopApplicationStoreProvider.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/desktop/DesktopApplicationStoreProvider.java @@ -23,23 +23,11 @@ public class DesktopApplicationStoreProvider implements DataStoreProvider { @Override public ActionProvider.Action browserAction(BrowserSessionModel sessionModel, DataStoreEntry store, BooleanProperty busy) { - DesktopApplicationStore s = store.getStore().asNeeded(); - return new ActionProvider.Action() { - @Override - public boolean requiresJavaFXPlatform() { - return false; - } - - @Override - public void execute() throws Exception { - s.getDesktop().getStore().runDesktopScript(store.getName(), s.getDesktop().getStore().getUsedDialect(), s.getFullCommand()); - } - }; + return launchAction(store); } @Override public ActionProvider.Action launchAction(DataStoreEntry store) { - DesktopApplicationStore s = store.getStore().asNeeded(); return new ActionProvider.Action() { @Override public boolean requiresJavaFXPlatform() { @@ -48,7 +36,13 @@ public class DesktopApplicationStoreProvider implements DataStoreProvider { @Override public void execute() throws Exception { - s.getDesktop().getStore().runDesktopScript(store.getName(), s.getDesktop().getStore().getUsedDialect(), s.getFullCommand()); + DesktopApplicationStore s = store.getStore().asNeeded(); + var baseEntry = s.getDesktop().get(); + var baseActivate = baseEntry.getProvider().activateAction(baseEntry); + if (baseActivate != null) { + baseActivate.execute(); + } + s.getDesktop().getStore().runDesktopApplication(store.getName(), s); } }; } @@ -71,7 +65,7 @@ public class DesktopApplicationStoreProvider implements DataStoreProvider { var path = new SimpleStringProperty(st.getPath() != null ? st.getPath().toAbsoluteFilePath(null) : null); var args = new SimpleStringProperty(st.getArguments() != null ? st.getArguments() : null); return new OptionsBuilder() - .nameAndDescription("desktopEnvironmentBase") + .nameAndDescription("desktopBase") .addComp( new DataStoreChoiceComp<>( DataStoreChoiceComp.Mode.HOST, diff --git a/ext/base/src/main/java/io/xpipe/ext/base/desktop/DesktopBaseStore.java b/ext/base/src/main/java/io/xpipe/ext/base/desktop/DesktopBaseStore.java index 990007284..76cd22780 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/desktop/DesktopBaseStore.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/desktop/DesktopBaseStore.java @@ -1,17 +1,19 @@ package io.xpipe.ext.base.desktop; -import io.xpipe.app.terminal.ExternalTerminalType; import io.xpipe.core.process.OsType; import io.xpipe.core.process.ShellDialect; import io.xpipe.core.store.DataStore; +import io.xpipe.core.store.FilePath; public interface DesktopBaseStore extends DataStore { boolean supportsDesktopAccess(); - void runDesktopScript(String name, ShellDialect dialect, String script) throws Exception; + void runDesktopApplication(String name, DesktopApplicationStore applicationStore) throws Exception; - void runDesktopTerminal(String name, ExternalTerminalType terminalType, ShellDialect dialect, String script) throws Exception; + void runDesktopScript(String name, String script) throws Exception; + + FilePath createScript(ShellDialect dialect, String content) throws Exception; ShellDialect getUsedDialect(); diff --git a/ext/base/src/main/java/io/xpipe/ext/base/desktop/DesktopCommandStore.java b/ext/base/src/main/java/io/xpipe/ext/base/desktop/DesktopCommandStore.java new file mode 100644 index 000000000..db2c28986 --- /dev/null +++ b/ext/base/src/main/java/io/xpipe/ext/base/desktop/DesktopCommandStore.java @@ -0,0 +1,28 @@ +package io.xpipe.ext.base.desktop; + +import com.fasterxml.jackson.annotation.JsonTypeName; +import io.xpipe.app.storage.DataStoreEntryRef; +import io.xpipe.app.util.Validators; +import io.xpipe.core.store.DataStore; +import io.xpipe.core.util.JacksonizedValue; +import io.xpipe.ext.base.SelfReferentialStore; +import lombok.Getter; +import lombok.experimental.SuperBuilder; +import lombok.extern.jackson.Jacksonized; + +@Getter +@SuperBuilder +@Jacksonized +@JsonTypeName("desktopCommand") +public class DesktopCommandStore extends JacksonizedValue implements DataStore, SelfReferentialStore { + + private final DataStoreEntryRef environment; + private final String script; + + @Override + public void checkComplete() throws Throwable { + Validators.nonNull(environment); + Validators.isType(environment, DesktopEnvironmentStore.class); + Validators.nonNull(script); + } +} diff --git a/ext/base/src/main/java/io/xpipe/ext/base/desktop/DesktopCommandStoreProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/desktop/DesktopCommandStoreProvider.java new file mode 100644 index 000000000..be50f0833 --- /dev/null +++ b/ext/base/src/main/java/io/xpipe/ext/base/desktop/DesktopCommandStoreProvider.java @@ -0,0 +1,129 @@ +package io.xpipe.ext.base.desktop; + +import io.xpipe.app.browser.session.BrowserSessionModel; +import io.xpipe.app.comp.base.IntegratedTextAreaComp; +import io.xpipe.app.comp.store.StoreEntryWrapper; +import io.xpipe.app.comp.store.StoreViewState; +import io.xpipe.app.ext.ActionProvider; +import io.xpipe.app.ext.DataStoreProvider; +import io.xpipe.app.ext.GuiDialog; +import io.xpipe.app.fxcomps.impl.DataStoreChoiceComp; +import io.xpipe.app.storage.DataStoreEntry; +import io.xpipe.app.util.DataStoreFormatter; +import io.xpipe.app.util.OptionsBuilder; +import io.xpipe.core.store.DataStore; +import javafx.beans.binding.Bindings; +import javafx.beans.property.BooleanProperty; +import javafx.beans.property.Property; +import javafx.beans.property.SimpleObjectProperty; +import javafx.beans.property.SimpleStringProperty; + +import java.util.List; + +public class DesktopCommandStoreProvider implements DataStoreProvider { + + @Override + public ActionProvider.Action browserAction(BrowserSessionModel sessionModel, DataStoreEntry store, BooleanProperty busy) { + return launchAction(store); + } + + @Override + public ActionProvider.Action launchAction(DataStoreEntry store) { + return new ActionProvider.Action() { + @Override + public boolean requiresJavaFXPlatform() { + return false; + } + + @Override + public void execute() throws Exception { + DesktopCommandStore s = store.getStore().asNeeded(); + var baseEntry = s.getEnvironment().getStore().getBase().get(); + var baseActivate = baseEntry.getProvider().activateAction(baseEntry); + if (baseActivate != null) { + baseActivate.execute(); + } + s.getEnvironment().getStore().runDesktopTerminal(store.getName(),s.getScript()); + } + }; + } + + @Override + public CreationCategory getCreationCategory() { + return CreationCategory.DESKSTOP; + } + + @Override + public DataStoreEntry getDisplayParent(DataStoreEntry store) { + DesktopCommandStore s = store.getStore().asNeeded(); + return s.getEnvironment().get(); + } + + @Override + public GuiDialog guiDialog(DataStoreEntry entry, Property store) { + DesktopCommandStore st = (DesktopCommandStore) store.getValue(); + var env = new SimpleObjectProperty<>(st.getEnvironment()); + var script = new SimpleStringProperty(st.getScript()); + return new OptionsBuilder() + .nameAndDescription("desktopEnvironmentBase") + .addComp( + new DataStoreChoiceComp<>( + DataStoreChoiceComp.Mode.HOST, + entry, + env, + DesktopEnvironmentStore.class, + desktopStoreDataStoreEntryRef -> desktopStoreDataStoreEntryRef.getStore().supportsDesktopAccess(), + StoreViewState.get().getAllConnectionsCategory()), + env) + .nonNull() + .nameAndDescription("desktopCommandScript") + .addComp( + new IntegratedTextAreaComp( + script, + false, + "commands", + Bindings.createStringBinding( + () -> { + return env.getValue() != null && env.getValue().getStore().getDialect() != null + ? env.getValue().getStore().getDialect() + .getScriptFileEnding() + : "sh"; + }, + env)), + script) + .nonNull() + .bind( + () -> { + return DesktopCommandStore.builder().environment(env.get()).script(script.get()).build(); + }, + store) + .buildDialog(); + } + + public String summaryString(StoreEntryWrapper wrapper) { + DesktopCommandStore s = wrapper.getEntry().getStore().asNeeded(); + return DataStoreFormatter.toApostropheName(s.getEnvironment().get()) + " config"; + } + + @Override + public String getDisplayIconFileName(DataStore store) { + return "base:desktopCommand_icon.svg"; + } + + @Override + public DataStore defaultStore() { + return DesktopCommandStore.builder().build(); + } + + @Override + public List getPossibleNames() { + return List.of("desktopCommand"); + } + + @Override + public List> getStoreClasses() { + return List.of(DesktopCommandStore.class); + } + + +} diff --git a/ext/base/src/main/java/io/xpipe/ext/base/desktop/DesktopEnvironmentStore.java b/ext/base/src/main/java/io/xpipe/ext/base/desktop/DesktopEnvironmentStore.java index 2ad830056..1872bc6e8 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/desktop/DesktopEnvironmentStore.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/desktop/DesktopEnvironmentStore.java @@ -7,6 +7,7 @@ import io.xpipe.app.util.Validators; import io.xpipe.core.process.OsType; import io.xpipe.core.process.ShellDialect; import io.xpipe.core.store.DataStore; +import io.xpipe.core.store.FilePath; import io.xpipe.core.util.JacksonizedValue; import io.xpipe.ext.base.SelfReferentialStore; import io.xpipe.ext.base.script.ScriptStore; @@ -14,14 +15,15 @@ import lombok.Getter; import lombok.experimental.SuperBuilder; import lombok.extern.jackson.Jacksonized; +import java.util.ArrayList; import java.util.List; -import java.util.stream.Stream; @Getter @SuperBuilder @Jacksonized @JsonTypeName("desktopEnvironment") -public class DesktopEnvironmentStore extends JacksonizedValue implements DesktopBaseStore, DataStore, SelfReferentialStore { +public class DesktopEnvironmentStore extends JacksonizedValue + implements DesktopBaseStore, DataStore, SelfReferentialStore { private final DataStoreEntryRef base; private final ExternalTerminalType terminal; @@ -45,35 +47,51 @@ public class DesktopEnvironmentStore extends JacksonizedValue implements Desktop public String getMergedInitCommands(String command) { var f = ScriptStore.flatten(scripts); - var filtered = f.stream().filter(simpleScriptStore -> simpleScriptStore.getMinimumDialect().isCompatibleTo(dialect) && simpleScriptStore.getExecutionType().runInTerminal()).toList(); - var initCommands = Stream.concat(filtered.stream().map(simpleScriptStore -> simpleScriptStore.getCommands()), command != null ? Stream.of(command) : Stream.of()).toList(); + var filtered = f.stream() + .filter(simpleScriptStore -> + simpleScriptStore.getMinimumDialect().isCompatibleTo(dialect) + && simpleScriptStore.getExecutionType().runInTerminal()) + .toList(); + var initCommands = new ArrayList<>(filtered.stream().map(simpleScriptStore -> simpleScriptStore.getCommands()).toList()); + if (initScript != null) { + initCommands.add(initScript); + } + if (command != null) { + initCommands.add(command); + } var joined = String.join(dialect.getNewLine().getNewLineString(), initCommands); return !joined.isBlank() ? joined : null; } - public void launch(String n, String commands) throws Exception { - var fullName = n + " [" + getSelfEntry().getName() + "]"; - base.getStore().runDesktopScript(fullName, dialect, getMergedInitCommands(commands)); - } - - public void launchSelf() throws Exception { - var fullName = getSelfEntry().getName(); - base.getStore().runDesktopTerminal(fullName, terminal, dialect, getMergedInitCommands(null)); - } - @Override public boolean supportsDesktopAccess() { return base.getStore().supportsDesktopAccess(); } @Override - public void runDesktopScript(String name, ShellDialect dialect, String script) throws Exception { - base.getStore().runDesktopScript(name, dialect, script); + public void runDesktopApplication(String name, DesktopApplicationStore applicationStore) throws Exception { + var fullName = name + " [" + getSelfEntry().getName() + "]"; + base.getStore().runDesktopApplication(fullName, applicationStore); } @Override - public void runDesktopTerminal(String name, ExternalTerminalType terminalType, ShellDialect dialect, String script) throws Exception { - base.getStore().runDesktopTerminal(name,terminalType,dialect,script); + public void runDesktopScript(String name, String script) throws Exception { + var fullName = getSelfEntry().getName(); + base.getStore().runDesktopScript(fullName, getMergedInitCommands(script)); + } + + @Override + public FilePath createScript(ShellDialect dialect, String content) throws Exception { + return base.getStore().createScript(dialect, content); + } + + public void runDesktopTerminal(String name, String script) throws Exception { + var launchCommand = terminal.remoteLaunchCommand(); + var toExecute = (script != null ? getMergedInitCommands(script + "\n" + dialect.getPauseCommand() + "\n" + dialect.getNormalExitCommand()): getMergedInitCommands(null)); + var scriptFile = base.getStore().createScript(dialect, toExecute); + var launchScriptFile = base.getStore().createScript(dialect, dialect.prepareTerminalInitFileOpenCommand(dialect, null, scriptFile.toString())); + var launchConfig = new ExternalTerminalType.LaunchConfiguration(null, name, name, launchScriptFile, getUsedDialect()); + base.getStore().runDesktopScript(name, launchCommand.apply(launchConfig)); } @Override diff --git a/ext/base/src/main/java/io/xpipe/ext/base/desktop/DesktopEnvironmentStoreProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/desktop/DesktopEnvironmentStoreProvider.java index 2f3d31bb2..d4f3f463f 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/desktop/DesktopEnvironmentStoreProvider.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/desktop/DesktopEnvironmentStoreProvider.java @@ -34,8 +34,7 @@ public class DesktopEnvironmentStoreProvider implements DataStoreProvider { } @Override - public ActionProvider.Action launchAction(DataStoreEntry store) { - DesktopEnvironmentStore s = store.getStore().asNeeded(); + public ActionProvider.Action activateAction(DataStoreEntry store) { return new ActionProvider.Action() { @Override public boolean requiresJavaFXPlatform() { @@ -44,7 +43,32 @@ public class DesktopEnvironmentStoreProvider implements DataStoreProvider { @Override public void execute() throws Exception { - s.launchSelf(); + DesktopEnvironmentStore s = store.getStore().asNeeded(); + var a = s.getBase().get().getProvider().activateAction(s.getBase().get()); + if (a != null) { + a.execute(); + } + } + }; + } + + @Override + public ActionProvider.Action launchAction(DataStoreEntry store) { + return new ActionProvider.Action() { + @Override + public boolean requiresJavaFXPlatform() { + return false; + } + + @Override + public void execute() throws Exception { + DesktopEnvironmentStore s = store.getStore().asNeeded(); + var a = s.getBase().get().getProvider().activateAction(s.getBase().get()); + if (a != null) { + a.execute(); + } + var fullName = store.getName(); + s.runDesktopTerminal(fullName, null); } }; } @@ -77,8 +101,8 @@ public class DesktopEnvironmentStoreProvider implements DataStoreProvider { .findModule("io.xpipe.ext.proc") .orElseThrow(), "io.xpipe.ext.proc.ShellDialectChoiceComp") - .getDeclaredConstructor(Property.class) - .newInstance(dialect); + .getDeclaredConstructor(Property.class, boolean.class) + .newInstance(dialect, false); return new OptionsBuilder() .nameAndDescription("desktopHost") .addComp( @@ -106,7 +130,6 @@ public class DesktopEnvironmentStoreProvider implements DataStoreProvider { StoreViewState.get().getAllScriptsCategory()), scripts) .nameAndDescription("desktopInitScript") - .longDescription("proc:environmentScript") .addComp( new IntegratedTextAreaComp( initScript, diff --git a/ext/base/src/main/java/io/xpipe/ext/base/script/SimpleScriptStoreProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/script/SimpleScriptStoreProvider.java index 31f812fbb..df426f3a3 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/script/SimpleScriptStoreProvider.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/script/SimpleScriptStoreProvider.java @@ -150,8 +150,8 @@ public class SimpleScriptStoreProvider implements DataStoreProvider { .findModule("io.xpipe.ext.proc") .orElseThrow(), "io.xpipe.ext.proc.ShellDialectChoiceComp") - .getDeclaredConstructor(Property.class) - .newInstance(dialect); + .getDeclaredConstructor(Property.class, boolean.class) + .newInstance(dialect, false); return new OptionsBuilder() .name("snippets") .description("snippetsDescription") @@ -210,7 +210,7 @@ public class SimpleScriptStoreProvider implements DataStoreProvider { } @Override - public void storageInit() { + public void init() { DataStorage.get() .addStoreEntryIfNotPresent(DataStoreEntry.createNew( UUID.fromString("a9945ad2-db61-4304-97d7-5dc4330691a7"), diff --git a/ext/base/src/main/java/module-info.java b/ext/base/src/main/java/module-info.java index f5eb0d1f1..626327f2e 100644 --- a/ext/base/src/main/java/module-info.java +++ b/ext/base/src/main/java/module-info.java @@ -3,6 +3,7 @@ import io.xpipe.app.ext.ActionProvider; import io.xpipe.app.ext.DataStoreProvider; import io.xpipe.ext.base.action.*; import io.xpipe.ext.base.browser.*; +import io.xpipe.ext.base.desktop.DesktopCommandStoreProvider; import io.xpipe.ext.base.desktop.DesktopEnvironmentStoreProvider; import io.xpipe.ext.base.script.ScriptGroupStoreProvider; import io.xpipe.ext.base.script.SimpleScriptStoreProvider; @@ -66,6 +67,6 @@ open module io.xpipe.ext.base { DeleteStoreChildrenAction, BrowseStoreAction; provides DataStoreProvider with - SimpleScriptStoreProvider, DesktopEnvironmentStoreProvider, DesktopApplicationStoreProvider, + SimpleScriptStoreProvider, DesktopEnvironmentStoreProvider, DesktopApplicationStoreProvider, DesktopCommandStoreProvider, ScriptGroupStoreProvider; } diff --git a/lang/base/strings/translations_en.properties b/lang/base/strings/translations_en.properties index 31bdfeee1..cc7980eb3 100644 --- a/lang/base/strings/translations_en.properties +++ b/lang/base/strings/translations_en.properties @@ -119,12 +119,18 @@ desktopInitScriptDescription=Init commands specific to this environment desktopTerminal=Terminal application desktopTerminalDescription=The terminal to use on the desktop to start scripts in desktopApplication.displayName=Desktop application -desktopApplication.displayDescription=Run an application in a desktop environment +desktopApplication.displayDescription=Run an application on a desktop +desktopBase=Desktop +desktopBaseDescription=The desktop to run this application on desktopEnvironmentBase=Desktop environment desktopEnvironmentBaseDescription=The desktop environment to run this application on desktopApplicationPath=Application path desktopApplicationPathDescription=The path of the executable to run desktopApplicationArguments=Arguments desktopApplicationArgumentsDescription=The optional arguments to pass to the application +desktopCommand.displayName=Desktop command +desktopCommand.displayDescription=Run a command in a desktop environment +desktopCommandScript=Commands +desktopCommandScriptDescription=The commands to run in the environment diff --git a/lang/proc/strings/translations_en.properties b/lang/proc/strings/translations_en.properties index f28f3afd2..0980cd8e2 100644 --- a/lang/proc/strings/translations_en.properties +++ b/lang/proc/strings/translations_en.properties @@ -34,7 +34,7 @@ start=Start stop=Stop pause=Pause rdpTunnelHost=Tunnel host -rdpTunnelHostDescription=The optional SSH connection to use as a tunnel +rdpTunnelHostDescription=The SSH connection to use as a tunnel rdpFileLocation=File location rdpFileLocationDescription=The file path of the .rdp file rdpPasswordAuthentication=Password authentication @@ -299,3 +299,6 @@ launch=Launch sshTrustKeyHeader=The host key is not known, and you have enabled manual host key verification. sshTrustKeyTitle=Unknown host key vnc=VNC connections +rdpTunnel.displayName=RDP over SSH +rdpTunnel.displayDescription=Connect via RDP over a tunneled SSH connection + diff --git a/lang/proc/texts/rdpTunnelHost_en.md b/lang/proc/texts/rdpTunnelHost_en.md index ac56ca932..e3f45af59 100644 --- a/lang/proc/texts/rdpTunnelHost_en.md +++ b/lang/proc/texts/rdpTunnelHost_en.md @@ -1,5 +1,5 @@ ## RDP Tunnel Host -You can choose to connect to a remote RDP host via an SSH tunnel. This gives you the ability to use the more advanced SSH authentication features with RDP out of the box. +You can connect to a remote RDP host via an SSH tunnel. This gives you the ability to use the more advanced SSH authentication features with RDP out of the box. -When this option is used, the host address in the RDP file will be replaced by the chosen hostname of the SSH connection. Upon first connection, an SSH tunnel will be established and the RDP client will connect to the tunneled connection via localhost instead. \ No newline at end of file +Upon first connection, an SSH tunnel will be established and the RDP client will connect to the tunneled connection via localhost instead. It will use the credentials of the SSH connection user for RDP authentication. \ No newline at end of file