1ms slower on average 💔 sad!

This commit is contained in:
Mars 2025-01-29 02:03:00 -05:00
parent 39a6a5cff0
commit ff3d9bcce8
Signed by: pupbrained
GPG key ID: 0FF5B8826803F895
6 changed files with 166 additions and 88 deletions

View file

@ -9,7 +9,7 @@ AllowShortLoopsOnASingleLine: true
BasedOnStyle: Chromium
BinPackArguments: false
BinPackParameters: false
ColumnLimit: 100
ColumnLimit: 120
ConstructorInitializerIndentWidth: 2
ContinuationIndentWidth: 2
Cpp11BracedListStyle: false

View file

@ -2,28 +2,27 @@
#include <filesystem>
#include <fmt/core.h>
#include <stdexcept>
#include <string>
#include "config.h"
using rfl::Result;
namespace fs = std::filesystem;
inline fn GetConfigPath() -> std::string {
inline fn GetConfigPath() -> fs::path {
#ifdef _WIN32
const char* localAppData = std::getenv("LOCALAPPDATA");
if (!localAppData)
throw std::runtime_error("Environment variable LOCALAPPDATA is not set");
return localAppData;
return fs::path(localAppData);
#else
const char* home = std::getenv("HOME");
if (!home)
throw std::runtime_error("Environment variable HOME is not set");
return std::string(home) + "/.config";
return fs::path(home) / ".config";
#endif
}
@ -34,7 +33,8 @@ fn Config::getInstance() -> Config {
const Result<Config> result = rfl::toml::load<Config>(configPath.string());
if (!result) {
fmt::println(stderr, "Failed to load config file: {}", result.error()->what());
ERROR_LOG("Failed to load config file: {}", result.error()->what());
exit(1);
}

View file

@ -1,4 +1,4 @@
#pragma once
#include <rfl.hpp>
#include <rfl/Field.hpp>
@ -19,6 +19,7 @@ struct NowPlaying {
struct Weather {
bool enabled = false;
bool show_town_name = false;
Location location;
string api_key;

View file

@ -43,11 +43,11 @@ namespace {
date.erase(date.begin());
// Append appropriate suffix for the date
if (date == "1" || date == "21" || date == "31")
if (date.ends_with("1") && date != "11")
date += "st";
else if (date == "2" || date == "22")
else if (date.ends_with("2") && date != "12")
date += "nd";
else if (date == "3" || date == "23")
else if (date.ends_with("3") && date != "13")
date += "rd";
else
date += "th";
@ -59,84 +59,125 @@ namespace {
fn CreateColorCircles() -> Element {
Elements circles;
for (int i = 0; i < 16; ++i) {
circles.push_back(text("") | bold | color(Color::Palette256(i)));
circles.push_back(text(" "));
}
for (int i = 0; i < 16; ++i)
circles.push_back(hbox({
text("") | bold | color(Color::Palette256(i)),
text(" "),
}));
return hbox(circles);
}
fn SystemInfoBox(const Config& config) -> Element {
// Fetch data
const std::string& name = config.general.get().name.get();
std::string date = GetDate();
const std::string& date = GetDate();
const std::string& host = GetHost();
const std::string& kernelVersion = GetKernelVersion();
const std::string& osVersion = GetOSVersion();
u64 memInfo = GetMemInfo();
std::string osVersion = GetOSVersion();
Weather weather = config.weather.get();
bool nowPlayingEnabled = config.now_playing.get().enabled;
std::string nowPlaying = nowPlayingEnabled ? GetNowPlaying() : "";
const std::string& nowPlaying = nowPlayingEnabled ? GetNowPlaying() : "";
// Icon constants (using Nerd Font v3)
constexpr const char* calendarIcon = "";
constexpr const char* memoryIcon = "";
constexpr const char* hostIcon = " 󰌢 ";
constexpr const char* kernelIcon = "";
constexpr const char* osIcon = "";
constexpr const char* memoryIcon = "";
constexpr const char* weatherIcon = " 󰖐 ";
constexpr const char* musicIcon = "";
const Color::Palette16 labelColor = Color::Yellow;
const Color::Palette16 valueColor = Color::White;
const Color::Palette16 borderColor = Color::GrayLight;
const Color iconColor = Color::RGB(100, 200, 255); // Bright cyan
const Color::Palette16 iconColor = Color::Cyan;
Elements content;
content.push_back(text("  Hello " + name + "! ") | bold | color(Color::Cyan));
content.push_back(separator() | color(borderColor));
content.push_back(hbox({
text("") | color(iconColor), // Palette icon
CreateColorCircles(),
}));
content.push_back(separator() | color(borderColor));
// Helper function for aligned rows
auto createRow =
[&](const std::string& emoji, const std::string& label, const std::string& value) {
return hbox({ text(emoji),
auto createRow = [&](const std::string& icon, const std::string& label, const std::string& value) {
return hbox({
text(icon) | color(iconColor),
text(label) | color(labelColor),
text(" "),
filler(),
text(value) | color(valueColor),
text(" ") });
text(" "),
});
};
// System info rows
content.push_back(createRow(calendarIcon, "Date", date));
content.push_back(createRow(memoryIcon, "RAM ", fmt::format("{:.2f}", BytesToGiB { memInfo })));
content.push_back(createRow(osIcon, "OS ", osVersion));
// Weather row
if (weather.enabled) {
auto weatherInfo = weather.getWeatherInfo();
content.push_back(separator() | color(borderColor));
content.push_back(hbox(
{ text(weatherIcon),
WeatherOutput weatherInfo = weather.getWeatherInfo();
if (weather.show_town_name)
content.push_back(hbox({
text(weatherIcon) | color(iconColor),
text("Weather") | color(labelColor),
filler(),
hbox({ text(fmt::format("{}°F ", std::lround(weatherInfo.main.temp))) | color(Color::Red),
hbox({
text(fmt::format("{}°F ", std::lround(weatherInfo.main.temp))),
text("in "),
text(weatherInfo.name),
text(" ") }) |
color(valueColor) }
));
text(" "),
}) |
color(valueColor),
}));
else
content.push_back(hbox({
text(weatherIcon) | color(iconColor),
text("Weather") | color(labelColor),
filler(),
hbox({
text(fmt::format("{}°F, {}", std::lround(weatherInfo.main.temp), weatherInfo.weather[0].description)),
text(" "),
}) |
color(valueColor),
}));
}
content.push_back(separator() | color(borderColor));
if (!host.empty())
content.push_back(createRow(hostIcon, "Host", host));
if (!kernelVersion.empty())
content.push_back(createRow(kernelIcon, "Kernel", kernelVersion));
if (!osVersion.empty())
content.push_back(createRow(osIcon, "OS", osVersion));
if (memInfo > 0)
content.push_back(createRow(memoryIcon, "RAM", fmt::format("{:.2f}", BytesToGiB { memInfo })));
// Now Playing row
if (nowPlayingEnabled && !nowPlaying.empty()) {
content.push_back(separator() | color(borderColor));
content.push_back(hbox({ text(musicIcon),
text("Now Playing ") | color(labelColor),
content.push_back(hbox({
text(musicIcon) | color(iconColor),
text("Music") | color(labelColor),
text(" "),
filler(),
text(nowPlaying),
text(" ") | color(Color::Magenta) }));
text(nowPlaying.length() > 30 ? nowPlaying.substr(0, 30) + "..." : nowPlaying) | color(Color::Magenta),
text(" "),
}));
}
// Color circles section
content.push_back(filler());
content.push_back(separator() | color(borderColor));
content.push_back(hbox({ text("") | color(iconColor), // Palette icon
CreateColorCircles() }));
return vbox(content) | borderRounded | color(Color::White);
}
}

View file

@ -1,32 +1,39 @@
#ifdef __linux__
#include <cstring>
#include <filesystem>
#include <fmt/format.h>
#include <fstream>
#include <sdbus-c++/sdbus-c++.h>
#include <sys/utsname.h>
#include <vector>
#include "os.h"
#include "src/util/macros.h"
enum SessionType : u8 { Wayland, X11, TTY, Unknown };
fn ParseLineAsNumber(const std::string& input) -> u64 {
usize start = input.find_first_of("0123456789");
if (start == std::string::npos)
throw std::runtime_error("No number found in input");
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(const std::filesystem::path& filepath) -> u64 {
std::ifstream input(filepath);
fn MeminfoParse() -> u64 {
constexpr const char* path = "/proc/meminfo";
if (!input.is_open())
throw std::runtime_error("Failed to open " + filepath.string());
std::ifstream input(path);
if (!input.is_open()) {
ERROR_LOG("Failed to open {}", path);
return 0;
}
std::string line;
@ -34,16 +41,21 @@ fn MeminfoParse(const std::filesystem::path& filepath) -> u64 {
if (line.starts_with("MemTotal"))
return ParseLineAsNumber(line);
throw std::runtime_error("MemTotal line not found in " + filepath.string());
ERROR_LOG("MemTotal line not found in {}", path);
return 0;
}
fn GetMemInfo() -> u64 { return MeminfoParse("/proc/meminfo") * 1024; }
fn GetMemInfo() -> u64 { return MeminfoParse() * 1024; }
fn GetOSVersion() -> std::string {
std::ifstream file("/etc/os-release");
constexpr const char* path = "/etc/os-release";
if (!file.is_open())
throw std::runtime_error("Failed to open /etc/os-release");
std::ifstream file(path);
if (!file.is_open()) {
ERROR_LOG("Failed to open {}", path);
return "";
}
string line;
const string prefix = "PRETTY_NAME=";
@ -58,7 +70,8 @@ fn GetOSVersion() -> std::string {
return prettyName;
}
throw std::runtime_error("PRETTY_NAME line not found in /etc/os-release");
ERROR_LOG("PRETTY_NAME line not found in {}", path);
return "";
}
fn GetMprisPlayers(sdbus::IConnection& connection) -> std::vector<string> {
@ -66,8 +79,7 @@ fn GetMprisPlayers(sdbus::IConnection& connection) -> std::vector<string> {
const sdbus::ObjectPath dbusObjectPath = sdbus::ObjectPath("/org/freedesktop/DBus");
const char* dbusMethodListNames = "ListNames";
const std::unique_ptr<sdbus::IProxy> dbusProxy =
createProxy(connection, dbusInterface, dbusObjectPath);
const std::unique_ptr<sdbus::IProxy> dbusProxy = createProxy(connection, dbusInterface, dbusObjectPath);
std::vector<string> names;
@ -76,8 +88,7 @@ fn GetMprisPlayers(sdbus::IConnection& connection) -> std::vector<string> {
std::vector<string> mprisPlayers;
for (const std::basic_string<char>& name : names)
if (const char* mprisInterfaceName = "org.mpris.MediaPlayer2";
name.find(mprisInterfaceName) != std::string::npos)
if (const char* mprisInterfaceName = "org.mpris.MediaPlayer2"; name.find(mprisInterfaceName) != std::string::npos)
mprisPlayers.push_back(name);
return mprisPlayers;
@ -92,30 +103,32 @@ fn GetActivePlayer(const std::vector<string>& mprisPlayers) -> string {
fn GetNowPlaying() -> string {
try {
const char *playerObjectPath = "/org/mpris/MediaPlayer2",
*playerInterfaceName = "org.mpris.MediaPlayer2.Player";
const char *playerObjectPath = "/org/mpris/MediaPlayer2", *playerInterfaceName = "org.mpris.MediaPlayer2.Player";
std::unique_ptr<sdbus::IConnection> connection = sdbus::createSessionBusConnection();
std::vector<string> mprisPlayers = GetMprisPlayers(*connection);
if (mprisPlayers.empty())
if (mprisPlayers.empty()) {
DEBUG_LOG("No MPRIS players found");
return "";
}
string activePlayer = GetActivePlayer(mprisPlayers);
if (activePlayer.empty())
if (activePlayer.empty()) {
DEBUG_LOG("No active player found");
return "";
}
auto playerProxy = sdbus::createProxy(
*connection, sdbus::ServiceName(activePlayer), sdbus::ObjectPath(playerObjectPath)
);
std::unique_ptr<sdbus::IProxy> playerProxy =
sdbus::createProxy(*connection, sdbus::ServiceName(activePlayer), sdbus::ObjectPath(playerObjectPath));
sdbus::Variant metadataVariant =
playerProxy->getProperty("Metadata").onInterface(playerInterfaceName);
sdbus::Variant metadataVariant = playerProxy->getProperty("Metadata").onInterface(playerInterfaceName);
if (metadataVariant.containsValueOfType<std::map<std::string, sdbus::Variant>>()) {
const auto& metadata = metadataVariant.get<std::map<std::string, sdbus::Variant>>();
const std::map<std::basic_string<char>, sdbus::Variant>& metadata =
metadataVariant.get<std::map<std::string, sdbus::Variant>>();
auto iter = metadata.find("xesam:title");
@ -123,8 +136,10 @@ fn GetNowPlaying() -> string {
return iter->second.get<std::string>();
}
} catch (const sdbus::Error& e) {
if (e.getName() != "com.github.altdesktop.playerctld.NoActivePlayer")
return fmt::format("Error: {}", e.what());
if (e.getName() != "com.github.altdesktop.playerctld.NoActivePlayer") {
ERROR_LOG("Error: {}", e.what());
return "";
}
return "No active player";
}
@ -138,17 +153,33 @@ fn GetShell() -> string {
return shell ? shell : "";
}
fn GetProductFamily() -> string {
std::ifstream file("/sys/class/dmi/id/product_family");
fn GetHost() -> string {
constexpr const char* path = "/sys/class/dmi/id/product_family";
if (!file.is_open())
throw std::runtime_error("Failed to open /sys/class/dmi/id/product_family");
std::ifstream file(path);
if (!file.is_open()) {
ERROR_LOG("Failed to open {}", path);
return "";
}
std::string productFamily;
std::getline(file, productFamily);
if (!std::getline(file, productFamily)) {
ERROR_LOG("Failed to read from {}", path);
return "";
}
return productFamily;
}
fn GetKernelVersion() -> string {
struct utsname uts;
if (uname(&uts) == -1) {
ERROR_LOG("uname() failed: {}", std::strerror(errno));
return "";
}
return static_cast<const char*>(uts.release);
}
#endif

View file

@ -36,4 +36,9 @@ fn GetShell() -> string;
/**
* @brief Get the product family
*/
fn GetProductFamily() -> string;
fn GetHost() -> string;
/**
* @brief Get the kernel version.
*/
fn GetKernelVersion() -> string;