Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
c324f83
Logo (Builtin): drop opak
CarterLi Dec 8, 2025
c613e55
Swap (Windows): adds `K32GetPerformanceInfo` fallback
CarterLi Nov 18, 2025
98fb810
Platform (Windows): fixes if checks
CarterLi Dec 3, 2025
100cd9a
Platform (Windows): adds a null check
CarterLi Dec 3, 2025
0b6ca15
Packages (Windows): improves performance for directory enumeration
CarterLi Dec 8, 2025
7a32215
Util (Windows): fixes / adds a new Unicode conversion function
CarterLi Dec 8, 2025
b952772
Packaging: update debian stuff [ci skip]
CarterLi Dec 10, 2025
ba6cdc7
IO (Windows): enhances `openat`
CarterLi Dec 9, 2025
88b1b55
CPU: adds option `tempSensor`
CarterLi Dec 10, 2025
c11b88f
CPU (macOS): supports `tempSensor`
CarterLi Dec 10, 2025
f4401f1
CPU (Windows): supports `tempSensor`
CarterLi Dec 10, 2025
bca56b2
CPU (Linux): supports `tempSensor`
CarterLi Dec 10, 2025
af6196f
CPU (FreeBSD): supports `tempSensor`
CarterLi Dec 10, 2025
b4f39e2
CPU (NetBSD): supports `tempSensor`
CarterLi Dec 10, 2025
6e7b4ba
CPU (OpenBSD): supports `tempSensor`
CarterLi Dec 10, 2025
f2a2930
CPU (Linux): prevents variables from integer overflow
CarterLi Dec 11, 2025
cb1f030
GPU (Linux): add comments
CarterLi Dec 11, 2025
e766809
CPU (SunOS): supports `tempSensor`
CarterLi Dec 11, 2025
42e7a7d
Doc: clarifies that we supports illumos only
CarterLi Dec 11, 2025
60ec8c9
JsonSchema: documents `cpu.tempSensor`
CarterLi Dec 11, 2025
d236850
CPUCache (macOS): fixes cache line size detection
CarterLi Dec 11, 2025
dc69e44
CPU(Linux): Fix build on GNU.
yelninei Dec 11, 2025
bc869f1
Chore: refines usage of `PATH_MAX`
CarterLi Dec 12, 2025
bdc5174
DisplayServer (Linux): upgrades kde-output-device-v2 wayland protocol…
CarterLi Dec 15, 2025
6083821
Logo (Builtin): adds gxde logo (#2094)
gitee-zeqi Dec 15, 2025
2bbd723
Release: v2.56.1
CarterLi Dec 16, 2025
94941da
Memory (macOS): uses `hw.memsize_usable`
CarterLi Dec 16, 2025
0130f61
Chore (Windows): Standardize windows header casing. (#2096) [ci skip]
Dariqq Dec 17, 2025
3e11672
IO (Windows): removes unneeded null terminator appending
CarterLi Dec 17, 2025
1d4d68f
CPU (SunOS): adds `const` for consistancy
CarterLi Dec 17, 2025
945aed7
Host (macOS): prefers `hw.product` than `hw.model`
CarterLi Dec 17, 2025
716c0e2
Doc: update changelog
CarterLi Dec 16, 2025
610fc2e
Memory (macOS): Refines Memory usage detection on macOS to match Acti…
CarterLi Dec 18, 2025
288d25e
Packages (Windows): fixes possible UB
CarterLi Dec 18, 2025
fa92bb8
JsonSchema: refines comments [ci skip]
CarterLi Dec 18, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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:
Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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"
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/fastfetch-cli/fastfetch)
[![中文README](https://img.shields.io/badge/%E4%B8%AD%E6%96%87-README-red)](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" />
Expand Down
6 changes: 6 additions & 0 deletions debian/changelog.tpl
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
fastfetch (2.56.0~#UBUNTU_CODENAME#) #UBUNTU_CODENAME#; urgency=medium

* Update to 2.56.0

-- Carter Li <zhangsongcui@live.cn> Mon, 08 Dec 2025 09:21:58 +0800

fastfetch (2.55.1~#UBUNTU_CODENAME#) #UBUNTU_CODENAME#; urgency=medium

* Update to 2.55.1
Expand Down
4 changes: 4 additions & 0 deletions doc/json_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
8 changes: 8 additions & 0 deletions src/common/io/io.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,13 @@ bool ffAppendFileBuffer(const char* fileName, FFstrbuf* buffer);
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)
{
Expand Down Expand Up @@ -254,4 +261,5 @@ bool ffRemoveFile(const char* fileName);
#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
55 changes: 36 additions & 19 deletions src/common/io/io_windows.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -102,31 +102,48 @@ bool ffAppendFileBuffer(const char* fileName, FFstrbuf* buffer)
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;

FF_AUTO_CLOSE_FD HANDLE hFile;
assert(fileNameLen <= 0x7FFF);

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);
Expand Down
2 changes: 1 addition & 1 deletion src/detection/brightness/brightness_linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ static const char* detectWithBacklight(FFlist* result)
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);
Expand Down
32 changes: 20 additions & 12 deletions src/detection/cpu/cpu_apple.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -130,7 +138,7 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
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;
}
40 changes: 20 additions & 20 deletions src/detection/cpu/cpu_bsd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -94,11 +98,7 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)

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);

Expand Down
Loading