diff --git a/CMakeLists.txt b/CMakeLists.txt index 28ff5ff..d8fd6bd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,42 +6,22 @@ string(STRIP ${VER_RAW} VER) project(hsi VERSION ${VER} LANGUAGES CXX) +set(CMAKE_CXX_STANDARD 23) set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package(Qt6 6.5 REQUIRED COMPONENTS Widgets Quick QuickControls2) find_package(PkgConfig REQUIRED) -set(CMAKE_CXX_STANDARD 23) -pkg_check_modules( - deps - REQUIRED - IMPORTED_TARGET - hyprutils) +pkg_check_modules(hyprutils REQUIRED IMPORTED_TARGET hyprutils) qt_standard_project_setup(REQUIRES 6.5) -qt_add_executable(hyprsysteminfo - src/main.cpp src/util/Utils.cpp src/util/Utils.hpp -) - -qt_add_qml_module(hyprsysteminfo - URI hsi - VERSION 1.0 - QML_FILES - qml/main.qml - SOURCES - qmlSources/SystemInternals.hpp qmlSources/SystemInternals.cpp qmlSources/SystemIconProvider.hpp -) +add_subdirectory(src) qt_add_resources(hyprsysteminfo "resource" PREFIX "/" FILES resource/hyprlandlogo.svg - resource/hyprlandlogo.png -) - -target_link_libraries(hyprsysteminfo - PRIVATE Qt6::Widgets Qt6::Quick Qt6::Gui Qt6::QuickControls2 PkgConfig::deps ) include(GNUInstallDirs) diff --git a/nix/default.nix b/nix/default.nix index 355765e..f59cfa3 100644 --- a/nix/default.nix +++ b/nix/default.nix @@ -2,11 +2,11 @@ lib, stdenv, cmake, - pkg-config, - hyprutils, kdePackages, pciutils, qt6, + pkg-config, + hyprutils, version ? "0", }: let inherit (lib.sources) cleanSource cleanSourceWith; @@ -31,11 +31,11 @@ in ]; buildInputs = [ - hyprutils kdePackages.kirigami-addons qt6.qtbase qt6.qtsvg qt6.qtwayland + hyprutils ]; preFixup = '' diff --git a/qmlSources/SystemInternals.cpp b/qmlSources/SystemInternals.cpp deleted file mode 100644 index 4e7724a..0000000 --- a/qmlSources/SystemInternals.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include "SystemInternals.hpp" -#include "src/util/Utils.hpp" -#include - -void CSystemInternals::copySystemInfo() { - execAndGet(std::format("echo '{}' | wl-copy && hyprctl notify 5 5000 0 'Copied system info to the clipboard.'", hlSystemInfo.toStdString()).c_str()); -} - -void CSystemInternals::copyVersion() { - execAndGet(std::format("echo '{}' | wl-copy && hyprctl notify 5 5000 0 'Copied version info to the clipboard.'", hlSystemVersion.toStdString()).c_str()); -} \ No newline at end of file diff --git a/qmlSources/SystemInternals.hpp b/qmlSources/SystemInternals.hpp deleted file mode 100644 index 7280f0f..0000000 --- a/qmlSources/SystemInternals.hpp +++ /dev/null @@ -1,102 +0,0 @@ -#ifndef SYSTEMINTERNALS_H -#define SYSTEMINTERNALS_H - -#include -#include -#include -#include - -class CSystemInternals : public QObject { - Q_OBJECT; - - public: - explicit CSystemInternals(QObject* parent = nullptr) : QObject(parent) { - ; - } - - QString systemLogoName, systemName = "Linux", systemURL = "https://kernel.org/", systemKernel = "unknown"; - QString hyprlandVersion, hyprlandVersionLong; - - QString cpuInfo = "missing dependency: lscpu"; - std::vector gpuInfo = {"missing dependency: lspci"}; - QString ramInfo = "?"; - - QString hlSystemInfo = "[error]", hlSystemVersion = "[error]"; - - QString uptime = "unknown", DE = "Unknown", screens = "unknown", board = "", user = ""; - - Q_INVOKABLE bool hasSystemLogoName() { - return systemLogoName.size() > 0; - } - - Q_INVOKABLE QString getSystemLogoName() { - return systemLogoName; - } - - Q_INVOKABLE QString getSystemName() { - return systemName; - } - - Q_INVOKABLE QString getSystemURL() { - return systemURL; - } - - Q_INVOKABLE QString getSystemKernel() { - return systemKernel; - } - - Q_INVOKABLE bool hasHyprland() { - return hyprlandVersionLong.size() > 0; - } - - Q_INVOKABLE QString getHyprlandVersion() { - return hyprlandVersion; - } - - Q_INVOKABLE QString getHyprlandVersionLong() { - return hyprlandVersionLong; - } - - Q_INVOKABLE QString getCPUInfo() { - return cpuInfo; - } - - Q_INVOKABLE int getGPUInfoCount() { - return gpuInfo.size(); - } - - Q_INVOKABLE QString getGPUInfo(int idx) { - if (idx >= gpuInfo.size()) - return "[error]"; - return gpuInfo.at(idx); - } - - Q_INVOKABLE QString getRAMInfo() { - return ramInfo; - } - - Q_INVOKABLE QString getDE() { - return DE; - } - - Q_INVOKABLE QString getUptime() { - return uptime; - } - - Q_INVOKABLE QString getDisplays() { - return screens; - } - - Q_INVOKABLE QString getModel() { - return board; - } - - Q_INVOKABLE QString getUserAt() { - return user; - } - - Q_INVOKABLE void copySystemInfo(); - Q_INVOKABLE void copyVersion(); -}; - -#endif // SYSTEMINTERNALS_H diff --git a/resource/hyprlandlogo.png b/resource/hyprlandlogo.png deleted file mode 100755 index 14ea6a4..0000000 Binary files a/resource/hyprlandlogo.png and /dev/null differ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..064efef --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,14 @@ +qt_add_executable(hyprsysteminfo + main.cpp + util/Utils.cpp + SystemInfo.cpp + SystemIconProvider.cpp +) + +qt_add_qml_module(hyprsysteminfo + URI org.hyprland.systeminfo + VERSION 1.0 + QML_FILES main.qml +) + +target_link_libraries(hyprsysteminfo PRIVATE Qt6::Widgets Qt6::QuickControls2 PkgConfig::hyprutils) diff --git a/src/SystemIconProvider.cpp b/src/SystemIconProvider.cpp new file mode 100644 index 0000000..9900e78 --- /dev/null +++ b/src/SystemIconProvider.cpp @@ -0,0 +1,25 @@ +#include "SystemIconProvider.hpp" +#include +#include +#include + +QPixmap CSystemIconProvider::requestPixmap(const QString& id, QSize* size, const QSize& requestedSize) { + auto icon = QIcon::fromTheme(id); + + if (!requestedSize.isValid()) { + qCritical() << "Icon requests without an explicit size are not allowed."; + return QPixmap(); + } + + auto pixmap = icon.pixmap(requestedSize.width(), requestedSize.height()); + + if (pixmap.isNull()) { + qWarning() << "Could not load icon" << id; + return QPixmap(); + } + + if (size != nullptr) + *size = pixmap.size(); + + return pixmap; +} diff --git a/qmlSources/SystemIconProvider.hpp b/src/SystemIconProvider.hpp similarity index 62% rename from qmlSources/SystemIconProvider.hpp rename to src/SystemIconProvider.hpp index d435d82..bd4b3a8 100644 --- a/qmlSources/SystemIconProvider.hpp +++ b/src/SystemIconProvider.hpp @@ -1,20 +1,14 @@ -#ifndef SYSTEMICONPROVIDER_H -#define SYSTEMICONPROVIDER_H +#pragma once #include #include #include #include #include -#include class CSystemIconProvider : public QQuickImageProvider { public: CSystemIconProvider() : QQuickImageProvider(QQuickImageProvider::Pixmap) {} - QPixmap requestPixmap(const QString& id, QSize* size, const QSize& requestedSize) override { - return QIcon::fromTheme(id).pixmap({512, 512}); - } + QPixmap requestPixmap(const QString& id, QSize* size, const QSize& requestedSize) override; }; - -#endif // SYSTEMICONPROVIDER_H \ No newline at end of file diff --git a/src/SystemInfo.cpp b/src/SystemInfo.cpp new file mode 100644 index 0000000..111cf41 --- /dev/null +++ b/src/SystemInfo.cpp @@ -0,0 +1,223 @@ +#include "SystemInfo.hpp" +#include "util/Utils.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +using namespace Hyprutils::String; + +CSystemInternals::CSystemInternals(QObject* parent) : QObject(parent) { + // gather data from os-release + if (auto data = readFile("/etc/os-release")) { + CVarList lines(data.value(), 0, '\n'); + + for (auto& line : lines) { + CVarList param(line, 2, '='); + + const auto& key = param[0]; + auto value = param[1]; + + if (value.length() >= 2 && value.at(0) == '\"') + value = value.substr(1, value.length() - 2); + + if (key == "PRETTY_NAME") { + systemName = QString::fromLocal8Bit(value); + continue; + } + + if (key == "HOME_URL") { + systemURL = QString::fromLocal8Bit(value); + continue; + } + + if (key == "LOGO") { + systemLogoName = QString::fromLocal8Bit(value); + continue; + } + } + } + + // get kernel ver + utsname unamebuf; + if (uname(&unamebuf) == 0) { + systemKernel = unamebuf.release; + } + + // get hyprland info + if (getenv("HYPRLAND_INSTANCE_SIGNATURE")) { + hlSystemVersion = execAndGet("hyprctl", {"version"}); + auto DATA = hlSystemVersion.toStdString(); + + if (DATA.contains("Tag: ")) { + auto temp = DATA.substr(DATA.find("Tag: ") + 5); + temp = temp.substr(0, temp.find(",")); + hyprlandVersionLong = QString::fromLocal8Bit(temp); + hyprlandVersion = QString::fromLocal8Bit(temp.substr(0, temp.find("-"))); + } + + if (hyprlandVersionLong.length() <= 0 && DATA.contains("at commit")) { + auto temp = DATA.substr(DATA.find("at commit") + 10); + temp = temp.substr(0, temp.find(" ")); + hyprlandVersionLong = QString::fromLocal8Bit(temp.substr(0, 7)); + hyprlandVersion = QString::fromLocal8Bit(temp.substr(0, 7)); + } + + if (hyprlandVersionLong.isEmpty()) { + hyprlandVersionLong = QStringLiteral("unknown"); + hyprlandVersion = QStringLiteral("unknown"); + } + + hlSystemInfo = execAndGet("hyprctl", {"systeminfo"}); + if (!hlSystemInfo.contains("Hyprland")) + hlSystemInfo = ""; + } + + // get cpu info + { + const auto DATA = execAndGet("lscpu").toStdString(); + if (DATA.contains("odel name")) { + std::string arch, model, ghz, nproc; + + CVarList data(DATA, 0, '\n'); + for (auto& line : data) { + std::string left, right; + left = trim(line.substr(0, line.find(":"))); + right = trim(line.substr(line.find(":") + 1)); + + if (left == "Architecture") { + arch = right; + continue; + } + if (left == "Model name") { + model = right; + continue; + } + if (left == "CPU(s)") { + nproc = right; + continue; + } + if (left == "CPU max MHz") { + try { + ghz = std::format("{:.02}GHz", std::stof(right) / 1000.F); + } catch (...) { ghz = "?GHz"; } + continue; + } + } + + cpuInfo = QString::fromLocal8Bit(std::format("{} at {}x{} ({})", model, nproc, ghz, arch)); + } + } + + // get gpu info + { + auto ok = false; + const auto DATA = execAndGet("lspci", {"-vnn"}, &ok).toStdString(); + CVarList lines(DATA, 0, '\n'); + + if (ok) { + for (auto& line : lines) { + if (!line.contains("VGA")) + continue; + gpuInfo.emplace_back(QString::fromLocal8Bit(std::format("{}", line.substr(line.find(":", line.find("VGA")) + 2)))); + } + + if (gpuInfo.isEmpty()) + gpuInfo.emplaceBack(QStringLiteral("No GPUs found")); + } else + gpuInfo.emplaceBack(QStringLiteral("missing dependency: lspci")); + } + + // get ram info + { + const auto DATA = execAndGet("free").toStdString(); + if (DATA.contains("total")) { + CVarList data(DATA, 0, '\n'); + + auto ramIntToReadable = [](const std::string& datapoint) -> std::string { + try { + auto asInt = std::stoull(datapoint); + return std::format("{:.03}GB", asInt / 1000000.0); + } catch (...) { return "[error]"; } + }; + + CVarList props(data[1], 0, 's', true); + + ramInfo = QString::fromLocal8Bit(std::format("{} / {}", ramIntToReadable(props[2]), ramIntToReadable(props[1]))); + } + } + + // other, misc + if (auto current = qEnvironmentVariable("XDG_CURRENT_DESKTOP"); !current.isEmpty()) + DE = current; + + if (auto procUptime = readFile("/proc/uptime")) { + CVarList data(procUptime.value(), 0, 's', true); + + try { + int uptimeSeconds = std::round(std::stof(data[0])); + int uptimeDays = std::floor(uptimeSeconds / 3600.0 / 24.0); + int uptimeHours = std::floor((uptimeSeconds % (3600 * 24)) / 3600.0); + int uptimeMinutes = std::floor((uptimeSeconds % (3600)) / 60.0); + + auto upStr = std::format("{}{}{}", (uptimeDays > 0 ? std::format("{} days, ", uptimeDays) : ""), (uptimeHours > 0 ? std::format("{} hours, ", uptimeHours) : ""), + (uptimeMinutes > 0 ? std::format("{} minutes, ", uptimeMinutes) : "")); + + if (!upStr.empty()) + upStr = upStr.substr(0, upStr.length() - 2); + + uptime = QString::fromLocal8Bit(upStr); + } catch (...) { ; } + } + + { + std::string screens; + for (auto* s : QGuiApplication::screens()) { + auto ratio = s->devicePixelRatio(); + screens += std::format("{} ({}x{}), ", s->name().toStdString(), s->geometry().width() * ratio, s->geometry().height() * ratio); + } + + if (!screens.empty()) + screens = screens.substr(0, screens.length() - 2); + + this->screens = QString::fromLocal8Bit(screens); + } + + if (auto* username = getlogin()) { + std::array hostname; + if (gethostname(hostname.data(), hostname.size()) == 0) + user = QString::fromLocal8Bit(std::format("{}@{}", username, hostname.data())); + } + + { + if (auto productName = readFile("/sys/devices/virtual/dmi/id/product_name")) + board = QString::fromLocal8Bit(trim(productName.value())); + else if (auto boardName = readFile("/sys/devices/virtual/dmi/id/board_name")) + board = QString::fromLocal8Bit(trim(boardName.value())); + } +} + +void CSystemInternals::copySystemInfo() { + QGuiApplication::clipboard()->setText(hlSystemInfo); + execAndGet("hyprctl", {"notify", "5", "5000", "0", "Copied system info to the clipboard."}); +} + +void CSystemInternals::copyVersion() { + QGuiApplication::clipboard()->setText(hlSystemVersion); + execAndGet("hyprctl", {"notify", "5", "5000", "0", "Copied version info to the clipboard."}); +} diff --git a/src/SystemInfo.hpp b/src/SystemInfo.hpp new file mode 100644 index 0000000..3c91a39 --- /dev/null +++ b/src/SystemInfo.hpp @@ -0,0 +1,46 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +class CSystemInternals : public QObject { + Q_OBJECT; + QML_NAMED_ELEMENT(SystemInfo); + QML_SINGLETON; + Q_PROPERTY(QString systemLogoName MEMBER systemLogoName CONSTANT); + Q_PROPERTY(QString systemName MEMBER systemName CONSTANT); + Q_PROPERTY(QString systemUrl MEMBER systemURL CONSTANT); + Q_PROPERTY(QString systemKernel MEMBER systemKernel CONSTANT); + Q_PROPERTY(QString hyprlandVersion MEMBER hyprlandVersion CONSTANT); + Q_PROPERTY(QString hyprlandVersionLong MEMBER hyprlandVersionLong CONSTANT); + Q_PROPERTY(QString cpuInfo MEMBER cpuInfo CONSTANT); + Q_PROPERTY(QVector gpuInfo MEMBER gpuInfo CONSTANT); + Q_PROPERTY(QString ramInfo MEMBER ramInfo CONSTANT); + Q_PROPERTY(QString uptime MEMBER uptime CONSTANT); + Q_PROPERTY(QString de MEMBER DE CONSTANT); + Q_PROPERTY(QString screens MEMBER screens CONSTANT); + Q_PROPERTY(QString model MEMBER board CONSTANT); + Q_PROPERTY(QString user MEMBER user CONSTANT); + + public: + explicit CSystemInternals(QObject* parent = nullptr); + + QString systemLogoName, systemName = "Linux", systemURL = "https://kernel.org/", systemKernel = "unknown"; + QString hyprlandVersion, hyprlandVersionLong; + + QString cpuInfo = "missing dependency: lscpu"; + QVector gpuInfo; + QString ramInfo = "?"; + + QString hlSystemInfo = "[error]", hlSystemVersion = "[error]"; + + QString uptime = "unknown", DE = "Unknown", screens = "unknown", board = "", user = ""; + + Q_INVOKABLE void copySystemInfo(); + Q_INVOKABLE void copyVersion(); +}; diff --git a/src/main.cpp b/src/main.cpp index b0bee14..21b0392 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,209 +1,8 @@ -#include "qmlSources/SystemIconProvider.hpp" -#include "qmlSources/SystemInternals.hpp" -#include -#include -#include -#include -#include -#include -#include -#include "util/Utils.hpp" - -#include -#include +#include "SystemIconProvider.hpp" +#include +#include +#include #include -using namespace Hyprutils::String; - -static std::string readFile(const std::string& filename) { - try { - std::ifstream ifs(filename); - if (ifs.good()) { - std::string data(std::istreambuf_iterator{ifs}, {}); - ifs.close(); - return trim(data); - } - } catch (...) { return "[error]"; } - return "[error]"; -} - -static void getSystemInfo(CSystemInternals* hsi, QGuiApplication* app) { - - // gather data from os-release - std::ifstream osInfo("/etc/os-release"); - if (osInfo.good()) { - std::string data(std::istreambuf_iterator{osInfo}, {}); - - osInfo.close(); - - CVarList lines(data, 0, '\n'); - - for (auto& line : lines) { - CVarList param(line, 2, '='); - - static auto stripName = [](const std::string& in) -> std::string { return in.length() > 0 && in.at(0) == '\"' ? in.substr(1, in.length() - 2) : in; }; - - if (param[0] == "PRETTY_NAME") { - hsi->systemName = stripName(param[1]).c_str(); - continue; - } - - if (param[0] == "HOME_URL") { - hsi->systemURL = stripName(param[1]).c_str(); - continue; - } - - if (param[0] == "LOGO") { - hsi->systemLogoName = stripName(param[1]).c_str(); - continue; - } - } - } - - // get kernel ver - hsi->systemKernel = trim(execAndGet("uname -r")).c_str(); - - // get hyprland info - if (getenv("HYPRLAND_INSTANCE_SIGNATURE")) { - const auto DATA = execAndGet("hyprctl version"); - hsi->hlSystemVersion = DATA.c_str(); - - if (DATA.contains("Tag:")) { - auto temp = DATA.substr(DATA.find("Tag:") + 5); - temp = temp.substr(0, temp.find(",")); - hsi->hyprlandVersionLong = temp.c_str(); - hsi->hyprlandVersion = temp.substr(0, temp.find("-")).c_str(); - } - - if (hsi->hyprlandVersionLong.length() <= 0 && DATA.contains("at commit")) { - auto temp = DATA.substr(DATA.find("at commit") + 10); - temp = temp.substr(0, temp.find(" ")); - hsi->hyprlandVersionLong = temp.substr(0, 7).c_str(); - hsi->hyprlandVersion = temp.substr(0, 7).c_str(); - } - - if (hsi->hyprlandVersionLong.length() <= 0) { - hsi->hyprlandVersionLong = "unknown"; - hsi->hyprlandVersion = "unknown"; - } - - const auto DATA2 = execAndGet("hyprctl systeminfo"); - if (DATA2.contains("Hyprland")) - hsi->hlSystemInfo = DATA2.c_str(); - } - - // get cpu info - { - const auto DATA = execAndGet("lscpu"); - if (DATA.contains("odel name")) { - std::string arch, model, ghz, nproc; - - CVarList data(DATA, 0, '\n'); - for (auto& line : data) { - std::string left, right; - left = trim(line.substr(0, line.find(":"))); - right = trim(line.substr(line.find(":") + 1)); - - if (left == "Architecture") { - arch = right; - continue; - } - if (left == "Model name") { - model = right; - continue; - } - if (left == "CPU(s)") { - nproc = right; - continue; - } - if (left == "CPU max MHz") { - try { - ghz = std::format("{:.02}GHz", std::stof(right) / 1000.F); - } catch (...) { ghz = "?GHz"; } - continue; - } - } - - hsi->cpuInfo = std::format("{} at {}x{} ({})", model, nproc, ghz, arch).c_str(); - } - } - - // get gpu info - { - const auto DATA = execAndGet("lspci -vnn | grep VGA"); - if (DATA.contains("VGA")) { - CVarList data(DATA, 0, '\n'); - hsi->gpuInfo.clear(); - for (auto& line : data) { - if (!line.contains("VGA")) - continue; - hsi->gpuInfo.emplace_back(std::format("{}", line.substr(line.find(":", line.find("VGA")) + 2)).c_str()); - } - } else { - hsi->gpuInfo = {"No GPUs found"}; - } - } - - // get ram info - { - const auto DATA = execAndGet("free"); - if (DATA.contains("total")) { - CVarList data(DATA, 0, '\n'); - - auto ramIntToReadable = [](const std::string& datapoint) -> std::string { - try { - auto asInt = std::stoull(datapoint); - return std::format("{:.03}GB", asInt / 1000000.0); - } catch (...) { return "[error]"; } - }; - - CVarList props(data[1], 0, 's', true); - - hsi->ramInfo = std::format("{} / {}", ramIntToReadable(props[2]), ramIntToReadable(props[1])).c_str(); - } - } - - // other, misc - if (const auto DE = getenv("XDG_CURRENT_DESKTOP"); DE) - hsi->DE = DE; - - if (const auto UPTIME = readFile("/proc/uptime"); UPTIME != "[error]") { - CVarList data(UPTIME, 0, 's', true); - try { - int uptimeSeconds = std::round(std::stof(data[0])); - int uptimeDays = std::floor(uptimeSeconds / 3600.0 / 24.0); - int uptimeHours = std::floor((uptimeSeconds % (3600 * 24)) / 3600.0); - int uptimeMinutes = std::floor((uptimeSeconds % (3600)) / 60.0); - - auto upStr = std::format("{}{}{}", (uptimeDays > 0 ? std::format("{} days, ", uptimeDays) : ""), (uptimeHours > 0 ? std::format("{} hours, ", uptimeHours) : ""), - (uptimeMinutes > 0 ? std::format("{} minutes, ", uptimeMinutes) : "")); - - if (!upStr.empty()) - upStr = upStr.substr(0, upStr.length() - 2); - - hsi->uptime = upStr.c_str(); - } catch (...) { ; } - } - - { - std::string screens; - - for (auto& s : app->screens()) { - screens += std::format("{} ({}x{}), ", s->name().toStdString(), s->geometry().width(), s->geometry().height()); - } - - if (!screens.empty()) - screens = screens.substr(0, screens.length() - 2); - - hsi->screens = screens.c_str(); - } - - hsi->user = std::format("{}@{}", trim(execAndGet("whoami")), readFile("/etc/hostname")).c_str(); - - if (const auto PRODUCT = readFile("/sys/devices/virtual/dmi/id/product_name"); PRODUCT != "[error]") - hsi->board = PRODUCT.c_str(); - else if (const auto BOARD = readFile("/sys/devices/virtual/dmi/id/board_name"); BOARD != "[error]") - hsi->board = BOARD.c_str(); -} int main(int argc, char* argv[]) { QApplication app(argc, argv); @@ -213,15 +12,10 @@ int main(int argc, char* argv[]) { if (qEnvironmentVariableIsEmpty("QT_QUICK_CONTROLS_STYLE")) QQuickStyle::setStyle("org.kde.desktop"); - auto systemInternals = new CSystemInternals; - - getSystemInfo(systemInternals, &app); - QQmlApplicationEngine engine; - engine.rootContext()->setContextProperty("hsi", systemInternals); engine.addImageProvider("systemIcons", new CSystemIconProvider); QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, &app, []() { QCoreApplication::exit(-1); }, Qt::QueuedConnection); - engine.load(QUrl{u"qrc:/qt/qml/hsi/qml/main.qml"_qs}); + engine.load("qrc:/qt/qml/org/hyprland/systeminfo/main.qml"); return app.exec(); } diff --git a/qml/main.qml b/src/main.qml similarity index 78% rename from qml/main.qml rename to src/main.qml index 379b968..3a11547 100644 --- a/qml/main.qml +++ b/src/main.qml @@ -3,6 +3,7 @@ pragma ComponentBehavior: Bound import QtQuick import QtQuick.Controls import QtQuick.Layouts +import org.hyprland.systeminfo ApplicationWindow { id: window @@ -58,8 +59,8 @@ ApplicationWindow { spacing: fontMetrics.height Image { - visible: hsi.hasSystemLogoName() - source: "image://systemIcons/" + hsi.getSystemLogoName() + visible: SystemInfo.systemLogoName != "" + source: "image://systemIcons/" + SystemInfo.systemLogoName sourceSize.width: firstPanelHeight sourceSize.height: firstPanelHeight Layout.preferredWidth: firstPanelHeight @@ -76,17 +77,17 @@ ApplicationWindow { Layout.alignment: Qt.AlignVCenter Label { - text: hsi.getSystemName() + text: SystemInfo.systemName Layout.alignment: Qt.AlignHCenter } Label { - text: hsi.getSystemURL() + text: SystemInfo.systemUrl Layout.alignment: Qt.AlignHCenter } Label { - text: hsi.getSystemKernel() + text: SystemInfo.systemKernel Layout.alignment: Qt.AlignHCenter } } @@ -98,7 +99,7 @@ ApplicationWindow { RowLayout { id: hyprlandInfo - visible: hsi.hasHyprland() + visible: SystemInfo.hyprlandVersionLong != "" spacing: fontMetrics.height Image { @@ -123,13 +124,13 @@ ApplicationWindow { } Label { - text: hsi.getHyprlandVersion() + text: SystemInfo.hyprlandVersion Layout.alignment: Qt.AlignHCenter } Label { - visible: hsi.getHyprlandVersion() != hsi.getHyprlandVersionLong() - text: hsi.getHyprlandVersionLong() + visible: SystemInfo.hyprlandVersion != text + text: SystemInfo.hyprlandVersionLong Layout.alignment: Qt.AlignHCenter } } @@ -151,23 +152,23 @@ ApplicationWindow { wrapMode: Text.NoWrap } - DetailsLabel { text: "User: " + hsi.getUserAt(); visible: hsi.getUserAt() != "" } - DetailsLabel { text: "Model: " + hsi.getModel(); visible: hsi.getModel() != "" } - DetailsLabel { text: "CPU: " + hsi.getCPUInfo() } + DetailsLabel { text: "User: " + SystemInfo.user; visible: text != "" } + DetailsLabel { text: "Model: " + SystemInfo.model; visible: text != "" } + DetailsLabel { text: "CPU: " + SystemInfo.cpuInfo } Repeater { - model: hsi.getGPUInfoCount() + model: SystemInfo.gpuInfo DetailsLabel { - required property int index - text: "GPU: " + hsi.getGPUInfo(index) + required property string modelData + text: "GPU: " + modelData } } - DetailsLabel { text: "Memory: " + hsi.getRAMInfo() } - DetailsLabel { text: "DE: " + hsi.getDE() } - DetailsLabel { text: "Uptime: " + hsi.getUptime() } - DetailsLabel { text: "Displays: " + hsi.getDisplays() } + DetailsLabel { text: "Memory: " + SystemInfo.ramInfo } + DetailsLabel { text: "DE: " + SystemInfo.de } + DetailsLabel { text: "Uptime: " + SystemInfo.uptime } + DetailsLabel { text: "Displays: " + SystemInfo.screens } } Item { Layout.fillHeight: true } @@ -175,19 +176,19 @@ ApplicationWindow { HSeparator {} RowLayout { - visible: hsi.hasHyprland() + visible: SystemInfo.hyprlandVersionLong != "" spacing: 6 Layout.leftMargin: 20 Layout.rightMargin: 20 Button { text: "Copy Hyprland System Info" - onClicked: hsi.copySystemInfo(); + onClicked: SystemInfo.copySystemInfo(); } Button { text: "Copy Hyprland Version" - onClicked: hsi.copyVersion(); + onClicked: SystemInfo.copyVersion(); } } } diff --git a/src/util/Utils.cpp b/src/util/Utils.cpp index 60cb70f..22510b6 100644 --- a/src/util/Utils.cpp +++ b/src/util/Utils.cpp @@ -1,18 +1,46 @@ #include "Utils.hpp" -#include -#include -#include +#include +#include +#include +#include +#include + +QString execAndGet(const QString& program, const QStringList& arguments, bool* ok) { + QProcess process; + process.setProcessChannelMode(QProcess::SeparateChannels); + process.start(program, arguments, QIODevice::ReadOnly); + + if (!process.waitForStarted(-1)) { + qCritical() << "Failed to start process" << program << arguments; + if (ok) + *ok = false; -std::string execAndGet(const char* cmd) { - std::array buffer; - std::string result; - const std::unique_ptr pipe(popen(cmd, "r"), pclose); - if (!pipe) return ""; - - while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) { - result += buffer.data(); } - return result; -} \ No newline at end of file + + if (!process.waitForFinished(-1)) { + qCritical() << "Failed to run process" << program << arguments; + if (ok) + *ok = false; + + return ""; + } + + if (ok) + *ok = true; + return process.readAll(); +} + +std::optional readFile(const std::string& filename) { + try { + std::ifstream ifs(filename); + if (ifs.good()) { + std::string data(std::istreambuf_iterator{ifs}, {}); + ifs.close(); + return data; + } + } catch (...) {} + + return {}; +} diff --git a/src/util/Utils.hpp b/src/util/Utils.hpp index 9bb0827..8b268c2 100644 --- a/src/util/Utils.hpp +++ b/src/util/Utils.hpp @@ -1,5 +1,8 @@ #pragma once -#include +#include +#include +#include -std::string execAndGet(const char* cmd); \ No newline at end of file +QString execAndGet(const QString& program, const QStringList& arguments = {}, bool* ok = nullptr); +std::optional readFile(const std::string& filename);