diff --git a/CHANGELOG.md b/CHANGELOG.md index d193851f44..06be822ca8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +# 2.64.2 + +Bugfixes: +* Fixes image rendering being wiped quickly (#2374) + * Regression from v2.64.0 +* Fixes ASCII logo being overwritten in `--dynamic-interval` mode + * Regression from v2.64.0 + +Logos: +* Updates OpenWrt and adds a small variant (#2376) + * The old one is renamed to `openwrt_old` + # 2.64.1 Features: diff --git a/CMakeLists.txt b/CMakeLists.txt index 56dafd95f7..c0211aeda7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url project(fastfetch - VERSION 2.64.1 + VERSION 2.64.2 LANGUAGES C DESCRIPTION "Fast neofetch-like system information tool" HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch" @@ -1638,6 +1638,11 @@ function(ff_lib_enable VARNAME PKGCONFIG_NAMES CMAKE_NAME) # [CMAKE_TARGET_NAME] set(${VARNAME}_LIBRARIES ${_FF_CMAKE_TARGET}) endif() endif() + + if(NOT BINARY_LINK_TYPE STREQUAL "dlopen") + # INTERFACE_LINK_LIBRARIES doesn't expose libvarname.a + target_link_libraries(libfastfetch PRIVATE ${_FF_CMAKE_TARGET}) + endif() endif() else() set(${VARNAME}_INCLUDE_DIRS ${${CMAKE_NAME}_INCLUDE_DIRS}) @@ -1691,8 +1696,8 @@ ff_lib_enable(DRM "Libdrm" ) ff_lib_enable(VA - "libva" - "Libva" + "libva-drm" + "Libva-drm" ) ff_lib_enable(VDPAU "vdpau" diff --git a/src/common/impl/lua.c b/src/common/impl/lua.c index 1f4050a005..ffc1d83c92 100644 --- a/src/common/impl/lua.c +++ b/src/common/impl/lua.c @@ -9,9 +9,7 @@ static yyjson_mut_val* lua2yyjson(lua_State* L, int idx, yyjson_mut_doc* doc, in if (__builtin_expect(depth > 15, false)) { yyjson_mut_doc_free(doc); lua_pushlstring( - L, "yyjson: recursion depth exceeded; possible circular reference", - strlen("yyjson: recursion depth exceeded; possible circular reference") - ); + L, "yyjson: recursion depth exceeded; possible circular reference", strlen("yyjson: recursion depth exceeded; possible circular reference")); lua_error(L); // noreturn __builtin_unreachable(); } @@ -140,7 +138,7 @@ static int yyjsonEncode(lua_State* L) { } } -const char* ffLuaLoadState() { +const char* ffLuaLoadState(void) { if (luaData.inited) { if (luaData.L == NULL) { return "Lua library is not available"; @@ -180,6 +178,8 @@ const char* ffLuaLoadState() { FF_LIBRARY_LOAD_SYMBOL_MESSAGE(liblua, luaopen_string) FF_LIBRARY_LOAD_SYMBOL_MESSAGE(liblua, luaopen_table) #endif + + #if !FF_DISABLE_DLOPEN FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(liblua, luaData, luaL_checkany) FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(liblua, luaData, luaL_loadbufferx) FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(liblua, luaData, luaL_tolstring) @@ -208,6 +208,7 @@ const char* ffLuaLoadState() { FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(liblua, luaData, lua_tolstring) FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(liblua, luaData, lua_tonumberx) FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(liblua, luaData, lua_type) + #endif lua_State* L = ffluaL_newstate(); if (L == NULL) { diff --git a/src/common/lua.h b/src/common/lua.h index 0c5917cd4d..06343c40e7 100644 --- a/src/common/lua.h +++ b/src/common/lua.h @@ -3,16 +3,19 @@ #include "fastfetch.h" #if FF_HAVE_LUA - // Hack. LUA_API is defined as extern which prevents us from implementing the functions ourselves. - #include - #undef LUA_API - #undef LUALIB_API - #undef LUAMOD_API - #define LUA_API static inline - #define LUALIB_API LUA_API - #define LUAMOD_API LUA_API - - #pragma GCC diagnostic ignored "-Wunused-function" + #if !FF_DISABLE_DLOPEN + // Hack. LUA_API is defined as extern which prevents us from implementing the functions ourselves. + #include + #undef LUA_API + #undef LUALIB_API + #undef LUAMOD_API + #define LUA_API static inline + #define LUALIB_API LUA_API + #define LUAMOD_API LUA_API + + #pragma GCC diagnostic ignored "-Wunused-function" + #endif + #include #include #include @@ -24,6 +27,7 @@ #include "common/library.h" extern struct FFLuaData { + #if !FF_DISABLE_DLOPEN FF_LIBRARY_SYMBOL(luaL_checkany) FF_LIBRARY_SYMBOL(luaL_loadbufferx) FF_LIBRARY_SYMBOL(luaL_tolstring) @@ -52,13 +56,13 @@ extern struct FFLuaData { FF_LIBRARY_SYMBOL(lua_tolstring) FF_LIBRARY_SYMBOL(lua_tonumberx) FF_LIBRARY_SYMBOL(lua_type) + #endif lua_State* L; bool inited; } luaData; -const char* ffLuaLoadState(); - + #if !FF_DISABLE_DLOPEN FF_A_ALWAYS_INLINE void(lua_settop)(lua_State* L, int idx) { return luaData.fflua_settop(L, idx); } @@ -148,11 +152,11 @@ FF_A_ALWAYS_INLINE int(lua_rawgeti)(lua_State* L, int idx, lua_Integer n) { } FF_A_ALWAYS_INLINE - #if LUA_VERSION_NUM > 503 + #if LUA_VERSION_NUM > 503 lua_Unsigned - #else + #else size_t - #endif + #endif (lua_rawlen)(lua_State* L, int idx) { return luaData.fflua_rawlen(L, idx); } @@ -176,5 +180,8 @@ FF_A_ALWAYS_INLINE lua_Number(lua_tonumberx)(lua_State* L, int idx, int* isnum) FF_A_ALWAYS_INLINE int(lua_type)(lua_State* L, int idx) { return luaData.fflua_type(L, idx); } + #endif + +const char* ffLuaLoadState(void); #endif diff --git a/src/fastfetch.c b/src/fastfetch.c index a82d853ebe..dc5c1797d8 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -765,9 +765,12 @@ static void run(FFdata* data) { } if (instance.state.dynamicInterval > 0) { + ffLogoPrintRemaining(); // `logoLineCacheClear` inside so that ffLogoPrintLine will use `\e[nC` to move the cursor to the right position instead of reprinting the logo + fputs("\e[J", stdout); // Clear from cursor to the end of the screen to prevent artifacts when the new output is shorter than the previous one fflush(stdout); ffTimeSleep(instance.state.dynamicInterval); - fputs("\e[H", stdout); + fputs("\e[H", stdout); // Move cursor to the top left corner to overwrite the previous output + instance.state.keysHeight = 0; // Reset keysHeight so `ffLogoPrintRemaining` will recalculate it } else { break; } diff --git a/src/logo/ascii/o.inc b/src/logo/ascii/o.inc index 0ddb7fdf42..b1840dc28e 100644 --- a/src/logo/ascii/o.inc +++ b/src/logo/ascii/o.inc @@ -291,6 +291,34 @@ static const FFlogo O[] = { { .names = { "openwrt" }, .lines = FASTFETCH_DATATEXT_LOGO_OPENWRT, + .colors = { + FF_COLOR_FG_DEFAULT, + FF_COLOR_FG_BLUE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_DEFAULT, + }, + #endif + #ifdef FASTFETCH_DATATEXT_LOGO_OPENWRT_SMALL + // OpenWrtSmall + { + .names = { "openwrt_small" }, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_OPENWRT_SMALL, + .colors = { + FF_COLOR_FG_DEFAULT, + FF_COLOR_FG_BLUE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_DEFAULT, + }, + #endif + #ifdef FASTFETCH_DATATEXT_LOGO_OPENWRT_OLD + // OpenWrtOld + { + .names = { "openwrt_old" }, + .type = FF_LOGO_LINE_TYPE_ALTER_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_OPENWRT_OLD, .colors = { FF_COLOR_FG_BLUE, }, diff --git a/src/logo/ascii/o/openwrt.txt b/src/logo/ascii/o/openwrt.txt index 47e4e1944e..cbb4c0b9df 100644 --- a/src/logo/ascii/o/openwrt.txt +++ b/src/logo/ascii/o/openwrt.txt @@ -1,9 +1,18 @@ - _______ -| |.-----.-----.-----. -| - || _ | -__| | -|_______|| __|_____|__|__| - |__| - ________ __ -| | | |.----.| |_ -| | | || _|| _| -|________||__| |____| \ No newline at end of file + ..,,.. + ,;odOMMMMMMMMObo:. + ,odOMMMMMO""''""OMMMMMObo. +.dMMMM" .,,. "OMMMb, + '0" ,;ddMMMMMMMMbb:. "0' + oOMMMMO""''""OMMMMOo + $2;. $1'0" .,,. "0' $2.: + .OMM* $1.odMMMMMMbo. $2*MMO. + MMMO $1"0"````"0" $2OMMM +iOMM $1.oo. $2MMMi +OMMl $1:MMMM: $2lMMO +iMMM $1'oo' $2MMMi + OMMb $2dMMO + 'OMMO. ,OMMO' + "MMMb. ,dMMM" + "MMMMbgo-,,-ogdMMMM" + "*MMMMMMMMMM*" + `'""'` \ No newline at end of file diff --git a/src/logo/ascii/o/openwrt_old.txt b/src/logo/ascii/o/openwrt_old.txt new file mode 100644 index 0000000000..47e4e1944e --- /dev/null +++ b/src/logo/ascii/o/openwrt_old.txt @@ -0,0 +1,9 @@ + _______ +| |.-----.-----.-----. +| - || _ | -__| | +|_______|| __|_____|__|__| + |__| + ________ __ +| | | |.----.| |_ +| | | || _|| _| +|________||__| |____| \ No newline at end of file diff --git a/src/logo/ascii/o/openwrt_small.txt b/src/logo/ascii/o/openwrt_small.txt new file mode 100644 index 0000000000..328cbeb472 --- /dev/null +++ b/src/logo/ascii/o/openwrt_small.txt @@ -0,0 +1,9 @@ + ..,.. + ,odM"""""Mbo, + `.odMMMMMbo.` + $2d,$1" ,mmm, "$2,b +iM $1" . " $2Mi +Ml $1dMb $2lM +'M, $1' $2.M' + "0b. ,d0" + `"WWWWW"` \ No newline at end of file diff --git a/src/logo/logo.c b/src/logo/logo.c index 9f2c89244f..571f1aac97 100644 --- a/src/logo/logo.c +++ b/src/logo/logo.c @@ -461,7 +461,7 @@ static bool updateLogoPath(void) { return true; } - #if !FF_MODULE_DISABLE_MEDIA +#if !FF_MODULE_DISABLE_MEDIA if (ffStrbufIgnCaseEqualS(&options->source, "media-cover")) { const FFMediaResult* media = ffDetectMedia(true); if (media->cover.length == 0) { @@ -470,7 +470,7 @@ static bool updateLogoPath(void) { ffStrbufSet(&options->source, &media->cover); return true; } - #endif +#endif FF_STRBUF_AUTO_DESTROY fullPath = ffStrbufCreateA(128); if (ffPathExpandEnv(options->source.chars, &fullPath) && ffPathExists(fullPath.chars, FF_PATHTYPE_FILE)) { @@ -639,7 +639,7 @@ void ffLogoPrint(void) { } if (!ffStrbufEndsWithIgnCaseS(&options->source, ".txt")) { - #if !FF_MODULE_DISABLE_TERMINAL +#if !FF_MODULE_DISABLE_TERMINAL const FFTerminalResult* terminal = ffDetectTerminal(); bool supportsIterm2 = ffStrbufEqualS(&terminal->prettyName, "iTerm"); @@ -655,15 +655,15 @@ void ffLogoPrint(void) { ffStrbufIgnCaseEqualS(&terminal->processName, "wezterm") || ffStrbufIgnCaseEqualS(&terminal->processName, "wayst") || ffStrbufIgnCaseEqualS(&terminal->processName, "ghostty") || -#ifdef __APPLE__ + #ifdef __APPLE__ ffStrbufIgnCaseEqualS(&terminal->processName, "WarpTerminal") || -#else + #else ffStrbufIgnCaseEqualS(&terminal->processName, "warp") || -#endif + #endif false; - #else +#else bool supportsKitty = false; - #endif +#endif // Try to load the logo as an image. If it succeeds, print it and return. if (logoPrintImageIfExists(supportsKitty ? FF_LOGO_TYPE_IMAGE_KITTY : FF_LOGO_TYPE_IMAGE_CHAFA, false)) { @@ -685,37 +685,39 @@ void ffLogoPrint(void) { } void ffLogoPrintLine(void) { - uint32_t printedLineWidth = 0; FFLogoLineCacheState* cache = &instance.state.logoLineCache; FFOptionsLogo* logo = &instance.config.logo; - if (cache->lines.length > 0 && (logo->position == FF_LOGO_POSITION_LEFT || logo->position == FF_LOGO_POSITION_RIGHT) && cache->nextLine < cache->lines.length) { - FFLogoCachedLine* line = FF_LIST_GET(FFLogoCachedLine, cache->lines, cache->nextLine); + if (cache->lines.length > 0) { + // Line cache is enabled. Always move cursor with whitespaces to make lolcat happy + if (cache->nextLine < cache->lines.length) { + // Print logo line and move cursor + FFLogoCachedLine* line = FF_LIST_GET(FFLogoCachedLine, cache->lines, cache->nextLine); - if (logo->position == FF_LOGO_POSITION_RIGHT && line->chars.length > 0) { - printf("\033[9999999C\033[%uD", cache->rightOffset); - ffStrbufWriteTo(&line->chars, stdout); - fputs("\033[G", stdout); - } else { - ffStrbufWriteTo(&line->chars, stdout); - printedLineWidth = line->width; - } + if (logo->position == FF_LOGO_POSITION_RIGHT) { + printf("\033[9999999C\033[%uD", cache->rightOffset); + ffStrbufWriteTo(&line->chars, stdout); - ++cache->nextLine; - } + fputs("\033[G", stdout); + } else { + ffStrbufWriteTo(&line->chars, stdout); - if (instance.state.logoWidth > 0) { - if (instance.config.logo.position == FF_LOGO_POSITION_LEFT) { - uint32_t remaining = instance.state.logoWidth; - remaining = printedLineWidth < remaining ? remaining - printedLineWidth : 0; - ffPrintCharTimes(' ', remaining); - } else { - printf("\033[%uC", instance.state.logoWidth); + uint32_t remaining = instance.state.logoWidth; + remaining = line->width < remaining ? remaining - line->width : 0; + ffPrintCharTimes(' ', remaining); + } + ++cache->nextLine; + } else if (logo->position == FF_LOGO_POSITION_LEFT) { + // Move cursor to the start position + ffPrintCharTimes(' ', instance.state.logoWidth); } + } else if (instance.state.logoWidth > 0) { + printf("\033[%uC", instance.state.logoWidth); } - if (instance.state.dynamicInterval > 0) { + if (instance.state.dynamicInterval > 0 && logo->position == FF_LOGO_POSITION_LEFT) { fputs("\033[K", stdout); // Clear to the end of the line + // Note that we don't clear the line when the logo is on the right, as it will also clear the logo itself } ++instance.state.keysHeight;