From 4c796683c05a0eaccc14aae8875f06972f9f3c5e Mon Sep 17 00:00:00 2001 From: zakk4223 Date: Wed, 20 Mar 2024 21:55:13 -0400 Subject: [PATCH] config: Config error limit/hyprctl (#5165) * Add error_limit to limit the number of config error messages shown in notification * Add configerrors hyprctl command * Formatting * Formatting for not my code * Use CVarList, add escapeJSONStrings * Add indication there are more undisplayed errors * Restore suppress_errors; move getErrors() to ConfigManager * Formatting, wtf * Format --- src/config/ConfigManager.cpp | 11 +++++++++++ src/config/ConfigManager.hpp | 2 ++ src/debug/HyprCtl.cpp | 25 +++++++++++++++++++++++++ src/hyprerror/HyprError.cpp | 19 ++++++++++++++++--- 4 files changed, 54 insertions(+), 3 deletions(-) diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index d671ffb0..7925da64 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -372,6 +372,7 @@ CConfigManager::CConfigManager() { m_pConfig->addConfigValue("debug:damage_tracking", {(Hyprlang::INT)DAMAGE_TRACKING_FULL}); m_pConfig->addConfigValue("debug:manual_crash", Hyprlang::INT{0}); m_pConfig->addConfigValue("debug:suppress_errors", Hyprlang::INT{0}); + m_pConfig->addConfigValue("debug:error_limit", Hyprlang::INT{5}); m_pConfig->addConfigValue("debug:watchdog_timeout", Hyprlang::INT{5}); m_pConfig->addConfigValue("debug:disable_scale_checks", Hyprlang::INT{0}); @@ -609,6 +610,10 @@ std::string CConfigManager::getMainConfigPath() { return getConfigDir() + "/hypr/" + (ISDEBUG ? "hyprlandd.conf" : "hyprland.conf"); } +std::string CConfigManager::getErrors() { + return m_szConfigErrors; +} + void CConfigManager::reload() { EMIT_HOOK_EVENT("preConfigReload", nullptr); setDefaultAnimationVars(); @@ -740,6 +745,12 @@ void CConfigManager::postConfigReload(const Hyprlang::CParseResult& result) { g_pHyprOpenGL->m_bReloadScreenShader = true; // parseError will be displayed next frame + + if (result.error) + m_szConfigErrors = result.getError(); + else + m_szConfigErrors = ""; + if (result.error && !std::any_cast(m_pConfig->getConfigValue("debug:suppress_errors"))) g_pHyprError->queueCreate(result.getError(), CColor(1.0, 50.0 / 255.0, 50.0 / 255.0, 1.0)); else if (std::any_cast(m_pConfig->getConfigValue("autogenerated")) == 1) diff --git a/src/config/ConfigManager.hpp b/src/config/ConfigManager.hpp index a00aaec9..9fd1e097 100644 --- a/src/config/ConfigManager.hpp +++ b/src/config/ConfigManager.hpp @@ -142,6 +142,7 @@ class CConfigManager { void addExecRule(const SExecRequestedRule&); void handlePluginLoads(); + std::string getErrors(); // keywords std::optional handleRawExec(const std::string&, const std::string&); @@ -193,6 +194,7 @@ class CConfigManager { std::deque firstExecRequests; std::vector> m_vFailedPluginConfigValues; // for plugin values of unloaded plugins + std::string m_szConfigErrors = ""; // internal methods void setAnimForChildren(SAnimationPropertyConfig* const); diff --git a/src/debug/HyprCtl.cpp b/src/debug/HyprCtl.cpp index f13843a3..211b532e 100644 --- a/src/debug/HyprCtl.cpp +++ b/src/debug/HyprCtl.cpp @@ -17,6 +17,7 @@ #include "../config/ConfigValue.hpp" #include "../managers/CursorManager.hpp" +#include "../hyprerror/HyprError.hpp" static void trimTrailingComma(std::string& str) { if (!str.empty() && str.back() == ',') @@ -497,6 +498,29 @@ std::string layoutsRequest(eHyprCtlOutputFormat format, std::string request) { return result; } +std::string configErrorsRequest(eHyprCtlOutputFormat format, std::string request) { + std::string result = ""; + std::string currErrors = g_pConfigManager->getErrors(); + CVarList errLines(currErrors, 0, '\n'); + if (format == eHyprCtlOutputFormat::FORMAT_JSON) { + result += "["; + for (auto line : errLines) { + result += std::format( + R"#( + "{}",)#", + + escapeJSONStrings(line)); + } + trimTrailingComma(result); + result += "\n]\n"; + } else { + for (auto line : errLines) { + result += std::format("{}\n", line); + } + } + return result; +} + std::string devicesRequest(eHyprCtlOutputFormat format, std::string request) { std::string result = ""; @@ -1531,6 +1555,7 @@ CHyprCtl::CHyprCtl() { registerCommand(SHyprCtlCommand{"animations", true, animationsRequest}); registerCommand(SHyprCtlCommand{"rollinglog", true, rollinglogRequest}); registerCommand(SHyprCtlCommand{"layouts", true, layoutsRequest}); + registerCommand(SHyprCtlCommand{"configerrors", true, configErrorsRequest}); registerCommand(SHyprCtlCommand{"monitors", false, monitorsRequest}); registerCommand(SHyprCtlCommand{"reload", false, reloadRequest}); diff --git a/src/hyprerror/HyprError.cpp b/src/hyprerror/HyprError.cpp index 97a18e8c..a7636b1c 100644 --- a/src/hyprerror/HyprError.cpp +++ b/src/hyprerror/HyprError.cpp @@ -1,5 +1,6 @@ #include "HyprError.hpp" #include "../Compositor.hpp" +#include "../config/ConfigValue.hpp" CHyprError::CHyprError() { m_fFadeOpacity.create(AVARTYPE_FLOAT, g_pConfigManager->getAnimationPropertyConfig("fadeIn"), nullptr, AVARDAMAGE_NONE); @@ -58,6 +59,10 @@ void CHyprError::createQueued() { cairo_restore(CAIRO); const auto LINECOUNT = 1 + std::count(m_szQueued.begin(), m_szQueued.end(), '\n'); + static auto LINELIMIT = CConfigValue("debug:error_limit"); + + const auto VISLINECOUNT = std::min(LINECOUNT, *LINELIMIT); + const auto EXTRALINES = (VISLINECOUNT < LINECOUNT) ? 1 : 0; const double DEGREES = M_PI / 180.0; @@ -66,7 +71,7 @@ void CHyprError::createQueued() { const double X = PAD; const double Y = PAD; const double WIDTH = PMONITOR->vecPixelSize.x - PAD * 2; - const double HEIGHT = (FONTSIZE + 2 * (FONTSIZE / 10.0)) * LINECOUNT + 3; + const double HEIGHT = (FONTSIZE + 2 * (FONTSIZE / 10.0)) * (VISLINECOUNT + EXTRALINES) + 3; const double RADIUS = PAD > HEIGHT / 2 ? HEIGHT / 2 - 1 : PAD; m_bDamageBox = {0, 0, (int)PMONITOR->vecPixelSize.x, (int)HEIGHT + (int)PAD * 2}; @@ -91,8 +96,9 @@ void CHyprError::createQueued() { cairo_set_font_size(CAIRO, FONTSIZE); cairo_set_source_rgba(CAIRO, textColor.r, textColor.g, textColor.b, textColor.a); - float yoffset = FONTSIZE; - while (m_szQueued != "") { + float yoffset = FONTSIZE; + int renderedcnt = 0; + while (m_szQueued != "" && renderedcnt < VISLINECOUNT) { std::string current = m_szQueued.substr(0, m_szQueued.find('\n')); if (const auto NEWLPOS = m_szQueued.find('\n'); NEWLPOS != std::string::npos) m_szQueued = m_szQueued.substr(NEWLPOS + 1); @@ -101,7 +107,14 @@ void CHyprError::createQueued() { cairo_move_to(CAIRO, PAD + 1 + RADIUS, yoffset + PAD + 1); cairo_show_text(CAIRO, current.c_str()); yoffset += FONTSIZE + (FONTSIZE / 10.f); + renderedcnt++; } + if (VISLINECOUNT < LINECOUNT) { + std::string moreString = std::format("({} more...)", LINECOUNT - VISLINECOUNT); + cairo_move_to(CAIRO, PAD + 1 + RADIUS, yoffset + PAD + 1); + cairo_show_text(CAIRO, moreString.c_str()); + } + m_szQueued = ""; cairo_surface_flush(CAIROSURFACE);