Rework terminal init

This commit is contained in:
crschnick
2026-04-27 00:14:49 +00:00
parent e3013b1e1d
commit cda4d23ddc
8 changed files with 39 additions and 19 deletions
@@ -41,6 +41,14 @@ public class TerminalLaunchRequest {
@NonFinal
CountDownLatch latch;
public TerminalLaunchRequest(UUID request, ProcessControl processControl, TerminalInitScriptConfig config, FilePath workingDirectory) {
this.request = request;
this.processControl = processControl;
this.config = config;
this.workingDirectory = workingDirectory;
this.shellPid = -1;
}
public Path waitForCompletion() throws BeaconServerException {
while (true) {
if (latch.getCount() > 0) {
@@ -111,7 +111,7 @@ public class TerminalLauncher {
true);
var singlePane = new TerminalPaneConfiguration(UUID.randomUUID(), title, 0, script, sc.getShellDialect());
var config = new TerminalLaunchConfiguration(null, title, title, true, List.of(singlePane));
launch(type, config, new CountDownLatch(0));
launch(type, config);
}
}
@@ -127,7 +127,6 @@ public class TerminalLauncher {
}
public static void open(List<Config> configs, boolean preferTabs, ExternalTerminalType type) throws Exception {
var latch = new CountDownLatch(configs.size());
var paneList = new ArrayList<TerminalPaneConfiguration>();
for (Config config : configs) {
var entry = config.getEntry();
@@ -149,7 +148,7 @@ public class TerminalLauncher {
? type.additionalInitCommands()
: TerminalInitFunction.none());
TerminalLauncherManager.submitAsync(
config.getRequest(), config.getProcessControl(), terminalConfig, config.getDirectory(), latch);
config.getRequest(), config.getProcessControl(), terminalConfig, config.getDirectory());
var paneIndex = configs.indexOf(config);
var paneConfig = TerminalPaneConfiguration.create(
@@ -199,27 +198,26 @@ public class TerminalLauncher {
TerminalMultiplexerManager.registerSessionLaunch(launchConfig);
if (launchMultiplexerTabInExistingTerminal(launchConfig)) {
latch.await();
return;
}
var multiplexerConfig = launchMultiplexerTabInNewTerminal(launchConfig);
if (multiplexerConfig.isPresent()) {
launch(type, multiplexerConfig.get(), latch);
launch(type, multiplexerConfig.get());
return;
}
}
var proxyConfig = launchProxy(launchConfig);
if (proxyConfig.isPresent()) {
launch(type, proxyConfig.get(), latch);
launch(type, proxyConfig.get());
return;
}
launch(type, launchConfig, latch);
launch(type, launchConfig);
}
private static void launch(ExternalTerminalType type, TerminalLaunchConfiguration config, CountDownLatch latch)
private static void launch(ExternalTerminalType type, TerminalLaunchConfiguration config)
throws Exception {
if (type == null) {
return;
@@ -227,7 +225,6 @@ public class TerminalLauncher {
try {
type.launch(config);
latch.await();
} catch (Exception ex) {
var modMsg = ex.getMessage() != null && ex.getMessage().contains("Unable to find application named")
? ex.getMessage() + " in installed /Applications on this system"
@@ -36,23 +36,21 @@ public class TerminalLauncherManager {
});
}
public static CountDownLatch submitAsync(
public static void submitAsync(
UUID request,
ProcessControl processControl,
TerminalInitScriptConfig config,
FilePath directory,
CountDownLatch latch) {
FilePath directory) {
synchronized (entries) {
var req = entries.get(request);
if (req == null) {
req = new TerminalLaunchRequest(request, processControl, config, directory, -1, null, false, latch);
req = new TerminalLaunchRequest(request, processControl, config, directory);
entries.put(request, req);
} else {
req.setResult(null);
}
req.setupRequestAsync();
return req.getLatch();
}
}
@@ -105,7 +103,7 @@ public class TerminalLauncherManager {
}
if (req.isSetupCompleted()) {
submitAsync(req.getRequest(), req.getProcessControl(), req.getConfig(), req.getWorkingDirectory(), null);
submitAsync(req.getRequest(), req.getProcessControl(), req.getConfig(), req.getWorkingDirectory());
}
try {
req.waitForCompletion();
@@ -175,7 +173,7 @@ public class TerminalLauncherManager {
}
var config = new TerminalInitScriptConfig(ref.get().getName(), false, TerminalInitFunction.none());
submitAsync(request, control, config, null, null);
submitAsync(request, control, config, null);
waitExchange(request);
var script = launchExchange(request);
try (var sc = LocalShell.getShell().start()) {
@@ -86,9 +86,9 @@ public class TerminalPaneConfiguration {
var content = """
%s
echo 'Transcript started, output file is "sessions\\%s"'
Start-Transcript -Force -LiteralPath "%s" > $Out-Null
Start-Transcript -Force -LiteralPath "%s" | Out-Null
& "%s"
Stop-Transcript > $Out-Null
Stop-Transcript | Out-Null
echo 'Transcript stopped, output file is "sessions\\%s"'
""".formatted(
TerminalLauncher.getTerminalRegisterCommand(
@@ -276,6 +276,11 @@ public class TerminalView {
this.controllable = controllable;
}
@Override
public boolean isRunning() {
return super.isRunning() && !controllable.isDestroyed();
}
public boolean manageBorders() {
return terminalType != null
&& terminalType instanceof TrackableTerminalType t
@@ -45,6 +45,8 @@ public abstract class ControllableWindowProcess {
public abstract boolean isActive();
public abstract boolean isDestroyed();
public abstract Rect queryBounds();
public void updateBoundsState() {
@@ -136,6 +136,11 @@ public final class ControllableWindowsProcess extends ControllableWindowProcess
return true;
}
@Override
public boolean isDestroyed() {
return control.isDestroyed();
}
@Override
public Rect queryBounds() {
return control.getBounds();
@@ -67,7 +67,8 @@ public class NativeWinWindowControl {
var wpid = new IntByReference();
User32.INSTANCE.GetWindowThreadProcessId(hWnd, wpid);
if (wpid.getValue() == pid) {
refs.add(new NativeWinWindowControl(hWnd));
var c = new NativeWinWindowControl(hWnd);
refs.add(c);
}
return true;
},
@@ -153,6 +154,10 @@ public class NativeWinWindowControl {
return User32.INSTANCE.IsWindowVisible(windowHandle);
}
public boolean isDestroyed() {
return !User32.INSTANCE.IsWindow(windowHandle);
}
public void moveToFront() {
orderRelative(new WinDef.HWND(new Pointer(0)));
}