windowrules: Make min/maxsize rules dynamic (#4775)

* rebase

* simplify and remove prop

* Stuff

- add back win prop
- change minsize defaults
- change request formatting for setprop

* style fix

* remove empty line

* change defaults

* redo string to vec

* remove redundant parsing

* change to vec

* support commas

* remove static rules

* take out garbage

* format

* don't allow commas and resize on setprop

* use isNumber
This commit is contained in:
Epilepsy Gatherings 2024-03-07 21:24:44 -05:00 committed by GitHub
parent ceecdd0fd5
commit e52d3fa852
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 87 additions and 55 deletions

View file

@ -687,6 +687,22 @@ void CWindow::applyDynamicRule(const SWindowRule& r) {
m_eIdleInhibitMode = IDLEINHIBIT_FULLSCREEN;
else
Debug::log(ERR, "Rule idleinhibit: unknown mode {}", IDLERULE);
} else if (r.szRule.starts_with("maxsize")) {
try {
m_sAdditionalConfigData.maxSize = configStringToVector2D(r.szRule.substr(8));
m_vRealSize = Vector2D(std::min((double)m_sAdditionalConfigData.maxSize.toUnderlying().x, m_vRealSize.goal().x),
std::min((double)m_sAdditionalConfigData.maxSize.toUnderlying().y, m_vRealSize.goal().y));
g_pXWaylandManager->setWindowSize(this, m_vRealSize.goal());
setHidden(false);
} catch (std::exception& e) { Debug::log(ERR, "maxsize rule \"{}\" failed with: {}", r.szRule, e.what()); }
} else if (r.szRule.starts_with("minsize")) {
try {
m_sAdditionalConfigData.minSize = configStringToVector2D(r.szRule.substr(8));
m_vRealSize = Vector2D(std::max((double)m_sAdditionalConfigData.minSize.toUnderlying().x, m_vRealSize.goal().x),
std::max((double)m_sAdditionalConfigData.minSize.toUnderlying().y, m_vRealSize.goal().y));
g_pXWaylandManager->setWindowSize(this, m_vRealSize.goal());
setHidden(false);
} catch (std::exception& e) { Debug::log(ERR, "minsize rule \"{}\" failed with: {}", r.szRule, e.what()); }
}
}
@ -701,6 +717,8 @@ void CWindow::updateDynamicRules() {
m_sAdditionalConfigData.forceNoDim = false;
if (!m_sAdditionalConfigData.forceOpaqueOverridden)
m_sAdditionalConfigData.forceOpaque = false;
m_sAdditionalConfigData.maxSize = Vector2D(std::numeric_limits<double>::max(), std::numeric_limits<double>::max());
m_sAdditionalConfigData.minSize = Vector2D(1, 1);
m_sAdditionalConfigData.forceNoAnims = false;
m_sAdditionalConfigData.animationStyle = std::string("");
m_sAdditionalConfigData.rounding = -1;

View file

@ -142,26 +142,28 @@ struct SWindowSpecialRenderData {
};
struct SWindowAdditionalConfigData {
std::string animationStyle = std::string("");
CWindowOverridableVar<int> rounding = -1; // -1 means no
CWindowOverridableVar<bool> forceNoBlur = false;
CWindowOverridableVar<bool> forceOpaque = false;
CWindowOverridableVar<bool> forceOpaqueOverridden = false; // if true, a rule will not change the forceOpaque state. This is for the force opaque dispatcher.
CWindowOverridableVar<bool> forceAllowsInput = false;
CWindowOverridableVar<bool> forceNoAnims = false;
CWindowOverridableVar<bool> forceNoBorder = false;
CWindowOverridableVar<bool> forceNoShadow = false;
CWindowOverridableVar<bool> forceNoDim = false;
CWindowOverridableVar<bool> noFocus = false;
CWindowOverridableVar<bool> windowDanceCompat = false;
CWindowOverridableVar<bool> noMaxSize = false;
CWindowOverridableVar<bool> dimAround = false;
CWindowOverridableVar<bool> forceRGBX = false;
CWindowOverridableVar<bool> keepAspectRatio = false;
CWindowOverridableVar<int> xray = -1; // -1 means unset, takes precedence over the renderdata one
CWindowOverridableVar<int> borderSize = -1; // -1 means unset, takes precedence over the renderdata one
CWindowOverridableVar<bool> forceTearing = false;
CWindowOverridableVar<bool> nearestNeighbor = false;
std::string animationStyle = std::string("");
CWindowOverridableVar<int> rounding = -1; // -1 means no
CWindowOverridableVar<bool> forceNoBlur = false;
CWindowOverridableVar<bool> forceOpaque = false;
CWindowOverridableVar<bool> forceOpaqueOverridden = false; // if true, a rule will not change the forceOpaque state. This is for the force opaque dispatcher.
CWindowOverridableVar<bool> forceAllowsInput = false;
CWindowOverridableVar<bool> forceNoAnims = false;
CWindowOverridableVar<bool> forceNoBorder = false;
CWindowOverridableVar<bool> forceNoShadow = false;
CWindowOverridableVar<bool> forceNoDim = false;
CWindowOverridableVar<bool> noFocus = false;
CWindowOverridableVar<bool> windowDanceCompat = false;
CWindowOverridableVar<bool> noMaxSize = false;
CWindowOverridableVar<Vector2D> maxSize = Vector2D(std::numeric_limits<double>::max(), std::numeric_limits<double>::max());
CWindowOverridableVar<Vector2D> minSize = Vector2D(1, 1);
CWindowOverridableVar<bool> dimAround = false;
CWindowOverridableVar<bool> forceRGBX = false;
CWindowOverridableVar<bool> keepAspectRatio = false;
CWindowOverridableVar<int> xray = -1; // -1 means unset, takes precedence over the renderdata one
CWindowOverridableVar<int> borderSize = -1; // -1 means unset, takes precedence over the renderdata one
CWindowOverridableVar<bool> forceTearing = false;
CWindowOverridableVar<bool> nearestNeighbor = false;
};
struct SWindowRule {

View file

@ -1147,11 +1147,8 @@ std::string dispatchSetProp(eHyprCtlOutputFormat format, std::string request) {
bool lock = false;
if (vars.size() > 4) {
if (vars[4].starts_with("lock")) {
lock = true;
}
}
if (request.ends_with("lock"))
lock = true;
try {
if (PROP == "animationstyle") {
@ -1180,6 +1177,22 @@ std::string dispatchSetProp(eHyprCtlOutputFormat format, std::string request) {
PWINDOW->m_sAdditionalConfigData.windowDanceCompat.forceSetIgnoreLocked(configStringToInt(VAL), lock);
} else if (PROP == "nomaxsize") {
PWINDOW->m_sAdditionalConfigData.noMaxSize.forceSetIgnoreLocked(configStringToInt(VAL), lock);
} else if (PROP == "maxsize") {
PWINDOW->m_sAdditionalConfigData.maxSize.forceSetIgnoreLocked(configStringToVector2D(VAL + " " + vars[4]), lock);
if (lock) {
PWINDOW->m_vRealSize = Vector2D(std::min((double)PWINDOW->m_sAdditionalConfigData.maxSize.toUnderlying().x, PWINDOW->m_vRealSize.goal().x),
std::min((double)PWINDOW->m_sAdditionalConfigData.maxSize.toUnderlying().y, PWINDOW->m_vRealSize.goal().y));
g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goal());
PWINDOW->setHidden(false);
}
} else if (PROP == "minsize") {
PWINDOW->m_sAdditionalConfigData.minSize.forceSetIgnoreLocked(configStringToVector2D(VAL + " " + vars[4]), lock);
if (lock) {
PWINDOW->m_vRealSize = Vector2D(std::max((double)PWINDOW->m_sAdditionalConfigData.minSize.toUnderlying().x, PWINDOW->m_vRealSize.goal().x),
std::max((double)PWINDOW->m_sAdditionalConfigData.minSize.toUnderlying().y, PWINDOW->m_vRealSize.goal().y));
g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goal());
PWINDOW->setHidden(false);
}
} else if (PROP == "dimaround") {
PWINDOW->m_sAdditionalConfigData.dimAround.forceSetIgnoreLocked(configStringToInt(VAL), lock);
} else if (PROP == "alphaoverride") {

View file

@ -328,34 +328,6 @@ void Events::listener_mapWindow(void* owner, void* data) {
PWINDOW->setHidden(false);
} catch (...) { Debug::log(LOG, "Rule size failed, rule: {} -> {}", r.szRule, r.szValue); }
} else if (r.szRule.starts_with("minsize")) {
try {
const auto VALUE = r.szRule.substr(r.szRule.find(' ') + 1);
const auto SIZEXSTR = VALUE.substr(0, VALUE.find(' '));
const auto SIZEYSTR = VALUE.substr(VALUE.find(' ') + 1);
const auto SIZE =
Vector2D(std::max((double)std::stoll(SIZEXSTR), PWINDOW->m_vRealSize.goal().x), std::max((double)std::stoll(SIZEYSTR), PWINDOW->m_vRealSize.goal().y));
PWINDOW->m_vRealSize = SIZE;
g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goal());
PWINDOW->setHidden(false);
} catch (...) { Debug::log(LOG, "Rule minsize failed, rule: {} -> {}", r.szRule, r.szValue); }
} else if (r.szRule.starts_with("maxsize")) {
try {
const auto VALUE = r.szRule.substr(r.szRule.find(' ') + 1);
const auto SIZEXSTR = VALUE.substr(0, VALUE.find(' '));
const auto SIZEYSTR = VALUE.substr(VALUE.find(' ') + 1);
const auto SIZE =
Vector2D(std::min((double)std::stoll(SIZEXSTR), PWINDOW->m_vRealSize.goal().x), std::min((double)std::stoll(SIZEYSTR), PWINDOW->m_vRealSize.goal().y));
PWINDOW->m_vRealSize = SIZE;
g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goal());
PWINDOW->setHidden(false);
} catch (...) { Debug::log(LOG, "Rule maxsize failed, rule: {} -> {}", r.szRule, r.szValue); }
} else if (r.szRule.starts_with("move")) {
try {
auto value = r.szRule.substr(r.szRule.find(' ') + 1);

View file

@ -722,6 +722,32 @@ int64_t configStringToInt(const std::string& VALUE) {
return std::stoll(VALUE);
}
Vector2D configStringToVector2D(const std::string& VALUE) {
std::istringstream iss(VALUE);
std::string token;
if (!std::getline(iss, token, ' ') && !std::getline(iss, token, ','))
throw std::invalid_argument("Invalid string format");
if (!isNumber(token))
throw std::invalid_argument("Invalid x value");
long long x = std::stoll(token);
if (!std::getline(iss, token))
throw std::invalid_argument("Invalid string format");
if (!isNumber(token))
throw std::invalid_argument("Invalid y value");
long long y = std::stoll(token);
if (std::getline(iss, token))
throw std::invalid_argument("Invalid string format");
return Vector2D(x, y);
}
double normalizeAngleRad(double ang) {
if (ang > M_PI * 2) {
while (ang > M_PI * 2)

View file

@ -28,6 +28,7 @@ void logSystemInfo();
std::string execAndGet(const char*);
int64_t getPPIDof(int64_t pid);
int64_t configStringToInt(const std::string&);
Vector2D configStringToVector2D(const std::string&);
std::optional<float> getPlusMinusKeywordResult(std::string in, float relative);
void matrixProjection(float mat[9], int w, int h, wl_output_transform tr);
double normalizeAngleRad(double ang);

View file

@ -358,8 +358,8 @@ void IHyprLayout::onMouseMove(const Vector2D& mousePos) {
} else if (g_pInputManager->dragMode == MBIND_RESIZE || g_pInputManager->dragMode == MBIND_RESIZE_FORCE_RATIO || g_pInputManager->dragMode == MBIND_RESIZE_BLOCK_RATIO) {
if (DRAGGINGWINDOW->m_bIsFloating) {
Vector2D MINSIZE = g_pXWaylandManager->getMinSizeForWindow(DRAGGINGWINDOW).clamp({20, 20});
Vector2D MAXSIZE = g_pXWaylandManager->getMaxSizeForWindow(DRAGGINGWINDOW);
Vector2D MINSIZE = g_pXWaylandManager->getMinSizeForWindow(DRAGGINGWINDOW).clamp(DRAGGINGWINDOW->m_sAdditionalConfigData.minSize.toUnderlying());
Vector2D MAXSIZE = g_pXWaylandManager->getMaxSizeForWindow(DRAGGINGWINDOW).clamp({}, DRAGGINGWINDOW->m_sAdditionalConfigData.maxSize.toUnderlying());
Vector2D newSize = m_vBeginDragSizeXY;
Vector2D newPos = m_vBeginDragPositionXY;