windowrules: rewrite completely (#12269)
Reworks the window rule syntax completely --------- Co-authored-by: Mihai Fufezan <mihai@fufexan.net>
This commit is contained in:
parent
95ee08b340
commit
c2670e9ab9
93 changed files with 3574 additions and 2255 deletions
|
|
@ -24,6 +24,7 @@
|
|||
#include "../protocols/FractionalScale.hpp"
|
||||
#include "../xwayland/XWayland.hpp"
|
||||
#include "../helpers/Color.hpp"
|
||||
#include "../helpers/math/Expression.hpp"
|
||||
#include "../events/Events.hpp"
|
||||
#include "../managers/XWaylandManager.hpp"
|
||||
#include "../render/Renderer.hpp"
|
||||
|
|
@ -41,8 +42,9 @@ using enum NContentType::eContentType;
|
|||
PHLWINDOW CWindow::create(SP<CXWaylandSurface> surface) {
|
||||
PHLWINDOW pWindow = SP<CWindow>(new CWindow(surface));
|
||||
|
||||
pWindow->m_self = pWindow;
|
||||
pWindow->m_isX11 = true;
|
||||
pWindow->m_self = pWindow;
|
||||
pWindow->m_isX11 = true;
|
||||
pWindow->m_ruleApplicator = makeUnique<Desktop::Rule::CWindowRuleApplicator>(pWindow);
|
||||
|
||||
g_pAnimationManager->createAnimation(Vector2D(0, 0), pWindow->m_realPosition, g_pConfigManager->getAnimationPropertyConfig("windowsIn"), pWindow, AVARDAMAGE_ENTIRE);
|
||||
g_pAnimationManager->createAnimation(Vector2D(0, 0), pWindow->m_realSize, g_pConfigManager->getAnimationPropertyConfig("windowsIn"), pWindow, AVARDAMAGE_ENTIRE);
|
||||
|
|
@ -67,6 +69,7 @@ PHLWINDOW CWindow::create(SP<CXDGSurfaceResource> resource) {
|
|||
|
||||
pWindow->m_self = pWindow;
|
||||
resource->m_toplevel->m_window = pWindow;
|
||||
pWindow->m_ruleApplicator = makeUnique<Desktop::Rule::CWindowRuleApplicator>(pWindow);
|
||||
|
||||
g_pAnimationManager->createAnimation(Vector2D(0, 0), pWindow->m_realPosition, g_pConfigManager->getAnimationPropertyConfig("windowsIn"), pWindow, AVARDAMAGE_ENTIRE);
|
||||
g_pAnimationManager->createAnimation(Vector2D(0, 0), pWindow->m_realSize, g_pConfigManager->getAnimationPropertyConfig("windowsIn"), pWindow, AVARDAMAGE_ENTIRE);
|
||||
|
|
@ -138,7 +141,7 @@ SBoxExtents CWindow::getFullWindowExtents() {
|
|||
|
||||
const int BORDERSIZE = getRealBorderSize();
|
||||
|
||||
if (m_windowData.dimAround.valueOrDefault()) {
|
||||
if (m_ruleApplicator->dimAround().valueOrDefault()) {
|
||||
if (const auto PMONITOR = m_monitor.lock(); PMONITOR)
|
||||
return {.topLeft = {m_realPosition->value().x - PMONITOR->m_position.x, m_realPosition->value().y - PMONITOR->m_position.y},
|
||||
.bottomRight = {PMONITOR->m_size.x - (m_realPosition->value().x - PMONITOR->m_position.x),
|
||||
|
|
@ -191,7 +194,7 @@ SBoxExtents CWindow::getFullWindowExtents() {
|
|||
}
|
||||
|
||||
CBox CWindow::getFullWindowBoundingBox() {
|
||||
if (m_windowData.dimAround.valueOrDefault()) {
|
||||
if (m_ruleApplicator->dimAround().valueOrDefault()) {
|
||||
if (const auto PMONITOR = m_monitor.lock(); PMONITOR)
|
||||
return {PMONITOR->m_position.x, PMONITOR->m_position.y, PMONITOR->m_size.x, PMONITOR->m_size.y};
|
||||
}
|
||||
|
|
@ -251,7 +254,7 @@ SBoxExtents CWindow::getWindowExtentsUnified(uint64_t properties) {
|
|||
}
|
||||
|
||||
CBox CWindow::getWindowBoxUnified(uint64_t properties) {
|
||||
if (m_windowData.dimAround.valueOrDefault()) {
|
||||
if (m_ruleApplicator->dimAround().valueOrDefault()) {
|
||||
const auto PMONITOR = m_monitor.lock();
|
||||
if (PMONITOR)
|
||||
return {PMONITOR->m_position.x, PMONITOR->m_position.y, PMONITOR->m_size.x, PMONITOR->m_size.y};
|
||||
|
|
@ -636,222 +639,6 @@ bool CWindow::isHidden() {
|
|||
return m_hidden;
|
||||
}
|
||||
|
||||
void CWindow::applyDynamicRule(const SP<CWindowRule>& r) {
|
||||
const eOverridePriority priority = r->m_execRule ? PRIORITY_SET_PROP : PRIORITY_WINDOW_RULE;
|
||||
static auto PCLAMP_TILED = CConfigValue<Hyprlang::INT>("misc:size_limits_tiled");
|
||||
|
||||
switch (r->m_ruleType) {
|
||||
case CWindowRule::RULE_TAG: {
|
||||
CVarList vars{r->m_rule, 0, 's', true};
|
||||
|
||||
if (vars.size() == 2 && vars[0] == "tag")
|
||||
m_tags.applyTag(vars[1], true);
|
||||
else
|
||||
Debug::log(ERR, "Tag rule invalid: {}", r->m_rule);
|
||||
break;
|
||||
}
|
||||
case CWindowRule::RULE_OPACITY: {
|
||||
try {
|
||||
CVarList vars(r->m_rule, 0, ' ');
|
||||
|
||||
int opacityIDX = 0;
|
||||
|
||||
for (auto const& r : vars) {
|
||||
if (r == "opacity")
|
||||
continue;
|
||||
|
||||
if (r == "override") {
|
||||
if (opacityIDX == 1)
|
||||
m_windowData.alpha = CWindowOverridableVar(SAlphaValue{.alpha = m_windowData.alpha.value().alpha, .overridden = true}, priority);
|
||||
else if (opacityIDX == 2)
|
||||
m_windowData.alphaInactive = CWindowOverridableVar(SAlphaValue{.alpha = m_windowData.alphaInactive.value().alpha, .overridden = true}, priority);
|
||||
else if (opacityIDX == 3)
|
||||
m_windowData.alphaFullscreen = CWindowOverridableVar(SAlphaValue{.alpha = m_windowData.alphaFullscreen.value().alpha, .overridden = true}, priority);
|
||||
} else {
|
||||
if (opacityIDX == 0) {
|
||||
m_windowData.alpha = CWindowOverridableVar(SAlphaValue{.alpha = std::stof(r), .overridden = false}, priority);
|
||||
} else if (opacityIDX == 1) {
|
||||
m_windowData.alphaInactive = CWindowOverridableVar(SAlphaValue{.alpha = std::stof(r), .overridden = false}, priority);
|
||||
} else if (opacityIDX == 2) {
|
||||
m_windowData.alphaFullscreen = CWindowOverridableVar(SAlphaValue{.alpha = std::stof(r), .overridden = false}, priority);
|
||||
} else {
|
||||
throw std::runtime_error("more than 3 alpha values");
|
||||
}
|
||||
|
||||
opacityIDX++;
|
||||
}
|
||||
}
|
||||
|
||||
if (opacityIDX == 1) {
|
||||
m_windowData.alphaInactive = m_windowData.alpha;
|
||||
m_windowData.alphaFullscreen = m_windowData.alpha;
|
||||
}
|
||||
} catch (std::exception& e) { Debug::log(ERR, "Opacity rule \"{}\" failed with: {}", r->m_rule, e.what()); }
|
||||
break;
|
||||
}
|
||||
case CWindowRule::RULE_ANIMATION: {
|
||||
auto STYLE = r->m_rule.substr(r->m_rule.find_first_of(' ') + 1);
|
||||
m_windowData.animationStyle = CWindowOverridableVar(STYLE, priority);
|
||||
break;
|
||||
}
|
||||
case CWindowRule::RULE_BORDERCOLOR: {
|
||||
try {
|
||||
// Each vector will only get used if it has at least one color
|
||||
CGradientValueData activeBorderGradient = {};
|
||||
CGradientValueData inactiveBorderGradient = {};
|
||||
bool active = true;
|
||||
CVarList colorsAndAngles = CVarList(trim(r->m_rule.substr(r->m_rule.find_first_of(' ') + 1)), 0, 's', true);
|
||||
|
||||
// Basic form has only two colors, everything else can be parsed as a gradient
|
||||
if (colorsAndAngles.size() == 2 && !colorsAndAngles[1].contains("deg")) {
|
||||
m_windowData.activeBorderColor = CWindowOverridableVar(CGradientValueData(CHyprColor(configStringToInt(colorsAndAngles[0]).value_or(0))), priority);
|
||||
m_windowData.inactiveBorderColor = CWindowOverridableVar(CGradientValueData(CHyprColor(configStringToInt(colorsAndAngles[1]).value_or(0))), priority);
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto const& token : colorsAndAngles) {
|
||||
// The first angle, or an explicit "0deg", splits the two gradients
|
||||
if (active && token.contains("deg")) {
|
||||
activeBorderGradient.m_angle = std::stoi(token.substr(0, token.size() - 3)) * (PI / 180.0);
|
||||
active = false;
|
||||
} else if (token.contains("deg"))
|
||||
inactiveBorderGradient.m_angle = std::stoi(token.substr(0, token.size() - 3)) * (PI / 180.0);
|
||||
else if (active)
|
||||
activeBorderGradient.m_colors.emplace_back(configStringToInt(token).value_or(0));
|
||||
else
|
||||
inactiveBorderGradient.m_colors.emplace_back(configStringToInt(token).value_or(0));
|
||||
}
|
||||
|
||||
activeBorderGradient.updateColorsOk();
|
||||
|
||||
// Includes sanity checks for the number of colors in each gradient
|
||||
if (activeBorderGradient.m_colors.size() > 10 || inactiveBorderGradient.m_colors.size() > 10)
|
||||
Debug::log(WARN, "Bordercolor rule \"{}\" has more than 10 colors in one gradient, ignoring", r->m_rule);
|
||||
else if (activeBorderGradient.m_colors.empty())
|
||||
Debug::log(WARN, "Bordercolor rule \"{}\" has no colors, ignoring", r->m_rule);
|
||||
else if (inactiveBorderGradient.m_colors.empty())
|
||||
m_windowData.activeBorderColor = CWindowOverridableVar(activeBorderGradient, priority);
|
||||
else {
|
||||
m_windowData.activeBorderColor = CWindowOverridableVar(activeBorderGradient, priority);
|
||||
m_windowData.inactiveBorderColor = CWindowOverridableVar(inactiveBorderGradient, priority);
|
||||
}
|
||||
} catch (std::exception& e) { Debug::log(ERR, "BorderColor rule \"{}\" failed with: {}", r->m_rule, e.what()); }
|
||||
break;
|
||||
}
|
||||
case CWindowRule::RULE_IDLEINHIBIT: {
|
||||
auto IDLERULE = r->m_rule.substr(r->m_rule.find_first_of(' ') + 1);
|
||||
|
||||
if (IDLERULE == "none")
|
||||
m_idleInhibitMode = IDLEINHIBIT_NONE;
|
||||
else if (IDLERULE == "always")
|
||||
m_idleInhibitMode = IDLEINHIBIT_ALWAYS;
|
||||
else if (IDLERULE == "focus")
|
||||
m_idleInhibitMode = IDLEINHIBIT_FOCUS;
|
||||
else if (IDLERULE == "fullscreen")
|
||||
m_idleInhibitMode = IDLEINHIBIT_FULLSCREEN;
|
||||
else
|
||||
Debug::log(ERR, "Rule idleinhibit: unknown mode {}", IDLERULE);
|
||||
break;
|
||||
}
|
||||
case CWindowRule::RULE_MAXSIZE: {
|
||||
try {
|
||||
if (!m_isFloating && !sc<bool>(*PCLAMP_TILED))
|
||||
return;
|
||||
const auto VEC = configStringToVector2D(r->m_rule.substr(8));
|
||||
if (VEC.x < 1 || VEC.y < 1) {
|
||||
Debug::log(ERR, "Invalid size for maxsize");
|
||||
return;
|
||||
}
|
||||
|
||||
m_windowData.maxSize = CWindowOverridableVar(VEC, priority);
|
||||
clampWindowSize(std::nullopt, m_windowData.maxSize.value());
|
||||
|
||||
} catch (std::exception& e) { Debug::log(ERR, "maxsize rule \"{}\" failed with: {}", r->m_rule, e.what()); }
|
||||
break;
|
||||
}
|
||||
case CWindowRule::RULE_MINSIZE: {
|
||||
try {
|
||||
if (!m_isFloating && !sc<bool>(*PCLAMP_TILED))
|
||||
return;
|
||||
const auto VEC = configStringToVector2D(r->m_rule.substr(8));
|
||||
if (VEC.x < 1 || VEC.y < 1) {
|
||||
Debug::log(ERR, "Invalid size for minsize");
|
||||
return;
|
||||
}
|
||||
|
||||
m_windowData.minSize = CWindowOverridableVar(VEC, priority);
|
||||
clampWindowSize(m_windowData.minSize.value(), std::nullopt);
|
||||
|
||||
if (m_groupData.pNextWindow.expired())
|
||||
setHidden(false);
|
||||
} catch (std::exception& e) { Debug::log(ERR, "minsize rule \"{}\" failed with: {}", r->m_rule, e.what()); }
|
||||
break;
|
||||
}
|
||||
case CWindowRule::RULE_RENDERUNFOCUSED: {
|
||||
m_windowData.renderUnfocused = CWindowOverridableVar(true, priority);
|
||||
g_pHyprRenderer->addWindowToRenderUnfocused(m_self.lock());
|
||||
break;
|
||||
}
|
||||
case CWindowRule::RULE_PROP: {
|
||||
const CVarList VARS(r->m_rule, 0, ' ');
|
||||
if (auto search = NWindowProperties::intWindowProperties.find(VARS[1]); search != NWindowProperties::intWindowProperties.end()) {
|
||||
try {
|
||||
*(search->second(m_self.lock())) = CWindowOverridableVar(sc<Hyprlang::INT>(std::stoi(VARS[2])), priority);
|
||||
} catch (std::exception& e) { Debug::log(ERR, "Rule \"{}\" failed with: {}", r->m_rule, e.what()); }
|
||||
} else if (auto search = NWindowProperties::floatWindowProperties.find(VARS[1]); search != NWindowProperties::floatWindowProperties.end()) {
|
||||
try {
|
||||
*(search->second(m_self.lock())) = CWindowOverridableVar(std::stof(VARS[2]), priority);
|
||||
} catch (std::exception& e) { Debug::log(ERR, "Rule \"{}\" failed with: {}", r->m_rule, e.what()); }
|
||||
} else if (auto search = NWindowProperties::boolWindowProperties.find(VARS[1]); search != NWindowProperties::boolWindowProperties.end()) {
|
||||
try {
|
||||
*(search->second(m_self.lock())) = CWindowOverridableVar(VARS[2].empty() ? true : sc<bool>(std::stoi(VARS[2])), priority);
|
||||
} catch (std::exception& e) { Debug::log(ERR, "Rule \"{}\" failed with: {}", r->m_rule, e.what()); }
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CWindowRule::RULE_PERSISTENTSIZE: {
|
||||
m_windowData.persistentSize = CWindowOverridableVar(true, PRIORITY_WINDOW_RULE);
|
||||
break;
|
||||
}
|
||||
case CWindowRule::RULE_NOVRR: {
|
||||
m_windowData.noVRR = CWindowOverridableVar(true, priority);
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
void CWindow::updateDynamicRules() {
|
||||
m_windowData.alpha.unset(PRIORITY_WINDOW_RULE);
|
||||
m_windowData.alphaInactive.unset(PRIORITY_WINDOW_RULE);
|
||||
m_windowData.alphaFullscreen.unset(PRIORITY_WINDOW_RULE);
|
||||
|
||||
unsetWindowData(PRIORITY_WINDOW_RULE);
|
||||
|
||||
m_windowData.animationStyle.unset(PRIORITY_WINDOW_RULE);
|
||||
m_windowData.maxSize.unset(PRIORITY_WINDOW_RULE);
|
||||
m_windowData.minSize.unset(PRIORITY_WINDOW_RULE);
|
||||
|
||||
m_windowData.activeBorderColor.unset(PRIORITY_WINDOW_RULE);
|
||||
m_windowData.inactiveBorderColor.unset(PRIORITY_WINDOW_RULE);
|
||||
|
||||
m_windowData.renderUnfocused.unset(PRIORITY_WINDOW_RULE);
|
||||
m_windowData.noVRR.unset(PRIORITY_WINDOW_RULE);
|
||||
|
||||
m_idleInhibitMode = IDLEINHIBIT_NONE;
|
||||
|
||||
m_tags.removeDynamicTags();
|
||||
|
||||
m_matchedRules = g_pConfigManager->getMatchingRules(m_self.lock());
|
||||
for (const auto& r : m_matchedRules) {
|
||||
applyDynamicRule(r);
|
||||
}
|
||||
|
||||
EMIT_HOOK_EVENT("windowUpdateRules", m_self.lock());
|
||||
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(monitorID());
|
||||
}
|
||||
|
||||
// check if the point is "hidden" under a rounded corner of the window
|
||||
// it is assumed that the point is within the real window box (m_vRealPosition, m_vRealSize)
|
||||
// otherwise behaviour is undefined
|
||||
|
|
@ -924,6 +711,8 @@ void CWindow::createGroup() {
|
|||
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{.event = "togglegroup", .data = std::format("1,{:x}", rc<uintptr_t>(this))});
|
||||
}
|
||||
|
||||
m_ruleApplicator->propertiesChanged(Desktop::Rule::RULE_PROP_GROUP | Desktop::Rule::RULE_PROP_ON_WORKSPACE);
|
||||
}
|
||||
|
||||
void CWindow::destroyGroup() {
|
||||
|
|
@ -943,6 +732,7 @@ void CWindow::destroyGroup() {
|
|||
g_pCompositor->updateAllWindowsAnimatedDecorationValues();
|
||||
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{.event = "togglegroup", .data = std::format("0,{:x}", rc<uintptr_t>(this))});
|
||||
m_ruleApplicator->propertiesChanged(Desktop::Rule::RULE_PROP_GROUP | Desktop::Rule::RULE_PROP_ON_WORKSPACE);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -969,6 +759,7 @@ void CWindow::destroyGroup() {
|
|||
g_pKeybindManager->m_groupsLocked = true;
|
||||
for (auto const& w : members) {
|
||||
g_pLayoutManager->getCurrentLayout()->onWindowCreated(w);
|
||||
w->m_ruleApplicator->propertiesChanged(Desktop::Rule::RULE_PROP_GROUP | Desktop::Rule::RULE_PROP_ON_WORKSPACE);
|
||||
w->updateWindowDecos();
|
||||
}
|
||||
g_pKeybindManager->m_groupsLocked = GROUPSLOCKEDPREV;
|
||||
|
|
@ -982,6 +773,8 @@ void CWindow::destroyGroup() {
|
|||
|
||||
if (!addresses.empty())
|
||||
addresses.pop_back();
|
||||
|
||||
m_ruleApplicator->propertiesChanged(Desktop::Rule::RULE_PROP_GROUP | Desktop::Rule::RULE_PROP_ON_WORKSPACE);
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{.event = "togglegroup", .data = std::format("0,{}", addresses)});
|
||||
}
|
||||
|
||||
|
|
@ -1217,16 +1010,16 @@ float CWindow::rounding() {
|
|||
static auto PROUNDING = CConfigValue<Hyprlang::INT>("decoration:rounding");
|
||||
static auto PROUNDINGPOWER = CConfigValue<Hyprlang::FLOAT>("decoration:rounding_power");
|
||||
|
||||
float roundingPower = m_windowData.roundingPower.valueOr(*PROUNDINGPOWER);
|
||||
float rounding = m_windowData.rounding.valueOr(*PROUNDING) * (roundingPower / 2.0); /* Make perceived roundness consistent. */
|
||||
float roundingPower = m_ruleApplicator->roundingPower().valueOr(*PROUNDINGPOWER);
|
||||
float rounding = m_ruleApplicator->rounding().valueOr(*PROUNDING) * (roundingPower / 2.0); /* Make perceived roundness consistent. */
|
||||
|
||||
return m_windowData.noRounding.valueOrDefault() ? 0 : rounding;
|
||||
return rounding;
|
||||
}
|
||||
|
||||
float CWindow::roundingPower() {
|
||||
static auto PROUNDINGPOWER = CConfigValue<Hyprlang::FLOAT>("decoration:rounding_power");
|
||||
|
||||
return m_windowData.roundingPower.valueOr(std::clamp(*PROUNDINGPOWER, 1.F, 10.F));
|
||||
return m_ruleApplicator->roundingPower().valueOr(std::clamp(*PROUNDINGPOWER, 1.F, 10.F));
|
||||
}
|
||||
|
||||
void CWindow::updateWindowData() {
|
||||
|
|
@ -1236,50 +1029,43 @@ void CWindow::updateWindowData() {
|
|||
}
|
||||
|
||||
void CWindow::updateWindowData(const SWorkspaceRule& workspaceRule) {
|
||||
static auto PNOBORDERONFLOATING = CConfigValue<Hyprlang::INT>("general:no_border_on_floating");
|
||||
|
||||
if (*PNOBORDERONFLOATING)
|
||||
m_windowData.noBorder = CWindowOverridableVar(m_isFloating, PRIORITY_LAYOUT);
|
||||
else
|
||||
m_windowData.noBorder.unset(PRIORITY_LAYOUT);
|
||||
|
||||
m_windowData.borderSize.matchOptional(workspaceRule.borderSize, PRIORITY_WORKSPACE_RULE);
|
||||
m_windowData.decorate.matchOptional(workspaceRule.decorate, PRIORITY_WORKSPACE_RULE);
|
||||
m_windowData.noBorder.matchOptional(workspaceRule.noBorder, PRIORITY_WORKSPACE_RULE);
|
||||
m_windowData.noRounding.matchOptional(workspaceRule.noRounding, PRIORITY_WORKSPACE_RULE);
|
||||
m_windowData.noShadow.matchOptional(workspaceRule.noShadow, PRIORITY_WORKSPACE_RULE);
|
||||
m_ruleApplicator->borderSize().matchOptional(workspaceRule.borderSize, Desktop::Types::PRIORITY_WORKSPACE_RULE);
|
||||
m_ruleApplicator->decorate().matchOptional(workspaceRule.decorate, Desktop::Types::PRIORITY_WORKSPACE_RULE);
|
||||
m_ruleApplicator->borderSize().matchOptional(workspaceRule.noBorder ? std::optional<Hyprlang::INT>(0) : std::nullopt, Desktop::Types::PRIORITY_WORKSPACE_RULE);
|
||||
m_ruleApplicator->rounding().matchOptional(workspaceRule.noRounding.value_or(false) ? std::optional<Hyprlang::INT>(0) : std::nullopt, Desktop::Types::PRIORITY_WORKSPACE_RULE);
|
||||
m_ruleApplicator->noShadow().matchOptional(workspaceRule.noShadow, Desktop::Types::PRIORITY_WORKSPACE_RULE);
|
||||
}
|
||||
|
||||
int CWindow::getRealBorderSize() {
|
||||
if (m_windowData.noBorder.valueOrDefault() || (m_workspace && isEffectiveInternalFSMode(FSMODE_FULLSCREEN)) || !m_windowData.decorate.valueOrDefault())
|
||||
if ((m_workspace && isEffectiveInternalFSMode(FSMODE_FULLSCREEN)) || !m_ruleApplicator->decorate().valueOrDefault())
|
||||
return 0;
|
||||
|
||||
static auto PBORDERSIZE = CConfigValue<Hyprlang::INT>("general:border_size");
|
||||
|
||||
return m_windowData.borderSize.valueOr(*PBORDERSIZE);
|
||||
return m_ruleApplicator->borderSize().valueOr(*PBORDERSIZE);
|
||||
}
|
||||
|
||||
float CWindow::getScrollMouse() {
|
||||
static auto PINPUTSCROLLFACTOR = CConfigValue<Hyprlang::FLOAT>("input:scroll_factor");
|
||||
return m_windowData.scrollMouse.valueOr(*PINPUTSCROLLFACTOR);
|
||||
return m_ruleApplicator->scrollMouse().valueOr(*PINPUTSCROLLFACTOR);
|
||||
}
|
||||
|
||||
float CWindow::getScrollTouchpad() {
|
||||
static auto PTOUCHPADSCROLLFACTOR = CConfigValue<Hyprlang::FLOAT>("input:touchpad:scroll_factor");
|
||||
return m_windowData.scrollTouchpad.valueOr(*PTOUCHPADSCROLLFACTOR);
|
||||
return m_ruleApplicator->scrollTouchpad().valueOr(*PTOUCHPADSCROLLFACTOR);
|
||||
}
|
||||
|
||||
bool CWindow::isScrollMouseOverridden() {
|
||||
return m_windowData.scrollMouse.hasValue();
|
||||
return m_ruleApplicator->scrollMouse().hasValue();
|
||||
}
|
||||
|
||||
bool CWindow::isScrollTouchpadOverridden() {
|
||||
return m_windowData.scrollTouchpad.hasValue();
|
||||
return m_ruleApplicator->scrollTouchpad().hasValue();
|
||||
}
|
||||
|
||||
bool CWindow::canBeTorn() {
|
||||
static auto PTEARING = CConfigValue<Hyprlang::INT>("general:allow_tearing");
|
||||
return m_windowData.tearing.valueOr(m_tearingHint) && *PTEARING;
|
||||
return m_ruleApplicator->tearing().valueOr(m_tearingHint) && *PTEARING;
|
||||
}
|
||||
|
||||
void CWindow::setSuspended(bool suspend) {
|
||||
|
|
@ -1454,7 +1240,8 @@ void CWindow::activate(bool force) {
|
|||
g_pEventManager->postEvent(SHyprIPCEvent{.event = "urgent", .data = std::format("{:x}", rc<uintptr_t>(this))});
|
||||
EMIT_HOOK_EVENT("urgent", m_self.lock());
|
||||
|
||||
if (!force && (!m_windowData.focusOnActivate.valueOr(*PFOCUSONACTIVATE) || (m_suppressedEvents & SUPPRESS_ACTIVATE_FOCUSONLY) || (m_suppressedEvents & SUPPRESS_ACTIVATE)))
|
||||
if (!force &&
|
||||
(!m_ruleApplicator->focusOnActivate().valueOr(*PFOCUSONACTIVATE) || (m_suppressedEvents & SUPPRESS_ACTIVATE_FOCUSONLY) || (m_suppressedEvents & SUPPRESS_ACTIVATE)))
|
||||
return;
|
||||
|
||||
if (!m_isMapped) {
|
||||
|
|
@ -1539,8 +1326,7 @@ void CWindow::onUpdateMeta() {
|
|||
}
|
||||
|
||||
if (doUpdate) {
|
||||
updateDynamicRules();
|
||||
g_pCompositor->updateWindowAnimatedDecorationValues(m_self.lock());
|
||||
m_ruleApplicator->propertiesChanged(Desktop::Rule::RULE_PROP_TITLE | Desktop::Rule::RULE_PROP_CLASS);
|
||||
updateToplevel();
|
||||
}
|
||||
}
|
||||
|
|
@ -1718,18 +1504,6 @@ PHLWINDOW CWindow::getSwallower() {
|
|||
return candidates[0];
|
||||
}
|
||||
|
||||
void CWindow::unsetWindowData(eOverridePriority priority) {
|
||||
for (auto const& element : NWindowProperties::boolWindowProperties) {
|
||||
element.second(m_self.lock())->unset(priority);
|
||||
}
|
||||
for (auto const& element : NWindowProperties::intWindowProperties) {
|
||||
element.second(m_self.lock())->unset(priority);
|
||||
}
|
||||
for (auto const& element : NWindowProperties::floatWindowProperties) {
|
||||
element.second(m_self.lock())->unset(priority);
|
||||
}
|
||||
}
|
||||
|
||||
bool CWindow::isX11OverrideRedirect() {
|
||||
return m_xwaylandSurface && m_xwaylandSurface->m_overrideRedirect;
|
||||
}
|
||||
|
|
@ -1753,7 +1527,7 @@ Vector2D CWindow::requestedMinSize() {
|
|||
|
||||
Vector2D CWindow::requestedMaxSize() {
|
||||
constexpr int NO_MAX_SIZE_LIMIT = 99999;
|
||||
if (((m_isX11 && !m_xwaylandSurface->m_sizeHints) || (!m_isX11 && (!m_xdgSurface || !m_xdgSurface->m_toplevel)) || m_windowData.noMaxSize.valueOrDefault()))
|
||||
if (((m_isX11 && !m_xwaylandSurface->m_sizeHints) || (!m_isX11 && (!m_xdgSurface || !m_xdgSurface->m_toplevel)) || m_ruleApplicator->noMaxSize().valueOrDefault()))
|
||||
return Vector2D(NO_MAX_SIZE_LIMIT, NO_MAX_SIZE_LIMIT);
|
||||
|
||||
Vector2D maxSize = m_isX11 ? Vector2D(m_xwaylandSurface->m_sizeHints->max_width, m_xwaylandSurface->m_sizeHints->max_height) : m_xdgSurface->m_toplevel->layoutMaxSize();
|
||||
|
|
@ -1951,3 +1725,127 @@ Vector2D CWindow::getReportedSize() {
|
|||
return m_wlSurface->resource()->m_current.ackedSize;
|
||||
return m_reportedSize;
|
||||
}
|
||||
|
||||
void CWindow::updateDecorationValues() {
|
||||
static auto PACTIVECOL = CConfigValue<Hyprlang::CUSTOMTYPE>("general:col.active_border");
|
||||
static auto PINACTIVECOL = CConfigValue<Hyprlang::CUSTOMTYPE>("general:col.inactive_border");
|
||||
static auto PNOGROUPACTIVECOL = CConfigValue<Hyprlang::CUSTOMTYPE>("general:col.nogroup_border_active");
|
||||
static auto PNOGROUPINACTIVECOL = CConfigValue<Hyprlang::CUSTOMTYPE>("general:col.nogroup_border");
|
||||
static auto PGROUPACTIVECOL = CConfigValue<Hyprlang::CUSTOMTYPE>("group:col.border_active");
|
||||
static auto PGROUPINACTIVECOL = CConfigValue<Hyprlang::CUSTOMTYPE>("group:col.border_inactive");
|
||||
static auto PGROUPACTIVELOCKEDCOL = CConfigValue<Hyprlang::CUSTOMTYPE>("group:col.border_locked_active");
|
||||
static auto PGROUPINACTIVELOCKEDCOL = CConfigValue<Hyprlang::CUSTOMTYPE>("group:col.border_locked_inactive");
|
||||
static auto PINACTIVEALPHA = CConfigValue<Hyprlang::FLOAT>("decoration:inactive_opacity");
|
||||
static auto PACTIVEALPHA = CConfigValue<Hyprlang::FLOAT>("decoration:active_opacity");
|
||||
static auto PFULLSCREENALPHA = CConfigValue<Hyprlang::FLOAT>("decoration:fullscreen_opacity");
|
||||
static auto PSHADOWCOL = CConfigValue<Hyprlang::INT>("decoration:shadow:color");
|
||||
static auto PSHADOWCOLINACTIVE = CConfigValue<Hyprlang::INT>("decoration:shadow:color_inactive");
|
||||
static auto PDIMSTRENGTH = CConfigValue<Hyprlang::FLOAT>("decoration:dim_strength");
|
||||
static auto PDIMENABLED = CConfigValue<Hyprlang::INT>("decoration:dim_inactive");
|
||||
static auto PDIMMODAL = CConfigValue<Hyprlang::INT>("decoration:dim_modal");
|
||||
|
||||
auto* const ACTIVECOL = sc<CGradientValueData*>((PACTIVECOL.ptr())->getData());
|
||||
auto* const INACTIVECOL = sc<CGradientValueData*>((PINACTIVECOL.ptr())->getData());
|
||||
auto* const NOGROUPACTIVECOL = sc<CGradientValueData*>((PNOGROUPACTIVECOL.ptr())->getData());
|
||||
auto* const NOGROUPINACTIVECOL = sc<CGradientValueData*>((PNOGROUPINACTIVECOL.ptr())->getData());
|
||||
auto* const GROUPACTIVECOL = sc<CGradientValueData*>((PGROUPACTIVECOL.ptr())->getData());
|
||||
auto* const GROUPINACTIVECOL = sc<CGradientValueData*>((PGROUPINACTIVECOL.ptr())->getData());
|
||||
auto* const GROUPACTIVELOCKEDCOL = sc<CGradientValueData*>((PGROUPACTIVELOCKEDCOL.ptr())->getData());
|
||||
auto* const GROUPINACTIVELOCKEDCOL = sc<CGradientValueData*>((PGROUPINACTIVELOCKEDCOL.ptr())->getData());
|
||||
|
||||
auto setBorderColor = [&](CGradientValueData grad) -> void {
|
||||
if (grad == m_realBorderColor)
|
||||
return;
|
||||
|
||||
m_realBorderColorPrevious = m_realBorderColor;
|
||||
m_realBorderColor = grad;
|
||||
m_borderFadeAnimationProgress->setValueAndWarp(0.f);
|
||||
*m_borderFadeAnimationProgress = 1.f;
|
||||
};
|
||||
|
||||
const bool IS_SHADOWED_BY_MODAL = m_xdgSurface && m_xdgSurface->m_toplevel && m_xdgSurface->m_toplevel->anyChildModal();
|
||||
|
||||
// border
|
||||
const auto RENDERDATA = g_pLayoutManager->getCurrentLayout()->requestRenderHints(m_self.lock());
|
||||
if (RENDERDATA.isBorderGradient)
|
||||
setBorderColor(*RENDERDATA.borderGradient);
|
||||
else {
|
||||
const bool GROUPLOCKED = m_groupData.pNextWindow.lock() ? getGroupHead()->m_groupData.locked : false;
|
||||
if (m_self == g_pCompositor->m_lastWindow) {
|
||||
const auto* const ACTIVECOLOR =
|
||||
!m_groupData.pNextWindow.lock() ? (!m_groupData.deny ? ACTIVECOL : NOGROUPACTIVECOL) : (GROUPLOCKED ? GROUPACTIVELOCKEDCOL : GROUPACTIVECOL);
|
||||
setBorderColor(m_ruleApplicator->activeBorderColor().valueOr(*ACTIVECOLOR));
|
||||
} else {
|
||||
const auto* const INACTIVECOLOR =
|
||||
!m_groupData.pNextWindow.lock() ? (!m_groupData.deny ? INACTIVECOL : NOGROUPINACTIVECOL) : (GROUPLOCKED ? GROUPINACTIVELOCKEDCOL : GROUPINACTIVECOL);
|
||||
setBorderColor(m_ruleApplicator->inactiveBorderColor().valueOr(*INACTIVECOLOR));
|
||||
}
|
||||
}
|
||||
|
||||
// opacity
|
||||
const auto PWORKSPACE = m_workspace;
|
||||
if (isEffectiveInternalFSMode(FSMODE_FULLSCREEN)) {
|
||||
*m_activeInactiveAlpha = m_ruleApplicator->alphaFullscreen().valueOrDefault().applyAlpha(*PFULLSCREENALPHA);
|
||||
} else {
|
||||
if (m_self == g_pCompositor->m_lastWindow)
|
||||
*m_activeInactiveAlpha = m_ruleApplicator->alpha().valueOrDefault().applyAlpha(*PACTIVEALPHA);
|
||||
else
|
||||
*m_activeInactiveAlpha = m_ruleApplicator->alphaInactive().valueOrDefault().applyAlpha(*PINACTIVEALPHA);
|
||||
}
|
||||
|
||||
// dim
|
||||
float goalDim = 1.F;
|
||||
if (m_self == g_pCompositor->m_lastWindow.lock() || m_ruleApplicator->noDim().valueOrDefault() || !*PDIMENABLED)
|
||||
goalDim = 0;
|
||||
else
|
||||
goalDim = *PDIMSTRENGTH;
|
||||
|
||||
if (IS_SHADOWED_BY_MODAL && *PDIMMODAL)
|
||||
goalDim += (1.F - goalDim) / 2.F;
|
||||
|
||||
*m_dimPercent = goalDim;
|
||||
|
||||
// shadow
|
||||
if (!isX11OverrideRedirect() && !m_X11DoesntWantBorders) {
|
||||
if (m_self == g_pCompositor->m_lastWindow)
|
||||
*m_realShadowColor = CHyprColor(*PSHADOWCOL);
|
||||
else
|
||||
*m_realShadowColor = CHyprColor(*PSHADOWCOLINACTIVE != -1 ? *PSHADOWCOLINACTIVE : *PSHADOWCOL);
|
||||
} else
|
||||
m_realShadowColor->setValueAndWarp(CHyprColor(0, 0, 0, 0)); // no shadow
|
||||
|
||||
updateWindowDecos();
|
||||
}
|
||||
|
||||
std::optional<double> CWindow::calculateSingleExpr(const std::string& s) {
|
||||
const auto PMONITOR = m_monitor ? m_monitor : g_pCompositor->m_lastMonitor;
|
||||
const auto CURSOR_LOCAL = g_pInputManager->getMouseCoordsInternal() - (PMONITOR ? PMONITOR->m_position : Vector2D{});
|
||||
|
||||
Math::CExpression expr;
|
||||
expr.addVariable("window_w", m_realSize->goal().x);
|
||||
expr.addVariable("window_h", m_realSize->goal().y);
|
||||
expr.addVariable("window_x", m_realPosition->goal().x - (PMONITOR ? PMONITOR->m_position.x : 0));
|
||||
expr.addVariable("window_y", m_realPosition->goal().y - (PMONITOR ? PMONITOR->m_position.y : 0));
|
||||
|
||||
expr.addVariable("monitor_w", PMONITOR ? PMONITOR->m_size.x : 1920);
|
||||
expr.addVariable("monitor_h", PMONITOR ? PMONITOR->m_size.y : 1080);
|
||||
|
||||
expr.addVariable("cursor_x", CURSOR_LOCAL.x);
|
||||
expr.addVariable("cursor_y", CURSOR_LOCAL.y);
|
||||
|
||||
return expr.compute(s);
|
||||
}
|
||||
|
||||
std::optional<Vector2D> CWindow::calculateExpression(const std::string& s) {
|
||||
auto spacePos = s.find(' ');
|
||||
if (spacePos == std::string::npos)
|
||||
return std::nullopt;
|
||||
|
||||
const auto LHS = calculateSingleExpr(s.substr(0, spacePos));
|
||||
const auto RHS = calculateSingleExpr(s.substr(spacePos + 1));
|
||||
|
||||
if (!LHS || !RHS)
|
||||
return std::nullopt;
|
||||
|
||||
return Vector2D{*LHS, *RHS};
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue