From c957ca72304d736ac388368a02f555e806dc0483 Mon Sep 17 00:00:00 2001 From: Carter Li Date: Wed, 2 Apr 2025 14:51:56 +0800 Subject: [PATCH] WM (Linux): query Hyprland version from hyprland dev header --- src/detection/wm/wm_linux.c | 75 ++++++++++++++++++++++++++++++------- 1 file changed, 61 insertions(+), 14 deletions(-) diff --git a/src/detection/wm/wm_linux.c b/src/detection/wm/wm_linux.c index 719ff7ff3..70f4ba579 100644 --- a/src/detection/wm/wm_linux.c +++ b/src/detection/wm/wm_linux.c @@ -6,43 +6,90 @@ #include "util/binary.h" #include "util/path.h" #include "util/stringUtils.h" +#include "util/debug.h" const char* ffDetectWMPlugin(FF_MAYBE_UNUSED FFstrbuf* pluginName) { return "Not supported on this platform"; } -static bool extractHyprlandVersion(const char* line, FF_MAYBE_UNUSED uint32_t len, void *userdata) +static bool extractHyprlandVersion(const char* line, uint32_t len, void *userdata) { + if (line[0] != 'v') return true; + ++line; --len; int count = 0; - sscanf(line, " version: bump to v%*d.%*d.%*d%n", &count); + sscanf(line, "%*d.%*d.%*d%n", &count); if (count == 0) return true; - // SUPER hacky and doesn't work for development versions - uint32_t prefixLen = (uint32_t) strlen(" version: bump to v"); // version bump commit message - ffStrbufSetNS((FFstrbuf*) userdata, len - prefixLen, line + prefixLen); + ffStrbufSetNS((FFstrbuf*) userdata, len, line); return false; } static const char* getHyprland(FFstrbuf* result) { - FF_STRBUF_AUTO_DESTROY path = ffStrbufCreate(); - const char* error = ffFindExecutableInPath("Hyprland", &path); - if (error) return "Failed to find Hyprland executable path"; + FF_DEBUG("Detecting Hyprland version"); + FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate(); - ffBinaryExtractStrings(path.chars, extractHyprlandVersion, result, (uint32_t) strlen(" version: bump to v0.0.0")); - if (result->length > 0) return NULL; + FF_DEBUG("Checking for " FASTFETCH_TARGET_DIR_USR "/include/hyprland/src/version.h" " file"); + if (ffReadFileBuffer(FASTFETCH_TARGET_DIR_USR "/include/hyprland/src/version.h", &buffer)) + { + FF_DEBUG("Found version.h file, extracting version"); + if (ffStrbufSubstrAfterFirstS(&buffer, "\n#define GIT_TAG ")) + { + ffStrbufSubstrAfterFirstC(&buffer, '"'); + ffStrbufSubstrBeforeFirstC(&buffer, '"'); + FF_DEBUG("Extracted version from version.h: %s", buffer.chars); + return NULL; + } + FF_DEBUG("Failed to extract version from version.h"); + ffStrbufClear(&buffer); + } + else + { + FF_DEBUG("version.h file not found, trying Hyprland executable"); + } + + const char* error = ffFindExecutableInPath("Hyprland", &buffer); + if (error) { + FF_DEBUG("Error finding Hyprland executable: %s", error); + return "Failed to find Hyprland executable path"; + } + FF_DEBUG("Found Hyprland executable at: %s", buffer.chars); + + ffBinaryExtractStrings(buffer.chars, extractHyprlandVersion, result, (uint32_t) strlen("v0.0.0")); + if (result->length > 0) { + FF_DEBUG("Extracted version from binary strings: %s", result->chars); + return NULL; + } + FF_DEBUG("Failed to extract version from binary strings, trying --version option"); if (ffProcessAppendStdOut(result, (char* const[]){ - path.chars, + buffer.chars, "--version", NULL }) == NULL) - { // Hyprland 0.46.2 built from branch v0.46.2-b at... long and multi line - ffStrbufSubstrAfterFirstC(result, ' '); - ffStrbufSubstrBeforeFirstC(result, ' '); + { + // Hyprland 0.48.1 built from branch at commit 29e2e59... + // Date: ... + // Tag: v0.48.1, commits: 5937 + // ... + + FF_DEBUG("Raw version output: %s", result->chars); + // Use tag if available + if (ffStrbufSubstrAfterFirstS(result, "\nTag: v")) + { + ffStrbufSubstrBeforeFirstC(result, ','); + FF_DEBUG("Extracted version from Tag: %s", result->chars); + } + else + { + ffStrbufSubstrAfterFirstC(result, ' '); + ffStrbufSubstrBeforeFirstC(result, ' '); + FF_DEBUG("Extracted version from output: %s", result->chars); + } return NULL; } + FF_DEBUG("Failed to run Hyprland --version command"); return "Failed to run command `Hyprland --version`"; }