mirror of
https://github.com/hyprwm/Hyprland
synced 2024-12-22 20:49:49 +01:00
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:
parent
ceecdd0fd5
commit
e52d3fa852
7 changed files with 87 additions and 55 deletions
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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") {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue