diff --git a/app/src/main/java/io/xpipe/app/terminal/TerminalLauncher.java b/app/src/main/java/io/xpipe/app/terminal/TerminalLauncher.java index eafda2295..f16b30da8 100644 --- a/app/src/main/java/io/xpipe/app/terminal/TerminalLauncher.java +++ b/app/src/main/java/io/xpipe/app/terminal/TerminalLauncher.java @@ -181,15 +181,18 @@ public class TerminalLauncher { } if (effectivePreferTabs) { + // There will be timing issues when launching multiple tabs in a short time span + TerminalMultiplexerManager.waitForMultiplexerStartup(); + // Synchronize between multiple existing tab launches as some terminals and multiplexers might break there - var elapsed = Duration.between(lastLaunch, Instant.now()).toMillis(); + long elapsed; + synchronized (TerminalLauncher.class) { + elapsed = Duration.between(lastLaunch, Instant.now()).toMillis(); + lastLaunch = Instant.now(); + } if (elapsed < 1000) { ThreadHelper.sleep(1000 - elapsed); } - lastLaunch = Instant.now(); - - // There will be timing issues when launching multiple tabs in a short time span - TerminalMultiplexerManager.synchronizeMultiplexerLaunchTiming(); // Track sessions that are used for the multiplexer // Used to figure out when it dies diff --git a/app/src/main/java/io/xpipe/app/terminal/TerminalMultiplexerManager.java b/app/src/main/java/io/xpipe/app/terminal/TerminalMultiplexerManager.java index 5442118aa..b77cf1510 100644 --- a/app/src/main/java/io/xpipe/app/terminal/TerminalMultiplexerManager.java +++ b/app/src/main/java/io/xpipe/app/terminal/TerminalMultiplexerManager.java @@ -4,8 +4,6 @@ import io.xpipe.app.prefs.AppPrefs; import io.xpipe.app.util.ThreadHelper; import io.xpipe.core.OsType; -import java.time.Duration; -import java.time.Instant; import java.util.*; public class TerminalMultiplexerManager { @@ -65,7 +63,7 @@ public class TerminalMultiplexerManager { return Optional.of(multiplexer); } - public static void synchronizeMultiplexerLaunchTiming() { + public static void waitForMultiplexerStartup() { var mult = getEffectiveMultiplexer(); if (mult.isEmpty()) { return; @@ -73,9 +71,12 @@ public class TerminalMultiplexerManager { // Wait if we are currently opening a new multiplexer if (pendingMultiplexerLaunch != null) { - // Wait for max 10s - for (int i = 0; i < 100; i++) { + // Wait for max 30s + // Multiplexer launches in WSL may take a while + for (int i = 0; i < 300; i++) { if (pendingMultiplexerLaunch == null) { + // Give it a bit more time if it just started + ThreadHelper.sleep(1000); break; } diff --git a/app/src/main/java/io/xpipe/app/terminal/TerminalPrompt.java b/app/src/main/java/io/xpipe/app/terminal/TerminalPrompt.java index fa89a7ea4..ffbb5fb53 100644 --- a/app/src/main/java/io/xpipe/app/terminal/TerminalPrompt.java +++ b/app/src/main/java/io/xpipe/app/terminal/TerminalPrompt.java @@ -5,6 +5,8 @@ import io.xpipe.app.process.ShellControl; import io.xpipe.app.process.ShellDialect; import io.xpipe.app.process.ShellTemp; import io.xpipe.app.process.ShellTerminalInitCommand; +import io.xpipe.app.storage.DataStorage; +import io.xpipe.app.storage.DataStoreEntry; import io.xpipe.core.FilePath; import com.fasterxml.jackson.annotation.JsonTypeInfo; @@ -45,9 +47,11 @@ public interface TerminalPrompt { checkCanInstall(sc); install(sc); } catch (Exception e) { + var name = sc.getSourceStoreId().flatMap(uuid -> DataStorage.get().getStoreEntryIfPresent(uuid)) + .map(DataStoreEntry::getName).orElse(null); ErrorEventFactory.fromThrowable(e) .omit() - .description("Prompt installation for " + getId() + " failed on remote system") + .description("Prompt installation for " + getId() + " failed on remote system" + (name != null ? " " + name : "")) .expected() .handle(); return false;