weh
This commit is contained in:
parent
4121e724ed
commit
02d24f4fd1
4 changed files with 116 additions and 245 deletions
191
src/os/linux.cpp
191
src/os/linux.cpp
|
@ -1,11 +1,9 @@
|
|||
#ifdef __linux__
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include <cstring>
|
||||
#include <filesystem>
|
||||
#include <fmt/format.h>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <sdbus-c++/sdbus-c++.h>
|
||||
#include <vector>
|
||||
|
||||
|
@ -13,58 +11,54 @@
|
|||
|
||||
enum SessionType { Wayland, X11, TTY, Unknown };
|
||||
|
||||
fn ParseLineAsNumber(const string& input) -> u64 {
|
||||
// Find the first number
|
||||
string::size_type start = 0;
|
||||
fn ParseLineAsNumber(const std::string& input) -> u64 {
|
||||
usize start = input.find_first_of("0123456789");
|
||||
|
||||
// Skip leading non-numbers
|
||||
while (!isdigit(input[++start]));
|
||||
if (start == std::string::npos)
|
||||
throw std::runtime_error("No number found in input");
|
||||
|
||||
// Start searching from the start of the number
|
||||
string::size_type end = start;
|
||||
usize end = input.find_first_not_of("0123456789", start);
|
||||
|
||||
// Increment to the end of the number
|
||||
while (isdigit(input[++end]));
|
||||
|
||||
// Return the substring containing the number
|
||||
return std::stoul(input.substr(start, end - start));
|
||||
return std::stoull(input.substr(start, end - start));
|
||||
}
|
||||
|
||||
fn MeminfoParse(std::ifstream input) -> u64 {
|
||||
string line;
|
||||
fn MeminfoParse(const std::filesystem::path& filepath) -> u64 {
|
||||
std::ifstream input(filepath);
|
||||
|
||||
// Skip every line before the one that starts with "MemTotal"
|
||||
while (std::getline(input, line) && !line.starts_with("MemTotal"));
|
||||
if (!input.is_open())
|
||||
throw std::runtime_error("Failed to open " + filepath.string());
|
||||
|
||||
return ParseLineAsNumber(line);
|
||||
std::string line;
|
||||
|
||||
while (std::getline(input, line))
|
||||
if (line.starts_with("MemTotal"))
|
||||
return ParseLineAsNumber(line);
|
||||
|
||||
throw std::runtime_error("MemTotal line not found in " + filepath.string());
|
||||
}
|
||||
|
||||
fn GetMemInfo() -> u64 { return MeminfoParse(std::ifstream("/proc/meminfo")) * 1024; }
|
||||
fn GetMemInfo() -> u64 { return MeminfoParse("/proc/meminfo") * 1024; }
|
||||
|
||||
fn GetOSVersion() -> string {
|
||||
fn GetOSVersion() -> std::string {
|
||||
std::ifstream file("/etc/os-release");
|
||||
|
||||
if (!file.is_open()) {
|
||||
std::cerr << "Failed to open /etc/os-release" << std::endl;
|
||||
return ""; // Return empty string indicating failure
|
||||
}
|
||||
if (!file.is_open())
|
||||
throw std::runtime_error("Failed to open /etc/os-release");
|
||||
|
||||
string line;
|
||||
const string prefix = "PRETTY_NAME=";
|
||||
|
||||
while (std::getline(file, line)) {
|
||||
if (line.find(prefix) == 0) {
|
||||
while (std::getline(file, line))
|
||||
if (line.starts_with(prefix)) {
|
||||
string prettyName = line.substr(prefix.size());
|
||||
|
||||
// Remove surrounding quotes if present
|
||||
if (!prettyName.empty() && prettyName.front() == '"' && prettyName.back() == '"')
|
||||
prettyName = prettyName.substr(1, prettyName.size() - 2);
|
||||
return prettyName.substr(1, prettyName.size() - 2);
|
||||
|
||||
return prettyName;
|
||||
}
|
||||
}
|
||||
|
||||
return ""; // Return empty string if PRETTY_NAME= line not found
|
||||
throw std::runtime_error("PRETTY_NAME line not found in /etc/os-release");
|
||||
}
|
||||
|
||||
fn GetMprisPlayers(sdbus::IConnection& connection) -> std::vector<string> {
|
||||
|
@ -138,137 +132,4 @@ fn GetNowPlaying() -> string {
|
|||
return "";
|
||||
}
|
||||
|
||||
fn GetDesktopEnvironment() -> string {
|
||||
const char* xdgCurrentDesktop = std::getenv("XDG_CURRENT_DESKTOP");
|
||||
|
||||
if (xdgCurrentDesktop)
|
||||
return xdgCurrentDesktop;
|
||||
|
||||
return std::getenv("DESKTOP_SESSION");
|
||||
}
|
||||
|
||||
fn GetSessionType() -> SessionType {
|
||||
string xdgSessionType = std::getenv("XDG_SESSION_TYPE");
|
||||
|
||||
if (xdgSessionType == "wayland")
|
||||
return Wayland;
|
||||
if (xdgSessionType == "x11")
|
||||
return X11;
|
||||
if (xdgSessionType == "tty")
|
||||
return TTY;
|
||||
return Unknown;
|
||||
}
|
||||
|
||||
fn Exec(const char* cmd) -> string {
|
||||
std::array<char, 128> buffer;
|
||||
std::string result;
|
||||
std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd, "r"), pclose);
|
||||
|
||||
if (!pipe) {
|
||||
throw std::runtime_error("popen() failed!");
|
||||
}
|
||||
|
||||
while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) { result += buffer.data(); }
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
fn GetWindowManager() -> string {
|
||||
string xdgSessionType = std::getenv("XDG_SESSION_TYPE");
|
||||
|
||||
if (xdgSessionType == "wayland") {
|
||||
// TODO implement wayland window manager
|
||||
}
|
||||
|
||||
if (xdgSessionType == "x11") {
|
||||
Display* display = XOpenDisplay(nullptr);
|
||||
|
||||
Atom wmCheckAtom = XInternAtom(display, "_NET_SUPPORTING_WM_CHECK", True);
|
||||
if (wmCheckAtom == None) {
|
||||
return "Unknown (no _NET_SUPPORTING_WM_CHECK)";
|
||||
}
|
||||
|
||||
Window root = DefaultRootWindow(display);
|
||||
Atom actualType = 0;
|
||||
int actualFormat = 0;
|
||||
unsigned long itemCount = 0, bytesAfter = 0;
|
||||
unsigned char* data = nullptr;
|
||||
|
||||
int status = XGetWindowProperty(
|
||||
display,
|
||||
root,
|
||||
wmCheckAtom,
|
||||
0,
|
||||
1,
|
||||
False,
|
||||
XA_WINDOW,
|
||||
&actualType,
|
||||
&actualFormat,
|
||||
&itemCount,
|
||||
&bytesAfter,
|
||||
&data
|
||||
);
|
||||
if (status != Success || !data) {
|
||||
return "Unknown (failed to get _NET_SUPPORTING_WM_CHECK)";
|
||||
}
|
||||
|
||||
Window wmWindow = *(Window*)(data);
|
||||
XFree(data);
|
||||
|
||||
status = XGetWindowProperty(
|
||||
display,
|
||||
wmWindow,
|
||||
wmCheckAtom,
|
||||
0,
|
||||
1,
|
||||
False,
|
||||
XA_WINDOW,
|
||||
&actualType,
|
||||
&actualFormat,
|
||||
&itemCount,
|
||||
&bytesAfter,
|
||||
&data
|
||||
);
|
||||
if (status != Success || !data) {
|
||||
return "Unknown (failed to get supporting window)";
|
||||
}
|
||||
|
||||
wmWindow = *(reinterpret_cast<Window*>(data));
|
||||
XFree(data);
|
||||
|
||||
Atom wmNameAtom = XInternAtom(display, "_NET_WM_NAME", True);
|
||||
if (wmNameAtom == None) {
|
||||
return "Unknown (no _NET_WM_NAME)";
|
||||
}
|
||||
|
||||
status = XGetWindowProperty(
|
||||
display,
|
||||
wmWindow,
|
||||
wmNameAtom,
|
||||
0,
|
||||
(~0L),
|
||||
False,
|
||||
AnyPropertyType,
|
||||
&actualType,
|
||||
&actualFormat,
|
||||
&itemCount,
|
||||
&bytesAfter,
|
||||
&data
|
||||
);
|
||||
if (status != Success || !data) {
|
||||
return "Unknown (failed to get _NET_WM_NAME)";
|
||||
}
|
||||
|
||||
std::string wmName(reinterpret_cast<char*>(data));
|
||||
XFree(data);
|
||||
|
||||
return wmName;
|
||||
}
|
||||
|
||||
if (xdgSessionType == "tty")
|
||||
return "TTY";
|
||||
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue