mirror of
https://github.com/hyprwm/Hyprland
synced 2026-05-07 03:18:01 +02:00
helpers/systemInfo: extract info fns (#14222)
This commit is contained in:
parent
450d8a0bf7
commit
c6fc1cab99
7 changed files with 323 additions and 289 deletions
|
|
@ -10,6 +10,7 @@
|
|||
#include "desktop/history/WorkspaceHistoryTracker.hpp"
|
||||
#include "desktop/view/Group.hpp"
|
||||
#include "helpers/Splashes.hpp"
|
||||
#include "helpers/SystemInfo.hpp"
|
||||
#include "config/ConfigValue.hpp"
|
||||
#include "config/legacy/ConfigManager.hpp"
|
||||
#include "config/shared/inotify/ConfigWatcher.hpp"
|
||||
|
|
@ -232,26 +233,7 @@ CCompositor::CCompositor(bool onlyConfig) : m_onlyConfigVerification(onlyConfig)
|
|||
|
||||
Log::logger->initIS(m_instancePath);
|
||||
|
||||
Log::logger->log(Log::DEBUG, "Instance Signature: {}", m_instanceSignature);
|
||||
|
||||
Log::logger->log(Log::DEBUG, "Runtime directory: {}", m_instancePath);
|
||||
|
||||
Log::logger->log(Log::DEBUG, "Hyprland PID: {}", m_hyprlandPID);
|
||||
|
||||
Log::logger->log(Log::DEBUG, "===== SYSTEM INFO: =====");
|
||||
|
||||
logSystemInfo();
|
||||
|
||||
Log::logger->log(Log::DEBUG, "========================");
|
||||
|
||||
Log::logger->log(Log::DEBUG, "\n\n"); // pad
|
||||
|
||||
Log::logger->log(Log::INFO, "If you are crashing, or encounter any bugs, please consult https://wiki.hypr.land/Crashes-and-Bugs/\n\n");
|
||||
|
||||
setRandomSplash();
|
||||
|
||||
Log::logger->log(Log::DEBUG, "\nCurrent splash: {}\n\n", m_currentSplash);
|
||||
|
||||
bumpNofile();
|
||||
}
|
||||
|
||||
|
|
@ -365,6 +347,16 @@ void CCompositor::initServer(std::string socketName, int socketFd) {
|
|||
|
||||
m_initialized = true;
|
||||
|
||||
Log::logger->log(Log::DEBUG, "Instance Signature: {}", m_instanceSignature);
|
||||
Log::logger->log(Log::DEBUG, "Runtime directory: {}", m_instancePath);
|
||||
Log::logger->log(Log::DEBUG, "Hyprland PID: {}", m_hyprlandPID);
|
||||
Log::logger->log(Log::DEBUG, "===== SYSTEM INFO: =====");
|
||||
Log::logger->log(Log::DEBUG, "{}", Helpers::SystemInfo::getSystemInfo());
|
||||
Log::logger->log(Log::DEBUG, "========================");
|
||||
Log::logger->log(Log::DEBUG, "\n\n"); // pad
|
||||
Log::logger->log(Log::INFO, "If you are crashing, or encounter any bugs, please consult https://wiki.hypr.land/Crashes-and-Bugs/\n\n");
|
||||
Log::logger->log(Log::DEBUG, "\nCurrent splash: {}\n\n", m_currentSplash);
|
||||
|
||||
m_drm.fd = m_aqBackend->drmFD();
|
||||
Log::logger->log(Log::DEBUG, "Running on DRMFD: {}", m_drm.fd);
|
||||
|
||||
|
|
|
|||
|
|
@ -49,9 +49,10 @@ using namespace Hyprutils::OS;
|
|||
#include "../devices/ITouch.hpp"
|
||||
#include "../devices/Tablet.hpp"
|
||||
#include "../protocols/GlobalShortcuts.hpp"
|
||||
#include "debug/log/RollingLogFollow.hpp"
|
||||
#include "config/ConfigManager.hpp"
|
||||
#include "helpers/MiscFunctions.hpp"
|
||||
#include "../debug/log/RollingLogFollow.hpp"
|
||||
#include "../config/ConfigManager.hpp"
|
||||
#include "../helpers/MiscFunctions.hpp"
|
||||
#include "../helpers/SystemInfo.hpp"
|
||||
#include "../desktop/view/LayerSurface.hpp"
|
||||
#include "../desktop/view/Group.hpp"
|
||||
#include "../desktop/rule/Engine.hpp"
|
||||
|
|
@ -1061,193 +1062,19 @@ static std::string bindsRequest(eHyprCtlOutputFormat format, std::string request
|
|||
}
|
||||
|
||||
std::string versionRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
return Helpers::SystemInfo::getVersion(format);
|
||||
}
|
||||
|
||||
auto commitMsg = trim(GIT_COMMIT_MESSAGE);
|
||||
std::ranges::replace(commitMsg, '#', ' ');
|
||||
|
||||
if (format == eHyprCtlOutputFormat::FORMAT_NORMAL) {
|
||||
std::string result = std::format("Hyprland {} built from branch {} at commit {} {} ({}).\n"
|
||||
"Date: {}\n"
|
||||
"Tag: {}, commits: {}\n",
|
||||
HYPRLAND_VERSION, GIT_BRANCH, GIT_COMMIT_HASH, GIT_DIRTY, commitMsg, GIT_COMMIT_DATE, GIT_TAG, GIT_COMMITS);
|
||||
|
||||
result += "\n";
|
||||
result += getBuiltSystemLibraryNames();
|
||||
result += "\n";
|
||||
result += "Version ABI string: ";
|
||||
result += __hyprland_api_get_hash();
|
||||
result += "\n";
|
||||
|
||||
#if (!ISDEBUG && !defined(NO_XWAYLAND) && !defined(BUILT_WITH_NIX))
|
||||
result += "no flags were set\n";
|
||||
#else
|
||||
result += "flags set:\n";
|
||||
#if ISDEBUG
|
||||
result += "debug\n";
|
||||
#endif
|
||||
#ifdef NO_XWAYLAND
|
||||
result += "no xwayland\n";
|
||||
#endif
|
||||
#ifdef BUILT_WITH_NIX
|
||||
result += "nix\n";
|
||||
#endif
|
||||
#endif
|
||||
return result;
|
||||
} else {
|
||||
std::string result = std::format(
|
||||
R"#({{
|
||||
"branch": "{}",
|
||||
"commit": "{}",
|
||||
"version": "{}",
|
||||
"dirty": {},
|
||||
"commit_message": "{}",
|
||||
"commit_date": "{}",
|
||||
"tag": "{}",
|
||||
"commits": "{}",
|
||||
"buildAquamarine": "{}",
|
||||
"buildHyprlang": "{}",
|
||||
"buildHyprutils": "{}",
|
||||
"buildHyprcursor": "{}",
|
||||
"buildHyprgraphics": "{}",
|
||||
"systemAquamarine": "{}",
|
||||
"systemHyprlang": "{}",
|
||||
"systemHyprutils": "{}",
|
||||
"systemHyprcursor": "{}",
|
||||
"systemHyprgraphics": "{}",
|
||||
"abiHash": "{}",
|
||||
"flags": [)#",
|
||||
GIT_BRANCH, GIT_COMMIT_HASH, HYPRLAND_VERSION, (strcmp(GIT_DIRTY, "dirty") == 0 ? "true" : "false"), escapeJSONStrings(commitMsg), GIT_COMMIT_DATE, GIT_TAG,
|
||||
GIT_COMMITS, AQUAMARINE_VERSION, HYPRLANG_VERSION, HYPRUTILS_VERSION, HYPRCURSOR_VERSION, HYPRGRAPHICS_VERSION, getSystemLibraryVersion("aquamarine"),
|
||||
getSystemLibraryVersion("hyprlang"), getSystemLibraryVersion("hyprutils"), getSystemLibraryVersion("hyprcursor"), getSystemLibraryVersion("hyprgraphics"),
|
||||
__hyprland_api_get_hash());
|
||||
|
||||
#if ISDEBUG
|
||||
result += "\"debug\",";
|
||||
#endif
|
||||
#ifdef NO_XWAYLAND
|
||||
result += "\"no xwayland\",";
|
||||
#endif
|
||||
#ifdef BUILT_WITH_NIX
|
||||
result += "\"nix\",";
|
||||
#endif
|
||||
|
||||
trimTrailingComma(result);
|
||||
|
||||
result += "]\n}";
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
return ""; // make the compiler happy
|
||||
static std::string statusRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
return Helpers::SystemInfo::getStatus(format);
|
||||
}
|
||||
|
||||
std::string systemInfoRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
std::string result = versionRequest(eHyprCtlOutputFormat::FORMAT_NORMAL, "");
|
||||
|
||||
static auto check = [](bool y) -> std::string { return y ? "✔️" : "❌"; };
|
||||
static auto backend = [](Aquamarine::eBackendType t) -> std::string {
|
||||
switch (t) {
|
||||
case Aquamarine::AQ_BACKEND_DRM: return "drm";
|
||||
case Aquamarine::AQ_BACKEND_HEADLESS: return "headless";
|
||||
case Aquamarine::AQ_BACKEND_WAYLAND: return "wayland";
|
||||
default: break;
|
||||
}
|
||||
return "?";
|
||||
};
|
||||
|
||||
result += "\n\nSystem Information:\n";
|
||||
|
||||
struct utsname unameInfo;
|
||||
|
||||
uname(&unameInfo);
|
||||
|
||||
result += "System name: " + std::string{unameInfo.sysname} + "\n";
|
||||
result += "Node name: " + std::string{unameInfo.nodename} + "\n";
|
||||
result += "Release: " + std::string{unameInfo.release} + "\n";
|
||||
result += "Version: " + std::string{unameInfo.version} + "\n";
|
||||
result += "\n";
|
||||
result += getBuiltSystemLibraryNames();
|
||||
result += "\n";
|
||||
|
||||
result += "\n\n";
|
||||
|
||||
#if defined(__DragonFly__) || defined(__FreeBSD__)
|
||||
const std::string GPUINFO = execAndGet("pciconf -lv | grep -F -A4 vga");
|
||||
#elif defined(__arm__) || defined(__aarch64__)
|
||||
std::string GPUINFO;
|
||||
const std::filesystem::path dev_tree = "/proc/device-tree";
|
||||
try {
|
||||
if (std::filesystem::exists(dev_tree) && std::filesystem::is_directory(dev_tree)) {
|
||||
std::for_each(std::filesystem::directory_iterator(dev_tree), std::filesystem::directory_iterator{}, [&](const std::filesystem::directory_entry& entry) {
|
||||
if (std::filesystem::is_directory(entry) && entry.path().filename().string().starts_with("soc")) {
|
||||
std::for_each(std::filesystem::directory_iterator(entry.path()), std::filesystem::directory_iterator{}, [&](const std::filesystem::directory_entry& sub_entry) {
|
||||
if (std::filesystem::is_directory(sub_entry) && sub_entry.path().filename().string().starts_with("gpu")) {
|
||||
std::filesystem::path file_path = sub_entry.path() / "compatible";
|
||||
std::ifstream file(file_path);
|
||||
if (file)
|
||||
GPUINFO.append(std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>());
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (...) { GPUINFO = "error"; }
|
||||
#else
|
||||
const std::string GPUINFO = execAndGet("lspci -vnn | grep -E '(VGA|Display|3D)'");
|
||||
#endif
|
||||
result += "GPU information: \n" + GPUINFO;
|
||||
if (GPUINFO.contains("NVIDIA") && std::filesystem::exists("/proc/driver/nvidia/version")) {
|
||||
std::ifstream file("/proc/driver/nvidia/version");
|
||||
std::string line;
|
||||
if (file.is_open()) {
|
||||
while (std::getline(file, line)) {
|
||||
if (!line.contains("NVRM"))
|
||||
continue;
|
||||
result += line;
|
||||
result += "\n";
|
||||
}
|
||||
} else
|
||||
result += "error";
|
||||
}
|
||||
result += "\n\n";
|
||||
|
||||
if (std::ifstream file("/etc/os-release"); file.is_open()) {
|
||||
std::stringstream buffer;
|
||||
buffer << file.rdbuf();
|
||||
result += "os-release: " + buffer.str() + "\n\n";
|
||||
} else
|
||||
result += "os-release: error\n\n";
|
||||
|
||||
result += "plugins:\n";
|
||||
if (g_pPluginSystem) {
|
||||
for (auto const& pl : g_pPluginSystem->getAllPlugins()) {
|
||||
result += std::format(" {} by {} ver {}\n", pl->m_name, pl->m_author, pl->m_version);
|
||||
}
|
||||
} else
|
||||
result += "\tunknown: not runtime\n";
|
||||
|
||||
if (g_pHyprOpenGL) {
|
||||
result += std::format("\nExplicit sync: {}", g_pHyprOpenGL->m_exts.EGL_ANDROID_native_fence_sync_ext ? "supported" : "missing");
|
||||
result += std::format("\nGL ver: {}", g_pHyprOpenGL->m_eglContextVersion == CHyprOpenGLImpl::EGL_CONTEXT_GLES_3_2 ? "3.2" : "3.0");
|
||||
}
|
||||
|
||||
if (g_pCompositor) {
|
||||
result += std::format("\nBackend: {}", g_pCompositor->m_aqBackend->hasSession() ? "drm" : "sessionless");
|
||||
|
||||
result += "\n\nMonitor info:";
|
||||
|
||||
for (const auto& m : g_pCompositor->m_monitors) {
|
||||
result += std::format("\n\tPanel {}: {}x{}, {} {} {} {} -> backend {}\n\t\texplicit {}\n\t\tedid:\n\t\t\thdr {}\n\t\t\tchroma {}\n\t\t\tbt2020 {}\n\t\tvrr capable "
|
||||
"{}\n\t\tnon-desktop {}\n\t\t",
|
||||
m->m_name, sc<int>(m->m_pixelSize.x), sc<int>(m->m_pixelSize.y), m->m_output->name, m->m_output->make, m->m_output->model, m->m_output->serial,
|
||||
backend(m->m_output->getBackend()->type()), check(m->m_output->supportsExplicit), check(m->m_output->parsedEDID.hdrMetadata.has_value()),
|
||||
check(m->m_output->parsedEDID.chromaticityCoords.has_value()), check(m->m_output->parsedEDID.supportsBT2020), check(m->m_output->vrrCapable),
|
||||
check(m->m_output->nonDesktop));
|
||||
}
|
||||
}
|
||||
auto result = Helpers::SystemInfo::getSystemInfo();
|
||||
|
||||
if (g_pHyprCtl && g_pHyprCtl->m_currentRequestParams.sysInfoConfig) {
|
||||
result += "\n======Config-Start======\n";
|
||||
result += "\n\n======Config-Start======\n";
|
||||
result += Config::mgr()->getConfigString();
|
||||
result += "\n======Config-End========\n";
|
||||
}
|
||||
|
|
@ -2097,43 +1924,6 @@ static std::string submapRequest(eHyprCtlOutputFormat format, std::string reques
|
|||
return format == FORMAT_JSON ? std::format("\"{}\"\n", escapeJSONStrings(submap)) : (submap + "\n");
|
||||
}
|
||||
|
||||
static std::string statusRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
Aquamarine::eBackendType backendType = Aquamarine::eBackendType::AQ_BACKEND_NULL;
|
||||
|
||||
for (const auto& i : g_pCompositor->m_aqBackend->getImplementations()) {
|
||||
if (i->type() == Aquamarine::eBackendType::AQ_BACKEND_NULL || i->type() == Aquamarine::eBackendType::AQ_BACKEND_HEADLESS)
|
||||
continue;
|
||||
|
||||
backendType = i->type();
|
||||
break;
|
||||
}
|
||||
|
||||
std::string backendStr;
|
||||
|
||||
switch (backendType) {
|
||||
case Aquamarine::AQ_BACKEND_DRM: backendStr = "drm"; break;
|
||||
case Aquamarine::AQ_BACKEND_WAYLAND: backendStr = "wayland"; break;
|
||||
default: backendStr = "error"; break;
|
||||
}
|
||||
|
||||
if (format == eHyprCtlOutputFormat::FORMAT_JSON) {
|
||||
|
||||
return std::format(R"#(
|
||||
{{
|
||||
"configProvider": "{}",
|
||||
"backend": "{}"
|
||||
}}
|
||||
)#",
|
||||
Config::typeToString(Config::mgr()->type()), backendStr);
|
||||
}
|
||||
|
||||
return std::format(R"#(
|
||||
configProvider: {}
|
||||
backend: {}
|
||||
)#",
|
||||
Config::typeToString(Config::mgr()->type()), backendStr);
|
||||
}
|
||||
|
||||
static std::string reloadShaders(eHyprCtlOutputFormat format, std::string request) {
|
||||
CVarList vars(request, 0, ' ');
|
||||
|
||||
|
|
|
|||
|
|
@ -523,54 +523,6 @@ std::string execAndGet(const char* cmd) {
|
|||
return proc.stdOut();
|
||||
}
|
||||
|
||||
void logSystemInfo() {
|
||||
struct utsname unameInfo;
|
||||
|
||||
uname(&unameInfo);
|
||||
|
||||
Log::logger->log(Log::DEBUG, "System name: {}", std::string{unameInfo.sysname});
|
||||
Log::logger->log(Log::DEBUG, "Node name: {}", std::string{unameInfo.nodename});
|
||||
Log::logger->log(Log::DEBUG, "Release: {}", std::string{unameInfo.release});
|
||||
Log::logger->log(Log::DEBUG, "Version: {}", std::string{unameInfo.version});
|
||||
|
||||
Log::logger->log(Log::DEBUG, "\n");
|
||||
|
||||
#if defined(__DragonFly__) || defined(__FreeBSD__)
|
||||
const std::string GPUINFO = execAndGet("pciconf -lv | grep -F -A4 vga");
|
||||
#elif defined(__arm__) || defined(__aarch64__)
|
||||
std::string GPUINFO;
|
||||
const std::filesystem::path dev_tree = "/proc/device-tree";
|
||||
try {
|
||||
if (std::filesystem::exists(dev_tree) && std::filesystem::is_directory(dev_tree)) {
|
||||
std::for_each(std::filesystem::directory_iterator(dev_tree), std::filesystem::directory_iterator{}, [&](const std::filesystem::directory_entry& entry) {
|
||||
if (std::filesystem::is_directory(entry) && entry.path().filename().string().starts_with("soc")) {
|
||||
std::for_each(std::filesystem::directory_iterator(entry.path()), std::filesystem::directory_iterator{}, [&](const std::filesystem::directory_entry& sub_entry) {
|
||||
if (std::filesystem::is_directory(sub_entry) && sub_entry.path().filename().string().starts_with("gpu")) {
|
||||
std::filesystem::path file_path = sub_entry.path() / "compatible";
|
||||
std::ifstream file(file_path);
|
||||
if (file)
|
||||
GPUINFO.append(std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>());
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (...) { GPUINFO = "error"; }
|
||||
#else
|
||||
const std::string GPUINFO = execAndGet("lspci -vnn | grep -E '(VGA|Display|3D)'");
|
||||
#endif
|
||||
Log::logger->log(Log::DEBUG, "GPU information:\n{}\n", GPUINFO);
|
||||
|
||||
if (GPUINFO.contains("NVIDIA")) {
|
||||
Log::logger->log(Log::WARN, "Warning: you're using an NVIDIA GPU. Make sure you follow the instructions on the wiki if anything is amiss.\n");
|
||||
}
|
||||
|
||||
// log etc
|
||||
Log::logger->log(Log::DEBUG, "os-release:");
|
||||
|
||||
Log::logger->log(Log::DEBUG, "{}", NFsUtils::readFileAsString("/etc/os-release").value_or("error"));
|
||||
}
|
||||
|
||||
int64_t getPPIDof(int64_t pid) {
|
||||
#if defined(KERN_PROC_PID)
|
||||
int mib[] = {
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ bool isDirection(const char&);
|
|||
SWorkspaceIDName getWorkspaceIDNameFromString(const std::string&);
|
||||
std::optional<std::string> cleanCmdForWorkspace(const std::string&, std::string);
|
||||
float vecToRectDistanceSquared(const Vector2D& vec, const Vector2D& p1, const Vector2D& p2);
|
||||
void logSystemInfo();
|
||||
std::string execAndGet(const char*);
|
||||
int64_t getPPIDof(int64_t pid);
|
||||
std::expected<int64_t, std::string> configStringToInt(const std::string&);
|
||||
|
|
|
|||
257
src/helpers/SystemInfo.cpp
Normal file
257
src/helpers/SystemInfo.cpp
Normal file
|
|
@ -0,0 +1,257 @@
|
|||
#include "SystemInfo.hpp"
|
||||
|
||||
#include "../Compositor.hpp"
|
||||
#include "../version.h"
|
||||
#include "../plugins/PluginAPI.hpp"
|
||||
#include "../plugins/PluginSystem.hpp"
|
||||
#include "../render/OpenGL.hpp"
|
||||
#include "../config/ConfigManager.hpp"
|
||||
|
||||
#include <hyprutils/string/String.hpp>
|
||||
|
||||
#include <sys/utsname.h>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <format>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace Helpers::SystemInfo;
|
||||
using namespace Helpers;
|
||||
using namespace Hyprutils::String;
|
||||
using namespace Render::GL;
|
||||
|
||||
static void trimTrailingComma(std::string& str) {
|
||||
if (!str.empty() && str.back() == ',')
|
||||
str.pop_back();
|
||||
}
|
||||
|
||||
std::string SystemInfo::getStatus(eHyprCtlOutputFormat fmt) {
|
||||
Aquamarine::eBackendType backendType = Aquamarine::eBackendType::AQ_BACKEND_NULL;
|
||||
|
||||
for (const auto& i : g_pCompositor->m_aqBackend->getImplementations()) {
|
||||
if (i->type() == Aquamarine::eBackendType::AQ_BACKEND_NULL || i->type() == Aquamarine::eBackendType::AQ_BACKEND_HEADLESS)
|
||||
continue;
|
||||
|
||||
backendType = i->type();
|
||||
break;
|
||||
}
|
||||
|
||||
std::string backendStr;
|
||||
|
||||
switch (backendType) {
|
||||
case Aquamarine::AQ_BACKEND_DRM: backendStr = "drm"; break;
|
||||
case Aquamarine::AQ_BACKEND_WAYLAND: backendStr = "wayland"; break;
|
||||
default: backendStr = "error"; break;
|
||||
}
|
||||
|
||||
if (fmt == eHyprCtlOutputFormat::FORMAT_JSON) {
|
||||
|
||||
return std::format(R"#(
|
||||
{{
|
||||
"configProvider": "{}",
|
||||
"backend": "{}"
|
||||
}}
|
||||
)#",
|
||||
Config::typeToString(Config::mgr()->type()), backendStr);
|
||||
}
|
||||
|
||||
return std::format(R"#(
|
||||
configProvider: {}
|
||||
backend: {}
|
||||
)#",
|
||||
Config::typeToString(Config::mgr()->type()), backendStr);
|
||||
}
|
||||
|
||||
std::string SystemInfo::getVersion(eHyprCtlOutputFormat fmt) {
|
||||
|
||||
auto commitMsg = trim(GIT_COMMIT_MESSAGE);
|
||||
std::ranges::replace(commitMsg, '#', ' ');
|
||||
|
||||
if (fmt == eHyprCtlOutputFormat::FORMAT_NORMAL) {
|
||||
std::string result = std::format("Hyprland {} built from branch {} at commit {} {} ({}).\n"
|
||||
"Date: {}\n"
|
||||
"Tag: {}, commits: {}\n",
|
||||
HYPRLAND_VERSION, GIT_BRANCH, GIT_COMMIT_HASH, GIT_DIRTY, commitMsg, GIT_COMMIT_DATE, GIT_TAG, GIT_COMMITS);
|
||||
|
||||
result += "\n";
|
||||
result += getBuiltSystemLibraryNames();
|
||||
result += "\n";
|
||||
result += "Version ABI string: ";
|
||||
result += __hyprland_api_get_hash();
|
||||
result += "\n";
|
||||
|
||||
#if (!ISDEBUG && !defined(NO_XWAYLAND) && !defined(BUILT_WITH_NIX))
|
||||
result += "no flags were set\n";
|
||||
#else
|
||||
result += "flags set:\n";
|
||||
#if ISDEBUG
|
||||
result += "debug\n";
|
||||
#endif
|
||||
#ifdef NO_XWAYLAND
|
||||
result += "no xwayland\n";
|
||||
#endif
|
||||
#ifdef BUILT_WITH_NIX
|
||||
result += "nix\n";
|
||||
#endif
|
||||
#endif
|
||||
return result;
|
||||
} else {
|
||||
std::string result = std::format(
|
||||
R"#({{
|
||||
"branch": "{}",
|
||||
"commit": "{}",
|
||||
"version": "{}",
|
||||
"dirty": {},
|
||||
"commit_message": "{}",
|
||||
"commit_date": "{}",
|
||||
"tag": "{}",
|
||||
"commits": "{}",
|
||||
"buildAquamarine": "{}",
|
||||
"buildHyprlang": "{}",
|
||||
"buildHyprutils": "{}",
|
||||
"buildHyprcursor": "{}",
|
||||
"buildHyprgraphics": "{}",
|
||||
"systemAquamarine": "{}",
|
||||
"systemHyprlang": "{}",
|
||||
"systemHyprutils": "{}",
|
||||
"systemHyprcursor": "{}",
|
||||
"systemHyprgraphics": "{}",
|
||||
"abiHash": "{}",
|
||||
"flags": [)#",
|
||||
GIT_BRANCH, GIT_COMMIT_HASH, HYPRLAND_VERSION, (GIT_DIRTY == std::string_view{"dirty"} ? "true" : "false"), escapeJSONStrings(commitMsg), GIT_COMMIT_DATE, GIT_TAG,
|
||||
GIT_COMMITS, AQUAMARINE_VERSION, HYPRLANG_VERSION, HYPRUTILS_VERSION, HYPRCURSOR_VERSION, HYPRGRAPHICS_VERSION, getSystemLibraryVersion("aquamarine"),
|
||||
getSystemLibraryVersion("hyprlang"), getSystemLibraryVersion("hyprutils"), getSystemLibraryVersion("hyprcursor"), getSystemLibraryVersion("hyprgraphics"),
|
||||
__hyprland_api_get_hash());
|
||||
|
||||
#if ISDEBUG
|
||||
result += "\"debug\",";
|
||||
#endif
|
||||
#ifdef NO_XWAYLAND
|
||||
result += "\"no xwayland\",";
|
||||
#endif
|
||||
#ifdef BUILT_WITH_NIX
|
||||
result += "\"nix\",";
|
||||
#endif
|
||||
|
||||
trimTrailingComma(result);
|
||||
|
||||
result += "]\n}";
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
return ""; // make the compiler happy
|
||||
}
|
||||
|
||||
std::string SystemInfo::getSystemInfo() {
|
||||
std::string result = getVersion(eHyprCtlOutputFormat::FORMAT_NORMAL);
|
||||
|
||||
static auto check = [](bool y) -> std::string { return y ? "✔️" : "❌"; };
|
||||
static auto backend = [](Aquamarine::eBackendType t) -> std::string {
|
||||
switch (t) {
|
||||
case Aquamarine::AQ_BACKEND_DRM: return "drm";
|
||||
case Aquamarine::AQ_BACKEND_HEADLESS: return "headless";
|
||||
case Aquamarine::AQ_BACKEND_WAYLAND: return "wayland";
|
||||
default: break;
|
||||
}
|
||||
return "?";
|
||||
};
|
||||
|
||||
result += "\n\nSystem Information:\n";
|
||||
|
||||
struct utsname unameInfo;
|
||||
|
||||
uname(&unameInfo);
|
||||
|
||||
result += "System name: " + std::string{unameInfo.sysname} + "\n";
|
||||
result += "Node name: " + std::string{unameInfo.nodename} + "\n";
|
||||
result += "Release: " + std::string{unameInfo.release} + "\n";
|
||||
result += "Version: " + std::string{unameInfo.version} + "\n";
|
||||
result += "\n";
|
||||
result += getBuiltSystemLibraryNames();
|
||||
result += "\n";
|
||||
|
||||
result += "\n\n";
|
||||
|
||||
#if defined(__DragonFly__) || defined(__FreeBSD__)
|
||||
const std::string GPUINFO = execAndGet("pciconf -lv | grep -F -A4 vga");
|
||||
#elif defined(__arm__) || defined(__aarch64__)
|
||||
std::string GPUINFO;
|
||||
const std::filesystem::path dev_tree = "/proc/device-tree";
|
||||
try {
|
||||
if (std::filesystem::exists(dev_tree) && std::filesystem::is_directory(dev_tree)) {
|
||||
std::for_each(std::filesystem::directory_iterator(dev_tree), std::filesystem::directory_iterator{}, [&](const std::filesystem::directory_entry& entry) {
|
||||
if (std::filesystem::is_directory(entry) && entry.path().filename().string().starts_with("soc")) {
|
||||
std::for_each(std::filesystem::directory_iterator(entry.path()), std::filesystem::directory_iterator{}, [&](const std::filesystem::directory_entry& sub_entry) {
|
||||
if (std::filesystem::is_directory(sub_entry) && sub_entry.path().filename().string().starts_with("gpu")) {
|
||||
std::filesystem::path file_path = sub_entry.path() / "compatible";
|
||||
std::ifstream file(file_path);
|
||||
if (file)
|
||||
GPUINFO.append(std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>());
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (...) { GPUINFO = "error"; }
|
||||
#else
|
||||
const std::string GPUINFO = execAndGet("lspci -vnn | grep -E '(VGA|Display|3D)'");
|
||||
#endif
|
||||
result += "GPU information: \n" + GPUINFO;
|
||||
if (GPUINFO.contains("NVIDIA") && std::filesystem::exists("/proc/driver/nvidia/version")) {
|
||||
std::ifstream file("/proc/driver/nvidia/version");
|
||||
std::string line;
|
||||
if (file.is_open()) {
|
||||
while (std::getline(file, line)) {
|
||||
if (!line.contains("NVRM"))
|
||||
continue;
|
||||
result += line;
|
||||
result += "\n";
|
||||
}
|
||||
} else
|
||||
result += "error";
|
||||
}
|
||||
result += "\n\n";
|
||||
|
||||
if (std::ifstream file("/etc/os-release"); file.is_open()) {
|
||||
std::stringstream buffer;
|
||||
buffer << file.rdbuf();
|
||||
result += "os-release: " + buffer.str() + "\n\n";
|
||||
} else
|
||||
result += "os-release: error\n\n";
|
||||
|
||||
result += "plugins:\n";
|
||||
if (g_pPluginSystem) {
|
||||
for (auto const& pl : g_pPluginSystem->getAllPlugins()) {
|
||||
result += std::format(" {} by {} ver {}\n", pl->m_name, pl->m_author, pl->m_version);
|
||||
}
|
||||
} else
|
||||
result += "\tunknown: not runtime\n";
|
||||
|
||||
if (g_pHyprOpenGL) {
|
||||
result += std::format("\nExplicit sync: {}", g_pHyprOpenGL->m_exts.EGL_ANDROID_native_fence_sync_ext ? "supported" : "missing");
|
||||
result += std::format("\nGL ver: {}", g_pHyprOpenGL->m_eglContextVersion == CHyprOpenGLImpl::EGL_CONTEXT_GLES_3_2 ? "3.2" : "3.0");
|
||||
}
|
||||
|
||||
if (g_pCompositor) {
|
||||
result += std::format("\nBackend: {}", g_pCompositor->m_aqBackend->hasSession() ? "drm" : "sessionless");
|
||||
|
||||
result += "\n\nMonitor info:";
|
||||
|
||||
for (const auto& m : g_pCompositor->m_monitors) {
|
||||
result += std::format("\n\tPanel {}: {}x{}, {} {} {} {} -> backend {}\n\t\texplicit {}\n\t\tedid:\n\t\t\thdr {}\n\t\t\tchroma {}\n\t\t\tbt2020 {}\n\t\tvrr capable "
|
||||
"{}\n\t\tnon-desktop {}\n\t\t",
|
||||
m->m_name, sc<int>(m->m_pixelSize.x), sc<int>(m->m_pixelSize.y), m->m_output->name, m->m_output->make, m->m_output->model, m->m_output->serial,
|
||||
backend(m->m_output->getBackend()->type()), check(m->m_output->supportsExplicit), check(m->m_output->parsedEDID.hdrMetadata.has_value()),
|
||||
check(m->m_output->parsedEDID.chromaticityCoords.has_value()), check(m->m_output->parsedEDID.supportsBT2020), check(m->m_output->vrrCapable),
|
||||
check(m->m_output->nonDesktop));
|
||||
}
|
||||
}
|
||||
|
||||
result += "\n\nState:\n";
|
||||
result += getStatus(FORMAT_NORMAL);
|
||||
|
||||
result += "\n\n";
|
||||
|
||||
return result;
|
||||
}
|
||||
11
src/helpers/SystemInfo.hpp
Normal file
11
src/helpers/SystemInfo.hpp
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "../SharedDefs.hpp"
|
||||
|
||||
namespace Helpers::SystemInfo {
|
||||
std::string getSystemInfo();
|
||||
std::string getVersion(eHyprCtlOutputFormat fmt);
|
||||
std::string getStatus(eHyprCtlOutputFormat fmt);
|
||||
};
|
||||
35
src/main.cpp
35
src/main.cpp
|
|
@ -202,8 +202,41 @@ int main(int argc, char** argv) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
if (!verifyConfig)
|
||||
if (!verifyConfig) {
|
||||
std::println("Welcome to Hyprland!");
|
||||
std::println(R"#(
|
||||
|
||||
YY UJ
|
||||
YYY UUJ
|
||||
XXXY UUUU
|
||||
zXXXX UUUUU
|
||||
zzzzX UUUUJ
|
||||
cczzz UUUUJ
|
||||
vccccz UUUUUJ
|
||||
vvcccc UUUUUJ
|
||||
vvvvv UUUUJ
|
||||
uuuvv UUUUJ
|
||||
uuuuu UUUUU
|
||||
nnnuu UUUUU
|
||||
nnnnn YUUUU
|
||||
xxnn YUUU
|
||||
xxxn YYUU
|
||||
xxxx YYUU
|
||||
rxxx YYYY
|
||||
rrrx YYYY
|
||||
rrrx XXXY
|
||||
rrrr XXXX
|
||||
rrrr zzXX
|
||||
rrrr zzzz
|
||||
rrrrr ccczz
|
||||
rrrrrx vccccc
|
||||
rrrrxxxx uuvvvvvc
|
||||
rrxxxxxxnnnnuuuuuv
|
||||
xxxxxnnnnu
|
||||
|
||||
|
||||
)#");
|
||||
}
|
||||
|
||||
// let's init the compositor.
|
||||
// it initializes basic Wayland stuff in the constructor.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue