From 8726a7363eb9213235e6e23657668e0daac39a5b Mon Sep 17 00:00:00 2001 From: Vaxry <43317083+vaxerski@users.noreply.github.com> Date: Fri, 20 Mar 2026 13:52:37 -0400 Subject: config: cleanup the entire config infrastructure (#13785) Massively refactors the config infrastructure, sorely needed and will be req'd for the lua stuff --- src/config/ConfigManager.cpp | 3258 +----------------------------------------- 1 file changed, 30 insertions(+), 3228 deletions(-) (limited to 'src/config/ConfigManager.cpp') diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 93edfe23..0c106629 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -1,3250 +1,52 @@ -#include - #include "ConfigManager.hpp" -#include "ConfigWatcher.hpp" -#include "../managers/KeybindManager.hpp" -#include "../Compositor.hpp" - -#include "../render/decorations/CHyprGroupBarDecoration.hpp" -#include "config/ConfigDataValues.hpp" -#include "config/ConfigValue.hpp" -#include "../protocols/LayerShell.hpp" -#include "../xwayland/XWayland.hpp" -#include "../protocols/OutputManagement.hpp" -#include "../managers/animation/AnimationManager.hpp" -#include "../desktop/view/LayerSurface.hpp" -#include "../desktop/rule/Engine.hpp" -#include "../desktop/rule/windowRule/WindowRule.hpp" -#include "../desktop/rule/layerRule/LayerRule.hpp" -#include "../debug/HyprCtl.hpp" -#include "../desktop/state/FocusState.hpp" -#include "../layout/space/Space.hpp" -#include "../layout/supplementary/WorkspaceAlgoMatcher.hpp" -#include "defaultConfig.hpp" - -#include "../render/Renderer.hpp" -#include "../hyprerror/HyprError.hpp" -#include "../managers/input/InputManager.hpp" -#include "../managers/eventLoop/EventLoopManager.hpp" -#include "../managers/EventManager.hpp" -#include "../managers/permissions/DynamicPermissionManager.hpp" -#include "../debug/HyprNotificationOverlay.hpp" -#include "../plugins/PluginSystem.hpp" - -#include "../managers/input/trackpad/TrackpadGestures.hpp" -#include "../managers/input/trackpad/gestures/DispatcherGesture.hpp" -#include "../managers/input/trackpad/gestures/WorkspaceSwipeGesture.hpp" -#include "../managers/input/trackpad/gestures/ResizeGesture.hpp" -#include "../managers/input/trackpad/gestures/MoveGesture.hpp" -#include "../managers/input/trackpad/gestures/SpecialWorkspaceGesture.hpp" -#include "../managers/input/trackpad/gestures/CloseGesture.hpp" -#include "../managers/input/trackpad/gestures/FloatGesture.hpp" -#include "../managers/input/trackpad/gestures/FullscreenGesture.hpp" -#include "../managers/input/trackpad/gestures/CursorZoomGesture.hpp" +#include "supplementary/jeremy/Jeremy.hpp" +#include "legacy/ConfigManager.hpp" +#include "../debug/log/Logger.hpp" -#include "../event/EventBus.hpp" - -#include "../protocols/types/ContentType.hpp" -#include -#include #include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include #include -#include -using namespace Hyprutils::String; -using namespace Hyprutils::Animation; -using enum NContentType::eContentType; - -//NOLINTNEXTLINE -extern "C" char** environ; - -#include "ConfigDescriptions.hpp" - -static Hyprlang::CParseResult configHandleGradientSet(const char* VALUE, void** data) { - std::string V = VALUE; - - if (!*data) - *data = new CGradientValueData(); - - const auto DATA = sc(*data); - - CVarList2 varlist(std::string(V), 0, ' '); - DATA->m_colors.clear(); - - std::string parseError = ""; - - for (auto const& var : varlist) { - if (var.find("deg") != std::string::npos) { - // last arg - try { - DATA->m_angle = std::stoi(std::string(var.substr(0, var.find("deg")))) * (PI / 180.0); // radians - } catch (...) { - Log::logger->log(Log::WARN, "Error parsing gradient {}", V); - parseError = "Error parsing gradient " + V; - } - - break; - } - - if (DATA->m_colors.size() >= 10) { - Log::logger->log(Log::WARN, "Error parsing gradient {}: max colors is 10.", V); - parseError = "Error parsing gradient " + V + ": max colors is 10."; - break; - } - - try { - const auto COL = configStringToInt(std::string(var)); - if (!COL) - throw std::runtime_error(std::format("failed to parse {} as a color", var)); - DATA->m_colors.emplace_back(COL.value()); - } catch (std::exception& e) { - Log::logger->log(Log::WARN, "Error parsing gradient {}", V); - parseError = "Error parsing gradient " + V + ": " + e.what(); - } - } - - if (DATA->m_colors.empty()) { - Log::logger->log(Log::WARN, "Error parsing gradient {}", V); - if (parseError.empty()) - parseError = "Error parsing gradient " + V + ": No colors?"; - - DATA->m_colors.emplace_back(0); // transparent - } - - DATA->updateColorsOk(); - - Hyprlang::CParseResult result; - if (!parseError.empty()) - result.setError(parseError.c_str()); - - return result; -} - -static void configHandleGradientDestroy(void** data) { - if (*data) - delete sc(*data); -} - -static Hyprlang::CParseResult configHandleGapSet(const char* VALUE, void** data) { - std::string V = VALUE; - - if (!*data) - *data = new CCssGapData(); - - const auto DATA = sc(*data); - CVarList2 varlist((std::string(V))); - Hyprlang::CParseResult result; - - try { - DATA->parseGapData(varlist); - } catch (...) { - std::string parseError = "Error parsing gaps " + V; - result.setError(parseError.c_str()); - } - - return result; -} - -static void configHandleGapDestroy(void** data) { - if (*data) - delete sc(*data); -} - -static Hyprlang::CParseResult configHandleFontWeightSet(const char* VALUE, void** data) { - if (!*data) - *data = new CFontWeightConfigValueData(); - - const auto DATA = sc(*data); - Hyprlang::CParseResult result; - - try { - DATA->parseWeight(VALUE); - } catch (...) { - std::string parseError = std::format("{} is not a valid font weight", VALUE); - result.setError(parseError.c_str()); - } - - return result; -} - -static void configHandleFontWeightDestroy(void** data) { - if (*data) - delete sc(*data); -} - -static Hyprlang::CParseResult handleExec(const char* c, const char* v) { - const std::string VALUE = v; - const std::string COMMAND = c; - - const auto RESULT = g_pConfigManager->handleExec(COMMAND, VALUE); - - Hyprlang::CParseResult result; - if (RESULT.has_value()) - result.setError(RESULT.value().c_str()); - return result; -} - -static Hyprlang::CParseResult handleRawExec(const char* c, const char* v) { - const std::string VALUE = v; - const std::string COMMAND = c; - - const auto RESULT = g_pConfigManager->handleRawExec(COMMAND, VALUE); - - Hyprlang::CParseResult result; - if (RESULT.has_value()) - result.setError(RESULT.value().c_str()); - return result; -} - -static Hyprlang::CParseResult handleExecOnce(const char* c, const char* v) { - const std::string VALUE = v; - const std::string COMMAND = c; - - const auto RESULT = g_pConfigManager->handleExecOnce(COMMAND, VALUE); - - Hyprlang::CParseResult result; - if (RESULT.has_value()) - result.setError(RESULT.value().c_str()); - return result; -} - -static Hyprlang::CParseResult handleExecRawOnce(const char* c, const char* v) { - const std::string VALUE = v; - const std::string COMMAND = c; - - const auto RESULT = g_pConfigManager->handleExecRawOnce(COMMAND, VALUE); - - Hyprlang::CParseResult result; - if (RESULT.has_value()) - result.setError(RESULT.value().c_str()); - return result; -} - -static Hyprlang::CParseResult handleExecShutdown(const char* c, const char* v) { - const std::string VALUE = v; - const std::string COMMAND = c; - - const auto RESULT = g_pConfigManager->handleExecShutdown(COMMAND, VALUE); - - Hyprlang::CParseResult result; - if (RESULT.has_value()) - result.setError(RESULT.value().c_str()); - return result; -} - -static Hyprlang::CParseResult handleMonitor(const char* c, const char* v) { - const std::string VALUE = v; - const std::string COMMAND = c; - - const auto RESULT = g_pConfigManager->handleMonitor(COMMAND, VALUE); - - Hyprlang::CParseResult result; - if (RESULT.has_value()) - result.setError(RESULT.value().c_str()); - return result; -} - -static Hyprlang::CParseResult handleBezier(const char* c, const char* v) { - const std::string VALUE = v; - const std::string COMMAND = c; - - const auto RESULT = g_pConfigManager->handleBezier(COMMAND, VALUE); - - Hyprlang::CParseResult result; - if (RESULT.has_value()) - result.setError(RESULT.value().c_str()); - return result; -} - -static Hyprlang::CParseResult handleAnimation(const char* c, const char* v) { - const std::string VALUE = v; - const std::string COMMAND = c; - - const auto RESULT = g_pConfigManager->handleAnimation(COMMAND, VALUE); - - Hyprlang::CParseResult result; - if (RESULT.has_value()) - result.setError(RESULT.value().c_str()); - return result; -} - -static Hyprlang::CParseResult handleBind(const char* c, const char* v) { - const std::string VALUE = v; - const std::string COMMAND = c; - - const auto RESULT = g_pConfigManager->handleBind(COMMAND, VALUE); - - Hyprlang::CParseResult result; - if (RESULT.has_value()) - result.setError(RESULT.value().c_str()); - return result; -} - -static Hyprlang::CParseResult handleUnbind(const char* c, const char* v) { - const std::string VALUE = v; - const std::string COMMAND = c; - - const auto RESULT = g_pConfigManager->handleUnbind(COMMAND, VALUE); - - Hyprlang::CParseResult result; - if (RESULT.has_value()) - result.setError(RESULT.value().c_str()); - return result; -} - -static Hyprlang::CParseResult handleWorkspaceRules(const char* c, const char* v) { - const std::string VALUE = v; - const std::string COMMAND = c; - - const auto RESULT = g_pConfigManager->handleWorkspaceRules(COMMAND, VALUE); - - Hyprlang::CParseResult result; - if (RESULT.has_value()) - result.setError(RESULT.value().c_str()); - return result; -} - -static Hyprlang::CParseResult handleSubmap(const char* c, const char* v) { - const std::string VALUE = v; - const std::string COMMAND = c; - - const auto RESULT = g_pConfigManager->handleSubmap(COMMAND, VALUE); - - Hyprlang::CParseResult result; - if (RESULT.has_value()) - result.setError(RESULT.value().c_str()); - return result; -} - -static Hyprlang::CParseResult handleSource(const char* c, const char* v) { - const std::string VALUE = v; - const std::string COMMAND = c; - - const auto RESULT = g_pConfigManager->handleSource(COMMAND, VALUE); - - Hyprlang::CParseResult result; - if (RESULT.has_value()) - result.setError(RESULT.value().c_str()); - return result; -} - -static Hyprlang::CParseResult handleEnv(const char* c, const char* v) { - const std::string VALUE = v; - const std::string COMMAND = c; - - const auto RESULT = g_pConfigManager->handleEnv(COMMAND, VALUE); - - Hyprlang::CParseResult result; - if (RESULT.has_value()) - result.setError(RESULT.value().c_str()); - return result; -} - -static Hyprlang::CParseResult handlePlugin(const char* c, const char* v) { - const std::string VALUE = v; - const std::string COMMAND = c; - - const auto RESULT = g_pConfigManager->handlePlugin(COMMAND, VALUE); - - Hyprlang::CParseResult result; - if (RESULT.has_value()) - result.setError(RESULT.value().c_str()); - return result; -} - -static Hyprlang::CParseResult handlePermission(const char* c, const char* v) { - const std::string VALUE = v; - const std::string COMMAND = c; - - const auto RESULT = g_pConfigManager->handlePermission(COMMAND, VALUE); - - Hyprlang::CParseResult result; - if (RESULT.has_value()) - result.setError(RESULT.value().c_str()); - return result; -} - -static Hyprlang::CParseResult handleGesture(const char* c, const char* v) { - const std::string VALUE = v; - const std::string COMMAND = c; - - const auto RESULT = g_pConfigManager->handleGesture(COMMAND, VALUE); - - Hyprlang::CParseResult result; - if (RESULT.has_value()) - result.setError(RESULT.value().c_str()); - return result; -} - -static Hyprlang::CParseResult handleWindowrule(const char* c, const char* v) { - const std::string VALUE = v; - const std::string COMMAND = c; - - const auto RESULT = g_pConfigManager->handleWindowrule(COMMAND, VALUE); - - Hyprlang::CParseResult result; - if (RESULT.has_value()) - result.setError(RESULT.value().c_str()); - return result; -} - -static Hyprlang::CParseResult handleWindowrulev2(const char* c, const char* v) { - Hyprlang::CParseResult res; - res.setError("windowrulev2 is deprecated. Correct syntax can be found on the wiki."); - return res; -} - -static Hyprlang::CParseResult handleLayerrule(const char* c, const char* v) { - const std::string VALUE = v; - const std::string COMMAND = c; - - const auto RESULT = g_pConfigManager->handleLayerrule(COMMAND, VALUE); - - Hyprlang::CParseResult result; - if (RESULT.has_value()) - result.setError(RESULT.value().c_str()); - return result; -} - -static Hyprlang::CParseResult handleLayerrulev2(const char* c, const char* v) { - Hyprlang::CParseResult res; - res.setError("layerrulev2 doesn't exist. Correct syntax can be found on the wiki."); - return res; -} - -void CConfigManager::registerConfigVar(const char* name, const Hyprlang::INT& val) { - m_configValueNumber++; - m_config->addConfigValue(name, val); -} - -void CConfigManager::registerConfigVar(const char* name, const Hyprlang::FLOAT& val) { - m_configValueNumber++; - m_config->addConfigValue(name, val); -} - -void CConfigManager::registerConfigVar(const char* name, const Hyprlang::VEC2& val) { - m_configValueNumber++; - m_config->addConfigValue(name, val); -} - -void CConfigManager::registerConfigVar(const char* name, const Hyprlang::STRING& val) { - m_configValueNumber++; - m_config->addConfigValue(name, val); -} - -void CConfigManager::registerConfigVar(const char* name, Hyprlang::CUSTOMTYPE&& val) { - m_configValueNumber++; - m_config->addConfigValue(name, std::move(val)); -} - -CConfigManager::CConfigManager() { - const auto ERR = verifyConfigExists(); - - m_configPaths.emplace_back(getMainConfigPath()); - m_config = makeUnique(m_configPaths.begin()->c_str(), Hyprlang::SConfigOptions{.throwAllErrors = true, .allowMissingConfig = true}); - - registerConfigVar("general:border_size", Hyprlang::INT{1}); - registerConfigVar("general:gaps_in", Hyprlang::CConfigCustomValueType{configHandleGapSet, configHandleGapDestroy, "5"}); - registerConfigVar("general:gaps_out", Hyprlang::CConfigCustomValueType{configHandleGapSet, configHandleGapDestroy, "20"}); - registerConfigVar("general:float_gaps", Hyprlang::CConfigCustomValueType{configHandleGapSet, configHandleGapDestroy, "0"}); - registerConfigVar("general:gaps_workspaces", Hyprlang::INT{0}); - registerConfigVar("general:no_focus_fallback", Hyprlang::INT{0}); - registerConfigVar("general:resize_on_border", Hyprlang::INT{0}); - registerConfigVar("general:extend_border_grab_area", Hyprlang::INT{15}); - registerConfigVar("general:hover_icon_on_border", Hyprlang::INT{1}); - registerConfigVar("general:layout", {"dwindle"}); - registerConfigVar("general:allow_tearing", Hyprlang::INT{0}); - registerConfigVar("general:resize_corner", Hyprlang::INT{0}); - registerConfigVar("general:snap:enabled", Hyprlang::INT{0}); - registerConfigVar("general:snap:window_gap", Hyprlang::INT{10}); - registerConfigVar("general:snap:monitor_gap", Hyprlang::INT{10}); - registerConfigVar("general:snap:border_overlap", Hyprlang::INT{0}); - registerConfigVar("general:snap:respect_gaps", Hyprlang::INT{0}); - registerConfigVar("general:col.active_border", Hyprlang::CConfigCustomValueType{&configHandleGradientSet, configHandleGradientDestroy, "0xffffffff"}); - registerConfigVar("general:col.inactive_border", Hyprlang::CConfigCustomValueType{&configHandleGradientSet, configHandleGradientDestroy, "0xff444444"}); - registerConfigVar("general:col.nogroup_border", Hyprlang::CConfigCustomValueType{&configHandleGradientSet, configHandleGradientDestroy, "0xffffaaff"}); - registerConfigVar("general:col.nogroup_border_active", Hyprlang::CConfigCustomValueType{&configHandleGradientSet, configHandleGradientDestroy, "0xffff00ff"}); - registerConfigVar("general:modal_parent_blocking", Hyprlang::INT{1}); - registerConfigVar("general:locale", {""}); - - registerConfigVar("misc:disable_hyprland_logo", Hyprlang::INT{0}); - registerConfigVar("misc:disable_splash_rendering", Hyprlang::INT{0}); - registerConfigVar("misc:col.splash", Hyprlang::INT{0x55ffffff}); - registerConfigVar("misc:splash_font_family", {STRVAL_EMPTY}); - registerConfigVar("misc:font_family", {"Sans"}); - registerConfigVar("misc:force_default_wallpaper", Hyprlang::INT{-1}); - registerConfigVar("misc:vfr", Hyprlang::INT{1}); - registerConfigVar("misc:vrr", Hyprlang::INT{0}); - registerConfigVar("misc:mouse_move_enables_dpms", Hyprlang::INT{0}); - registerConfigVar("misc:key_press_enables_dpms", Hyprlang::INT{0}); - registerConfigVar("misc:name_vk_after_proc", Hyprlang::INT{1}); - registerConfigVar("misc:always_follow_on_dnd", Hyprlang::INT{1}); - registerConfigVar("misc:layers_hog_keyboard_focus", Hyprlang::INT{1}); - registerConfigVar("misc:animate_manual_resizes", Hyprlang::INT{0}); - registerConfigVar("misc:animate_mouse_windowdragging", Hyprlang::INT{0}); - registerConfigVar("misc:disable_autoreload", Hyprlang::INT{0}); - registerConfigVar("misc:enable_swallow", Hyprlang::INT{0}); - registerConfigVar("misc:swallow_regex", {STRVAL_EMPTY}); - registerConfigVar("misc:swallow_exception_regex", {STRVAL_EMPTY}); - registerConfigVar("misc:focus_on_activate", Hyprlang::INT{0}); - registerConfigVar("misc:mouse_move_focuses_monitor", Hyprlang::INT{1}); - registerConfigVar("misc:allow_session_lock_restore", Hyprlang::INT{0}); - registerConfigVar("misc:session_lock_xray", Hyprlang::INT{0}); - registerConfigVar("misc:close_special_on_empty", Hyprlang::INT{1}); - registerConfigVar("misc:background_color", Hyprlang::INT{0xff111111}); - registerConfigVar("misc:on_focus_under_fullscreen", Hyprlang::INT{2}); - registerConfigVar("misc:exit_window_retains_fullscreen", Hyprlang::INT{0}); - registerConfigVar("misc:initial_workspace_tracking", Hyprlang::INT{1}); - registerConfigVar("misc:middle_click_paste", Hyprlang::INT{1}); - registerConfigVar("misc:render_unfocused_fps", Hyprlang::INT{15}); - registerConfigVar("misc:disable_xdg_env_checks", Hyprlang::INT{0}); - registerConfigVar("misc:disable_hyprland_guiutils_check", Hyprlang::INT{0}); - registerConfigVar("misc:disable_watchdog_warning", Hyprlang::INT{0}); - registerConfigVar("misc:lockdead_screen_delay", Hyprlang::INT{1000}); - registerConfigVar("misc:enable_anr_dialog", Hyprlang::INT{1}); - registerConfigVar("misc:anr_missed_pings", Hyprlang::INT{5}); - registerConfigVar("misc:screencopy_force_8b", Hyprlang::INT{1}); - registerConfigVar("misc:disable_scale_notification", Hyprlang::INT{0}); - registerConfigVar("misc:size_limits_tiled", Hyprlang::INT{0}); - - registerConfigVar("group:insert_after_current", Hyprlang::INT{1}); - registerConfigVar("group:focus_removed_window", Hyprlang::INT{1}); - registerConfigVar("group:merge_groups_on_drag", Hyprlang::INT{1}); - registerConfigVar("group:merge_groups_on_groupbar", Hyprlang::INT{1}); - registerConfigVar("group:merge_floated_into_tiled_on_groupbar", Hyprlang::INT{0}); - registerConfigVar("group:auto_group", Hyprlang::INT{1}); - registerConfigVar("group:drag_into_group", Hyprlang::INT{1}); - registerConfigVar("group:group_on_movetoworkspace", Hyprlang::INT{0}); - registerConfigVar("group:groupbar:enabled", Hyprlang::INT{1}); - registerConfigVar("group:groupbar:font_family", {STRVAL_EMPTY}); - registerConfigVar("group:groupbar:font_weight_active", Hyprlang::CConfigCustomValueType{&configHandleFontWeightSet, configHandleFontWeightDestroy, "normal"}); - registerConfigVar("group:groupbar:font_weight_inactive", Hyprlang::CConfigCustomValueType{&configHandleFontWeightSet, configHandleFontWeightDestroy, "normal"}); - registerConfigVar("group:groupbar:font_size", Hyprlang::INT{8}); - registerConfigVar("group:groupbar:gradients", Hyprlang::INT{0}); - registerConfigVar("group:groupbar:height", Hyprlang::INT{14}); - registerConfigVar("group:groupbar:indicator_gap", Hyprlang::INT{0}); - registerConfigVar("group:groupbar:indicator_height", Hyprlang::INT{3}); - registerConfigVar("group:groupbar:priority", Hyprlang::INT{3}); - registerConfigVar("group:groupbar:render_titles", Hyprlang::INT{1}); - registerConfigVar("group:groupbar:scrolling", Hyprlang::INT{1}); - registerConfigVar("group:groupbar:text_color", Hyprlang::INT{0xffffffff}); - registerConfigVar("group:groupbar:text_color_inactive", Hyprlang::INT{-1}); - registerConfigVar("group:groupbar:text_color_locked_active", Hyprlang::INT{-1}); - registerConfigVar("group:groupbar:text_color_locked_inactive", Hyprlang::INT{-1}); - registerConfigVar("group:groupbar:stacked", Hyprlang::INT{0}); - registerConfigVar("group:groupbar:rounding", Hyprlang::INT{1}); - registerConfigVar("group:groupbar:rounding_power", {2.F}); - registerConfigVar("group:groupbar:gradient_rounding", Hyprlang::INT{2}); - registerConfigVar("group:groupbar:gradient_rounding_power", {2.F}); - registerConfigVar("group:groupbar:round_only_edges", Hyprlang::INT{1}); - registerConfigVar("group:groupbar:gradient_round_only_edges", Hyprlang::INT{1}); - registerConfigVar("group:groupbar:gaps_out", Hyprlang::INT{2}); - registerConfigVar("group:groupbar:gaps_in", Hyprlang::INT{2}); - registerConfigVar("group:groupbar:keep_upper_gap", Hyprlang::INT{1}); - registerConfigVar("group:groupbar:text_offset", Hyprlang::INT{0}); - registerConfigVar("group:groupbar:text_padding", Hyprlang::INT{0}); - registerConfigVar("group:groupbar:blur", Hyprlang::INT{0}); - - registerConfigVar("debug:log_damage", Hyprlang::INT{0}); - registerConfigVar("debug:overlay", Hyprlang::INT{0}); - registerConfigVar("debug:damage_blink", Hyprlang::INT{0}); - registerConfigVar("debug:pass", Hyprlang::INT{0}); - registerConfigVar("debug:gl_debugging", Hyprlang::INT{0}); - registerConfigVar("debug:disable_logs", Hyprlang::INT{1}); - registerConfigVar("debug:disable_time", Hyprlang::INT{1}); - registerConfigVar("debug:enable_stdout_logs", Hyprlang::INT{0}); - registerConfigVar("debug:damage_tracking", {sc(DAMAGE_TRACKING_FULL)}); - registerConfigVar("debug:manual_crash", Hyprlang::INT{0}); - registerConfigVar("debug:suppress_errors", Hyprlang::INT{0}); - registerConfigVar("debug:error_limit", Hyprlang::INT{5}); - registerConfigVar("debug:error_position", Hyprlang::INT{0}); - registerConfigVar("debug:disable_scale_checks", Hyprlang::INT{0}); - registerConfigVar("debug:colored_stdout_logs", Hyprlang::INT{1}); - registerConfigVar("debug:full_cm_proto", Hyprlang::INT{0}); - registerConfigVar("debug:ds_handle_same_buffer", Hyprlang::INT{1}); - registerConfigVar("debug:ds_handle_same_buffer_fifo", Hyprlang::INT{1}); - registerConfigVar("debug:fifo_pending_workaround", Hyprlang::INT{0}); - registerConfigVar("debug:render_solitary_wo_damage", Hyprlang::INT{0}); - - registerConfigVar("decoration:rounding", Hyprlang::INT{0}); - registerConfigVar("decoration:rounding_power", {2.F}); - registerConfigVar("decoration:blur:enabled", Hyprlang::INT{1}); - registerConfigVar("decoration:blur:size", Hyprlang::INT{8}); - registerConfigVar("decoration:blur:passes", Hyprlang::INT{1}); - registerConfigVar("decoration:blur:ignore_opacity", Hyprlang::INT{1}); - registerConfigVar("decoration:blur:new_optimizations", Hyprlang::INT{1}); - registerConfigVar("decoration:blur:xray", Hyprlang::INT{0}); - registerConfigVar("decoration:blur:contrast", {0.8916F}); - registerConfigVar("decoration:blur:brightness", {1.0F}); - registerConfigVar("decoration:blur:vibrancy", {0.1696F}); - registerConfigVar("decoration:blur:vibrancy_darkness", {0.0F}); - registerConfigVar("decoration:blur:noise", {0.0117F}); - registerConfigVar("decoration:blur:special", Hyprlang::INT{0}); - registerConfigVar("decoration:blur:popups", Hyprlang::INT{0}); - registerConfigVar("decoration:blur:popups_ignorealpha", {0.2F}); - registerConfigVar("decoration:blur:input_methods", Hyprlang::INT{0}); - registerConfigVar("decoration:blur:input_methods_ignorealpha", {0.2F}); - registerConfigVar("decoration:active_opacity", {1.F}); - registerConfigVar("decoration:inactive_opacity", {1.F}); - registerConfigVar("decoration:fullscreen_opacity", {1.F}); - registerConfigVar("decoration:shadow:enabled", Hyprlang::INT{1}); - registerConfigVar("decoration:shadow:range", Hyprlang::INT{4}); - registerConfigVar("decoration:shadow:render_power", Hyprlang::INT{3}); - registerConfigVar("decoration:shadow:ignore_window", Hyprlang::INT{1}); - registerConfigVar("decoration:shadow:offset", Hyprlang::VEC2{0, 0}); - registerConfigVar("decoration:shadow:scale", {1.f}); - registerConfigVar("decoration:shadow:sharp", Hyprlang::INT{0}); - registerConfigVar("decoration:shadow:color", Hyprlang::INT{0xee1a1a1a}); - registerConfigVar("decoration:shadow:color_inactive", Hyprlang::INT{-1}); - registerConfigVar("decoration:dim_inactive", Hyprlang::INT{0}); - registerConfigVar("decoration:dim_modal", Hyprlang::INT{1}); - registerConfigVar("decoration:dim_strength", {0.5f}); - registerConfigVar("decoration:dim_special", {0.2f}); - registerConfigVar("decoration:dim_around", {0.4f}); - registerConfigVar("decoration:screen_shader", {STRVAL_EMPTY}); - registerConfigVar("decoration:border_part_of_window", Hyprlang::INT{1}); - - registerConfigVar("layout:single_window_aspect_ratio", Hyprlang::VEC2{0, 0}); - registerConfigVar("layout:single_window_aspect_ratio_tolerance", {0.1f}); - - registerConfigVar("dwindle:pseudotile", Hyprlang::INT{0}); - registerConfigVar("dwindle:force_split", Hyprlang::INT{0}); - registerConfigVar("dwindle:permanent_direction_override", Hyprlang::INT{0}); - registerConfigVar("dwindle:preserve_split", Hyprlang::INT{0}); - registerConfigVar("dwindle:special_scale_factor", {1.f}); - registerConfigVar("dwindle:split_width_multiplier", {1.0f}); - registerConfigVar("dwindle:use_active_for_splits", Hyprlang::INT{1}); - registerConfigVar("dwindle:default_split_ratio", {1.f}); - registerConfigVar("dwindle:split_bias", Hyprlang::INT{0}); - registerConfigVar("dwindle:smart_split", Hyprlang::INT{0}); - registerConfigVar("dwindle:smart_resizing", Hyprlang::INT{1}); - registerConfigVar("dwindle:precise_mouse_move", Hyprlang::INT{0}); - - registerConfigVar("master:special_scale_factor", {1.f}); - registerConfigVar("master:mfact", {0.55f}); - registerConfigVar("master:new_status", {"slave"}); - registerConfigVar("master:slave_count_for_center_master", Hyprlang::INT{2}); - registerConfigVar("master:center_master_fallback", {"left"}); - registerConfigVar("master:center_ignores_reserved", Hyprlang::INT{0}); - registerConfigVar("master:new_on_active", {"none"}); - registerConfigVar("master:new_on_top", Hyprlang::INT{0}); - registerConfigVar("master:orientation", {"left"}); - registerConfigVar("master:allow_small_split", Hyprlang::INT{0}); - registerConfigVar("master:smart_resizing", Hyprlang::INT{1}); - registerConfigVar("master:drop_at_cursor", Hyprlang::INT{1}); - registerConfigVar("master:always_keep_position", Hyprlang::INT{0}); - - registerConfigVar("scrolling:fullscreen_on_one_column", Hyprlang::INT{1}); - registerConfigVar("scrolling:column_width", Hyprlang::FLOAT{0.5F}); - registerConfigVar("scrolling:focus_fit_method", Hyprlang::INT{1}); - registerConfigVar("scrolling:follow_focus", Hyprlang::INT{1}); - registerConfigVar("scrolling:follow_min_visible", Hyprlang::FLOAT{0.4}); - registerConfigVar("scrolling:explicit_column_widths", Hyprlang::STRING{"0.333, 0.5, 0.667, 1.0"}); - registerConfigVar("scrolling:direction", Hyprlang::STRING{"right"}); - registerConfigVar("scrolling:wrap_focus", Hyprlang::INT{1}); - registerConfigVar("scrolling:wrap_swapcol", Hyprlang::INT{1}); - - registerConfigVar("animations:enabled", Hyprlang::INT{1}); - registerConfigVar("animations:workspace_wraparound", Hyprlang::INT{0}); - - registerConfigVar("input:follow_mouse", Hyprlang::INT{1}); - registerConfigVar("input:follow_mouse_threshold", Hyprlang::FLOAT{0}); - registerConfigVar("input:focus_on_close", Hyprlang::INT{0}); - registerConfigVar("input:mouse_refocus", Hyprlang::INT{1}); - registerConfigVar("input:special_fallthrough", Hyprlang::INT{0}); - registerConfigVar("input:off_window_axis_events", Hyprlang::INT{1}); - registerConfigVar("input:sensitivity", {0.f}); - registerConfigVar("input:accel_profile", {STRVAL_EMPTY}); - registerConfigVar("input:rotation", Hyprlang::INT{0}); - registerConfigVar("input:kb_file", {STRVAL_EMPTY}); - registerConfigVar("input:kb_layout", {"us"}); - registerConfigVar("input:kb_variant", {STRVAL_EMPTY}); - registerConfigVar("input:kb_options", {STRVAL_EMPTY}); - registerConfigVar("input:kb_rules", {STRVAL_EMPTY}); - registerConfigVar("input:kb_model", {STRVAL_EMPTY}); - registerConfigVar("input:repeat_rate", Hyprlang::INT{25}); - registerConfigVar("input:repeat_delay", Hyprlang::INT{600}); - registerConfigVar("input:natural_scroll", Hyprlang::INT{0}); - registerConfigVar("input:numlock_by_default", Hyprlang::INT{0}); - registerConfigVar("input:resolve_binds_by_sym", Hyprlang::INT{0}); - registerConfigVar("input:force_no_accel", Hyprlang::INT{0}); - registerConfigVar("input:float_switch_override_focus", Hyprlang::INT{1}); - registerConfigVar("input:left_handed", Hyprlang::INT{0}); - registerConfigVar("input:scroll_method", {STRVAL_EMPTY}); - registerConfigVar("input:scroll_button", Hyprlang::INT{0}); - registerConfigVar("input:scroll_button_lock", Hyprlang::INT{0}); - registerConfigVar("input:scroll_factor", {1.f}); - registerConfigVar("input:scroll_points", {STRVAL_EMPTY}); - registerConfigVar("input:emulate_discrete_scroll", Hyprlang::INT{1}); - registerConfigVar("input:touchpad:natural_scroll", Hyprlang::INT{0}); - registerConfigVar("input:touchpad:disable_while_typing", Hyprlang::INT{1}); - registerConfigVar("input:touchpad:clickfinger_behavior", Hyprlang::INT{0}); - registerConfigVar("input:touchpad:tap_button_map", {STRVAL_EMPTY}); - registerConfigVar("input:touchpad:middle_button_emulation", Hyprlang::INT{0}); - registerConfigVar("input:touchpad:tap-to-click", Hyprlang::INT{1}); - registerConfigVar("input:touchpad:tap-and-drag", Hyprlang::INT{1}); - registerConfigVar("input:touchpad:drag_lock", Hyprlang::INT{0}); - registerConfigVar("input:touchpad:scroll_factor", {1.f}); - registerConfigVar("input:touchpad:flip_x", Hyprlang::INT{0}); - registerConfigVar("input:touchpad:flip_y", Hyprlang::INT{0}); - registerConfigVar("input:touchpad:drag_3fg", Hyprlang::INT{0}); - registerConfigVar("input:touchdevice:transform", Hyprlang::INT{-1}); - registerConfigVar("input:touchdevice:output", {"[[Auto]]"}); - registerConfigVar("input:touchdevice:enabled", Hyprlang::INT{1}); - registerConfigVar("input:virtualkeyboard:share_states", Hyprlang::INT{2}); - registerConfigVar("input:virtualkeyboard:release_pressed_on_close", Hyprlang::INT{0}); - registerConfigVar("input:tablet:transform", Hyprlang::INT{0}); - registerConfigVar("input:tablet:output", {STRVAL_EMPTY}); - registerConfigVar("input:tablet:region_position", Hyprlang::VEC2{0, 0}); - registerConfigVar("input:tablet:absolute_region_position", Hyprlang::INT{0}); - registerConfigVar("input:tablet:region_size", Hyprlang::VEC2{0, 0}); - registerConfigVar("input:tablet:relative_input", Hyprlang::INT{0}); - registerConfigVar("input:tablet:left_handed", Hyprlang::INT{0}); - registerConfigVar("input:tablet:active_area_position", Hyprlang::VEC2{0, 0}); - registerConfigVar("input:tablet:active_area_size", Hyprlang::VEC2{0, 0}); - - registerConfigVar("binds:pass_mouse_when_bound", Hyprlang::INT{0}); - registerConfigVar("binds:scroll_event_delay", Hyprlang::INT{300}); - registerConfigVar("binds:workspace_back_and_forth", Hyprlang::INT{0}); - registerConfigVar("binds:hide_special_on_workspace_change", Hyprlang::INT{0}); - registerConfigVar("binds:allow_workspace_cycles", Hyprlang::INT{0}); - registerConfigVar("binds:workspace_center_on", Hyprlang::INT{1}); - registerConfigVar("binds:focus_preferred_method", Hyprlang::INT{0}); - registerConfigVar("binds:ignore_group_lock", Hyprlang::INT{0}); - registerConfigVar("binds:movefocus_cycles_fullscreen", Hyprlang::INT{0}); - registerConfigVar("binds:movefocus_cycles_groupfirst", Hyprlang::INT{0}); - registerConfigVar("binds:disable_keybind_grabbing", Hyprlang::INT{0}); - registerConfigVar("binds:allow_pin_fullscreen", Hyprlang::INT{0}); - registerConfigVar("binds:drag_threshold", Hyprlang::INT{0}); - registerConfigVar("binds:window_direction_monitor_fallback", Hyprlang::INT{1}); - - registerConfigVar("gestures:workspace_swipe_distance", Hyprlang::INT{300}); - registerConfigVar("gestures:workspace_swipe_invert", Hyprlang::INT{1}); - registerConfigVar("gestures:workspace_swipe_min_speed_to_force", Hyprlang::INT{30}); - registerConfigVar("gestures:workspace_swipe_cancel_ratio", {0.5f}); - registerConfigVar("gestures:workspace_swipe_create_new", Hyprlang::INT{1}); - registerConfigVar("gestures:workspace_swipe_direction_lock", Hyprlang::INT{1}); - registerConfigVar("gestures:workspace_swipe_direction_lock_threshold", Hyprlang::INT{10}); - registerConfigVar("gestures:workspace_swipe_forever", Hyprlang::INT{0}); - registerConfigVar("gestures:workspace_swipe_use_r", Hyprlang::INT{0}); - registerConfigVar("gestures:workspace_swipe_touch", Hyprlang::INT{0}); - registerConfigVar("gestures:workspace_swipe_touch_invert", Hyprlang::INT{0}); - registerConfigVar("gestures:close_max_timeout", Hyprlang::INT{1000}); - - registerConfigVar("xwayland:enabled", Hyprlang::INT{1}); - registerConfigVar("xwayland:use_nearest_neighbor", Hyprlang::INT{1}); - registerConfigVar("xwayland:force_zero_scaling", Hyprlang::INT{0}); - registerConfigVar("xwayland:create_abstract_socket", Hyprlang::INT{0}); - - registerConfigVar("opengl:nvidia_anti_flicker", Hyprlang::INT{1}); - - registerConfigVar("cursor:invisible", Hyprlang::INT{0}); - registerConfigVar("cursor:no_hardware_cursors", Hyprlang::INT{2}); - registerConfigVar("cursor:no_break_fs_vrr", Hyprlang::INT{2}); - registerConfigVar("cursor:min_refresh_rate", Hyprlang::INT{24}); - registerConfigVar("cursor:hotspot_padding", Hyprlang::INT{0}); - registerConfigVar("cursor:inactive_timeout", {0.f}); - registerConfigVar("cursor:no_warps", Hyprlang::INT{0}); - registerConfigVar("cursor:persistent_warps", Hyprlang::INT{0}); - registerConfigVar("cursor:warp_on_change_workspace", Hyprlang::INT{0}); - registerConfigVar("cursor:warp_on_toggle_special", Hyprlang::INT{0}); - registerConfigVar("cursor:default_monitor", {STRVAL_EMPTY}); - registerConfigVar("cursor:zoom_factor", {1.f}); - registerConfigVar("cursor:zoom_rigid", Hyprlang::INT{0}); - registerConfigVar("cursor:zoom_disable_aa", Hyprlang::INT{0}); - registerConfigVar("cursor:zoom_detached_camera", Hyprlang::INT{1}); - registerConfigVar("cursor:enable_hyprcursor", Hyprlang::INT{1}); - registerConfigVar("cursor:sync_gsettings_theme", Hyprlang::INT{1}); - registerConfigVar("cursor:hide_on_key_press", Hyprlang::INT{0}); - registerConfigVar("cursor:hide_on_touch", Hyprlang::INT{1}); - registerConfigVar("cursor:hide_on_tablet", Hyprlang::INT{0}); - registerConfigVar("cursor:use_cpu_buffer", Hyprlang::INT{2}); - registerConfigVar("cursor:warp_back_after_non_mouse_input", Hyprlang::INT{0}); - - registerConfigVar("autogenerated", Hyprlang::INT{0}); - - registerConfigVar("group:col.border_active", Hyprlang::CConfigCustomValueType{&configHandleGradientSet, configHandleGradientDestroy, "0x66ffff00"}); - registerConfigVar("group:col.border_inactive", Hyprlang::CConfigCustomValueType{&configHandleGradientSet, configHandleGradientDestroy, "0x66777700"}); - registerConfigVar("group:col.border_locked_active", Hyprlang::CConfigCustomValueType{&configHandleGradientSet, configHandleGradientDestroy, "0x66ff5500"}); - registerConfigVar("group:col.border_locked_inactive", Hyprlang::CConfigCustomValueType{&configHandleGradientSet, configHandleGradientDestroy, "0x66775500"}); - - registerConfigVar("group:groupbar:col.active", Hyprlang::CConfigCustomValueType{&configHandleGradientSet, configHandleGradientDestroy, "0x66ffff00"}); - registerConfigVar("group:groupbar:col.inactive", Hyprlang::CConfigCustomValueType{&configHandleGradientSet, configHandleGradientDestroy, "0x66777700"}); - registerConfigVar("group:groupbar:col.locked_active", Hyprlang::CConfigCustomValueType{&configHandleGradientSet, configHandleGradientDestroy, "0x66ff5500"}); - registerConfigVar("group:groupbar:col.locked_inactive", Hyprlang::CConfigCustomValueType{&configHandleGradientSet, configHandleGradientDestroy, "0x66775500"}); - - registerConfigVar("render:direct_scanout", Hyprlang::INT{0}); - registerConfigVar("render:expand_undersized_textures", Hyprlang::INT{1}); - registerConfigVar("render:xp_mode", Hyprlang::INT{0}); - registerConfigVar("render:ctm_animation", Hyprlang::INT{2}); - registerConfigVar("render:cm_fs_passthrough", Hyprlang::INT{2}); - registerConfigVar("render:cm_enabled", Hyprlang::INT{1}); - registerConfigVar("render:send_content_type", Hyprlang::INT{1}); - registerConfigVar("render:cm_auto_hdr", Hyprlang::INT{1}); - registerConfigVar("render:new_render_scheduling", Hyprlang::INT{0}); - registerConfigVar("render:non_shader_cm", Hyprlang::INT{3}); - registerConfigVar("render:cm_sdr_eotf", {"default"}); - registerConfigVar("render:commit_timing_enabled", Hyprlang::INT{1}); - registerConfigVar("render:icc_vcgt_enabled", Hyprlang::INT{1}); - registerConfigVar("render:use_shader_blur_blend", Hyprlang::INT{0}); - - registerConfigVar("ecosystem:no_update_news", Hyprlang::INT{0}); - registerConfigVar("ecosystem:no_donation_nag", Hyprlang::INT{0}); - registerConfigVar("ecosystem:enforce_permissions", Hyprlang::INT{0}); - registerConfigVar("quirks:prefer_hdr", Hyprlang::INT{0}); - registerConfigVar("quirks:skip_non_kms_dmabuf_formats", Hyprlang::INT{0}); +using namespace Config; - // devices - m_config->addSpecialCategory("device", {"name"}); - m_config->addSpecialConfigValue("device", "sensitivity", {0.F}); - m_config->addSpecialConfigValue("device", "accel_profile", {STRVAL_EMPTY}); - m_config->addSpecialConfigValue("device", "rotation", Hyprlang::INT{0}); - m_config->addSpecialConfigValue("device", "kb_file", {STRVAL_EMPTY}); - m_config->addSpecialConfigValue("device", "kb_layout", {"us"}); - m_config->addSpecialConfigValue("device", "kb_variant", {STRVAL_EMPTY}); - m_config->addSpecialConfigValue("device", "kb_options", {STRVAL_EMPTY}); - m_config->addSpecialConfigValue("device", "kb_rules", {STRVAL_EMPTY}); - m_config->addSpecialConfigValue("device", "kb_model", {STRVAL_EMPTY}); - m_config->addSpecialConfigValue("device", "repeat_rate", Hyprlang::INT{25}); - m_config->addSpecialConfigValue("device", "repeat_delay", Hyprlang::INT{600}); - m_config->addSpecialConfigValue("device", "natural_scroll", Hyprlang::INT{0}); - m_config->addSpecialConfigValue("device", "tap_button_map", {STRVAL_EMPTY}); - m_config->addSpecialConfigValue("device", "numlock_by_default", Hyprlang::INT{0}); - m_config->addSpecialConfigValue("device", "resolve_binds_by_sym", Hyprlang::INT{0}); - m_config->addSpecialConfigValue("device", "disable_while_typing", Hyprlang::INT{1}); - m_config->addSpecialConfigValue("device", "clickfinger_behavior", Hyprlang::INT{0}); - m_config->addSpecialConfigValue("device", "middle_button_emulation", Hyprlang::INT{0}); - m_config->addSpecialConfigValue("device", "tap-to-click", Hyprlang::INT{1}); - m_config->addSpecialConfigValue("device", "tap-and-drag", Hyprlang::INT{1}); - m_config->addSpecialConfigValue("device", "drag_lock", Hyprlang::INT{0}); - m_config->addSpecialConfigValue("device", "left_handed", Hyprlang::INT{0}); - m_config->addSpecialConfigValue("device", "scroll_method", {STRVAL_EMPTY}); - m_config->addSpecialConfigValue("device", "scroll_button", Hyprlang::INT{0}); - m_config->addSpecialConfigValue("device", "scroll_button_lock", Hyprlang::INT{0}); - m_config->addSpecialConfigValue("device", "scroll_points", {STRVAL_EMPTY}); - m_config->addSpecialConfigValue("device", "scroll_factor", Hyprlang::FLOAT{-1}); - m_config->addSpecialConfigValue("device", "transform", Hyprlang::INT{-1}); - m_config->addSpecialConfigValue("device", "output", {STRVAL_EMPTY}); - m_config->addSpecialConfigValue("device", "enabled", Hyprlang::INT{1}); // only for mice, touchpads, and touchdevices - m_config->addSpecialConfigValue("device", "region_position", Hyprlang::VEC2{0, 0}); // only for tablets - m_config->addSpecialConfigValue("device", "absolute_region_position", Hyprlang::INT{0}); // only for tablets - m_config->addSpecialConfigValue("device", "region_size", Hyprlang::VEC2{0, 0}); // only for tablets - m_config->addSpecialConfigValue("device", "relative_input", Hyprlang::INT{0}); // only for tablets - m_config->addSpecialConfigValue("device", "active_area_position", Hyprlang::VEC2{0, 0}); // only for tablets - m_config->addSpecialConfigValue("device", "active_area_size", Hyprlang::VEC2{0, 0}); // only for tablets - m_config->addSpecialConfigValue("device", "flip_x", Hyprlang::INT{0}); // only for touchpads - m_config->addSpecialConfigValue("device", "flip_y", Hyprlang::INT{0}); // only for touchpads - m_config->addSpecialConfigValue("device", "drag_3fg", Hyprlang::INT{0}); // only for touchpads - m_config->addSpecialConfigValue("device", "keybinds", Hyprlang::INT{1}); // enable/disable keybinds - m_config->addSpecialConfigValue("device", "share_states", Hyprlang::INT{0}); // only for virtualkeyboards - m_config->addSpecialConfigValue("device", "release_pressed_on_close", Hyprlang::INT{0}); // only for virtualkeyboards +static UP g_mgr; - m_config->addSpecialCategory("monitorv2", {.key = "output"}); - m_config->addSpecialConfigValue("monitorv2", "disabled", Hyprlang::INT{0}); - m_config->addSpecialConfigValue("monitorv2", "mode", {"preferred"}); - m_config->addSpecialConfigValue("monitorv2", "position", {"auto"}); - m_config->addSpecialConfigValue("monitorv2", "scale", {"auto"}); - m_config->addSpecialConfigValue("monitorv2", "addreserved", {STRVAL_EMPTY}); - m_config->addSpecialConfigValue("monitorv2", "mirror", {STRVAL_EMPTY}); - m_config->addSpecialConfigValue("monitorv2", "bitdepth", {STRVAL_EMPTY}); // TODO use correct type - m_config->addSpecialConfigValue("monitorv2", "cm", {"auto"}); - m_config->addSpecialConfigValue("monitorv2", "sdr_eotf", {"default"}); - m_config->addSpecialConfigValue("monitorv2", "sdrbrightness", Hyprlang::FLOAT{1.0}); - m_config->addSpecialConfigValue("monitorv2", "sdrsaturation", Hyprlang::FLOAT{1.0}); - m_config->addSpecialConfigValue("monitorv2", "vrr", Hyprlang::INT{0}); - m_config->addSpecialConfigValue("monitorv2", "transform", {STRVAL_EMPTY}); // TODO use correct type - m_config->addSpecialConfigValue("monitorv2", "supports_wide_color", Hyprlang::INT{0}); - m_config->addSpecialConfigValue("monitorv2", "supports_hdr", Hyprlang::INT{0}); - m_config->addSpecialConfigValue("monitorv2", "sdr_min_luminance", Hyprlang::FLOAT{0.2}); - m_config->addSpecialConfigValue("monitorv2", "sdr_max_luminance", Hyprlang::INT{80}); - m_config->addSpecialConfigValue("monitorv2", "min_luminance", Hyprlang::FLOAT{-1.0}); - m_config->addSpecialConfigValue("monitorv2", "max_luminance", Hyprlang::INT{-1}); - m_config->addSpecialConfigValue("monitorv2", "max_avg_luminance", Hyprlang::INT{-1}); - m_config->addSpecialConfigValue("monitorv2", "icc", Hyprlang::STRING{""}); - - // windowrule v3 - m_config->addSpecialCategory("windowrule", {.key = "name"}); - m_config->addSpecialConfigValue("windowrule", "enable", Hyprlang::INT{1}); - - // layerrule v2 - m_config->addSpecialCategory("layerrule", {.key = "name"}); - m_config->addSpecialConfigValue("layerrule", "enable", Hyprlang::INT{1}); - - reloadRuleConfigs(); - - // keywords - m_config->registerHandler(&::handleExec, "exec", {false}); - m_config->registerHandler(&::handleRawExec, "execr", {false}); - m_config->registerHandler(&::handleExecOnce, "exec-once", {false}); - m_config->registerHandler(&::handleExecRawOnce, "execr-once", {false}); - m_config->registerHandler(&::handleExecShutdown, "exec-shutdown", {false}); - m_config->registerHandler(&::handleMonitor, "monitor", {false}); - m_config->registerHandler(&::handleBind, "bind", {true}); - m_config->registerHandler(&::handleUnbind, "unbind", {false}); - m_config->registerHandler(&::handleWorkspaceRules, "workspace", {false}); - m_config->registerHandler(&::handleWindowrule, "windowrule", {false}); - m_config->registerHandler(&::handleLayerrule, "layerrule", {false}); - m_config->registerHandler(&::handleBezier, "bezier", {false}); - m_config->registerHandler(&::handleAnimation, "animation", {false}); - m_config->registerHandler(&::handleSource, "source", {false}); - m_config->registerHandler(&::handleSubmap, "submap", {false}); - m_config->registerHandler(&::handlePlugin, "plugin", {false}); - m_config->registerHandler(&::handlePermission, "permission", {false}); - m_config->registerHandler(&::handleGesture, "gesture", {true}); - m_config->registerHandler(&::handleEnv, "env", {true}); - - // windowrulev2 and layerrulev2 errors - m_config->registerHandler(&::handleWindowrulev2, "windowrulev2", {false}); - m_config->registerHandler(&::handleLayerrulev2, "layerrulev2", {false}); - - // pluginza - m_config->addSpecialCategory("plugin", {nullptr, true}); - - m_config->commence(); - - resetHLConfig(); - - if (CONFIG_OPTIONS.size() != m_configValueNumber - 1 /* autogenerated is special */) - Log::logger->log(Log::DEBUG, "Warning: config descriptions have {} entries, but there are {} config values. This should fail tests!!", CONFIG_OPTIONS.size(), - m_configValueNumber); - - if (!g_pCompositor->m_onlyConfigVerification) { - Log::logger->log( - Log::DEBUG, - "!!!!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.hypr.land/Configuring/Variables/#debug"); - } - - if (g_pEventLoopManager && ERR.has_value()) - g_pEventLoopManager->doLater([ERR] { g_pHyprError->queueCreate(ERR.value(), CHyprColor{1.0, 0.1, 0.1, 1.0}); }); -} - -void CConfigManager::reloadRuleConfigs() { - // FIXME: this should also remove old values if they are removed +// +bool Config::initConfigManager() { + if (mgr()) + return true; - for (const auto& r : Desktop::Rule::allMatchPropStrings()) { - m_config->addSpecialConfigValue("windowrule", ("match:" + r).c_str(), Hyprlang::STRING{""}); - } + // run this bitch + const auto CFG_PATH = Supplementary::Jeremy::getMainConfigPath(); - for (const auto& r : Desktop::Rule::windowEffects()->allEffectStrings()) { - m_config->addSpecialConfigValue("windowrule", r.c_str(), Hyprlang::STRING{""}); + if (!CFG_PATH) { + Log::logger->log(Log::CRIT, "Couldn't load config: {}", CFG_PATH.error()); + return false; } - for (const auto& r : Desktop::Rule::allMatchPropStrings()) { - m_config->addSpecialConfigValue("layerrule", ("match:" + r).c_str(), Hyprlang::STRING{""}); - } + std::filesystem::path filePath = *CFG_PATH; - for (const auto& r : Desktop::Rule::layerEffects()->allEffectStrings()) { - m_config->addSpecialConfigValue("layerrule", r.c_str(), Hyprlang::STRING{""}); - } -} + // TODO: + // filePath.replace_extension(".lua"); -std::optional CConfigManager::generateConfig(std::string configPath, bool safeMode) { - std::string parentPath = std::filesystem::path(configPath).parent_path(); + g_mgr = makeUnique(); - if (!parentPath.empty()) { - std::error_code ec; - bool created = std::filesystem::create_directories(parentPath, ec); + std::error_code ec; + if (!std::filesystem::exists(filePath, ec) || ec) { if (ec) { - Log::logger->log(Log::ERR, "Couldn't create config home directory ({}): {}", ec.message(), parentPath); - return "Config could not be generated."; - } - if (created) - Log::logger->log(Log::WARN, "Creating config home directory"); - } - - Log::logger->log(Log::WARN, "No config file found; attempting to generate."); - std::ofstream ofs; - ofs.open(configPath, std::ios::trunc); - if (!safeMode) { - ofs << AUTOGENERATED_PREFIX; - ofs << EXAMPLE_CONFIG; - } else { - std::string n = std::string{EXAMPLE_CONFIG}; - replaceInString(n, "\n$menu = hyprlauncher\n", "\n$menu = hyprland-run\n"); - ofs << n; - } - ofs.close(); - - if (ofs.fail()) - return "Config could not be generated."; - - return configPath; -} - -std::string CConfigManager::getMainConfigPath() { - static bool lastSafeMode = g_pCompositor->m_safeMode; - static auto getCfgPath = [this]() -> std::string { - lastSafeMode = g_pCompositor->m_safeMode; - m_firstExecDispatched = false; - - if (g_pCompositor->m_safeMode) { - const auto CONFIGPATH = g_pCompositor->m_instancePath + "/recoverycfg.conf"; - return generateConfig(CONFIGPATH, false).value(); + Log::logger->log(Log::CRIT, "Couldn't load config: {}", ec.message()); + return false; } - if (!g_pCompositor->m_explicitConfigPath.empty()) - return g_pCompositor->m_explicitConfigPath; - - if (const auto CFG_ENV = getenv("HYPRLAND_CONFIG"); CFG_ENV) - return CFG_ENV; - - const auto PATHS = Hyprutils::Path::findConfig(ISDEBUG ? "hyprlandd" : "hyprland"); - if (PATHS.first.has_value()) { - return PATHS.first.value(); - } else if (PATHS.second.has_value()) { - const auto CONFIGPATH = Hyprutils::Path::fullConfigPath(PATHS.second.value(), ISDEBUG ? "hyprlandd" : "hyprland"); - return generateConfig(CONFIGPATH).value(); - } else - throw std::runtime_error("Neither HOME nor XDG_CONFIG_HOME are set in the environment. Could not find config in XDG_CONFIG_DIRS or /etc/xdg."); - }; - static std::string CONFIG_PATH = getCfgPath(); - - if (lastSafeMode != g_pCompositor->m_safeMode) { - CONFIG_PATH = getCfgPath(); - m_config->changeRootPath(CONFIG_PATH.c_str()); - } - - return CONFIG_PATH; -} - -std::optional CConfigManager::verifyConfigExists() { - std::string mainConfigPath = getMainConfigPath(); - - if (!std::filesystem::exists(mainConfigPath)) - return "broken config dir?"; - - return {}; -} - -std::string CConfigManager::getConfigString() { - std::string configString; - std::string currFileContent; - - for (const auto& path : m_configPaths) { - std::ifstream configFile(path); - configString += ("\n\nConfig File: " + path + ": "); - if (!configFile.is_open()) { - Log::logger->log(Log::DEBUG, "Config file not readable/found!"); - configString += "Read Failed\n"; - continue; + // generate default + if (const auto v = g_mgr->generateDefaultConfig(filePath); !v) { + Log::logger->log(Log::CRIT, "Couldn't generate default config: {}", v.error()); + return false; } - configString += "Read Succeeded\n"; - currFileContent.assign(std::istreambuf_iterator(configFile), std::istreambuf_iterator()); - configString.append(currFileContent); - } - return configString; -} - -std::string CConfigManager::getErrors() { - return m_configErrors; -} - -static std::vector HL_VERSION_VARS = { - "HYPRLAND_V_0_53", -}; - -static void exportHlVersionVars() { - for (const auto& v : HL_VERSION_VARS) { - setenv(v, "1", 1); - } -} - -static void clearHlVersionVars() { - for (const auto& v : HL_VERSION_VARS) { - unsetenv(v); - } -} - -void CConfigManager::reload() { - Event::bus()->m_events.config.preReload.emit(); - setDefaultAnimationVars(); - resetHLConfig(); - m_configCurrentPath = getMainConfigPath(); - - exportHlVersionVars(); - - const auto ERR = m_config->parse(); - - clearHlVersionVars(); - - const auto monitorError = handleMonitorv2(); - const auto ruleError = reloadRules(); - m_lastConfigVerificationWasSuccessful = !ERR.error && !monitorError.error; - postConfigReload(ERR.error || !monitorError.error ? ERR : monitorError); -} - -std::string CConfigManager::verify() { - setDefaultAnimationVars(); - resetHLConfig(); - m_configCurrentPath = getMainConfigPath(); - const auto ERR = m_config->parse(); - m_lastConfigVerificationWasSuccessful = !ERR.error; - if (ERR.error) - return ERR.getError(); - return "config ok"; -} - -void CConfigManager::setDefaultAnimationVars() { - m_animationTree.createNode("__internal_fadeCTM"); - m_animationTree.createNode("global"); - - // global - m_animationTree.createNode("windows", "global"); - m_animationTree.createNode("layers", "global"); - m_animationTree.createNode("fade", "global"); - m_animationTree.createNode("border", "global"); - m_animationTree.createNode("borderangle", "global"); - m_animationTree.createNode("workspaces", "global"); - m_animationTree.createNode("zoomFactor", "global"); - m_animationTree.createNode("monitorAdded", "global"); - - // layer - m_animationTree.createNode("layersIn", "layers"); - m_animationTree.createNode("layersOut", "layers"); - - // windows - m_animationTree.createNode("windowsIn", "windows"); - m_animationTree.createNode("windowsOut", "windows"); - m_animationTree.createNode("windowsMove", "windows"); - - // fade - m_animationTree.createNode("fadeIn", "fade"); - m_animationTree.createNode("fadeOut", "fade"); - m_animationTree.createNode("fadeSwitch", "fade"); - m_animationTree.createNode("fadeShadow", "fade"); - m_animationTree.createNode("fadeDim", "fade"); - m_animationTree.createNode("fadeLayers", "fade"); - m_animationTree.createNode("fadeLayersIn", "fadeLayers"); - m_animationTree.createNode("fadeLayersOut", "fadeLayers"); - m_animationTree.createNode("fadePopups", "fade"); - m_animationTree.createNode("fadePopupsIn", "fadePopups"); - m_animationTree.createNode("fadePopupsOut", "fadePopups"); - m_animationTree.createNode("fadeDpms", "fade"); - - // workspaces - m_animationTree.createNode("workspacesIn", "workspaces"); - m_animationTree.createNode("workspacesOut", "workspaces"); - m_animationTree.createNode("specialWorkspace", "workspaces"); - m_animationTree.createNode("specialWorkspaceIn", "specialWorkspace"); - m_animationTree.createNode("specialWorkspaceOut", "specialWorkspace"); - - // init the root nodes - m_animationTree.setConfigForNode("global", 1, 8.f, "default"); - m_animationTree.setConfigForNode("__internal_fadeCTM", 1, 5.f, "linear"); - m_animationTree.setConfigForNode("borderangle", 0, 1, "default"); -} - -std::optional CConfigManager::resetHLConfig() { - m_monitorRules.clear(); - g_pKeybindManager->clearKeybinds(); - g_pAnimationManager->removeAllBeziers(); - g_pAnimationManager->addBezierWithName("linear", Vector2D(0.0, 0.0), Vector2D(1.0, 1.0)); - g_pTrackpadGestures->clearGestures(); - - m_workspaceRules.clear(); - setDefaultAnimationVars(); // reset anims - m_declaredPlugins.clear(); - m_failedPluginConfigValues.clear(); - m_finalExecRequests.clear(); - m_keywordRules.clear(); - - // paths - m_configPaths.clear(); - std::string mainConfigPath = getMainConfigPath(); - Log::logger->log(Log::DEBUG, "Using config: {}", mainConfigPath); - m_configPaths.emplace_back(mainConfigPath); - - const auto RET = verifyConfigExists(); - - reloadRuleConfigs(); - - return RET; -} - -void CConfigManager::updateWatcher() { - static const auto PDISABLEAUTORELOAD = CConfigValue("misc:disable_autoreload"); - g_pConfigWatcher->setWatchList(*PDISABLEAUTORELOAD ? std::vector{} : m_configPaths); -} - -std::optional CConfigManager::handleMonitorv2(const std::string& output) { - auto parser = CMonitorRuleParser(output); - auto VAL = m_config->getSpecialConfigValuePtr("monitorv2", "disabled", output.c_str()); - if (VAL && VAL->m_bSetByUser && std::any_cast(VAL->getValue())) - parser.setDisabled(); - VAL = m_config->getSpecialConfigValuePtr("monitorv2", "mode", output.c_str()); - if (VAL && VAL->m_bSetByUser) - parser.parseMode(std::any_cast(VAL->getValue())); - VAL = m_config->getSpecialConfigValuePtr("monitorv2", "position", output.c_str()); - if (VAL && VAL->m_bSetByUser) - parser.parsePosition(std::any_cast(VAL->getValue())); - VAL = m_config->getSpecialConfigValuePtr("monitorv2", "scale", output.c_str()); - if (VAL && VAL->m_bSetByUser) - parser.parseScale(std::any_cast(VAL->getValue())); - VAL = m_config->getSpecialConfigValuePtr("monitorv2", "addreserved", output.c_str()); - if (VAL && VAL->m_bSetByUser) { - const auto ARGS = CVarList(std::any_cast(VAL->getValue())); - try { - // top, right, bottom, left - parser.setReserved({std::stoi(ARGS[0]), std::stoi(ARGS[3]), std::stoi(ARGS[1]), std::stoi(ARGS[2])}); - } catch (...) { return "parse error: invalid reserved area"; } } - VAL = m_config->getSpecialConfigValuePtr("monitorv2", "mirror", output.c_str()); - if (VAL && VAL->m_bSetByUser) - parser.setMirror(std::any_cast(VAL->getValue())); - VAL = m_config->getSpecialConfigValuePtr("monitorv2", "bitdepth", output.c_str()); - if (VAL && VAL->m_bSetByUser) - parser.parseBitdepth(std::any_cast(VAL->getValue())); - VAL = m_config->getSpecialConfigValuePtr("monitorv2", "cm", output.c_str()); - if (VAL && VAL->m_bSetByUser) - parser.parseCM(std::any_cast(VAL->getValue())); - VAL = m_config->getSpecialConfigValuePtr("monitorv2", "sdr_eotf", output.c_str()); - if (VAL && VAL->m_bSetByUser) { - const std::string value = std::any_cast(VAL->getValue()); - // remap legacy - if (value == "0") - parser.rule().sdrEotf = NTransferFunction::TF_AUTO; - else if (value == "1") - parser.rule().sdrEotf = NTransferFunction::TF_SRGB; - else if (value == "2") - parser.rule().sdrEotf = NTransferFunction::TF_GAMMA22; - else - parser.rule().sdrEotf = NTransferFunction::fromString(value); - } - VAL = m_config->getSpecialConfigValuePtr("monitorv2", "sdrbrightness", output.c_str()); - if (VAL && VAL->m_bSetByUser) - parser.rule().sdrBrightness = std::any_cast(VAL->getValue()); - VAL = m_config->getSpecialConfigValuePtr("monitorv2", "sdrsaturation", output.c_str()); - if (VAL && VAL->m_bSetByUser) - parser.rule().sdrSaturation = std::any_cast(VAL->getValue()); - VAL = m_config->getSpecialConfigValuePtr("monitorv2", "vrr", output.c_str()); - if (VAL && VAL->m_bSetByUser) - parser.rule().vrr = std::any_cast(VAL->getValue()); - VAL = m_config->getSpecialConfigValuePtr("monitorv2", "transform", output.c_str()); - if (VAL && VAL->m_bSetByUser) - parser.parseTransform(std::any_cast(VAL->getValue())); - - VAL = m_config->getSpecialConfigValuePtr("monitorv2", "supports_wide_color", output.c_str()); - if (VAL && VAL->m_bSetByUser) - parser.rule().supportsWideColor = std::any_cast(VAL->getValue()); - VAL = m_config->getSpecialConfigValuePtr("monitorv2", "supports_hdr", output.c_str()); - if (VAL && VAL->m_bSetByUser) - parser.rule().supportsHDR = std::any_cast(VAL->getValue()); - VAL = m_config->getSpecialConfigValuePtr("monitorv2", "sdr_min_luminance", output.c_str()); - if (VAL && VAL->m_bSetByUser) - parser.rule().sdrMinLuminance = std::any_cast(VAL->getValue()); - VAL = m_config->getSpecialConfigValuePtr("monitorv2", "sdr_max_luminance", output.c_str()); - if (VAL && VAL->m_bSetByUser) - parser.rule().sdrMaxLuminance = std::any_cast(VAL->getValue()); - - VAL = m_config->getSpecialConfigValuePtr("monitorv2", "min_luminance", output.c_str()); - if (VAL && VAL->m_bSetByUser) - parser.rule().minLuminance = std::any_cast(VAL->getValue()); - VAL = m_config->getSpecialConfigValuePtr("monitorv2", "max_luminance", output.c_str()); - if (VAL && VAL->m_bSetByUser) - parser.rule().maxLuminance = std::any_cast(VAL->getValue()); - VAL = m_config->getSpecialConfigValuePtr("monitorv2", "max_avg_luminance", output.c_str()); - if (VAL && VAL->m_bSetByUser) - parser.rule().maxAvgLuminance = std::any_cast(VAL->getValue()); - - VAL = m_config->getSpecialConfigValuePtr("monitorv2", "icc", output.c_str()); - if (VAL && VAL->m_bSetByUser) - parser.rule().iccFile = std::any_cast(VAL->getValue()); - - auto newrule = parser.rule(); - - std::erase_if(m_monitorRules, [&](const auto& other) { return other.name == newrule.name; }); - - m_monitorRules.push_back(newrule); - - return parser.getError(); -} -Hyprlang::CParseResult CConfigManager::handleMonitorv2() { - Hyprlang::CParseResult result; - for (const auto& output : m_config->listKeysForSpecialCategory("monitorv2")) { - const auto error = handleMonitorv2(output); - if (error.has_value()) { - result.setError(error.value().c_str()); - return result; - } - } - return result; + return true; } -std::optional CConfigManager::addRuleFromConfigKey(const std::string& name) { - const auto ENABLED = m_config->getSpecialConfigValuePtr("windowrule", "enable", name.c_str()); - if (ENABLED && ENABLED->m_bSetByUser && std::any_cast(ENABLED->getValue()) == 0) - return std::nullopt; - - SP rule = makeShared(name); - - for (const auto& r : Desktop::Rule::allMatchPropStrings()) { - auto VAL = m_config->getSpecialConfigValuePtr("windowrule", ("match:" + r).c_str(), name.c_str()); - if (VAL && VAL->m_bSetByUser) - rule->registerMatch(Desktop::Rule::matchPropFromString(r).value_or(Desktop::Rule::RULE_PROP_NONE), std::any_cast(VAL->getValue())); - } - - for (const auto& e : Desktop::Rule::windowEffects()->allEffectStrings()) { - auto VAL = m_config->getSpecialConfigValuePtr("windowrule", e.c_str(), name.c_str()); - if (VAL && VAL->m_bSetByUser) - rule->addEffect(Desktop::Rule::windowEffects()->get(e).value_or(Desktop::Rule::WINDOW_RULE_EFFECT_NONE), std::any_cast(VAL->getValue())); - } - - Desktop::Rule::ruleEngine()->registerRule(std::move(rule)); - return std::nullopt; -} - -std::optional CConfigManager::addLayerRuleFromConfigKey(const std::string& name) { - - const auto ENABLED = m_config->getSpecialConfigValuePtr("layerrule", "enable", name.c_str()); - if (ENABLED && ENABLED->m_bSetByUser && std::any_cast(ENABLED->getValue()) != 0) - return std::nullopt; - - SP rule = makeShared(name); - - for (const auto& r : Desktop::Rule::allMatchPropStrings()) { - auto VAL = m_config->getSpecialConfigValuePtr("layerrule", ("match:" + r).c_str(), name.c_str()); - if (VAL && VAL->m_bSetByUser) - rule->registerMatch(Desktop::Rule::matchPropFromString(r).value_or(Desktop::Rule::RULE_PROP_NONE), std::any_cast(VAL->getValue())); - } - - for (const auto& e : Desktop::Rule::layerEffects()->allEffectStrings()) { - auto VAL = m_config->getSpecialConfigValuePtr("layerrule", e.c_str(), name.c_str()); - if (VAL && VAL->m_bSetByUser) - rule->addEffect(Desktop::Rule::layerEffects()->get(e).value_or(Desktop::Rule::LAYER_RULE_EFFECT_NONE), std::any_cast(VAL->getValue())); - } - - Desktop::Rule::ruleEngine()->registerRule(std::move(rule)); - return std::nullopt; -} - -Hyprlang::CParseResult CConfigManager::reloadRules() { - Desktop::Rule::ruleEngine()->clearAllRules(); - - Hyprlang::CParseResult result; - for (const auto& name : m_config->listKeysForSpecialCategory("windowrule")) { - const auto error = addRuleFromConfigKey(name); - if (error.has_value()) - result.setError(error.value().c_str()); - } - for (const auto& name : m_config->listKeysForSpecialCategory("layerrule")) { - const auto error = addLayerRuleFromConfigKey(name); - if (error.has_value()) - result.setError(error.value().c_str()); - } - - for (auto& rule : m_keywordRules) { - Desktop::Rule::ruleEngine()->registerRule(SP{rule}); - } - - Desktop::Rule::ruleEngine()->updateAllRules(); - - return result; -} - -void CConfigManager::postConfigReload(const Hyprlang::CParseResult& result) { - updateWatcher(); - - for (auto const& w : g_pCompositor->m_windows) { - w->uncacheWindowDecos(); - } - - static auto PZOOMFACTOR = CConfigValue("cursor:zoom_factor"); - for (auto const& m : g_pCompositor->m_monitors) { - *(m->m_cursorZoom) = *PZOOMFACTOR; - if (m->m_activeWorkspace) - m->m_activeWorkspace->m_space->recalculate(); - } - - // Update the keyboard layout to the cfg'd one if this is not the first launch - if (!m_isFirstLaunch) { - g_pInputManager->setKeyboardLayout(); - g_pInputManager->setPointerConfigs(); - g_pInputManager->setTouchDeviceConfigs(); - g_pInputManager->setTabletConfigs(); - - g_pHyprRenderer->m_reloadScreenShader = true; - } - - // parseError will be displayed next frame - - if (result.error) - m_configErrors = result.getError(); - else - m_configErrors = ""; - - if (result.error && !std::any_cast(m_config->getConfigValue("debug:suppress_errors"))) - g_pHyprError->queueCreate(result.getError(), CHyprColor(1.0, 50.0 / 255.0, 50.0 / 255.0, 1.0)); - else if (std::any_cast(m_config->getConfigValue("autogenerated")) == 1) - g_pHyprError->queueCreate( - "Warning: You're using an autogenerated config! Edit the config file to get rid of this message. (config file: " + getMainConfigPath() + - " )\nSUPER+Q -> kitty (if it doesn't launch, make sure it's installed or choose a different terminal in the config)\nSUPER+M -> exit Hyprland", - CHyprColor(1.0, 1.0, 70.0 / 255.0, 1.0)); - else - g_pHyprError->destroy(); - - // Set the modes for all monitors as we configured them - // not on first launch because monitors might not exist yet - // and they'll be taken care of in the newMonitor event - // ignore if nomonitorreload is set - if (!m_isFirstLaunch && !m_noMonitorReload) { - // check - performMonitorReload(); - ensureMonitorStatus(); - ensureVRR(); - } - -#ifndef NO_XWAYLAND - const auto PENABLEXWAYLAND = std::any_cast(m_config->getConfigValue("xwayland:enabled")); - g_pCompositor->m_wantsXwayland = PENABLEXWAYLAND; - // enable/disable xwayland usage - if (!m_isFirstLaunch && - g_pXWayland /* XWayland has to be initialized by CCompositor::initManagers for this to make sense, and it doesn't have to be (e.g. very early plugin load) */) { - bool prevEnabledXwayland = g_pXWayland->enabled(); - if (g_pCompositor->m_wantsXwayland != prevEnabledXwayland) - g_pXWayland = makeUnique(g_pCompositor->m_wantsXwayland); - } else - g_pCompositor->m_wantsXwayland = PENABLEXWAYLAND; -#endif - - if (!m_isFirstLaunch && !g_pCompositor->m_unsafeState) - refreshGroupBarGradients(); - - // Updates dynamic window and workspace rules - for (auto const& w : g_pCompositor->getWorkspaces()) { - if (w->inert()) - continue; - w->updateWindows(); - w->updateWindowData(); - } - - // Update window border colors - g_pCompositor->updateAllWindowsAnimatedDecorationValues(); - - // manual crash - if (std::any_cast(m_config->getConfigValue("debug:manual_crash")) && !m_manualCrashInitiated) { - m_manualCrashInitiated = true; - g_pHyprNotificationOverlay->addNotification("Manual crash has been set up. Set debug:manual_crash back to 0 in order to crash the compositor.", CHyprColor(0), 5000, - ICON_INFO); - } else if (m_manualCrashInitiated && !std::any_cast(m_config->getConfigValue("debug:manual_crash"))) { - // cowabunga it is - g_pHyprRenderer->initiateManualCrash(); - } - - auto disableStdout = !std::any_cast(m_config->getConfigValue("debug:enable_stdout_logs")); - if (disableStdout && m_isFirstLaunch) - Log::logger->log(Log::DEBUG, "Disabling stdout logs! Check the log for further logs."); - - for (auto const& m : g_pCompositor->m_monitors) { - // mark blur dirty - m->m_blurFBDirty = true; - - g_pCompositor->scheduleFrameForMonitor(m); - - // Force the compositor to fully re-render all monitors - m->m_forceFullFrames = 2; - - // also force mirrors, as the aspect ratio could've changed - for (auto const& mirror : m->m_mirrors) - mirror->m_forceFullFrames = 3; - } - - // Reset no monitor reload - m_noMonitorReload = false; - - // update plugins - handlePluginLoads(); - - // update persistent workspaces - if (!m_isFirstLaunch) - ensurePersistentWorkspacesPresent(); - - // update layouts - Layout::Supplementary::algoMatcher()->updateWorkspaceLayouts(); - - Event::bus()->m_events.config.reloaded.emit(); - if (g_pEventManager) - g_pEventManager->postEvent(SHyprIPCEvent{"configreloaded", ""}); -} - -void CConfigManager::init() { - - g_pConfigWatcher->setOnChange([this](const CConfigWatcher::SConfigWatchEvent& e) { - Log::logger->log(Log::DEBUG, "CConfigManager: file {} modified, reloading", e.file); - reload(); - }); - - reload(); - - m_isFirstLaunch = false; -} - -std::string CConfigManager::parseKeyword(const std::string& COMMAND, const std::string& VALUE) { - const auto RET = m_config->parseDynamic(COMMAND.c_str(), VALUE.c_str()); - - // invalidate layouts if they changed - if (COMMAND == "monitor" || COMMAND.contains("gaps_") || COMMAND.starts_with("dwindle:") || COMMAND.starts_with("master:")) { - for (auto const& m : g_pCompositor->m_monitors) { - g_layoutManager->recalculateMonitor(m); - } - } - - // Update window border colors - g_pCompositor->updateAllWindowsAnimatedDecorationValues(); - - // manual crash - if (std::any_cast(m_config->getConfigValue("debug:manual_crash")) && !m_manualCrashInitiated) { - m_manualCrashInitiated = true; - if (g_pHyprNotificationOverlay) { - g_pHyprNotificationOverlay->addNotification("Manual crash has been set up. Set debug:manual_crash back to 0 in order to crash the compositor.", CHyprColor(0), 5000, - ICON_INFO); - } - } else if (m_manualCrashInitiated && !std::any_cast(m_config->getConfigValue("debug:manual_crash"))) { - // cowabunga it is - g_pHyprRenderer->initiateManualCrash(); - } - - return RET.error ? RET.getError() : ""; -} - -Hyprlang::CConfigValue* CConfigManager::getConfigValueSafeDevice(const std::string& dev, const std::string& val, const std::string& fallback) { - - const auto VAL = m_config->getSpecialConfigValuePtr("device", val.c_str(), dev.c_str()); - - if ((!VAL || !VAL->m_bSetByUser) && !fallback.empty()) - return m_config->getConfigValuePtr(fallback.c_str()); - - return VAL; -} - -bool CConfigManager::deviceConfigExplicitlySet(const std::string& dev, const std::string& val) { - const auto VAL = m_config->getSpecialConfigValuePtr("device", val.c_str(), dev.c_str()); - - return VAL && VAL->m_bSetByUser; -} - -int CConfigManager::getDeviceInt(const std::string& dev, const std::string& v, const std::string& fallback) { - return std::any_cast(getConfigValueSafeDevice(dev, v, fallback)->getValue()); -} - -float CConfigManager::getDeviceFloat(const std::string& dev, const std::string& v, const std::string& fallback) { - return std::any_cast(getConfigValueSafeDevice(dev, v, fallback)->getValue()); -} - -Vector2D CConfigManager::getDeviceVec(const std::string& dev, const std::string& v, const std::string& fallback) { - auto vec = std::any_cast(getConfigValueSafeDevice(dev, v, fallback)->getValue()); - return {vec.x, vec.y}; -} - -std::string CConfigManager::getDeviceString(const std::string& dev, const std::string& v, const std::string& fallback) { - auto VAL = std::string{std::any_cast(getConfigValueSafeDevice(dev, v, fallback)->getValue())}; - - if (VAL == STRVAL_EMPTY) - return ""; - - return VAL; -} - -SMonitorRule CConfigManager::getMonitorRuleFor(const PHLMONITOR PMONITOR) { - auto applyWlrOutputConfig = [PMONITOR](SMonitorRule rule) -> SMonitorRule { - const auto CONFIG = PROTO::outputManagement->getOutputStateFor(PMONITOR); - - if (!CONFIG) - return rule; - - Log::logger->log(Log::DEBUG, "CConfigManager::getMonitorRuleFor: found a wlr_output_manager override for {}", PMONITOR->m_name); - - Log::logger->log(Log::DEBUG, " > overriding enabled: {} -> {}", !rule.disabled, !CONFIG->enabled); - rule.disabled = !CONFIG->enabled; - - if ((CONFIG->committedProperties & OUTPUT_HEAD_COMMITTED_MODE) || (CONFIG->committedProperties & OUTPUT_HEAD_COMMITTED_CUSTOM_MODE)) { - Log::logger->log(Log::DEBUG, " > overriding mode: {:.0f}x{:.0f}@{:.2f}Hz -> {:.0f}x{:.0f}@{:.2f}Hz", rule.resolution.x, rule.resolution.y, rule.refreshRate, - CONFIG->resolution.x, CONFIG->resolution.y, CONFIG->refresh / 1000.F); - rule.resolution = CONFIG->resolution; - rule.refreshRate = CONFIG->refresh / 1000.F; - } - - if (CONFIG->committedProperties & OUTPUT_HEAD_COMMITTED_POSITION) { - Log::logger->log(Log::DEBUG, " > overriding offset: {:.0f}, {:.0f} -> {:.0f}, {:.0f}", rule.offset.x, rule.offset.y, CONFIG->position.x, CONFIG->position.y); - rule.offset = CONFIG->position; - } - - if (CONFIG->committedProperties & OUTPUT_HEAD_COMMITTED_TRANSFORM) { - Log::logger->log(Log::DEBUG, " > overriding transform: {} -> {}", sc(rule.transform), sc(CONFIG->transform)); - rule.transform = CONFIG->transform; - } - - if (CONFIG->committedProperties & OUTPUT_HEAD_COMMITTED_SCALE) { - Log::logger->log(Log::DEBUG, " > overriding scale: {} -> {}", sc(rule.scale), sc(CONFIG->scale)); - rule.scale = CONFIG->scale; - } - - if (CONFIG->committedProperties & OUTPUT_HEAD_COMMITTED_ADAPTIVE_SYNC) { - Log::logger->log(Log::DEBUG, " > overriding vrr: {} -> {}", rule.vrr.value_or(0), CONFIG->adaptiveSync); - rule.vrr = sc(CONFIG->adaptiveSync); - } - - return rule; - }; - - for (auto const& r : m_monitorRules | std::views::reverse) { - if (PMONITOR->matchesStaticSelector(r.name)) { - return applyWlrOutputConfig(r); - } - } - - Log::logger->log(Log::WARN, "No rule found for {}, trying to use the first.", PMONITOR->m_name); - - for (auto const& r : m_monitorRules) { - if (r.name.empty()) { - return applyWlrOutputConfig(r); - } - } - - Log::logger->log(Log::WARN, "No rules configured. Using the default hardcoded one."); - - return applyWlrOutputConfig(SMonitorRule{.autoDir = eAutoDirs::DIR_AUTO_RIGHT, - .name = "", - .resolution = Vector2D(0, 0), - .offset = Vector2D(-INT32_MAX, -INT32_MAX), - .scale = -1}); // 0, 0 is preferred and -1, -1 is auto -} - -SWorkspaceRule CConfigManager::getWorkspaceRuleFor(PHLWORKSPACE pWorkspace) { - SWorkspaceRule mergedRule{}; - for (auto const& rule : m_workspaceRules) { - if (!pWorkspace->matchesStaticSelector(rule.workspaceString)) - continue; - - mergedRule = mergeWorkspaceRules(mergedRule, rule); - } - - return mergedRule; -} - -SWorkspaceRule CConfigManager::mergeWorkspaceRules(const SWorkspaceRule& rule1, const SWorkspaceRule& rule2) { - SWorkspaceRule mergedRule = rule1; - - if (rule1.monitor.empty()) - mergedRule.monitor = rule2.monitor; - if (rule1.workspaceString.empty()) - mergedRule.workspaceString = rule2.workspaceString; - if (rule1.workspaceName.empty()) - mergedRule.workspaceName = rule2.workspaceName; - if (rule1.workspaceId == WORKSPACE_INVALID) - mergedRule.workspaceId = rule2.workspaceId; - - if (rule2.isDefault) - mergedRule.isDefault = true; - if (rule2.isPersistent) - mergedRule.isPersistent = true; - if (rule2.gapsIn.has_value()) - mergedRule.gapsIn = rule2.gapsIn; - if (rule2.gapsOut.has_value()) - mergedRule.gapsOut = rule2.gapsOut; - if (rule2.floatGaps) - mergedRule.floatGaps = rule2.floatGaps; - if (rule2.borderSize.has_value()) - mergedRule.borderSize = rule2.borderSize; - if (rule2.noBorder.has_value()) - mergedRule.noBorder = rule2.noBorder; - if (rule2.noRounding.has_value()) - mergedRule.noRounding = rule2.noRounding; - if (rule2.decorate.has_value()) - mergedRule.decorate = rule2.decorate; - if (rule2.noShadow.has_value()) - mergedRule.noShadow = rule2.noShadow; - if (rule2.onCreatedEmptyRunCmd.has_value()) - mergedRule.onCreatedEmptyRunCmd = rule2.onCreatedEmptyRunCmd; - if (rule2.defaultName.has_value()) - mergedRule.defaultName = rule2.defaultName; - if (rule2.layout.has_value()) - mergedRule.layout = rule2.layout; - if (!rule2.layoutopts.empty()) { - for (const auto& layoutopt : rule2.layoutopts) { - mergedRule.layoutopts[layoutopt.first] = layoutopt.second; - } - } - if (rule2.animationStyle.has_value()) - mergedRule.animationStyle = rule2.animationStyle; - return mergedRule; -} - -void CConfigManager::dispatchExecOnce() { - if (m_firstExecDispatched || m_isFirstLaunch) - return; - - // update dbus env - if (g_pCompositor->m_aqBackend->hasSession()) - handleRawExec("", -#ifdef USES_SYSTEMD - "systemctl --user import-environment DISPLAY WAYLAND_DISPLAY HYPRLAND_INSTANCE_SIGNATURE XDG_CURRENT_DESKTOP QT_QPA_PLATFORMTHEME PATH XDG_DATA_DIRS && hash " - "dbus-update-activation-environment 2>/dev/null && " -#endif - "dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP HYPRLAND_INSTANCE_SIGNATURE QT_QPA_PLATFORMTHEME PATH XDG_DATA_DIRS"); - - m_firstExecDispatched = true; - m_isLaunchingExecOnce = true; - - for (auto const& c : m_firstExecRequests) { - c.withRules ? handleExec("", c.exec) : handleRawExec("", c.exec); - } - - m_firstExecRequests.clear(); // free some kb of memory :P - m_isLaunchingExecOnce = false; - - // set input, fixes some certain issues - g_pInputManager->setKeyboardLayout(); - g_pInputManager->setPointerConfigs(); - g_pInputManager->setTouchDeviceConfigs(); - g_pInputManager->setTabletConfigs(); - - // check for user's possible errors with their setup and notify them if needed - // this is additionally guarded because exiting safe mode will re-run this. - static bool once = true; - if (once) { - g_pCompositor->performUserChecks(); - once = false; - } -} - -void CConfigManager::dispatchExecShutdown() { - if (m_finalExecRequests.empty()) { - g_pCompositor->m_finalRequests = false; - return; - } - - g_pCompositor->m_finalRequests = true; - - for (auto const& c : m_finalExecRequests) { - handleExecShutdown("", c); - } - - m_finalExecRequests.clear(); - - // Actually exit now - handleExecShutdown("", "hyprctl dispatch exit"); -} - -void CConfigManager::performMonitorReload() { - handleMonitorv2(); - - bool overAgain = false; - - for (auto const& m : g_pCompositor->m_realMonitors) { - if (!m->m_output || m->m_isUnsafeFallback) - continue; - - auto rule = getMonitorRuleFor(m); - - if (!m->applyMonitorRule(&rule)) { - overAgain = true; - break; - } - - // ensure mirror - m->setMirror(rule.mirrorOf); - - g_pHyprRenderer->arrangeLayersForMonitor(m->m_id); - } - - if (overAgain) - performMonitorReload(); - - m_wantsMonitorReload = false; - - Event::bus()->m_events.monitor.layoutChanged.emit(); -} - -void* const* CConfigManager::getConfigValuePtr(const std::string& val) { - const auto VAL = m_config->getConfigValuePtr(val.c_str()); - if (!VAL) - return nullptr; - return VAL->getDataStaticPtr(); -} - -Hyprlang::CConfigValue* CConfigManager::getHyprlangConfigValuePtr(const std::string& name, const std::string& specialCat) { - if (!specialCat.empty()) - return m_config->getSpecialConfigValuePtr(specialCat.c_str(), name.c_str(), nullptr); - - if (name.starts_with("plugin:")) - return m_config->getSpecialConfigValuePtr("plugin", name.substr(7).c_str(), nullptr); - - return m_config->getConfigValuePtr(name.c_str()); -} - -bool CConfigManager::deviceConfigExists(const std::string& dev) { - auto copy = dev; - std::ranges::replace(copy, ' ', '-'); - - return m_config->specialCategoryExistsForKey("device", copy.c_str()); -} - -void CConfigManager::ensureMonitorStatus() { - for (auto const& rm : g_pCompositor->m_realMonitors) { - if (!rm->m_output || rm->m_isUnsafeFallback) - continue; - - auto rule = getMonitorRuleFor(rm); - - if (rule.disabled == rm->m_enabled) - rm->applyMonitorRule(&rule); - } -} - -void CConfigManager::ensureVRR(PHLMONITOR pMonitor) { - static auto PVRR = rc(getConfigValuePtr("misc:vrr")); - - static auto ensureVRRForDisplay = [&](PHLMONITOR m) -> void { - if (!m->m_output || m->m_createdByUser) - return; - - const auto USEVRR = m->m_activeMonitorRule.vrr.has_value() ? m->m_activeMonitorRule.vrr.value() : **PVRR; - - if (USEVRR == 0) { - if (m->m_vrrActive) { - m->m_output->state->resetExplicitFences(); - m->m_output->state->setAdaptiveSync(false); - - if (!m->m_state.commit()) - Log::logger->log(Log::ERR, "Couldn't commit output {} in ensureVRR -> false", m->m_output->name); - } - m->m_vrrActive = false; - return; - } - - const auto PWORKSPACE = m->m_activeWorkspace; - - if (USEVRR == 1) { - bool wantVRR = true; - if (PWORKSPACE && PWORKSPACE->m_hasFullscreenWindow && (PWORKSPACE->m_fullscreenMode & FSMODE_FULLSCREEN)) - wantVRR = !PWORKSPACE->getFullscreenWindow()->m_ruleApplicator->noVRR().valueOrDefault(); - - if (wantVRR) { - if (!m->m_vrrActive) { - m->m_output->state->resetExplicitFences(); - m->m_output->state->setAdaptiveSync(true); - - if (!m->m_state.test()) { - Log::logger->log(Log::DEBUG, "Pending output {} does not accept VRR.", m->m_output->name); - m->m_output->state->setAdaptiveSync(false); - } - - if (!m->m_state.commit()) - Log::logger->log(Log::ERR, "Couldn't commit output {} in ensureVRR -> true", m->m_output->name); - } - m->m_vrrActive = true; - } else { - if (m->m_vrrActive) { - m->m_output->state->resetExplicitFences(); - m->m_output->state->setAdaptiveSync(false); - - if (!m->m_state.commit()) - Log::logger->log(Log::ERR, "Couldn't commit output {} in ensureVRR -> false", m->m_output->name); - } - m->m_vrrActive = false; - } - return; - } else if (USEVRR == 2 || USEVRR == 3) { - if (!PWORKSPACE) - return; // ??? - - bool wantVRR = PWORKSPACE->m_hasFullscreenWindow && (PWORKSPACE->m_fullscreenMode & FSMODE_FULLSCREEN); - if (wantVRR && PWORKSPACE->getFullscreenWindow()->m_ruleApplicator->noVRR().valueOrDefault()) - wantVRR = false; - - if (wantVRR && USEVRR == 3) { - const auto contentType = PWORKSPACE->getFullscreenWindow()->getContentType(); - wantVRR = contentType == CONTENT_TYPE_GAME || contentType == CONTENT_TYPE_VIDEO; - } - - if (wantVRR) { - /* fullscreen */ - m->m_vrrActive = true; - - if (!m->m_output->state->state().adaptiveSync) { - m->m_output->state->setAdaptiveSync(true); - - if (!m->m_state.test()) { - Log::logger->log(Log::DEBUG, "Pending output {} does not accept VRR.", m->m_output->name); - m->m_output->state->setAdaptiveSync(false); - } - } - } else { - m->m_vrrActive = false; - - m->m_output->state->setAdaptiveSync(false); - } - } - }; - - if (pMonitor) { - ensureVRRForDisplay(pMonitor); - return; - } - - for (auto const& m : g_pCompositor->m_monitors) { - ensureVRRForDisplay(m); - } -} - -SP CConfigManager::getAnimationPropertyConfig(const std::string& name) { - return m_animationTree.getConfig(name); -} - -void CConfigManager::addParseError(const std::string& err) { - g_pHyprError->queueCreate(err + "\nHyprland may not work correctly.", CHyprColor(1.0, 50.0 / 255.0, 50.0 / 255.0, 1.0)); -} - -PHLMONITOR CConfigManager::getBoundMonitorForWS(const std::string& wsname) { - auto monitor = getBoundMonitorStringForWS(wsname); - if (monitor.starts_with("desc:")) - return g_pCompositor->getMonitorFromDesc(trim(monitor.substr(5))); - else - return g_pCompositor->getMonitorFromName(monitor); -} - -std::string CConfigManager::getBoundMonitorStringForWS(const std::string& wsname) { - for (auto const& wr : m_workspaceRules) { - const auto WSNAME = wr.workspaceName.starts_with("name:") ? wr.workspaceName.substr(5) : wr.workspaceName; - if (WSNAME == wsname) - return wr.monitor; - } - - return ""; -} - -const std::vector& CConfigManager::getAllWorkspaceRules() { - return m_workspaceRules; -} - -void CConfigManager::handlePluginLoads() { - if (!g_pPluginSystem) - return; - - bool pluginsChanged = false; - g_pPluginSystem->updateConfigPlugins(m_declaredPlugins, pluginsChanged); - - if (pluginsChanged) { - g_pHyprError->destroy(); - reload(); - } -} - -const std::unordered_map>& CConfigManager::getAnimationConfig() { - return m_animationTree.getFullConfig(); -} - -void CConfigManager::addPluginConfigVar(HANDLE handle, const std::string& name, const Hyprlang::CConfigValue& value) { - if (!name.starts_with("plugin:")) - return; - - std::string field = name.substr(7); - - m_config->addSpecialConfigValue("plugin", field.c_str(), value); - m_pluginVariables.push_back({handle, field}); -} - -void CConfigManager::addPluginKeyword(HANDLE handle, const std::string& name, Hyprlang::PCONFIGHANDLERFUNC fn, Hyprlang::SHandlerOptions opts) { - m_pluginKeywords.emplace_back(SPluginKeyword{handle, name, fn}); - m_config->registerHandler(fn, name.c_str(), opts); -} - -void CConfigManager::removePluginConfig(HANDLE handle) { - for (auto const& k : m_pluginKeywords) { - if (k.handle != handle) - continue; - - m_config->unregisterHandler(k.name.c_str()); - } - - std::erase_if(m_pluginKeywords, [&](const auto& other) { return other.handle == handle; }); - for (auto const& [h, n] : m_pluginVariables) { - if (h != handle) - continue; - - m_config->removeSpecialConfigValue("plugin", n.c_str()); - } - std::erase_if(m_pluginVariables, [handle](const auto& other) { return other.handle == handle; }); -} - -std::string CConfigManager::getDefaultWorkspaceFor(const std::string& name) { - for (auto other = m_workspaceRules.begin(); other != m_workspaceRules.end(); ++other) { - if (other->isDefault) { - if (other->monitor == name) - return other->workspaceString; - if (other->monitor.starts_with("desc:")) { - auto const monitor = g_pCompositor->getMonitorFromDesc(trim(other->monitor.substr(5))); - if (monitor && monitor->m_name == name) - return other->workspaceString; - } - } - } - return ""; -} - -std::optional CConfigManager::handleRawExec(const std::string& command, const std::string& args) { - if (m_isFirstLaunch) { - m_firstExecRequests.push_back({args, false}); - return {}; - } - - g_pKeybindManager->spawnRaw(args); - return {}; -} - -std::optional CConfigManager::handleExec(const std::string& command, const std::string& args) { - if (m_isFirstLaunch) { - m_firstExecRequests.push_back({args, true}); - return {}; - } - - g_pKeybindManager->spawn(args); - return {}; -} - -std::optional CConfigManager::handleExecOnce(const std::string& command, const std::string& args) { - if (m_isFirstLaunch) - m_firstExecRequests.push_back({args, true}); - - return {}; -} - -std::optional CConfigManager::handleExecRawOnce(const std::string& command, const std::string& args) { - if (m_isFirstLaunch) - m_firstExecRequests.push_back({args, false}); - - return {}; -} - -std::optional CConfigManager::handleExecShutdown(const std::string& command, const std::string& args) { - if (g_pCompositor->m_finalRequests) { - g_pKeybindManager->spawn(args); - return {}; - } - - m_finalExecRequests.push_back(args); - return {}; -} - -static bool parseModeLine(const std::string& modeline, drmModeModeInfo& mode) { - auto args = CVarList(modeline, 0, 's'); - - auto keyword = args[0]; - std::ranges::transform(keyword, keyword.begin(), ::tolower); - - if (keyword != "modeline") - return false; - - if (args.size() < 10) { - Log::logger->log(Log::ERR, "modeline parse error: expected at least 9 arguments, got {}", args.size() - 1); - return false; - } - - int argno = 1; - - try { - mode.type = DRM_MODE_TYPE_USERDEF; - mode.clock = std::stof(args[argno++]) * 1000; - mode.hdisplay = std::stoi(args[argno++]); - mode.hsync_start = std::stoi(args[argno++]); - mode.hsync_end = std::stoi(args[argno++]); - mode.htotal = std::stoi(args[argno++]); - mode.vdisplay = std::stoi(args[argno++]); - mode.vsync_start = std::stoi(args[argno++]); - mode.vsync_end = std::stoi(args[argno++]); - mode.vtotal = std::stoi(args[argno++]); - mode.vrefresh = mode.clock * 1000.0 * 1000.0 / mode.htotal / mode.vtotal; - } catch (const std::exception& e) { - Log::logger->log(Log::ERR, "modeline parse error: invalid numeric value: {}", e.what()); - return false; - } - - // clang-format off - static std::unordered_map flagsmap = { - {"+hsync", DRM_MODE_FLAG_PHSYNC}, - {"-hsync", DRM_MODE_FLAG_NHSYNC}, - {"+vsync", DRM_MODE_FLAG_PVSYNC}, - {"-vsync", DRM_MODE_FLAG_NVSYNC}, - {"Interlace", DRM_MODE_FLAG_INTERLACE}, - }; - // clang-format on - - for (; argno < sc(args.size()); argno++) { - auto key = args[argno]; - std::ranges::transform(key, key.begin(), ::tolower); - - auto it = flagsmap.find(key); - - if (it != flagsmap.end()) - mode.flags |= it->second; - else - Log::logger->log(Log::ERR, "Invalid flag {} in modeline", key); - } - - snprintf(mode.name, sizeof(mode.name), "%dx%d@%d", mode.hdisplay, mode.vdisplay, mode.vrefresh / 1000); - - return true; -} - -CMonitorRuleParser::CMonitorRuleParser(const std::string& name) { - m_rule.name = name; -} - -const std::string& CMonitorRuleParser::name() { - return m_rule.name; -} - -SMonitorRule& CMonitorRuleParser::rule() { - return m_rule; -} - -std::optional CMonitorRuleParser::getError() { - if (m_error.empty()) - return {}; - return m_error; -} - -bool CMonitorRuleParser::parseMode(const std::string& value) { - if (value.starts_with("pref")) - m_rule.resolution = Vector2D(); - else if (value.starts_with("highrr")) - m_rule.resolution = Vector2D(-1, -1); - else if (value.starts_with("highres")) - m_rule.resolution = Vector2D(-1, -2); - else if (value.starts_with("maxwidth")) - m_rule.resolution = Vector2D(-1, -3); - else if (parseModeLine(value, m_rule.drmMode)) { - m_rule.resolution = Vector2D(m_rule.drmMode.hdisplay, m_rule.drmMode.vdisplay); - m_rule.refreshRate = sc(m_rule.drmMode.vrefresh) / 1000; - } else { - - if (!value.contains("x")) { - m_error += "invalid resolution "; - m_rule.resolution = Vector2D(); - return false; - } else { - try { - m_rule.resolution.x = stoi(value.substr(0, value.find_first_of('x'))); - m_rule.resolution.y = stoi(value.substr(value.find_first_of('x') + 1, value.find_first_of('@'))); - - if (value.contains("@")) - m_rule.refreshRate = stof(value.substr(value.find_first_of('@') + 1)); - } catch (...) { - m_error += "invalid resolution "; - m_rule.resolution = Vector2D(); - return false; - } - } - } - return true; -} - -bool CMonitorRuleParser::parsePosition(const std::string& value, bool isFirst) { - if (value.starts_with("auto")) { - m_rule.offset = Vector2D(-INT32_MAX, -INT32_MAX); - // If this is the first monitor rule needs to be on the right. - if (value == "auto-right" || value == "auto" || isFirst) - m_rule.autoDir = eAutoDirs::DIR_AUTO_RIGHT; - else if (value == "auto-left") - m_rule.autoDir = eAutoDirs::DIR_AUTO_LEFT; - else if (value == "auto-up") - m_rule.autoDir = eAutoDirs::DIR_AUTO_UP; - else if (value == "auto-down") - m_rule.autoDir = eAutoDirs::DIR_AUTO_DOWN; - else if (value == "auto-center-right") - m_rule.autoDir = eAutoDirs::DIR_AUTO_CENTER_RIGHT; - else if (value == "auto-center-left") - m_rule.autoDir = eAutoDirs::DIR_AUTO_CENTER_LEFT; - else if (value == "auto-center-up") - m_rule.autoDir = eAutoDirs::DIR_AUTO_CENTER_UP; - else if (value == "auto-center-down") - m_rule.autoDir = eAutoDirs::DIR_AUTO_CENTER_DOWN; - else { - Log::logger->log(Log::WARN, - "Invalid auto direction. Valid options are 'auto'," - "'auto-up', 'auto-down', 'auto-left', 'auto-right'," - "'auto-center-up', 'auto-center-down'," - "'auto-center-left', and 'auto-center-right'."); - m_error += "invalid auto direction "; - return false; - } - } else { - if (!value.contains("x")) { - m_error += "invalid offset "; - m_rule.offset = Vector2D(-INT32_MAX, -INT32_MAX); - return false; - } else { - try { - m_rule.offset.x = stoi(value.substr(0, value.find_first_of('x'))); - m_rule.offset.y = stoi(value.substr(value.find_first_of('x') + 1)); - } catch (...) { - m_error += "invalid offset "; - m_rule.offset = Vector2D(-INT32_MAX, -INT32_MAX); - return false; - } - } - } - return true; -} - -bool CMonitorRuleParser::parseScale(const std::string& value) { - if (value.starts_with("auto")) - m_rule.scale = -1; - else { - if (!isNumber(value, true)) { - m_error += "invalid scale "; - return false; - } else { - m_rule.scale = stof(value); - - if (m_rule.scale < 0.25f) { - m_error += "invalid scale "; - m_rule.scale = 1; - return false; - } - } - } - return true; -} - -bool CMonitorRuleParser::parseTransform(const std::string& value) { - if (!isNumber(value)) { - m_error += "invalid transform "; - return false; - } - - const auto TSF = std::stoi(value); - if (std::clamp(TSF, 0, 7) != TSF) { - Log::logger->log(Log::ERR, "Invalid transform {} in monitor", TSF); - m_error += "invalid transform "; - return false; - } - m_rule.transform = sc(TSF); - return true; -} - -bool CMonitorRuleParser::parseBitdepth(const std::string& value) { - m_rule.enable10bit = value == "10"; - return true; -} - -bool CMonitorRuleParser::parseCM(const std::string& value) { - auto parsedCM = NCMType::fromString(value); - if (!parsedCM.has_value()) { - m_error += "invalid cm "; - return false; - } - m_rule.cmType = parsedCM.value(); - return true; -} - -bool CMonitorRuleParser::parseSDRBrightness(const std::string& value) { - try { - m_rule.sdrBrightness = stof(value); - } catch (...) { - m_error += "invalid sdrbrightness "; - return false; - } - return true; -} - -bool CMonitorRuleParser::parseSDRSaturation(const std::string& value) { - try { - m_rule.sdrSaturation = stof(value); - } catch (...) { - m_error += "invalid sdrsaturation "; - return false; - } - return true; -} - -bool CMonitorRuleParser::parseVRR(const std::string& value) { - if (!isNumber(value)) { - m_error += "invalid vrr "; - return false; - } - - m_rule.vrr = std::stoi(value); - return true; -} - -bool CMonitorRuleParser::parseICC(const std::string& val) { - if (val.empty()) { - m_error += "invalid icc "; - return false; - } - m_rule.iccFile = val; - return true; -} - -void CMonitorRuleParser::setDisabled() { - m_rule.disabled = true; -} - -void CMonitorRuleParser::setMirror(const std::string& value) { - m_rule.mirrorOf = value; -} - -bool CMonitorRuleParser::setReserved(const Desktop::CReservedArea& value) { - m_rule.reservedArea = value; - return true; -} - -std::optional CConfigManager::handleMonitor(const std::string& command, const std::string& args) { - // get the monitor config - const auto ARGS = CVarList2(std::string(args)); - - auto parser = CMonitorRuleParser(std::string(ARGS[0])); - - if (ARGS[1] == "disable" || ARGS[1] == "disabled" || ARGS[1] == "addreserved" || ARGS[1] == "transform") { - if (ARGS[1] == "disable" || ARGS[1] == "disabled") - parser.setDisabled(); - else if (ARGS[1] == "transform") { - if (!parser.parseTransform(std::string(ARGS[2]))) - return parser.getError(); - - const auto TRANSFORM = parser.rule().transform; - - // overwrite if exists - for (auto& r : m_monitorRules) { - if (r.name == parser.name()) { - r.transform = TRANSFORM; - return {}; - } - } - - return {}; - } else if (ARGS[1] == "addreserved") { - std::optional area; - try { - // top, right, bottom, left - area = {std::stoi(std::string{ARGS[2]}), std::stoi(std::string{ARGS[5]}), std::stoi(std::string{ARGS[3]}), std::stoi(std::string{ARGS[4]})}; - } catch (...) { return "parse error: invalid reserved area"; } - - if (!area.has_value()) - return "parse error: bad addreserved"; - - auto rule = std::ranges::find_if(m_monitorRules, [n = ARGS[0]](const auto& other) { return other.name == n; }); - if (rule != m_monitorRules.end()) { - rule->reservedArea = area.value(); - return {}; - } - - // fall - } else { - Log::logger->log(Log::ERR, "ConfigManager parseMonitor, curitem bogus???"); - return "parse error: curitem bogus"; - } - - std::erase_if(m_monitorRules, [&](const auto& other) { return other.name == parser.name(); }); - - m_monitorRules.push_back(parser.rule()); - - return {}; - } - - parser.parseMode(std::string(ARGS[1])); - parser.parsePosition(std::string(ARGS[2])); - parser.parseScale(std::string(ARGS[3])); - - int argno = 4; - - while (!ARGS[argno].empty()) { - if (ARGS[argno] == "mirror") { - parser.setMirror(std::string(ARGS[argno + 1])); - argno++; - } else if (ARGS[argno] == "bitdepth") { - parser.parseBitdepth(std::string(ARGS[argno + 1])); - argno++; - } else if (ARGS[argno] == "cm") { - parser.parseCM(std::string(ARGS[argno + 1])); - argno++; - } else if (ARGS[argno] == "sdrsaturation") { - parser.parseSDRSaturation(std::string(ARGS[argno + 1])); - argno++; - } else if (ARGS[argno] == "sdrbrightness") { - parser.parseSDRBrightness(std::string(ARGS[argno + 1])); - argno++; - } else if (ARGS[argno] == "transform") { - parser.parseTransform(std::string(ARGS[argno + 1])); - argno++; - } else if (ARGS[argno] == "vrr") { - parser.parseVRR(std::string(ARGS[argno + 1])); - argno++; - } else if (ARGS[argno] == "icc") { - parser.parseICC(std::string(ARGS[argno + 1])); - argno++; - } else if (ARGS[argno] == "workspace") { - const auto& [id, name, isAutoID] = getWorkspaceIDNameFromString(std::string(ARGS[argno + 1])); - - SWorkspaceRule wsRule; - wsRule.monitor = parser.name(); - wsRule.workspaceString = ARGS[argno + 1]; - wsRule.workspaceId = isAutoID ? WORKSPACE_INVALID : id; - wsRule.workspaceName = name; - - m_workspaceRules.emplace_back(wsRule); - argno++; - } else { - Log::logger->log(Log::ERR, "Config error: invalid monitor syntax at \"{}\"", ARGS[argno]); - return "invalid syntax at \"" + std::string(ARGS[argno]) + "\""; - } - - argno++; - } - - auto newrule = parser.rule(); - - std::erase_if(m_monitorRules, [&](const auto& other) { return other.name == newrule.name; }); - - m_monitorRules.push_back(newrule); - - return parser.getError(); -} - -std::optional CConfigManager::handleBezier(const std::string& command, const std::string& args) { - const auto ARGS = CVarList(args); - - std::string bezierName = ARGS[0]; - - if (ARGS[1].empty()) - return "too few arguments"; - else if (!isNumber(ARGS[1], true)) - return "invalid point"; - float p1x = std::stof(ARGS[1]); - - if (ARGS[2].empty()) - return "too few arguments"; - else if (!isNumber(ARGS[2], true)) - return "invalid point"; - float p1y = std::stof(ARGS[2]); - - if (ARGS[3].empty()) - return "too few arguments"; - else if (!isNumber(ARGS[3], true)) - return "invalid point"; - float p2x = std::stof(ARGS[3]); - - if (ARGS[4].empty()) - return "too few arguments"; - else if (!isNumber(ARGS[4], true)) - return "invalid point"; - float p2y = std::stof(ARGS[4]); - - if (!ARGS[5].empty()) - return "too many arguments"; - - g_pAnimationManager->addBezierWithName(bezierName, Vector2D(p1x, p1y), Vector2D(p2x, p2y)); - - return {}; -} - -std::optional CConfigManager::handleAnimation(const std::string& command, const std::string& args) { - const auto ARGS = CVarList(args); - - // Master on/off - - // anim name - const auto ANIMNAME = ARGS[0]; - - if (!m_animationTree.nodeExists(ANIMNAME)) - return "no such animation"; - - // This helper casts strings like "1", "true", "off", "yes"... to int. - int64_t enabledInt = configStringToInt(ARGS[1]).value_or(0) == 1; - - // Checking that the int is 1 or 0 because the helper can return integers out of range. - if (enabledInt != 0 && enabledInt != 1) - return "invalid animation on/off state"; - - if (!enabledInt) { - m_animationTree.setConfigForNode(ANIMNAME, enabledInt, 1, "default"); - return {}; - } - - float speed = -1; - - // speed - if (isNumber(ARGS[2], true)) { - speed = std::stof(ARGS[2]); - - if (speed <= 0) { - speed = 1.f; - return "invalid speed"; - } - } else { - speed = 10.f; - return "invalid speed"; - } - - std::string bezierName = ARGS[3]; - m_animationTree.setConfigForNode(ANIMNAME, enabledInt, speed, ARGS[3], ARGS[4]); - - if (!g_pAnimationManager->bezierExists(bezierName)) { - const auto PANIMNODE = m_animationTree.getConfig(ANIMNAME); - PANIMNODE->internalBezier = "default"; - return "no such bezier"; - } - - if (!ARGS[4].empty()) { - auto ERR = g_pAnimationManager->styleValidInConfigVar(ANIMNAME, ARGS[4]); - - if (!ERR.empty()) - return ERR; - } - - return {}; -} - -SParsedKey parseKey(const std::string& key) { - if (isNumber(key) && std::stoi(key) > 9) - return {.keycode = std::stoi(key)}; - else if (key.starts_with("code:") && isNumber(key.substr(5))) - return {.keycode = std::stoi(key.substr(5))}; - else if (key == "catchall") - return {.catchAll = true}; - else - return {.key = key}; -} - -std::optional CConfigManager::handleBind(const std::string& command, const std::string& value) { - // example: - // bind[fl]=SUPER,G,exec,dmenu_run - - // flags - bool locked = false; - bool release = false; - bool repeat = false; - bool mouse = false; - bool nonConsuming = false; - bool transparent = false; - bool ignoreMods = false; - bool multiKey = false; - bool longPress = false; - bool hasDescription = false; - bool dontInhibit = false; - bool click = false; - bool drag = false; - bool submapUniversal = false; - bool isPerDevice = false; - const auto BINDARGS = command.substr(4); - - for (auto const& arg : BINDARGS) { - switch (arg) { - case 'l': locked = true; break; - case 'r': release = true; break; - case 'e': repeat = true; break; - case 'm': mouse = true; break; - case 'n': nonConsuming = true; break; - case 't': transparent = true; break; - case 'i': ignoreMods = true; break; - case 's': multiKey = true; break; - case 'o': longPress = true; break; - case 'd': hasDescription = true; break; - case 'p': dontInhibit = true; break; - case 'c': - click = true; - release = true; - break; - case 'g': - drag = true; - release = true; - break; - case 'u': submapUniversal = true; break; - case 'k': isPerDevice = true; break; - default: return "bind: invalid flag"; - } - } - - if ((longPress || release) && repeat) - return "flags e is mutually exclusive with r and o"; - - if (mouse && (repeat || release || locked)) - return "flag m is exclusive"; - - if (click && drag) - return "flags c and g are mutually exclusive"; - - const int numbArgs = (hasDescription ? 5 : 4) + sc(isPerDevice); - const auto ARGS = CVarList(value, numbArgs); - - const int DESCR_OFFSET = hasDescription ? 1 : 0; - const int DEVICE_OFFSET = sc(isPerDevice); - if ((ARGS.size() < 3 && !mouse) || (ARGS.size() < 3 && mouse)) - return "bind: too few args"; - else if ((ARGS.size() > sc(4) + DESCR_OFFSET + DEVICE_OFFSET && !mouse) || (ARGS.size() > sc(3) + DESCR_OFFSET + DEVICE_OFFSET && mouse)) - return "bind: too many args"; - - std::set KEYSYMS; - std::set MODS; - - if (multiKey) { - for (const auto& splitKey : CVarList(ARGS[1], 8, '&')) { - KEYSYMS.insert(xkb_keysym_from_name(splitKey.c_str(), XKB_KEYSYM_CASE_INSENSITIVE)); - } - for (const auto& splitMod : CVarList(ARGS[0], 8, '&')) { - MODS.insert(xkb_keysym_from_name(splitMod.c_str(), XKB_KEYSYM_CASE_INSENSITIVE)); - } - } - const auto MOD = g_pKeybindManager->stringToModMask(ARGS[0]); - const auto MODSTR = ARGS[0]; - - const auto KEY = multiKey ? "" : ARGS[1]; - - const auto DEVICEARGS = isPerDevice ? ARGS[2] : ""; - - const auto DESCRIPTION = hasDescription ? ARGS[2 + DEVICE_OFFSET] : ""; - - auto HANDLER = ARGS[2 + DESCR_OFFSET + DEVICE_OFFSET]; - - const auto COMMAND = mouse ? HANDLER : ARGS[3 + DESCR_OFFSET + DEVICE_OFFSET]; - - if (mouse) - HANDLER = "mouse"; - - // to lower - std::ranges::transform(HANDLER, HANDLER.begin(), ::tolower); - - const auto DISPATCHER = g_pKeybindManager->m_dispatchers.find(HANDLER); - - if (DISPATCHER == g_pKeybindManager->m_dispatchers.end()) { - Log::logger->log(Log::ERR, "Invalid dispatcher: {}", HANDLER); - return "Invalid dispatcher, requested \"" + HANDLER + "\" does not exist"; - } - - if (MOD == 0 && !MODSTR.empty()) { - Log::logger->log(Log::ERR, "Invalid mod: {}", MODSTR); - return "Invalid mod, requested mod \"" + MODSTR + "\" is not a valid mod."; - } - - //[!]keyboard1 keyboard2 ... - bool deviceInclusive = false; - std::unordered_set devices = {}; - if (!DEVICEARGS.empty()) { - deviceInclusive = DEVICEARGS[0] != '!'; - for (const auto deviceString : std::ranges::views::split(DEVICEARGS.substr(deviceInclusive ? 0 : 1), ' ')) { - devices.emplace(std::string_view(deviceString)); - } - } - - if ((!KEY.empty()) || multiKey) { - SParsedKey parsedKey = parseKey(KEY); - - if (parsedKey.catchAll && m_currentSubmap.name.empty()) { - Log::logger->log(Log::ERR, "Catchall not allowed outside of submap!"); - return "Invalid catchall, catchall keybinds are only allowed in submaps."; - } - - g_pKeybindManager->addKeybind(SKeybind{parsedKey.key, KEYSYMS, parsedKey.keycode, parsedKey.catchAll, MOD, MODS, HANDLER, - COMMAND, locked, m_currentSubmap, DESCRIPTION, release, repeat, longPress, - mouse, nonConsuming, transparent, ignoreMods, multiKey, hasDescription, dontInhibit, - click, drag, submapUniversal, deviceInclusive, devices}); - } - - return {}; -} - -std::optional CConfigManager::handleUnbind(const std::string& command, const std::string& value) { - const auto ARGS = CVarList(value); - - if (ARGS.size() == 1 && ARGS[0] == "all") { - g_pKeybindManager->m_keybinds.clear(); - g_pKeybindManager->m_activeKeybinds.clear(); - g_pKeybindManager->m_lastLongPressKeybind.reset(); - return {}; - } - - const auto MOD = g_pKeybindManager->stringToModMask(ARGS[0]); - - const auto KEY = parseKey(ARGS[1]); - - g_pKeybindManager->removeKeybind(MOD, KEY); - - return {}; -} - -std::optional CConfigManager::handleWorkspaceRules(const std::string& command, const std::string& value) { - // This can either be the monitor or the workspace identifier - const auto FIRST_DELIM = value.find_first_of(','); - - auto first_ident = trim(value.substr(0, FIRST_DELIM)); - - const auto& [id, name, isAutoID] = getWorkspaceIDNameFromString(first_ident); - - auto rules = value.substr(FIRST_DELIM + 1); - SWorkspaceRule wsRule; - wsRule.workspaceString = first_ident; - // if (id == WORKSPACE_INVALID) { - // // it could be the monitor. If so, second value MUST be - // // the workspace. - // const auto WORKSPACE_DELIM = value.find_first_of(',', FIRST_DELIM + 1); - // auto wsIdent = removeBeginEndSpacesTabs(value.substr(FIRST_DELIM + 1, (WORKSPACE_DELIM - FIRST_DELIM - 1))); - // id = getWorkspaceIDFromString(wsIdent, name); - // if (id == WORKSPACE_INVALID) { - // Log::logger->log(Log::ERR, "Invalid workspace identifier found: {}", wsIdent); - // return "Invalid workspace identifier found: " + wsIdent; - // } - // wsRule.monitor = first_ident; - // wsRule.workspaceString = wsIdent; - // wsRule.isDefault = true; // backwards compat - // rules = value.substr(WORKSPACE_DELIM + 1); - // } - - const static std::string ruleOnCreatedEmpty = "on-created-empty:"; - const static auto ruleOnCreatedEmptyLen = ruleOnCreatedEmpty.length(); - -#define CHECK_OR_THROW(expr) \ - \ - auto X = expr; \ - if (!X) { \ - return "Failed parsing a workspace rule"; \ - } - - auto assignRule = [&](std::string rule) -> std::optional { - size_t delim = std::string::npos; - if ((delim = rule.find("gapsin:")) != std::string::npos) { - CVarList2 varlist(rule.substr(delim + 7), 0, ' '); - wsRule.gapsIn = CCssGapData(); - try { - wsRule.gapsIn->parseGapData(varlist); - } catch (...) { return "Error parsing workspace rule gaps: {}", rule.substr(delim + 7); } - } else if ((delim = rule.find("gapsout:")) != std::string::npos) { - CVarList2 varlist(rule.substr(delim + 8), 0, ' '); - wsRule.gapsOut = CCssGapData(); - try { - wsRule.gapsOut->parseGapData(varlist); - } catch (...) { return "Error parsing workspace rule gaps: {}", rule.substr(delim + 8); } - } else if ((delim = rule.find("bordersize:")) != std::string::npos) - try { - wsRule.borderSize = std::stoi(rule.substr(delim + 11)); - } catch (...) { return "Error parsing workspace rule bordersize: {}", rule.substr(delim + 11); } - else if ((delim = rule.find("border:")) != std::string::npos) { - CHECK_OR_THROW(configStringToInt(rule.substr(delim + 7))) - wsRule.noBorder = !*X; - } else if ((delim = rule.find("shadow:")) != std::string::npos) { - CHECK_OR_THROW(configStringToInt(rule.substr(delim + 7))) - wsRule.noShadow = !*X; - } else if ((delim = rule.find("rounding:")) != std::string::npos) { - CHECK_OR_THROW(configStringToInt(rule.substr(delim + 9))) - wsRule.noRounding = !*X; - } else if ((delim = rule.find("decorate:")) != std::string::npos) { - CHECK_OR_THROW(configStringToInt(rule.substr(delim + 9))) - wsRule.decorate = *X; - } else if ((delim = rule.find("monitor:")) != std::string::npos) - wsRule.monitor = rule.substr(delim + 8); - else if ((delim = rule.find("default:")) != std::string::npos) { - CHECK_OR_THROW(configStringToInt(rule.substr(delim + 8))) - wsRule.isDefault = *X; - } else if ((delim = rule.find("persistent:")) != std::string::npos) { - CHECK_OR_THROW(configStringToInt(rule.substr(delim + 11))) - wsRule.isPersistent = *X; - } else if ((delim = rule.find("defaultName:")) != std::string::npos) - wsRule.defaultName = trim(rule.substr(delim + 12)); - else if ((delim = rule.find(ruleOnCreatedEmpty)) != std::string::npos) { - CHECK_OR_THROW(cleanCmdForWorkspace(name, rule.substr(delim + ruleOnCreatedEmptyLen))) - wsRule.onCreatedEmptyRunCmd = *X; - } else if ((delim = rule.find("layoutopt:")) != std::string::npos) { - std::string opt = rule.substr(delim + 10); - if (!opt.contains(":")) { - // invalid - Log::logger->log(Log::ERR, "Invalid workspace rule found: {}", rule); - return "Invalid workspace rule found: " + rule; - } - - std::string val = opt.substr(opt.find(':') + 1); - opt = opt.substr(0, opt.find(':')); - - wsRule.layoutopts[opt] = val; - } else if ((delim = rule.find("layout:")) != std::string::npos) { - std::string layout = rule.substr(delim + 7); - wsRule.layout = std::move(layout); - } else if ((delim = rule.find("animation:")) != std::string::npos) { - std::string animationStyle = rule.substr(delim + 10); - wsRule.animationStyle = std::move(animationStyle); - } - - return {}; - }; - -#undef CHECK_OR_THROW - - CVarList2 rulesList(std::string(rules), 0, ',', true); - for (auto const& r : rulesList) { - const auto R = assignRule(std::string(r)); - if (R.has_value()) - return R; - } - - wsRule.workspaceName = name; - wsRule.workspaceId = isAutoID ? WORKSPACE_INVALID : id; - - const auto IT = std::ranges::find_if(m_workspaceRules, [&](const auto& other) { return other.workspaceString == wsRule.workspaceString; }); - - if (IT == m_workspaceRules.end()) - m_workspaceRules.emplace_back(wsRule); - else - *IT = mergeWorkspaceRules(*IT, wsRule); - - return {}; -} - -std::optional CConfigManager::handleSubmap(const std::string&, const std::string& submap) { - CVarList2 data((std::string(submap))); - m_currentSubmap.name = (data[0] == "reset") ? "" : data[0]; - m_currentSubmap.reset = data[1]; - return {}; -} - -std::optional CConfigManager::handleSource(const std::string& command, const std::string& rawpath) { - if (rawpath.length() < 2) { - Log::logger->log(Log::ERR, "source= path garbage"); - return "source= path " + rawpath + " bogus!"; - } - - std::unique_ptr glob_buf{sc(calloc(1, sizeof(glob_t))), // allocate and zero-initialize NOLINT(cppcoreguidelines-no-malloc) - [](glob_t* g) { - if (g) { - globfree(g); // free internal resources allocated by glob() - free(g); // free the memory for the glob_t structure NOLINT(cppcoreguidelines-no-malloc) - } - }}; - - if (auto r = glob(absolutePath(rawpath, m_configCurrentPath).c_str(), GLOB_TILDE, nullptr, glob_buf.get()); r != 0) { - std::string err = std::format("source= globbing error: {}", r == GLOB_NOMATCH ? "found no match" : GLOB_ABORTED ? "read error" : "out of memory"); - Log::logger->log(Log::ERR, "{}", err); - return err; - } - - std::string errorsFromParsing; - - for (size_t i = 0; i < glob_buf->gl_pathc; i++) { - auto value = absolutePath(glob_buf->gl_pathv[i], m_configCurrentPath); - - std::error_code ec; - auto file_status = std::filesystem::status(value, ec); - - if (ec) { - Log::logger->log(Log::ERR, "source= file from glob result is inaccessible ({}): {}", ec.message(), value); - return "source= file " + value + " is inaccessible!"; - } - - if (std::filesystem::is_regular_file(file_status)) { - m_configPaths.emplace_back(value); - auto configCurrentPathBackup = m_configCurrentPath; - m_configCurrentPath = value; - const auto THISRESULT = m_config->parseFile(value.c_str()); - m_configCurrentPath = configCurrentPathBackup; - if (THISRESULT.error && errorsFromParsing.empty()) - errorsFromParsing += THISRESULT.getError(); - } else if (std::filesystem::is_directory(file_status)) { - Log::logger->log(Log::WARN, "source= skipping directory {}", value); - continue; - } else { - Log::logger->log(Log::WARN, "source= skipping non-regular-file {}", value); - continue; - } - } - - if (errorsFromParsing.empty()) - return {}; - return errorsFromParsing; -} - -std::optional CConfigManager::handleEnv(const std::string& command, const std::string& value) { - const auto ARGS = CVarList(value, 2); - - if (ARGS[0].empty()) - return "env empty"; - - if (!m_isFirstLaunch) { - // check if env changed at all. If it didn't, ignore. If it did, update it. - const auto* ENV = getenv(ARGS[0].c_str()); - if (ENV && ENV == ARGS[1]) - return {}; // env hasn't changed - } - - setenv(ARGS[0].c_str(), ARGS[1].c_str(), 1); - - if (command.back() == 'd') { - // dbus - const auto CMD = -#ifdef USES_SYSTEMD - "systemctl --user import-environment " + ARGS[0] + - " && hash dbus-update-activation-environment 2>/dev/null && " -#endif - "dbus-update-activation-environment --systemd " + - ARGS[0]; - handleRawExec("", CMD); - } - - return {}; -} - -std::optional CConfigManager::handlePlugin(const std::string& command, const std::string& path) { - if (std::ranges::find(m_declaredPlugins, path) != m_declaredPlugins.end()) - return "plugin '" + path + "' declared twice"; - - m_declaredPlugins.push_back(path); - - return {}; -} - -std::optional CConfigManager::handlePermission(const std::string& command, const std::string& value) { - CVarList2 data((std::string(value))); - - eDynamicPermissionType type = PERMISSION_TYPE_UNKNOWN; - eDynamicPermissionAllowMode mode = PERMISSION_RULE_ALLOW_MODE_UNKNOWN; - - if (data[1] == "screencopy") - type = PERMISSION_TYPE_SCREENCOPY; - else if (data[1] == "cursorpos") - type = PERMISSION_TYPE_CURSOR_POS; - else if (data[1] == "plugin") - type = PERMISSION_TYPE_PLUGIN; - else if (data[1] == "keyboard" || data[1] == "keeb") - type = PERMISSION_TYPE_KEYBOARD; - - if (data[2] == "ask") - mode = PERMISSION_RULE_ALLOW_MODE_ASK; - else if (data[2] == "allow") - mode = PERMISSION_RULE_ALLOW_MODE_ALLOW; - else if (data[2] == "deny") - mode = PERMISSION_RULE_ALLOW_MODE_DENY; - - if (type == PERMISSION_TYPE_UNKNOWN) - return "unknown permission type"; - if (mode == PERMISSION_RULE_ALLOW_MODE_UNKNOWN) - return "unknown permission allow mode"; - - if (m_isFirstLaunch && g_pDynamicPermissionManager) - g_pDynamicPermissionManager->addConfigPermissionRule(std::string(data[0]), type, mode); - - return {}; -} - -std::optional CConfigManager::handleGesture(const std::string& command, const std::string& value) { - CVarList2 data((std::string(value))); - - size_t fingerCount = 0; - eTrackpadGestureDirection direction = TRACKPAD_GESTURE_DIR_NONE; - - try { - fingerCount = std::stoul(std::string{data[0]}); - } catch (...) { return std::format("Invalid value {} for finger count", data[0]); } - - if (fingerCount <= 1 || fingerCount >= 10) - return std::format("Invalid value {} for finger count", data[0]); - - direction = g_pTrackpadGestures->dirForString(data[1]); - - if (direction == TRACKPAD_GESTURE_DIR_NONE) - return std::format("Invalid direction: {}", data[1]); - - int startDataIdx = 2; - uint32_t modMask = 0; - float deltaScale = 1.F; - bool disableInhibit = false; - - for (const auto arg : command.substr(7)) { - switch (arg) { - case 'p': disableInhibit = true; break; - default: return "gesture: invalid flag"; - } - } - - while (true) { - - if (data[startDataIdx].starts_with("mod:")) { - modMask = g_pKeybindManager->stringToModMask(std::string{data[startDataIdx].substr(4)}); - startDataIdx++; - continue; - } else if (data[startDataIdx].starts_with("scale:")) { - try { - deltaScale = std::clamp(std::stof(std::string{data[startDataIdx].substr(6)}), 0.1F, 10.F); - startDataIdx++; - continue; - } catch (...) { return std::format("Invalid delta scale: {}", std::string{data[startDataIdx].substr(6)}); } - } - - break; - } - - std::expected result; - - if (data[startDataIdx] == "dispatcher") - result = g_pTrackpadGestures->addGesture(makeUnique(std::string{data[startDataIdx + 1]}, data.join(",", startDataIdx + 2)), fingerCount, - direction, modMask, deltaScale, disableInhibit); - else if (data[startDataIdx] == "workspace") - result = g_pTrackpadGestures->addGesture(makeUnique(), fingerCount, direction, modMask, deltaScale, disableInhibit); - else if (data[startDataIdx] == "resize") - result = g_pTrackpadGestures->addGesture(makeUnique(), fingerCount, direction, modMask, deltaScale, disableInhibit); - else if (data[startDataIdx] == "move") - result = g_pTrackpadGestures->addGesture(makeUnique(), fingerCount, direction, modMask, deltaScale, disableInhibit); - else if (data[startDataIdx] == "special") - result = - g_pTrackpadGestures->addGesture(makeUnique(std::string{data[startDataIdx + 1]}), fingerCount, direction, modMask, deltaScale, disableInhibit); - else if (data[startDataIdx] == "close") - result = g_pTrackpadGestures->addGesture(makeUnique(), fingerCount, direction, modMask, deltaScale, disableInhibit); - else if (data[startDataIdx] == "float") - result = - g_pTrackpadGestures->addGesture(makeUnique(std::string{data[startDataIdx + 1]}), fingerCount, direction, modMask, deltaScale, disableInhibit); - else if (data[startDataIdx] == "fullscreen") - result = g_pTrackpadGestures->addGesture(makeUnique(std::string{data[startDataIdx + 1]}), fingerCount, direction, modMask, deltaScale, - disableInhibit); - else if (data[startDataIdx] == "cursorZoom") { - result = g_pTrackpadGestures->addGesture(makeUnique(std::string{data[startDataIdx + 1]}, std::string{data[startDataIdx + 2]}), fingerCount, - direction, modMask, deltaScale, disableInhibit); - } else if (data[startDataIdx] == "unset") - result = g_pTrackpadGestures->removeGesture(fingerCount, direction, modMask, deltaScale, disableInhibit); - else - return std::format("Invalid gesture: {}", data[startDataIdx]); - - if (!result) - return result.error(); - - return std::nullopt; -} - -std::optional CConfigManager::handleWindowrule(const std::string& command, const std::string& value) { - CVarList2 data((std::string(value))); - - SP rule = makeShared(); - - const auto& PROPS = Desktop::Rule::allMatchPropStrings(); - const auto& EFFECTS = Desktop::Rule::windowEffects()->allEffectStrings(); - - for (const auto& el : data) { - // split on space, no need for a CVarList here - size_t spacePos = el.find(' '); - if (spacePos == std::string::npos) - return std::format("invalid field {}: missing a value", el); - - const bool FIRST_IS_PROP = el.starts_with("match:"); - const auto FIRST = FIRST_IS_PROP ? el.substr(6, spacePos - 6) : el.substr(0, spacePos); - if (FIRST_IS_PROP && std::ranges::contains(PROPS, FIRST)) { - // it's a prop - const auto PROP = Desktop::Rule::matchPropFromString(FIRST); - if (!PROP.has_value()) - return std::format("invalid prop {}", el); - rule->registerMatch(*PROP, std::string{el.substr(spacePos + 1)}); - } else if (!FIRST_IS_PROP && std::ranges::contains(EFFECTS, FIRST)) { - // it's an effect - const auto EFFECT = Desktop::Rule::windowEffects()->get(FIRST); - if (!EFFECT.has_value()) - return std::format("invalid effect {}", el); - rule->addEffect(*EFFECT, std::string{el.substr(spacePos + 1)}); - } else - return std::format("invalid field type {}", FIRST); - } - - m_keywordRules.emplace_back(std::move(rule)); - if (g_pHyprCtl && g_pHyprCtl->m_currentRequestParams.isDynamicKeyword) - Desktop::Rule::ruleEngine()->registerRule(SP{m_keywordRules.back()}); - - return std::nullopt; -} - -std::optional CConfigManager::handleLayerrule(const std::string& command, const std::string& value) { - CVarList2 data((std::string(value))); - - SP rule = makeShared(); - - const auto& PROPS = Desktop::Rule::allMatchPropStrings(); - const auto& EFFECTS = Desktop::Rule::layerEffects()->allEffectStrings(); - - for (const auto& el : data) { - // split on space, no need for a CVarList here - size_t spacePos = el.find(' '); - if (spacePos == std::string::npos) - return std::format("invalid field {}: missing a value", el); - - const bool FIRST_IS_PROP = el.starts_with("match:"); - const auto FIRST = FIRST_IS_PROP ? el.substr(6, spacePos - 6) : el.substr(0, spacePos); - if (FIRST_IS_PROP && std::ranges::contains(PROPS, FIRST)) { - // it's a prop - const auto PROP = Desktop::Rule::matchPropFromString(FIRST); - if (!PROP.has_value()) - return std::format("invalid prop {}", el); - rule->registerMatch(*PROP, std::string{el.substr(spacePos + 1)}); - } else if (!FIRST_IS_PROP && std::ranges::contains(EFFECTS, FIRST)) { - // it's an effect - const auto EFFECT = Desktop::Rule::layerEffects()->get(FIRST); - if (!EFFECT.has_value()) - return std::format("invalid effect {}", el); - rule->addEffect(*EFFECT, std::string{el.substr(spacePos + 1)}); - } else - return std::format("invalid field type {}", FIRST); - } - - m_keywordRules.emplace_back(std::move(rule)); - - return std::nullopt; -} - -const std::vector& CConfigManager::getAllDescriptions() { - return CONFIG_OPTIONS; -} - -bool CConfigManager::shouldUseSoftwareCursors(PHLMONITOR pMonitor) { - static auto PNOHW = CConfigValue("cursor:no_hardware_cursors"); - static auto PINVISIBLE = CConfigValue("cursor:invisible"); - - if (pMonitor->m_tearingState.activelyTearing) - return true; - - if (*PINVISIBLE != 0) - return true; - - switch (*PNOHW) { - case 0: return false; - case 1: return true; - case 2: return g_pHyprRenderer->isNvidia() && (g_pHyprRenderer->isMgpu() || g_pCompositor->isVRRActiveOnAnyMonitor()); - default: break; - } - - return true; -} - -std::string SConfigOptionDescription::jsonify() const { - auto parseData = [this]() -> std::string { - return std::visit( - [this](auto&& val) { - const auto PTR = g_pConfigManager->m_config->getConfigValuePtr(value.c_str()); - if (!PTR) { - Log::logger->log(Log::ERR, "invalid SConfigOptionDescription: no config option {} exists", value); - return std::string{""}; - } - const char* const EXPLICIT = PTR->m_bSetByUser ? "true" : "false"; - - std::string currentValue = "undefined"; - - const auto CONFIGVALUE = PTR->getValue(); - - if (typeid(Hyprlang::INT) == std::type_index(CONFIGVALUE.type())) - currentValue = std::format("{}", std::any_cast(CONFIGVALUE)); - else if (typeid(Hyprlang::FLOAT) == std::type_index(CONFIGVALUE.type())) - currentValue = std::format("{:.2f}", std::any_cast(CONFIGVALUE)); - else if (typeid(Hyprlang::STRING) == std::type_index(CONFIGVALUE.type())) - currentValue = std::format("\"{}\"", std::any_cast(CONFIGVALUE)); - else if (typeid(Hyprlang::VEC2) == std::type_index(CONFIGVALUE.type())) { - const auto V = std::any_cast(CONFIGVALUE); - currentValue = std::format("\"{}, {}\"", V.x, V.y); - } else if (typeid(void*) == std::type_index(CONFIGVALUE.type())) { - const auto DATA = sc(std::any_cast(CONFIGVALUE)); - currentValue = std::format("\"{}\"", DATA->toString()); - } - - try { - using T = std::decay_t; - if constexpr (std::is_same_v) { - return std::format(R"#( "value": "{}", - "current": {}, - "explicit": {})#", - val.value, currentValue, EXPLICIT); - } else if constexpr (std::is_same_v) { - return std::format(R"#( "value": {}, - "min": {}, - "max": {}, - "current": {}, - "explicit": {})#", - val.value, val.min, val.max, currentValue, EXPLICIT); - } else if constexpr (std::is_same_v) { - return std::format(R"#( "value": {}, - "min": {}, - "max": {}, - "current": {}, - "explicit": {})#", - val.value, val.min, val.max, currentValue, EXPLICIT); - } else if constexpr (std::is_same_v) { - return std::format(R"#( "value": "{}", - "current": {}, - "explicit": {})#", - val.color.getAsHex(), currentValue, EXPLICIT); - } else if constexpr (std::is_same_v) { - return std::format(R"#( "value": {}, - "current": {}, - "explicit": {})#", - val.value, currentValue, EXPLICIT); - } else if constexpr (std::is_same_v) { - return std::format(R"#( "value": "{}", - "firstIndex": {}, - "current": {}, - "explicit": {})#", - val.choices, val.firstIndex, currentValue, EXPLICIT); - } else if constexpr (std::is_same_v) { - return std::format(R"#( "x": {}, - "y": {}, - "min_x": {}, - "min_y": {}, - "max_x": {}, - "max_y": {}, - "current": {}, - "explicit": {})#", - val.vec.x, val.vec.y, val.min.x, val.min.y, val.max.x, val.max.y, currentValue, EXPLICIT); - } else if constexpr (std::is_same_v) { - return std::format(R"#( "value": "{}", - "current": {}, - "explicit": {})#", - val.gradient, currentValue, EXPLICIT); - } - - } catch (std::bad_any_cast& e) { Log::logger->log(Log::ERR, "Bad any_cast on value {} in descriptions", value); } - return std::string{""}; - }, - data); - }; - - std::string json = std::format(R"#({{ - "value": "{}", - "description": "{}", - "type": {}, - "flags": {}, - "data": {{ - {} - }} -}})#", - value, escapeJSONStrings(description), sc(type), sc(flags), parseData()); - - return json; -} - -void CConfigManager::ensurePersistentWorkspacesPresent() { - g_pCompositor->ensurePersistentWorkspacesPresent(m_workspaceRules); -} - -void CConfigManager::storeFloatingSize(PHLWINDOW window, const Vector2D& size) { - Log::logger->log(Log::DEBUG, "storing floating size {}x{} for window {}::{}", size.x, size.y, window->m_initialClass, window->m_initialTitle); - // true -> use m_initialClass and m_initialTitle - SFloatCache id{window, true}; - m_mStoredFloatingSizes[id] = size; -} - -std::optional CConfigManager::getStoredFloatingSize(PHLWINDOW window) { - // At startup, m_initialClass and m_initialTitle are undefined - // and m_class and m_title are just "initial" ones. - // false -> use m_class and m_title - SFloatCache id{window, false}; - Log::logger->log(Log::DEBUG, "Hash for window {}::{} = {}", window->m_class, window->m_title, id.hash); - if (m_mStoredFloatingSizes.contains(id)) { - Log::logger->log(Log::DEBUG, "got stored size {}x{} for window {}::{}", m_mStoredFloatingSizes[id].x, m_mStoredFloatingSizes[id].y, window->m_class, window->m_title); - return m_mStoredFloatingSizes[id]; - } - return std::nullopt; -} +UP& Config::mgr() { + return g_mgr; +} \ No newline at end of file -- cgit v1.2.3