windowrules: allow incrementing window props (#9566)
This commit is contained in:
parent
8b7b169043
commit
ffd6cf65e4
21 changed files with 191 additions and 102 deletions
|
|
@ -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<CWindowRule>& 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 {
|
||||
|
|
|
|||
|
|
@ -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 <typename T>
|
||||
class CWindowOverridableVar {
|
||||
public:
|
||||
CWindowOverridableVar(T const& value, eOverridePriority priority) {
|
||||
values[priority] = value;
|
||||
}
|
||||
CWindowOverridableVar(T const& value) : defaultValue{value} {}
|
||||
|
||||
CWindowOverridableVar() = default;
|
||||
~CWindowOverridableVar() = default;
|
||||
|
||||
CWindowOverridableVar<T>& operator=(CWindowOverridableVar<T> 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<T> const& optValue, eOverridePriority priority) {
|
||||
if (optValue.has_value())
|
||||
values[priority] = optValue.value();
|
||||
else
|
||||
unset(priority);
|
||||
}
|
||||
|
||||
operator std::optional<T>() {
|
||||
if (hasValue())
|
||||
return value();
|
||||
else
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
private:
|
||||
std::map<eOverridePriority, T> values;
|
||||
T defaultValue; // used for toggling, so required for bool
|
||||
};
|
||||
|
||||
struct SWindowData {
|
||||
CWindowOverridableVar<SAlphaValue> alpha = SAlphaValue{1.f, false};
|
||||
CWindowOverridableVar<SAlphaValue> alphaInactive = SAlphaValue{1.f, false};
|
||||
|
|
@ -186,12 +105,12 @@ struct SWindowData {
|
|||
CWindowOverridableVar<bool> xray = false;
|
||||
CWindowOverridableVar<bool> renderUnfocused = false;
|
||||
|
||||
CWindowOverridableVar<int> rounding;
|
||||
CWindowOverridableVar<float> roundingPower;
|
||||
CWindowOverridableVar<int> borderSize;
|
||||
CWindowOverridableVar<Hyprlang::INT> borderSize = {std::string("general:border_size"), Hyprlang::INT(0), std::nullopt};
|
||||
CWindowOverridableVar<Hyprlang::INT> rounding = {std::string("decoration:rounding"), Hyprlang::INT(0), std::nullopt};
|
||||
|
||||
CWindowOverridableVar<float> scrollMouse;
|
||||
CWindowOverridableVar<float> scrollTouchpad;
|
||||
CWindowOverridableVar<Hyprlang::FLOAT> roundingPower = {std::string("decoration:rounding_power")};
|
||||
CWindowOverridableVar<Hyprlang::FLOAT> scrollMouse = {std::string("input:scroll_factor")};
|
||||
CWindowOverridableVar<Hyprlang::FLOAT> scrollTouchpad = {std::string("input:touchpad:scroll_factor")};
|
||||
|
||||
CWindowOverridableVar<std::string> animationStyle;
|
||||
CWindowOverridableVar<Vector2D> maxSize;
|
||||
|
|
@ -567,12 +486,12 @@ namespace NWindowProperties {
|
|||
{"xray", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.xray; }},
|
||||
};
|
||||
|
||||
const std::unordered_map<std::string, std::function<CWindowOverridableVar<int>*(const PHLWINDOW&)>> intWindowProperties = {
|
||||
const std::unordered_map<std::string, std::function<CWindowOverridableVar<Hyprlang::INT>*(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<std::string, std::function<CWindowOverridableVar<float>*(PHLWINDOW)>> floatWindowProperties = {
|
||||
const std::unordered_map<std::string, std::function<CWindowOverridableVar<Hyprlang::FLOAT>*(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; }},
|
||||
|
|
|
|||
132
src/desktop/WindowOverridableVar.hpp
Normal file
132
src/desktop/WindowOverridableVar.hpp
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
#include <any>
|
||||
#include "../config/ConfigValue.hpp"
|
||||
|
||||
enum eOverridePriority : uint8_t {
|
||||
PRIORITY_LAYOUT = 0,
|
||||
PRIORITY_WORKSPACE_RULE,
|
||||
PRIORITY_WINDOW_RULE,
|
||||
PRIORITY_SET_PROP,
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
T clampOptional(T const& value, std::optional<T> const& min, std::optional<T> const& max) {
|
||||
return std::clamp(value, min.value_or(std::numeric_limits<T>::min()), max.value_or(std::numeric_limits<T>::max()));
|
||||
}
|
||||
|
||||
template <typename T, bool Extended = std::is_same_v<T, bool> || std::is_same_v<T, Hyprlang::INT> || std::is_same_v<T, Hyprlang::FLOAT>>
|
||||
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<T> const& min, std::optional<T> const& max = std::nullopt) : m_defaultValue{value}, m_minValue{min}, m_maxValue{max} {}
|
||||
CWindowOverridableVar(std::string const& value)
|
||||
requires(Extended && !std::is_same_v<T, bool>)
|
||||
: m_configValue(SP<CConfigValue<T>>(new CConfigValue<T>(value))) {}
|
||||
CWindowOverridableVar(std::string const& value, std::optional<T> const& min, std::optional<T> const& max = std::nullopt)
|
||||
requires(Extended && !std::is_same_v<T, bool>)
|
||||
: m_minValue(min), m_maxValue(max), m_configValue(SP<CConfigValue<T>>(new CConfigValue<T>(value))) {}
|
||||
|
||||
CWindowOverridableVar() = default;
|
||||
~CWindowOverridableVar() = default;
|
||||
|
||||
CWindowOverridableVar& operator=(CWindowOverridableVar<T> const& other) {
|
||||
// Self-assignment check
|
||||
if (this == &other)
|
||||
return *this;
|
||||
|
||||
for (auto const& value : other.m_values) {
|
||||
if constexpr (Extended && !std::is_same_v<T, bool>)
|
||||
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<T, bool>)
|
||||
{
|
||||
if (hasValue())
|
||||
return value();
|
||||
else if (m_defaultValue.has_value())
|
||||
return m_defaultValue.value();
|
||||
else
|
||||
return **std::any_cast<SP<CConfigValue<T>>>(m_configValue);
|
||||
}
|
||||
|
||||
T valueOrDefault()
|
||||
requires(!Extended || std::is_same_v<T, bool>)
|
||||
{
|
||||
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<T, bool>)
|
||||
m_values[priority] = valueOr(false) ^ other;
|
||||
else
|
||||
m_values[priority] = clampOptional(valueOrDefault() + other, m_minValue, m_maxValue);
|
||||
}
|
||||
|
||||
void matchOptional(std::optional<T> const& optValue, eOverridePriority priority) {
|
||||
if (optValue.has_value())
|
||||
m_values[priority] = optValue.value();
|
||||
else
|
||||
unset(priority);
|
||||
}
|
||||
|
||||
operator std::optional<T>() {
|
||||
if (hasValue())
|
||||
return value();
|
||||
else
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
private:
|
||||
std::map<eOverridePriority, T> m_values;
|
||||
std::optional<T> m_defaultValue; // used for toggling, so required for bool
|
||||
std::optional<T> m_minValue;
|
||||
std::optional<T> m_maxValue;
|
||||
std::any m_configValue; // only there for select variables
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue