diff --git a/CHANGELOG.md b/CHANGELOG.md index 584f7cc0a..753feb5fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,17 @@ +# 2.9.1 + +Features: +* Support weston-terminal (missed commit in v2.9.0) (TerminalFont, Linux) +* Support hyprcursor detection (#776, Cursor, Linux) + +Bugfixes: +* Fix `fastfetch --gen-config` raises SIGSEGV when `~/.config/fastfetch` doesn't exist. Regression of `2.9.0` (#778) + # 2.9.0 Features: * Support Lxterminal version detection (Terminal, Linux) -* Support weston-terminal version and font detection (TerminalFont, Linux) +* Support weston-terminal version detection (Terminal, Linux) * Support `am` package manager detection (#771, Packages, Linux) * Support network prefix length detection for IPv6 (LocalIP) * Display all IPs when multiple IPs are assigned to the same interface (LocalIP) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6470145a3..316048646 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.9.0 + VERSION 2.9.1 LANGUAGES C DESCRIPTION "Fast neofetch-like system information tool" HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch" diff --git a/src/common/parsing.c b/src/common/parsing.c index b3f07a509..0d1aaba54 100644 --- a/src/common/parsing.c +++ b/src/common/parsing.c @@ -100,19 +100,19 @@ void ffParseGTK(FFstrbuf* buffer, const FFstrbuf* gtk2, const FFstrbuf* gtk3, co { if(gtk2->length > 0 && gtk3->length > 0 && gtk4->length > 0) { - if((ffStrbufIgnCaseComp(gtk2, gtk3) == 0) && (ffStrbufIgnCaseComp(gtk2, gtk4) == 0)) + if((ffStrbufIgnCaseEqual(gtk2, gtk3)) && (ffStrbufIgnCaseEqual(gtk2, gtk4))) { ffStrbufAppend(buffer, gtk4); ffStrbufAppendS(buffer, " [GTK2/3/4]"); } - else if(ffStrbufIgnCaseComp(gtk2, gtk3) == 0) + else if(ffStrbufIgnCaseEqual(gtk2, gtk3)) { ffStrbufAppend(buffer, gtk3); ffStrbufAppendS(buffer, " [GTK2/3], "); ffStrbufAppend(buffer, gtk4); ffStrbufAppendS(buffer, " [GTK4]"); } - else if(ffStrbufIgnCaseComp(gtk3, gtk4) == 0) + else if(ffStrbufIgnCaseEqual(gtk3, gtk4)) { ffStrbufAppend(buffer, gtk2); ffStrbufAppendS(buffer, " [GTK2], "); @@ -131,7 +131,7 @@ void ffParseGTK(FFstrbuf* buffer, const FFstrbuf* gtk2, const FFstrbuf* gtk3, co } else if(gtk2->length > 0 && gtk3->length > 0) { - if(ffStrbufIgnCaseComp(gtk2, gtk3) == 0) + if(ffStrbufIgnCaseEqual(gtk2, gtk3)) { ffStrbufAppend(buffer, gtk3); ffStrbufAppendS(buffer, " [GTK2/3]"); @@ -146,7 +146,7 @@ void ffParseGTK(FFstrbuf* buffer, const FFstrbuf* gtk2, const FFstrbuf* gtk3, co } else if(gtk3->length > 0 && gtk4->length > 0) { - if(ffStrbufIgnCaseComp(gtk3, gtk4) == 0) + if(ffStrbufIgnCaseEqual(gtk3, gtk4)) { ffStrbufAppend(buffer, gtk4); ffStrbufAppendS(buffer, " [GTK3/4]"); diff --git a/src/detection/cursor/cursor_linux.c b/src/detection/cursor/cursor_linux.c index 17ff04765..bd8c9b1cd 100644 --- a/src/detection/cursor/cursor_linux.c +++ b/src/detection/cursor/cursor_linux.c @@ -68,18 +68,33 @@ static bool detectCursorFromEnv(FFCursorResult* result) return true; } +static bool detectCursorHyprcursor(FFCursorResult* result) +{ + const char* hyprcursor_theme = getenv("HYPRCURSOR_THEME"); + + if(!ffStrSet(hyprcursor_theme)) + return false; + + ffStrbufAppendS(&result->theme, hyprcursor_theme); + ffStrbufAppendS(&result->size, getenv("HYPRCURSOR_SIZE")); + + return true; +} + void ffDetectCursor(FFCursorResult* result) { const FFDisplayServerResult* wmde = ffConnectDisplayServer(); - if(ffStrbufCompS(&wmde->wmPrettyName, FF_WM_PRETTY_WSLG) == 0) + if(ffStrbufEqualS(&wmde->wmPrettyName, FF_WM_PRETTY_WSLG)) ffStrbufAppendS(&result->error, "WSLg uses native windows cursor"); - else if(ffStrbufIgnCaseCompS(&wmde->wmProtocolName, FF_WM_PROTOCOL_TTY) == 0) + else if(ffStrbufIgnCaseEqualS(&wmde->wmProtocolName, FF_WM_PROTOCOL_TTY)) ffStrbufAppendS(&result->error, "Cursor isn't supported in TTY"); - else if(ffStrbufIgnCaseCompS(&wmde->dePrettyName, FF_DE_PRETTY_PLASMA) == 0) + else if(ffStrbufIgnCaseEqualS(&wmde->dePrettyName, FF_DE_PRETTY_PLASMA)) detectCursorFromConfigFile("kcminputrc", "cursorTheme =", "Breeze", "cursorSize =", "24", result); - else if(ffStrbufStartsWithIgnCaseS(&wmde->dePrettyName, FF_DE_PRETTY_LXQT)) + else if(ffStrbufIgnCaseEqualS(&wmde->dePrettyName, FF_DE_PRETTY_LXQT)) detectCursorFromConfigFile("lxqt/session.conf", "cursor_theme =", "Adwaita", "cursor_size =", "24", result); + else if(ffStrbufIgnCaseEqualS(&wmde->wmPrettyName, FF_WM_PRETTY_HYPRLAND) && detectCursorHyprcursor(result)) + return; else if( !detectCursorGTK(result) && !detectCursorFromEnv(result) && diff --git a/src/detection/displayserver/displayserver.h b/src/detection/displayserver/displayserver.h index b5655a84f..9c6c2d96e 100644 --- a/src/detection/displayserver/displayserver.h +++ b/src/detection/displayserver/displayserver.h @@ -21,6 +21,7 @@ #define FF_WM_PRETTY_XFWM4 "Xfwm4" #define FF_WM_PRETTY_OPENBOX "Openbox" #define FF_WM_PRETTY_I3 "i3" +#define FF_WM_PRETTY_HYPRLAND "Hyprland" #define FF_WM_PRETTY_WAYFIRE "Wayfire" #define FF_WM_PRETTY_SWAY "Sway" #define FF_WM_PRETTY_BSPWM "bspwm" diff --git a/src/detection/displayserver/linux/wmde.c b/src/detection/displayserver/linux/wmde.c index 625f04e47..5d21f1d6c 100644 --- a/src/detection/displayserver/linux/wmde.c +++ b/src/detection/displayserver/linux/wmde.c @@ -52,6 +52,9 @@ static const char* parseEnv(void) if(getenv("TDE_FULL_SESSION") != NULL) return "Trinity"; + if(getenv("HYPRLAND_CMD") != NULL) + return "Hyprland"; + #ifdef __linux__ if( getenv("WAYLAND_DISPLAY") != NULL && @@ -116,6 +119,8 @@ static void applyPrettyNameIfWM(FFDisplayServerResult* result, const char* name) ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_ICEWM); else if(ffStrEqualsIgnCase(name, "dtwm")) ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_DTWM); + else if(ffStrEqualsIgnCase(name, "hyprland")) + ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_HYPRLAND); } static void applyNameIfWM(FFDisplayServerResult* result, const char* processName) diff --git a/src/detection/gtk_qt/qt.c b/src/detection/gtk_qt/qt.c index a18a324b1..331de6609 100644 --- a/src/detection/gtk_qt/qt.c +++ b/src/detection/gtk_qt/qt.c @@ -151,9 +151,9 @@ const FFQtResult* ffDetectQt(void) const FFDisplayServerResult* wmde = ffConnectDisplayServer(); - if(ffStrbufIgnCaseCompS(&wmde->dePrettyName, FF_DE_PRETTY_PLASMA) == 0) + if(ffStrbufIgnCaseEqualS(&wmde->dePrettyName, FF_DE_PRETTY_PLASMA)) detectPlasma(&result); - else if(ffStrbufIgnCaseCompS(&wmde->dePrettyName, FF_DE_PRETTY_LXQT) == 0) + else if(ffStrbufIgnCaseEqualS(&wmde->dePrettyName, FF_DE_PRETTY_LXQT)) detectLXQt(&result); return &result; diff --git a/src/detection/terminalfont/terminalfont_linux.c b/src/detection/terminalfont/terminalfont_linux.c index 3a6ac9086..247959fc3 100644 --- a/src/detection/terminalfont/terminalfont_linux.c +++ b/src/detection/terminalfont/terminalfont_linux.c @@ -325,6 +325,19 @@ static void detectWarp(FFTerminalFontResult* terminalFont) } } +static void detectWestonTerminal(FFTerminalFontResult* terminalFont) +{ + FF_STRBUF_AUTO_DESTROY font = ffStrbufCreate(); + FF_STRBUF_AUTO_DESTROY size = ffStrbufCreate(); + ffParsePropFileConfigValues("weston.ini", 2, (FFpropquery[]) { + {"font=", &font}, + {"font-size=", &size}, + }); + if (!font.length) ffStrbufSetStatic(&font, "DejaVu Sans Mono"); + if (!size.length) ffStrbufSetStatic(&size, "14"); + ffFontInitValues(&terminalFont->font, font.chars, size.chars); +} + void ffDetectTerminalFontPlatform(const FFTerminalResult* terminal, FFTerminalFontResult* terminalFont) { if(ffStrbufIgnCaseEqualS(&terminal->processName, "konsole")) @@ -355,4 +368,6 @@ void ffDetectTerminalFontPlatform(const FFTerminalResult* terminal, FFTerminalFo detectSt(terminalFont, terminal->pid); else if(ffStrbufIgnCaseEqualS(&terminal->processName, "warp")) detectWarp(terminalFont); + else if(ffStrbufIgnCaseEqualS(&terminal->processName, "weston-terminal")) + detectWestonTerminal(terminalFont); } diff --git a/src/fastfetch.c b/src/fastfetch.c index 20f316d0e..0109c2717 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -821,7 +821,6 @@ static void run(FFdata* data) if (instance.state.resultDoc) { yyjson_mut_write_fp(stdout, instance.state.resultDoc, YYJSON_WRITE_INF_AND_NAN_AS_NULL | YYJSON_WRITE_PRETTY_TWO_SPACES, NULL, NULL); - //TODO should use YYJSON_WRITE_NEWLINE_AT_END when it is available putchar('\n'); } else @@ -841,23 +840,24 @@ static void writeConfigFile(FFdata* data, const FFstrbuf* filename) ffOptionsGenerateLibraryJsonConfig(&instance.config.library, doc); ffMigrateCommandOptionToJsonc(data, doc); - FILE *fp = stdout; - bool writeToStdout = ffStrbufEqualS(filename, "-"); - if (!writeToStdout) - fp = fopen(filename->chars, "w"); - - bool ok = yyjson_mut_write_fp(fp, doc, YYJSON_WRITE_INF_AND_NAN_AS_NULL | YYJSON_WRITE_PRETTY_TWO_SPACES, NULL, NULL); - //TODO should use YYJSON_WRITE_NEWLINE_AT_END when it is available - fputc('\n', fp); - if (!ok) + if (ffStrbufEqualS(filename, "-")) + yyjson_mut_write_fp(stdout, doc, YYJSON_WRITE_INF_AND_NAN_AS_NULL | YYJSON_WRITE_PRETTY_TWO_SPACES, NULL, NULL); + else { - fprintf(stderr, "Error: failed to generate config in `%s`\n", writeToStdout ? "stdout" : filename->chars); - exit(1); - } - if (ok && !writeToStdout) - { - fclose(fp); - printf("The generated config file has been written in `%s`\n", filename->chars); + size_t len; + FF_AUTO_FREE const char* str = yyjson_mut_write(doc, YYJSON_WRITE_INF_AND_NAN_AS_NULL | YYJSON_WRITE_PRETTY_TWO_SPACES, &len); + if (!str) + { + printf("Error: failed to generate config file\n"); + exit(1); + } + if (ffWriteFileData(filename->chars, len, str)) + printf("The generated config file has been written in `%s`\n", filename->chars); + else + { + printf("Error: failed to write file in `%s`\n", filename->chars); + exit(1); + } } yyjson_mut_doc_free(doc);