summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVaxry <43317083+vaxerski@users.noreply.github.com>2026-04-30 22:31:29 +0100
committerGitHub <noreply@github.com>2026-04-30 22:31:29 +0100
commitc6fc1cab99ff8a3d721ae0e5937512e8d6f58a71 (patch)
tree9a362f9ba1984fc9ba554e4e13e50dee0e861192 /src
parent450d8a0bf703f3ec460d367f38d61b5966daf8fe (diff)
helpers/systemInfo: extract info fns (#14222)
Diffstat (limited to 'src')
-rw-r--r--src/Compositor.cpp30
-rw-r--r--src/debug/HyprCtl.cpp230
-rw-r--r--src/helpers/MiscFunctions.cpp48
-rw-r--r--src/helpers/MiscFunctions.hpp1
-rw-r--r--src/helpers/SystemInfo.cpp257
-rw-r--r--src/helpers/SystemInfo.hpp11
-rw-r--r--src/main.cpp35
7 files changed, 323 insertions, 289 deletions
diff --git a/src/Compositor.cpp b/src/Compositor.cpp
index c6430027..ab371df2 100644
--- a/src/Compositor.cpp
+++ b/src/Compositor.cpp
@@ -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);
diff --git a/src/debug/HyprCtl.cpp b/src/debug/HyprCtl.cpp
index 11171472..278e92c6 100644
--- a/src/debug/HyprCtl.cpp
+++ b/src/debug/HyprCtl.cpp
@@ -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, ' ');
diff --git a/src/helpers/MiscFunctions.cpp b/src/helpers/MiscFunctions.cpp
index 5e37f19f..5aa58a2c 100644
--- a/src/helpers/MiscFunctions.cpp
+++ b/src/helpers/MiscFunctions.cpp
@@ -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[] = {
diff --git a/src/helpers/MiscFunctions.hpp b/src/helpers/MiscFunctions.hpp
index 26c5c7ad..0528be58 100644
--- a/src/helpers/MiscFunctions.hpp
+++ b/src/helpers/MiscFunctions.hpp
@@ -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&);
diff --git a/src/helpers/SystemInfo.cpp b/src/helpers/SystemInfo.cpp
new file mode 100644
index 00000000..3ebdd16d
--- /dev/null
+++ b/src/helpers/SystemInfo.cpp
@@ -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;
+} \ No newline at end of file
diff --git a/src/helpers/SystemInfo.hpp b/src/helpers/SystemInfo.hpp
new file mode 100644
index 00000000..5eec45c2
--- /dev/null
+++ b/src/helpers/SystemInfo.hpp
@@ -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);
+}; \ No newline at end of file
diff --git a/src/main.cpp b/src/main.cpp
index faf78083..b85146f6 100644
--- a/src/main.cpp
+++ b/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.