diff --git a/CHANGELOG.md b/CHANGELOG.md index 816a2641c..cad3178e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,8 @@ Features: * Support GPU detection (SunOS) * Support GPU type detection with AMD GPU driver (GPU, Windows) * Add fast path of version and font detection for kitty (Terminal / TerminalFont) -* Make sure `stdin` and `stdout` are TTYs when querying terminal (Linux) +* Make sure `stdin` and `stdout` are TTYs when querying terminal + * So modules like `TerminalSize` should work when `stdin` or `stdout` is redirected * Add new JSON config option `general.preRun`, which is executed before fastfetch prints output. * It can be used to generate a temp logo file. For example ```jsonc diff --git a/src/common/io/io_windows.c b/src/common/io/io_windows.c index be8e7e573..fd6c22ce2 100644 --- a/src/common/io/io_windows.c +++ b/src/common/io/io_windows.c @@ -175,24 +175,37 @@ void ffListFilesRecursively(const char* path, bool pretty) const char* ffGetTerminalResponse(const char* request, const char* format, ...) { - if (instance.config.display.pipe) - return "Not supported in --pipe mode"; - HANDLE hInput = GetStdHandle(STD_INPUT_HANDLE); - DWORD prev_mode; - GetConsoleMode(hInput, &prev_mode); + FF_AUTO_CLOSE_FD HANDLE hConin = INVALID_HANDLE_VALUE; + DWORD inputMode; + if (!GetConsoleMode(hInput, &inputMode)) + { + hConin = CreateFileW(L"CONIN$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, NULL); + hInput = hConin; + } SetConsoleMode(hInput, 0); FlushConsoleInputBuffer(hInput); - DWORD bytes = 0; - WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), request, (DWORD) strlen(request), &bytes, NULL); + { + DWORD bytes = 0; + HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE); + FF_AUTO_CLOSE_FD HANDLE hConout = INVALID_HANDLE_VALUE; + DWORD outputMode; + if (!GetConsoleMode(hOutput, &outputMode)) + { + hConout = CreateFileW(L"CONOUT$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, NULL); + hOutput = hConout; + } + WriteFile(hOutput, "TEST\n", 5, &bytes, NULL); + WriteFile(hOutput, request, (DWORD) strlen(request), &bytes, NULL); + } while (true) { if (WaitForSingleObjectEx(hInput, FF_IO_TERM_RESP_WAIT_MS, TRUE) != WAIT_OBJECT_0) { - SetConsoleMode(hInput, prev_mode); + SetConsoleMode(hInput, inputMode); return "WaitForSingleObject() failed or timeout"; } @@ -213,10 +226,10 @@ const char* ffGetTerminalResponse(const char* request, const char* format, ...) } char buffer[512]; - bytes = 0; + DWORD bytes = 0; ReadFile(hInput, buffer, sizeof(buffer) - 1, &bytes, NULL); - SetConsoleMode(hInput, prev_mode); + SetConsoleMode(hInput, inputMode); if(bytes <= 0) return "ReadFile() failed"; diff --git a/src/detection/terminalsize/terminalsize_windows.c b/src/detection/terminalsize/terminalsize_windows.c index 4d2f6c83d..1264f0321 100644 --- a/src/detection/terminalsize/terminalsize_windows.c +++ b/src/detection/terminalsize/terminalsize_windows.c @@ -5,9 +5,19 @@ bool ffDetectTerminalSize(FFTerminalSizeResult* result) { + HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE); + FF_AUTO_CLOSE_FD HANDLE hConout = INVALID_HANDLE_VALUE; + { + DWORD outputMode; + if (!GetConsoleMode(hOutput, &outputMode)) + { + hConout = CreateFileW(L"CONOUT$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, NULL); + hOutput = hConout; + } + } { CONSOLE_SCREEN_BUFFER_INFO csbi; - if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi)) + if (GetConsoleScreenBufferInfo(hOutput, &csbi)) { result->columns = (uint16_t) (csbi.srWindow.Right - csbi.srWindow.Left + 1); result->rows = (uint16_t) (csbi.srWindow.Bottom - csbi.srWindow.Top + 1); @@ -23,7 +33,7 @@ bool ffDetectTerminalSize(FFTerminalSizeResult* result) { CONSOLE_FONT_INFO cfi; - if(GetCurrentConsoleFont(GetStdHandle(STD_OUTPUT_HANDLE), FALSE, &cfi)) // Only works for ConHost + if(GetCurrentConsoleFont(hOutput, FALSE, &cfi)) // Only works for ConHost { result->width = result->columns * (uint16_t) cfi.dwFontSize.X; result->height = result->rows * (uint16_t) cfi.dwFontSize.Y;