mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-12 10:22:12 +02:00
Merge pull request #2516 from fastfetch-cli/dev
This commit is contained in:
@@ -12,3 +12,4 @@ fastfetch.kdev4
|
||||
*.user
|
||||
*.user.*
|
||||
*.swp
|
||||
*.log
|
||||
|
||||
+30
-9
@@ -1,3 +1,24 @@
|
||||
# 2.67.1
|
||||
|
||||
Bugfixes:
|
||||
* Fixed a `Symbol not found` error when running on macOS 10.15. (Codec, macOS)
|
||||
* Fixed Alacritty font size never being parsed from the TOML config. (TerminalFont)
|
||||
* Fixed bright colors incorrectly being active when the terminal uses a light theme. (#2509, Display)
|
||||
* Fixed Ghostty terminal font detection (TerminalFont)
|
||||
* Now tries to load the config with the `.ghostty` extension. (#2500)
|
||||
* Fixed `font-family` fallback order. (#2510)
|
||||
* Some internal cleanups and optimizations.
|
||||
|
||||
Features:
|
||||
* Added a C23 compiler check so the build process gracefully exits during CMake configuration if the compiler is unsupported. (CMake)
|
||||
* Added compatibility workarounds for Apple Clang 16 to fix building on macOS 14. (CMake, macOS)
|
||||
* Reported real Android version codenames (e.g., "Baklava", "Vanilla Ice Cream") instead of "REL". (OS, Android)
|
||||
* Added Loadavg detection support on Haiku R1B6. (Loadavg, Haiku)
|
||||
* Enabled image logo support in the Zellij terminal multiplexer. (#2507, Logo)
|
||||
* Improved Locale detection on Windows (Locale, Windows)
|
||||
* Now respects `LC_ALL` and `LANG` environment variables if set for better compatibility with MSYS2/cygwin.
|
||||
* Appends the active system Code Page (e.g., `.UTF-8` or `.Windows-1252`) to the default system locale fallback.
|
||||
|
||||
# 2.67.0
|
||||
|
||||
Changes:
|
||||
@@ -31,12 +52,12 @@ Bugfixes:
|
||||
* Fixed invalid URL parsing in the PublicIP module. (PublicIP)
|
||||
* Correctly reported virtual GPUs on Windows. (#2461, GPU, Windows)
|
||||
* Added a size limit for network responses to prevent excessive memory usage and mitigate potential attacks. (PublicIP / Weather)
|
||||
* Fixed Ubuntu Studio Core detection (OS, Linux)
|
||||
* Fixed Ubuntu Studio Core detection. (OS, Linux)
|
||||
* Relaxed the HTTP response check so that both `HTTP/1.0` and `HTTP/1.1` responses are accepted when fetching data over the network. (PublicIP / Weather)
|
||||
* Various internal cleanups and optimizations:
|
||||
* Fixed multiple memory leaks (Separator, Camera, Codec, Display)
|
||||
* Added integer overflow checks to the string buffer implementation
|
||||
* Various code cleanups and compiler warning fixes
|
||||
* Fixed multiple memory leaks (Separator, Camera, Codec, Display).
|
||||
* Added integer overflow checks to the string buffer implementation.
|
||||
* Various code cleanups and compiler warning fixes.
|
||||
|
||||
Logos:
|
||||
* Removed Hypros, MagpieOS, Furreto, EmperorOS and Magix
|
||||
@@ -49,9 +70,9 @@ Changes:
|
||||
|
||||
Bugfixes:
|
||||
* Fixed compatibility with WSL 2.9.3 (#2433, WM, Linux)
|
||||
* Fixed accurate AMD GPU names are not queried in `driverSpecific` mode (GPU, Linux)
|
||||
* Fixed AMD GPU names not being queried accurately in `driverSpecific` mode (GPU, Linux)
|
||||
* Fixed GPU core counting for Apple Silicon GPU on Asahi Linux (GPU, Linux)
|
||||
* Some internal cleanups and optimizations
|
||||
* Some internal cleanups and optimizations.
|
||||
|
||||
Features:
|
||||
* Added Astra Linux version detection (OS, Linux)
|
||||
@@ -784,7 +805,7 @@ Features:
|
||||
* Added support for interface speed detection on SunOS (LocalIP, SunOS)
|
||||
* Added detection support for Xlibre (#1888, WM, Linux)
|
||||
* Improved the accuracy of color detection (Cursor, macOS)
|
||||
* Improved the proformance of `Nix` package manager detection on macOS by porting optimizations form Linux port (#1893, Packages, macOS)
|
||||
* Improved the performance of `Nix` package manager detection on macOS by porting optimizations from the Linux port (#1893, Packages, macOS)
|
||||
|
||||
Bugfixes:
|
||||
* Fixed custom object inheriting a key from the previous custom object if the key is blank (#1477)
|
||||
@@ -1295,7 +1316,7 @@ Features:
|
||||
* Change package manager name of NetBSD from `pkg` to `pkgsrc` (#1515, Packages, NetBSD)
|
||||
* Detect SOC name on RISCV (#1519, CPU, Linux)
|
||||
* Report marketing name of new QS8Es (CPU, Android)
|
||||
* Acquire acquire more os info from lsb-release if missing from os-release (#1521)
|
||||
* Acquire more OS info from lsb-release if missing from os-release (#1521)
|
||||
* CMake: add option `-DCUSTOM_LSB_RELEASE_PATH` to specify the path of `lsb-release` file
|
||||
* `-DCUSTOM_OS_RELEASE_PATH` has been supported since `v2.11.4`
|
||||
* Report more SOC names on Android (CPU, Android)
|
||||
@@ -1763,7 +1784,7 @@ Logos:
|
||||
|
||||
Bugfixes:
|
||||
* Fix bad Intel Arc GPU name detection, which was supposed to be fixed in the last version but the change was reverted accidentally (#1177, GPU, Linux)
|
||||
* Fix arm32 CPU name detection no longer work. Regression of 2.21.2 (CPU, Linux)
|
||||
* Fix arm32 CPU name detection no longer working. Regression of 2.21.2 (CPU, Linux)
|
||||
|
||||
# 2.21.2
|
||||
|
||||
|
||||
+29
-8
@@ -1,7 +1,7 @@
|
||||
cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url
|
||||
|
||||
project(fastfetch
|
||||
VERSION 2.67.0
|
||||
VERSION 2.67.1
|
||||
LANGUAGES C
|
||||
DESCRIPTION "Fast neofetch-like system information tool"
|
||||
HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch"
|
||||
@@ -62,6 +62,7 @@ if(NOT PKG_CONFIG_FOUND)
|
||||
endif()
|
||||
|
||||
include(CheckIncludeFile)
|
||||
include(CheckFunctionExists)
|
||||
|
||||
if(LINUX)
|
||||
CHECK_INCLUDE_FILE("linux/version.h" HAVE_LINUX_VERSION_H)
|
||||
@@ -1022,7 +1023,7 @@ elseif(APPLE)
|
||||
src/detection/cpu/cpu_apple.c
|
||||
src/detection/cpucache/cpucache_apple.c
|
||||
src/detection/cpuusage/cpuusage_apple.c
|
||||
src/detection/cursor/cursor_apple.m
|
||||
src/detection/cursor/cursor_apple.c
|
||||
src/detection/disk/disk_bsd.c
|
||||
src/detection/dns/dns_apple.c
|
||||
src/detection/physicaldisk/physicaldisk_apple.c
|
||||
@@ -1063,7 +1064,7 @@ elseif(APPLE)
|
||||
src/detection/wifi/wifi_apple.m
|
||||
src/detection/wm/wm_apple.m
|
||||
src/detection/de/de_nosupport.c
|
||||
src/detection/wmtheme/wmtheme_apple.m
|
||||
src/detection/wmtheme/wmtheme_apple.c
|
||||
src/detection/camera/camera_apple.m
|
||||
)
|
||||
# CMAKE_SYSTEM_PROCESSOR has been normalized before
|
||||
@@ -1281,7 +1282,6 @@ elseif(Haiku)
|
||||
src/detection/keyboard/keyboard_haiku.cpp
|
||||
src/detection/libc/libc_nosupport.c
|
||||
src/detection/lm/lm_nosupport.c
|
||||
src/detection/loadavg/loadavg_nosupport.c
|
||||
src/detection/locale/locale_linux.c
|
||||
src/detection/localip/localip_linux.c
|
||||
src/detection/gamepad/gamepad_haiku.cpp
|
||||
@@ -1311,6 +1311,13 @@ elseif(Haiku)
|
||||
src/detection/wmtheme/wmtheme_haiku.cpp
|
||||
src/detection/camera/camera_nosupport.c
|
||||
)
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} bsd)
|
||||
check_function_exists(getloadavg HAVE_GETLOADAVG)
|
||||
if(HAVE_GETLOADAVG)
|
||||
list(APPEND LIBFASTFETCH_SRC src/detection/loadavg/loadavg_sunos.c)
|
||||
else()
|
||||
list(APPEND LIBFASTFETCH_SRC src/detection/loadavg/loadavg_nosupport.c)
|
||||
endif()
|
||||
elseif(GNU)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
src/common/impl/dbus.c
|
||||
@@ -1428,7 +1435,6 @@ if(WIN32)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
include(CheckFunctionExists)
|
||||
if(NOT WIN32)
|
||||
check_function_exists(pipe2 HAVE_PIPE2)
|
||||
endif()
|
||||
@@ -1469,10 +1475,24 @@ endforeach()
|
||||
include(CheckCSourceCompiles)
|
||||
check_c_source_compiles("int main(void){int arr[1];return _Countof(arr);}" COMPILER_SUPPORTS_COUNT_OF)
|
||||
if(COMPILER_SUPPORTS_COUNT_OF)
|
||||
message(STATUS "_Countof is supported by the compiler")
|
||||
message(STATUS "C2Y _Countof is supported by the compiler")
|
||||
target_compile_definitions(libfastfetch PUBLIC FF_SUPPORTS_COUNT_OF=1)
|
||||
else()
|
||||
message(STATUS "_Countof is NOT supported by the compiler")
|
||||
message(STATUS "C2Y _Countof is NOT supported by the compiler")
|
||||
endif()
|
||||
|
||||
# Test C23 compiler support
|
||||
check_c_source_compiles("enum my_enum: long{MY_ENUM_ZERO}; void test(void*p){} int main(int,const char**){[[gnu::cleanup(test)]] void* x=nullptr; return (int)MY_ENUM_ZERO;}" COMPILER_SUPPORTS_C23)
|
||||
if(NOT COMPILER_SUPPORTS_C23)
|
||||
message(FATAL_ERROR "Compiler does not support C23. Please use a newer compiler.")
|
||||
endif()
|
||||
|
||||
# A hack for AppleClang 17, which supports most C23 features we use except for the `auto` keyword.
|
||||
# See https://github.com/Homebrew/homebrew-core/pull/297403
|
||||
check_c_source_compiles("int main(void){auto v = 12.34; return (int)v;}" COMPILER_SUPPORTS_AUTO)
|
||||
if(NOT COMPILER_SUPPORTS_AUTO)
|
||||
message(WARNING "Compiler does not support C23 'auto' keyword. A workaround will be applied.")
|
||||
target_compile_definitions(libfastfetch PUBLIC $<$<COMPILE_LANGUAGE:C>:auto=__auto_type>)
|
||||
endif()
|
||||
|
||||
if(yyjson_FOUND)
|
||||
@@ -1555,7 +1575,7 @@ elseif(Haiku)
|
||||
target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE)
|
||||
elseif(GNU)
|
||||
# On Hurd PATH_MAX is not defined. Set an arbitrary limit as workaround.
|
||||
target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE PATH_MAX=4096 O_PATH=0)
|
||||
target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE PATH_MAX=4096 O_PATH=O_NORW)
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
@@ -2006,6 +2026,7 @@ elseif(Haiku)
|
||||
PRIVATE "GL"
|
||||
PRIVATE "be"
|
||||
PRIVATE "gnu"
|
||||
PRIVATE "bsd"
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -335,10 +335,10 @@ If you find Fastfetch useful, please consider donating.
|
||||
|
||||
Give us a star to show your support!
|
||||
|
||||
<a href="https://star-history.com/#fastfetch-cli/fastfetch&Date">
|
||||
<a href="https://star-history.dera.page/#fastfetch-cli/fastfetch&Date">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=fastfetch-cli/fastfetch&type=Date&theme=dark" />
|
||||
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=fastfetch-cli/fastfetch&type=Date" />
|
||||
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=fastfetch-cli/fastfetch&type=Date" />
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://star-history.dera.page/svg?repos=fastfetch-cli/fastfetch&type=Date&theme=dark" />
|
||||
<source media="(prefers-color-scheme: light)" srcset="https://star-history.dera.page/svg?repos=fastfetch-cli/fastfetch&type=Date" />
|
||||
<img alt="Star History Chart" src="https://star-history.dera.page/svg?repos=fastfetch-cli/fastfetch&type=Date" />
|
||||
</picture>
|
||||
</a>
|
||||
|
||||
Vendored
+6
@@ -1,3 +1,9 @@
|
||||
fastfetch (2.67.0~#UBUNTU_CODENAME#) #UBUNTU_CODENAME#; urgency=medium
|
||||
|
||||
* Update to 2.67.0
|
||||
|
||||
-- Carter Li <zhangsongcui@live.cn> Thu, 06 Aug 2026 16:22:22 +0800
|
||||
|
||||
fastfetch (2.66.0~#UBUNTU_CODENAME#) #UBUNTU_CODENAME#; urgency=medium
|
||||
|
||||
* Update to 2.66.0
|
||||
|
||||
@@ -31,6 +31,10 @@ typedef struct FFPlatform {
|
||||
FFstrbuf userShell;
|
||||
|
||||
FFPlatformSysinfo sysinfo;
|
||||
|
||||
#if _WIN32
|
||||
uint32_t initCP; // The code page used by the console when the program started
|
||||
#endif
|
||||
} FFPlatform;
|
||||
|
||||
void ffPlatformInit(FFPlatform* platform);
|
||||
|
||||
@@ -18,6 +18,7 @@ void ffPlatformInit(FFPlatform* platform) {
|
||||
|
||||
#ifdef _WIN32
|
||||
ffStrbufInit(&platform->sid);
|
||||
platform->initCP = 0;
|
||||
#endif
|
||||
|
||||
FFPlatformSysinfo* info = &platform->sysinfo;
|
||||
|
||||
+5
-13
@@ -5,7 +5,6 @@
|
||||
#include "common/textModifier.h"
|
||||
#include "common/strutil.h"
|
||||
#include "detection/displayserver/displayserver.h"
|
||||
#include "detection/terminaltheme/terminaltheme.h"
|
||||
#include "logo/logo.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
@@ -27,21 +26,10 @@ static void initState(FFstate* state) {
|
||||
state->logoWidth = 0;
|
||||
state->logoHeight = 0;
|
||||
state->keysHeight = 0;
|
||||
state->terminalLightTheme = false;
|
||||
state->titleFqdn = false;
|
||||
|
||||
ffPlatformInit(&state->platform);
|
||||
state->dynamicInterval = 0;
|
||||
|
||||
#if !FF_MODULE_DISABLE_TERMINALTHEME
|
||||
{
|
||||
// don't enable bright color if the terminal is in light mode
|
||||
FFTerminalThemeResult result;
|
||||
if (ffDetectTerminalTheme(&result, true /* forceEnv for performance */) && !result.bg.dark) {
|
||||
state->terminalLightTheme = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void defaultConfig(void) {
|
||||
@@ -51,7 +39,7 @@ static void defaultConfig(void) {
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
static volatile UINT oldCp = CP_UTF8;
|
||||
static UINT oldCp = CP_UTF8;
|
||||
void resetConsoleCP(void) {
|
||||
if (oldCp != CP_UTF8) {
|
||||
SetConsoleOutputCP(oldCp);
|
||||
@@ -81,6 +69,10 @@ void ffInitInstance(void) {
|
||||
|
||||
defaultConfig();
|
||||
initState(&instance.state);
|
||||
|
||||
#ifdef _WIN32
|
||||
instance.state.platform.initCP = oldCp;
|
||||
#endif
|
||||
}
|
||||
|
||||
static volatile bool ffDisableLinewrap = false;
|
||||
|
||||
@@ -178,3 +178,83 @@ void* ffLibraryGetModule(const wchar_t* libraryFileName) {
|
||||
return module;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct LibraryIterateDynamicLibsBundle {
|
||||
FFLibraryIterateCallback callback;
|
||||
void* userData;
|
||||
};
|
||||
|
||||
#if _WIN32
|
||||
|
||||
static void ffLibraryIterateDynamicLibsCallback(PLDR_DATA_TABLE_ENTRY DataTableEntry, PVOID Context, BOOLEAN* StopEnumeration) {
|
||||
if (DataTableEntry->FullDllName.Buffer == nullptr || DataTableEntry->FullDllName.Buffer[0] == L'\0') {
|
||||
return;
|
||||
}
|
||||
|
||||
char path[PATH_MAX * 3];
|
||||
ULONG outBytes;
|
||||
if (NT_SUCCESS(RtlUnicodeToUTF8N(path, sizeof(path), &outBytes, DataTableEntry->FullDllName.Buffer, DataTableEntry->FullDllName.Length))) {
|
||||
path[outBytes] = '\0';
|
||||
struct LibraryIterateDynamicLibsBundle* bundle = (struct LibraryIterateDynamicLibsBundle*) Context;
|
||||
*StopEnumeration = !bundle->callback(path, bundle->userData);
|
||||
}
|
||||
}
|
||||
|
||||
bool ffLibraryIterateDynamicLibs(FFLibraryIterateCallback callback, void* userData) {
|
||||
struct LibraryIterateDynamicLibsBundle bundle = {
|
||||
.callback = callback,
|
||||
.userData = userData,
|
||||
};
|
||||
return NT_SUCCESS(LdrEnumerateLoadedModules(FALSE, ffLibraryIterateDynamicLibsCallback, &bundle));
|
||||
}
|
||||
|
||||
#elif defined(__APPLE__)
|
||||
|
||||
#include <mach-o/dyld.h>
|
||||
|
||||
bool ffLibraryIterateDynamicLibs(FFLibraryIterateCallback callback, void* userData) {
|
||||
uint32_t imageCount = _dyld_image_count();
|
||||
for (uint32_t i = 0; i < imageCount; ++i) {
|
||||
const char* name = _dyld_get_image_name(i);
|
||||
if (name == nullptr || name[0] == '\0') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!callback(name, userData)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#elif __has_include(<link.h>)
|
||||
#include <link.h>
|
||||
|
||||
static int ffLibraryIterateDynamicLibsCallback(struct dl_phdr_info* info, size_t, void* data) {
|
||||
if (info->dlpi_name == nullptr || info->dlpi_name[0] == '\0') {
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct LibraryIterateDynamicLibsBundle* bundle = (struct LibraryIterateDynamicLibsBundle*) data;
|
||||
return !bundle->callback(info->dlpi_name, bundle->userData);
|
||||
}
|
||||
|
||||
bool ffLibraryIterateDynamicLibs(bool (*callback)(const char* name, void* userData), void* userData) {
|
||||
dl_iterate_phdr(
|
||||
ffLibraryIterateDynamicLibsCallback,
|
||||
&(struct LibraryIterateDynamicLibsBundle) {
|
||||
.callback = callback,
|
||||
.userData = userData,
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
bool ffLibraryIterateDynamicLibs(FFLibraryIterateCallback, void*) {
|
||||
// Not implemented for this platform
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -48,6 +48,41 @@ static void argvToCmdline(char* const argv[], FFstrbuf* result) {
|
||||
}
|
||||
}
|
||||
|
||||
static wchar_t* createChildEnvironment(void) {
|
||||
auto pparams = ffGetPeb()->ProcessParameters;
|
||||
const wchar_t* readStart = pparams->Environment;
|
||||
|
||||
if (!readStart) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RtlAcquirePebLock();
|
||||
wchar_t* result = malloc(pparams->EnvironmentSize + sizeof(L"LANG=C.UTF-8"));
|
||||
|
||||
const wchar_t* entry = readStart;
|
||||
wchar_t* writeStart = result;
|
||||
|
||||
// Copy all environment variables except LANG
|
||||
while (*entry) {
|
||||
assert((const uint8_t*) entry <= (const uint8_t*) pparams->Environment + pparams->EnvironmentSize);
|
||||
size_t entryLength = wcslen(entry);
|
||||
if (entryLength >= strlen("LANG=") && memcmp(entry, L"LANG=", strlen("LANG=") * sizeof(wchar_t)) == 0) {
|
||||
memcpy(writeStart, readStart, (size_t) (entry - readStart) * sizeof(wchar_t));
|
||||
writeStart += (size_t) (entry - readStart);
|
||||
readStart = entry + entryLength + 1;
|
||||
}
|
||||
entry += entryLength + 1;
|
||||
}
|
||||
// Copy the remaining environment variables
|
||||
memcpy(writeStart, readStart, (size_t) (entry - readStart) * sizeof(wchar_t));
|
||||
writeStart += (size_t) (entry - readStart);
|
||||
// Add LANG=C.UTF-8 and double null terminator
|
||||
memcpy(writeStart, L"LANG=C.UTF-8\0", sizeof(L"LANG=C.UTF-8\0"));
|
||||
|
||||
RtlReleasePebLock();
|
||||
return result;
|
||||
}
|
||||
|
||||
const char* ffProcessSpawn(char* const argv[], bool useStdErr, FFProcessHandle* outHandle) {
|
||||
const int32_t timeout = instance.config.general.processingTimeout;
|
||||
|
||||
@@ -108,17 +143,18 @@ const char* ffProcessSpawn(char* const argv[], bool useStdErr, FFProcessHandle*
|
||||
}
|
||||
}
|
||||
|
||||
FF_AUTO_FREE wchar_t* environment = createChildEnvironment();
|
||||
BOOL success = CreateProcessW(
|
||||
nullptr, // application name
|
||||
cmdline, // command line
|
||||
nullptr, // process security attributes
|
||||
nullptr, // primary thread security attributes
|
||||
TRUE, // handles are inherited
|
||||
0, // creation flags
|
||||
nullptr, // use parent's environment
|
||||
nullptr, // use parent's current directory
|
||||
&siStartInfo, // STARTUPINFO pointer
|
||||
&piProcInfo // receives PROCESS_INFORMATION
|
||||
nullptr, // application name
|
||||
cmdline, // command line
|
||||
nullptr, // process security attributes
|
||||
nullptr, // primary thread security attributes
|
||||
TRUE, // handles are inherited
|
||||
CREATE_UNICODE_ENVIRONMENT, // creation flags
|
||||
environment, // child environment
|
||||
nullptr, // use parent's current directory
|
||||
&siStartInfo, // STARTUPINFO pointer
|
||||
&piProcInfo // receives PROCESS_INFORMATION
|
||||
);
|
||||
|
||||
NtClose(hChildPipeWrite);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "fastfetch.h"
|
||||
#include "fastfetch.h" // IWYU pragma: keep
|
||||
|
||||
#ifndef FF_DISABLE_DLOPEN
|
||||
|
||||
@@ -111,3 +111,8 @@ void* ffLibraryLoadMulti(const char* path, int maxVersion, ...);
|
||||
#if _WIN32
|
||||
void* ffLibraryGetModule(const wchar_t* libraryFileName);
|
||||
#endif
|
||||
|
||||
// Return false to stop iterating, true to continue
|
||||
typedef bool (*FFLibraryIterateCallback)(const char* name, void* userData);
|
||||
// Iterate over all loaded dynamic libraries. Returns true on success, false on failure.
|
||||
bool ffLibraryIterateDynamicLibs(FFLibraryIterateCallback callback, void* userData);
|
||||
|
||||
@@ -1279,6 +1279,22 @@ NTSYSAPI NTSTATUS NTAPI LdrGetProcedureAddress(
|
||||
_In_opt_ ULONG ProcedureNumber,
|
||||
_Out_ PVOID* ProcedureAddress);
|
||||
|
||||
typedef _Function_class_(LDR_LOADED_MODULE_ENUMERATION_CALLBACK_FUNCTION)
|
||||
VOID NTAPI LDR_LOADED_MODULE_ENUMERATION_CALLBACK_FUNCTION(
|
||||
_In_ PLDR_DATA_TABLE_ENTRY DataTableEntry,
|
||||
_In_opt_ PVOID Context,
|
||||
_Inout_ BOOLEAN* StopEnumeration
|
||||
);
|
||||
|
||||
NTSYSAPI
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
LdrEnumerateLoadedModules(
|
||||
_In_ BOOLEAN ReservedFlag,
|
||||
_In_ LDR_LOADED_MODULE_ENUMERATION_CALLBACK_FUNCTION* EnumProc,
|
||||
_In_opt_ PVOID Context
|
||||
);
|
||||
|
||||
typedef enum _SECTION_INHERIT {
|
||||
ViewShare = 1,
|
||||
ViewUnmap = 2
|
||||
@@ -1323,3 +1339,6 @@ NTSYSAPI NTSTATUS NTAPI NtCancelIoFileEx(
|
||||
NTSYSAPI NTSTATUS NTAPI NtTerminateProcess(
|
||||
_In_opt_ HANDLE ProcessHandle,
|
||||
_In_ NTSTATUS ExitStatus);
|
||||
|
||||
NTSYSAPI NTSTATUS NTAPI RtlAcquirePebLock(VOID);
|
||||
NTSYSAPI NTSTATUS NTAPI RtlReleasePebLock(VOID);
|
||||
|
||||
@@ -19,12 +19,8 @@ const char* ffDetectCamera(FFlist* result)
|
||||
AVCaptureDeviceType deviceType = nullptr;
|
||||
|
||||
#ifdef MAC_OS_VERSION_14_0
|
||||
// Strangely `@available(macOS 14.0, *)` doesn't work here (#1594)
|
||||
if (@available(macOS 14.0, *))
|
||||
{
|
||||
if (&AVCaptureDeviceTypeExternal)
|
||||
deviceType = AVCaptureDeviceTypeExternal;
|
||||
}
|
||||
if (&AVCaptureDeviceTypeExternal)
|
||||
deviceType = AVCaptureDeviceTypeExternal;
|
||||
#endif
|
||||
if (deviceType == nullptr)
|
||||
deviceType = AVCaptureDeviceTypeExternalUnknown;
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
#include <VideoToolbox/VideoToolbox.h>
|
||||
#include "common/apple/cf_helpers.h"
|
||||
|
||||
#ifdef MAC_OS_VERSION_11_0
|
||||
[[clang::weak_import]] VT_EXPORT void VTRegisterSupplementalVideoDecoderIfAvailable(CMVideoCodecType codecType);
|
||||
#endif
|
||||
|
||||
static const struct {
|
||||
CMVideoCodecType codec;
|
||||
FFCodecType type;
|
||||
@@ -70,9 +74,11 @@ static FFCodecType ffCodecDetectDecoders() {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (__builtin_available(macOS 11.0, *)) {
|
||||
#ifdef MAC_OS_VERSION_11_0
|
||||
if (VTRegisterSupplementalVideoDecoderIfAvailable) {
|
||||
VTRegisterSupplementalVideoDecoderIfAvailable(codec.codec);
|
||||
}
|
||||
#endif
|
||||
bool supported = VTIsHardwareDecodeSupported(codec.codec);
|
||||
if (!supported) {
|
||||
continue;
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
#include "cursor.h"
|
||||
#include "common/apple/cf_helpers.h"
|
||||
|
||||
static bool appendColor(FFstrbuf* str, CFDictionaryRef dict) {
|
||||
double r, g, b, a;
|
||||
if (
|
||||
ffCfDictGetDouble(dict, CFSTR("red"), &r) ||
|
||||
ffCfDictGetDouble(dict, CFSTR("green"), &g) ||
|
||||
ffCfDictGetDouble(dict, CFSTR("blue"), &b) ||
|
||||
ffCfDictGetDouble(dict, CFSTR("alpha"), &a)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
r = r * 255 + .5;
|
||||
g = g * 255 + .5;
|
||||
b = b * 255 + .5;
|
||||
a = a * 255 + .5;
|
||||
|
||||
uint32_t color = ((uint32_t) r << 24) | ((uint32_t) g << 16) | ((uint32_t) b << 8) | ((uint32_t) a);
|
||||
|
||||
// clang-format off
|
||||
switch (color)
|
||||
{
|
||||
case 0x000000FF: ffStrbufAppendS(str, "Black"); break;
|
||||
case 0x0433FFFF: ffStrbufAppendS(str, "Blue"); break;
|
||||
case 0xAA7942FF: ffStrbufAppendS(str, "Brown"); break;
|
||||
case 0x00FDFFFF: ffStrbufAppendS(str, "Cyan"); break;
|
||||
case 0x00F900FF: ffStrbufAppendS(str, "Green"); break;
|
||||
case 0xFF40FFFF: ffStrbufAppendS(str, "Magenta"); break;
|
||||
case 0xFF9300FF: ffStrbufAppendS(str, "Orange"); break;
|
||||
case 0x942192FF: ffStrbufAppendS(str, "Purple"); break;
|
||||
case 0xFF2600FF: ffStrbufAppendS(str, "Red"); break;
|
||||
case 0xFFFB00FF: ffStrbufAppendS(str, "Yellow"); break;
|
||||
case 0xFFFFFFFF: ffStrbufAppendS(str, "White"); break;
|
||||
case 0x00000000: ffStrbufAppendS(str, "Transparent"); break;
|
||||
default: ffStrbufAppendF(str, "#%08X", color); break;
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ffDetectCursor(FFCursorResult* result) {
|
||||
// Read via cfprefsd (equivalent to `defaults read com.apple.universalaccess <key>`)
|
||||
ffStrbufAppendS(&result->theme, "Fill - ");
|
||||
{
|
||||
FF_CFTYPE_AUTO_RELEASE CFTypeRef color = CFPreferencesCopyAppValue(CFSTR("cursorFill"), CFSTR("com.apple.universalaccess"));
|
||||
if (!color || CFGetTypeID(color) != CFDictionaryGetTypeID() || !appendColor(&result->theme, (CFDictionaryRef) color)) {
|
||||
ffStrbufAppendS(&result->theme, "Black");
|
||||
}
|
||||
}
|
||||
|
||||
ffStrbufAppendS(&result->theme, ", Outline - ");
|
||||
{
|
||||
FF_CFTYPE_AUTO_RELEASE CFTypeRef color = CFPreferencesCopyAppValue(CFSTR("cursorOutline"), CFSTR("com.apple.universalaccess"));
|
||||
if (!color || CFGetTypeID(color) != CFDictionaryGetTypeID() || !appendColor(&result->theme, (CFDictionaryRef) color)) {
|
||||
ffStrbufAppendS(&result->theme, "White");
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
FF_CFTYPE_AUTO_RELEASE CFTypeRef mouseDriverCursorSize = CFPreferencesCopyAppValue(CFSTR("mouseDriverCursorSize"), CFSTR("com.apple.universalaccess"));
|
||||
double size = 32;
|
||||
if (mouseDriverCursorSize && ffCfNumGetDouble(mouseDriverCursorSize, &size) == nullptr) {
|
||||
ffStrbufAppendUInt(&result->size, (uint32_t) (size * 32 + 0.5));
|
||||
} else {
|
||||
ffStrbufAppendS(&result->size, "32");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
#include "cursor.h"
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
static void appendColor(FFstrbuf* str, NSDictionary* dict)
|
||||
{
|
||||
uint32_t r = (uint32_t) (((NSNumber*) dict[@"red"]).doubleValue * 255 + .5);
|
||||
uint32_t g = (uint32_t) (((NSNumber*) dict[@"green"]).doubleValue * 255 + .5);
|
||||
uint32_t b = (uint32_t) (((NSNumber*) dict[@"blue"]).doubleValue * 255 + .5);
|
||||
uint32_t a = (uint32_t) (((NSNumber*) dict[@"alpha"]).doubleValue * 255 + .5);
|
||||
uint32_t color = (r << 24) | (g << 16) | (b << 8) | a;
|
||||
|
||||
switch (color)
|
||||
{
|
||||
case 0x000000FF: ffStrbufAppendS(str, "Black"); return;
|
||||
case 0x0433FFFF: ffStrbufAppendS(str, "Blue"); return;
|
||||
case 0xAA7942FF: ffStrbufAppendS(str, "Brown"); return;
|
||||
case 0x00FDFFFF: ffStrbufAppendS(str, "Cyan"); return;
|
||||
case 0x00F900FF: ffStrbufAppendS(str, "Green"); return;
|
||||
case 0xFF40FFFF: ffStrbufAppendS(str, "Magenta"); return;
|
||||
case 0xFF9300FF: ffStrbufAppendS(str, "Orange"); return;
|
||||
case 0x942192FF: ffStrbufAppendS(str, "Purple"); return;
|
||||
case 0xFF2600FF: ffStrbufAppendS(str, "Red"); return;
|
||||
case 0xFFFB00FF: ffStrbufAppendS(str, "Yellow"); return;
|
||||
case 0xFFFFFFFF: ffStrbufAppendS(str, "White"); return;
|
||||
case 0x00000000: ffStrbufAppendS(str, "Transparent"); return;
|
||||
default: ffStrbufAppendF(str, "#%08X", color); return;
|
||||
}
|
||||
}
|
||||
|
||||
void ffDetectCursor(FFCursorResult* result)
|
||||
{
|
||||
NSError* error;
|
||||
NSString* fileName = [NSString stringWithFormat:@"file://%s/Library/Preferences/com.apple.universalaccess.plist", instance.state.platform.homeDir.chars];
|
||||
NSDictionary* dict = [NSDictionary dictionaryWithContentsOfURL:[NSURL URLWithString:fileName]
|
||||
error:&error];
|
||||
if(error)
|
||||
{
|
||||
ffStrbufAppendS(&result->error, error.localizedDescription.UTF8String);
|
||||
return;
|
||||
}
|
||||
|
||||
NSDictionary* color;
|
||||
|
||||
ffStrbufAppendS(&result->theme, "Fill - ");
|
||||
if ((color = dict[@"cursorFill"]))
|
||||
appendColor(&result->theme, color);
|
||||
else
|
||||
ffStrbufAppendS(&result->theme, "Black");
|
||||
|
||||
ffStrbufAppendS(&result->theme, ", Outline - ");
|
||||
|
||||
if ((color = dict[@"cursorOutline"]))
|
||||
appendColor(&result->theme, color);
|
||||
else
|
||||
ffStrbufAppendS(&result->theme, "White");
|
||||
|
||||
NSNumber* mouseDriverCursorSize = dict[@"mouseDriverCursorSize"];
|
||||
if (mouseDriverCursorSize)
|
||||
ffStrbufAppendF(&result->size, "%d", (int) (mouseDriverCursorSize.doubleValue * 32 + 0.5));
|
||||
else
|
||||
ffStrbufAppendS(&result->size, "32");
|
||||
}
|
||||
@@ -1,6 +1,10 @@
|
||||
#include "detection/loadavg/loadavg.h"
|
||||
|
||||
#include <sys/loadavg.h>
|
||||
#if __has_include(<sys/loadavg.h>)
|
||||
#include <sys/loadavg.h>
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
const char* ffDetectLoadavg(double result[3]) {
|
||||
return getloadavg(result, 3) == 3 ? nullptr : "getloadavg() failed";
|
||||
|
||||
@@ -1,16 +1,87 @@
|
||||
#include "detection/locale/locale.h"
|
||||
#include "common/windows/unicode.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <winnls.h>
|
||||
|
||||
const char* ffDetectLocale(FFstrbuf* result) {
|
||||
ffStrbufAppendS(result, getenv("LC_ALL"));
|
||||
if (result->length > 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ffStrbufAppendS(result, getenv("LANG")); // Available in MSYS2 and Cygwin
|
||||
if (result->length > 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
wchar_t name[LOCALE_NAME_MAX_LENGTH];
|
||||
int size = GetUserDefaultLocaleName(name, LOCALE_NAME_MAX_LENGTH);
|
||||
if (size <= 1) { // including '\0'
|
||||
return "GetUserDefaultLocaleName() failed";
|
||||
}
|
||||
ffStrbufAppendNWS(result, (uint32_t) size - 1, name);
|
||||
if (result->length > 2 && result->chars[2] == '-') { // Windows uses '-' instead of '_'
|
||||
result->chars[2] = '_';
|
||||
}
|
||||
|
||||
ffStrbufSetNWS(result, (uint32_t) size - 1, name);
|
||||
uint32_t codePage = instance.state.platform.initCP;
|
||||
if (__builtin_expect(codePage != 0, true)) {
|
||||
ffStrbufAppendC(result, '.');
|
||||
|
||||
switch (codePage) {
|
||||
case CP_UTF8:
|
||||
ffStrbufAppendS(result, "UTF-8");
|
||||
break;
|
||||
case CP_UTF7:
|
||||
ffStrbufAppendS(result, "UTF-7");
|
||||
break;
|
||||
case 1200:
|
||||
ffStrbufAppendS(result, "UTF-16LE");
|
||||
break;
|
||||
case 1201:
|
||||
ffStrbufAppendS(result, "UTF-16BE");
|
||||
break;
|
||||
case 936:
|
||||
ffStrbufAppendS(result, "GBK");
|
||||
break;
|
||||
case 54936:
|
||||
ffStrbufAppendS(result, "GB18030");
|
||||
break;
|
||||
case 950:
|
||||
ffStrbufAppendS(result, "BIG5");
|
||||
break;
|
||||
case 932:
|
||||
ffStrbufAppendS(result, "Shift_JIS");
|
||||
break;
|
||||
case 949:
|
||||
ffStrbufAppendS(result, "EUC-KR");
|
||||
break;
|
||||
case 20932:
|
||||
ffStrbufAppendS(result, "EUC-JP");
|
||||
break;
|
||||
|
||||
case 20866:
|
||||
ffStrbufAppendS(result, "KOI8-R");
|
||||
break;
|
||||
case 21866:
|
||||
ffStrbufAppendS(result, "KOI8-U");
|
||||
break;
|
||||
case 20127:
|
||||
ffStrbufAppendS(result, "US-ASCII");
|
||||
break;
|
||||
|
||||
case 874:
|
||||
case 1250 ... 1258:
|
||||
ffStrbufAppendS(result, "Windows-");
|
||||
ffStrbufAppendUInt(result, codePage);
|
||||
break;
|
||||
|
||||
default:
|
||||
ffStrbufAppendS(result, "CP");
|
||||
ffStrbufAppendUInt(result, codePage);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -8,9 +8,39 @@ void ffDetectOSImpl(FFOSResult* os) {
|
||||
|
||||
ffSettingsGetAndroidProperty("ro.build.version.release", &os->version);
|
||||
|
||||
ffSettingsGetAndroidProperty("ro.build.version.release", &os->versionID);
|
||||
ffStrbufSet(&os->versionID, &os->version);
|
||||
|
||||
ffSettingsGetAndroidProperty("ro.build.version.codename", &os->codename);
|
||||
unsigned major = 0;
|
||||
for (const char* p = os->version.chars; *p >= '0' && *p <= '9'; ++p) {
|
||||
major = major * 10 + (unsigned) (*p - '0');
|
||||
}
|
||||
|
||||
const char* codename = NULL;
|
||||
// https://en.wikipedia.org/wiki/Android_version_history
|
||||
// Android 5 is the oldest version supported by Termux
|
||||
// clang-format off
|
||||
switch (major) {
|
||||
case 17: codename = "Cinnamon Bun"; break;
|
||||
case 16: codename = "Baklava"; break;
|
||||
case 15: codename = "Vanilla Ice Cream"; break;
|
||||
case 14: codename = "Upside Down Cake"; break;
|
||||
case 13: codename = "Tiramisu"; break;
|
||||
case 12: codename = "Snow Cone"; break;
|
||||
case 11: codename = "Red Velvet Cake"; break;
|
||||
case 10: codename = "Quince Tart"; break;
|
||||
case 9: codename = "Pie"; break;
|
||||
case 8: codename = "Oreo"; break;
|
||||
case 7: codename = "Nougat"; break;
|
||||
case 6: codename = "Marshmallow"; break;
|
||||
case 5: codename = "Lollipop"; break;
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
if (codename) {
|
||||
ffStrbufSetStatic(&os->codename, codename);
|
||||
} else {
|
||||
ffSettingsGetAndroidProperty("ro.build.version.codename", &os->codename);
|
||||
}
|
||||
|
||||
ffSettingsGetAndroidProperty("ro.build.id", &os->buildID);
|
||||
}
|
||||
|
||||
@@ -23,13 +23,13 @@ static void detectAlacritty(FFTerminalFontResult* terminalFont) {
|
||||
};
|
||||
|
||||
// alacritty parses config files in this order
|
||||
if (ffParsePropFileConfigValues("alacritty/alacritty.toml", 2, fontQueryToml)) {
|
||||
if (ffParsePropFileConfigValues("alacritty/alacritty.toml", 3, fontQueryToml)) {
|
||||
break;
|
||||
}
|
||||
if (ffParsePropFileConfigValues("alacritty.toml", 2, fontQueryToml)) {
|
||||
if (ffParsePropFileConfigValues("alacritty.toml", 3, fontQueryToml)) {
|
||||
break;
|
||||
}
|
||||
if (ffParsePropFileConfigValues(".alacritty.toml", 2, fontQueryToml)) {
|
||||
if (ffParsePropFileConfigValues(".alacritty.toml", 3, fontQueryToml)) {
|
||||
break;
|
||||
}
|
||||
} while (false);
|
||||
@@ -69,7 +69,7 @@ static void detectAlacritty(FFTerminalFontResult* terminalFont) {
|
||||
ffFontInitMoveValues(&terminalFont->font, &fontFamily, &fontSize, &fontStyle);
|
||||
}
|
||||
|
||||
static void parseGhosttyConfig(const FFstrbuf* path, FFstrbuf* fontName, FFstrbuf* fontNameFallback, FFstrbuf* fontSize, FFlist* configFiles /* list of FFstrbuf */) {
|
||||
static void parseGhosttyConfig(FFstrbuf* path, FFstrbuf* fontName, FFstrbuf* fontNameFallback, FFstrbuf* fontSize, FFlist* configFiles /* list of FFstrbuf */) {
|
||||
// Maximum number of `config-file` directives to follow, guarding against runaway includes
|
||||
enum { FF_GHOSTTY_MAX_CONFIG_FILES = 16 };
|
||||
|
||||
@@ -79,7 +79,18 @@ static void parseGhosttyConfig(const FFstrbuf* path, FFstrbuf* fontName, FFstrbu
|
||||
FF_STRBUF_AUTO_DESTROY temp = ffStrbufCreate();
|
||||
if (!ffAppendFileBuffer(path->chars, &buffer)) {
|
||||
FF_DEBUG("cannot read config: %s", path->chars);
|
||||
return;
|
||||
if (ffStrbufEndsWithS(path, ".ghostty")) {
|
||||
FF_DEBUG("Trying to load config without .ghostty extension");
|
||||
path->chars[path->length - strlen(".ghostty")] = '\0';
|
||||
bool ok = ffAppendFileBuffer(path->chars, &buffer);
|
||||
path->chars[path->length - strlen(".ghostty")] = '.';
|
||||
if (!ok) {
|
||||
FF_DEBUG("cannot read config: %s", path->chars);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
char* line = nullptr;
|
||||
@@ -87,13 +98,17 @@ static void parseGhosttyConfig(const FFstrbuf* path, FFstrbuf* fontName, FFstrbu
|
||||
while (ffStrbufGetline(&line, &len, &buffer)) {
|
||||
if (ffParsePropLine(line, "font-family =", &temp)) {
|
||||
FF_DEBUG("found font-family='%s' in %s", temp.chars, path->chars);
|
||||
// Latter overrides former; former becomes the fallback font
|
||||
if (fontName->length > 0) {
|
||||
ffStrbufDestroy(fontNameFallback);
|
||||
ffStrbufInitMove(fontNameFallback, fontName);
|
||||
// Ghostty appends to a fallback list; the first entry is the primary font.
|
||||
// An empty value resets the list.
|
||||
if (temp.length == 0) {
|
||||
ffStrbufClear(fontName);
|
||||
ffStrbufClear(fontNameFallback);
|
||||
} else if (fontName->length == 0) {
|
||||
ffStrbufSet(fontName, &temp);
|
||||
} else if (fontNameFallback->length == 0) {
|
||||
ffStrbufSet(fontNameFallback, &temp);
|
||||
}
|
||||
ffStrbufDestroy(fontName);
|
||||
ffStrbufInitMove(fontName, &temp);
|
||||
ffStrbufClear(&temp);
|
||||
} else if (ffParsePropLine(line, "font-size =", &temp)) {
|
||||
FF_DEBUG("found font-size='%s' in %s", temp.chars, path->chars);
|
||||
// Latter overrides former
|
||||
@@ -394,7 +409,7 @@ static bool detectTerminalFontCommon(const FFTerminalResult* terminal, FFTermina
|
||||
} else if (ffStrbufStartsWithIgnCaseS(&terminal->processName, "contour")) {
|
||||
detectContour(&terminal->exe, terminalFont);
|
||||
} else if (ffStrbufStartsWithIgnCaseS(&terminal->processName, "ghostty")) {
|
||||
detectGhostty(terminalFont, "com.mitchellh.ghostty/config", "ghostty/config");
|
||||
detectGhostty(terminalFont, "com.mitchellh.ghostty/config.ghostty", "ghostty/config.ghostty");
|
||||
} else if (ffStrbufStartsWithIgnCaseS(&terminal->processName, "Muxy")) {
|
||||
detectGhostty(terminalFont, "Muxy/ghostty.conf", "muxy/ghostty.conf");
|
||||
} else if (ffStrbufStartsWithIgnCaseS(&terminal->processName, "rio")) {
|
||||
|
||||
@@ -3,9 +3,20 @@
|
||||
#include "common/apple/osascript.h"
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
const char* ffDetectWallpaper(FFstrbuf* result)
|
||||
{
|
||||
{
|
||||
// Reliable for user-picked static images.
|
||||
NSURL* url = [NSWorkspace.sharedWorkspace desktopImageURLForScreen:NSScreen.mainScreen];
|
||||
if (url.fileURL && ![url.path isEqualToString:@"/System/Library/CoreServices/DefaultDesktop.heic"] /* dynamic wallpapers */)
|
||||
{
|
||||
ffStrbufSetS(result, url.path.UTF8String);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// For Sonoma
|
||||
// https://github.com/JohnCoates/Aerial/issues/1332
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
#include "fastfetch.h"
|
||||
#include "wmtheme.h"
|
||||
#include "common/apple/cf_helpers.h"
|
||||
|
||||
bool ffDetectWmTheme(FFstrbuf* themeOrError) {
|
||||
// Read via cfprefsd instead of the raw plist file to keep cache consistency with the system
|
||||
FF_CFTYPE_AUTO_RELEASE CFTypeRef wmThemeColor = CFPreferencesCopyAppValue(CFSTR("AppleAccentColor"), kCFPreferencesAnyApplication);
|
||||
int32_t accentColor = -2; // -2: not set; -1 is Graphite
|
||||
if (wmThemeColor && ffCfNumGetInt(wmThemeColor, &accentColor) == nullptr) {
|
||||
switch (accentColor) {
|
||||
case -1:
|
||||
ffStrbufAppendS(themeOrError, "Graphite");
|
||||
break;
|
||||
case 0:
|
||||
ffStrbufAppendS(themeOrError, "Red");
|
||||
break;
|
||||
case 1:
|
||||
ffStrbufAppendS(themeOrError, "Orange");
|
||||
break;
|
||||
case 2:
|
||||
ffStrbufAppendS(themeOrError, "Yellow");
|
||||
break;
|
||||
case 3:
|
||||
ffStrbufAppendS(themeOrError, "Green");
|
||||
break;
|
||||
case 4:
|
||||
ffStrbufAppendS(themeOrError, "Blue");
|
||||
break;
|
||||
case 5:
|
||||
ffStrbufAppendS(themeOrError, "Purple");
|
||||
break;
|
||||
case 6:
|
||||
ffStrbufAppendS(themeOrError, "Pink");
|
||||
break;
|
||||
default:
|
||||
ffStrbufAppendS(themeOrError, "Unknown");
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
ffStrbufAppendS(themeOrError, "Multicolor");
|
||||
}
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY style = ffStrbufCreate();
|
||||
FF_CFTYPE_AUTO_RELEASE CFTypeRef wmTheme = CFPreferencesCopyAppValue(CFSTR("AppleInterfaceStyle"), kCFPreferencesAnyApplication);
|
||||
if (wmTheme && ffCfStrGetString(wmTheme, &style) == nullptr) {
|
||||
ffStrbufAppendF(themeOrError, " (%s)", style.chars);
|
||||
} else {
|
||||
ffStrbufAppendS(themeOrError, " (Light)");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
#include "fastfetch.h"
|
||||
#include "wmtheme.h"
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
bool ffDetectWmTheme(FFstrbuf* themeOrError)
|
||||
{
|
||||
NSError* error;
|
||||
NSString* fileName = [NSString stringWithFormat:@"file://%s/Library/Preferences/.GlobalPreferences.plist", instance.state.platform.homeDir.chars];
|
||||
NSDictionary* dict = [NSDictionary dictionaryWithContentsOfURL:[NSURL URLWithString:fileName]
|
||||
error:&error];
|
||||
if(error)
|
||||
{
|
||||
ffStrbufAppendS(themeOrError, error.localizedDescription.UTF8String);
|
||||
return false;
|
||||
}
|
||||
|
||||
NSNumber* wmThemeColor = dict[@"AppleAccentColor"];
|
||||
if(!wmThemeColor)
|
||||
ffStrbufAppendS(themeOrError, "Multicolor");
|
||||
else
|
||||
{
|
||||
switch(wmThemeColor.intValue)
|
||||
{
|
||||
case -1: ffStrbufAppendS(themeOrError, "Graphite"); break;
|
||||
case 0: ffStrbufAppendS(themeOrError, "Red"); break;
|
||||
case 1: ffStrbufAppendS(themeOrError, "Orange"); break;
|
||||
case 2: ffStrbufAppendS(themeOrError, "Yellow"); break;
|
||||
case 3: ffStrbufAppendS(themeOrError, "Green"); break;
|
||||
case 4: ffStrbufAppendS(themeOrError, "Blue"); break;
|
||||
case 5: ffStrbufAppendS(themeOrError, "Purple"); break;
|
||||
case 6: ffStrbufAppendS(themeOrError, "Pink"); break;
|
||||
default: ffStrbufAppendS(themeOrError, "Unknown"); break;
|
||||
}
|
||||
}
|
||||
|
||||
NSString* wmTheme = dict[@"AppleInterfaceStyle"];
|
||||
ffStrbufAppendF(themeOrError, " (%s)", wmTheme ? wmTheme.UTF8String : "Light");
|
||||
return true;
|
||||
}
|
||||
@@ -31,7 +31,6 @@ typedef struct FFstate {
|
||||
uint32_t logoWidth;
|
||||
uint32_t logoHeight;
|
||||
uint32_t keysHeight;
|
||||
bool terminalLightTheme;
|
||||
bool titleFqdn;
|
||||
uint32_t dynamicInterval;
|
||||
FFPlatform platform;
|
||||
|
||||
@@ -996,7 +996,7 @@ bool ffLogoPrintImageIfExists(FFLogoType type, bool printError) {
|
||||
}
|
||||
|
||||
const char* term = getenv("TERM");
|
||||
if ((term && ffStrEquals(term, "screen")) || getenv("ZELLIJ")) {
|
||||
if (term && ffStrEquals(term, "screen")) {
|
||||
if (printError) {
|
||||
fputs("Logo: Image logo is not supported in terminal multiplexers\n", stderr);
|
||||
}
|
||||
|
||||
+22
-7
@@ -5,6 +5,10 @@
|
||||
#include "common/strutil.h"
|
||||
#include "options/display.h"
|
||||
|
||||
#if !FF_MODULE_DISABLE_TERMINALTHEME
|
||||
#include "detection/terminaltheme/terminaltheme.h"
|
||||
#endif
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
const char* ffOptionsParseDisplayJsonConfig(FFOptionsDisplay* options, yyjson_val* root, yyjson_val** pkey) {
|
||||
@@ -825,11 +829,22 @@ bool ffOptionsParseDisplayCommandLine(FFOptionsDisplay* options, const char* key
|
||||
}
|
||||
|
||||
void ffOptionsInitDisplay(FFOptionsDisplay* options) {
|
||||
bool terminalLightTheme = false;
|
||||
#if !FF_MODULE_DISABLE_TERMINALTHEME
|
||||
{
|
||||
// don't enable bright color if the terminal is in light mode
|
||||
FFTerminalThemeResult result;
|
||||
if (ffDetectTerminalTheme(&result, true /* forceEnv for performance */) && !result.bg.dark) {
|
||||
terminalLightTheme = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
ffStrbufInit(&options->colorKeys);
|
||||
ffStrbufInit(&options->colorTitle);
|
||||
ffStrbufInit(&options->colorOutput);
|
||||
ffStrbufInit(&options->colorSeparator);
|
||||
options->brightColor = !instance.state.terminalLightTheme;
|
||||
options->brightColor = !terminalLightTheme;
|
||||
ffStrbufInitStatic(&options->keyValueSeparator, ": ");
|
||||
|
||||
options->showErrors = false;
|
||||
@@ -856,8 +871,8 @@ void ffOptionsInitDisplay(FFOptionsDisplay* options) {
|
||||
options->tempUnit = FF_TEMPERATURE_UNIT_DEFAULT;
|
||||
options->tempNdigits = 1;
|
||||
ffStrbufInitStatic(&options->tempColorGreen, FF_COLOR_FG_GREEN);
|
||||
ffStrbufInitStatic(&options->tempColorYellow, instance.state.terminalLightTheme ? FF_COLOR_FG_YELLOW : FF_COLOR_FG_LIGHT_YELLOW);
|
||||
ffStrbufInitStatic(&options->tempColorRed, instance.state.terminalLightTheme ? FF_COLOR_FG_RED : FF_COLOR_FG_LIGHT_RED);
|
||||
ffStrbufInitStatic(&options->tempColorYellow, terminalLightTheme ? FF_COLOR_FG_YELLOW : FF_COLOR_FG_LIGHT_YELLOW);
|
||||
ffStrbufInitStatic(&options->tempColorRed, terminalLightTheme ? FF_COLOR_FG_RED : FF_COLOR_FG_LIGHT_RED);
|
||||
options->tempSpaceBeforeUnit = FF_SPACE_BEFORE_UNIT_DEFAULT;
|
||||
|
||||
ffStrbufInitStatic(&options->barCharElapsed, "■");
|
||||
@@ -867,8 +882,8 @@ void ffOptionsInitDisplay(FFOptionsDisplay* options) {
|
||||
ffStrbufInit(&options->barBorderLeftElapsed);
|
||||
ffStrbufInit(&options->barBorderRightElapsed);
|
||||
ffStrbufInitStatic(&options->barColorElapsed, "auto");
|
||||
ffStrbufInitStatic(&options->barColorTotal, instance.state.terminalLightTheme ? FF_COLOR_FG_WHITE : FF_COLOR_FG_LIGHT_WHITE);
|
||||
ffStrbufInitStatic(&options->barColorBorder, instance.state.terminalLightTheme ? FF_COLOR_FG_WHITE : FF_COLOR_FG_LIGHT_WHITE);
|
||||
ffStrbufInitStatic(&options->barColorTotal, terminalLightTheme ? FF_COLOR_FG_WHITE : FF_COLOR_FG_LIGHT_WHITE);
|
||||
ffStrbufInitStatic(&options->barColorBorder, terminalLightTheme ? FF_COLOR_FG_WHITE : FF_COLOR_FG_LIGHT_WHITE);
|
||||
options->barWidth = 10;
|
||||
|
||||
options->durationAbbreviation = false;
|
||||
@@ -876,8 +891,8 @@ void ffOptionsInitDisplay(FFOptionsDisplay* options) {
|
||||
options->percentType = FF_PERCENTAGE_TYPE_NUM_BIT | FF_PERCENTAGE_TYPE_NUM_COLOR_BIT;
|
||||
options->percentNdigits = 0;
|
||||
ffStrbufInitStatic(&options->percentColorGreen, FF_COLOR_FG_GREEN);
|
||||
ffStrbufInitStatic(&options->percentColorYellow, instance.state.terminalLightTheme ? FF_COLOR_FG_YELLOW : FF_COLOR_FG_LIGHT_YELLOW);
|
||||
ffStrbufInitStatic(&options->percentColorRed, instance.state.terminalLightTheme ? FF_COLOR_FG_RED : FF_COLOR_FG_LIGHT_RED);
|
||||
ffStrbufInitStatic(&options->percentColorYellow, terminalLightTheme ? FF_COLOR_FG_YELLOW : FF_COLOR_FG_LIGHT_YELLOW);
|
||||
ffStrbufInitStatic(&options->percentColorRed, terminalLightTheme ? FF_COLOR_FG_RED : FF_COLOR_FG_LIGHT_RED);
|
||||
options->percentSpaceBeforeUnit = FF_SPACE_BEFORE_UNIT_DEFAULT;
|
||||
options->percentWidth = 0;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user