2025-01-02 11:13:28 +09:00
|
|
|
#include "wm.h"
|
|
|
|
|
|
|
|
|
|
#include "common/processing.h"
|
2025-01-02 20:19:15 +08:00
|
|
|
#include "common/io/io.h"
|
2025-01-02 11:13:28 +09:00
|
|
|
#include "detection/displayserver/displayserver.h"
|
2025-01-02 16:36:31 +08:00
|
|
|
#include "util/binary.h"
|
|
|
|
|
#include "util/path.h"
|
|
|
|
|
#include "util/stringUtils.h"
|
2025-01-02 11:13:28 +09:00
|
|
|
|
|
|
|
|
const char* ffDetectWMPlugin(FF_MAYBE_UNUSED FFstrbuf* pluginName)
|
|
|
|
|
{
|
|
|
|
|
return "Not supported on this platform";
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-02 16:36:31 +08:00
|
|
|
static bool extractHyprlandVersion(const char* line, FF_MAYBE_UNUSED uint32_t len, void *userdata)
|
2025-01-02 11:13:28 +09:00
|
|
|
{
|
2025-01-02 16:36:31 +08:00
|
|
|
int count = 0;
|
2025-04-02 00:11:41 +08:00
|
|
|
sscanf(line, " version: bump to v%*d.%*d.%*d%n", &count);
|
2025-01-02 16:36:31 +08:00
|
|
|
if (count == 0) return true;
|
|
|
|
|
|
2025-04-02 10:14:53 +08:00
|
|
|
// SUPER hacky and doesn't work for development versions
|
2025-04-02 00:11:41 +08:00
|
|
|
uint32_t prefixLen = (uint32_t) strlen(" version: bump to v"); // version bump commit message
|
|
|
|
|
ffStrbufSetNS((FFstrbuf*) userdata, len - prefixLen, line + prefixLen);
|
2025-01-02 16:36:31 +08:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-02 20:19:15 +08:00
|
|
|
static const char* getHyprland(FFstrbuf* result)
|
2025-01-02 16:36:31 +08:00
|
|
|
{
|
|
|
|
|
FF_STRBUF_AUTO_DESTROY path = ffStrbufCreate();
|
|
|
|
|
const char* error = ffFindExecutableInPath("Hyprland", &path);
|
|
|
|
|
if (error) return "Failed to find Hyprland executable path";
|
|
|
|
|
|
2025-04-02 10:14:53 +08:00
|
|
|
ffBinaryExtractStrings(path.chars, extractHyprlandVersion, result, (uint32_t) strlen(" version: bump to v0.0.0"));
|
|
|
|
|
if (result->length > 0) return NULL;
|
2025-01-02 16:36:31 +08:00
|
|
|
|
2025-01-02 11:13:28 +09:00
|
|
|
if (ffProcessAppendStdOut(result, (char* const[]){
|
2025-01-02 16:36:31 +08:00
|
|
|
path.chars,
|
2025-01-02 11:13:28 +09:00
|
|
|
"--version",
|
|
|
|
|
NULL
|
2025-01-02 16:36:31 +08:00
|
|
|
}) == NULL)
|
|
|
|
|
{ // Hyprland 0.46.2 built from branch v0.46.2-b at... long and multi line
|
2025-01-02 11:13:28 +09:00
|
|
|
ffStrbufSubstrAfterFirstC(result, ' ');
|
|
|
|
|
ffStrbufSubstrBeforeFirstC(result, ' ');
|
2025-01-02 16:36:31 +08:00
|
|
|
return NULL;
|
2025-01-02 11:13:28 +09:00
|
|
|
}
|
2025-01-02 16:36:31 +08:00
|
|
|
|
|
|
|
|
return "Failed to run command `Hyprland --version`";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool extractSwayVersion(const char* line, FF_MAYBE_UNUSED uint32_t len, void *userdata)
|
|
|
|
|
{
|
|
|
|
|
if (!ffStrStartsWith(line, "sway version ")) return true;
|
|
|
|
|
|
2025-04-02 10:14:53 +08:00
|
|
|
FFstrbuf* result = (FFstrbuf*) userdata;
|
|
|
|
|
ffStrbufSetNS(result, len - (uint32_t) strlen("sway version "), line + strlen("sway version "));
|
|
|
|
|
ffStrbufTrimRightSpace(result);
|
2025-01-02 16:36:31 +08:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-02 20:19:15 +08:00
|
|
|
static const char* getSway(FFstrbuf* result)
|
2025-01-02 16:36:31 +08:00
|
|
|
{
|
|
|
|
|
FF_STRBUF_AUTO_DESTROY path = ffStrbufCreate();
|
|
|
|
|
const char* error = ffFindExecutableInPath("sway", &path);
|
|
|
|
|
if (error) return "Failed to find sway executable path";
|
|
|
|
|
|
2025-04-02 10:14:53 +08:00
|
|
|
ffBinaryExtractStrings(path.chars, extractSwayVersion, result, (uint32_t) strlen("v0.0.0"));
|
|
|
|
|
if (result->length > 0) return NULL;
|
2025-01-02 16:36:31 +08:00
|
|
|
|
|
|
|
|
if (ffProcessAppendStdOut(result, (char* const[]){
|
|
|
|
|
path.chars,
|
|
|
|
|
"--version",
|
|
|
|
|
NULL
|
|
|
|
|
}) == NULL)
|
|
|
|
|
{ // sway version 1.10
|
|
|
|
|
ffStrbufSubstrAfterLastC(result, ' ');
|
|
|
|
|
ffStrbufTrimRightSpace(result);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return "Failed to run command `sway --version`";
|
2025-01-02 11:13:28 +09:00
|
|
|
}
|
|
|
|
|
|
2025-01-02 20:19:15 +08:00
|
|
|
static const char* getWslg(FFstrbuf* result)
|
|
|
|
|
{
|
|
|
|
|
if (!ffAppendFileBuffer("/mnt/wslg/versions.txt", result))
|
|
|
|
|
return "Failed to read /mnt/wslg/versions.txt";
|
|
|
|
|
|
|
|
|
|
if (!ffStrbufStartsWithS(result, "WSLg "))
|
|
|
|
|
return "Failed to find WSLg version";
|
|
|
|
|
|
|
|
|
|
ffStrbufSubstrBeforeFirstC(result, '\n');
|
|
|
|
|
ffStrbufSubstrBeforeFirstC(result, '+');
|
|
|
|
|
ffStrbufSubstrAfterFirstC(result, ':');
|
|
|
|
|
ffStrbufTrimLeft(result, ' ');
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const char* ffDetectWMVersion(const FFstrbuf* wmName, FFstrbuf* result, FF_MAYBE_UNUSED FFWMOptions* options)
|
2025-01-02 11:13:28 +09:00
|
|
|
{
|
2025-01-02 10:54:44 +08:00
|
|
|
if (!wmName)
|
|
|
|
|
return "No WM detected";
|
|
|
|
|
|
2025-01-02 16:36:31 +08:00
|
|
|
if (ffStrbufEqualS(wmName, "Hyprland"))
|
2025-01-02 20:19:15 +08:00
|
|
|
return getHyprland(result);
|
2025-01-02 16:36:31 +08:00
|
|
|
|
|
|
|
|
if (ffStrbufEqualS(wmName, "sway"))
|
2025-01-02 20:19:15 +08:00
|
|
|
return getSway(result);
|
|
|
|
|
|
|
|
|
|
if (ffStrbufEqualS(wmName, "WSLg"))
|
|
|
|
|
return getWslg(result);
|
2025-01-02 10:54:44 +08:00
|
|
|
|
2025-01-02 16:36:31 +08:00
|
|
|
return "Unsupported WM";
|
2025-01-02 11:13:28 +09:00
|
|
|
}
|