Skip to content

Commit

Permalink
core: add --verify-config to verify the config with Hyprland
Browse files Browse the repository at this point in the history
fixes #9135
  • Loading branch information
vaxerski committed Jan 24, 2025
1 parent 80b2fd1 commit d8f79d7
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 25 deletions.
18 changes: 16 additions & 2 deletions src/Compositor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <cstring>
#include <filesystem>
#include <ranges>
#include <print>
#include <unordered_set>
#include "debug/HyprCtl.hpp"
#include "debug/CrashReporter.hpp"
Expand Down Expand Up @@ -162,7 +163,10 @@ void CCompositor::restoreNofile() {
Debug::log(ERR, "Failed restoring NOFILE limits");
}

CCompositor::CCompositor() : m_iHyprlandPID(getpid()) {
CCompositor::CCompositor(bool onlyConfig) : m_bOnlyConfigVerification(onlyConfig), m_iHyprlandPID(getpid()) {
if (onlyConfig)
return;

m_szHyprTempDataRoot = std::string{getenv("XDG_RUNTIME_DIR")} + "/hypr";

if (m_szHyprTempDataRoot.starts_with("/hypr")) {
Expand Down Expand Up @@ -226,7 +230,7 @@ CCompositor::CCompositor() : m_iHyprlandPID(getpid()) {
}

CCompositor::~CCompositor() {
if (!m_bIsShuttingDown)
if (!m_bIsShuttingDown && !m_bOnlyConfigVerification)
cleanup();
}

Expand Down Expand Up @@ -262,6 +266,16 @@ static bool filterGlobals(const wl_client* client, const wl_global* global, void
//
void CCompositor::initServer(std::string socketName, int socketFd) {

if (m_bOnlyConfigVerification) {
g_pHookSystem = makeUnique<CHookSystemManager>();
g_pKeybindManager = makeUnique<CKeybindManager>();
g_pAnimationManager = makeUnique<CHyprAnimationManager>();
g_pConfigManager = makeUnique<CConfigManager>();

std::println("\n\n======== Config parsing result:\n\n{}", g_pConfigManager->verify());
return;
}

m_sWLDisplay = wl_display_create();

wl_display_set_global_filter(m_sWLDisplay, ::filterGlobals, nullptr);
Expand Down
11 changes: 6 additions & 5 deletions src/Compositor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ enum eManagersInitStage : uint8_t {

class CCompositor {
public:
CCompositor();
CCompositor(bool onlyConfig = false);
~CCompositor();

wl_display* m_sWLDisplay;
Expand Down Expand Up @@ -71,10 +71,11 @@ class CCompositor {
bool m_bUnsafeState = false; // unsafe state is when there is no monitors.
bool m_bNextIsUnsafe = false;
PHLMONITORREF m_pUnsafeOutput; // fallback output for the unsafe state
bool m_bIsShuttingDown = false;
bool m_bFinalRequests = false;
bool m_bDesktopEnvSet = false;
bool m_bWantsXwayland = true;
bool m_bIsShuttingDown = false;
bool m_bFinalRequests = false;
bool m_bDesktopEnvSet = false;
bool m_bWantsXwayland = true;
bool m_bOnlyConfigVerification = false;

// ------------------------------------------------- //

Expand Down
30 changes: 23 additions & 7 deletions src/config/ConfigManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "../render/Renderer.hpp"
#include "../hyprerror/HyprError.hpp"
#include "../managers/input/InputManager.hpp"
#include "../managers/eventLoop/EventLoopManager.hpp"
#include "../managers/LayoutManager.hpp"
#include "../managers/EventManager.hpp"
#include "../debug/HyprNotificationOverlay.hpp"
Expand Down Expand Up @@ -730,15 +731,18 @@ CConfigManager::CConfigManager() {

resetHLConfig();

Debug::log(INFO,
"!!!!HEY YOU, YES YOU!!!!: further logs to stdout / logfile are disabled by default. BEFORE SENDING THIS LOG, ENABLE THEM. Use debug:disable_logs = false to do so: "
"https://wiki.hyprland.org/Configuring/Variables/#debug");
if (!g_pCompositor->m_bOnlyConfigVerification) {
Debug::log(
INFO,
"!!!!HEY YOU, YES YOU!!!!: further logs to stdout / logfile are disabled by default. BEFORE SENDING THIS LOG, ENABLE THEM. Use debug:disable_logs = false to do so: "
"https://wiki.hyprland.org/Configuring/Variables/#debug");
}

Debug::disableLogs = reinterpret_cast<int64_t* const*>(m_pConfig->getConfigValuePtr("debug:disable_logs")->getDataStaticPtr());
Debug::disableTime = reinterpret_cast<int64_t* const*>(m_pConfig->getConfigValuePtr("debug:disable_time")->getDataStaticPtr());

if (ERR.has_value())
g_pHyprError->queueCreate(ERR.value(), CHyprColor{1.0, 0.1, 0.1, 1.0});
if (g_pEventLoopManager && ERR.has_value())
g_pEventLoopManager->doLater([ERR] { g_pHyprError->queueCreate(ERR.value(), CHyprColor{1.0, 0.1, 0.1, 1.0}); });
}

std::optional<std::string> CConfigManager::generateConfig(std::string configPath) {
Expand Down Expand Up @@ -820,11 +824,23 @@ void CConfigManager::reload() {
EMIT_HOOK_EVENT("preConfigReload", nullptr);
setDefaultAnimationVars();
resetHLConfig();
configCurrentPath = getMainConfigPath();
const auto ERR = m_pConfig->parse();
configCurrentPath = getMainConfigPath();
const auto ERR = m_pConfig->parse();
m_bLastConfigVerificationWasSuccessful = !ERR.error;
postConfigReload(ERR);
}

std::string CConfigManager::verify() {
setDefaultAnimationVars();
resetHLConfig();
configCurrentPath = getMainConfigPath();
const auto ERR = m_pConfig->parse();
m_bLastConfigVerificationWasSuccessful = !ERR.error;
if (ERR.error)
return ERR.getError();
return "config ok";
}

void CConfigManager::setDefaultAnimationVars() {
m_AnimationTree.createNode("__internal_fadeCTM");
m_AnimationTree.createNode("global");
Expand Down
8 changes: 5 additions & 3 deletions src/config/ConfigManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ class CConfigManager {

void init();
void reload();
std::string verify();

int getDeviceInt(const std::string&, const std::string&, const std::string& fallback = "");
float getDeviceFloat(const std::string&, const std::string&, const std::string& fallback = "");
Expand Down Expand Up @@ -257,9 +258,10 @@ class CConfigManager {
{"scrollmouse", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.scrollMouse; }},
{"scrolltouchpad", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.scrollTouchpad; }}};

bool m_bWantsMonitorReload = false;
bool m_bNoMonitorReload = false;
bool isLaunchingExecOnce = false; // For exec-once to skip initial ws tracking
bool m_bWantsMonitorReload = false;
bool m_bNoMonitorReload = false;
bool isLaunchingExecOnce = false; // For exec-once to skip initial ws tracking
bool m_bLastConfigVerificationWasSuccessful = true;

private:
UP<Hyprlang::CConfig> m_pConfig;
Expand Down
17 changes: 12 additions & 5 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ static void help() {
--wayland-fd FD - Sets the Wayland socket fd (for Wayland socket handover)
--systeminfo - Prints system infos
--i-am-really-stupid - Omits root user privileges check (why would you do that?)
--verify-config - Do not run Hyprland, only print if the config has any errors
--version -v - Print this binary's version)");
}

Expand All @@ -49,7 +50,7 @@ int main(int argc, char** argv) {
std::string configPath;
std::string socketName;
int socketFd = -1;
bool ignoreSudo = false;
bool ignoreSudo = false, verifyConfig = false;

std::vector<std::string> args{argv + 1, argv + argc};

Expand Down Expand Up @@ -124,6 +125,9 @@ int main(int argc, char** argv) {
} else if (*it == "--systeminfo") {
std::println("{}", systemInfoRequest(eHyprCtlOutputFormat::FORMAT_NORMAL, ""));
return 0;
} else if (*it == "--verify-config") {
verifyConfig = true;
continue;
} else {
std::println(stderr, "[ ERROR ] Unknown option '{}' !", *it);
help();
Expand All @@ -138,9 +142,8 @@ int main(int argc, char** argv) {
" Hint: Use the --i-am-really-stupid flag to omit that check.");

return 1;
} else if (ignoreSudo && NInit::isSudo()) {
} else if (ignoreSudo && NInit::isSudo())
std::println("Superuser privileges check is omitted. I hope you know what you're doing.");
}

if (socketName.empty() ^ (socketFd == -1)) {
std::println(stderr,
Expand All @@ -150,12 +153,13 @@ int main(int argc, char** argv) {
return 1;
}

std::println("Welcome to Hyprland!");
if (!verifyConfig)
std::println("Welcome to Hyprland!");

// let's init the compositor.
// it initializes basic Wayland stuff in the constructor.
try {
g_pCompositor = makeUnique<CCompositor>();
g_pCompositor = makeUnique<CCompositor>(verifyConfig);
g_pCompositor->explicitConfigPath = configPath;
} catch (const std::exception& e) {
std::println(stderr, "Hyprland threw in ctor: {}\nCannot continue.", e.what());
Expand All @@ -164,6 +168,9 @@ int main(int argc, char** argv) {

g_pCompositor->initServer(socketName, socketFd);

if (verifyConfig)
return !g_pConfigManager->m_bLastConfigVerificationWasSuccessful;

if (!envEnabled("HYPRLAND_NO_RT"))
NInit::gainRealTime();

Expand Down
3 changes: 2 additions & 1 deletion src/managers/AnimationManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ static int wlTick(SP<CEventLoopTimer> self, void* data) {

CHyprAnimationManager::CHyprAnimationManager() {
m_pAnimationTimer = SP<CEventLoopTimer>(new CEventLoopTimer(std::chrono::microseconds(500), wlTick, nullptr));
g_pEventLoopManager->addTimer(m_pAnimationTimer);
if (g_pEventLoopManager) // null in --verify-config mode
g_pEventLoopManager->addTimer(m_pAnimationTimer);

addBezierWithName("linear", Vector2D(0.0, 0.0), Vector2D(1.0, 1.0));
}
Expand Down
7 changes: 5 additions & 2 deletions src/managers/KeybindManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,11 @@ CKeybindManager::CKeybindManager() {
},
nullptr);

g_pEventLoopManager->addTimer(m_pLongPressTimer);
g_pEventLoopManager->addTimer(m_pRepeatKeyTimer);
// null in --verify-config mode
if (g_pEventLoopManager) {
g_pEventLoopManager->addTimer(m_pLongPressTimer);
g_pEventLoopManager->addTimer(m_pRepeatKeyTimer);
}

static auto P = g_pHookSystem->hookDynamic("configReloaded", [this](void* hk, SCallbackInfo& info, std::any param) {
// clear cuz realloc'd
Expand Down

0 comments on commit d8f79d7

Please sign in to comment.