apply some rules dynamically when state of window changes (#1020)

Co-authored-by: Jef Steelant <jef.steelant_ext@softathome.com>
This commit is contained in:
Jef 2022-11-15 11:21:26 +01:00 committed by GitHub
parent 4034aa2c60
commit dbb6732743
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 130 additions and 60 deletions

View file

@ -1732,6 +1732,9 @@ void CCompositor::setWindowFullscreen(CWindow* pWindow, bool on, eFullscreenMode
g_pXWaylandManager->setWindowFullscreen(pWindow, pWindow->m_bIsFullscreen && mode == FULLSCREEN_FULL); g_pXWaylandManager->setWindowFullscreen(pWindow, pWindow->m_bIsFullscreen && mode == FULLSCREEN_FULL);
pWindow->updateDynamicRules();
g_pCompositor->updateWindowAnimatedDecorationValues(pWindow);
// make all windows on the same workspace under the fullscreen window // make all windows on the same workspace under the fullscreen window
for (auto& w : g_pCompositor->m_vWindows) { for (auto& w : g_pCompositor->m_vWindows) {
if (w->m_iWorkspaceID == pWindow->m_iWorkspaceID) { if (w->m_iWorkspaceID == pWindow->m_iWorkspaceID) {

View file

@ -292,3 +292,73 @@ void CWindow::setHidden(bool hidden) {
bool CWindow::isHidden() { bool CWindow::isHidden() {
return m_bHidden; return m_bHidden;
} }
void CWindow::applyDynamicRule(const SWindowRule& r) {
if (r.szRule == "noblur") {
m_sAdditionalConfigData.forceNoBlur = true;
} else if (r.szRule == "noborder") {
m_sAdditionalConfigData.forceNoBorder = true;
} else if (r.szRule == "noshadow") {
m_sAdditionalConfigData.forceNoShadow = true;
} else if (r.szRule == "opaque") {
m_sAdditionalConfigData.forceOpaque = true;
} else if (r.szRule.find("rounding") == 0) {
try {
m_sAdditionalConfigData.rounding = std::stoi(r.szRule.substr(r.szRule.find_first_of(' ') + 1));
} catch (std::exception& e) {
Debug::log(ERR, "Rounding rule \"%s\" failed with: %s", r.szRule.c_str(), e.what());
}
} else if (r.szRule.find("opacity") == 0) {
try {
std::string alphaPart = removeBeginEndSpacesTabs(r.szRule.substr(r.szRule.find_first_of(' ') + 1));
if (alphaPart.contains(' ')) {
// we have a space, 2 values
m_sSpecialRenderData.alpha = std::stof(alphaPart.substr(0, alphaPart.find_first_of(' ')));
m_sSpecialRenderData.alphaInactive = std::stof(alphaPart.substr(alphaPart.find_first_of(' ') + 1));
} else {
m_sSpecialRenderData.alpha = std::stof(alphaPart);
}
} catch(std::exception& e) {
Debug::log(ERR, "Opacity rule \"%s\" failed with: %s", r.szRule.c_str(), e.what());
}
} else if (r.szRule == "noanim") {
m_sAdditionalConfigData.forceNoAnims = true;
} else if (r.szRule.find("animation") == 0) {
auto STYLE = r.szRule.substr(r.szRule.find_first_of(' ') + 1);
m_sAdditionalConfigData.animationStyle = STYLE;
} else if (r.szRule.find("bordercolor") == 0) {
try {
std::string colorPart = removeBeginEndSpacesTabs(r.szRule.substr(r.szRule.find_first_of(' ') + 1));
if (colorPart.contains(' ')) {
// we have a space, 2 values
m_sSpecialRenderData.activeBorderColor = configStringToInt(colorPart.substr(0, colorPart.find_first_of(' ')));
m_sSpecialRenderData.inactiveBorderColor = configStringToInt(colorPart.substr(colorPart.find_first_of(' ') + 1));
} else {
m_sSpecialRenderData.activeBorderColor = configStringToInt(colorPart);
}
} catch(std::exception& e) {
Debug::log(ERR, "BorderColor rule \"%s\" failed with: %s", r.szRule.c_str(), e.what());
}
}
}
void CWindow::updateDynamicRules() {
m_sSpecialRenderData.activeBorderColor = -1;
m_sSpecialRenderData.inactiveBorderColor = -1;
m_sSpecialRenderData.alpha = 1.f;
m_sSpecialRenderData.alphaInactive = -1.f;
m_sAdditionalConfigData.forceNoBlur = false;
m_sAdditionalConfigData.forceNoBorder = false;
m_sAdditionalConfigData.forceNoShadow = false;
m_sAdditionalConfigData.forceOpaque = false;
m_sAdditionalConfigData.forceNoAnims = false;
m_sAdditionalConfigData.animationStyle = "";
m_sAdditionalConfigData.rounding = -1;
const auto WINDOWRULES = g_pConfigManager->getMatchingRules(this);
for (auto& r : WINDOWRULES) {
applyDynamicRule(r);
}
}

View file

@ -39,6 +39,19 @@ struct SWindowAdditionalConfigData {
bool windowDanceCompat = false; bool windowDanceCompat = false;
}; };
struct SWindowRule {
std::string szRule;
std::string szValue;
bool v2 = false;
std::string szTitle;
std::string szClass;
int bX11 = -1; // -1 means "ANY"
int bFloating = -1;
int bFullscreen = -1;
int bPinned = -1;
};
class CWindow { class CWindow {
public: public:
CWindow(); CWindow();
@ -189,6 +202,8 @@ public:
void onMap(); void onMap();
void setHidden(bool hidden); void setHidden(bool hidden);
bool isHidden(); bool isHidden();
void applyDynamicRule(const SWindowRule& r);
void updateDynamicRules();
private: private:
// For hidden windows and stuff // For hidden windows and stuff

View file

@ -732,8 +732,12 @@ void CConfigManager::handleWindowRuleV2(const std::string& command, const std::s
const auto CLASSPOS = VALUE.find("class:"); const auto CLASSPOS = VALUE.find("class:");
const auto X11POS = VALUE.find("xwayland:"); const auto X11POS = VALUE.find("xwayland:");
const auto FLOATPOS = VALUE.find("floating:"); const auto FLOATPOS = VALUE.find("floating:");
const auto FULLSCREENPOS = VALUE.find("fullscreen:");
const auto PINNEDPOS = VALUE.find("pinned:");
if (TITLEPOS == std::string::npos && CLASSPOS == std::string::npos && X11POS == std::string::npos && FLOATPOS == std::string::npos) { if (TITLEPOS == std::string::npos && CLASSPOS == std::string::npos &&
X11POS == std::string::npos && FLOATPOS == std::string::npos &&
FULLSCREENPOS == std::string::npos && PINNEDPOS == std::string::npos) {
Debug::log(ERR, "Invalid rulev2 syntax: %s", VALUE.c_str()); Debug::log(ERR, "Invalid rulev2 syntax: %s", VALUE.c_str());
parseError = "Invalid rulev2 syntax: " + VALUE; parseError = "Invalid rulev2 syntax: " + VALUE;
return; return;
@ -748,6 +752,8 @@ void CConfigManager::handleWindowRuleV2(const std::string& command, const std::s
if (CLASSPOS > pos && CLASSPOS < min) min = CLASSPOS; if (CLASSPOS > pos && CLASSPOS < min) min = CLASSPOS;
if (X11POS > pos && X11POS < min) min = X11POS; if (X11POS > pos && X11POS < min) min = X11POS;
if (FLOATPOS > pos && FLOATPOS < min) min = FLOATPOS; if (FLOATPOS > pos && FLOATPOS < min) min = FLOATPOS;
if (FULLSCREENPOS > pos && FULLSCREENPOS < min) min = FULLSCREENPOS;
if (PINNEDPOS > pos && PINNEDPOS < min) min = PINNEDPOS;
result = result.substr(0, min - pos); result = result.substr(0, min - pos);
@ -775,6 +781,14 @@ void CConfigManager::handleWindowRuleV2(const std::string& command, const std::s
rule.bFloating = extract(FLOATPOS + 9) == "1" ? 1 : 0; rule.bFloating = extract(FLOATPOS + 9) == "1" ? 1 : 0;
} }
if (FULLSCREENPOS != std::string::npos) {
rule.bFullscreen = extract(FULLSCREENPOS + 11) == "1" ? 1 : 0;
}
if (PINNEDPOS != std::string::npos) {
rule.bPinned = extract(PINNEDPOS + 7) == "1" ? 1 : 0;
}
if (RULE == "unset") { if (RULE == "unset") {
std::erase_if(m_dWindowRules, [&](const SWindowRule& other) { std::erase_if(m_dWindowRules, [&](const SWindowRule& other) {
if (!other.v2) { if (!other.v2) {
@ -796,6 +810,14 @@ void CConfigManager::handleWindowRuleV2(const std::string& command, const std::s
return false; return false;
} }
if (rule.bFullscreen != -1 && rule.bFullscreen != other.bFullscreen) {
return false;
}
if (rule.bPinned != -1 && rule.bPinned != other.bPinned) {
return false;
}
return true; return true;
} }
}); });
@ -1389,6 +1411,16 @@ std::vector<SWindowRule> CConfigManager::getMatchingRules(CWindow* pWindow) {
if (pWindow->m_bIsFloating != rule.bFloating) if (pWindow->m_bIsFloating != rule.bFloating)
continue; continue;
} }
if (rule.bFullscreen != -1) {
if (pWindow->m_bIsFullscreen != rule.bFullscreen)
continue;
}
if (rule.bPinned != -1) {
if (pWindow->m_bPinned != rule.bPinned)
continue;
}
} catch (...) { } catch (...) {
Debug::log(ERR, "Regex error at %s", rule.szValue.c_str()); Debug::log(ERR, "Regex error at %s", rule.szValue.c_str());
continue; continue;

View file

@ -48,17 +48,6 @@ struct SMonitorAdditionalReservedArea {
int right = 0; int right = 0;
}; };
struct SWindowRule {
std::string szRule;
std::string szValue;
bool v2 = false;
std::string szTitle;
std::string szClass;
int bX11 = -1; // -1 means "ANY"
int bFloating = -1;
};
struct SAnimationPropertyConfig { struct SAnimationPropertyConfig {
bool overriden = true; bool overriden = true;

View file

@ -161,47 +161,14 @@ void Events::listener_mapWindow(void* owner, void* data) {
PWINDOW->m_bIsPseudotiled = true; PWINDOW->m_bIsPseudotiled = true;
} else if (r.szRule.find("nofocus") == 0) { } else if (r.szRule.find("nofocus") == 0) {
PWINDOW->m_bNoFocus = true; PWINDOW->m_bNoFocus = true;
} else if (r.szRule == "noblur") {
PWINDOW->m_sAdditionalConfigData.forceNoBlur = true;
} else if (r.szRule == "noborder") {
PWINDOW->m_sAdditionalConfigData.forceNoBorder = true;
} else if (r.szRule == "noshadow") {
PWINDOW->m_sAdditionalConfigData.forceNoShadow = true;
} else if (r.szRule == "fullscreen") { } else if (r.szRule == "fullscreen") {
requestsFullscreen = true; requestsFullscreen = true;
} else if (r.szRule == "opaque") {
PWINDOW->m_sAdditionalConfigData.forceOpaque = true;
} else if (r.szRule == "windowdance") { } else if (r.szRule == "windowdance") {
PWINDOW->m_sAdditionalConfigData.windowDanceCompat = true; PWINDOW->m_sAdditionalConfigData.windowDanceCompat = true;
} else if (r.szRule == "forceinput") { } else if (r.szRule == "forceinput") {
PWINDOW->m_sAdditionalConfigData.forceAllowsInput = true; PWINDOW->m_sAdditionalConfigData.forceAllowsInput = true;
} else if (r.szRule == "pin") { } else if (r.szRule == "pin") {
PWINDOW->m_bPinned = true; PWINDOW->m_bPinned = true;
} else if (r.szRule == "noanim") {
PWINDOW->m_sAdditionalConfigData.forceNoAnims = true;
} else if (r.szRule.find("rounding") == 0) {
try {
PWINDOW->m_sAdditionalConfigData.rounding = std::stoi(r.szRule.substr(r.szRule.find_first_of(' ') + 1));
} catch (std::exception& e) {
Debug::log(ERR, "Rounding rule \"%s\" failed with: %s", r.szRule.c_str(), e.what());
}
} else if (r.szRule.find("opacity") == 0) {
try {
std::string alphaPart = removeBeginEndSpacesTabs(r.szRule.substr(r.szRule.find_first_of(' ') + 1));
if (alphaPart.contains(' ')) {
// we have a space, 2 values
PWINDOW->m_sSpecialRenderData.alpha = std::stof(alphaPart.substr(0, alphaPart.find_first_of(' ')));
PWINDOW->m_sSpecialRenderData.alphaInactive = std::stof(alphaPart.substr(alphaPart.find_first_of(' ') + 1));
} else {
PWINDOW->m_sSpecialRenderData.alpha = std::stof(alphaPart);
}
} catch(std::exception& e) {
Debug::log(ERR, "Opacity rule \"%s\" failed with: %s", r.szRule.c_str(), e.what());
}
} else if (r.szRule.find("animation") == 0) {
auto STYLE = r.szRule.substr(r.szRule.find_first_of(' ') + 1);
PWINDOW->m_sAdditionalConfigData.animationStyle = STYLE;
} else if (r.szRule.find("idleinhibit") == 0) { } else if (r.szRule.find("idleinhibit") == 0) {
auto IDLERULE = r.szRule.substr(r.szRule.find_first_of(' ') + 1); auto IDLERULE = r.szRule.substr(r.szRule.find_first_of(' ') + 1);
@ -216,21 +183,8 @@ void Events::listener_mapWindow(void* owner, void* data) {
} else { } else {
Debug::log(ERR, "Rule idleinhibit: unknown mode %s", IDLERULE.c_str()); Debug::log(ERR, "Rule idleinhibit: unknown mode %s", IDLERULE.c_str());
} }
} else if (r.szRule.find("bordercolor") == 0) {
try {
std::string colorPart = removeBeginEndSpacesTabs(r.szRule.substr(r.szRule.find_first_of(' ') + 1));
if (colorPart.contains(' ')) {
// we have a space, 2 values
PWINDOW->m_sSpecialRenderData.activeBorderColor = configStringToInt(colorPart.substr(0, colorPart.find_first_of(' ')));
PWINDOW->m_sSpecialRenderData.inactiveBorderColor = configStringToInt(colorPart.substr(colorPart.find_first_of(' ') + 1));
} else {
PWINDOW->m_sSpecialRenderData.activeBorderColor = configStringToInt(colorPart);
}
} catch(std::exception& e) {
Debug::log(ERR, "BorderColor rule \"%s\" failed with: %s", r.szRule.c_str(), e.what());
}
} }
PWINDOW->applyDynamicRule(r);
} }
// disallow tiled pinned // disallow tiled pinned
@ -752,6 +706,8 @@ void Events::listener_setTitleWindow(void* owner, void* data) {
if (PWINDOW == g_pCompositor->m_pLastWindow) // if it's the active, let's post an event to update others if (PWINDOW == g_pCompositor->m_pLastWindow) // if it's the active, let's post an event to update others
g_pEventManager->postEvent(SHyprIPCEvent{"activewindow", g_pXWaylandManager->getAppIDClass(PWINDOW) + "," + PWINDOW->m_szTitle}); g_pEventManager->postEvent(SHyprIPCEvent{"activewindow", g_pXWaylandManager->getAppIDClass(PWINDOW) + "," + PWINDOW->m_szTitle});
PWINDOW->updateDynamicRules();
g_pCompositor->updateWindowAnimatedDecorationValues(PWINDOW);
PWINDOW->updateToplevel(); PWINDOW->updateToplevel();
Debug::log(LOG, "Window %x set title to %s", PWINDOW, PWINDOW->m_szTitle.c_str()); Debug::log(LOG, "Window %x set title to %s", PWINDOW, PWINDOW->m_szTitle.c_str());

View file

@ -599,6 +599,8 @@ void CKeybindManager::toggleActiveFloating(std::string args) {
PWINDOW->m_bIsFloating = !PWINDOW->m_bIsFloating; PWINDOW->m_bIsFloating = !PWINDOW->m_bIsFloating;
PWINDOW->updateDynamicRules();
g_pLayoutManager->getCurrentLayout()->changeWindowFloatingMode(PWINDOW); g_pLayoutManager->getCurrentLayout()->changeWindowFloatingMode(PWINDOW);
} }
@ -1707,6 +1709,9 @@ void CKeybindManager::pinActive(std::string args) {
g_pCompositor->m_pLastWindow->m_bPinned = !g_pCompositor->m_pLastWindow->m_bPinned; g_pCompositor->m_pLastWindow->m_bPinned = !g_pCompositor->m_pLastWindow->m_bPinned;
g_pCompositor->m_pLastWindow->m_iWorkspaceID = g_pCompositor->getMonitorFromID(g_pCompositor->m_pLastWindow->m_iMonitorID)->activeWorkspace; g_pCompositor->m_pLastWindow->m_iWorkspaceID = g_pCompositor->getMonitorFromID(g_pCompositor->m_pLastWindow->m_iMonitorID)->activeWorkspace;
g_pCompositor->m_pLastWindow->updateDynamicRules();
g_pCompositor->updateWindowAnimatedDecorationValues(g_pCompositor->m_pLastWindow);
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(g_pCompositor->m_pLastWindow->m_iWorkspaceID); const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(g_pCompositor->m_pLastWindow->m_iWorkspaceID);
PWORKSPACE->m_pLastFocusedWindow = g_pCompositor->vectorToWindowTiled(g_pInputManager->getMouseCoordsInternal()); PWORKSPACE->m_pLastFocusedWindow = g_pCompositor->vectorToWindowTiled(g_pInputManager->getMouseCoordsInternal());