diff --git a/src/config/ConfigValue.cpp b/src/config/ConfigValue.cpp new file mode 100644 index 000000000..9f6cc3191 --- /dev/null +++ b/src/config/ConfigValue.cpp @@ -0,0 +1,15 @@ +#include "ConfigValue.hpp" +#include "ConfigManager.hpp" +#include "../macros.hpp" + +void local__configValuePopulate(void* const** p, const std::string& val) { + const auto PVHYPRLANG = g_pConfigManager->getHyprlangConfigValuePtr(val); + + *p = PVHYPRLANG->getDataStaticPtr(); +} + +std::type_index local__configValueTypeIdx(const std::string& val) { + const auto PVHYPRLANG = g_pConfigManager->getHyprlangConfigValuePtr(val); + const auto ANY = PVHYPRLANG->getValue(); + return std::type_index(ANY.type()); +} \ No newline at end of file diff --git a/src/config/ConfigValue.hpp b/src/config/ConfigValue.hpp index 089ae8bf4..a159bf8cc 100644 --- a/src/config/ConfigValue.hpp +++ b/src/config/ConfigValue.hpp @@ -4,21 +4,19 @@ #include #include #include "../macros.hpp" -#include "ConfigManager.hpp" + +// giga hack to avoid including configManager here +// NOLINTNEXTLINE +void local__configValuePopulate(void* const** p, const std::string& val); +std::type_index local__configValueTypeIdx(const std::string& val); template class CConfigValue { public: CConfigValue(const std::string& val) { - const auto PVHYPRLANG = g_pConfigManager->getHyprlangConfigValuePtr(val); - - // NOLINTNEXTLINE - p_ = PVHYPRLANG->getDataStaticPtr(); - #ifdef HYPRLAND_DEBUG // verify type - const auto ANY = PVHYPRLANG->getValue(); - const auto TYPE = std::type_index(ANY.type()); + const auto TYPE = local__configValueTypeIdx(val); // exceptions const bool STRINGEX = (typeid(T) == typeid(std::string) && TYPE == typeid(Hyprlang::STRING)); @@ -26,6 +24,8 @@ class CConfigValue { RASSERT(typeid(T) == TYPE || STRINGEX || CUSTOMEX, "Mismatched type in CConfigValue, got {} but has {}", typeid(T).name(), TYPE.name()); #endif + + local__configValuePopulate(&p_, val); } T* ptr() const { diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp index 4b9a07fcb..323aa03a4 100644 --- a/src/desktop/Window.cpp +++ b/src/desktop/Window.cpp @@ -11,6 +11,7 @@ #include "../render/decorations/CHyprGroupBarDecoration.hpp" #include "../render/decorations/CHyprBorderDecoration.hpp" #include "../config/ConfigValue.hpp" +#include "../config/ConfigManager.hpp" #include "../managers/TokenManager.hpp" #include "../managers/AnimationManager.hpp" #include "../managers/ANRManager.hpp" @@ -780,7 +781,7 @@ void CWindow::applyDynamicRule(const SP& r) { const CVarList VARS(r->szRule, 0, ' '); if (auto search = NWindowProperties::intWindowProperties.find(VARS[1]); search != NWindowProperties::intWindowProperties.end()) { try { - *(search->second(m_pSelf.lock())) = CWindowOverridableVar(std::stoi(VARS[2]), priority); + *(search->second(m_pSelf.lock())) = CWindowOverridableVar(Hyprlang::INT(std::stoi(VARS[2])), priority); } catch (std::exception& e) { Debug::log(ERR, "Rule \"{}\" failed with: {}", r->szRule, e.what()); } } else if (auto search = NWindowProperties::floatWindowProperties.find(VARS[1]); search != NWindowProperties::floatWindowProperties.end()) { try { diff --git a/src/desktop/Window.hpp b/src/desktop/Window.hpp index b314eca5b..f592aed66 100644 --- a/src/desktop/Window.hpp +++ b/src/desktop/Window.hpp @@ -19,6 +19,7 @@ #include "WLSurface.hpp" #include "Workspace.hpp" #include "WindowRule.hpp" +#include "WindowOverridableVar.hpp" #include "../protocols/types/ContentType.hpp" class CXDGSurfaceResource; @@ -77,88 +78,6 @@ struct SAlphaValue { }; }; -enum eOverridePriority : uint8_t { - PRIORITY_LAYOUT = 0, - PRIORITY_WORKSPACE_RULE, - PRIORITY_WINDOW_RULE, - PRIORITY_SET_PROP, -}; - -template -class CWindowOverridableVar { - public: - CWindowOverridableVar(T const& value, eOverridePriority priority) { - values[priority] = value; - } - CWindowOverridableVar(T const& value) : defaultValue{value} {} - - CWindowOverridableVar() = default; - ~CWindowOverridableVar() = default; - - CWindowOverridableVar& operator=(CWindowOverridableVar const& other) { - // Self-assignment check - if (this == &other) - return *this; - - for (auto const& value : other.values) { - values[value.first] = value.second; - } - - return *this; - } - - void unset(eOverridePriority priority) { - values.erase(priority); - } - - bool hasValue() { - return !values.empty(); - } - - T value() { - if (!values.empty()) - return std::prev(values.end())->second; - else - throw std::bad_optional_access(); - } - - T valueOr(T const& other) { - if (hasValue()) - return value(); - else - return other; - } - - T valueOrDefault() { - return valueOr(defaultValue); - } - - eOverridePriority getPriority() { - if (!values.empty()) - return std::prev(values.end())->first; - else - throw std::bad_optional_access(); - } - - void matchOptional(std::optional const& optValue, eOverridePriority priority) { - if (optValue.has_value()) - values[priority] = optValue.value(); - else - unset(priority); - } - - operator std::optional() { - if (hasValue()) - return value(); - else - return std::nullopt; - } - - private: - std::map values; - T defaultValue; // used for toggling, so required for bool -}; - struct SWindowData { CWindowOverridableVar alpha = SAlphaValue{1.f, false}; CWindowOverridableVar alphaInactive = SAlphaValue{1.f, false}; @@ -186,12 +105,12 @@ struct SWindowData { CWindowOverridableVar xray = false; CWindowOverridableVar renderUnfocused = false; - CWindowOverridableVar rounding; - CWindowOverridableVar roundingPower; - CWindowOverridableVar borderSize; + CWindowOverridableVar borderSize = {std::string("general:border_size"), Hyprlang::INT(0), std::nullopt}; + CWindowOverridableVar rounding = {std::string("decoration:rounding"), Hyprlang::INT(0), std::nullopt}; - CWindowOverridableVar scrollMouse; - CWindowOverridableVar scrollTouchpad; + CWindowOverridableVar roundingPower = {std::string("decoration:rounding_power")}; + CWindowOverridableVar scrollMouse = {std::string("input:scroll_factor")}; + CWindowOverridableVar scrollTouchpad = {std::string("input:touchpad:scroll_factor")}; CWindowOverridableVar animationStyle; CWindowOverridableVar maxSize; @@ -567,12 +486,12 @@ namespace NWindowProperties { {"xray", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.xray; }}, }; - const std::unordered_map*(const PHLWINDOW&)>> intWindowProperties = { + const std::unordered_map*(const PHLWINDOW&)>> intWindowProperties = { {"rounding", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.rounding; }}, {"bordersize", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.borderSize; }}, }; - const std::unordered_map*(PHLWINDOW)>> floatWindowProperties = { + const std::unordered_map*(PHLWINDOW)>> floatWindowProperties = { {"roundingpower", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.roundingPower; }}, {"scrollmouse", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.scrollMouse; }}, {"scrolltouchpad", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.scrollTouchpad; }}, diff --git a/src/desktop/WindowOverridableVar.hpp b/src/desktop/WindowOverridableVar.hpp new file mode 100644 index 000000000..ea113d3e6 --- /dev/null +++ b/src/desktop/WindowOverridableVar.hpp @@ -0,0 +1,132 @@ +#pragma once + +#include +#include +#include +#include "../config/ConfigValue.hpp" + +enum eOverridePriority : uint8_t { + PRIORITY_LAYOUT = 0, + PRIORITY_WORKSPACE_RULE, + PRIORITY_WINDOW_RULE, + PRIORITY_SET_PROP, +}; + +template +T clampOptional(T const& value, std::optional const& min, std::optional const& max) { + return std::clamp(value, min.value_or(std::numeric_limits::min()), max.value_or(std::numeric_limits::max())); +} + +template || std::is_same_v || std::is_same_v> +class CWindowOverridableVar { + public: + CWindowOverridableVar(T const& value, eOverridePriority priority) { + m_values[priority] = value; + } + + CWindowOverridableVar(T const& value) : m_defaultValue{value} {} + CWindowOverridableVar(T const& value, std::optional const& min, std::optional const& max = std::nullopt) : m_defaultValue{value}, m_minValue{min}, m_maxValue{max} {} + CWindowOverridableVar(std::string const& value) + requires(Extended && !std::is_same_v) + : m_configValue(SP>(new CConfigValue(value))) {} + CWindowOverridableVar(std::string const& value, std::optional const& min, std::optional const& max = std::nullopt) + requires(Extended && !std::is_same_v) + : m_minValue(min), m_maxValue(max), m_configValue(SP>(new CConfigValue(value))) {} + + CWindowOverridableVar() = default; + ~CWindowOverridableVar() = default; + + CWindowOverridableVar& operator=(CWindowOverridableVar const& other) { + // Self-assignment check + if (this == &other) + return *this; + + for (auto const& value : other.m_values) { + if constexpr (Extended && !std::is_same_v) + m_values[value.first] = clampOptional(value.second, m_minValue, m_maxValue); + else + m_values[value.first] = value.second; + } + + return *this; + } + + void unset(eOverridePriority priority) { + m_values.erase(priority); + } + + bool hasValue() { + return !m_values.empty(); + } + + T value() { + if (!m_values.empty()) + return std::prev(m_values.end())->second; + else + throw std::bad_optional_access(); + } + + T valueOr(T const& other) { + if (hasValue()) + return value(); + else + return other; + } + + T valueOrDefault() + requires(Extended && !std::is_same_v) + { + if (hasValue()) + return value(); + else if (m_defaultValue.has_value()) + return m_defaultValue.value(); + else + return **std::any_cast>>(m_configValue); + } + + T valueOrDefault() + requires(!Extended || std::is_same_v) + { + if (hasValue()) + return value(); + else if (!m_defaultValue.has_value()) + throw std::bad_optional_access(); + else + return m_defaultValue.value(); + } + + eOverridePriority getPriority() { + if (!m_values.empty()) + return std::prev(m_values.end())->first; + else + throw std::bad_optional_access(); + } + + void increment(T const& other, eOverridePriority priority) { + if constexpr (std::is_same_v) + m_values[priority] = valueOr(false) ^ other; + else + m_values[priority] = clampOptional(valueOrDefault() + other, m_minValue, m_maxValue); + } + + void matchOptional(std::optional const& optValue, eOverridePriority priority) { + if (optValue.has_value()) + m_values[priority] = optValue.value(); + else + unset(priority); + } + + operator std::optional() { + if (hasValue()) + return value(); + else + return std::nullopt; + } + + private: + std::map m_values; + std::optional m_defaultValue; // used for toggling, so required for bool + std::optional m_minValue; + std::optional m_maxValue; + std::any m_configValue; // only there for select variables +}; diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp index adc0c7623..452e977dc 100644 --- a/src/events/Windows.cpp +++ b/src/events/Windows.cpp @@ -7,6 +7,7 @@ #include "../managers/SeatManager.hpp" #include "../render/Renderer.hpp" #include "../config/ConfigValue.hpp" +#include "../config/ConfigManager.hpp" #include "../protocols/LayerShell.hpp" #include "../protocols/XDGShell.hpp" #include "../protocols/core/Compositor.hpp" diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp index e30849a7b..495cecbc0 100644 --- a/src/helpers/Monitor.cpp +++ b/src/helpers/Monitor.cpp @@ -6,6 +6,7 @@ #include "sync/SyncReleaser.hpp" #include "../Compositor.hpp" #include "../config/ConfigValue.hpp" +#include "../config/ConfigManager.hpp" #include "../protocols/GammaControl.hpp" #include "../devices/ITouch.hpp" #include "../protocols/LayerShell.hpp" diff --git a/src/hyprerror/HyprError.cpp b/src/hyprerror/HyprError.cpp index 9f889fdf8..75b04286b 100644 --- a/src/hyprerror/HyprError.cpp +++ b/src/hyprerror/HyprError.cpp @@ -2,6 +2,7 @@ #include "HyprError.hpp" #include "../Compositor.hpp" #include "../config/ConfigValue.hpp" +#include "../config/ConfigManager.hpp" #include "../render/pass/TexPassElement.hpp" #include "../managers/AnimationManager.hpp" #include "../render/Renderer.hpp" diff --git a/src/layout/DwindleLayout.cpp b/src/layout/DwindleLayout.cpp index 0058c890a..90cc2f6c4 100644 --- a/src/layout/DwindleLayout.cpp +++ b/src/layout/DwindleLayout.cpp @@ -1,6 +1,7 @@ #include "DwindleLayout.hpp" #include "../Compositor.hpp" #include "../config/ConfigValue.hpp" +#include "../config/ConfigManager.hpp" #include "../render/decorations/CHyprGroupBarDecoration.hpp" #include "../render/Renderer.hpp" #include "../managers/input/InputManager.hpp" diff --git a/src/layout/IHyprLayout.cpp b/src/layout/IHyprLayout.cpp index c7607377f..e87267da5 100644 --- a/src/layout/IHyprLayout.cpp +++ b/src/layout/IHyprLayout.cpp @@ -3,6 +3,7 @@ #include "../Compositor.hpp" #include "../render/decorations/CHyprGroupBarDecoration.hpp" #include "../config/ConfigValue.hpp" +#include "../config/ConfigManager.hpp" #include "../desktop/Window.hpp" #include "../protocols/XDGShell.hpp" #include "../protocols/core/Compositor.hpp" diff --git a/src/layout/MasterLayout.cpp b/src/layout/MasterLayout.cpp index 59a5b14f1..a02e6abaf 100644 --- a/src/layout/MasterLayout.cpp +++ b/src/layout/MasterLayout.cpp @@ -4,6 +4,7 @@ #include "config/ConfigDataValues.hpp" #include #include "../config/ConfigValue.hpp" +#include "../config/ConfigManager.hpp" #include "../render/Renderer.hpp" #include "../managers/input/InputManager.hpp" #include "../managers/LayoutManager.hpp" diff --git a/src/managers/CursorManager.cpp b/src/managers/CursorManager.cpp index ee0cff351..1535734ba 100644 --- a/src/managers/CursorManager.cpp +++ b/src/managers/CursorManager.cpp @@ -4,6 +4,7 @@ #include "PointerManager.hpp" #include "../xwayland/XWayland.hpp" #include "../managers/HookSystemManager.hpp" +#include "../helpers/Monitor.hpp" static int cursorAnimTimer(SP self, void* data) { const auto cursorMgr = reinterpret_cast(data); diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index 2644cf535..4ef7d2296 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -18,6 +18,7 @@ #include "../managers/EventManager.hpp" #include "../render/Renderer.hpp" #include "../hyprerror/HyprError.hpp" +#include "../config/ConfigManager.hpp" #include #include @@ -3221,7 +3222,7 @@ SDispatchResult CKeybindManager::setProp(std::string args) { } else if (auto search = NWindowProperties::boolWindowProperties.find(PROP); search != NWindowProperties::boolWindowProperties.end()) { auto pWindowDataElement = search->second(PWINDOW); if (VAL == "toggle") - *pWindowDataElement = CWindowOverridableVar(!pWindowDataElement->valueOrDefault(), PRIORITY_SET_PROP); + pWindowDataElement->increment(true, PRIORITY_SET_PROP); else if (VAL == "unset") pWindowDataElement->unset(PRIORITY_SET_PROP); else @@ -3229,12 +3230,18 @@ SDispatchResult CKeybindManager::setProp(std::string args) { } else if (auto search = NWindowProperties::intWindowProperties.find(PROP); search != NWindowProperties::intWindowProperties.end()) { if (VAL == "unset") search->second(PWINDOW)->unset(PRIORITY_SET_PROP); - else if (const auto V = configStringToInt(VAL); V) - *(search->second(PWINDOW)) = CWindowOverridableVar((int)*V, PRIORITY_SET_PROP); + else if (VAL.starts_with("relative")) { + const Hyprlang::INT V = std::stoi(VAL.substr(VAL.find(' '))); + search->second(PWINDOW)->increment(V, PRIORITY_SET_PROP); + } else if (const auto V = configStringToInt(VAL); V) + *(search->second(PWINDOW)) = CWindowOverridableVar((Hyprlang::INT)*V, PRIORITY_SET_PROP); } else if (auto search = NWindowProperties::floatWindowProperties.find(PROP); search != NWindowProperties::floatWindowProperties.end()) { if (VAL == "unset") search->second(PWINDOW)->unset(PRIORITY_SET_PROP); - else { + else if (VAL.starts_with("relative")) { + const auto V = std::stof(VAL.substr(VAL.find(' '))); + search->second(PWINDOW)->increment(V, PRIORITY_SET_PROP); + } else { const auto V = std::stof(VAL); *(search->second(PWINDOW)) = CWindowOverridableVar(V, PRIORITY_SET_PROP); } diff --git a/src/managers/PointerManager.cpp b/src/managers/PointerManager.cpp index 89be4e990..e116aa963 100644 --- a/src/managers/PointerManager.cpp +++ b/src/managers/PointerManager.cpp @@ -1,6 +1,7 @@ #include "PointerManager.hpp" #include "../Compositor.hpp" #include "../config/ConfigValue.hpp" +#include "../config/ConfigManager.hpp" #include "../protocols/PointerGestures.hpp" #include "../protocols/RelativePointer.hpp" #include "../protocols/FractionalScale.hpp" diff --git a/src/managers/XWaylandManager.cpp b/src/managers/XWaylandManager.cpp index 9d2fda1d7..e8481a26f 100644 --- a/src/managers/XWaylandManager.cpp +++ b/src/managers/XWaylandManager.cpp @@ -2,6 +2,7 @@ #include "../Compositor.hpp" #include "../events/Events.hpp" #include "../config/ConfigValue.hpp" +#include "../helpers/Monitor.hpp" #include "../protocols/XDGShell.hpp" #include "../protocols/core/Compositor.hpp" #include "../xwayland/XWayland.hpp" diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp index 2153b916f..4c5de729c 100644 --- a/src/managers/input/InputManager.cpp +++ b/src/managers/input/InputManager.cpp @@ -4,6 +4,7 @@ #include #include #include "../../config/ConfigValue.hpp" +#include "../../config/ConfigManager.hpp" #include "../../desktop/Window.hpp" #include "../../desktop/LayerSurface.hpp" #include "../../protocols/CursorShape.hpp" diff --git a/src/managers/input/Touch.cpp b/src/managers/input/Touch.cpp index a166a2569..6b6cc376c 100644 --- a/src/managers/input/Touch.cpp +++ b/src/managers/input/Touch.cpp @@ -4,6 +4,7 @@ #include "../../Compositor.hpp" #include "../../desktop/LayerSurface.hpp" #include "../../config/ConfigValue.hpp" +#include "../../helpers/Monitor.hpp" #include "../../devices/ITouch.hpp" #include "../SeatManager.hpp" #include "managers/AnimationManager.hpp" diff --git a/src/protocols/CTMControl.cpp b/src/protocols/CTMControl.cpp index 750c6f8b5..c3b6862df 100644 --- a/src/protocols/CTMControl.cpp +++ b/src/protocols/CTMControl.cpp @@ -3,6 +3,7 @@ #include "../render/Renderer.hpp" #include "core/Output.hpp" #include "../config/ConfigValue.hpp" +#include "../config/ConfigManager.hpp" #include "managers/AnimationManager.hpp" #include "../helpers/Monitor.hpp" diff --git a/src/protocols/XDGOutput.cpp b/src/protocols/XDGOutput.cpp index 544deed05..e95b9c7d6 100644 --- a/src/protocols/XDGOutput.cpp +++ b/src/protocols/XDGOutput.cpp @@ -1,5 +1,6 @@ #include "XDGOutput.hpp" #include "../config/ConfigValue.hpp" +#include "../helpers/Monitor.hpp" #include "../xwayland/XWayland.hpp" #include "../managers/HookSystemManager.hpp" #include "core/Output.hpp" diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index eaea31bef..27d3671fb 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -7,6 +7,7 @@ #include "../Compositor.hpp" #include "../helpers/MiscFunctions.hpp" #include "../config/ConfigValue.hpp" +#include "../config/ConfigManager.hpp" #include "../desktop/LayerSurface.hpp" #include "../protocols/LayerShell.hpp" #include "../protocols/core/Compositor.hpp" diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index dc5c1284c..1ce717bca 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -6,6 +6,7 @@ #include #include #include "../config/ConfigValue.hpp" +#include "../config/ConfigManager.hpp" #include "../managers/CursorManager.hpp" #include "../managers/PointerManager.hpp" #include "../managers/input/InputManager.hpp"