mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-13 02:42:09 +02:00
TerminalShell: split terminal and shell detection code further
This commit is contained in:
@@ -394,35 +394,35 @@ static bool detectContour(const FFstrbuf* exe, FFTerminalFontResult* result)
|
||||
return true;
|
||||
}
|
||||
|
||||
void ffDetectTerminalFontPlatform(const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont);
|
||||
void ffDetectTerminalFontPlatform(const FFTerminalResult* terminal, FFTerminalFontResult* terminalFont);
|
||||
|
||||
static bool detectTerminalFontCommon(const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont)
|
||||
static bool detectTerminalFontCommon(const FFTerminalResult* terminal, FFTerminalFontResult* terminalFont)
|
||||
{
|
||||
if(ffStrbufStartsWithIgnCaseS(&terminalShell->terminalProcessName, "alacritty"))
|
||||
if(ffStrbufStartsWithIgnCaseS(&terminal->processName, "alacritty"))
|
||||
detectAlacritty(terminalFont);
|
||||
else if(ffStrbufStartsWithIgnCaseS(&terminalShell->terminalProcessName, "terminator"))
|
||||
else if(ffStrbufStartsWithIgnCaseS(&terminal->processName, "terminator"))
|
||||
detectTerminator(terminalFont);
|
||||
else if(ffStrbufStartsWithIgnCaseS(&terminalShell->terminalProcessName, "wezterm-gui"))
|
||||
else if(ffStrbufStartsWithIgnCaseS(&terminal->processName, "wezterm-gui"))
|
||||
detectWezterm(terminalFont);
|
||||
else if(ffStrbufStartsWithIgnCaseS(&terminalShell->terminalProcessName, "tabby"))
|
||||
else if(ffStrbufStartsWithIgnCaseS(&terminal->processName, "tabby"))
|
||||
detectTabby(terminalFont);
|
||||
else if(ffStrbufStartsWithIgnCaseS(&terminalShell->terminalProcessName, "contour"))
|
||||
detectContour(&terminalShell->terminalExe, terminalFont);
|
||||
else if(ffStrbufStartsWithIgnCaseS(&terminal->processName, "contour"))
|
||||
detectContour(&terminal->exe, terminalFont);
|
||||
|
||||
#ifndef _WIN32
|
||||
else if(ffStrbufStartsWithIgnCaseS(&terminalShell->terminalExe, "/dev/pts/"))
|
||||
else if(ffStrbufStartsWithIgnCaseS(&terminal->exe, "/dev/pts/"))
|
||||
ffStrbufAppendS(&terminalFont->error, "Terminal font detection is not supported on PTS");
|
||||
else if(ffStrbufIgnCaseEqualS(&terminalShell->terminalProcessName, "kitty"))
|
||||
detectKitty(&terminalShell->terminalExe, terminalFont);
|
||||
else if(ffStrbufStartsWithIgnCaseS(&terminalShell->terminalExe, "/dev/tty"))
|
||||
else if(ffStrbufIgnCaseEqualS(&terminal->processName, "kitty"))
|
||||
detectKitty(&terminal->exe, terminalFont);
|
||||
else if(ffStrbufStartsWithIgnCaseS(&terminal->exe, "/dev/tty"))
|
||||
detectTTY(terminalFont);
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) || defined(__linux__)
|
||||
//Used by both Linux (WSL) and Windows
|
||||
else if(ffStrbufIgnCaseEqualS(&terminalShell->terminalProcessName, "Windows Terminal") ||
|
||||
ffStrbufIgnCaseEqualS(&terminalShell->terminalProcessName, "WindowsTerminal.exe"))
|
||||
detectFromWindowsTeriminal(&terminalShell->terminalExe, terminalFont);
|
||||
else if(ffStrbufIgnCaseEqualS(&terminal->processName, "Windows Terminal") ||
|
||||
ffStrbufIgnCaseEqualS(&terminal->processName, "WindowsTerminal.exe"))
|
||||
detectFromWindowsTeriminal(&terminal->exe, terminalFont);
|
||||
#endif
|
||||
|
||||
else
|
||||
@@ -433,16 +433,16 @@ static bool detectTerminalFontCommon(const FFTerminalShellResult* terminalShell,
|
||||
|
||||
bool ffDetectTerminalFont(FFTerminalFontResult* result)
|
||||
{
|
||||
const FFTerminalShellResult* terminalShell = ffDetectTerminalShell();
|
||||
const FFTerminalResult* terminal = ffDetectTerminal();
|
||||
|
||||
if(terminalShell->terminalProcessName.length == 0)
|
||||
if(terminal->processName.length == 0)
|
||||
ffStrbufAppendS(&result->error, "Terminal font needs successful terminal detection");
|
||||
|
||||
else if(!detectTerminalFontCommon(terminalShell, result))
|
||||
ffDetectTerminalFontPlatform(terminalShell, result);
|
||||
else if(!detectTerminalFontCommon(terminal, result))
|
||||
ffDetectTerminalFontPlatform(terminal, result);
|
||||
|
||||
if(result->error.length == 0 && result->font.pretty.length == 0)
|
||||
ffStrbufAppendF(&result->error, "Unknown terminal: %s", terminalShell->terminalProcessName.chars);
|
||||
ffStrbufAppendF(&result->error, "Unknown terminal: %s", terminal->processName.chars);
|
||||
|
||||
return result->error.length == 0;
|
||||
}
|
||||
|
||||
@@ -53,9 +53,9 @@ exit:
|
||||
#endif
|
||||
}
|
||||
|
||||
void ffDetectTerminalFontPlatform(const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont)
|
||||
void ffDetectTerminalFontPlatform(const FFTerminalResult* terminal, FFTerminalFontResult* terminalFont)
|
||||
{
|
||||
if(ffStrbufCompS(&terminalShell->terminalProcessName, "com.termux") != 0)
|
||||
if(ffStrbufCompS(&terminal->processName, "com.termux") != 0)
|
||||
{
|
||||
ffStrbufSetS(&terminalFont->error, "Unsupported terminal");
|
||||
return;
|
||||
|
||||
@@ -91,13 +91,13 @@ static void detectWarpTerminal(FFTerminalFontResult* terminalFont)
|
||||
ffFontInitValues(&terminalFont->font, fontName.UTF8String, fontSize.UTF8String);
|
||||
}
|
||||
|
||||
void ffDetectTerminalFontPlatform(const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont)
|
||||
void ffDetectTerminalFontPlatform(const FFTerminalResult* terminal, FFTerminalFontResult* terminalFont)
|
||||
{
|
||||
if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "iterm.app") == 0 ||
|
||||
ffStrbufStartsWithIgnCaseS(&terminalShell->terminalProcessName, "iTermServer-"))
|
||||
if(ffStrbufIgnCaseCompS(&terminal->processName, "iterm.app") == 0 ||
|
||||
ffStrbufStartsWithIgnCaseS(&terminal->processName, "iTermServer-"))
|
||||
detectIterm2(terminalFont);
|
||||
else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "Apple_Terminal") == 0)
|
||||
else if(ffStrbufIgnCaseCompS(&terminal->processName, "Apple_Terminal") == 0)
|
||||
detectAppleTerminal(terminalFont);
|
||||
else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "WarpTerminal") == 0)
|
||||
else if(ffStrbufIgnCaseCompS(&terminal->processName, "WarpTerminal") == 0)
|
||||
detectWarpTerminal(terminalFont);
|
||||
}
|
||||
|
||||
@@ -303,32 +303,32 @@ static void detectSt(FFTerminalFontResult* terminalFont, uint32_t pid)
|
||||
ffFontInitValues(&terminalFont->font, font.chars, size.chars);
|
||||
}
|
||||
|
||||
void ffDetectTerminalFontPlatform(const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont)
|
||||
void ffDetectTerminalFontPlatform(const FFTerminalResult* terminal, FFTerminalFontResult* terminalFont)
|
||||
{
|
||||
if(ffStrbufIgnCaseEqualS(&terminalShell->terminalProcessName, "konsole"))
|
||||
if(ffStrbufIgnCaseEqualS(&terminal->processName, "konsole"))
|
||||
detectKonsole(terminalFont, "konsolerc");
|
||||
else if(ffStrbufIgnCaseEqualS(&terminalShell->terminalProcessName, "yakuake"))
|
||||
else if(ffStrbufIgnCaseEqualS(&terminal->processName, "yakuake"))
|
||||
detectKonsole(terminalFont, "yakuakerc");
|
||||
else if(ffStrbufIgnCaseEqualS(&terminalShell->terminalProcessName, "xfce4-terminal"))
|
||||
else if(ffStrbufIgnCaseEqualS(&terminal->processName, "xfce4-terminal"))
|
||||
detectXFCETerminal(terminalFont);
|
||||
else if(ffStrbufIgnCaseEqualS(&terminalShell->terminalProcessName, "lxterminal"))
|
||||
else if(ffStrbufIgnCaseEqualS(&terminal->processName, "lxterminal"))
|
||||
detectFromConfigFile("lxterminal/lxterminal.conf", "fontname =", terminalFont);
|
||||
else if(ffStrbufIgnCaseEqualS(&terminalShell->terminalProcessName, "tilix"))
|
||||
else if(ffStrbufIgnCaseEqualS(&terminal->processName, "tilix"))
|
||||
detectFromGSettings("/com/gexperts/Tilix/profiles/", "com.gexperts.Tilix.ProfilesList", "com.gexperts.Tilix.Profile", "default", terminalFont);
|
||||
else if(ffStrbufStartsWithIgnCaseS(&terminalShell->terminalProcessName, "gnome-terminal-"))
|
||||
else if(ffStrbufStartsWithIgnCaseS(&terminal->processName, "gnome-terminal-"))
|
||||
detectFromGSettings("/org/gnome/terminal/legacy/profiles:/:", "org.gnome.Terminal.ProfilesList", "org.gnome.Terminal.Legacy.Profile", "default", terminalFont);
|
||||
else if(ffStrbufIgnCaseEqualS(&terminalShell->terminalProcessName, "kgx"))
|
||||
else if(ffStrbufIgnCaseEqualS(&terminal->processName, "kgx"))
|
||||
detectKgx(terminalFont);
|
||||
else if(ffStrbufIgnCaseEqualS(&terminalShell->terminalProcessName, "mate-terminal"))
|
||||
else if(ffStrbufIgnCaseEqualS(&terminal->processName, "mate-terminal"))
|
||||
detectFromGSettings("/org/mate/terminal/profiles/", "org.mate.terminal.global", "org.mate.terminal.profile", "default-profile", terminalFont);
|
||||
else if(ffStrbufIgnCaseEqualS(&terminalShell->terminalProcessName, "deepin-terminal"))
|
||||
else if(ffStrbufIgnCaseEqualS(&terminal->processName, "deepin-terminal"))
|
||||
detectDeepinTerminal(terminalFont);
|
||||
else if(ffStrbufIgnCaseEqualS(&terminalShell->terminalProcessName, "foot"))
|
||||
else if(ffStrbufIgnCaseEqualS(&terminal->processName, "foot"))
|
||||
detectFootTerminal(terminalFont);
|
||||
else if(ffStrbufIgnCaseEqualS(&terminalShell->terminalProcessName, "qterminal"))
|
||||
else if(ffStrbufIgnCaseEqualS(&terminal->processName, "qterminal"))
|
||||
detectQTerminal(terminalFont);
|
||||
else if(ffStrbufIgnCaseEqualS(&terminalShell->terminalProcessName, "xterm"))
|
||||
else if(ffStrbufIgnCaseEqualS(&terminal->processName, "xterm"))
|
||||
detectXterm(terminalFont);
|
||||
else if(ffStrbufIgnCaseEqualS(&terminalShell->terminalProcessName, "st"))
|
||||
detectSt(terminalFont, terminalShell->terminalPid);
|
||||
else if(ffStrbufIgnCaseEqualS(&terminal->processName, "st"))
|
||||
detectSt(terminalFont, terminal->pid);
|
||||
}
|
||||
|
||||
@@ -85,12 +85,12 @@ static void detectConEmu(FFTerminalFontResult* terminalFont)
|
||||
ffFontInitValues(&terminalFont->font, fontName.chars, fontSize.chars);
|
||||
}
|
||||
|
||||
void ffDetectTerminalFontPlatform(const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont)
|
||||
void ffDetectTerminalFontPlatform(const FFTerminalResult* terminal, FFTerminalFontResult* terminalFont)
|
||||
{
|
||||
if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "mintty") == 0)
|
||||
if(ffStrbufIgnCaseCompS(&terminal->processName, "mintty") == 0)
|
||||
detectMintty(terminalFont);
|
||||
else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "conhost.exe") == 0)
|
||||
else if(ffStrbufIgnCaseCompS(&terminal->processName, "conhost.exe") == 0)
|
||||
detectConhost(terminalFont);
|
||||
else if(ffStrbufStartsWithIgnCaseS(&terminalShell->terminalProcessName, "ConEmu"))
|
||||
else if(ffStrbufStartsWithIgnCaseS(&terminal->processName, "ConEmu"))
|
||||
detectConEmu(terminalFont);
|
||||
}
|
||||
|
||||
@@ -2,21 +2,28 @@
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
typedef struct FFTerminalShellResult
|
||||
typedef struct FFShellResult
|
||||
{
|
||||
FFstrbuf shellProcessName;
|
||||
FFstrbuf shellExe;
|
||||
const char* shellExeName; //pointer to a char in shellExe
|
||||
FFstrbuf shellPrettyName;
|
||||
FFstrbuf shellVersion;
|
||||
uint32_t shellPid;
|
||||
FFstrbuf processName;
|
||||
FFstrbuf exe;
|
||||
const char* exeName; //pointer to a char in exe
|
||||
FFstrbuf prettyName;
|
||||
FFstrbuf version;
|
||||
uint32_t pid;
|
||||
uint32_t ppid;
|
||||
} FFShellResult;
|
||||
|
||||
FFstrbuf terminalProcessName;
|
||||
FFstrbuf terminalExe;
|
||||
FFstrbuf terminalPrettyName;
|
||||
const char* terminalExeName; //pointer to a char in terminalExe
|
||||
FFstrbuf terminalVersion;
|
||||
uint32_t terminalPid;
|
||||
} FFTerminalShellResult;
|
||||
typedef struct FFTerminalResult
|
||||
{
|
||||
|
||||
const FFTerminalShellResult* ffDetectTerminalShell();
|
||||
FFstrbuf processName;
|
||||
FFstrbuf exe;
|
||||
FFstrbuf prettyName;
|
||||
const char* exeName; //pointer to a char in exe
|
||||
FFstrbuf version;
|
||||
uint32_t pid;
|
||||
uint32_t ppid;
|
||||
} FFTerminalResult;
|
||||
|
||||
const FFShellResult* ffDetectShell();
|
||||
const FFTerminalResult* ffDetectTerminal();
|
||||
|
||||
@@ -118,7 +118,7 @@ static const char* getProcessNameAndPpid(pid_t pid, char* name, pid_t* ppid)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static pid_t getShellInfo(FFTerminalShellResult* result, pid_t pid)
|
||||
static pid_t getShellInfo(FFShellResult* result, pid_t pid)
|
||||
{
|
||||
char name[256];
|
||||
name[0] = '\0';
|
||||
@@ -148,13 +148,14 @@ static pid_t getShellInfo(FFTerminalShellResult* result, pid_t pid)
|
||||
)
|
||||
return getShellInfo(result, ppid);
|
||||
|
||||
result->shellPid = (uint32_t) pid;
|
||||
ffStrbufSetS(&result->shellProcessName, name);
|
||||
getProcessInformation(pid, &result->shellProcessName, &result->shellExe, &result->shellExeName);
|
||||
result->pid = (uint32_t) pid;
|
||||
result->ppid = (uint32_t) ppid;
|
||||
ffStrbufSetS(&result->processName, name);
|
||||
getProcessInformation(pid, &result->processName, &result->exe, &result->exeName);
|
||||
return ppid;
|
||||
}
|
||||
|
||||
static pid_t getTerminalInfo(FFTerminalShellResult* result, pid_t pid)
|
||||
static pid_t getTerminalInfo(FFTerminalResult* result, pid_t pid)
|
||||
{
|
||||
char name[256];
|
||||
name[0] = '\0';
|
||||
@@ -191,29 +192,29 @@ static pid_t getTerminalInfo(FFTerminalShellResult* result, pid_t pid)
|
||||
getProcessNameAndPpid(ppid, name, &ppid);
|
||||
#endif
|
||||
|
||||
result->terminalPid = (uint32_t) pid;
|
||||
ffStrbufSetS(&result->terminalProcessName, name);
|
||||
getProcessInformation(pid, &result->terminalProcessName, &result->terminalExe, &result->terminalExeName);
|
||||
result->pid = (uint32_t) pid;
|
||||
ffStrbufSetS(&result->processName, name);
|
||||
getProcessInformation(pid, &result->processName, &result->exe, &result->exeName);
|
||||
return ppid;
|
||||
}
|
||||
|
||||
static void getTerminalFromEnv(FFTerminalShellResult* result)
|
||||
static void getTerminalFromEnv(FFTerminalResult* result)
|
||||
{
|
||||
if(
|
||||
result->terminalProcessName.length > 0 &&
|
||||
!ffStrbufStartsWithIgnCaseS(&result->terminalProcessName, "login") &&
|
||||
!ffStrbufIgnCaseEqualS(&result->terminalProcessName, "(login)") &&
|
||||
result->processName.length > 0 &&
|
||||
!ffStrbufStartsWithIgnCaseS(&result->processName, "login") &&
|
||||
!ffStrbufIgnCaseEqualS(&result->processName, "(login)") &&
|
||||
|
||||
#ifdef __APPLE__
|
||||
!ffStrbufIgnCaseEqualS(&result->terminalProcessName, "launchd") &&
|
||||
!ffStrbufIgnCaseEqualS(&result->terminalProcessName, "stable") && //for WarpTerminal
|
||||
!ffStrbufIgnCaseEqualS(&result->processName, "launchd") &&
|
||||
!ffStrbufIgnCaseEqualS(&result->processName, "stable") && //for WarpTerminal
|
||||
#else
|
||||
!ffStrbufIgnCaseEqualS(&result->terminalProcessName, "systemd") &&
|
||||
!ffStrbufIgnCaseEqualS(&result->terminalProcessName, "init") &&
|
||||
!ffStrbufIgnCaseEqualS(&result->terminalProcessName, "(init)") &&
|
||||
!ffStrbufIgnCaseEqualS(&result->processName, "systemd") &&
|
||||
!ffStrbufIgnCaseEqualS(&result->processName, "init") &&
|
||||
!ffStrbufIgnCaseEqualS(&result->processName, "(init)") &&
|
||||
#endif
|
||||
|
||||
ffStrbufIgnCaseCompS(&result->terminalProcessName, "0") != 0
|
||||
ffStrbufIgnCaseCompS(&result->processName, "0") != 0
|
||||
) return;
|
||||
|
||||
const char* term = NULL;
|
||||
@@ -274,20 +275,20 @@ static void getTerminalFromEnv(FFTerminalShellResult* result)
|
||||
|
||||
if(ffStrSet(term))
|
||||
{
|
||||
ffStrbufSetS(&result->terminalProcessName, term);
|
||||
ffStrbufSetS(&result->terminalExe, term);
|
||||
setExeName(&result->terminalExe, &result->terminalExeName);
|
||||
ffStrbufSetS(&result->processName, term);
|
||||
ffStrbufSetS(&result->exe, term);
|
||||
setExeName(&result->exe, &result->exeName);
|
||||
}
|
||||
}
|
||||
|
||||
static void getUserShellFromEnv(FFTerminalShellResult* result)
|
||||
static void getUserShellFromEnv(FFShellResult* result)
|
||||
{
|
||||
//If shell detection via processes failed
|
||||
if(result->shellProcessName.length == 0 && instance.state.platform.userShell.length > 0)
|
||||
if(result->processName.length == 0 && instance.state.platform.userShell.length > 0)
|
||||
{
|
||||
ffStrbufSet(&result->shellExe, &instance.state.platform.userShell);
|
||||
setExeName(&result->shellExe, &result->shellExeName);
|
||||
ffStrbufAppendS(&result->shellProcessName, result->shellExeName);
|
||||
ffStrbufSet(&result->exe, &instance.state.platform.userShell);
|
||||
setExeName(&result->exe, &result->exeName);
|
||||
ffStrbufAppendS(&result->processName, result->exeName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -295,114 +296,129 @@ bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version);
|
||||
|
||||
bool fftsGetTerminalVersion(FFstrbuf* processName, FFstrbuf* exe, FFstrbuf* version);
|
||||
|
||||
static void setShellInfoDetails(FFTerminalShellResult* result)
|
||||
static void setShellInfoDetails(FFShellResult* result)
|
||||
{
|
||||
ffStrbufClear(&result->shellVersion);
|
||||
fftsGetShellVersion(&result->shellExe, result->shellExeName, &result->shellVersion);
|
||||
ffStrbufClear(&result->version);
|
||||
fftsGetShellVersion(&result->exe, result->exeName, &result->version);
|
||||
|
||||
if(ffStrbufEqualS(&result->shellProcessName, "pwsh"))
|
||||
ffStrbufInitStatic(&result->shellPrettyName, "PowerShell");
|
||||
else if(ffStrbufEqualS(&result->shellProcessName, "nu"))
|
||||
ffStrbufInitStatic(&result->shellPrettyName, "nushell");
|
||||
else if(ffStrbufIgnCaseEqualS(&result->shellProcessName, "python") && getenv("XONSH_VERSION"))
|
||||
ffStrbufInitStatic(&result->shellPrettyName, "xonsh");
|
||||
else if(ffStrbufIgnCaseEqualS(&result->shellProcessName, "oil.ovm"))
|
||||
ffStrbufInitStatic(&result->shellPrettyName, "Oils");
|
||||
if(ffStrbufEqualS(&result->processName, "pwsh"))
|
||||
ffStrbufInitStatic(&result->prettyName, "PowerShell");
|
||||
else if(ffStrbufEqualS(&result->processName, "nu"))
|
||||
ffStrbufInitStatic(&result->prettyName, "nushell");
|
||||
else if(ffStrbufIgnCaseEqualS(&result->processName, "python") && getenv("XONSH_VERSION"))
|
||||
ffStrbufInitStatic(&result->prettyName, "xonsh");
|
||||
else if(ffStrbufIgnCaseEqualS(&result->processName, "oil.ovm"))
|
||||
ffStrbufInitStatic(&result->prettyName, "Oils");
|
||||
else
|
||||
{
|
||||
// https://github.com/fastfetch-cli/fastfetch/discussions/280#discussioncomment-3831734
|
||||
ffStrbufInitS(&result->shellPrettyName, result->shellExeName);
|
||||
ffStrbufInitS(&result->prettyName, result->exeName);
|
||||
}
|
||||
}
|
||||
|
||||
static void setTerminalInfoDetails(FFTerminalShellResult* result)
|
||||
static void setTerminalInfoDetails(FFTerminalResult* result)
|
||||
{
|
||||
if(result->terminalExeName[0] == '.' && ffStrEndsWith(result->terminalExeName, "-wrapped"))
|
||||
if(result->exeName[0] == '.' && ffStrEndsWith(result->exeName, "-wrapped"))
|
||||
{
|
||||
// For NixOS. Ref: #510 and https://github.com/NixOS/nixpkgs/pull/249428
|
||||
// We use terminalProcessName when detecting version and font, overriding it for simplification
|
||||
// We use processName when detecting version and font, overriding it for simplification
|
||||
ffStrbufSetNS(
|
||||
&result->terminalProcessName,
|
||||
(uint32_t) (strlen(result->terminalExeName) - strlen(".-wrapped")),
|
||||
result->terminalExeName + 1);
|
||||
&result->processName,
|
||||
(uint32_t) (strlen(result->exeName) - strlen(".-wrapped")),
|
||||
result->exeName + 1);
|
||||
}
|
||||
|
||||
if(ffStrbufEqualS(&result->terminalProcessName, "wezterm-gui"))
|
||||
ffStrbufInitStatic(&result->terminalPrettyName, "WezTerm");
|
||||
if(ffStrbufStartsWithS(&result->terminalProcessName, "tmux:"))
|
||||
ffStrbufInitStatic(&result->terminalPrettyName, "tmux");
|
||||
if(ffStrbufEqualS(&result->processName, "wezterm-gui"))
|
||||
ffStrbufInitStatic(&result->prettyName, "WezTerm");
|
||||
if(ffStrbufStartsWithS(&result->processName, "tmux:"))
|
||||
ffStrbufInitStatic(&result->prettyName, "tmux");
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
|
||||
else if(ffStrbufEqualS(&result->terminalProcessName, "com.termux"))
|
||||
ffStrbufInitStatic(&result->terminalPrettyName, "Termux");
|
||||
else if(ffStrbufEqualS(&result->processName, "com.termux"))
|
||||
ffStrbufInitStatic(&result->prettyName, "Termux");
|
||||
|
||||
#elif defined(__linux__) || defined(__FreeBSD__)
|
||||
|
||||
else if(ffStrbufStartsWithS(&result->terminalProcessName, "gnome-terminal-"))
|
||||
ffStrbufInitStatic(&result->terminalPrettyName, "GNOME Terminal");
|
||||
else if(ffStrbufStartsWithS(&result->terminalProcessName, "kgx"))
|
||||
ffStrbufInitStatic(&result->terminalPrettyName, "GNOME Console");
|
||||
else if(ffStrbufEqualS(&result->terminalProcessName, "urxvt") ||
|
||||
ffStrbufEqualS(&result->terminalProcessName, "urxvtd") ||
|
||||
ffStrbufEqualS(&result->terminalProcessName, "rxvt")
|
||||
else if(ffStrbufStartsWithS(&result->processName, "gnome-terminal-"))
|
||||
ffStrbufInitStatic(&result->prettyName, "GNOME Terminal");
|
||||
else if(ffStrbufStartsWithS(&result->processName, "kgx"))
|
||||
ffStrbufInitStatic(&result->prettyName, "GNOME Console");
|
||||
else if(ffStrbufEqualS(&result->processName, "urxvt") ||
|
||||
ffStrbufEqualS(&result->processName, "urxvtd") ||
|
||||
ffStrbufEqualS(&result->processName, "rxvt")
|
||||
)
|
||||
ffStrbufInitStatic(&result->terminalPrettyName, "rxvt-unicode");
|
||||
ffStrbufInitStatic(&result->prettyName, "rxvt-unicode");
|
||||
|
||||
#elif defined(__APPLE__)
|
||||
|
||||
else if(ffStrbufEqualS(&result->terminalProcessName, "iTerm.app") || ffStrbufStartsWithS(&result->terminalProcessName, "iTermServer-"))
|
||||
ffStrbufInitStatic(&result->terminalPrettyName, "iTerm");
|
||||
else if(ffStrbufEqualS(&result->terminalProcessName, "Apple_Terminal"))
|
||||
ffStrbufInitStatic(&result->terminalPrettyName, "Apple Terminal");
|
||||
else if(ffStrbufEqualS(&result->terminalProcessName, "WarpTerminal"))
|
||||
ffStrbufInitStatic(&result->terminalPrettyName, "Warp");
|
||||
else if(ffStrbufEqualS(&result->processName, "iTerm.app") || ffStrbufStartsWithS(&result->processName, "iTermServer-"))
|
||||
ffStrbufInitStatic(&result->prettyName, "iTerm");
|
||||
else if(ffStrbufEqualS(&result->processName, "Apple_Terminal"))
|
||||
ffStrbufInitStatic(&result->prettyName, "Apple Terminal");
|
||||
else if(ffStrbufEqualS(&result->processName, "WarpTerminal"))
|
||||
ffStrbufInitStatic(&result->prettyName, "Warp");
|
||||
|
||||
#endif
|
||||
|
||||
else if(strncmp(result->terminalExeName, result->terminalProcessName.chars, result->terminalProcessName.length) == 0) // if exeName starts with processName, print it. Otherwise print processName
|
||||
ffStrbufInitS(&result->terminalPrettyName, result->terminalExeName);
|
||||
else if(strncmp(result->exeName, result->processName.chars, result->processName.length) == 0) // if exeName starts with processName, print it. Otherwise print processName
|
||||
ffStrbufInitS(&result->prettyName, result->exeName);
|
||||
else
|
||||
ffStrbufInitCopy(&result->terminalPrettyName, &result->terminalProcessName);
|
||||
ffStrbufInitCopy(&result->prettyName, &result->processName);
|
||||
|
||||
ffStrbufInit(&result->terminalVersion);
|
||||
fftsGetTerminalVersion(&result->terminalProcessName, &result->terminalExe, &result->terminalVersion);
|
||||
ffStrbufInit(&result->version);
|
||||
fftsGetTerminalVersion(&result->processName, &result->exe, &result->version);
|
||||
}
|
||||
|
||||
const FFTerminalShellResult* ffDetectTerminalShell()
|
||||
#ifdef __APPLE__
|
||||
#define FF_EXE_PATH_LEN PROC_PIDPATHINFO_MAXSIZE
|
||||
#elif defined(MAXPATH)
|
||||
#define FF_EXE_PATH_LEN MAXPATH
|
||||
#elif defined(PATH_MAX)
|
||||
#define FF_EXE_PATH_LEN PATH_MAX
|
||||
#else
|
||||
#define FF_EXE_PATH_LEN 260
|
||||
#endif
|
||||
|
||||
const FFShellResult* ffDetectShell()
|
||||
{
|
||||
static FFTerminalShellResult result;
|
||||
static FFShellResult result;
|
||||
static bool init = false;
|
||||
if(init)
|
||||
return &result;
|
||||
init = true;
|
||||
|
||||
#ifdef __APPLE__
|
||||
const uint32_t exePathLen = PROC_PIDPATHINFO_MAXSIZE;
|
||||
#elif defined(MAXPATH)
|
||||
const uint32_t exePathLen = MAXPATH;
|
||||
#elif defined(PATH_MAX)
|
||||
const uint32_t exePathLen = PATH_MAX;
|
||||
#else
|
||||
const uint32_t exePathLen = 260;
|
||||
#endif
|
||||
|
||||
ffStrbufInit(&result.shellProcessName);
|
||||
ffStrbufInitA(&result.shellExe, exePathLen);
|
||||
result.shellExeName = result.shellExe.chars;
|
||||
ffStrbufInit(&result.shellVersion);
|
||||
result.shellPid = 0;
|
||||
|
||||
ffStrbufInit(&result.terminalProcessName);
|
||||
ffStrbufInitA(&result.terminalExe, exePathLen);
|
||||
result.terminalExeName = result.terminalExe.chars;
|
||||
result.terminalPid = 0;
|
||||
ffStrbufInit(&result.processName);
|
||||
ffStrbufInitA(&result.exe, FF_EXE_PATH_LEN);
|
||||
result.exeName = result.exe.chars;
|
||||
ffStrbufInit(&result.version);
|
||||
result.pid = 0;
|
||||
result.ppid = 0;
|
||||
|
||||
pid_t ppid = getppid();
|
||||
ppid = getShellInfo(&result, ppid);
|
||||
getUserShellFromEnv(&result);
|
||||
setShellInfoDetails(&result);
|
||||
|
||||
return &result;
|
||||
}
|
||||
|
||||
const FFTerminalResult* ffDetectTerminal()
|
||||
{
|
||||
static FFTerminalResult result;
|
||||
static bool init = false;
|
||||
if(init)
|
||||
return &result;
|
||||
init = true;
|
||||
|
||||
ffStrbufInit(&result.processName);
|
||||
ffStrbufInitA(&result.exe, FF_EXE_PATH_LEN);
|
||||
result.exeName = result.exe.chars;
|
||||
result.pid = 0;
|
||||
result.ppid = 0;
|
||||
|
||||
pid_t ppid = (pid_t) ffDetectShell()->ppid;
|
||||
|
||||
if (ppid)
|
||||
ppid = getTerminalInfo(&result, ppid);
|
||||
getTerminalFromEnv(&result);
|
||||
|
||||
@@ -83,47 +83,48 @@ static bool getProcessInfo(uint32_t pid, uint32_t* ppid, FFstrbuf* pname, FFstrb
|
||||
|
||||
bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version);
|
||||
|
||||
static uint32_t getShellInfo(FFTerminalShellResult* result, uint32_t pid)
|
||||
static uint32_t getShellInfo(FFShellResult* result, uint32_t pid)
|
||||
{
|
||||
uint32_t ppid;
|
||||
|
||||
if(pid == 0 || !getProcessInfo(pid, &ppid, &result->shellProcessName, &result->shellExe, &result->shellExeName))
|
||||
if(pid == 0 || !getProcessInfo(pid, &ppid, &result->processName, &result->exe, &result->exeName))
|
||||
return 0;
|
||||
|
||||
ffStrbufSet(&result->shellPrettyName, &result->shellProcessName);
|
||||
if(ffStrbufEndsWithIgnCaseS(&result->shellPrettyName, ".exe"))
|
||||
ffStrbufSubstrBefore(&result->shellPrettyName, result->shellPrettyName.length - 4);
|
||||
ffStrbufSet(&result->prettyName, &result->processName);
|
||||
if(ffStrbufEndsWithIgnCaseS(&result->prettyName, ".exe"))
|
||||
ffStrbufSubstrBefore(&result->prettyName, result->prettyName.length - 4);
|
||||
|
||||
//Common programs that are between terminal and own process, but are not the shell
|
||||
if(
|
||||
ffStrbufIgnCaseEqualS(&result->shellPrettyName, "sudo") ||
|
||||
ffStrbufIgnCaseEqualS(&result->shellPrettyName, "su") ||
|
||||
ffStrbufIgnCaseEqualS(&result->shellPrettyName, "doas") ||
|
||||
ffStrbufIgnCaseEqualS(&result->shellPrettyName, "strace") ||
|
||||
ffStrbufIgnCaseEqualS(&result->shellPrettyName, "sshd") ||
|
||||
ffStrbufIgnCaseEqualS(&result->shellPrettyName, "gdb") ||
|
||||
ffStrbufIgnCaseEqualS(&result->shellPrettyName, "lldb") ||
|
||||
ffStrbufIgnCaseEqualS(&result->shellPrettyName, "guake-wrapped") ||
|
||||
ffStrbufIgnCaseEqualS(&result->shellPrettyName, "fastfetch") || //scoop warps the real binaries with a "shim" exe
|
||||
ffStrbufIgnCaseEqualS(&result->shellPrettyName, "flashfetch") ||
|
||||
ffStrbufContainIgnCaseS(&result->shellPrettyName, "debug") ||
|
||||
ffStrbufStartsWithIgnCaseS(&result->shellPrettyName, "ConEmu") // https://github.com/fastfetch-cli/fastfetch/issues/488#issuecomment-1619982014
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "sudo") ||
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "su") ||
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "doas") ||
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "strace") ||
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "sshd") ||
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "gdb") ||
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "lldb") ||
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "guake-wrapped") ||
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "fastfetch") || //scoop warps the real binaries with a "shim" exe
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "flashfetch") ||
|
||||
ffStrbufContainIgnCaseS(&result->prettyName, "debug") ||
|
||||
ffStrbufStartsWithIgnCaseS(&result->prettyName, "ConEmu") // https://github.com/fastfetch-cli/fastfetch/issues/488#issuecomment-1619982014
|
||||
) {
|
||||
ffStrbufClear(&result->shellProcessName);
|
||||
ffStrbufClear(&result->shellPrettyName);
|
||||
ffStrbufClear(&result->shellExe);
|
||||
result->shellExeName = NULL;
|
||||
ffStrbufClear(&result->processName);
|
||||
ffStrbufClear(&result->prettyName);
|
||||
ffStrbufClear(&result->exe);
|
||||
result->exeName = NULL;
|
||||
return getShellInfo(result, ppid);
|
||||
}
|
||||
|
||||
ffStrbufClear(&result->shellVersion);
|
||||
fftsGetShellVersion(&result->shellExe, result->shellPrettyName.chars, &result->shellVersion);
|
||||
ffStrbufClear(&result->version);
|
||||
fftsGetShellVersion(&result->exe, result->prettyName.chars, &result->version);
|
||||
|
||||
result->shellPid = pid;
|
||||
result->pid = pid;
|
||||
result->ppid = ppid;
|
||||
|
||||
if(ffStrbufIgnCaseEqualS(&result->shellPrettyName, "explorer"))
|
||||
if(ffStrbufIgnCaseEqualS(&result->prettyName, "explorer"))
|
||||
{
|
||||
ffStrbufSetS(&result->shellPrettyName, "Windows Explorer"); // Started without shell
|
||||
ffStrbufSetS(&result->prettyName, "Windows Explorer"); // Started without shell
|
||||
// In this case, terminal process will be created by fastfetch itself.
|
||||
ppid = 0;
|
||||
}
|
||||
@@ -131,20 +132,20 @@ static uint32_t getShellInfo(FFTerminalShellResult* result, uint32_t pid)
|
||||
return ppid;
|
||||
}
|
||||
|
||||
static void setShellInfoDetails(FFTerminalShellResult* result)
|
||||
static void setShellInfoDetails(FFShellResult* result)
|
||||
{
|
||||
if(ffStrbufIgnCaseEqualS(&result->shellPrettyName, "pwsh"))
|
||||
ffStrbufSetS(&result->shellPrettyName, "PowerShell");
|
||||
else if(ffStrbufIgnCaseEqualS(&result->shellPrettyName, "powershell"))
|
||||
ffStrbufSetS(&result->shellPrettyName, "Windows PowerShell");
|
||||
else if(ffStrbufIgnCaseEqualS(&result->shellPrettyName, "powershell_ise"))
|
||||
ffStrbufSetS(&result->shellPrettyName, "Windows PowerShell ISE");
|
||||
else if(ffStrbufIgnCaseEqualS(&result->shellPrettyName, "cmd"))
|
||||
if(ffStrbufIgnCaseEqualS(&result->prettyName, "pwsh"))
|
||||
ffStrbufSetS(&result->prettyName, "PowerShell");
|
||||
else if(ffStrbufIgnCaseEqualS(&result->prettyName, "powershell"))
|
||||
ffStrbufSetS(&result->prettyName, "Windows PowerShell");
|
||||
else if(ffStrbufIgnCaseEqualS(&result->prettyName, "powershell_ise"))
|
||||
ffStrbufSetS(&result->prettyName, "Windows PowerShell ISE");
|
||||
else if(ffStrbufIgnCaseEqualS(&result->prettyName, "cmd"))
|
||||
{
|
||||
ffStrbufClear(&result->shellPrettyName);
|
||||
ffStrbufClear(&result->prettyName);
|
||||
|
||||
FF_AUTO_CLOSE_FD HANDLE snapshot = NULL;
|
||||
while(!(snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, result->shellPid)) && GetLastError() == ERROR_BAD_LENGTH) {}
|
||||
while(!(snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, result->pid)) && GetLastError() == ERROR_BAD_LENGTH) {}
|
||||
|
||||
if(snapshot)
|
||||
{
|
||||
@@ -154,27 +155,27 @@ static void setShellInfoDetails(FFTerminalShellResult* result)
|
||||
{
|
||||
if(wcsncmp(module.szModule, L"clink_dll_", strlen("clink_dll_")) == 0)
|
||||
{
|
||||
ffStrbufAppendS(&result->shellPrettyName, "CMD (with Clink ");
|
||||
getProductVersion(module.szExePath, &result->shellPrettyName);
|
||||
ffStrbufAppendC(&result->shellPrettyName, ')');
|
||||
ffStrbufAppendS(&result->prettyName, "CMD (with Clink ");
|
||||
getProductVersion(module.szExePath, &result->prettyName);
|
||||
ffStrbufAppendC(&result->prettyName, ')');
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(result->shellPrettyName.length == 0)
|
||||
ffStrbufAppendS(&result->shellPrettyName, "Command Prompt");
|
||||
if(result->prettyName.length == 0)
|
||||
ffStrbufAppendS(&result->prettyName, "Command Prompt");
|
||||
}
|
||||
else if(ffStrbufIgnCaseEqualS(&result->shellPrettyName, "nu"))
|
||||
ffStrbufSetS(&result->shellPrettyName, "nushell");
|
||||
else if(ffStrbufIgnCaseEqualS(&result->shellPrettyName, "explorer"))
|
||||
ffStrbufSetS(&result->shellPrettyName, "Windows Explorer");
|
||||
else if(ffStrbufIgnCaseEqualS(&result->prettyName, "nu"))
|
||||
ffStrbufSetS(&result->prettyName, "nushell");
|
||||
else if(ffStrbufIgnCaseEqualS(&result->prettyName, "explorer"))
|
||||
ffStrbufSetS(&result->prettyName, "Windows Explorer");
|
||||
}
|
||||
|
||||
static bool getTerminalFromEnv(FFTerminalShellResult* result)
|
||||
static bool getTerminalFromEnv(FFTerminalResult* result)
|
||||
{
|
||||
if(
|
||||
result->terminalProcessName.length > 0 &&
|
||||
ffStrbufIgnCaseCompS(&result->terminalProcessName, "explorer") != 0
|
||||
result->processName.length > 0 &&
|
||||
ffStrbufIgnCaseCompS(&result->processName, "explorer") != 0
|
||||
) return false;
|
||||
|
||||
const char* term = getenv("ConEmuPID");
|
||||
@@ -183,12 +184,12 @@ static bool getTerminalFromEnv(FFTerminalShellResult* result)
|
||||
{
|
||||
//ConEmu
|
||||
uint32_t pid = (uint32_t) strtoul(term, NULL, 10);
|
||||
result->terminalPid = pid;
|
||||
if(getProcessInfo(pid, NULL, &result->terminalProcessName, &result->terminalExe, &result->terminalExeName))
|
||||
result->pid = pid;
|
||||
if(getProcessInfo(pid, NULL, &result->processName, &result->exe, &result->exeName))
|
||||
{
|
||||
ffStrbufSet(&result->terminalPrettyName, &result->terminalProcessName);
|
||||
if(ffStrbufEndsWithIgnCaseS(&result->terminalPrettyName, ".exe"))
|
||||
ffStrbufSubstrBefore(&result->terminalPrettyName, result->terminalPrettyName.length - 4);
|
||||
ffStrbufSet(&result->prettyName, &result->processName);
|
||||
if(ffStrbufEndsWithIgnCaseS(&result->prettyName, ".exe"))
|
||||
ffStrbufSubstrBefore(&result->prettyName, result->prettyName.length - 4);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@@ -223,17 +224,17 @@ static bool getTerminalFromEnv(FFTerminalShellResult* result)
|
||||
|
||||
if(term)
|
||||
{
|
||||
ffStrbufSetS(&result->terminalProcessName, term);
|
||||
ffStrbufSetS(&result->terminalPrettyName, term);
|
||||
ffStrbufSetS(&result->terminalExe, term);
|
||||
result->terminalExeName = "";
|
||||
ffStrbufSetS(&result->processName, term);
|
||||
ffStrbufSetS(&result->prettyName, term);
|
||||
ffStrbufSetS(&result->exe, term);
|
||||
result->exeName = "";
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool detectDefaultTerminal(FFTerminalShellResult* result)
|
||||
static bool detectDefaultTerminal(FFTerminalResult* result)
|
||||
{
|
||||
wchar_t regPath[128] = L"SOFTWARE\\Classes\\PackagedCom\\ClassIndex\\";
|
||||
wchar_t* uuid = regPath + strlen("SOFTWARE\\Classes\\PackagedCom\\ClassIndex\\");
|
||||
@@ -258,18 +259,18 @@ static bool detectDefaultTerminal(FFTerminalShellResult* result)
|
||||
{
|
||||
if (ffStrbufStartsWithS(&path, "Microsoft.WindowsTerminal"))
|
||||
{
|
||||
ffStrbufSetS(&result->terminalProcessName, "WindowsTerminal.exe");
|
||||
ffStrbufSetS(&result->terminalPrettyName, "WindowsTerminal");
|
||||
ffStrbufSetF(&result->terminalExe, "%s\\WindowsApps\\%s\\WindowsTerminal.exe", getenv("ProgramFiles"), path.chars);
|
||||
if(ffPathExists(result->terminalExe.chars, FF_PATHTYPE_FILE))
|
||||
ffStrbufSetS(&result->processName, "WindowsTerminal.exe");
|
||||
ffStrbufSetS(&result->prettyName, "WindowsTerminal");
|
||||
ffStrbufSetF(&result->exe, "%s\\WindowsApps\\%s\\WindowsTerminal.exe", getenv("ProgramFiles"), path.chars);
|
||||
if(ffPathExists(result->exe.chars, FF_PATHTYPE_FILE))
|
||||
{
|
||||
result->terminalExeName = result->terminalExe.chars + ffStrbufLastIndexC(&result->terminalExe, '\\') + 1;
|
||||
result->exeName = result->exe.chars + ffStrbufLastIndexC(&result->exe, '\\') + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ffStrbufDestroy(&result->terminalExe);
|
||||
ffStrbufInitMove(&result->terminalExe, &path);
|
||||
result->terminalExeName = "";
|
||||
ffStrbufDestroy(&result->exe);
|
||||
ffStrbufInitMove(&result->exe, &path);
|
||||
result->exeName = "";
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -278,111 +279,109 @@ static bool detectDefaultTerminal(FFTerminalShellResult* result)
|
||||
}
|
||||
|
||||
conhost:
|
||||
ffStrbufSetF(&result->terminalExe, "%s\\System32\\conhost.exe", getenv("SystemRoot"));
|
||||
if(ffPathExists(result->terminalExe.chars, FF_PATHTYPE_FILE))
|
||||
ffStrbufSetF(&result->exe, "%s\\System32\\conhost.exe", getenv("SystemRoot"));
|
||||
if(ffPathExists(result->exe.chars, FF_PATHTYPE_FILE))
|
||||
{
|
||||
ffStrbufSetS(&result->terminalProcessName, "conhost.exe");
|
||||
ffStrbufSetS(&result->terminalPrettyName, "conhost");
|
||||
result->terminalExeName = result->terminalExe.chars + ffStrbufLastIndexC(&result->terminalExe, '\\') + 1;
|
||||
ffStrbufSetS(&result->processName, "conhost.exe");
|
||||
ffStrbufSetS(&result->prettyName, "conhost");
|
||||
result->exeName = result->exe.chars + ffStrbufLastIndexC(&result->exe, '\\') + 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
ffStrbufClear(&result->terminalExe);
|
||||
ffStrbufClear(&result->exe);
|
||||
return false;
|
||||
}
|
||||
|
||||
static uint32_t getTerminalInfo(FFTerminalShellResult* result, uint32_t pid)
|
||||
static uint32_t getTerminalInfo(FFTerminalResult* result, uint32_t pid)
|
||||
{
|
||||
uint32_t ppid;
|
||||
|
||||
if(pid == 0 || !getProcessInfo(pid, &ppid, &result->terminalProcessName, &result->terminalExe, &result->terminalExeName))
|
||||
if(pid == 0 || !getProcessInfo(pid, &ppid, &result->processName, &result->exe, &result->exeName))
|
||||
return 0;
|
||||
|
||||
ffStrbufSet(&result->terminalPrettyName, &result->terminalProcessName);
|
||||
if(ffStrbufEndsWithIgnCaseS(&result->terminalPrettyName, ".exe"))
|
||||
ffStrbufSubstrBefore(&result->terminalPrettyName, result->terminalPrettyName.length - 4);
|
||||
ffStrbufSet(&result->prettyName, &result->processName);
|
||||
if(ffStrbufEndsWithIgnCaseS(&result->prettyName, ".exe"))
|
||||
ffStrbufSubstrBefore(&result->prettyName, result->prettyName.length - 4);
|
||||
|
||||
if(
|
||||
ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "pwsh") ||
|
||||
ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "cmd") ||
|
||||
ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "bash") ||
|
||||
ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "zsh") ||
|
||||
ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "fish") ||
|
||||
ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "nu") ||
|
||||
ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "powershell") ||
|
||||
ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "powershell_ise") ||
|
||||
ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "wsl") || // running inside wsl
|
||||
ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "servercoreshell") || // ServerCore Shell Launcher
|
||||
ffStrbufStartsWithIgnCaseS(&result->terminalPrettyName, "ConEmuC") // wrapper process of ConEmu
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "pwsh") ||
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "cmd") ||
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "bash") ||
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "zsh") ||
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "fish") ||
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "nu") ||
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "powershell") ||
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "powershell_ise") ||
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "wsl") || // running inside wsl
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "servercoreshell") || // ServerCore Shell Launcher
|
||||
ffStrbufStartsWithIgnCaseS(&result->prettyName, "ConEmuC") // wrapper process of ConEmu
|
||||
) {
|
||||
//We are nested shell
|
||||
ffStrbufClear(&result->terminalProcessName);
|
||||
ffStrbufClear(&result->terminalPrettyName);
|
||||
ffStrbufClear(&result->terminalExe);
|
||||
result->terminalExeName = "";
|
||||
ffStrbufClear(&result->processName);
|
||||
ffStrbufClear(&result->prettyName);
|
||||
ffStrbufClear(&result->exe);
|
||||
result->exeName = "";
|
||||
return getTerminalInfo(result, ppid);
|
||||
}
|
||||
|
||||
if(ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "sihost") ||
|
||||
ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "explorer")
|
||||
if(ffStrbufIgnCaseEqualS(&result->prettyName, "sihost") ||
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "explorer")
|
||||
) {
|
||||
// A CUI program created by Windows Explorer will spawn a conhost as its child.
|
||||
// However the conhost process is just a placeholder;
|
||||
// The true terminal can be Windows Terminal or others.
|
||||
if (!getTerminalFromEnv(result) && !detectDefaultTerminal(result))
|
||||
{
|
||||
ffStrbufClear(&result->terminalProcessName);
|
||||
ffStrbufClear(&result->terminalPrettyName);
|
||||
ffStrbufClear(&result->terminalExe);
|
||||
result->terminalExeName = "";
|
||||
ffStrbufClear(&result->processName);
|
||||
ffStrbufClear(&result->prettyName);
|
||||
ffStrbufClear(&result->exe);
|
||||
result->exeName = "";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
result->terminalPid = pid;
|
||||
{
|
||||
result->pid = pid;
|
||||
result->ppid = ppid;
|
||||
}
|
||||
|
||||
return ppid;
|
||||
}
|
||||
|
||||
static void setTerminalInfoDetails(FFTerminalShellResult* result)
|
||||
static void setTerminalInfoDetails(FFTerminalResult* result)
|
||||
{
|
||||
if(ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "WindowsTerminal"))
|
||||
ffStrbufSetStatic(&result->terminalPrettyName, ffStrbufContainIgnCaseS(&result->terminalExe, ".WindowsTerminalPreview_")
|
||||
if(ffStrbufIgnCaseEqualS(&result->prettyName, "WindowsTerminal"))
|
||||
ffStrbufSetStatic(&result->prettyName, ffStrbufContainIgnCaseS(&result->exe, ".WindowsTerminalPreview_")
|
||||
? "Windows Terminal Preview"
|
||||
: "Windows Terminal"
|
||||
);
|
||||
else if(ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "conhost"))
|
||||
ffStrbufSetStatic(&result->terminalPrettyName, "Console Window Host");
|
||||
else if(ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "Code"))
|
||||
ffStrbufSetStatic(&result->terminalPrettyName, "Visual Studio Code");
|
||||
else if(ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "explorer"))
|
||||
ffStrbufSetStatic(&result->terminalPrettyName, "Windows Explorer");
|
||||
else if(ffStrbufEqualS(&result->terminalPrettyName, "wezterm-gui"))
|
||||
ffStrbufSetStatic(&result->terminalPrettyName, "WezTerm");
|
||||
else if(ffStrbufIgnCaseEqualS(&result->prettyName, "conhost"))
|
||||
ffStrbufSetStatic(&result->prettyName, "Console Window Host");
|
||||
else if(ffStrbufIgnCaseEqualS(&result->prettyName, "Code"))
|
||||
ffStrbufSetStatic(&result->prettyName, "Visual Studio Code");
|
||||
else if(ffStrbufIgnCaseEqualS(&result->prettyName, "explorer"))
|
||||
ffStrbufSetStatic(&result->prettyName, "Windows Explorer");
|
||||
else if(ffStrbufEqualS(&result->prettyName, "wezterm-gui"))
|
||||
ffStrbufSetStatic(&result->prettyName, "WezTerm");
|
||||
}
|
||||
|
||||
bool fftsGetTerminalVersion(FFstrbuf* processName, FFstrbuf* exe, FFstrbuf* version);
|
||||
|
||||
const FFTerminalShellResult* ffDetectTerminalShell(void)
|
||||
const FFShellResult* ffDetectShell(void)
|
||||
{
|
||||
static FFTerminalShellResult result;
|
||||
static FFShellResult result;
|
||||
static bool init = false;
|
||||
if(init)
|
||||
return &result;
|
||||
init = true;
|
||||
|
||||
ffStrbufInit(&result.shellProcessName);
|
||||
ffStrbufInitA(&result.shellExe, 128);
|
||||
result.shellExeName = "";
|
||||
ffStrbufInit(&result.shellPrettyName);
|
||||
ffStrbufInit(&result.shellVersion);
|
||||
result.shellPid = 0;
|
||||
|
||||
ffStrbufInit(&result.terminalProcessName);
|
||||
ffStrbufInitA(&result.terminalExe, 128);
|
||||
result.terminalExeName = "";
|
||||
ffStrbufInit(&result.terminalPrettyName);
|
||||
result.terminalPid = 0;
|
||||
ffStrbufInit(&result.processName);
|
||||
ffStrbufInitA(&result.exe, 128);
|
||||
result.exeName = "";
|
||||
ffStrbufInit(&result.prettyName);
|
||||
ffStrbufInit(&result.version);
|
||||
result.pid = 0;
|
||||
result.ppid = 0;
|
||||
|
||||
uint32_t ppid;
|
||||
if(!getProcessInfo(0, &ppid, NULL, NULL, NULL))
|
||||
@@ -391,16 +390,35 @@ const FFTerminalShellResult* ffDetectTerminalShell(void)
|
||||
ppid = getShellInfo(&result, ppid);
|
||||
setShellInfoDetails(&result);
|
||||
|
||||
return &result;
|
||||
}
|
||||
|
||||
const FFTerminalResult* ffDetectTerminal(void)
|
||||
{
|
||||
static FFTerminalResult result;
|
||||
static bool init = false;
|
||||
if(init)
|
||||
return &result;
|
||||
init = true;
|
||||
|
||||
ffStrbufInit(&result.processName);
|
||||
ffStrbufInitA(&result.exe, 128);
|
||||
result.exeName = "";
|
||||
ffStrbufInit(&result.prettyName);
|
||||
ffStrbufInit(&result.version);
|
||||
result.pid = 0;
|
||||
result.ppid = 0;
|
||||
|
||||
uint32_t ppid = ffDetectShell()->ppid;
|
||||
if(ppid)
|
||||
getTerminalInfo(&result, ppid);
|
||||
|
||||
if(result.terminalProcessName.length == 0)
|
||||
if(result.processName.length == 0)
|
||||
getTerminalFromEnv(&result);
|
||||
|
||||
setTerminalInfoDetails(&result);
|
||||
|
||||
ffStrbufInit(&result.terminalVersion);
|
||||
fftsGetTerminalVersion(&result.terminalProcessName, &result.terminalExe, &result.terminalVersion);
|
||||
fftsGetTerminalVersion(&result.processName, &result.exe, &result.version);
|
||||
|
||||
return &result;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ private:
|
||||
extern "C"
|
||||
const char* ffDetectWMPlugin(FFstrbuf* pluginName)
|
||||
{
|
||||
DWORD pid = ffDetectTerminalShell()->terminalPid; // Whatever GUI program
|
||||
DWORD pid = ffDetectTerminal()->pid; // Whatever GUI program
|
||||
if (pid == 0) return "Unable to find a GUI program";
|
||||
|
||||
FF_AUTO_CLOSE_FD HANDLE snapshot = NULL;
|
||||
|
||||
+5
-5
@@ -498,14 +498,14 @@ void ffLogoPrint(void)
|
||||
//Make sure the logo path is set correctly.
|
||||
updateLogoPath();
|
||||
|
||||
const FFTerminalShellResult* terminalShell = ffDetectTerminalShell();
|
||||
const FFTerminalResult* terminal = ffDetectTerminal();
|
||||
|
||||
//Terminal emulators that support kitty graphics protocol.
|
||||
bool supportsKitty =
|
||||
ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "kitty") == 0 ||
|
||||
ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "konsole") == 0 ||
|
||||
ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "wezterm") == 0 ||
|
||||
ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "wayst") == 0;
|
||||
ffStrbufIgnCaseCompS(&terminal->processName, "kitty") == 0 ||
|
||||
ffStrbufIgnCaseCompS(&terminal->processName, "konsole") == 0 ||
|
||||
ffStrbufIgnCaseCompS(&terminal->processName, "wezterm") == 0 ||
|
||||
ffStrbufIgnCaseCompS(&terminal->processName, "wayst") == 0;
|
||||
|
||||
//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))
|
||||
|
||||
+19
-18
@@ -8,9 +8,9 @@
|
||||
|
||||
void ffPrintShell(FFShellOptions* options)
|
||||
{
|
||||
const FFTerminalShellResult* result = ffDetectTerminalShell();
|
||||
const FFShellResult* result = ffDetectShell();
|
||||
|
||||
if(result->shellProcessName.length == 0)
|
||||
if(result->processName.length == 0)
|
||||
{
|
||||
ffPrintError(FF_SHELL_MODULE_NAME, 0, &options->moduleArgs, "Couldn't detect shell");
|
||||
return;
|
||||
@@ -19,12 +19,12 @@ void ffPrintShell(FFShellOptions* options)
|
||||
if(options->moduleArgs.outputFormat.length == 0)
|
||||
{
|
||||
ffPrintLogoAndKey(FF_SHELL_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT);
|
||||
ffStrbufWriteTo(&result->shellPrettyName, stdout);
|
||||
ffStrbufWriteTo(&result->prettyName, stdout);
|
||||
|
||||
if(result->shellVersion.length > 0)
|
||||
if(result->version.length > 0)
|
||||
{
|
||||
putchar(' ');
|
||||
ffStrbufWriteTo(&result->shellVersion, stdout);
|
||||
ffStrbufWriteTo(&result->version, stdout);
|
||||
}
|
||||
|
||||
putchar('\n');
|
||||
@@ -32,12 +32,12 @@ void ffPrintShell(FFShellOptions* options)
|
||||
else
|
||||
{
|
||||
ffPrintFormat(FF_SHELL_MODULE_NAME, 0, &options->moduleArgs, FF_SHELL_NUM_FORMAT_ARGS, (FFformatarg[]) {
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &result->shellProcessName},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &result->shellExe},
|
||||
{FF_FORMAT_ARG_TYPE_STRING, result->shellExeName},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &result->shellVersion},
|
||||
{FF_FORMAT_ARG_TYPE_UINT, &result->shellPid},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &result->shellPrettyName},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &result->processName},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &result->exe},
|
||||
{FF_FORMAT_ARG_TYPE_STRING, result->exeName},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &result->version},
|
||||
{FF_FORMAT_ARG_TYPE_UINT, &result->pid},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &result->prettyName},
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -79,20 +79,21 @@ void ffGenerateShellJsonConfig(FFShellOptions* options, yyjson_mut_doc* doc, yyj
|
||||
|
||||
void ffGenerateShellJsonResult(FF_MAYBE_UNUSED FFShellOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module)
|
||||
{
|
||||
const FFTerminalShellResult* result = ffDetectTerminalShell();
|
||||
const FFShellResult* result = ffDetectShell();
|
||||
|
||||
if(result->shellProcessName.length == 0)
|
||||
if(result->processName.length == 0)
|
||||
{
|
||||
yyjson_mut_obj_add_str(doc, module, "error", "Couldn't detect shell");
|
||||
return;
|
||||
}
|
||||
|
||||
yyjson_mut_val* obj = yyjson_mut_obj_add_obj(doc, module, "result");
|
||||
yyjson_mut_obj_add_strbuf(doc, obj, "exe", &result->shellExe);
|
||||
yyjson_mut_obj_add_strcpy(doc, obj, "exeName", result->shellExeName);
|
||||
yyjson_mut_obj_add_uint(doc, obj, "pid", result->shellPid);
|
||||
yyjson_mut_obj_add_strbuf(doc, obj, "processName", &result->shellProcessName);
|
||||
yyjson_mut_obj_add_strbuf(doc, obj, "version", &result->shellVersion);
|
||||
yyjson_mut_obj_add_strbuf(doc, obj, "exe", &result->exe);
|
||||
yyjson_mut_obj_add_strcpy(doc, obj, "exeName", result->exeName);
|
||||
yyjson_mut_obj_add_uint(doc, obj, "pid", result->pid);
|
||||
yyjson_mut_obj_add_uint(doc, obj, "ppid", result->ppid);
|
||||
yyjson_mut_obj_add_strbuf(doc, obj, "processName", &result->processName);
|
||||
yyjson_mut_obj_add_strbuf(doc, obj, "version", &result->version);
|
||||
}
|
||||
|
||||
void ffPrintShellHelpFormat(void)
|
||||
|
||||
@@ -10,9 +10,9 @@
|
||||
|
||||
void ffPrintTerminal(FFTerminalOptions* options)
|
||||
{
|
||||
const FFTerminalShellResult* result = ffDetectTerminalShell();
|
||||
const FFTerminalResult* result = ffDetectTerminal();
|
||||
|
||||
if(result->terminalProcessName.length == 0)
|
||||
if(result->processName.length == 0)
|
||||
{
|
||||
ffPrintError(FF_TERMINAL_MODULE_NAME, 0, &options->moduleArgs, "Couldn't detect terminal");
|
||||
return;
|
||||
@@ -22,20 +22,20 @@ void ffPrintTerminal(FFTerminalOptions* options)
|
||||
{
|
||||
ffPrintLogoAndKey(FF_TERMINAL_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT);
|
||||
|
||||
if(result->terminalVersion.length)
|
||||
printf("%s %s\n", result->terminalPrettyName.chars, result->terminalVersion.chars);
|
||||
if(result->version.length)
|
||||
printf("%s %s\n", result->prettyName.chars, result->version.chars);
|
||||
else
|
||||
ffStrbufPutTo(&result->terminalPrettyName, stdout);
|
||||
ffStrbufPutTo(&result->prettyName, stdout);
|
||||
}
|
||||
else
|
||||
{
|
||||
ffPrintFormat(FF_TERMINAL_MODULE_NAME, 0, &options->moduleArgs, FF_TERMINAL_NUM_FORMAT_ARGS, (FFformatarg[]){
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &result->terminalProcessName},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &result->terminalExe},
|
||||
{FF_FORMAT_ARG_TYPE_STRING, result->terminalExeName},
|
||||
{FF_FORMAT_ARG_TYPE_UINT, &result->terminalPid},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &result->terminalPrettyName},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &result->terminalVersion},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &result->processName},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &result->exe},
|
||||
{FF_FORMAT_ARG_TYPE_STRING, result->exeName},
|
||||
{FF_FORMAT_ARG_TYPE_UINT, &result->pid},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &result->prettyName},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &result->version},
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -77,21 +77,22 @@ void ffGenerateTerminalJsonConfig(FFTerminalOptions* options, yyjson_mut_doc* do
|
||||
|
||||
void ffGenerateTerminalJsonResult(FF_MAYBE_UNUSED FFTerminalOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module)
|
||||
{
|
||||
const FFTerminalShellResult* result = ffDetectTerminalShell();
|
||||
const FFTerminalResult* result = ffDetectTerminal();
|
||||
|
||||
if(result->terminalProcessName.length == 0)
|
||||
if(result->processName.length == 0)
|
||||
{
|
||||
yyjson_mut_obj_add_str(doc, module, "error", "Couldn't detect terminal");
|
||||
return;
|
||||
}
|
||||
|
||||
yyjson_mut_val* obj = yyjson_mut_obj_add_obj(doc, module, "result");
|
||||
yyjson_mut_obj_add_strbuf(doc, obj, "processName", &result->terminalProcessName);
|
||||
yyjson_mut_obj_add_strbuf(doc, obj, "exe", &result->terminalExe);
|
||||
yyjson_mut_obj_add_strcpy(doc, obj, "exeName", result->terminalExeName);
|
||||
yyjson_mut_obj_add_uint(doc, obj, "pid", result->terminalPid);
|
||||
yyjson_mut_obj_add_strbuf(doc, obj, "prettyName", &result->terminalPrettyName);
|
||||
yyjson_mut_obj_add_strbuf(doc, obj, "version", &result->terminalVersion);
|
||||
yyjson_mut_obj_add_strbuf(doc, obj, "processName", &result->processName);
|
||||
yyjson_mut_obj_add_strbuf(doc, obj, "exe", &result->exe);
|
||||
yyjson_mut_obj_add_strcpy(doc, obj, "exeName", result->exeName);
|
||||
yyjson_mut_obj_add_uint(doc, obj, "pid", result->pid);
|
||||
yyjson_mut_obj_add_uint(doc, obj, "ppid", result->ppid);
|
||||
yyjson_mut_obj_add_strbuf(doc, obj, "prettyName", &result->prettyName);
|
||||
yyjson_mut_obj_add_strbuf(doc, obj, "version", &result->version);
|
||||
}
|
||||
|
||||
void ffPrintTerminalHelpFormat(void)
|
||||
|
||||
Reference in New Issue
Block a user