diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/LocalTerminalDirectRunner.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/LocalTerminalDirectRunner.java index c95f519d8f7a..edb096d928fa 100644 --- a/plugins/terminal/src/org/jetbrains/plugins/terminal/LocalTerminalDirectRunner.java +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/LocalTerminalDirectRunner.java @@ -7,14 +7,11 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.registry.Registry; -import com.intellij.terminal.pty.PtyProcessTtyConnector; import com.intellij.util.ArrayUtil; import com.intellij.util.TimeoutUtil; -import com.intellij.util.concurrency.AppExecutorUtil; import com.jediterm.core.util.TermSize; import com.jediterm.terminal.TtyConnector; import com.pty4j.PtyProcess; -import com.pty4j.unix.UnixPtyProcess; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -25,7 +22,6 @@ import org.jetbrains.plugins.terminal.runner.LocalOptionsConfigurer; import org.jetbrains.plugins.terminal.runner.LocalShellIntegrationInjector; import org.jetbrains.plugins.terminal.runner.LocalTerminalStartCommandBuilder; -import java.io.IOException; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.nio.file.Files; @@ -33,7 +29,6 @@ import java.nio.file.InvalidPathException; import java.nio.file.Path; import java.util.*; import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; import static org.jetbrains.plugins.terminal.LocalBlockTerminalRunner.*; @@ -188,47 +183,7 @@ public class LocalTerminalDirectRunner extends AbstractTerminalRunner { - if (process.isAlive()) { - LOG.info("Terminal hasn't been terminated by SIGHUP, performing default termination"); - process.destroy(); - } - }, 1000, TimeUnit.MILLISECONDS); - } - else { - process.destroy(); - } - } - - @Override - public void resize(@NotNull TermSize termSize) { - if (LOG.isDebugEnabled()) { - LOG.debug("resize to " + termSize); - } - super.resize(termSize); - } - }; + return new LocalTerminalTtyConnector(process, myDefaultCharset); } @Override diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/LocalTerminalTtyConnector.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/LocalTerminalTtyConnector.java new file mode 100644 index 000000000000..de42b8bedb77 --- /dev/null +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/LocalTerminalTtyConnector.java @@ -0,0 +1,67 @@ +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package org.jetbrains.plugins.terminal; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.terminal.pty.PtyProcessTtyConnector; +import com.intellij.util.concurrency.AppExecutorUtil; +import com.jediterm.core.util.TermSize; +import com.pty4j.PtyProcess; +import com.pty4j.unix.UnixPtyProcess; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.terminal.fus.ReworkedTerminalUsageCollector; + +import java.io.IOException; +import java.nio.charset.Charset; +import java.util.concurrent.TimeUnit; + +@ApiStatus.Internal +public class LocalTerminalTtyConnector extends PtyProcessTtyConnector { + private static final Logger LOG = Logger.getInstance(LocalTerminalTtyConnector.class); + private final @NotNull PtyProcess myProcess; + + LocalTerminalTtyConnector(@NotNull PtyProcess process, @NotNull Charset charset) { + super(process, charset); + myProcess = process; + } + + @Override + public void write(byte[] bytes) throws IOException { + var fusActivity = ReworkedTerminalUsageCollector.getBackendTypingActivityOrNull(bytes); + try { + super.write(bytes); + if (fusActivity != null) { + fusActivity.reportDuration(); + } + } + finally { + if (fusActivity != null) { + fusActivity.finishBytesProcessing(); + } + } + } + + @Override + public void close() { + if (myProcess instanceof UnixPtyProcess) { + ((UnixPtyProcess)myProcess).hangup(); + AppExecutorUtil.getAppScheduledExecutorService().schedule(() -> { + if (myProcess.isAlive()) { + LOG.info("Terminal hasn't been terminated by SIGHUP, performing default termination"); + myProcess.destroy(); + } + }, 1000, TimeUnit.MILLISECONDS); + } + else { + myProcess.destroy(); + } + } + + @Override + public void resize(@NotNull TermSize termSize) { + if (LOG.isDebugEnabled()) { + LOG.debug("resize to " + termSize); + } + super.resize(termSize); + } +}