ok thats better i think
This commit is contained in:
parent
36bf93de41
commit
bf449d91fc
|
@ -195,9 +195,6 @@ namespace {
|
||||||
fn main() -> i32 {
|
fn main() -> i32 {
|
||||||
const Config& config = Config::getInstance();
|
const Config& config = Config::getInstance();
|
||||||
|
|
||||||
DEBUG_LOG("Window Manager: {}", GetWindowManager());
|
|
||||||
DEBUG_LOG("Desktop Environment: {}", GetDesktopEnvironment());
|
|
||||||
|
|
||||||
Element document = hbox({ SystemInfoBox(config), filler() });
|
Element document = hbox({ SystemInfoBox(config), filler() });
|
||||||
|
|
||||||
Screen screen = Screen::Create(Dimension::Full(), Dimension::Fit(document));
|
Screen screen = Screen::Create(Dimension::Full(), Dimension::Fit(document));
|
||||||
|
|
229
src/os/linux.cpp
229
src/os/linux.cpp
|
@ -20,34 +20,55 @@
|
||||||
enum SessionType : u8 { Wayland, X11, TTY, Unknown };
|
enum SessionType : u8 { Wayland, X11, TTY, Unknown };
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
fn ParseLineAsNumber(const std::string& input) -> u64 {
|
|
||||||
usize start = input.find_first_of("0123456789");
|
|
||||||
|
|
||||||
if (start == std::string::npos) {
|
|
||||||
ERROR_LOG("No number found in input");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
usize end = input.find_first_not_of("0123456789", start);
|
|
||||||
|
|
||||||
return std::stoull(input.substr(start, end - start));
|
|
||||||
}
|
|
||||||
|
|
||||||
fn MeminfoParse() -> u64 {
|
fn MeminfoParse() -> u64 {
|
||||||
constexpr const char* path = "/proc/meminfo";
|
constexpr const char* path = "/proc/meminfo";
|
||||||
|
|
||||||
std::ifstream input(path);
|
std::ifstream input(path);
|
||||||
|
|
||||||
if (!input.is_open()) {
|
if (!input.is_open()) {
|
||||||
ERROR_LOG("Failed to open {}", path);
|
ERROR_LOG("Failed to open {}", path);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string line;
|
std::string line;
|
||||||
|
while (std::getline(input, line)) {
|
||||||
|
if (line.starts_with("MemTotal")) {
|
||||||
|
const size_t colonPos = line.find(':');
|
||||||
|
if (colonPos == std::string::npos) {
|
||||||
|
ERROR_LOG("Invalid MemTotal line: no colon found");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
while (std::getline(input, line))
|
std::string_view view(line);
|
||||||
if (line.starts_with("MemTotal"))
|
view.remove_prefix(colonPos + 1);
|
||||||
return ParseLineAsNumber(line);
|
|
||||||
|
// Trim leading whitespace
|
||||||
|
const size_t firstNonSpace = view.find_first_not_of(' ');
|
||||||
|
if (firstNonSpace == std::string_view::npos) {
|
||||||
|
ERROR_LOG("No number found after colon in MemTotal line");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
view.remove_prefix(firstNonSpace);
|
||||||
|
|
||||||
|
// Find the end of the numeric part
|
||||||
|
const size_t end = view.find_first_not_of("0123456789");
|
||||||
|
if (end != std::string_view::npos) {
|
||||||
|
view = view.substr(0, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get pointers via iterators
|
||||||
|
const char* startPtr = &*view.begin(); // Safe iterator-to-pointer conversion
|
||||||
|
const char* endPtr = &*view.end(); // No manual arithmetic
|
||||||
|
|
||||||
|
u64 value = 0;
|
||||||
|
const auto result = std::from_chars(startPtr, endPtr, value);
|
||||||
|
if (result.ec != std::errc() || result.ptr != endPtr) {
|
||||||
|
ERROR_LOG("Failed to parse number in MemTotal line");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ERROR_LOG("MemTotal line not found in {}", path);
|
ERROR_LOG("MemTotal line not found in {}", path);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -242,6 +263,97 @@ namespace {
|
||||||
// Final cleanup of wrapper names
|
// Final cleanup of wrapper names
|
||||||
return TrimHyprlandWrapper(compositorName);
|
return TrimHyprlandWrapper(compositorName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper functions
|
||||||
|
fn ToLowercase(std::string str) -> std::string {
|
||||||
|
std::ranges::transform(str, str.begin(), ::tolower);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ContainsAny(std::string_view haystack, const std::vector<std::string>& needles) -> bool {
|
||||||
|
return std::ranges::any_of(needles, [&](auto& n) { return haystack.find(n) != std::string_view::npos; });
|
||||||
|
}
|
||||||
|
|
||||||
|
fn DetectFromEnvVars() -> std::string {
|
||||||
|
// Check XDG_CURRENT_DESKTOP
|
||||||
|
if (const char* xdgDe = std::getenv("XDG_CURRENT_DESKTOP")) {
|
||||||
|
std::string_view sview(xdgDe);
|
||||||
|
if (!sview.empty()) {
|
||||||
|
std::string deStr(sview);
|
||||||
|
if (size_t colon = deStr.find(':'); colon != std::string::npos)
|
||||||
|
deStr.erase(colon);
|
||||||
|
if (!deStr.empty())
|
||||||
|
return deStr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check DESKTOP_SESSION
|
||||||
|
if (const char* desktopSession = std::getenv("DESKTOP_SESSION")) {
|
||||||
|
std::string_view sview(desktopSession);
|
||||||
|
if (!sview.empty())
|
||||||
|
return std::string(sview);
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
fn DetectFromSessionFiles() -> std::string {
|
||||||
|
namespace fs = std::filesystem;
|
||||||
|
const std::vector<fs::path> sessionPaths = { "/usr/share/xsessions", "/usr/share/wayland-sessions" };
|
||||||
|
|
||||||
|
const std::vector<std::pair<std::string, std::vector<std::string>>> dePatterns = {
|
||||||
|
{ "KDE", { "plasma", "plasmax11", "kde" } },
|
||||||
|
{ "GNOME", { "gnome", "gnome-xorg", "gnome-wayland" } },
|
||||||
|
{ "XFCE", { "xfce" } },
|
||||||
|
{ "MATE", { "mate" } },
|
||||||
|
{ "Cinnamon", { "cinnamon" } },
|
||||||
|
{ "Budgie", { "budgie" } },
|
||||||
|
{ "LXQt", { "lxqt" } },
|
||||||
|
{ "Unity", { "unity" } }
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const auto& sessionPath : sessionPaths) {
|
||||||
|
if (!fs::exists(sessionPath))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (const auto& entry : fs::directory_iterator(sessionPath)) {
|
||||||
|
if (!entry.is_regular_file())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const std::string filename = entry.path().stem();
|
||||||
|
auto lowerFilename = ToLowercase(filename);
|
||||||
|
|
||||||
|
for (const auto& [deName, patterns] : dePatterns) {
|
||||||
|
if (ContainsAny(lowerFilename, patterns))
|
||||||
|
return deName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
fn DetectFromProcesses() -> std::string {
|
||||||
|
const std::vector<std::pair<std::string, std::string>> processChecks = {
|
||||||
|
{ "plasmashell", "KDE" },
|
||||||
|
{ "gnome-shell", "GNOME" },
|
||||||
|
{ "xfce4-session", "XFCE" },
|
||||||
|
{ "mate-session", "MATE" },
|
||||||
|
{ "cinnamon-sessio", "Cinnamon" },
|
||||||
|
{ "budgie-wm", "Budgie" },
|
||||||
|
{ "lxqt-session", "LXQt" }
|
||||||
|
};
|
||||||
|
|
||||||
|
std::ifstream cmdline("/proc/self/environ");
|
||||||
|
std::string envVars((std::istreambuf_iterator<char>(cmdline)), std::istreambuf_iterator<char>());
|
||||||
|
|
||||||
|
for (const auto& [process, deName] : processChecks) {
|
||||||
|
if (envVars.find(process) != std::string::npos)
|
||||||
|
return deName;
|
||||||
|
}
|
||||||
|
|
||||||
|
return "Unknown";
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn GetOSVersion() -> std::string {
|
fn GetOSVersion() -> std::string {
|
||||||
|
@ -349,83 +461,16 @@ fn GetWindowManager() -> string {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn GetDesktopEnvironment() -> string {
|
fn GetDesktopEnvironment() -> string {
|
||||||
namespace fs = std::filesystem;
|
// Try environment variables first
|
||||||
|
if (auto desktopEnvironment = DetectFromEnvVars(); !desktopEnvironment.empty())
|
||||||
|
return desktopEnvironment;
|
||||||
|
|
||||||
// Check standard environment variables first
|
// Try session files next
|
||||||
if (const char* xdgDe = std::getenv("XDG_CURRENT_DESKTOP")) {
|
if (auto desktopEnvironment = DetectFromSessionFiles(); !desktopEnvironment.empty())
|
||||||
if (xdgDe[0] != '\0') {
|
return desktopEnvironment;
|
||||||
std::string de(xdgDe);
|
|
||||||
if (size_t colon = de.find(':'); colon != std::string::npos)
|
|
||||||
de.erase(colon);
|
|
||||||
if (!de.empty())
|
|
||||||
return de;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (const char* desktopSession = std::getenv("DESKTOP_SESSION")) {
|
// Fallback to process detection
|
||||||
if (desktopSession[0] != '\0') {
|
return DetectFromProcesses();
|
||||||
return desktopSession;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check session files in standard locations
|
|
||||||
const std::vector<fs::path> sessionPaths = { "/usr/share/xsessions", "/usr/share/wayland-sessions" };
|
|
||||||
|
|
||||||
// Map of DE identifiers to their session file patterns
|
|
||||||
const std::vector<std::pair<std::string, std::vector<std::string>>> dePatterns = {
|
|
||||||
{ "KDE", { "plasma", "plasmax11", "kde" } },
|
|
||||||
{ "GNOME", { "gnome", "gnome-xorg", "gnome-wayland" } },
|
|
||||||
{ "XFCE", { "xfce" } },
|
|
||||||
{ "MATE", { "mate" } },
|
|
||||||
{ "Cinnamon", { "cinnamon" } },
|
|
||||||
{ "Budgie", { "budgie" } },
|
|
||||||
{ "LXQt", { "lxqt" } },
|
|
||||||
{ "Unity", { "unity" } }
|
|
||||||
};
|
|
||||||
|
|
||||||
for (const auto& sessionPath : sessionPaths) {
|
|
||||||
if (!fs::exists(sessionPath))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for (const auto& entry : fs::directory_iterator(sessionPath)) {
|
|
||||||
if (!entry.is_regular_file())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
const std::string filename = entry.path().stem();
|
|
||||||
std::string lowercaseFilename;
|
|
||||||
std::ranges::transform(filename, std::back_inserter(lowercaseFilename), ::tolower);
|
|
||||||
|
|
||||||
for (const auto& [deName, patterns] : dePatterns) {
|
|
||||||
for (const auto& pattern : patterns) {
|
|
||||||
if (lowercaseFilename.find(pattern) != std::string::npos) {
|
|
||||||
return deName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fallback: Check process-based detection
|
|
||||||
const std::vector<std::pair<std::string, std::string>> processChecks = {
|
|
||||||
{ "plasmashell", "KDE" },
|
|
||||||
{ "gnome-shell", "GNOME" },
|
|
||||||
{ "xfce4-session", "XFCE" },
|
|
||||||
{ "mate-session", "MATE" },
|
|
||||||
{ "cinnamon-sessio", "Cinnamon" },
|
|
||||||
{ "budgie-wm", "Budgie" },
|
|
||||||
{ "lxqt-session", "LXQt" }
|
|
||||||
};
|
|
||||||
|
|
||||||
std::ifstream cmdline("/proc/self/environ");
|
|
||||||
std::string envVars((std::istreambuf_iterator<char>(cmdline)), std::istreambuf_iterator<char>());
|
|
||||||
|
|
||||||
for (const auto& [process, deName] : processChecks) {
|
|
||||||
if (envVars.find(process) != std::string::npos) {
|
|
||||||
return deName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return "Unknown";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn GetShell() -> string {
|
fn GetShell() -> string {
|
||||||
|
|
Loading…
Reference in a new issue