diff --git a/app/src/main/java/io/xpipe/app/prefs/TroubleshootCategory.java b/app/src/main/java/io/xpipe/app/prefs/TroubleshootCategory.java index 13167b34..6cdc1943 100644 --- a/app/src/main/java/io/xpipe/app/prefs/TroubleshootCategory.java +++ b/app/src/main/java/io/xpipe/app/prefs/TroubleshootCategory.java @@ -6,6 +6,7 @@ import io.xpipe.app.core.mode.OperationMode; import io.xpipe.app.fxcomps.Comp; import io.xpipe.app.issue.ErrorEvent; import io.xpipe.app.issue.UserReportComp; +import io.xpipe.app.terminal.ExternalTerminalType; import io.xpipe.app.util.DesktopHelper; import io.xpipe.app.util.FileOpener; import io.xpipe.app.util.OptionsBuilder; @@ -45,8 +46,10 @@ public class TroubleshootCategory extends AppPrefsCategory { XPipeInstallation.getCurrentInstallationBasePath() .toString(), XPipeInstallation.getDaemonDebugScriptPath(OsType.getLocal())); + // We can't use the SSH bridge + var type = ExternalTerminalType.determineNonSshBridgeFallback(AppPrefs.get().terminalType().getValue()); TerminalLauncher.openDirect("XPipe Debug", sc -> sc.getShellDialect() - .runScriptCommand(sc, script)); + .runScriptCommand(sc, script), type); }); e.consume(); }) diff --git a/app/src/main/java/io/xpipe/app/terminal/ExternalTerminalType.java b/app/src/main/java/io/xpipe/app/terminal/ExternalTerminalType.java index 99ad4ad4..6f6b90f8 100644 --- a/app/src/main/java/io/xpipe/app/terminal/ExternalTerminalType.java +++ b/app/src/main/java/io/xpipe/app/terminal/ExternalTerminalType.java @@ -70,6 +70,31 @@ public interface ExternalTerminalType extends PrefsChoiceValue { // } // }; + static ExternalTerminalType determineNonSshBridgeFallback(ExternalTerminalType type) { + if (type == XSHELL || type == MOBAXTERM || type == SECURECRT) { + return CMD; + } + + if (type != TERMIUS) { + return type; + } + + switch (OsType.getLocal()) { + case OsType.Linux linux -> { + // This should not be termius as all others take precedence + var def = determineDefault(type); + // If there's no other terminal available, use a fallback which won't work + return def != TERMIUS ? def : XTERM; + } + case OsType.MacOs macOs -> { + return MACOS_TERMINAL; + } + case OsType.Windows windows -> { + return CMD; + } + } + } + ExternalTerminalType XSHELL = new WindowsType("app.xShell", "Xshell") { @Override @@ -319,21 +344,21 @@ public interface ExternalTerminalType extends PrefsChoiceValue { + user + "&os=undefined"); } - private boolean showInfo() { - boolean set = AppCache.get("termiusSetup", Boolean.class, () -> false); + private boolean showInfo() throws IOException { + boolean set = AppCache.get("termiusSetupa", Boolean.class, () -> false); if (set) { return true; } var b = SshLocalBridge.get(); - var keyName = b.getIdentityKey().getFileName().toString(); + var keyContent = Files.readString(b.getIdentityKey()); var r = AppWindowHelper.showBlockingAlert(alert -> { alert.setTitle(AppI18n.get("termiusSetup")); alert.setAlertType(Alert.AlertType.NONE); var activated = AppI18n.get() .getMarkdownDocumentation("app:termiusSetup") - .formatted(b.getIdentityKey(), keyName); + .formatted(b.getIdentityKey(), keyContent); var markdown = new MarkdownComp(activated, s -> s) .prefWidth(450) .prefHeight(400) @@ -471,7 +496,7 @@ public interface ExternalTerminalType extends PrefsChoiceValue { @Override public boolean supportsColoredTitle() { - return true; + return false; } @Override @@ -979,13 +1004,13 @@ public interface ExternalTerminalType extends PrefsChoiceValue { TabbyTerminalType.TABBY_WINDOWS, AlacrittyTerminalType.ALACRITTY_WINDOWS, WezTerminalType.WEZTERM_WINDOWS, + CMD, + PWSH, + POWERSHELL, MOBAXTERM, SECURECRT, TERMIUS, - XSHELL, - CMD, - PWSH, - POWERSHELL); + XSHELL); List LINUX_TERMINALS = List.of( KittyTerminalType.KITTY_LINUX, AlacrittyTerminalType.ALACRITTY_LINUX, @@ -1002,7 +1027,8 @@ public interface ExternalTerminalType extends PrefsChoiceValue { XTERM, DEEPIN_TERMINAL, FOOT, - Q_TERMINAL); + Q_TERMINAL, + TERMIUS); List MACOS_TERMINALS = List.of( KittyTerminalType.KITTY_MACOS, WARP, @@ -1010,7 +1036,8 @@ public interface ExternalTerminalType extends PrefsChoiceValue { TabbyTerminalType.TABBY_MAC_OS, AlacrittyTerminalType.ALACRITTY_MAC_OS, WezTerminalType.WEZTERM_MAC_OS, - MACOS_TERMINAL); + MACOS_TERMINAL, + TERMIUS); List ALL = getTypes(OsType.getLocal(), false, true); diff --git a/app/src/main/java/io/xpipe/app/update/AppInstaller.java b/app/src/main/java/io/xpipe/app/update/AppInstaller.java index 7b45c427..6e521cfa 100644 --- a/app/src/main/java/io/xpipe/app/update/AppInstaller.java +++ b/app/src/main/java/io/xpipe/app/update/AppInstaller.java @@ -4,6 +4,7 @@ import io.xpipe.app.core.AppLogs; import io.xpipe.app.core.AppProperties; import io.xpipe.app.core.mode.OperationMode; import io.xpipe.app.prefs.AppPrefs; +import io.xpipe.app.terminal.ExternalTerminalType; import io.xpipe.app.util.LocalShell; import io.xpipe.app.util.ScriptHelper; import io.xpipe.app.util.TerminalLauncher; @@ -163,7 +164,9 @@ public class AppInstaller { file, file, name); runAndClose(() -> { - TerminalLauncher.openDirect("XPipe Updater", sc -> command); + // We can't use the SSH bridge + var type = ExternalTerminalType.determineNonSshBridgeFallback(AppPrefs.get().terminalType().getValue()); + TerminalLauncher.openDirect("XPipe Updater", sc -> command, type); }); } @@ -201,7 +204,9 @@ public class AppInstaller { file, file, name); runAndClose(() -> { - TerminalLauncher.openDirect("XPipe Updater", sc -> command); + // We can't use the SSH bridge + var type = ExternalTerminalType.determineNonSshBridgeFallback(AppPrefs.get().terminalType().getValue()); + TerminalLauncher.openDirect("XPipe Updater", sc -> command, type); }); } @@ -239,7 +244,9 @@ public class AppInstaller { file, file, name); runAndClose(() -> { - TerminalLauncher.openDirect("XPipe Updater", sc -> command); + // We can't use the SSH bridge + var type = ExternalTerminalType.determineNonSshBridgeFallback(AppPrefs.get().terminalType().getValue()); + TerminalLauncher.openDirect("XPipe Updater", sc -> command, type); }); } diff --git a/app/src/main/java/io/xpipe/app/util/SshLocalBridge.java b/app/src/main/java/io/xpipe/app/util/SshLocalBridge.java index e5ac8915..75978564 100644 --- a/app/src/main/java/io/xpipe/app/util/SshLocalBridge.java +++ b/app/src/main/java/io/xpipe/app/util/SshLocalBridge.java @@ -67,11 +67,16 @@ public class SshLocalBridge { return; } + var server = AppBeaconServer.get(); + if (server == null) { + return; + } + // Add a gap to not interfere with PTB or dev ports + var port = server.getPort() + 10; + try (var sc = LocalShell.getShell().start()) { var bridgeDir = AppProperties.get().getDataDir().resolve("ssh_bridge"); Files.createDirectories(bridgeDir); - // Add a gap to not interfere with PTB or dev ports - var port = AppBeaconServer.get().getPort() + 10; var user = sc.getShellDialect().printUsernameCommand(sc).readStdoutOrThrow(); INSTANCE = new SshLocalBridge(bridgeDir, port, user); diff --git a/app/src/main/java/io/xpipe/app/util/TerminalLauncher.java b/app/src/main/java/io/xpipe/app/util/TerminalLauncher.java index 4cc84e72..f440a253 100644 --- a/app/src/main/java/io/xpipe/app/util/TerminalLauncher.java +++ b/app/src/main/java/io/xpipe/app/util/TerminalLauncher.java @@ -17,11 +17,15 @@ public class TerminalLauncher { public static void openDirect(String title, FailableFunction command) throws Exception { + var type = AppPrefs.get().terminalType().getValue(); + if (type == null) { + throw ErrorEvent.expected(new IllegalStateException(AppI18n.get("noTerminalSet"))); + } + openDirect(title, command, type); + } + public static void openDirect(String title, FailableFunction command, ExternalTerminalType type) + throws Exception { try (var sc = LocalShell.getShell().start()) { - var type = AppPrefs.get().terminalType().getValue(); - if (type == null) { - throw ErrorEvent.expected(new IllegalStateException(AppI18n.get("noTerminalSet"))); - } var script = ScriptHelper.constructTerminalInitFile( sc.getShellDialect(), sc, diff --git a/lang/app/texts/termiusSetup_en.md b/lang/app/texts/termiusSetup_en.md index f4ec9015..ee9b0731 100644 --- a/lang/app/texts/termiusSetup_en.md +++ b/lang/app/texts/termiusSetup_en.md @@ -2,4 +2,8 @@ To use Termius as your terminal, you can connect it to the XPipe SSH bridge. This can work automatically once the local bridge ssh key has been added to Termius. -The only thing you have to do manually is to add the private key file `%s` to Termius first. \ No newline at end of file +The only thing you have to do manually is to add the private key file `%s` to Termius first: + +``` +%s +``` \ No newline at end of file