Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package fastfetch for openSUSE:Factory checked in at 2025-12-22 22:48:53 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/fastfetch (Old) and /work/SRC/openSUSE:Factory/.fastfetch.new.1928 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "fastfetch" Mon Dec 22 22:48:53 2025 rev:83 rq:1323858 version:2.56.1 Changes: -------- --- /work/SRC/openSUSE:Factory/fastfetch/fastfetch.changes 2025-12-09 12:57:53.062952091 +0100 +++ /work/SRC/openSUSE:Factory/.fastfetch.new.1928/fastfetch.changes 2025-12-22 22:51:00.093379032 +0100 @@ -1,0 +2,16 @@ +Sun Dec 21 01:44:36 UTC 2025 - RN <[email protected]> + +- Update to version 2.56.1: + * Packaging: update debian stuff + * JsonSchema: refines comments [ci skip] + * Packages (Windows): fixes possible UB + * Memory (macOS): Refines Memory usage detection on macOS to match + Activity Monitor more closely + * Doc: update changelog + * Host (macOS): prefers `hw.product` than `hw.model` + * CPU (SunOS): adds `const` for consistancy + * IO (Windows): removes unneeded null terminator appending + * Chore (Windows): Standardize windows header casing. (#2096) + [ci skip] + +------------------------------------------------------------------- Old: ---- fastfetch-2.56.0.obscpio New: ---- fastfetch-2.56.1.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ fastfetch.spec ++++++ --- /var/tmp/diff_new_pack.AKYPt0/_old 2025-12-22 22:51:02.709486815 +0100 +++ /var/tmp/diff_new_pack.AKYPt0/_new 2025-12-22 22:51:02.721487310 +0100 @@ -17,7 +17,7 @@ Name: fastfetch -Version: 2.56.0 +Version: 2.56.1 Release: 0 Summary: Neofetch-like tool written mostly in C License: MIT ++++++ _service ++++++ --- /var/tmp/diff_new_pack.AKYPt0/_old 2025-12-22 22:51:02.901494726 +0100 +++ /var/tmp/diff_new_pack.AKYPt0/_new 2025-12-22 22:51:02.933496044 +0100 @@ -6,7 +6,7 @@ <param name="scm">git</param> <param name="version">master</param> <param name="versionformat">@PARENT_TAG@</param> - <param name="revision">2.56.0</param> + <param name="revision">2.56.1</param> <!-- <param name="changesgenerate">enable</param> --> <!-- <param name="changesauthor">RN</param> --> </service> ++++++ fastfetch-2.56.0.obscpio -> fastfetch-2.56.1.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fastfetch-2.56.0/CHANGELOG.md new/fastfetch-2.56.1/CHANGELOG.md --- old/fastfetch-2.56.0/CHANGELOG.md 2025-12-05 15:42:51.000000000 +0100 +++ new/fastfetch-2.56.1/CHANGELOG.md 2025-12-18 08:00:51.000000000 +0100 @@ -1,3 +1,19 @@ +# 2.56.1 + +Features: +* Improves compatibility with KDE Plasma 6.5 (#2093, Display) +* Adds a `tempSensor` option to specify the sensor name used for CPU temperature detection (CPU) + * Example: `{ "type": "cpu", "tempSensor": "hwmon0" /* Use /sys/class/hwmon/hwmon0 for temperature detection */ }` +* Refines Memory usage detection on macOS to match Activity Monitor more closely (Memory, macOS) +* Minor optimizations + +Bugfixes: +* Fixes cache line size detection (CPU, macOS) + +Logos: +* Removes Opak +* Updates GXDE + # 2.56.0 Features: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fastfetch-2.56.0/CMakeLists.txt new/fastfetch-2.56.1/CMakeLists.txt --- old/fastfetch-2.56.0/CMakeLists.txt 2025-12-05 15:42:51.000000000 +0100 +++ new/fastfetch-2.56.1/CMakeLists.txt 2025-12-18 08:00:51.000000000 +0100 @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url project(fastfetch - VERSION 2.56.0 + VERSION 2.56.1 LANGUAGES C DESCRIPTION "Fast neofetch-like system information tool" HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fastfetch-2.56.0/README.md new/fastfetch-2.56.1/README.md --- old/fastfetch-2.56.0/README.md 2025-12-05 15:42:51.000000000 +0100 +++ new/fastfetch-2.56.1/README.md 2025-12-18 08:00:51.000000000 +0100 @@ -13,7 +13,7 @@ [](https://deepwiki.com/fastfetch-cli/fastfetch) [](README-cn.md) -Fastfetch is a [neofetch](https://github.com/dylanaraps/neofetch)-like tool for fetching system information and displaying it in a visually appealing way. It is written mainly in C, with a focus on performance and customizability. Currently, it supports Linux, macOS, Windows 7+, Android, FreeBSD, OpenBSD, NetBSD, DragonFly, Haiku, and SunOS. +Fastfetch is a [neofetch](https://github.com/dylanaraps/neofetch)-like tool for fetching system information and displaying it in a visually appealing way. It is written mainly in C, with a focus on performance and customizability. Currently, it supports Linux, macOS, Windows 7+, Android, FreeBSD, OpenBSD, NetBSD, DragonFly, Haiku, and illumos (SunOS). <img src="screenshots/example1.png" width="49%" align="left" /> <img src="https://upload.wikimedia.org/wikipedia/commons/2/24/Transparent_Square_Tiles_Texture.png" width="49%" height="16px" align="left" /> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fastfetch-2.56.0/debian/changelog.tpl new/fastfetch-2.56.1/debian/changelog.tpl --- old/fastfetch-2.56.0/debian/changelog.tpl 2025-12-05 15:42:51.000000000 +0100 +++ new/fastfetch-2.56.1/debian/changelog.tpl 2025-12-18 08:00:51.000000000 +0100 @@ -1,3 +1,15 @@ +fastfetch (2.56.1~#UBUNTU_CODENAME#) #UBUNTU_CODENAME#; urgency=medium + + * Update to 2.56.1 + + -- Carter Li <[email protected]> Thu, 18 Dec 2025 14:57:36 +0800 + +fastfetch (2.56.0~#UBUNTU_CODENAME#) #UBUNTU_CODENAME#; urgency=medium + + * Update to 2.56.0 + + -- Carter Li <[email protected]> Mon, 08 Dec 2025 09:21:58 +0800 + fastfetch (2.55.1~#UBUNTU_CODENAME#) #UBUNTU_CODENAME#; urgency=medium * Update to 2.55.1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fastfetch-2.56.0/doc/json_schema.json new/fastfetch-2.56.1/doc/json_schema.json --- old/fastfetch-2.56.0/doc/json_schema.json 2025-12-05 15:42:51.000000000 +0100 +++ new/fastfetch-2.56.1/doc/json_schema.json 2025-12-18 08:00:51.000000000 +0100 @@ -1880,6 +1880,10 @@ "temp": { "$ref": "#/$defs/temperature" }, + "tempSensor": { + "description": "Set the temperature sensor to use for CPU temperature detection\n* Linux: `hwmon` or `thermal` path name (eg. `hwmon0`, `thermal_zone0)`\n* macOS: SMC sensor key (eg. `Tp01`)\n* Windows: thermal zone key (eg. `\\_TZ.CPUZ`)\n* FreeBSD: sysctl key (eg. `dev.cpu.0.temperature`)\n* NetBSD: sysmon sensor key (eg. `coretemp0`)", + "type": "string" + }, "showPeCoreCount": { "description": "Detect and display CPU frequency of different core types (eg. Pcore and Ecore) if supported", "type": "boolean", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fastfetch-2.56.0/src/common/io/io.h new/fastfetch-2.56.1/src/common/io/io.h --- old/fastfetch-2.56.0/src/common/io/io.h 2025-12-05 15:42:51.000000000 +0100 +++ new/fastfetch-2.56.1/src/common/io/io.h 2025-12-18 08:00:51.000000000 +0100 @@ -83,6 +83,13 @@ FF_C_NONNULL(2, 3) bool ffAppendFileBufferRelative(FFNativeFD dfd, const char* fileName, FFstrbuf* buffer); +FF_C_NONNULL(2) +static inline bool ffReadFDBuffer(FFNativeFD fd, FFstrbuf* buffer) +{ + ffStrbufClear(buffer); + return ffAppendFDBuffer(fd, buffer); +} + FF_C_NONNULL(1, 2) static inline bool ffReadFileBuffer(const char* fileName, FFstrbuf* buffer) { @@ -254,4 +261,5 @@ #ifdef _WIN32 // Only O_RDONLY is supported HANDLE openat(HANDLE dfd, const char* fileName, bool directory); +HANDLE openatW(HANDLE dfd, const wchar_t* fileName, uint16_t fileNameLen, bool directory); #endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fastfetch-2.56.0/src/common/io/io_windows.c new/fastfetch-2.56.1/src/common/io/io_windows.c --- old/fastfetch-2.56.0/src/common/io/io_windows.c 2025-12-05 15:42:51.000000000 +0100 +++ new/fastfetch-2.56.1/src/common/io/io_windows.c 2025-12-18 08:00:51.000000000 +0100 @@ -3,8 +3,8 @@ #include "util/stringUtils.h" #include <windows.h> +#include "util/windows/nt.h" #include <ntstatus.h> -#include <winternl.h> static void createSubfolders(const char* fileName) { @@ -102,31 +102,48 @@ return ffAppendFDBuffer(handle, buffer); } -HANDLE openat(HANDLE dfd, const char* fileName, bool directory) +HANDLE openatW(HANDLE dfd, const wchar_t* fileName, uint16_t fileNameLen, bool directory) { - NTSTATUS ret; - UNICODE_STRING fileNameW; - ret = RtlAnsiStringToUnicodeString(&fileNameW, &(ANSI_STRING) { - .Length = (USHORT) strlen(fileName), - .Buffer = (PCHAR) fileName - }, TRUE); - if (!NT_SUCCESS(ret)) return INVALID_HANDLE_VALUE; + assert(fileNameLen <= 0x7FFF); - FF_AUTO_CLOSE_FD HANDLE hFile; + HANDLE hFile; IO_STATUS_BLOCK iosb = {}; - ret = NtOpenFile(&hFile, FILE_READ_DATA | SYNCHRONIZE, &(OBJECT_ATTRIBUTES) { - .Length = sizeof(OBJECT_ATTRIBUTES), - .RootDirectory = dfd, - .ObjectName = &fileNameW, - }, &iosb, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT | (directory ? FILE_DIRECTORY_FILE : FILE_NON_DIRECTORY_FILE)); - RtlFreeUnicodeString(&fileNameW); - - if(!NT_SUCCESS(ret) || iosb.Information != FILE_OPENED) + if(!NT_SUCCESS(NtOpenFile(&hFile, + (directory ? FILE_LIST_DIRECTORY | FILE_TRAVERSE : FILE_READ_DATA | FILE_READ_EA) | FILE_READ_ATTRIBUTES | SYNCHRONIZE, &(OBJECT_ATTRIBUTES) { + .Length = sizeof(OBJECT_ATTRIBUTES), + .RootDirectory = dfd, + .ObjectName = &(UNICODE_STRING) { + .Buffer = (PWSTR) fileName, + .Length = fileNameLen * (USHORT) sizeof(wchar_t), + .MaximumLength = (fileNameLen + 1) * (USHORT) sizeof(wchar_t), + }, + .Attributes = OBJ_CASE_INSENSITIVE, + }, + &iosb, + FILE_SHARE_READ | (directory ? FILE_SHARE_WRITE | FILE_SHARE_DELETE : 0), + FILE_SYNCHRONOUS_IO_NONALERT | (directory ? FILE_DIRECTORY_FILE : FILE_NON_DIRECTORY_FILE) + ))) return INVALID_HANDLE_VALUE; return hFile; } +HANDLE openat(HANDLE dfd, const char* fileName, bool directory) +{ + wchar_t fileNameW[MAX_PATH]; + int len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, fileName, -1, fileNameW, ARRAY_SIZE(fileNameW)); + if (len == 0) return INVALID_HANDLE_VALUE; + // Implies `fileNameW[len] = L'\0';` and `len` includes the null terminator + + for (int i = 0; i < len - 1; ++i) + { + if (fileNameW[i] == L'/') + fileNameW[i] = L'\\'; + } + + return openatW(dfd, fileNameW, (uint16_t)(len - 1), directory); +} + bool ffAppendFileBufferRelative(HANDLE dfd, const char* fileName, FFstrbuf* buffer) { HANDLE FF_AUTO_CLOSE_FD fd = openat(dfd, fileName, false); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fastfetch-2.56.0/src/detection/brightness/brightness_linux.c new/fastfetch-2.56.1/src/detection/brightness/brightness_linux.c --- old/fastfetch-2.56.0/src/detection/brightness/brightness_linux.c 2025-12-05 15:42:51.000000000 +0100 +++ new/fastfetch-2.56.1/src/detection/brightness/brightness_linux.c 2025-12-18 08:00:51.000000000 +0100 @@ -41,7 +41,7 @@ FFBrightnessResult* brightness = (FFBrightnessResult*) ffListAdd(result); ffStrbufSubstrBeforeLastC(&backlightDir, '/'); ffStrbufAppendS(&backlightDir, "/device"); - ffStrbufInitA(&brightness->name, PATH_MAX + 1); + ffStrbufInitA(&brightness->name, PATH_MAX); if(realpath(backlightDir.chars, brightness->name.chars)) { ffStrbufRecalculateLength(&brightness->name); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fastfetch-2.56.0/src/detection/cpu/cpu_apple.c new/fastfetch-2.56.1/src/detection/cpu/cpu_apple.c --- old/fastfetch-2.56.0/src/detection/cpu/cpu_apple.c 2025-12-05 15:42:51.000000000 +0100 +++ new/fastfetch-2.56.1/src/detection/cpu/cpu_apple.c 2025-12-18 08:00:51.000000000 +0100 @@ -3,26 +3,34 @@ #include "util/apple/smc_temps.h" #include "util/stringUtils.h" -static double detectCpuTemp(const FFstrbuf* cpuName) +static double detectCpuTemp(const FFCPUOptions* options, const FFstrbuf* cpuName) { double result = 0; const char* error = NULL; - if (ffStrbufStartsWithS(cpuName, "Apple M")) + + if (options->tempSensor.length) + { + error = ffDetectSmcSpecificTemp(options->tempSensor.chars, &result); + } + else { - switch (strtol(cpuName->chars + strlen("Apple M"), NULL, 10)) + if (ffStrbufStartsWithS(cpuName, "Apple M")) { - case 1: error = ffDetectSmcTemps(FF_TEMP_CPU_M1X, &result); break; - case 2: error = ffDetectSmcTemps(FF_TEMP_CPU_M2X, &result); break; - case 3: error = ffDetectSmcTemps(FF_TEMP_CPU_M3X, &result); break; - case 4: error = ffDetectSmcTemps(FF_TEMP_CPU_M4X, &result); break; - default: error = "Unsupported Apple Silicon CPU"; + switch (strtol(cpuName->chars + strlen("Apple M"), NULL, 10)) + { + case 1: error = ffDetectSmcTemps(FF_TEMP_CPU_M1X, &result); break; + case 2: error = ffDetectSmcTemps(FF_TEMP_CPU_M2X, &result); break; + case 3: error = ffDetectSmcTemps(FF_TEMP_CPU_M3X, &result); break; + case 4: error = ffDetectSmcTemps(FF_TEMP_CPU_M4X, &result); break; + default: error = "Unsupported Apple Silicon CPU"; + } } + else // PPC? + error = ffDetectSmcTemps(FF_TEMP_CPU_X64, &result); } - else // PPC? - error = ffDetectSmcTemps(FF_TEMP_CPU_X64, &result); - if(error) + if (error) return FF_CPU_TEMP_UNSET; return result; @@ -130,7 +138,7 @@ detectFrequency(cpu); if (options->showPeCoreCount) detectCoreCount(cpu); - cpu->temperature = options->temp ? detectCpuTemp(&cpu->name) : FF_CPU_TEMP_UNSET; + cpu->temperature = options->temp ? detectCpuTemp(options, &cpu->name) : FF_CPU_TEMP_UNSET; return NULL; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fastfetch-2.56.0/src/detection/cpu/cpu_bsd.c new/fastfetch-2.56.1/src/detection/cpu/cpu_bsd.c --- old/fastfetch-2.56.0/src/detection/cpu/cpu_bsd.c 2025-12-05 15:42:51.000000000 +0100 +++ new/fastfetch-2.56.1/src/detection/cpu/cpu_bsd.c 2025-12-18 08:00:51.000000000 +0100 @@ -8,22 +8,26 @@ #define FF_HAVE_CPUSET 1 #endif -static const char* detectCpuTemp(double* current) +static const char* detectCpuTemp(const FFCPUOptions* options, double* current) { - int temp = ffSysctlGetInt("dev.cpu.0.temperature", -999999); - if (temp == -999999) - return "ffSysctlGetInt(\"dev.cpu.0.temperature\") failed"; - - // In tenth of degrees Kelvin - *current = (double) temp / 10 - 273.15; - return NULL; -} - -static const char* detectThermalTemp(double* current) -{ - int temp = ffSysctlGetInt("hw.acpi.thermal.tz0.temperature", -999999); - if (temp == -999999) - return "ffSysctlGetInt(\"hw.acpi.thermal.tz0.temperature\") failed"; + int temp; + if (options->tempSensor.length > 0) + { + temp = ffSysctlGetInt(options->tempSensor.chars, -999999); + if (temp == -999999) + return "ffSysctlGetInt(options->tempSensor) failed"; + } + else + { + temp = ffSysctlGetInt("dev.cpu.0.temperature", -999999); + if (temp == -999999) + { + // Thermal zone temperature + temp = ffSysctlGetInt("hw.acpi.thermal.tz0.temperature", -999999); + if (temp == -999999) + return "ffSysctlGetInt(\"dev.cpu.0.temperature\" or \"hw.acpi.thermal.tz0.temperature\") failed"; + } + } // In tenth of degrees Kelvin *current = (double) temp / 10 - 273.15; @@ -94,11 +98,7 @@ cpu->temperature = FF_CPU_TEMP_UNSET; - if (options->temp) - { - if (detectCpuTemp(&cpu->temperature) != NULL) - detectThermalTemp(&cpu->temperature); - } + if (options->temp) detectCpuTemp(options, &cpu->temperature); cpu->numaNodes = (uint16_t) ffSysctlGetInt("vm.ndomains", 0); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fastfetch-2.56.0/src/detection/cpu/cpu_linux.c new/fastfetch-2.56.1/src/detection/cpu/cpu_linux.c --- old/fastfetch-2.56.0/src/detection/cpu/cpu_linux.c 2025-12-05 15:42:51.000000000 +0100 +++ new/fastfetch-2.56.1/src/detection/cpu/cpu_linux.c 2025-12-18 08:00:51.000000000 +0100 @@ -4,6 +4,7 @@ #include "common/properties.h" #include "util/mallocHelper.h" #include "util/stringUtils.h" +#include "util/path.h" #include <sys/sysinfo.h> #include <stdlib.h> @@ -13,6 +14,22 @@ #define FF_CPUINFO_PATH "/proc/cpuinfo" +#ifndef O_PATH +#define O_PATH 0 +#endif + +static double readTempFile(int dfd, const char* filename, FFstrbuf* buffer) +{ + if (filename ? !ffReadFileBufferRelative(dfd, filename, buffer) : !ffReadFDBuffer(dfd, buffer)) + return FF_CPU_TEMP_UNSET; + + double value = ffStrbufToDouble(buffer, FF_CPU_TEMP_UNSET); // millidegree Celsius + if (value == FF_CPU_TEMP_UNSET) + return FF_CPU_TEMP_UNSET; + + return value / 1000.; +} + static double parseTZDir(int dfd, FFstrbuf* buffer) { if (!ffReadFileBufferRelative(dfd, "type", buffer)) @@ -26,18 +43,12 @@ true ) return FF_CPU_TEMP_UNSET; - if (!ffReadFileBufferRelative(dfd, "temp", buffer)) - return FF_CPU_TEMP_UNSET; - - double value = ffStrbufToDouble(buffer, FF_CPU_TEMP_UNSET);// millidegree Celsius - if (value == FF_CPU_TEMP_UNSET) - return FF_CPU_TEMP_UNSET; - - return value / 1000.; + return readTempFile(dfd, "temp", buffer); } static double parseHwmonDir(int dfd, FFstrbuf* buffer) { + //https://www.kernel.org/doc/Documentation/hwmon/sysfs-interface if (!ffReadFileBufferRelative(dfd, "name", buffer)) return FF_CPU_TEMP_UNSET; @@ -53,25 +64,64 @@ true ) return FF_CPU_TEMP_UNSET; - //https://www.kernel.org/doc/Documentation/hwmon/sysfs-interface - if (!ffReadFileBufferRelative(dfd, "temp1_input", buffer)) - return FF_CPU_TEMP_UNSET; - - double value = ffStrbufToDouble(buffer, FF_CPU_TEMP_UNSET);// millidegree Celsius - if (value == FF_CPU_TEMP_UNSET) - return FF_CPU_TEMP_UNSET; - - return value / 1000.; + return readTempFile(dfd, "temp1_input", buffer); } -static double detectCPUTemp(void) +static double detectCPUTemp(const FFCPUOptions* options) { FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate(); + + if (options->tempSensor.length > 0) + { + FF_AUTO_CLOSE_FD int subfd = -1; + const char* fileName = NULL; + if (ffStrbufStartsWithS(&options->tempSensor, "hwmon") && ffCharIsDigit(options->tempSensor.chars[strlen("hwmon")])) + { + FF_AUTO_CLOSE_FD int dfd = open("/sys/class/hwmon/", O_PATH | O_CLOEXEC); + subfd = openat(dfd, options->tempSensor.chars, O_RDONLY | O_DIRECTORY | O_CLOEXEC); + if (subfd >= 0) + fileName = "temp1_input"; + else + subfd = openat(dfd, options->tempSensor.chars, O_RDONLY | O_CLOEXEC); + } + else if (ffStrbufStartsWithS(&options->tempSensor, "thermal_zone") && ffCharIsDigit(options->tempSensor.chars[strlen("thermal_zone")])) + { + FF_AUTO_CLOSE_FD int dfd = open("/sys/class/thermal/", O_PATH | O_CLOEXEC); + subfd = openat(dfd, options->tempSensor.chars, O_RDONLY | O_DIRECTORY | O_CLOEXEC); + if (subfd >= 0) + fileName = "temp"; + else + subfd = openat(dfd, options->tempSensor.chars, O_RDONLY | O_CLOEXEC); + } + else if (ffStrbufStartsWithS(&options->tempSensor, "cputemp.") && ffCharIsDigit(options->tempSensor.chars[strlen("cputemp.")])) + { + FF_AUTO_CLOSE_FD int dfd = open("/sys/class/platform/", O_PATH | O_CLOEXEC); + subfd = openat(dfd, options->tempSensor.chars, O_RDONLY | O_DIRECTORY | O_CLOEXEC); + if (subfd >= 0) + fileName = "temp1_input"; + else + subfd = openat(dfd, options->tempSensor.chars, O_RDONLY | O_CLOEXEC); + } + else if (ffIsAbsolutePath(options->tempSensor.chars)) + { + subfd = open(options->tempSensor.chars, O_RDONLY | O_DIRECTORY | O_CLOEXEC); + if (subfd >= 0) + fileName = "temp1_input"; + else + subfd = open(options->tempSensor.chars, O_RDONLY | O_CLOEXEC); + } + if (subfd < 0) + return FF_CPU_TEMP_UNSET; + + return readTempFile(subfd, fileName, &buffer); + } + { FF_AUTO_CLOSE_DIR DIR* dirp = opendir("/sys/class/hwmon/"); if(dirp) { int dfd = dirfd(dirp); + struct dirent* entry; while((entry = readdir(dirp)) != NULL) { @@ -816,9 +866,9 @@ char* pend; unsigned long id = strtoul(p, &pend, 10); if (__builtin_expect(id > 64, false)) - high |= 1 << (id - 64); + high |= 1UL << (id - 64); else - low |= 1 << id; + low |= 1UL << id; p = pend; } @@ -902,7 +952,7 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu) { - cpu->temperature = options->temp ? detectCPUTemp() : FF_CPU_TEMP_UNSET; + cpu->temperature = options->temp ? detectCPUTemp(options) : FF_CPU_TEMP_UNSET; #if __x86_64__ || __i386__ return detectCPUX86(options, cpu); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fastfetch-2.56.0/src/detection/cpu/cpu_nbsd.c new/fastfetch-2.56.1/src/detection/cpu/cpu_nbsd.c --- old/fastfetch-2.56.0/src/detection/cpu/cpu_nbsd.c 2025-12-05 15:42:51.000000000 +0100 +++ new/fastfetch-2.56.1/src/detection/cpu/cpu_nbsd.c 2025-12-18 08:00:51.000000000 +0100 @@ -16,7 +16,7 @@ prop_object_release(*pdict); } -static const char* detectCpuTemp(double* current) +static const char* detectCpuTemp(const FFCPUOptions* options, double* current) { FF_AUTO_CLOSE_FD int fd = open(_PATH_SYSMON, O_RDONLY | O_CLOEXEC); if (fd < 0) return "open(_PATH_SYSMON, O_RDONLY | O_CLOEXEC) failed"; @@ -25,11 +25,21 @@ if (prop_dictionary_recv_ioctl(fd, ENVSYS_GETDICTIONARY, &root) < 0) return "prop_dictionary_recv_ioctl(ENVSYS_GETDICTIONARY) failed"; - prop_array_t array = prop_dictionary_get(root, "coretemp0"); - if (!array) array = prop_dictionary_get(root, "amdzentemp0"); - if (!array) array = prop_dictionary_get(root, "viac7temp0"); - if (!array) array = prop_dictionary_get(root, "acpitz0"); // Thermal Zones - if (!array) return "No temp data found in root dictionary"; + prop_array_t array; + + if (options->tempSensor.length > 0) + { + array = prop_dictionary_get(root, options->tempSensor.chars); + if (!array) return "No temp data found in specified sensor"; + } + else + { + array = prop_dictionary_get(root, "coretemp0"); + if (!array) array = prop_dictionary_get(root, "amdzentemp0"); + if (!array) array = prop_dictionary_get(root, "viac7temp0"); + if (!array) array = prop_dictionary_get(root, "acpitz0"); // Thermal Zones + if (!array) return "No temp data found in root dictionary"; + } if (prop_array_count(array) != 2) return "Unexpected `xtemp0` data"; @@ -73,7 +83,7 @@ cpu->temperature = FF_CPU_TEMP_UNSET; - if (options->temp) detectCpuTemp(&cpu->temperature); + if (options->temp) detectCpuTemp(options, &cpu->temperature); return NULL; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fastfetch-2.56.0/src/detection/cpu/cpu_obsd.c new/fastfetch-2.56.1/src/detection/cpu/cpu_obsd.c --- old/fastfetch-2.56.0/src/detection/cpu/cpu_obsd.c 2025-12-05 15:42:51.000000000 +0100 +++ new/fastfetch-2.56.1/src/detection/cpu/cpu_obsd.c 2025-12-18 08:00:51.000000000 +0100 @@ -6,7 +6,7 @@ #include <sys/time.h> #include <sys/sensors.h> -static const char* detectCPUTemp(FFCPUResult* cpu) +static const char* detectCPUTemp(const FFCPUOptions* options, FFCPUResult* cpu) { int mib[5] = {CTL_HW, HW_SENSORS, 0, SENSOR_TEMP, 0}; @@ -23,8 +23,16 @@ return "sysctl(sensordev) failed"; } - if (!ffStrStartsWith(sensordev.xname, "cpu")) - continue; + if (options->tempSensor.length > 0) + { + if (!ffStrbufEqualS(&options->tempSensor, sensordev.xname)) + continue; + } + else + { + if (!ffStrStartsWith(sensordev.xname, "cpu")) + continue; + } for (mib[4] = 0; mib[4] < sensordev.maxnumt[SENSOR_TEMP]; mib[4]++) { @@ -62,7 +70,7 @@ if (cpuspeed > cpu->frequencyBase) cpu->frequencyBase = cpuspeed; cpu->temperature = FF_CPU_TEMP_UNSET; - if (options->temp) detectCPUTemp(cpu); + if (options->temp) detectCPUTemp(options, cpu); return NULL; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fastfetch-2.56.0/src/detection/cpu/cpu_sunos.c new/fastfetch-2.56.1/src/detection/cpu/cpu_sunos.c --- old/fastfetch-2.56.0/src/detection/cpu/cpu_sunos.c 2025-12-05 15:42:51.000000000 +0100 +++ new/fastfetch-2.56.1/src/detection/cpu/cpu_sunos.c 2025-12-18 08:00:51.000000000 +0100 @@ -3,10 +3,15 @@ #include "util/stringUtils.h" #include <kstat.h> -static const char* detectCPUTempByKstat(kstat_ctl_t* kc, FFCPUResult* cpu) +static const char* detectCPUTempByKstat(const FFCPUOptions* options, kstat_ctl_t* kc, FFCPUResult* cpu) { const char* possibleModules[] = {"temperature", "cpu_temp", "acpi_thermal", NULL}; + if (options->tempSensor.length > 0) { + possibleModules[0] = options->tempSensor.chars; + possibleModules[1] = NULL; + } + for (int i = 0; possibleModules[i] != NULL; i++) { kstat_t* ks = kstat_lookup(kc, possibleModules[i], -1, NULL); if (ks && kstat_read(kc, ks, NULL) >= 0) { @@ -141,7 +146,7 @@ if (options->temp) { - if (detectCPUTempByKstat(kc, cpu) != NULL) + if (detectCPUTempByKstat(options, kc, cpu) != NULL) detectCPUTempByIpmiTool(cpu); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fastfetch-2.56.0/src/detection/cpu/cpu_windows.c new/fastfetch-2.56.1/src/detection/cpu/cpu_windows.c --- old/fastfetch-2.56.0/src/detection/cpu/cpu_windows.c 2025-12-05 15:42:51.000000000 +0100 +++ new/fastfetch-2.56.1/src/detection/cpu/cpu_windows.c 2025-12-18 08:00:51.000000000 +0100 @@ -17,7 +17,7 @@ } } -const char* detectThermalTemp(double* result) +const char* detectThermalTemp(const FFCPUOptions* options, double* result) { struct FFPerfQuerySpec { @@ -35,6 +35,14 @@ .Name = L"\\_TZ.CPUZ", // The standard(?) instance name for CPU temperature in the thermal provider }; + if (options->tempSensor.length > 0) + { + int written = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, options->tempSensor.chars, (int) options->tempSensor.length, querySpec.Name, (int)(ARRAY_SIZE(querySpec.Name) - 1)); + if (written == 0) + return "Invalid temp sensor string"; + querySpec.Name[written] = L'\0'; + } + DWORD dataSize = 0; if (PerfEnumerateCounterSetInstances(NULL, &querySpec.Identifier.CounterSetGuid, NULL, 0, &dataSize) != ERROR_NOT_ENOUGH_MEMORY) return "PerfEnumerateCounterSetInstances() failed"; @@ -62,6 +70,9 @@ if (dataSize == 0) { + if (options->tempSensor.length > 0) + return "Unable to find CPU sensor"; + const wchar_t* instanceName = (const wchar_t*)((BYTE*)pHead + sizeof(*pHead)); wcscpy(querySpec.Name, instanceName); // Use the first instance name if the specific one is not found } @@ -301,7 +312,7 @@ detectMaxSpeedBySmbios(cpu); if(options->temp) - detectThermalTemp(&cpu->temperature); + detectThermalTemp(options, &cpu->temperature); return NULL; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fastfetch-2.56.0/src/detection/cpucache/cpucache_apple.c new/fastfetch-2.56.1/src/detection/cpucache/cpucache_apple.c --- old/fastfetch-2.56.0/src/detection/cpucache/cpucache_apple.c 2025-12-05 15:42:51.000000000 +0100 +++ new/fastfetch-2.56.1/src/detection/cpucache/cpucache_apple.c 2025-12-18 08:00:51.000000000 +0100 @@ -9,7 +9,7 @@ if (nPerfLevels <= 0) return "sysctl(hw.nperflevels) failed"; // macOS provides the global system cache line size - uint32_t lineSize = (uint32_t) ffSysctlGetInt("hw.cachelinesize", 0); + uint32_t lineSize = (uint32_t) ffSysctlGetInt64("hw.cachelinesize", 0); char sysctlKey[128] = "hw.perflevelN."; char* pNum = sysctlKey + strlen("hw.perflevel"); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fastfetch-2.56.0/src/detection/displayserver/linux/wayland/kde-output-device-v2-client-protocol.h new/fastfetch-2.56.1/src/detection/displayserver/linux/wayland/kde-output-device-v2-client-protocol.h --- old/fastfetch-2.56.0/src/detection/displayserver/linux/wayland/kde-output-device-v2-client-protocol.h 2025-12-05 15:42:51.000000000 +0100 +++ new/fastfetch-2.56.1/src/detection/displayserver/linux/wayland/kde-output-device-v2-client-protocol.h 2025-12-18 08:00:51.000000000 +0100 @@ -239,6 +239,11 @@ * @since 17 */ KDE_OUTPUT_DEVICE_V2_CAPABILITY_SHARPNESS = 0x1000, + /** + * if this outputdevice supports custom modes + * @since 18 + */ + KDE_OUTPUT_DEVICE_V2_CAPABILITY_CUSTOM_MODES = 0x2000, }; /** * @ingroup iface_kde_output_device_v2 @@ -280,6 +285,10 @@ * @ingroup iface_kde_output_device_v2 */ #define KDE_OUTPUT_DEVICE_V2_CAPABILITY_SHARPNESS_SINCE_VERSION 17 +/** + * @ingroup iface_kde_output_device_v2 + */ +#define KDE_OUTPUT_DEVICE_V2_CAPABILITY_CUSTOM_MODES_SINCE_VERSION 18 #endif /* KDE_OUTPUT_DEVICE_V2_CAPABILITY_ENUM */ #ifndef KDE_OUTPUT_DEVICE_V2_VRR_POLICY_ENUM @@ -794,6 +803,23 @@ void (*sharpness)(void *data, struct kde_output_device_v2 *kde_output_device_v2, uint32_t sharpness); + /** + * output priority + * + * Describes the position of the output in the output order list, + * with lower values being earlier in the list. There's no specific + * value the list has to start at, this value is only used in + * sorting outputs. + * + * Note that the output order protocol is not sufficient for this, + * as an output may not be in the output order if it's disabled or + * mirroring another screen. + * @param priority priority + * @since 18 + */ + void (*priority)(void *data, + struct kde_output_device_v2 *kde_output_device_v2, + uint32_t priority); }; /** @@ -943,6 +969,10 @@ * @ingroup iface_kde_output_device_v2 */ #define KDE_OUTPUT_DEVICE_V2_SHARPNESS_SINCE_VERSION 17 +/** + * @ingroup iface_kde_output_device_v2 + */ +#define KDE_OUTPUT_DEVICE_V2_PRIORITY_SINCE_VERSION 18 /** @ingroup iface_kde_output_device_v2 */ @@ -972,6 +1002,18 @@ wl_proxy_destroy((struct wl_proxy *) kde_output_device_v2); } +#ifndef KDE_OUTPUT_DEVICE_MODE_V2_FLAGS_ENUM +#define KDE_OUTPUT_DEVICE_MODE_V2_FLAGS_ENUM +/** + * @ingroup iface_kde_output_device_mode_v2 + * mode flags + */ +enum kde_output_device_mode_v2_flags { + KDE_OUTPUT_DEVICE_MODE_V2_FLAGS_CUSTOM = 0x1, + KDE_OUTPUT_DEVICE_MODE_V2_FLAGS_REDUCED_BLANKING = 0x2, +}; +#endif /* KDE_OUTPUT_DEVICE_MODE_V2_FLAGS_ENUM */ + /** * @ingroup iface_kde_output_device_mode_v2 * @struct kde_output_device_mode_v2_listener @@ -1017,6 +1059,15 @@ */ void (*removed)(void *data, struct kde_output_device_mode_v2 *kde_output_device_mode_v2); + /** + * mode flags + * + * This event describes the mode's flags. + * @since 19 + */ + void (*flags)(void *data, + struct kde_output_device_mode_v2 *kde_output_device_mode_v2, + uint32_t flags); }; /** @@ -1046,6 +1097,10 @@ * @ingroup iface_kde_output_device_mode_v2 */ #define KDE_OUTPUT_DEVICE_MODE_V2_REMOVED_SINCE_VERSION 1 +/** + * @ingroup iface_kde_output_device_mode_v2 + */ +#define KDE_OUTPUT_DEVICE_MODE_V2_FLAGS_SINCE_VERSION 19 /** @ingroup iface_kde_output_device_mode_v2 */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fastfetch-2.56.0/src/detection/displayserver/linux/wayland/kde-output-device-v2-protocol.c new/fastfetch-2.56.1/src/detection/displayserver/linux/wayland/kde-output-device-v2-protocol.c --- old/fastfetch-2.56.0/src/detection/displayserver/linux/wayland/kde-output-device-v2-protocol.c 2025-12-05 15:42:51.000000000 +0100 +++ new/fastfetch-2.56.1/src/detection/displayserver/linux/wayland/kde-output-device-v2-protocol.c 2025-12-18 08:00:51.000000000 +0100 @@ -67,12 +67,13 @@ { "automatic_max_bits_per_color_limit", "15u", kde_output_device_v2_types + 0 }, { "edr_policy", "16u", kde_output_device_v2_types + 0 }, { "sharpness", "17u", kde_output_device_v2_types + 0 }, + { "priority", "18u", kde_output_device_v2_types + 0 }, }; WL_EXPORT const struct wl_interface kde_output_device_v2_interface = { - "kde_output_device_v2", 17, + "kde_output_device_v2", 19, 0, NULL, - 34, kde_output_device_v2_events, + 35, kde_output_device_v2_events, }; static const struct wl_message kde_output_device_mode_v2_events[] = { @@ -80,12 +81,13 @@ { "refresh", "i", kde_output_device_v2_types + 0 }, { "preferred", "", kde_output_device_v2_types + 0 }, { "removed", "", kde_output_device_v2_types + 0 }, + { "flags", "19u", kde_output_device_v2_types + 0 }, }; WL_EXPORT const struct wl_interface kde_output_device_mode_v2_interface = { - "kde_output_device_mode_v2", 1, + "kde_output_device_mode_v2", 19, 0, NULL, - 4, kde_output_device_mode_v2_events, + 5, kde_output_device_mode_v2_events, }; #endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fastfetch-2.56.0/src/detection/displayserver/linux/wayland/kde-output.c new/fastfetch-2.56.1/src/detection/displayserver/linux/wayland/kde-output.c --- old/fastfetch-2.56.0/src/detection/displayserver/linux/wayland/kde-output.c 2025-12-05 15:42:51.000000000 +0100 +++ new/fastfetch-2.56.1/src/detection/displayserver/linux/wayland/kde-output.c 2025-12-18 08:00:51.000000000 +0100 @@ -178,6 +178,7 @@ .automatic_max_bits_per_color_limit = (void*) stubListener, .edr_policy = (void*) stubListener, .sharpness = (void*) stubListener, + .priority = (void*) stubListener, }; const char* ffWaylandHandleKdeOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fastfetch-2.56.0/src/detection/gpu/gpu_linux.c new/fastfetch-2.56.1/src/detection/gpu/gpu_linux.c --- old/fastfetch-2.56.0/src/detection/gpu/gpu_linux.c 2025-12-05 15:42:51.000000000 +0100 +++ new/fastfetch-2.56.1/src/detection/gpu/gpu_linux.c 2025-12-18 08:00:51.000000000 +0100 @@ -605,7 +605,7 @@ if (ffStrbufStartsWithS(&buffer, "pci:")) detectPci(options, gpus, &buffer, &drmDir, entry->d_name); - else if (ffStrbufStartsWithS(&buffer, "of:")) + else if (ffStrbufStartsWithS(&buffer, "of:")) // Open Firmware detectOf(gpus, &buffer, &drmDir, entry->d_name); ffStrbufSubstrBefore(&drmDir, drmDirLength); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fastfetch-2.56.0/src/detection/host/host_apple.c new/fastfetch-2.56.1/src/detection/host/host_apple.c --- old/fastfetch-2.56.0/src/detection/host/host_apple.c 2025-12-05 15:42:51.000000000 +0100 +++ new/fastfetch-2.56.1/src/detection/host/host_apple.c 2025-12-18 08:00:51.000000000 +0100 @@ -45,7 +45,8 @@ const char* ffDetectHost(FFHostResult* host) { - const char* error = ffSysctlGetString("hw.model", &host->family); + const char* error = ffSysctlGetString("hw.product", &host->family); + if (error) error = ffSysctlGetString("hw.model", &host->family); if (error) return error; ffStrbufSetStatic(&host->name, ffHostGetMacProductNameWithHwModel(&host->family)); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fastfetch-2.56.0/src/detection/memory/memory_apple.c new/fastfetch-2.56.1/src/detection/memory/memory_apple.c --- old/fastfetch-2.56.0/src/detection/memory/memory_apple.c 2025-12-05 15:42:51.000000000 +0100 +++ new/fastfetch-2.56.1/src/detection/memory/memory_apple.c 2025-12-18 08:00:51.000000000 +0100 @@ -8,24 +8,25 @@ const char* ffDetectMemory(FFMemoryResult* ram) { size_t length = sizeof(ram->bytesTotal); - if (sysctl((int[]){ CTL_HW, HW_MEMSIZE }, 2, &ram->bytesTotal, &length, NULL, 0)) + if (sysctl((int[]){ CTL_HW, HW_MEMSIZE }, 2, &ram->bytesTotal, &length, NULL, 0) != 0) return "Failed to read hw.memsize"; + uint64_t usableMemory = 0; + length = sizeof(usableMemory); + if (sysctlbyname("hw.memsize_usable", &usableMemory, &length, NULL, 0) != 0) + usableMemory = ram->bytesTotal; mach_msg_type_number_t count = HOST_VM_INFO64_COUNT; vm_statistics64_data_t vmstat; if(host_statistics64(mach_host_self(), HOST_VM_INFO64, (host_info64_t) (&vmstat), &count) != KERN_SUCCESS) return "Failed to read host_statistics64"; - // https://github.com/exelban/stats/blob/master/Modules/RAM/readers.swift#L56 - ram->bytesUsed = ((uint64_t) - + vmstat.active_count - + vmstat.inactive_count - + vmstat.speculative_count - + vmstat.wire_count - + vmstat.compressor_page_count - - vmstat.purgeable_count - - vmstat.external_page_count - ) * instance.state.platform.sysinfo.pageSize; + uint64_t pageSize = instance.state.platform.sysinfo.pageSize; + uint64_t appMemory = vmstat.internal_page_count * pageSize; + uint64_t wiredMemory = vmstat.wire_count * pageSize; + uint64_t compressed = vmstat.compressor_page_count * pageSize; + uint64_t reserved = ram->bytesTotal - usableMemory; + + ram->bytesUsed = appMemory + wiredMemory + compressed + reserved; return NULL; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fastfetch-2.56.0/src/detection/packages/packages_windows.c new/fastfetch-2.56.1/src/detection/packages/packages_windows.c --- old/fastfetch-2.56.0/src/detection/packages/packages_windows.c 2025-12-05 15:42:51.000000000 +0100 +++ new/fastfetch-2.56.1/src/detection/packages/packages_windows.c 2025-12-18 08:00:51.000000000 +0100 @@ -2,35 +2,67 @@ #include "common/processing.h" #include "util/stringUtils.h" #include "util/path.h" +#include "util/windows/unicode.h" +#include "util/mallocHelper.h" +#include "common/io/io.h" + +#include <windows.h> +#include "util/windows/nt.h" +#include <ntstatus.h> -#include <handleapi.h> -#include <fileapi.h> - -static uint32_t getNumElements(const char* searchPath /* including `\*` suffix */, DWORD type, const char* ignore) +static uint32_t getNumElements(const char* searchPath, DWORD type, const wchar_t* ignore) { - uint32_t counter = 0; + FF_AUTO_CLOSE_FD HANDLE dfd = CreateFileA(searchPath, FILE_LIST_DIRECTORY | SYNCHRONIZE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); + if (dfd == INVALID_HANDLE_VALUE) return 0; + bool flag = ignore == NULL; - WIN32_FIND_DATAA wfd; - HANDLE hFind = FindFirstFileA(searchPath, &wfd); + uint32_t counter = 0; + uint8_t buffer[64 * 1024] __attribute__((aligned(8))); // Required for WoA + BOOLEAN firstScan = TRUE; - if (hFind != INVALID_HANDLE_VALUE) - { - do // Managed to locate and create an handle to that folder. + size_t ignoreLen = ignore ? wcslen(ignore) : 0; + + while (true) { + IO_STATUS_BLOCK ioStatus = {}; + NTSTATUS status = NtQueryDirectoryFile( + dfd, + NULL, NULL, NULL, + &ioStatus, + buffer, ARRAY_SIZE(buffer), + FileDirectoryInformation, + FALSE, + NULL, + firstScan + ); + firstScan = FALSE; + + if (!NT_SUCCESS(status) && status != STATUS_BUFFER_OVERFLOW) break; + + for (FILE_DIRECTORY_INFORMATION* entry = (FILE_DIRECTORY_INFORMATION*) buffer; + ; + entry = (FILE_DIRECTORY_INFORMATION*) ((uint8_t*) entry + entry->NextEntryOffset)) { - if(!(wfd.dwFileAttributes & type)) continue; - if(!flag && ffStrEqualsIgnCase(ignore, wfd.cFileName)) + if (!(entry->FileAttributes & type)) continue; + + if (!flag && + ignoreLen == entry->FileNameLength / sizeof(*entry->FileName) && + _wcsnicmp(entry->FileName, ignore, ignoreLen) == 0) { flag = true; continue; } + counter++; - } while (FindNextFileA(hFind, &wfd)); - FindClose(hFind); - if(type == FILE_ATTRIBUTE_DIRECTORY && counter >= 2) - counter -= 2; // accounting for . and .. + if (entry->NextEntryOffset == 0) break; + } + + if (status == STATUS_SUCCESS) break; // No next page } + if(type == FILE_ATTRIBUTE_DIRECTORY && counter >= 2) + counter -= 2; // accounting for . and .. + return counter; } @@ -65,8 +97,8 @@ ffStrbufSet(&scoopPath, &instance.state.platform.homeDir); ffStrbufAppendS(&scoopPath, "/scoop"); } - ffStrbufAppendS(&scoopPath, "/apps/*"); - result->scoopUser = getNumElements(scoopPath.chars, FILE_ATTRIBUTE_DIRECTORY, "scoop"); + ffStrbufAppendS(&scoopPath, "/apps/"); + result->scoopUser = getNumElements(scoopPath.chars, FILE_ATTRIBUTE_DIRECTORY, L"scoop"); } { @@ -78,8 +110,8 @@ ffStrbufSetS(&scoopPath, getenv("ProgramData")); ffStrbufAppendS(&scoopPath, "/scoop"); } - ffStrbufAppendS(&scoopPath, "/apps/*"); - result->scoopGlobal = getNumElements(scoopPath.chars, FILE_ATTRIBUTE_DIRECTORY, "scoop"); + ffStrbufAppendS(&scoopPath, "/apps/"); + result->scoopGlobal = getNumElements(scoopPath.chars, FILE_ATTRIBUTE_DIRECTORY, L"scoop"); } } @@ -91,8 +123,8 @@ char chocoPath[MAX_PATH + 3]; char* pend = ffStrCopy(chocoPath, chocoInstall, ARRAY_SIZE(chocoPath)); - ffStrCopy(pend, "/lib/*", ARRAY_SIZE(chocoPath) - (size_t) (pend - chocoPath)); - result->choco = getNumElements(chocoPath, FILE_ATTRIBUTE_DIRECTORY, "choco"); + ffStrCopy(pend, "/lib/", ARRAY_SIZE(chocoPath) - (size_t) (pend - chocoPath)); + result->choco = getNumElements(chocoPath, FILE_ATTRIBUTE_DIRECTORY, L"choco"); } static void detectPacman(FFPackagesResult* result) @@ -104,7 +136,7 @@ // MSYS2 char pacmanPath[MAX_PATH + 3]; char* pend = ffStrCopy(pacmanPath, msystemPrefix, ARRAY_SIZE(pacmanPath)); - ffStrCopy(pend, "/../var/lib/pacman/local/*", ARRAY_SIZE(pacmanPath) - (size_t) (pend - pacmanPath)); + ffStrCopy(pend, "/../var/lib/pacman/local/", ARRAY_SIZE(pacmanPath) - (size_t) (pend - pacmanPath)); result->pacman = getNumElements(pacmanPath, FILE_ATTRIBUTE_DIRECTORY, NULL); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fastfetch-2.56.0/src/detection/swap/swap_windows.c new/fastfetch-2.56.1/src/detection/swap/swap_windows.c --- old/fastfetch-2.56.0/src/detection/swap/swap_windows.c 2025-12-05 15:42:51.000000000 +0100 +++ new/fastfetch-2.56.1/src/detection/swap/swap_windows.c 2025-12-18 08:00:51.000000000 +0100 @@ -5,8 +5,9 @@ #include <winternl.h> #include <ntstatus.h> #include <windows.h> +#include <psapi.h> -const char* ffDetectSwap(FFlist* result) +const char* detectByNqsi(FFlist* result) { uint8_t buffer[4096]; ULONG size = sizeof(buffer); @@ -26,6 +27,27 @@ if (current->NextEntryOffset == 0) break; } + return NULL; +} + +const char* detectByKgpi(FFlist* result) +{ + PERFORMANCE_INFORMATION pi = {}; + if (!K32GetPerformanceInfo(&pi, sizeof(pi))) + return "K32GetPerformanceInfo(&pi, sizeof(pi)) failed"; + FFSwapResult* swap = ffListAdd(result); + ffStrbufInitS(&swap->name, "Page File"); + swap->bytesTotal = (uint64_t) (pi.CommitLimit > pi.PhysicalTotal ? pi.CommitLimit - pi.PhysicalTotal : 0) * pi.PageSize; + swap->bytesUsed = (uint64_t) (pi.CommitTotal > pi.PhysicalTotal ? pi.CommitTotal - pi.PhysicalTotal : 0) * pi.PageSize; return NULL; } + +const char* ffDetectSwap(FFlist* result) +{ + const char* err = detectByNqsi(result); + if (err == NULL) + return NULL; + + return detectByKgpi(result); +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fastfetch-2.56.0/src/logo/ascii/gxde.txt new/fastfetch-2.56.1/src/logo/ascii/gxde.txt --- old/fastfetch-2.56.0/src/logo/ascii/gxde.txt 1970-01-01 01:00:00.000000000 +0100 +++ new/fastfetch-2.56.1/src/logo/ascii/gxde.txt 2025-12-18 08:00:51.000000000 +0100 @@ -0,0 +1,20 @@ + ################ + ######################## + ##########-- --########## + #######* ****** *####### + ###### --*######--- ###### + ##### --- *#### ##### + ##### *-- #*#*#* * #### ##### +#####* ##- ##*-#* ### ### *##### +##### ###* -##*#* *# *# *### ##### +##### ###* -*##*-*## *#* ### ##### +##### #### - --#### - ##* ### ##### +##### *####* * - ###- ##* ##### +#####* #######- *###- ### *##### + #####* ***#####****--- ### *##### + ###### ----------- - ### ###### + ###### ----- ### ###### + ####### ####### + ##########*----*########## + ###################### + ############## diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fastfetch-2.56.0/src/logo/ascii/opak.txt new/fastfetch-2.56.1/src/logo/ascii/opak.txt --- old/fastfetch-2.56.0/src/logo/ascii/opak.txt 2025-12-05 15:42:51.000000000 +0100 +++ new/fastfetch-2.56.1/src/logo/ascii/opak.txt 1970-01-01 01:00:00.000000000 +0100 @@ -1,13 +0,0 @@ - .':ldkOOOOkxo:,. - .:d0KKXXXXXXXXXXKkl, - .;xOOO0000KKKKXXXXXXX0l. - .cxxxkkkkOOO0000KKKKXXXXx' - ;ool;,,,,;coxkOOOO0000KKKd. -.clc'.........:oxkkkkOOOO0O, -.ccc:ccclc:,....,:oddxxdxkO; - cllllccccccc;'........'lxx. - 'ooooolllllccc:;,''',,coo, - ,ddddooooollllllccccccl' - cxxxdddddooooollllc; - ,dxxxxxddddddol. - .';::,. \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fastfetch-2.56.0/src/logo/builtin.c new/fastfetch-2.56.1/src/logo/builtin.c --- old/fastfetch-2.56.0/src/logo/builtin.c 2025-12-05 15:42:51.000000000 +0100 +++ new/fastfetch-2.56.1/src/logo/builtin.c 2025-12-18 08:00:51.000000000 +0100 @@ -2157,7 +2157,7 @@ // GXDE { .names = {"GXDE"}, - .lines = FASTFETCH_DATATEXT_LOGO_DEEPIN, + .lines = FASTFETCH_DATATEXT_LOGO_GXDE, .colors = { FF_COLOR_FG_RED, }, @@ -3455,12 +3455,6 @@ FF_COLOR_FG_LIGHT_BLACK, } }, - // Opak - { - .names = {"Opak"}, - .lines = FASTFETCH_DATATEXT_LOGO_OPAK, - .colors = {}, // #1070 - }, // OpenKylin { .names = {"openkylin", "open-kylin"}, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fastfetch-2.56.0/src/modules/cpu/cpu.c new/fastfetch-2.56.1/src/modules/cpu/cpu.c --- old/fastfetch-2.56.0/src/modules/cpu/cpu.c 2025-12-05 15:42:51.000000000 +0100 +++ new/fastfetch-2.56.1/src/modules/cpu/cpu.c 2025-12-18 08:00:51.000000000 +0100 @@ -134,6 +134,12 @@ if (ffTempsParseJsonObject(key, val, &options->temp, &options->tempConfig)) continue; + if (unsafe_yyjson_equals_str(key, "tempSensor")) + { + ffStrbufSetS(&options->tempSensor, unsafe_yyjson_get_str(val)); + continue; + } + if (unsafe_yyjson_equals_str(key, "freqNdigits")) { ffPrintError(FF_CPU_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "modules.CPU.freqNdigits has been moved to display.freq.ndigits"); @@ -234,6 +240,7 @@ void ffInitCPUOptions(FFCPUOptions* options) { ffOptionInitModuleArg(&options->moduleArgs, ""); + ffStrbufInit(&options->tempSensor); options->temp = false; options->tempConfig = (FFColorRangeConfig) { 60, 80 }; options->showPeCoreCount = false; @@ -242,6 +249,7 @@ void ffDestroyCPUOptions(FFCPUOptions* options) { ffOptionDestroyModuleArg(&options->moduleArgs); + ffStrbufDestroy(&options->tempSensor); } FFModuleBaseInfo ffCPUModuleInfo = { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fastfetch-2.56.0/src/modules/cpu/option.h new/fastfetch-2.56.1/src/modules/cpu/option.h --- old/fastfetch-2.56.0/src/modules/cpu/option.h 2025-12-05 15:42:51.000000000 +0100 +++ new/fastfetch-2.56.1/src/modules/cpu/option.h 2025-12-18 08:00:51.000000000 +0100 @@ -6,6 +6,7 @@ { FFModuleArgs moduleArgs; + FFstrbuf tempSensor; bool temp; FFColorRangeConfig tempConfig; bool showPeCoreCount; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fastfetch-2.56.0/src/util/apple/smc_temps.c new/fastfetch-2.56.1/src/util/apple/smc_temps.c --- old/fastfetch-2.56.0/src/util/apple/smc_temps.c 2025-12-05 15:42:51.000000000 +0100 +++ new/fastfetch-2.56.1/src/util/apple/smc_temps.c 2025-12-18 08:00:51.000000000 +0100 @@ -277,15 +277,32 @@ return true; } +static io_connect_t conn; + +const char* ffDetectSmcSpecificTemp(const char* sensor, double* result) +{ + if (!conn) + { + if (smcOpen(&conn) != NULL) + conn = (io_connect_t) -1; + } + if (conn == (io_connect_t) -1) + return "Could not open SMC connection"; + + if (!detectTemp(conn, sensor, result)) + return "Could not read SMC temperature"; + + return NULL; +} + const char* ffDetectSmcTemps(enum FFTempType type, double* result) { - static io_connect_t conn; if (!conn) { if (smcOpen(&conn) != NULL) conn = (io_connect_t) -1; } - else if (conn == (io_connect_t) -1) + if (conn == (io_connect_t) -1) return "Could not open SMC connection"; uint32_t count = 0; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fastfetch-2.56.0/src/util/apple/smc_temps.h new/fastfetch-2.56.1/src/util/apple/smc_temps.h --- old/fastfetch-2.56.0/src/util/apple/smc_temps.h 2025-12-05 15:42:51.000000000 +0100 +++ new/fastfetch-2.56.1/src/util/apple/smc_temps.h 2025-12-18 08:00:51.000000000 +0100 @@ -30,4 +30,5 @@ FF_TEMP_MEMORY, }; +const char* ffDetectSmcSpecificTemp(const char* sensor, double* result); const char* ffDetectSmcTemps(enum FFTempType type, double* result); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fastfetch-2.56.0/src/util/platform/FFPlatform_unix.c new/fastfetch-2.56.1/src/util/platform/FFPlatform_unix.c --- old/fastfetch-2.56.0/src/util/platform/FFPlatform_unix.c 2025-12-05 15:42:51.000000000 +0100 +++ new/fastfetch-2.56.1/src/util/platform/FFPlatform_unix.c 2025-12-18 08:00:51.000000000 +0100 @@ -22,7 +22,7 @@ static void getExePath(FFPlatform* platform) { - char exePath[PATH_MAX + 1]; + char exePath[PATH_MAX]; #if defined(__linux__) || defined (__GNU__) ssize_t exePathLen = readlink("/proc/self/exe", exePath, sizeof(exePath) - 1); if (exePathLen >= 0) @@ -58,7 +58,7 @@ while (get_next_image_info(B_CURRENT_TEAM, &cookie, &info) == B_OK) { if (info.type == B_APP_IMAGE) { - exePathLen = strlcpy(exePath, info.name, PATH_MAX); + exePathLen = strlcpy(exePath, info.name, sizeof(exePath)); break; } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fastfetch-2.56.0/src/util/platform/FFPlatform_windows.c new/fastfetch-2.56.1/src/util/platform/FFPlatform_windows.c --- old/fastfetch-2.56.0/src/util/platform/FFPlatform_windows.c 2025-12-05 15:42:51.000000000 +0100 +++ new/fastfetch-2.56.1/src/util/platform/FFPlatform_windows.c 2025-12-18 08:00:51.000000000 +0100 @@ -16,7 +16,7 @@ { wchar_t exePathW[MAX_PATH]; DWORD exePathWLen = GetModuleFileNameW(NULL, exePathW, MAX_PATH); - if (exePathWLen == 0 && exePathWLen >= MAX_PATH) return; + if (exePathWLen == 0 || exePathWLen >= MAX_PATH) return; FF_AUTO_CLOSE_FD HANDLE hPath = CreateFileW(exePathW, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); if (hPath != INVALID_HANDLE_VALUE) @@ -164,8 +164,12 @@ static void getUserShell(FFPlatform* platform) { // Works in MSYS2 - ffStrbufAppendS(&platform->userShell, getenv("SHELL")); - ffStrbufReplaceAllC(&platform->userShell, '\\', '/'); + const char* userShell = getenv("SHELL"); + if (userShell) + { + ffStrbufAppendS(&platform->userShell, userShell); + ffStrbufReplaceAllC(&platform->userShell, '\\', '/'); + } } static const char* detectWine(void) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fastfetch-2.56.0/src/util/windows/nt.h new/fastfetch-2.56.1/src/util/windows/nt.h --- old/fastfetch-2.56.0/src/util/windows/nt.h 2025-12-05 15:42:51.000000000 +0100 +++ new/fastfetch-2.56.1/src/util/windows/nt.h 2025-12-18 08:00:51.000000000 +0100 @@ -232,3 +232,19 @@ static_assert(sizeof(D3DKMT_NODEMETADATA) == 0x4E, "D3DKMT_NODEMETADATA structure size mismatch"); #endif + +NTSYSCALLAPI +NTSTATUS +NTAPI +NtQueryDirectoryFile( + IN HANDLE FileHandle, + IN HANDLE Event OPTIONAL, + IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, + IN PVOID ApcContext OPTIONAL, + OUT PIO_STATUS_BLOCK IoStatusBlock, + OUT PVOID FileInformation, + IN ULONG Length, + IN FILE_INFORMATION_CLASS FileInformationClass, + IN BOOLEAN ReturnSingleEntry, + IN PUNICODE_STRING FileName OPTIONAL, + IN BOOLEAN RestartScan); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fastfetch-2.56.0/src/util/windows/unicode.c new/fastfetch-2.56.1/src/util/windows/unicode.c --- old/fastfetch-2.56.0/src/util/windows/unicode.c 2025-12-05 15:42:51.000000000 +0100 +++ new/fastfetch-2.56.1/src/util/windows/unicode.c 2025-12-18 08:00:51.000000000 +0100 @@ -11,7 +11,7 @@ } int size_needed = WideCharToMultiByte(CP_UTF8, 0, source, (int)length, NULL, 0, NULL, NULL); - if (size_needed < 0) + if (size_needed <= 0) { ffStrbufSetF(result, "WCTMB failed: %u", (unsigned) GetLastError()); return; @@ -21,3 +21,18 @@ result->length = (uint32_t)size_needed; result->chars[size_needed] = '\0'; } + +void ffStrbufAppendNWS(FFstrbuf* result, uint32_t length, const wchar_t* source) +{ + if(!length) + return; + + int size_needed = WideCharToMultiByte(CP_UTF8, 0, source, (int)length, NULL, 0, NULL, NULL); + if (size_needed <= 0) + return; + + ffStrbufEnsureFree(result, (uint32_t)size_needed); + WideCharToMultiByte(CP_UTF8, 0, source, (int)length, result->chars + result->length, size_needed, NULL, NULL); + result->length += (uint32_t)size_needed; + result->chars[result->length] = '\0'; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fastfetch-2.56.0/src/util/windows/unicode.h new/fastfetch-2.56.1/src/util/windows/unicode.h --- old/fastfetch-2.56.0/src/util/windows/unicode.h 2025-12-05 15:42:51.000000000 +0100 +++ new/fastfetch-2.56.1/src/util/windows/unicode.h 2025-12-18 08:00:51.000000000 +0100 @@ -4,6 +4,7 @@ #include <wchar.h> void ffStrbufSetNWS(FFstrbuf* result, uint32_t length, const wchar_t* source); +void ffStrbufAppendNWS(FFstrbuf* result, uint32_t length, const wchar_t* source); static inline void ffStrbufSetWS(FFstrbuf* result, const wchar_t* source) { @@ -11,6 +12,12 @@ return ffStrbufSetNWS(result, (uint32_t)wcslen(source), source); } +static inline void ffStrbufAppendWS(FFstrbuf* result, const wchar_t* source) +{ + if (!source) return; + return ffStrbufAppendNWS(result, (uint32_t)wcslen(source), source); +} + static inline void ffStrbufInitNWS(FFstrbuf* result, uint32_t length, const wchar_t* source) { ffStrbufInit(result); ++++++ fastfetch.obsinfo ++++++ --- /var/tmp/diff_new_pack.AKYPt0/_old 2025-12-22 22:51:06.117627229 +0100 +++ /var/tmp/diff_new_pack.AKYPt0/_new 2025-12-22 22:51:06.157628877 +0100 @@ -1,5 +1,5 @@ name: fastfetch -version: 2.56.0 -mtime: 1764945771 -commit: e50421a6ce8736be5e2fb80a23b2af60fd2ead8a +version: 2.56.1 +mtime: 1766041251 +commit: a9f43ff466ad9ba47222c795d2725f721a86eac0
