diff --git a/meson.build b/meson.build index fdc8ad3..7a0a4dc 100644 --- a/meson.build +++ b/meson.build @@ -92,12 +92,12 @@ base_sources = files('src/core/system_data.cpp', 'src/core/package.cpp', 'src/co platform_sources = { 'darwin' : ['src/os/macos.cpp', 'src/os/macos/bridge.mm'], - 'dragonfly' : ['src/os/bsd.cpp', 'src/os/bsd/package.cpp'], - 'freebsd' : ['src/os/bsd.cpp', 'src/os/bsd/package.cpp'], - 'haiku' : ['src/os/haiku.cpp', 'src/os/haiku/package.cpp'], + 'dragonfly' : ['src/os/bsd.cpp'], + 'freebsd' : ['src/os/bsd.cpp'], + 'haiku' : ['src/os/haiku.cpp'], 'linux' : ['src/os/linux.cpp'], - 'netbsd' : ['src/os/bsd.cpp', 'src/os/bsd/package.cpp'], - 'serenity' : ['src/os/serenity.cpp', 'src/os/serenity/package.cpp'], + 'netbsd' : ['src/os/bsd.cpp'], + 'serenity' : ['src/os/serenity.cpp'], 'windows' : ['src/os/windows.cpp'], } diff --git a/src/config/config.cpp b/src/config/config.cpp index 2b63e4f..dafe0f9 100644 --- a/src/config/config.cpp +++ b/src/config/config.cpp @@ -26,11 +26,11 @@ namespace { # General settings [general] -name = "{}" # Your display name +name = "{}" # Your display name # Now Playing integration [now_playing] -enabled = false # Set to true to enable media integration +enabled = false # Set to true to enable media integration # Weather settings [weather] diff --git a/src/config/config.hpp b/src/config/config.hpp index 7cd42cc..1e5f02d 100644 --- a/src/config/config.hpp +++ b/src/config/config.hpp @@ -1,11 +1,10 @@ #pragma once -#include // std::string (String) #include // toml::node #include // toml::node_view #include // toml::table #include // std::variant -// + #ifdef _WIN32 #include // GetUserNameA #else diff --git a/src/main.cpp b/src/main.cpp index 41dac0e..6b9690e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -116,7 +116,7 @@ namespace { }; fn CreateColorCircles() -> Element { - fn color_view = + fn colorView = std::views::iota(0, 16) | std::views::transform([](i32 colorIndex) { return ftxui::hbox( { ftxui::text("◯") | ftxui::bold | ftxui::color(static_cast(colorIndex)), @@ -124,9 +124,9 @@ namespace { ); }); - Elements elements_container(std::ranges::begin(color_view), std::ranges::end(color_view)); + Elements elementsContainer(std::ranges::begin(colorView), std::ranges::end(colorView)); - return hbox(elements_container); + return hbox(elementsContainer); } fn get_visual_width(const String& str) -> usize { return ftxui::string_width(str); } diff --git a/src/os/bsd.cpp b/src/os/bsd.cpp index bd1a3d9..32b687b 100644 --- a/src/os/bsd.cpp +++ b/src/os/bsd.cpp @@ -7,15 +7,15 @@ #include // ucred, getsockopt, SOL_SOCKET, SO_PEERCRED #include // statvfs #include // sysctlbyname -#include // LOCAL_PEERCRED -#include // uname, utsname -#include // readlink +#include // LOCAL_PEERCRED +#include // uname, utsname -#if defined(__FreeBSD__) || defined(__DragonFly__) -#include // kenv -#include // xucred +#ifndef __NetBSD__ + #include // kenv + #include // xucred #endif +#include "src/core/package.hpp" #include "src/util/defs.hpp" #include "src/util/error.hpp" #include "src/util/helpers.hpp" @@ -165,9 +165,8 @@ namespace { Result exePathResult = GetPathByPid(peerPid); - if (!exePathResult) { + if (!exePathResult) return Err(std::move(exePathResult).error()); - } const String& exeRealPath = *exePathResult; @@ -485,4 +484,22 @@ namespace os { } } // namespace os +namespace package { + #ifdef __NetBSD__ + fn GetPkgSrcCount() -> Result { + return GetCountFromDirectory("pkgsrc", fs::current_path().root_path() / "usr" / "pkg" / "pkgdb", true); + } + #else + fn GetPkgNgCount() -> Result { + const PackageManagerInfo pkgInfo = { + .id = "pkgng", + .dbPath = "/var/db/pkg/local.sqlite", + .countQuery = "SELECT COUNT(*) FROM packages", + }; + + return GetCountFromDb(pkgInfo); + } + #endif +} // namespace package + #endif // __FreeBSD__ || __DragonFly__ || __NetBSD__ diff --git a/src/os/bsd/package.cpp b/src/os/bsd/package.cpp deleted file mode 100644 index 489ad49..0000000 --- a/src/os/bsd/package.cpp +++ /dev/null @@ -1,34 +0,0 @@ -#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__NetBSD__) - -// clang-format off -#include "src/core/package.hpp" - -#include // SQLite::{Database, OPEN_READONLY} -#include // SQLite::Exception -#include // SQLite::Statement -#include // glz::write_beve -#include // glz::object -#include // glz::detail::Object - -#include "src/util/defs.hpp" -// clang-format on - -namespace package { - #if defined(__FreeBSD__) || defined(__DragonFly__) - fn GetPkgNgCount() -> Result { - const PackageManagerInfo pkgInfo = { - .id = "pkgng", // Use core struct - .dbPath = "/var/db/pkg/local.sqlite", - .countQuery = "SELECT COUNT(*) FROM packages", - }; - - return GetCountFromDb(pkgInfo); - } - #elif defined(__NetBSD__) - fn GetPkgSrcCount() -> Result { - return GetCountFromDirectory("pkgsrc", fs::current_path().root_path() / "usr" / "pkg" / "pkgdb", true); - } - #endif -} // namespace package - -#endif // __FreeBSD__ || __DragonFly__ || __NetBSD__ diff --git a/src/os/haiku.cpp b/src/os/haiku.cpp index 9b71d80..5e03ab3 100644 --- a/src/os/haiku.cpp +++ b/src/os/haiku.cpp @@ -1,9 +1,9 @@ #ifdef __HAIKU__ // clang-format off -#include // For BFile #include // For BAppFileInfo and version_info #include // B_OK, strerror, status_t +#include // For BFile #include // get_system_info, system_info #include // PATH_MAX #include // std::strlen @@ -16,12 +16,12 @@ #include // statvfs #include // std::move +#include "src/core/package.hpp" #include "src/util/defs.hpp" #include "src/util/error.hpp" #include "src/util/helpers.hpp" #include "src/util/logging.hpp" #include "src/util/types.hpp" -#include "src/wrappers/dbus.hpp" #include "os.hpp" // clang-format on @@ -69,134 +69,7 @@ namespace os { } fn GetNowPlaying() -> Result { - using namespace dbus; - - Result connectionResult = Connection::busGet(DBUS_BUS_SESSION); - if (!connectionResult) - return Err(connectionResult.error()); - - const Connection& connection = *connectionResult; - - Option activePlayer = None; - - { - Result listNamesResult = - Message::newMethodCall("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "ListNames"); - if (!listNamesResult) - return Err(listNamesResult.error()); - - Result listNamesReplyResult = connection.sendWithReplyAndBlock(*listNamesResult, 100); - if (!listNamesReplyResult) - return Err(listNamesReplyResult.error()); - - MessageIter iter = listNamesReplyResult->iterInit(); - if (!iter.isValid() || iter.getArgType() != DBUS_TYPE_ARRAY) - return Err(DracError(DracErrorCode::ParseError, "Invalid DBus ListNames reply format: Expected array")); - - MessageIter subIter = iter.recurse(); - if (!subIter.isValid()) - return Err( - DracError(DracErrorCode::ParseError, "Invalid DBus ListNames reply format: Could not recurse into array") - ); - - while (subIter.getArgType() != DBUS_TYPE_INVALID) { - if (Option name = subIter.getString()) - if (name->starts_with("org.mpris.MediaPlayer2.")) { - activePlayer = std::move(*name); - break; - } - if (!subIter.next()) - break; - } - } - - if (!activePlayer) - return Err(DracError(DracErrorCode::NotFound, "No active MPRIS players found")); - - Result msgResult = Message::newMethodCall( - activePlayer->c_str(), "/org/mpris/MediaPlayer2", "org.freedesktop.DBus.Properties", "Get" - ); - - if (!msgResult) - return Err(msgResult.error()); - - Message& msg = *msgResult; - - if (!msg.appendArgs("org.mpris.MediaPlayer2.Player", "Metadata")) - return Err(DracError(DracErrorCode::InternalError, "Failed to append arguments to Properties.Get message")); - - Result replyResult = connection.sendWithReplyAndBlock(msg, 100); - - if (!replyResult) - return Err(replyResult.error()); - - Option title = None; - Option artist = None; - - MessageIter propIter = replyResult->iterInit(); - if (!propIter.isValid()) - return Err(DracError(DracErrorCode::ParseError, "Properties.Get reply has no arguments or invalid iterator")); - - if (propIter.getArgType() != DBUS_TYPE_VARIANT) - return Err(DracError(DracErrorCode::ParseError, "Properties.Get reply argument is not a variant")); - - MessageIter variantIter = propIter.recurse(); - if (!variantIter.isValid()) - return Err(DracError(DracErrorCode::ParseError, "Could not recurse into variant")); - - if (variantIter.getArgType() != DBUS_TYPE_ARRAY || variantIter.getElementType() != DBUS_TYPE_DICT_ENTRY) - return Err(DracError(DracErrorCode::ParseError, "Metadata variant content is not a dictionary array (a{sv})")); - - MessageIter dictIter = variantIter.recurse(); - if (!dictIter.isValid()) - return Err(DracError(DracErrorCode::ParseError, "Could not recurse into metadata dictionary array")); - - while (dictIter.getArgType() == DBUS_TYPE_DICT_ENTRY) { - MessageIter entryIter = dictIter.recurse(); - if (!entryIter.isValid()) { - debug_log("Warning: Could not recurse into dict entry, skipping."); - if (!dictIter.next()) - break; - continue; - } - - Option key = entryIter.getString(); - if (!key) { - debug_log("Warning: Could not get key string from dict entry, skipping."); - if (!dictIter.next()) - break; - continue; - } - - if (!entryIter.next() || entryIter.getArgType() != DBUS_TYPE_VARIANT) { - if (!dictIter.next()) - break; - continue; - } - - MessageIter valueVariantIter = entryIter.recurse(); - if (!valueVariantIter.isValid()) { - if (!dictIter.next()) - break; - continue; - } - - if (*key == "xesam:title") { - title = valueVariantIter.getString(); - } else if (*key == "xesam:artist") { - if (valueVariantIter.getArgType() == DBUS_TYPE_ARRAY && valueVariantIter.getElementType() == DBUS_TYPE_STRING) { - if (MessageIter artistArrayIter = valueVariantIter.recurse(); artistArrayIter.isValid()) - artist = artistArrayIter.getString(); - } else { - debug_log("Warning: Artist value was not an array of strings as expected."); - } - } - - if (!dictIter.next()) - break; - } - - return MediaInfo(std::move(title), std::move(artist)); + return Err(DracError(DracErrorCode::NotSupported, "Now playing is not supported on Haiku")); } fn GetWindowManager() -> Result { return "app_server"; } @@ -261,4 +134,18 @@ namespace os { } } // namespace os +namespace package { + fn GetHaikuCount() -> Result { + BPackageKit::BPackageRoster roster; + BPackageKit::BPackageInfoSet packageList; + + const status_t status = roster.GetActivePackages(BPackageKit::B_PACKAGE_INSTALLATION_LOCATION_SYSTEM, packageList); + + if (status != B_OK) + return Err(DracError(DracErrorCode::ApiUnavailable, "Failed to get active package list")); + + return static_cast(packageList.CountInfos()); + } +} // namespace package + #endif // __HAIKU__ diff --git a/src/os/haiku/package.cpp b/src/os/haiku/package.cpp deleted file mode 100644 index 0c4da1e..0000000 --- a/src/os/haiku/package.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#ifdef __HAIKU__ -// clang-format off -#include "src/core/package.hpp" - -#include // BPackageKit::BPackageInfoSet -#include // BPackageKit::BPackageInfo -#include // BPackageKit::BPackageRoster - -#include "src/util/defs.hpp" -#include "src/util/error.hpp" -// clang-format on - -namespace package { - using util::error::DracError, util::error::DracErrorCode; - using util::types::Err; - - fn GetHaikuCount() -> Result { - BPackageKit::BPackageRoster roster; - BPackageKit::BPackageInfoSet packageList; - - const status_t status = roster.GetActivePackages(BPackageKit::B_PACKAGE_INSTALLATION_LOCATION_SYSTEM, packageList); - - if (status != B_OK) - return Err(DracError(DracErrorCode::ApiUnavailable, "Failed to get active package list")); - - return static_cast(packageList.CountInfos()); - } -} // namespace package - -#endif // __HAIKU__ diff --git a/src/os/serenity.cpp b/src/os/serenity.cpp index 634563c..3e96dc7 100644 --- a/src/os/serenity.cpp +++ b/src/os/serenity.cpp @@ -16,7 +16,9 @@ #include // uid_t #include // utsname, uname #include // getuid, gethostname +#include // std::unordered_set +#include "src/core/package.hpp" #include "src/util/defs.hpp" #include "src/util/error.hpp" #include "src/util/helpers.hpp" @@ -47,6 +49,22 @@ namespace { }; // NOLINTEND(readability-identifier-naming) }; + + fn CountUniquePackages(const String& dbPath) -> Result { + std::ifstream dbFile(dbPath); + + if (!dbFile.is_open()) + return Err(DracError(DracErrorCode::NotFound, std::format("Failed to open file: {}", dbPath))); + + std::unordered_set uniquePackages; + String line; + + while (std::getline(dbFile, line)) + if (line.starts_with("manual ") || line.starts_with("auto ")) + uniquePackages.insert(line); + + return uniquePackages.size(); + } } // namespace namespace os { @@ -147,4 +165,8 @@ namespace os { } } // namespace os +namespace package { + fn GetSerenityCount() -> Result { return CountUniquePackages("/usr/Ports/installed.db"); } +} // namespace package + #endif // __serenity__ diff --git a/src/os/serenity/package.cpp b/src/os/serenity/package.cpp deleted file mode 100644 index 3b708a9..0000000 --- a/src/os/serenity/package.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#ifdef __serenity__ - -// clang-format off -#include "src/core/package.hpp" - -#include -#include - -#include "src/util/defs.hpp" -#include "src/util/error.hpp" -#include "src/util/types.hpp" -// clang-format on - -using util::error::DracError, util::error::DracErrorCode; -using util::types::u64, util::types::String, util::types::Result, util::types::Err; - -namespace { - fn CountUniquePackages(const String& dbPath) -> Result { - std::ifstream dbFile(dbPath); - - if (!dbFile.is_open()) - return Err(DracError(DracErrorCode::NotFound, std::format("Failed to open file: {}", dbPath))); - - std::unordered_set uniquePackages; - String line; - - while (std::getline(dbFile, line)) - if (line.starts_with("manual ") || line.starts_with("auto ")) - uniquePackages.insert(line); - - return uniquePackages.size(); - } -} // namespace - -namespace package { - fn GetSerenityCount() -> Result { return CountUniquePackages("/usr/Ports/installed.db"); } -} // namespace package - -#endif // __serenity__ diff --git a/src/wrappers/dbus.hpp b/src/wrappers/dbus.hpp index 188ee4b..ab38cd4 100644 --- a/src/wrappers/dbus.hpp +++ b/src/wrappers/dbus.hpp @@ -1,6 +1,6 @@ #pragma once -#if defined(__linux__) || defined(__FreeBSD__) || defined(__DragonFly__) || defined(__NetBSD__) || defined(__HAIKU__) +#if defined(__linux__) || defined(__FreeBSD__) || defined(__DragonFly__) || defined(__NetBSD__) // clang-format off #include @@ -280,8 +280,8 @@ namespace dbus { using DecayedT = std::decay_t; if constexpr (std::is_convertible_v) { - const char* valuePtr = static_cast(arg); - return dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &valuePtr); + const char* valuePtr = static_cast(std::forward(arg)); + return dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, static_cast(&valuePtr)); } else { static_assert(!sizeof(T*), "Unsupported type passed to appendArgs"); return false; @@ -386,4 +386,4 @@ namespace dbus { }; } // namespace dbus -#endif // __linux__ || __FreeBSD__ || __DragonFly__ || __NetBSD__ || __HAIKU__ +#endif // __linux__ || __FreeBSD__ || __DragonFly__ || __NetBSD__