diff --git a/CMakeLists.txt b/CMakeLists.txt index 398ff33..df6a941 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,7 +28,7 @@ pkg_check_modules( wayland-client wayland-protocols egl - hyprutils>=0.9.0 + hyprutils>=0.10.4 hyprlang>=0.6.0 pixman-1 libdrm @@ -39,7 +39,7 @@ pkg_check_modules( pangocairo iniparser hyprgraphics>=0.3.0 - aquamarine>=0.9.5) + aquamarine>=0.10.0) configure_file(hyprtoolkit.pc.in hyprtoolkit.pc @ONLY) diff --git a/flake.lock b/flake.lock index 0d35a1f..52532b5 100644 --- a/flake.lock +++ b/flake.lock @@ -16,11 +16,11 @@ ] }, "locked": { - "lastModified": 1762356719, - "narHash": "sha256-qwd/xdoOya1m8FENle+4hWnydCtlXUWLAW/Auk6WL7s=", + "lastModified": 1764370710, + "narHash": "sha256-7iZklFmziy6Vn5ZFy9mvTSuFopp3kJNuPxL5QAvtmFQ=", "owner": "hyprwm", "repo": "aquamarine", - "rev": "6d0b3567584691bf9d8fedb5d0093309e2f979c7", + "rev": "561ae7fbe1ca15dfd908262ec815bf21a13eef63", "type": "github" }, "original": { @@ -91,11 +91,11 @@ ] }, "locked": { - "lastModified": 1762387740, - "narHash": "sha256-gQ9zJ+pUI4o+Gh4Z6jhJll7jjCSwi8ZqJIhCE2oqwhQ=", + "lastModified": 1764464068, + "narHash": "sha256-0TphQ03mCptteIXI7skQeRjwkl1bWGvNfGR020rWSKo=", "owner": "hyprwm", "repo": "hyprutils", - "rev": "926689ddb9c0a8787e58c02c765a62e32d63d1f7", + "rev": "7e6346f84be8918e3eca405546c45fb37d74bdfe", "type": "github" }, "original": { diff --git a/include/hyprtoolkit/core/Backend.hpp b/include/hyprtoolkit/core/Backend.hpp index c2d2892..dfa5bd9 100644 --- a/include/hyprtoolkit/core/Backend.hpp +++ b/include/hyprtoolkit/core/Backend.hpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -28,12 +29,19 @@ namespace Hyprtoolkit { using LogFn = std::function; + struct SBackendCreationData { + explicit SBackendCreationData(); + + Hyprutils::Memory::CSharedPointer pLogConnection; + }; + /* Create a backend. There can only be one backend per process: In case of another create(), it will fail. */ static Hyprutils::Memory::CSharedPointer create(); + static Hyprutils::Memory::CSharedPointer createWithData(const SBackendCreationData& data); /* Destroy the backend. diff --git a/src/core/Backend.cpp b/src/core/Backend.cpp index 44e36aa..fadff5c 100644 --- a/src/core/Backend.cpp +++ b/src/core/Backend.cpp @@ -30,22 +30,15 @@ using namespace Hyprutils::Memory; #define SP CSharedPointer #define WP CWeakPointer -static void aqLog(Aquamarine::eBackendLogLevel level, std::string msg) { - if (Env::envEnabled("HT_QUIET")) - return; - - if (g_logger) - g_logger->log(HT_LOG_DEBUG, "[AQ] {}", msg); - else - std::println("{}", msg); -} - CBackend::CBackend() { pipe(m_sLoopState.exitfd); pipe(m_sLoopState.wakeupfd); Aquamarine::SBackendOptions options{}; - options.logFunction = ::aqLog; + g_logger->m_aqLoggerConnection = makeShared(g_logger->m_logger); + g_logger->m_aqLoggerConnection->setLogLevel(Hyprutils::CLI::LOG_WARN); // don't print debug logs, unless AQ_TRACE is set, then aq will set it + g_logger->m_aqLoggerConnection->setName("aquamarine"); + options.logConnection = g_logger->m_aqLoggerConnection; std::vector implementations; Aquamarine::SBackendImplementationOptions option; @@ -65,11 +58,18 @@ CBackend::~CBackend() { close(m_sLoopState.wakeupfd[1]); } +IBackend::SBackendCreationData::SBackendCreationData() = default; + +SP IBackend::createWithData(const IBackend::SBackendCreationData& data) { + g_logger->m_loggerConnection = data.pLogConnection; + g_logger->updateLogLevel(); + return IBackend::create(); +} + SP IBackend::create() { if (g_backend) return nullptr; g_backend = SP(new CBackend()); - g_logger = SP(new CBackendLogger()); g_config = makeShared(); g_config->parse(); g_palette = CPalette::palette(); @@ -94,7 +94,7 @@ void CBackend::destroy() { } void CBackend::setLogFn(LogFn&& fn) { - m_logFn = std::move(fn); + g_logger->m_logFn = std::move(fn); } SP CBackend::getPalette() { diff --git a/src/core/Backend.hpp b/src/core/Backend.hpp index 6cbc758..2cb712a 100644 --- a/src/core/Backend.hpp +++ b/src/core/Backend.hpp @@ -2,6 +2,7 @@ #include #include +#include #include #include "../helpers/Env.hpp" @@ -48,8 +49,6 @@ namespace Hyprtoolkit { Hyprutils::Memory::CSharedPointer m_aqBackend; - LogFn m_logFn; - bool m_terminate = false; bool m_needsConfigReload = false; diff --git a/src/core/InternalBackend.cpp b/src/core/InternalBackend.cpp index 47859be..aed81d7 100644 --- a/src/core/InternalBackend.cpp +++ b/src/core/InternalBackend.cpp @@ -9,49 +9,3 @@ using namespace Hyprtoolkit; IBackend::~IBackend() = default; IBackend::IBackend() = default; - -void CBackendLogger::log(eLogLevel level, std::string str) { - if (Env::envEnabled("HT_QUIET")) - return; - - if (g_backend->m_logFn) { - g_backend->m_logFn(level, str); - return; - } - - std::string coloredStr = str; - //NOLINTBEGIN - switch (level) { - case HT_LOG_TRACE: - str = "[HT] TRACE: " + str; - coloredStr = str; - break; - case HT_LOG_DEBUG: - str = "[HT] DEBUG: " + str; - coloredStr = "\033[1;33m" + str + "\033[0m"; // yellow - break; - case HT_LOG_WARNING: - str = "[HT] WARN: " + str; - coloredStr = "\033[1;33m" + str + "\033[0m"; // yellow - break; - case HT_LOG_ERROR: - str = "[HT] ERR: " + str; - coloredStr = "\033[1;31m" + str + "\033[0m"; // red - break; - case HT_LOG_CRITICAL: - str = "[HT] CRIT: " + str; - coloredStr = "\033[1;35m" + str + "\033[0m"; // magenta - break; - default: break; - } - //NOLINTEND - - static bool LOG_NO_COLOR = Env::envEnabled("HT_NO_COLOR_LOGS"); - - if (LOG_NO_COLOR) - std::println("{}", coloredStr); - else - std::println("{}", str); - - std::fflush(stdout); -} \ No newline at end of file diff --git a/src/core/InternalBackend.hpp b/src/core/InternalBackend.hpp index 08d69e5..1de479e 100644 --- a/src/core/InternalBackend.hpp +++ b/src/core/InternalBackend.hpp @@ -6,6 +6,7 @@ #include "Backend.hpp" #include "../helpers/Env.hpp" +#include "Logger.hpp" namespace Hyprtoolkit { @@ -13,33 +14,7 @@ namespace Hyprtoolkit { class CConfigManager; class CSystemIconFactory; - class CBackendLogger { - public: - void log(eLogLevel level, std::string str); - - template - //NOLINTNEXTLINE - void log(eLogLevel level, std::format_string fmt, Args&&... args) { - static bool LOG_DISABLED = Env::envEnabled("HT_NO_LOGS"); - - if (LOG_DISABLED) - return; - - std::string logMsg = ""; - - // no need for try {} catch {} because std::format_string ensures that vformat never throw std::format_error - // because - // 1. any faulty format specifier that sucks will cause a compilation error. - // 2. and `std::bad_alloc` is catastrophic, (Almost any operation in stdlib could throw this.) - // 3. this is actually what std::format in stdlib does - logMsg += std::vformat(fmt.get(), std::make_format_args(args...)); - - log(level, logMsg); - } - }; - inline Hyprutils::Memory::CSharedPointer g_backend; - inline Hyprutils::Memory::CSharedPointer g_logger; inline Hyprutils::Memory::CSharedPointer g_asyncResourceGatherer; inline Hyprutils::Memory::CSharedPointer g_palette; inline Hyprutils::Memory::CSharedPointer g_config; diff --git a/src/core/Logger.cpp b/src/core/Logger.cpp new file mode 100644 index 0000000..f9387d9 --- /dev/null +++ b/src/core/Logger.cpp @@ -0,0 +1,43 @@ +#include "Logger.hpp" + +using namespace Hyprtoolkit; + +static Hyprutils::CLI::eLogLevel levelToHU(eLogLevel l) { + switch (l) { + case Hyprtoolkit::HT_LOG_DEBUG: return Hyprutils::CLI::LOG_DEBUG; + case Hyprtoolkit::HT_LOG_ERROR: return Hyprutils::CLI::LOG_ERR; + case Hyprtoolkit::HT_LOG_WARNING: return Hyprutils::CLI::LOG_WARN; + case Hyprtoolkit::HT_LOG_CRITICAL: return Hyprutils::CLI::LOG_CRIT; + case Hyprtoolkit::HT_LOG_TRACE: return Hyprutils::CLI::LOG_TRACE; + } + return Hyprutils::CLI::LOG_DEBUG; +} + +CLogger::CLogger() { + const auto IS_TRACE = Env::isTrace(); + m_logger.setLogLevel(IS_TRACE ? Hyprutils::CLI::LOG_TRACE : Hyprutils::CLI::LOG_DEBUG); +} + +void CLogger::updateLogLevel() { + const auto IS_TRACE = Env::isTrace(); + if (m_loggerConnection && IS_TRACE) + m_loggerConnection->setLogLevel(Hyprutils::CLI::LOG_TRACE); +} + +void CLogger::log(eLogLevel level, const std::string& str) { + static const bool IS_QUIET = Env::envEnabled("HT_QUIET"); + if (IS_QUIET) + return; + + if (m_logFn) { + m_logFn(level, str); + return; + } + + if (m_loggerConnection) { + m_loggerConnection->log(levelToHU(level), str); + return; + } + + m_logger.log(levelToHU(level), str); +} diff --git a/src/core/Logger.hpp b/src/core/Logger.hpp new file mode 100644 index 0000000..fba4fb7 --- /dev/null +++ b/src/core/Logger.hpp @@ -0,0 +1,48 @@ +#pragma once + +#include +#include + +#include +#include + +#include "../helpers/Env.hpp" + +namespace Hyprtoolkit { + class CLogger { + public: + CLogger(); + ~CLogger() = default; + + void log(eLogLevel level, const std::string& str); + + template + //NOLINTNEXTLINE + void log(eLogLevel level, std::format_string fmt, Args&&... args) { + static bool LOG_DISABLED = Env::envEnabled("HT_NO_LOGS"); + + if (LOG_DISABLED) + return; + + std::string logMsg = ""; + + // no need for try {} catch {} because std::format_string ensures that vformat never throw std::format_error + // because + // 1. any faulty format specifier that sucks will cause a compilation error. + // 2. and `std::bad_alloc` is catastrophic, (Almost any operation in stdlib could throw this.) + // 3. this is actually what std::format in stdlib does + logMsg += std::vformat(fmt.get(), std::make_format_args(args...)); + + log(level, logMsg); + } + + void updateLogLevel(); + + Hyprutils::CLI::CLogger m_logger; + IBackend::LogFn m_logFn; + Hyprutils::Memory::CSharedPointer m_loggerConnection; + Hyprutils::Memory::CSharedPointer m_aqLoggerConnection; + }; + + inline Hyprutils::Memory::CSharedPointer g_logger = Hyprutils::Memory::makeShared(); +}; \ No newline at end of file