update windows + fixes

This commit is contained in:
Mars 2025-05-02 15:17:17 -04:00
parent c33ab763e6
commit 34e6bf52fd
10 changed files with 75 additions and 79 deletions

View file

@ -3,12 +3,15 @@
#include <filesystem> // std::filesystem::{path, operator/, exists, create_directories} #include <filesystem> // std::filesystem::{path, operator/, exists, create_directories}
#include <format> // std::{format, format_error} #include <format> // std::{format, format_error}
#include <fstream> // std::{ifstream, ofstream, operator<<} #include <fstream> // std::{ifstream, ofstream, operator<<}
#include <pwd.h> // passwd, getpwuid
#include <system_error> // std::error_code #include <system_error> // std::error_code
#include <toml++/impl/node_view.hpp> // toml::node_view #include <toml++/impl/node_view.hpp> // toml::node_view
#include <toml++/impl/parser.hpp> // toml::{parse_file, parse_result} #include <toml++/impl/parser.hpp> // toml::{parse_file, parse_result}
#include <toml++/impl/table.hpp> // toml::table #include <toml++/impl/table.hpp> // toml::table
#include <unistd.h> // getuid
#ifndef _WIN32
#include <pwd.h> // passwd, getpwuid
#include <unistd.h> // getuid
#endif
#include "src/util/defs.hpp" #include "src/util/defs.hpp"
#include "src/util/helpers.hpp" #include "src/util/helpers.hpp"

View file

@ -4,14 +4,12 @@
#include <future> // std::future #include <future> // std::future
#include <glaze/core/common.hpp> // glz::object #include <glaze/core/common.hpp> // glz::object
#include <glaze/core/meta.hpp> // glz::detail::Object #include <glaze/core/meta.hpp> // glz::detail::Object
#include <vector> // std::vector
#include "src/util/defs.hpp" #include "src/util/defs.hpp"
#include "src/util/error.hpp" #include "src/util/error.hpp"
#include "src/util/types.hpp" #include "src/util/types.hpp"
namespace packages { namespace packages {
namespace fs = std::filesystem; namespace fs = std::filesystem;
using util::error::DracError; using util::error::DracError;
using util::types::Result, util::types::u64, util::types::i64, util::types::String, util::types::Vec, using util::types::Result, util::types::u64, util::types::i64, util::types::String, util::types::Vec,

View file

@ -17,7 +17,7 @@ using util::error::DracError, util::error::DracErrorCode;
namespace { namespace {
using util::types::i32, util::types::CStr; using util::types::i32, util::types::CStr;
fn getOrdinalSuffix(i32 day) -> CStr { fn getOrdinalSuffix(const i32 day) -> CStr {
if (day >= 11 && day <= 13) if (day >= 11 && day <= 13)
return "th"; return "th";
@ -46,9 +46,8 @@ namespace {
i32 day = nowTm.tm_mday; i32 day = nowTm.tm_mday;
String monthBuffer(32, '\0'); String monthBuffer(32, '\0');
const usize monthLen = std::strftime(monthBuffer.data(), monthBuffer.size(), "%B", &nowTm);
if (monthLen > 0) { if (const usize monthLen = std::strftime(monthBuffer.data(), monthBuffer.size(), "%B", &nowTm); monthLen > 0) {
monthBuffer.resize(monthLen); monthBuffer.resize(monthLen);
CStr suffix = getOrdinalSuffix(day); CStr suffix = getOrdinalSuffix(day);
@ -56,9 +55,11 @@ namespace {
try { try {
return std::format("{} {}{}", monthBuffer, day, suffix); return std::format("{} {}{}", monthBuffer, day, suffix);
} catch (const std::format_error& e) { return Err(DracError(DracErrorCode::ParseError, e.what())); } } catch (const std::format_error& e) { return Err(DracError(DracErrorCode::ParseError, e.what())); }
} else }
return Err(DracError(DracErrorCode::ParseError, "Failed to format date")); return Err(DracError(DracErrorCode::ParseError, "Failed to format date"));
} else }
return Err(DracError(DracErrorCode::ParseError, "Failed to get local time")); return Err(DracError(DracErrorCode::ParseError, "Failed to get local time"));
} }
} // namespace } // namespace
@ -81,9 +82,7 @@ namespace os {
Future<Result<MediaInfo, DracError>> npFut = Future<Result<MediaInfo, DracError>> npFut =
std::async(config.nowPlaying.enabled ? async : deferred, GetNowPlaying); std::async(config.nowPlaying.enabled ? async : deferred, GetNowPlaying);
Future<Result<Output, DracError>> wthrFut = Future<Result<Output, DracError>> wthrFut =
std::async(config.weather.enabled ? async : deferred, [&config] -> Result<Output, DracError> { std::async(config.weather.enabled ? async : deferred, [&config] { return config.weather.getWeatherInfo(); });
return config.weather.getWeatherInfo();
});
this->date = getDate(); this->date = getDate();
this->host = hostFut.get(); this->host = hostFut.get();

View file

@ -2,8 +2,8 @@
#include <format> // std::{formatter, format_to} #include <format> // std::{formatter, format_to}
#include "src/config/config.hpp" // Config #include "src/config/config.hpp"
#include "src/config/weather.hpp" // weather::Output #include "src/config/weather.hpp"
#include "src/util/defs.hpp" #include "src/util/defs.hpp"
#include "src/util/types.hpp" #include "src/util/types.hpp"

View file

@ -244,8 +244,8 @@ namespace {
usize requiredWidthSystemW = iconActualWidth + maxLabelWidthSystem; usize requiredWidthSystemW = iconActualWidth + maxLabelWidthSystem;
usize requiredWidthEnvW = iconActualWidth + maxLabelWidthEnv; usize requiredWidthEnvW = iconActualWidth + maxLabelWidthEnv;
fn calculateRowVisualWidth = [&](const RowInfo& row, usize requiredLabelVisualWidth) -> usize { fn calculateRowVisualWidth = [&](const RowInfo& row, const usize requiredLabelVisualWidth) -> usize {
return requiredLabelVisualWidth + get_visual_width(row.value) + get_visual_width_sv(" "); // Use visual width return requiredLabelVisualWidth + get_visual_width(row.value) + get_visual_width_sv(" ");
}; };
for (const RowInfo& row : initialRows) for (const RowInfo& row : initialRows)
@ -278,7 +278,7 @@ namespace {
paragraphLimit = std::max(1, availableForParagraph); paragraphLimit = std::max(1, availableForParagraph);
} }
fn createStandardRow = [&](const RowInfo& row, usize sectionRequiredVisualWidth) { fn createStandardRow = [&](const RowInfo& row, const usize sectionRequiredVisualWidth) {
return hbox( return hbox(
{ {
hbox( hbox(

View file

@ -1,15 +1,16 @@
#include <SQLiteCpp/Database.h> // SQLite::{Database, OPEN_READONLY} #ifndef _WIN32
#include <SQLiteCpp/Exception.h> // SQLite::Exception #include <SQLiteCpp/Database.h> // SQLite::{Database, OPEN_READONLY}
#include <SQLiteCpp/Statement.h> // SQLite::Statement #include <SQLiteCpp/Exception.h> // SQLite::Exception
#include <SQLiteCpp/Statement.h> // SQLite::Statement
#endif
#include <chrono> // std::chrono #include <chrono> // std::chrono
#include <filesystem> // std::filesystem #include <filesystem> // std::filesystem
#include <format> // std::format #include <format> // std::format
#include <fstream> // std::{ifstream, ofstream} #include <fstream> // std::{ifstream, ofstream}
#include <glaze/beve/read.hpp> // glz::read_beve
#include <glaze/beve/write.hpp> // glz::write_beve #include <glaze/beve/write.hpp> // glz::write_beve
#include <glaze/core/common.hpp> // glz::object #include <glaze/core/common.hpp> // glz::object
#include <glaze/core/meta.hpp> // glz::detail::Object #include <glaze/core/meta.hpp> // glz::detail::Object
#include <ios> // std::ios::{binary, trunc}, std::ios_base
#include <iterator> // std::istreambuf_iterator #include <iterator> // std::istreambuf_iterator
#include <system_error> // std::error_code #include <system_error> // std::error_code
@ -32,11 +33,13 @@ namespace {
using namespace std::chrono; using namespace std::chrono;
using namespace util::cache; using namespace util::cache;
#ifndef _WIN32
struct PackageManagerInfo { struct PackageManagerInfo {
String id; String id;
fs::path dbPath; fs::path dbPath;
String countQuery; String countQuery;
}; };
#endif
struct PkgCountCacheData { struct PkgCountCacheData {
u64 count {}; u64 count {};
@ -52,6 +55,7 @@ namespace {
// NOLINTEND(readability-identifier-naming) // NOLINTEND(readability-identifier-naming)
}; };
#ifndef _WIN32
fn GetPackageCountInternalDb(const PackageManagerInfo& pmInfo) -> Result<u64, DracError> { fn GetPackageCountInternalDb(const PackageManagerInfo& pmInfo) -> Result<u64, DracError> {
const auto& [pmId, dbPath, countQuery] = pmInfo; const auto& [pmId, dbPath, countQuery] = pmInfo;
@ -113,6 +117,7 @@ namespace {
return count; return count;
} }
#endif
#ifndef _WIN32 #ifndef _WIN32
fn GetNixPackageCount() -> Result<u64, DracError> { fn GetNixPackageCount() -> Result<u64, DracError> {
@ -142,9 +147,9 @@ namespace {
fs::path cargoPath {}; fs::path cargoPath {};
if (Result<String, DracError> cargoHome = GetEnv("CARGO_HOME")) if (const Result<String, DracError> cargoHome = GetEnv("CARGO_HOME"))
cargoPath = fs::path(*cargoHome) / "bin"; cargoPath = fs::path(*cargoHome) / "bin";
else if (Result<String, DracError> homeDir = GetEnv("HOME")) else if (const Result<String, DracError> homeDir = GetEnv("HOME"))
cargoPath = fs::path(*homeDir) / ".cargo" / "bin"; cargoPath = fs::path(*homeDir) / ".cargo" / "bin";
if (cargoPath.empty() || !fs::exists(cargoPath)) if (cargoPath.empty() || !fs::exists(cargoPath))

View file

@ -27,7 +27,7 @@
using RtlGetVersionPtr = NTSTATUS(WINAPI*)(PRTL_OSVERSIONINFOW); using RtlGetVersionPtr = NTSTATUS(WINAPI*)(PRTL_OSVERSIONINFOW);
namespace { namespace {
using util::error::DraconisError, util::error::DraconisErrorCode; using util::error::DracError, util::error::DracErrorCode;
using namespace util::types; using namespace util::types;
struct ProcessData { struct ProcessData {
@ -165,7 +165,7 @@ namespace {
} // namespace } // namespace
namespace os { namespace os {
fn GetMemInfo() -> Result<u64, DraconisError> { fn GetMemInfo() -> Result<u64, DracError> {
MEMORYSTATUSEX memInfo; MEMORYSTATUSEX memInfo;
memInfo.dwLength = sizeof(MEMORYSTATUSEX); memInfo.dwLength = sizeof(MEMORYSTATUSEX);
@ -173,12 +173,12 @@ namespace os {
return memInfo.ullTotalPhys; return memInfo.ullTotalPhys;
DWORD lastError = GetLastError(); DWORD lastError = GetLastError();
return Err(DraconisError( return Err(DracError(
DraconisErrorCode::PlatformSpecific, std::format("GlobalMemoryStatusEx failed with error code {}", lastError) DracErrorCode::PlatformSpecific, std::format("GlobalMemoryStatusEx failed with error code {}", lastError)
)); ));
} }
fn GetNowPlaying() -> Result<MediaInfo, DraconisError> { fn GetNowPlaying() -> Result<MediaInfo, DracError> {
using namespace winrt::Windows::Media::Control; using namespace winrt::Windows::Media::Control;
using namespace winrt::Windows::Foundation; using namespace winrt::Windows::Foundation;
@ -193,16 +193,14 @@ namespace os {
if (const Session currentSession = sessionManager.GetCurrentSession()) { if (const Session currentSession = sessionManager.GetCurrentSession()) {
const MediaProperties mediaProperties = currentSession.TryGetMediaPropertiesAsync().get(); const MediaProperties mediaProperties = currentSession.TryGetMediaPropertiesAsync().get();
return MediaInfo( return MediaInfo(winrt::to_string(mediaProperties.Title()), winrt::to_string(mediaProperties.Artist()));
winrt::to_string(mediaProperties.Title()), winrt::to_string(mediaProperties.Artist()), None, None
);
} }
return Err(DraconisError(DraconisErrorCode::NotFound, "No media session found")); return Err(DracError(DracErrorCode::NotFound, "No media session found"));
} catch (const winrt::hresult_error& e) { return Err(DraconisError(e)); } } catch (const winrt::hresult_error& e) { return Err(DracError(e)); }
} }
fn GetOSVersion() -> Result<String, DraconisError> { fn GetOSVersion() -> Result<String, DracError> {
try { try {
const String regSubKey = R"(SOFTWARE\Microsoft\Windows NT\CurrentVersion)"; const String regSubKey = R"(SOFTWARE\Microsoft\Windows NT\CurrentVersion)";
@ -210,7 +208,7 @@ namespace os {
const String displayVersion = GetRegistryValue(HKEY_LOCAL_MACHINE, regSubKey, "DisplayVersion"); const String displayVersion = GetRegistryValue(HKEY_LOCAL_MACHINE, regSubKey, "DisplayVersion");
if (productName.empty()) if (productName.empty())
return Err(DraconisError(DraconisErrorCode::NotFound, "ProductName not found in registry")); return Err(DracError(DracErrorCode::NotFound, "ProductName not found in registry"));
if (const Option<u64> buildNumberOpt = GetBuildNumber()) { if (const Option<u64> buildNumberOpt = GetBuildNumber()) {
if (const u64 buildNumber = *buildNumberOpt; buildNumber >= 22000) { if (const u64 buildNumber = *buildNumberOpt; buildNumber >= 22000) {
@ -229,14 +227,14 @@ namespace os {
} }
return displayVersion.empty() ? productName : productName + " " + displayVersion; return displayVersion.empty() ? productName : productName + " " + displayVersion;
} catch (const std::exception& e) { return Err(DraconisError(e)); } } catch (const std::exception& e) { return Err(DracError(e)); }
} }
fn GetHost() -> Result<String, DraconisError> { fn GetHost() -> Result<String, DracError> {
return GetRegistryValue(HKEY_LOCAL_MACHINE, R"(SYSTEM\HardwareConfig\Current)", "SystemFamily"); return GetRegistryValue(HKEY_LOCAL_MACHINE, R"(SYSTEM\HardwareConfig\Current)", "SystemFamily");
} }
fn GetKernelVersion() -> Result<String, DraconisError> { fn GetKernelVersion() -> Result<String, DracError> {
if (const HMODULE ntdllHandle = GetModuleHandleW(L"ntdll.dll")) { if (const HMODULE ntdllHandle = GetModuleHandleW(L"ntdll.dll")) {
if (const auto rtlGetVersion = std::bit_cast<RtlGetVersionPtr>(GetProcAddress(ntdllHandle, "RtlGetVersion"))) { if (const auto rtlGetVersion = std::bit_cast<RtlGetVersionPtr>(GetProcAddress(ntdllHandle, "RtlGetVersion"))) {
RTL_OSVERSIONINFOW osInfo = {}; RTL_OSVERSIONINFOW osInfo = {};
@ -249,28 +247,24 @@ namespace os {
} }
} }
return Err(DraconisError(DraconisErrorCode::NotFound, "Could not determine kernel version using RtlGetVersion")); return Err(DracError(DracErrorCode::NotFound, "Could not determine kernel version using RtlGetVersion"));
} }
fn GetWindowManager() -> Option<String> { fn GetWindowManager() -> Result<String, DracError> {
BOOL compositionEnabled = FALSE; BOOL compositionEnabled = FALSE;
if (SUCCEEDED(DwmIsCompositionEnabled(&compositionEnabled))) {
if (SUCCEEDED(DwmIsCompositionEnabled(&compositionEnabled)))
return compositionEnabled ? "DWM" : "Windows Manager (Basic)"; return compositionEnabled ? "DWM" : "Windows Manager (Basic)";
return Err(DracError(DracErrorCode::NotFound, "Failed to get window manager (DwmIsCompositionEnabled failed"));
} }
error_log("GetWindowManager: DwmIsCompositionEnabled failed"); fn GetDesktopEnvironment() -> Result<String, DracError> {
return None;
}
fn GetDesktopEnvironment() -> Option<String> {
const String buildStr = const String buildStr =
GetRegistryValue(HKEY_LOCAL_MACHINE, R"(SOFTWARE\Microsoft\Windows NT\CurrentVersion)", "CurrentBuildNumber"); GetRegistryValue(HKEY_LOCAL_MACHINE, R"(SOFTWARE\Microsoft\Windows NT\CurrentVersion)", "CurrentBuildNumber");
if (buildStr.empty()) { if (buildStr.empty())
debug_log("Failed to get CurrentBuildNumber from registry"); return Err(DracError(DracErrorCode::InternalError, "Failed to get CurrentBuildNumber from registry"));
return None;
}
try { try {
const i32 build = stoi(buildStr); const i32 build = stoi(buildStr);
@ -304,22 +298,18 @@ namespace os {
// Pre-Win7 // Pre-Win7
return "Classic"; return "Classic";
} catch (...) { } catch (...) { return Err(DracError(DracErrorCode::ParseError, "Failed to parse CurrentBuildNumber")); }
debug_log("Failed to parse CurrentBuildNumber");
return None;
}
} }
fn GetShell() -> Option<String> { fn GetShell() -> Result<String, DracError> {
using util::helpers::GetEnv; using util::helpers::GetEnv;
if (const Result<String, DraconisError> msystemResult = GetEnv("MSYSTEM"); if (const Result<String, DracError> msystemResult = GetEnv("MSYSTEM"); msystemResult && !msystemResult->empty()) {
msystemResult && !msystemResult->empty()) {
String shellPath; String shellPath;
if (const Result<String, DraconisError> shellResult = GetEnv("SHELL"); shellResult && !shellResult->empty()) { if (const Result<String, DracError> shellResult = GetEnv("SHELL"); shellResult && !shellResult->empty()) {
shellPath = *shellResult; shellPath = *shellResult;
} else if (const Result<String, DraconisError> loginShellResult = GetEnv("LOGINSHELL"); } else if (const Result<String, DracError> loginShellResult = GetEnv("LOGINSHELL");
loginShellResult && !loginShellResult->empty()) { loginShellResult && !loginShellResult->empty()) {
shellPath = *loginShellResult; shellPath = *loginShellResult;
} }
@ -339,31 +329,31 @@ namespace os {
const DWORD currentPid = GetCurrentProcessId(); const DWORD currentPid = GetCurrentProcessId();
if (const Option<String> msysShell = FindShellInProcessTree(currentPid, msysShellMap)) if (const Option<String> msysShell = FindShellInProcessTree(currentPid, msysShellMap))
return msysShell; return *msysShell;
return "MSYS2 Environment"; return "MSYS2 Environment";
} }
const DWORD currentPid = GetCurrentProcessId(); const DWORD currentPid = GetCurrentProcessId();
if (const Option<String> windowsShell = FindShellInProcessTree(currentPid, windowsShellMap)) if (const Option<String> windowsShell = FindShellInProcessTree(currentPid, windowsShellMap))
return windowsShell; return *windowsShell;
return None; return Err(DracError(DracErrorCode::NotFound, "Shell not found"));
} }
fn GetDiskUsage() -> Result<DiskSpace, DraconisError> { fn GetDiskUsage() -> Result<DiskSpace, DracError> {
ULARGE_INTEGER freeBytes, totalBytes; ULARGE_INTEGER freeBytes, totalBytes;
if (GetDiskFreeSpaceExW(L"C:\\", nullptr, &totalBytes, &freeBytes)) if (GetDiskFreeSpaceExW(L"C:\\", nullptr, &totalBytes, &freeBytes))
return DiskSpace { .used_bytes = totalBytes.QuadPart - freeBytes.QuadPart, .total_bytes = totalBytes.QuadPart }; return DiskSpace { .used_bytes = totalBytes.QuadPart - freeBytes.QuadPart, .total_bytes = totalBytes.QuadPart };
return Err(DraconisError(util::error::DraconisErrorCode::NotFound, "Failed to get disk usage")); return Err(DracError(util::error::DracErrorCode::NotFound, "Failed to get disk usage"));
} }
fn GetPackageCount() -> Result<u64, DraconisError> { fn GetPackageCount() -> Result<u64, DracError> {
try { try {
return std::ranges::distance(winrt::Windows::Management::Deployment::PackageManager().FindPackagesForUser(L"")); return std::ranges::distance(winrt::Windows::Management::Deployment::PackageManager().FindPackagesForUser(L""));
} catch (const winrt::hresult_error& e) { return Err(DraconisError(e)); } } catch (const winrt::hresult_error& e) { return Err(DracError(e)); }
} }
} // namespace os } // namespace os

View file

@ -71,16 +71,16 @@ namespace util::error {
} }
} }
#ifdef _WIN32 #ifdef _WIN32
explicit DraconisError(const winrt::hresult_error& e) : message(winrt::to_string(e.message())) { explicit DracError(const winrt::hresult_error& e) : message(winrt::to_string(e.message())) {
switch (e.code()) { switch (e.code()) {
case E_ACCESSDENIED: code = DraconisErrorCode::PermissionDenied; break; case E_ACCESSDENIED: code = DracErrorCode::PermissionDenied; break;
case HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND): case HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND):
case HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND): case HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND):
case HRESULT_FROM_WIN32(ERROR_SERVICE_NOT_FOUND): code = DraconisErrorCode::NotFound; break; case HRESULT_FROM_WIN32(ERROR_SERVICE_NOT_FOUND): code = DracErrorCode::NotFound; break;
case HRESULT_FROM_WIN32(ERROR_TIMEOUT): case HRESULT_FROM_WIN32(ERROR_TIMEOUT):
case HRESULT_FROM_WIN32(ERROR_SEM_TIMEOUT): code = DraconisErrorCode::Timeout; break; case HRESULT_FROM_WIN32(ERROR_SEM_TIMEOUT): code = DracErrorCode::Timeout; break;
case HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED): code = DraconisErrorCode::NotSupported; break; case HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED): code = DracErrorCode::NotSupported; break;
default: code = DraconisErrorCode::PlatformSpecific; break; default: code = DracErrorCode::PlatformSpecific; break;
} }
} }
#else #else

View file

@ -27,10 +27,10 @@ namespace util::helpers {
const UniquePointer<char, decltype(&free)> ptrManager(rawPtr, free); const UniquePointer<char, decltype(&free)> ptrManager(rawPtr, free);
if (err != 0) if (err != 0)
return Err(DraconisError(DraconisErrorCode::PermissionDenied, "Failed to retrieve environment variable")); return Err(DracError(DracErrorCode::PermissionDenied, "Failed to retrieve environment variable"));
if (!ptrManager) if (!ptrManager)
return Err(DraconisError(DraconisErrorCode::NotFound, "Environment variable not found")); return Err(DracError(DracErrorCode::NotFound, "Environment variable not found"));
return ptrManager.get(); return ptrManager.get();
#else #else

View file

@ -156,6 +156,7 @@ namespace util::logging {
fn LogImpl( fn LogImpl(
const LogLevel level, const LogLevel level,
#ifndef NDEBUG #ifndef NDEBUG
// ReSharper disable once CppDoxygenUndocumentedParameter
const std::source_location& loc, const std::source_location& loc,
#endif #endif
std::format_string<Args...> fmt, std::format_string<Args...> fmt,
@ -173,7 +174,7 @@ namespace util::logging {
String timestamp; String timestamp;
#ifdef _WIN32 #ifdef _WIN32
if (localtime_s(&local_tm, &now_tt) == 0) { if (localtime_s(&localTm, &nowTt) == 0) {
#else #else
if (localtime_r(&nowTt, &localTm) != nullptr) { if (localtime_r(&nowTt, &localTm) != nullptr) {
#endif #endif