mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-10-30 00:37:23 +01:00
greatly improved WM / DE detection
This commit is contained in:
+13
-43
@@ -3,59 +3,31 @@
|
||||
#include <string.h>
|
||||
|
||||
#define FF_DE_MODULE_NAME "DE"
|
||||
#define FF_DE_NUM_FORMAT_ARGS 3
|
||||
|
||||
static void getKDE(FFstrbuf* name, FFstrbuf* version)
|
||||
{
|
||||
ffStrbufSetS(name, "KDE Plasma");
|
||||
|
||||
char versionBuf[256];
|
||||
ffParsePropFile("/usr/share/xsessions/plasma.desktop", "X-KDE-PluginInfo-Version=%[^\n]", versionBuf);
|
||||
|
||||
ffStrbufSetS(version, versionBuf);
|
||||
}
|
||||
#define FF_DE_NUM_FORMAT_ARGS 4
|
||||
|
||||
void ffPrintDesktopEnvironment(FFinstance* instance)
|
||||
{
|
||||
const char* sessionDesktop = ffGetSessionDesktop();
|
||||
const FFWMDEResult* result = ffDetectWMDE(instance);
|
||||
|
||||
if(sessionDesktop == NULL)
|
||||
if(result->dePrettyName.length == 0 && result->sessionDesktop == NULL)
|
||||
{
|
||||
ffPrintError(instance, FF_DE_MODULE_NAME, 0, &instance->config.deKey, &instance->config.deFormat, FF_DE_NUM_FORMAT_ARGS, "No relevant XDG_SESSION_* environment variable set");
|
||||
ffPrintError(instance, FF_DE_MODULE_NAME, 0, &instance->config.deKey, &instance->config.deFormat, FF_DE_NUM_FORMAT_ARGS, "No DE found");
|
||||
return;
|
||||
}
|
||||
|
||||
const FFWMResult* wm = ffDetectWM(instance);
|
||||
|
||||
// test if we are running only a WM
|
||||
if(
|
||||
ffStrbufIgnCaseCompS(&wm->processName, sessionDesktop) == 0 ||
|
||||
ffStrbufIgnCaseCompS(&wm->prettyName, sessionDesktop) == 0
|
||||
) return;
|
||||
|
||||
FFstrbuf sessionName;
|
||||
ffStrbufInit(&sessionName);
|
||||
|
||||
FFstrbuf sessionVersion;
|
||||
ffStrbufInit(&sessionVersion);
|
||||
|
||||
if(strcasecmp(sessionDesktop, "KDE") == 0)
|
||||
getKDE(&sessionName, &sessionVersion);
|
||||
|
||||
if(instance->config.deFormat.length == 0)
|
||||
{
|
||||
|
||||
ffPrintLogoAndKey(instance, FF_DE_MODULE_NAME, 0, &instance->config.deKey);
|
||||
|
||||
if(sessionName.length > 0)
|
||||
ffStrbufWriteTo(&sessionName, stdout);
|
||||
if(result->dePrettyName.length > 0)
|
||||
ffStrbufWriteTo(&result->dePrettyName, stdout);
|
||||
else
|
||||
fputs(sessionDesktop, stdout);
|
||||
fputs(result->sessionDesktop, stdout);
|
||||
|
||||
if(sessionVersion.length > 0)
|
||||
if(result->deVersion.length > 0)
|
||||
{
|
||||
putchar(' ');
|
||||
ffStrbufWriteTo(&sessionVersion, stdout);
|
||||
ffStrbufWriteTo(&result->deVersion, stdout);
|
||||
}
|
||||
|
||||
putchar('\n');
|
||||
@@ -63,12 +35,10 @@ void ffPrintDesktopEnvironment(FFinstance* instance)
|
||||
else
|
||||
{
|
||||
ffPrintFormatString(instance, FF_DE_MODULE_NAME, 0, &instance->config.deKey, &instance->config.deFormat, NULL, FF_DE_NUM_FORMAT_ARGS, (FFformatarg[]){
|
||||
{FF_FORMAT_ARG_TYPE_STRING, sessionDesktop},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &sessionName},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &sessionVersion},
|
||||
{FF_FORMAT_ARG_TYPE_STRING, result->sessionDesktop},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &result->deProcessName},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &result->dePrettyName},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &result->deVersion}
|
||||
});
|
||||
}
|
||||
|
||||
ffStrbufDestroy(&sessionName);
|
||||
ffStrbufDestroy(&sessionVersion);
|
||||
}
|
||||
|
||||
+15
-203
@@ -1,204 +1,15 @@
|
||||
#include "fastfetch.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <dirent.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#define FF_WM_MODULE_NAME "WM"
|
||||
#define FF_WM_NUM_FORMAT_ARGS 3
|
||||
|
||||
typedef enum ProtocolHint
|
||||
{
|
||||
FF_WM_PROTOCOL_HINT_UNKNOWN,
|
||||
FF_WM_PROTOCOL_HINT_X11,
|
||||
FF_WM_PROTOCOL_HINT_WAYLAND
|
||||
} ProtocolHint;
|
||||
|
||||
const char* ffGetSessionDesktop()
|
||||
{
|
||||
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static char* sessionDesktop = NULL;
|
||||
|
||||
pthread_mutex_lock(&mutex);
|
||||
|
||||
if(sessionDesktop != NULL)
|
||||
{
|
||||
pthread_mutex_unlock(&mutex);
|
||||
return sessionDesktop;
|
||||
}
|
||||
|
||||
if(sessionDesktop == NULL)
|
||||
sessionDesktop = getenv("XDG_CURRENT_DESKTOP");
|
||||
|
||||
if(sessionDesktop == NULL)
|
||||
sessionDesktop = getenv("XDG_SESSION_DESKTOP");
|
||||
|
||||
pthread_mutex_unlock(&mutex);
|
||||
return sessionDesktop;
|
||||
}
|
||||
|
||||
static bool applyPrettyNameIfWM(FFWMResult* result, ProtocolHint* protocolHint)
|
||||
{
|
||||
if(ffStrbufIgnCaseCompS(&result->processName, "kwin_wayland") == 0)
|
||||
{
|
||||
ffStrbufSetS(&result->prettyName, "KWin");
|
||||
*protocolHint = FF_WM_PROTOCOL_HINT_WAYLAND;
|
||||
}
|
||||
else if(ffStrbufIgnCaseCompS(&result->processName, "kwin_x11") == 0)
|
||||
{
|
||||
ffStrbufSetS(&result->prettyName, "KWin");
|
||||
*protocolHint = FF_WM_PROTOCOL_HINT_X11;
|
||||
}
|
||||
else if(ffStrbufIgnCaseCompS(&result->processName, "sway") == 0)
|
||||
{
|
||||
ffStrbufSetS(&result->prettyName, "Sway");
|
||||
*protocolHint = FF_WM_PROTOCOL_HINT_WAYLAND;
|
||||
}
|
||||
else if(ffStrbufIgnCaseCompS(&result->processName, "weston") == 0)
|
||||
{
|
||||
ffStrbufSetS(&result->prettyName, "Weston");
|
||||
*protocolHint = FF_WM_PROTOCOL_HINT_WAYLAND;
|
||||
}
|
||||
else if(ffStrbufIgnCaseCompS(&result->processName, "wayfire") == 0)
|
||||
{
|
||||
ffStrbufSetS(&result->prettyName, "Wayfire");
|
||||
*protocolHint = FF_WM_PROTOCOL_HINT_WAYLAND;
|
||||
}
|
||||
else if(ffStrbufIgnCaseCompS(&result->processName, "openbox") == 0)
|
||||
{
|
||||
ffStrbufSetS(&result->prettyName, "Openbox");
|
||||
*protocolHint = FF_WM_PROTOCOL_HINT_X11;
|
||||
}
|
||||
else if(ffStrbufIgnCaseCompS(&result->processName, "xfwm4") == 0)
|
||||
{
|
||||
ffStrbufSetS(&result->prettyName, "XFWM");
|
||||
*protocolHint = FF_WM_PROTOCOL_HINT_X11;
|
||||
}
|
||||
else if(ffStrbufIgnCaseCompS(&result->processName, "mutter") == 0)
|
||||
ffStrbufSetS(&result->prettyName, "Mutter");
|
||||
else if(ffStrbufIgnCaseCompS(&result->processName, "cinnamon") == 0)
|
||||
ffStrbufSetS(&result->prettyName, "Muffin");
|
||||
|
||||
return result->prettyName.length > 0;
|
||||
}
|
||||
|
||||
static inline void getFromProcDir(FFWMResult* result, ProtocolHint* protocolHint)
|
||||
{
|
||||
DIR* proc = opendir("/proc/");
|
||||
if(proc == NULL)
|
||||
return;
|
||||
|
||||
struct dirent* dirent;
|
||||
|
||||
while((dirent = readdir(proc)) != NULL)
|
||||
{
|
||||
if(dirent->d_type != DT_DIR)
|
||||
continue;
|
||||
|
||||
char path[20];
|
||||
sprintf(path, "/proc/%.8s/comm", dirent->d_name);
|
||||
ffGetFileContent(path, &result->processName);
|
||||
|
||||
if(applyPrettyNameIfWM(result, protocolHint))
|
||||
break;
|
||||
}
|
||||
|
||||
if(result->prettyName.length == 0)
|
||||
ffStrbufClear(&result->processName);
|
||||
|
||||
closedir(proc);
|
||||
}
|
||||
|
||||
static void getSessionTypeFromProtocolHint(FFstrbuf* sessionType, ProtocolHint protocolHint)
|
||||
{
|
||||
if(protocolHint == FF_WM_PROTOCOL_HINT_WAYLAND)
|
||||
ffStrbufSetS(sessionType, "Wayland");
|
||||
else if(protocolHint == FF_WM_PROTOCOL_HINT_X11)
|
||||
ffStrbufSetS(sessionType, "X11");
|
||||
}
|
||||
|
||||
static inline void getSessionType(FFstrbuf* sessionType, ProtocolHint protocolHint)
|
||||
{
|
||||
const char* xdgSessionType = getenv("XDG_SESSION_TYPE");
|
||||
|
||||
if (xdgSessionType == NULL)
|
||||
{
|
||||
getSessionTypeFromProtocolHint(sessionType, protocolHint);
|
||||
return;
|
||||
}
|
||||
|
||||
if(strcasecmp(xdgSessionType, "wayland") == 0)
|
||||
ffStrbufSetS(sessionType, "Wayland");
|
||||
else if(strcasecmp(xdgSessionType, "x11") == 0)
|
||||
ffStrbufSetS(sessionType, "X11");
|
||||
else if(strcasecmp(xdgSessionType, "tty") == 0)
|
||||
ffStrbufSetS(sessionType, "TTY");
|
||||
else if(strcasecmp(xdgSessionType, "mir") == 0)
|
||||
ffStrbufSetS(sessionType, "Mir");
|
||||
else
|
||||
ffStrbufSetS(sessionType, xdgSessionType);
|
||||
|
||||
// $XDG_SESSION_TYPE is empty
|
||||
if(sessionType->length == 0)
|
||||
getSessionTypeFromProtocolHint(sessionType, protocolHint);
|
||||
}
|
||||
|
||||
const FFWMResult* ffDetectWM(FFinstance* instance)
|
||||
{
|
||||
UNUSED(instance);
|
||||
|
||||
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static FFWMResult result;
|
||||
static bool init = false;
|
||||
pthread_mutex_lock(&mutex);
|
||||
if(init)
|
||||
{
|
||||
pthread_mutex_unlock(&mutex);
|
||||
return &result;
|
||||
}
|
||||
init = true;
|
||||
|
||||
ffStrbufInit(&result.processName);
|
||||
ffStrbufInit(&result.prettyName);
|
||||
ffStrbufInit(&result.protocolName);
|
||||
ffStrbufInit(&result.error);
|
||||
|
||||
ProtocolHint protocolHint = FF_WM_PROTOCOL_HINT_UNKNOWN;
|
||||
|
||||
const char* sessionDesktop = ffGetSessionDesktop();
|
||||
|
||||
//If sessionDesktop env is a known WM, set it. Otherwise we might be running a DE, search /proc for known WMs
|
||||
ffStrbufSetS(&result.processName, sessionDesktop);
|
||||
if(!applyPrettyNameIfWM(&result, &protocolHint))
|
||||
getFromProcDir(&result, &protocolHint);
|
||||
|
||||
//Fallback for unknown window managers. This will falsely detect DEs as WMs if their WM is unknown
|
||||
if(result.prettyName.length == 0 && sessionDesktop != NULL)
|
||||
{
|
||||
ffStrbufSetS(&result.processName, sessionDesktop);
|
||||
ffStrbufSetS(&result.prettyName, sessionDesktop);
|
||||
}
|
||||
|
||||
getSessionType(&result.protocolName, protocolHint);
|
||||
|
||||
if(result.prettyName.length == 0 && result.protocolName.length == 0)
|
||||
{
|
||||
ffStrbufClear(&result.processName);
|
||||
ffStrbufSetS(&result.error, "No WM or WM protocol type found");
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&mutex);
|
||||
|
||||
return &result;
|
||||
}
|
||||
#define FF_WM_NUM_FORMAT_ARGS 4
|
||||
|
||||
void ffPrintWM(FFinstance* instance)
|
||||
{
|
||||
const FFWMResult* result = ffDetectWM(instance);
|
||||
const FFWMDEResult* result = ffDetectWMDE(instance);
|
||||
|
||||
if(result->error.length > 0)
|
||||
if(result->wmPrettyName.length == 0)
|
||||
{
|
||||
ffPrintError(instance, FF_WM_MODULE_NAME, 0, &instance->config.wmKey, &instance->config.wmFormat, FF_WM_NUM_FORMAT_ARGS, result->error.chars);
|
||||
ffPrintError(instance, FF_WM_MODULE_NAME, 0, &instance->config.wmKey, &instance->config.wmFormat, FF_WM_NUM_FORMAT_ARGS, "No WM found");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -206,21 +17,21 @@ void ffPrintWM(FFinstance* instance)
|
||||
{
|
||||
ffPrintLogoAndKey(instance, "WM", 0, &instance->config.wmKey);
|
||||
|
||||
if(result->prettyName.length == 0 && result->processName.length == 0)
|
||||
if(result->wmPrettyName.length == 0 && result->wmProcessName.length == 0)
|
||||
{
|
||||
ffStrbufPutTo(&result->protocolName, stdout);
|
||||
ffStrbufPutTo(&result->wmProtocolName, stdout);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(result->prettyName.length > 0)
|
||||
ffStrbufWriteTo(&result->prettyName, stdout);
|
||||
if(result->wmPrettyName.length > 0)
|
||||
ffStrbufWriteTo(&result->wmPrettyName, stdout);
|
||||
else
|
||||
ffStrbufWriteTo(&result->processName, stdout);
|
||||
ffStrbufWriteTo(&result->wmProcessName, stdout);
|
||||
|
||||
if(result->protocolName.length > 0)
|
||||
if(result->wmProtocolName.length > 0)
|
||||
{
|
||||
fputs(" (", stdout);
|
||||
ffStrbufWriteTo(&result->protocolName, stdout);
|
||||
ffStrbufWriteTo(&result->wmProtocolName, stdout);
|
||||
putchar(')');
|
||||
}
|
||||
|
||||
@@ -230,9 +41,10 @@ void ffPrintWM(FFinstance* instance)
|
||||
else
|
||||
{
|
||||
ffPrintFormatString(instance, FF_WM_MODULE_NAME, 0, &instance->config.wmKey, &instance->config.wmFormat, NULL, FF_WM_NUM_FORMAT_ARGS, (FFformatarg[]){
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &result->processName},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &result->prettyName},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &result->protocolName}
|
||||
{FF_FORMAT_ARG_TYPE_STRING, result->sessionDesktop},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &result->wmProcessName},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &result->wmPrettyName},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &result->wmProtocolName}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
+9
-11
@@ -34,18 +34,16 @@ static void printKWin(FFinstance* instance)
|
||||
printWMTheme(instance, theme);
|
||||
}
|
||||
|
||||
static void printOpenbox(FFinstance* instance)
|
||||
static void printOpenbox(FFinstance* instance, const FFstrbuf* dePrettyName)
|
||||
{
|
||||
FFstrbuf absolutePath;
|
||||
ffStrbufInitA(&absolutePath, 64);
|
||||
ffStrbufAppendS(&absolutePath, instance->state.passwd->pw_dir);
|
||||
ffStrbufAppendC(&absolutePath, '/');
|
||||
|
||||
const char* deName = ffGetSessionDesktop();
|
||||
|
||||
if(strcasecmp(deName, (const char*)"LXQt") == 0)
|
||||
if(ffStrbufIgnCaseCompS(dePrettyName, "LXQT") == 0)
|
||||
ffStrbufAppendS(&absolutePath, ".config/openbox/lxqt-rc.xml");
|
||||
else if(strcasecmp(deName, (const char*)"LXDE") == 0)
|
||||
else if(ffStrbufIgnCaseCompS(dePrettyName, "LXDE") == 0)
|
||||
ffStrbufAppendS(&absolutePath, ".config/openbox/lxde-rc.xml");
|
||||
else
|
||||
ffStrbufAppendS(&absolutePath, ".config/openbox/rc.xml");
|
||||
@@ -102,18 +100,18 @@ static void printOpenbox(FFinstance* instance)
|
||||
|
||||
void ffPrintWMTheme(FFinstance* instance)
|
||||
{
|
||||
const FFWMResult* result = ffDetectWM(instance);
|
||||
const FFWMDEResult* result = ffDetectWMDE(instance);
|
||||
|
||||
if(result->prettyName.length == 0)
|
||||
if(result->wmPrettyName.length == 0)
|
||||
{
|
||||
ffPrintError(instance, FF_WMTHEME_MODULE_NAME, 0, &instance->config.wmThemeKey, &instance->config.wmThemeFormat, FF_WMTHEME_NUM_FORMAT_ARGS, "WM Theme needs sucessfull WM detection");
|
||||
return;
|
||||
}
|
||||
|
||||
if(ffStrbufIgnCaseCompS(&result->prettyName, "KWin") == 0)
|
||||
if(ffStrbufIgnCaseCompS(&result->wmPrettyName, "KWin") == 0)
|
||||
printKWin(instance);
|
||||
else if(ffStrbufIgnCaseCompS(&result->prettyName, "Openbox") == 0)
|
||||
printOpenbox(instance);
|
||||
else if(ffStrbufIgnCaseCompS(&result->wmPrettyName, "Openbox") == 0)
|
||||
printOpenbox(instance, &result->dePrettyName);
|
||||
else
|
||||
ffPrintError(instance, FF_WMTHEME_MODULE_NAME, 0, &instance->config.wmThemeKey, &instance->config.wmThemeFormat, FF_WMTHEME_NUM_FORMAT_ARGS, "Unknown WM: %s", result->prettyName.chars);
|
||||
ffPrintError(instance, FF_WMTHEME_MODULE_NAME, 0, &instance->config.wmThemeKey, &instance->config.wmThemeFormat, FF_WMTHEME_NUM_FORMAT_ARGS, "Unknown WM: %s", result->dePrettyName.chars);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user