From e0ddf93bb013a7f38a32a9a326466182d91f8654 Mon Sep 17 00:00:00 2001 From: Emanuel Krollmann <115734183+Sodastream11@users.noreply.github.com> Date: Mon, 2 Jun 2025 00:23:42 +0200 Subject: [PATCH 1/2] fix(windows): don't set window icon on SIGHUP #34260 Problem: When using conhost and pressing the 'x' button to close it while nvim is open, nvim hangs up while trying to reset the window icon, causing a big delay before the terminal actually closes. #34171 Solution: Set the window handle to NULL after receiving SIGHUP so that nvim will not try resetting the icon. (cherry picked from commit 52991d8728c876366cd28f75be29ee579a0a8605) --- src/nvim/os/os_win_console.c | 5 +++++ src/nvim/os/signal.c | 10 +++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/nvim/os/os_win_console.c b/src/nvim/os/os_win_console.c index 953d291290..99fd50a040 100644 --- a/src/nvim/os/os_win_console.c +++ b/src/nvim/os/os_win_console.c @@ -29,6 +29,11 @@ int os_open_conin_fd(void) return conin_fd; } +void os_clear_hwnd(void) +{ + hWnd = NULL; +} + void os_replace_stdin_to_conin(void) { close(STDIN_FILENO); diff --git a/src/nvim/os/signal.c b/src/nvim/os/signal.c index 11f99d0a0f..a7c57fff7c 100644 --- a/src/nvim/os/signal.c +++ b/src/nvim/os/signal.c @@ -22,6 +22,11 @@ #endif static SignalWatcher spipe, shup, squit, sterm, susr1, swinch; + +#ifdef MSWIN +# include "nvim/os/os_win_console.h" +#endif + #ifdef SIGPWR static SignalWatcher spwr; #endif @@ -195,12 +200,15 @@ static void on_signal(SignalWatcher *handle, int signum, void *data) case SIGPIPE: // Ignore break; +#endif + case SIGHUP: +#ifdef MSWIN + os_clear_hwnd(); #endif case SIGTERM: #ifdef SIGQUIT case SIGQUIT: #endif - case SIGHUP: if (!rejecting_deadly) { deadly_signal(signum); } From 33cec55a26dca7fed0a04cf7a7ea553e17c0eb06 Mon Sep 17 00:00:00 2001 From: Emanuel Krollmann <115734183+Sodastream11@users.noreply.github.com> Date: Wed, 4 Jun 2025 16:11:01 +0200 Subject: [PATCH 2/2] refactor(windows): redundant icon messages #34274 Problem: Two separate window messages are used to get the original console icon and set a new one on windows, although the `WM_SETICON` message returns the original icon itself. Solution: Replace the two `WM_GETICON` messages with two `WM_SETICON` messages, save the return values and remove the call to `os_icon_set`. Also, replace `os_icon_set` with `os_icon_reset` as its only usage is now resetting the icon to the original one. (cherry picked from commit 7e393ff4f24b2e9d32bc6a008b2b8549f473aba5) --- src/nvim/main.c | 2 +- src/nvim/os/os_win_console.c | 23 +++++++++-------------- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/src/nvim/main.c b/src/nvim/main.c index 50677607eb..6e75982927 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -811,7 +811,7 @@ void getout(int exitval) #ifdef MSWIN // Restore Windows console icon before exiting. - os_icon_set(NULL, NULL); + os_icon_reset(); os_title_reset(); #endif diff --git a/src/nvim/os/os_win_console.c b/src/nvim/os/os_win_console.c index 99fd50a040..8c587c3d02 100644 --- a/src/nvim/os/os_win_console.c +++ b/src/nvim/os/os_win_console.c @@ -31,7 +31,7 @@ int os_open_conin_fd(void) void os_clear_hwnd(void) { - hWnd = NULL; + hWnd = NULL; } void os_replace_stdin_to_conin(void) @@ -58,20 +58,17 @@ void os_replace_stdout_and_stderr_to_conout(void) assert(conerr_fd == STDERR_FILENO); } -/// Sets Windows console icon, or pass NULL to restore original icon. -void os_icon_set(HICON hIconSmall, HICON hIcon) -{ +/// Resets Windows console icon if we got an original one on startup. +void os_icon_reset(void) { if (hWnd == NULL) { return; } - hIconSmall = hIconSmall ? hIconSmall : hOrigIconSmall; - hIcon = hIcon ? hIcon : hOrigIcon; - if (hIconSmall != NULL) { - SendMessage(hWnd, WM_SETICON, (WPARAM)ICON_SMALL, (LPARAM)hIconSmall); + if (hOrigIconSmall) { + SendMessage(hWnd, WM_SETICON, (WPARAM)ICON_SMALL, (LPARAM)hOrigIconSmall); } - if (hIcon != NULL) { - SendMessage(hWnd, WM_SETICON, (WPARAM)ICON_BIG, (LPARAM)hIcon); + if (hOrigIcon) { + SendMessage(hWnd, WM_SETICON, (WPARAM)ICON_BIG, (LPARAM)hOrigIcon); } } @@ -83,9 +80,6 @@ void os_icon_init(void) if ((hWnd = GetConsoleWindow()) == NULL) { return; } - // Save Windows console icon to be restored later. - hOrigIconSmall = (HICON)SendMessage(hWnd, WM_GETICON, (WPARAM)ICON_SMALL, (LPARAM)0); - hOrigIcon = (HICON)SendMessage(hWnd, WM_GETICON, (WPARAM)ICON_BIG, (LPARAM)0); const char *vimruntime = os_getenv("VIMRUNTIME"); if (vimruntime != NULL) { @@ -95,7 +89,8 @@ void os_icon_init(void) } else { HICON hVimIcon = LoadImage(NULL, NameBuff, IMAGE_ICON, 64, 64, LR_LOADFROMFILE | LR_LOADMAP3DCOLORS); - os_icon_set(hVimIcon, hVimIcon); + hOrigIconSmall = (HICON)SendMessage(hWnd, WM_SETICON, (WPARAM)ICON_SMALL, (LPARAM)hVimIcon); + hOrigIcon = (HICON)SendMessage(hWnd, WM_SETICON, (WPARAM)ICON_BIG, (LPARAM)hVimIcon); } } }