mirror of
https://github.com/neovim/neovim.git
synced 2026-04-18 13:30:42 +00:00
fix(channel): fix Ctrl-C handling regression in terminal
Problem: Normal Windows builtin-TUI startup spawns the embedded server as DETACHED_PROCESS, which breaks Ctrl-C delivery to :terminal jobs.
Solution: Restores the default behavior once the embedded server has a
console so terminal jobs inherit it.
(cherry picked from commit 8bb7533639)
This commit is contained in:
committed by
github-actions[bot]
parent
608d0e01ba
commit
319c031820
@@ -556,23 +556,24 @@ uint64_t channel_from_stdio(bool rpc, CallbackReader on_output, const char **err
|
||||
os_set_cloexec(stdin_dup_fd);
|
||||
stdout_dup_fd = os_dup(STDOUT_FILENO);
|
||||
os_set_cloexec(stdout_dup_fd);
|
||||
// :restart spawns a replacement server that must not borrow the parent
|
||||
// Nvim process console, because that parent process will soon exit.
|
||||
const bool restart_alloc_console = os_env_exists("__NVIM_RESTART_ALLOC_CONSOLE", true);
|
||||
if (restart_alloc_console) {
|
||||
os_unsetenv("__NVIM_RESTART_ALLOC_CONSOLE");
|
||||
}
|
||||
if (!GetConsoleWindow()) {
|
||||
if (restart_alloc_console) {
|
||||
AllocConsole();
|
||||
ShowWindow(GetConsoleWindow(), SW_HIDE);
|
||||
} else if (!AttachConsole(ATTACH_PARENT_PROCESS)) {
|
||||
// Borrow the parent's console so CONOUT$ resolves to the real terminal,
|
||||
// preserving io.stdout rendering (e.g. SIXEL/Kitty images). Only fall
|
||||
// back to a hidden AllocConsole when there is no parent console (e.g.
|
||||
// launched from a non-console parent).
|
||||
// Borrow the parent's console so CONOUT$ resolves to the real terminal,
|
||||
// preserving io.stdout rendering (e.g. SIXEL/Kitty images). Only fall
|
||||
// back to a hidden AllocConsole when there is no parent console (e.g.
|
||||
// launched from a non-console parent), or for the replacement server
|
||||
// spawned by :restart, because the parent Nvim process will soon exit.
|
||||
if (restart_alloc_console || !AttachConsole(ATTACH_PARENT_PROCESS)) {
|
||||
AllocConsole();
|
||||
ShowWindow(GetConsoleWindow(), SW_HIDE);
|
||||
}
|
||||
}
|
||||
os_enable_ctrl_c();
|
||||
os_replace_stdin_to_conin();
|
||||
os_replace_stdout_and_stderr_to_conout();
|
||||
}
|
||||
|
||||
@@ -14,6 +14,16 @@ static HWND hWnd = NULL;
|
||||
static HICON hOrigIconSmall = NULL;
|
||||
static HICON hOrigIcon = NULL;
|
||||
|
||||
/// Re-enable normal Ctrl-C processing after detached startup.
|
||||
///
|
||||
/// On Windows, UV_PROCESS_DETACHED implies CREATE_NEW_PROCESS_GROUP, which
|
||||
/// disables Ctrl-C handling for the new process. Restore the default behavior
|
||||
/// once the embedded server has a console so terminal jobs inherit it.
|
||||
void os_enable_ctrl_c(void)
|
||||
{
|
||||
SetConsoleCtrlHandler(NULL, FALSE);
|
||||
}
|
||||
|
||||
int os_open_conin_fd(void)
|
||||
{
|
||||
const HANDLE conin_handle = CreateFile("CONIN$",
|
||||
@@ -65,6 +75,7 @@ void os_swap_to_hidden_console(void)
|
||||
FreeConsole();
|
||||
AllocConsole();
|
||||
ShowWindow(GetConsoleWindow(), SW_HIDE);
|
||||
os_enable_ctrl_c();
|
||||
os_replace_stdin_to_conin();
|
||||
os_replace_stdout_and_stderr_to_conout();
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@ local ok = t.ok
|
||||
local rmdir = n.rmdir
|
||||
local new_pipename = n.new_pipename
|
||||
local pesc = vim.pesc
|
||||
local is_os = t.is_os
|
||||
local skip = t.skip
|
||||
local set_session = n.set_session
|
||||
local async_meths = n.async_meths
|
||||
local expect_msg_seq = n.expect_msg_seq
|
||||
@@ -116,6 +118,10 @@ describe("preserve and (R)ecover with custom 'directory'", function()
|
||||
end)
|
||||
|
||||
it('killing TUI process without :preserve #22096', function()
|
||||
-- Windows(#38669): inner server could attach to the outer Nvim terminal's console
|
||||
-- and die abruptly when the outer terminal job closed, leaving an unreadable swapfile
|
||||
skip(is_os('win'), 'unreadable swapfile on Windows after TUI process exit')
|
||||
|
||||
local screen0 = Screen.new()
|
||||
local child_server = new_pipename()
|
||||
fn.jobstart({ nvim_prog, '-u', 'NONE', '-i', 'NONE', '--listen', child_server }, {
|
||||
|
||||
Reference in New Issue
Block a user