TerminalSize (Windows): make it work when stdin or stdout is redirected

This commit is contained in:
李通洲
2024-06-26 10:50:25 +08:00
parent e9031171c0
commit e257f876ae
3 changed files with 37 additions and 13 deletions
+2 -1
View File
@@ -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
+23 -10
View File
@@ -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";
@@ -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;