diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 97184e00bd..a721ef589f 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -193,6 +193,8 @@ jobs:
arch="${{ matrix.arch }}"
echo "PLATFORM=${arch%% *}" >> "$GITHUB_OUTPUT"
echo "ARCH=${arch##* }" >> "$GITHUB_OUTPUT"
+ - name: "update APT database"
+ run: sudo apt -q update
- name: Installing xmllint for ci-set-vars
run: sudo apt -qy install libxml2-utils
- name: set environment variables
@@ -245,6 +247,8 @@ jobs:
arch="${{ matrix.arch }}"
echo "PLATFORM=${arch%% *}" >> "$GITHUB_OUTPUT"
echo "ARCH=${arch##* }" >> "$GITHUB_OUTPUT"
+ - name: "update APT database"
+ run: sudo apt -q update
- name: Installing xmllint for ci-set-vars
run: sudo apt -qy install libxml2-utils
- name: set environment variables
@@ -1169,6 +1173,8 @@ jobs:
needs: [package_for_Ubuntu]
steps:
- uses: actions/checkout@v3
+ - name: "update APT database"
+ run: sudo apt -q update
- name: Installing xmllint for ci-set-vars
run: sudo apt -qy install libxml2-utils
- name: set environment variables
@@ -1190,6 +1196,8 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
+ - name: "update APT database"
+ run: sudo apt -q update
- name: Installing xmllint for ci-set-vars.sh and check-release.sh
run: sudo apt -qy install libxml2-utils
- name: set variables
@@ -1220,6 +1228,8 @@ jobs:
discussions: write
steps:
- uses: actions/checkout@v3
+ - name: "update APT database"
+ run: sudo apt -q update
- name: Installing xmllint for ci-set-vars
run: sudo apt -qy install libxml2-utils
- name: set variables
diff --git a/docs/configuration/index.md b/docs/configuration/index.md
index 8966a16f0a..5e680a3c63 100644
--- a/docs/configuration/index.md
+++ b/docs/configuration/index.md
@@ -38,7 +38,9 @@ option specifies the default PTY read buffer size in bytes. It is an advanced op
option sets the size in bytes per PTY Buffer Object. It is an advanced option for internal storage and should be changed carefully. The default value is `1048576`.
### `default_profile`
option determines the default profile to use in the terminal.
-`spawn_new_process`
+### 'early_exit_threshold'
+option determines the early threshold time. If contour atempts to close earlier than specified threshold, additional message will be printed that contour terminated too early and additional key press is required to close contour.
+### `spawn_new_process`
flag determines whether a new process should be spawned when creating a new terminal. The default value is `false`.
### `reflow_on_resize`
option controls whether or not the lines in the terminal should be reflowed when a resize event occurs. The default value is `true`.
diff --git a/metainfo.xml b/metainfo.xml
index 6f4ffff5fd..d357806d95 100644
--- a/metainfo.xml
+++ b/metainfo.xml
@@ -107,6 +107,7 @@
+ - Adds 'early_exit_threshold' config option (#1460)
- Add ability to customize the indicator statusline through configuration (#687)
- Add generation of config file from internal state (#1282)
- Add SGRSAVE and SGRRESTORE VT sequences to save and restore SGR state (They intentionally conflict with XTPUSHSGR and XTPOPSGR)
diff --git a/src/contour/Config.cpp b/src/contour/Config.cpp
index 6f9031df73..e7007fb0e0 100644
--- a/src/contour/Config.cpp
+++ b/src/contour/Config.cpp
@@ -294,6 +294,7 @@ void YAMLConfigReader::load(Config& c)
loadFromEntry("pty_buffer_size", c.ptyBufferObjectSize);
loadFromEntry("images.sixel_register_count", c.maxImageColorRegisters);
loadFromEntry("live_config", c.live);
+ loadFromEntry("early_exit_threshold", c.earlyExitThreshold);
loadFromEntry("spawn_new_process", c.spawnNewProcess);
loadFromEntry("images.sixe_scrolling", c.sixelScrolling);
loadFromEntry("reflow_on_resize", c.reflowOnResize);
@@ -1848,6 +1849,7 @@ std::string YAMLConfigWriter::createString(Config const& c)
process(c.ptyReadBufferSize);
process(c.ptyBufferObjectSize);
process(c.defaultProfileName);
+ process(c.earlyExitThreshold);
process(c.spawnNewProcess);
process(c.reflowOnResize);
process(c.bypassMouseProtocolModifiers);
diff --git a/src/contour/Config.h b/src/contour/Config.h
index 9f786824a7..b5858a081e 100644
--- a/src/contour/Config.h
+++ b/src/contour/Config.h
@@ -663,6 +663,9 @@ struct Config
ConfigEntry
mouseBlockSelectionModifiers { vtbackend::Modifier::Control };
ConfigEntry inputMappings { defaultInputMappings };
+ ConfigEntry earlyExitThreshold {
+ documentation::DefaultEarlyExitThreshold
+ };
ConfigEntry spawnNewProcess { false };
ConfigEntry sixelScrolling { true };
ConfigEntry maxImageSize { { vtpty::Width { 0 },
diff --git a/src/contour/ConfigDocumentation.h b/src/contour/ConfigDocumentation.h
index 7ba2e003aa..671fcbb868 100644
--- a/src/contour/ConfigDocumentation.h
+++ b/src/contour/ConfigDocumentation.h
@@ -522,6 +522,7 @@ constexpr StringLiteral PTYBufferObjectSize {
};
constexpr StringLiteral ReflowOnResize {
+ "\n"
"{comment} Whether or not to reflow the lines on terminal resize events. \n"
"reflow_on_resize: {} \n"
};
@@ -743,10 +744,16 @@ constexpr StringLiteral InputMappings {
};
constexpr StringLiteral SpawnNewProcess {
+ "\n"
"{comment} Flag to determine whether to spawn new process or not when creating new terminal \n"
"spawn_new_process: {} \n"
};
+constexpr unsigned DefaultEarlyExitThreshold = 5u;
+constexpr StringLiteral EarlyExitThreshold { "\n"
+ "{comment} Time in seconds to check for early threshold \n"
+ "early_exit_threshold: {} \n" };
+
constexpr StringLiteral SixelScrolling { "{comment} Enable or disable sixel scrolling (SM/RM ?80 default) \n"
"sixel_scrolling: {} \n" };
diff --git a/src/contour/ContourGuiApp.cpp b/src/contour/ContourGuiApp.cpp
index 717f7fd836..e9b2bf3c83 100644
--- a/src/contour/ContourGuiApp.cpp
+++ b/src/contour/ContourGuiApp.cpp
@@ -109,7 +109,7 @@ crispy::cli::command ContourGuiApp::parameterDefinition() const
"Dumps internal state at exit into the given directory. This is for debugging contour.",
"PATH" },
CLI::option { "early-exit-threshold",
- CLI::value { 6u },
+ CLI::value { -1 },
"If the spawned process exits earlier than the given threshold seconds, an "
"error message will be printed and the window not closed immediately." },
CLI::option { "working-directory",
@@ -149,7 +149,17 @@ crispy::cli::command ContourGuiApp::parameterDefinition() const
std::chrono::seconds ContourGuiApp::earlyExitThreshold() const
{
- return std::chrono::seconds(parameters().get("contour.terminal.early-exit-threshold"));
+ auto const configThreshold = config().earlyExitThreshold.value();
+ auto const parameterThreshold = parameters().get("contour.terminal.early-exit-threshold");
+
+ // default threshold is config::documentation::DefaultEarlyExitThreshold seconds
+ if (parameterThreshold >= 0)
+ return std::chrono::seconds(parameterThreshold);
+
+ if (configThreshold != config::documentation::DefaultEarlyExitThreshold)
+ return std::chrono::seconds(configThreshold);
+
+ return std::chrono::seconds(config::documentation::DefaultEarlyExitThreshold);
}
string ContourGuiApp::profileName() const
diff --git a/src/contour/TerminalSession.cpp b/src/contour/TerminalSession.cpp
index cf8ab1c75e..2a36420fcf 100644
--- a/src/contour/TerminalSession.cpp
+++ b/src/contour/TerminalSession.cpp
@@ -288,7 +288,6 @@ void TerminalSession::mainLoop()
}
sessionLog()("Event loop terminating (PTY {}).", _terminal.device().isClosed() ? "closed" : "open");
- onClosed();
}
void TerminalSession::terminate()
@@ -572,15 +571,6 @@ void TerminalSession::notify(string_view title, string_view content)
void TerminalSession::onClosed()
{
auto const _ = std::scoped_lock { _onClosedMutex };
- auto isClosedAlready = _onClosedHandled.load();
- if (isClosedAlready || !_onClosedHandled.compare_exchange_weak(isClosedAlready, true))
- {
- sessionLog()("onClosed called: thread {}, display {}", crispy::threadName(), _display ? "yes" : "no");
- if (_display)
- _display->closeDisplay();
- return;
- }
-
sessionLog()("Terminal device closed (thread {})", crispy::threadName());
if (!_terminal.device().isClosed())
@@ -628,6 +618,15 @@ void TerminalSession::onClosed()
return;
}
+ auto isClosedAlready = _onClosedHandled.load();
+ if (isClosedAlready || !_onClosedHandled.compare_exchange_weak(isClosedAlready, true))
+ {
+ sessionLog()("onClosed called: thread {}, display {}", crispy::threadName(), _display ? "yes" : "no");
+ if (_display)
+ _display->closeDisplay();
+ return;
+ }
+
if (_app.dumpStateAtExit().has_value())
inspect();
else if (_display)
diff --git a/src/contour/contour.yml b/src/contour/contour.yml
index 6b623b862b..fe5ba09682 100644
--- a/src/contour/contour.yml
+++ b/src/contour/contour.yml
@@ -64,6 +64,9 @@ pty_buffer_size: 1048576
default_profile: main
+# Time in seconds to check for early threshold
+early_exit_threshold: 5
+
# Flag to determine whether to spawn new process or not when creating new terminal
# Default: false
spawn_new_process: false