diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 99e7d99b..e649e1ab 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -863,7 +863,7 @@ bool windowRuleValid(const std::string& RULE) { } bool layerRuleValid(const std::string& RULE) { - return !(RULE != "noanim" && RULE != "blur" && RULE != "ignorezero"); + return !(RULE != "noanim" && RULE != "blur" && RULE.find("ignorealpha") != 0 && RULE.find("ignorezero") != 0); } void CConfigManager::handleWindowRule(const std::string& command, const std::string& value) { diff --git a/src/helpers/WLClasses.cpp b/src/helpers/WLClasses.cpp index 29e10a54..3a03afcd 100644 --- a/src/helpers/WLClasses.cpp +++ b/src/helpers/WLClasses.cpp @@ -8,16 +8,27 @@ SLayerSurface::SLayerSurface() { } void SLayerSurface::applyRules() { - noAnimations = false; - forceBlur = false; - ignoreZero = false; + noAnimations = false; + forceBlur = false; + ignoreAlpha = false; + ignoreAlphaValue = 0.f; for (auto& rule : g_pConfigManager->getMatchingRules(this)) { if (rule.rule == "noanim") noAnimations = true; else if (rule.rule == "blur") forceBlur = true; - else if (rule.rule == "ignorezero") - ignoreZero = true; + else if (rule.rule.find("ignorealpha") == 0 || rule.rule.find("ignorezero") == 0) { + const auto FIRST_SPACE_POS = rule.rule.find_first_of(' '); + std::string alphaValue = ""; + if (FIRST_SPACE_POS != std::string::npos) + alphaValue = rule.rule.substr(FIRST_SPACE_POS + 1); + + try { + ignoreAlpha = true; + if (!alphaValue.empty()) + ignoreAlphaValue = std::stof(alphaValue); + } catch (...) { Debug::log(ERR, "Invalid value passed to ignoreAlpha"); } + } } } \ No newline at end of file diff --git a/src/helpers/WLClasses.hpp b/src/helpers/WLClasses.hpp index c70c8406..b7cd6e34 100644 --- a/src/helpers/WLClasses.hpp +++ b/src/helpers/WLClasses.hpp @@ -48,8 +48,9 @@ struct SLayerSurface { bool noProcess = false; bool noAnimations = false; - bool forceBlur = false; - bool ignoreZero = false; + bool forceBlur = false; + bool ignoreAlpha = false; + float ignoreAlphaValue = 0.f; // For the list lookup bool operator==(const SLayerSurface& rhs) const { diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index dd0cd3f9..477a0317 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -216,7 +216,8 @@ void CHyprOpenGLImpl::initShaders() { m_RenderData.pCurrentMonData->m_shRGBA.texAttrib = glGetAttribLocation(prog, "texcoord"); m_RenderData.pCurrentMonData->m_shRGBA.posAttrib = glGetAttribLocation(prog, "pos"); m_RenderData.pCurrentMonData->m_shRGBA.discardOpaque = glGetUniformLocation(prog, "discardOpaque"); - m_RenderData.pCurrentMonData->m_shRGBA.discardAlphaZero = glGetUniformLocation(prog, "discardAlphaZero"); + m_RenderData.pCurrentMonData->m_shRGBA.discardAlpha = glGetUniformLocation(prog, "discardAlpha"); + m_RenderData.pCurrentMonData->m_shRGBA.discardAlphaValue = glGetUniformLocation(prog, "discardAlphaValue"); m_RenderData.pCurrentMonData->m_shRGBA.topLeft = glGetUniformLocation(prog, "topLeft"); m_RenderData.pCurrentMonData->m_shRGBA.fullSize = glGetUniformLocation(prog, "fullSize"); m_RenderData.pCurrentMonData->m_shRGBA.radius = glGetUniformLocation(prog, "radius"); @@ -249,7 +250,8 @@ void CHyprOpenGLImpl::initShaders() { m_RenderData.pCurrentMonData->m_shRGBX.texAttrib = glGetAttribLocation(prog, "texcoord"); m_RenderData.pCurrentMonData->m_shRGBX.posAttrib = glGetAttribLocation(prog, "pos"); m_RenderData.pCurrentMonData->m_shRGBX.discardOpaque = glGetUniformLocation(prog, "discardOpaque"); - m_RenderData.pCurrentMonData->m_shRGBX.discardAlphaZero = glGetUniformLocation(prog, "discardAlphaZero"); + m_RenderData.pCurrentMonData->m_shRGBX.discardAlpha = glGetUniformLocation(prog, "discardAlpha"); + m_RenderData.pCurrentMonData->m_shRGBX.discardAlphaValue = glGetUniformLocation(prog, "discardAlphaValue"); m_RenderData.pCurrentMonData->m_shRGBX.topLeft = glGetUniformLocation(prog, "topLeft"); m_RenderData.pCurrentMonData->m_shRGBX.fullSize = glGetUniformLocation(prog, "fullSize"); m_RenderData.pCurrentMonData->m_shRGBX.radius = glGetUniformLocation(prog, "radius"); @@ -265,7 +267,8 @@ void CHyprOpenGLImpl::initShaders() { m_RenderData.pCurrentMonData->m_shEXT.posAttrib = glGetAttribLocation(prog, "pos"); m_RenderData.pCurrentMonData->m_shEXT.texAttrib = glGetAttribLocation(prog, "texcoord"); m_RenderData.pCurrentMonData->m_shEXT.discardOpaque = glGetUniformLocation(prog, "discardOpaque"); - m_RenderData.pCurrentMonData->m_shEXT.discardAlphaZero = glGetUniformLocation(prog, "discardAlphaZero"); + m_RenderData.pCurrentMonData->m_shEXT.discardAlpha = glGetUniformLocation(prog, "discardAlpha"); + m_RenderData.pCurrentMonData->m_shEXT.discardAlphaValue = glGetUniformLocation(prog, "discardAlphaValue"); m_RenderData.pCurrentMonData->m_shEXT.topLeft = glGetUniformLocation(prog, "topLeft"); m_RenderData.pCurrentMonData->m_shEXT.fullSize = glGetUniformLocation(prog, "fullSize"); m_RenderData.pCurrentMonData->m_shEXT.radius = glGetUniformLocation(prog, "radius"); @@ -619,10 +622,11 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_b if (discardActive) { glUniform1i(shader->discardOpaque, !!(m_RenderData.discardMode & DISCARD_OPAQUE)); - glUniform1i(shader->discardAlphaZero, !!(m_RenderData.discardMode & DISCARD_ALPHAZERO)); + glUniform1i(shader->discardAlpha, !!(m_RenderData.discardMode & DISCARD_ALPHA)); + glUniform1f(shader->discardAlphaValue, m_RenderData.discardOpacity); } else { glUniform1i(shader->discardOpaque, 0); - glUniform1i(shader->discardAlphaZero, 0); + glUniform1i(shader->discardAlpha, 0); } } @@ -1015,7 +1019,7 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, wlr_box* pBox, glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - if (USENEWOPTIMIZE && !(m_RenderData.discardMode & DISCARD_ALPHAZERO)) + if (USENEWOPTIMIZE && !(m_RenderData.discardMode & DISCARD_ALPHA)) renderRect(pBox, CColor(0, 0, 0, 0), round); else renderTexture(tex, pBox, a, round, true, true); // discard opaque @@ -1030,7 +1034,7 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, wlr_box* pBox, static auto* const PBLURIGNOREOPACITY = &g_pConfigManager->getConfigValuePtr("decoration:blur_ignore_opacity")->intValue; m_bEndFrame = true; // fix transformed const auto SAVEDRENDERMODIF = m_RenderData.renderModif; - m_RenderData.renderModif = {}; // fix shit + m_RenderData.renderModif = {}; // fix shit renderTextureInternalWithDamage(POUTFB->m_cTex, &MONITORBOX, *PBLURIGNOREOPACITY ? 1.f : a, &damage, 0, false, false, false); m_bEndFrame = false; m_RenderData.renderModif = SAVEDRENDERMODIF; diff --git a/src/render/OpenGL.hpp b/src/render/OpenGL.hpp index 1b61887e..36aa612c 100644 --- a/src/render/OpenGL.hpp +++ b/src/render/OpenGL.hpp @@ -24,8 +24,8 @@ inline const float fullVerts[] = { inline const float fanVertsFull[] = {-1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f}; enum eDiscardMode { - DISCARD_OPAQUE = 1, - DISCARD_ALPHAZERO = 1 << 1 + DISCARD_OPAQUE = 1, + DISCARD_ALPHA = 1 << 1 }; struct SRenderModifData { @@ -35,8 +35,8 @@ struct SRenderModifData { struct SMonitorRenderData { CFramebuffer primaryFB; - CFramebuffer mirrorFB; // these are used for some effects, - CFramebuffer mirrorSwapFB; // etc + CFramebuffer mirrorFB; // these are used for some effects, + CFramebuffer mirrorSwapFB; // etc CFramebuffer monitorMirrorFB; // used for mirroring outputs @@ -83,7 +83,8 @@ struct SCurrentRenderData { wlr_box clipBox = {}; - uint32_t discardMode = DISCARD_OPAQUE; + uint32_t discardMode = DISCARD_OPAQUE; + float discardOpacity = 0.f; }; class CGradientValueData; @@ -138,9 +139,9 @@ class CHyprOpenGLImpl { bool m_bReloadScreenShader = true; // at launch it can be set - CWindow* m_pCurrentWindow = nullptr; // hack to get the current rendered window + CWindow* m_pCurrentWindow = nullptr; // hack to get the current rendered window - pixman_region32_t m_rOriginalDamageRegion; // used for storing the pre-expanded region + pixman_region32_t m_rOriginalDamageRegion; // used for storing the pre-expanded region std::unordered_map m_mWindowFramebuffers; std::unordered_map m_mLayerFramebuffers; diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 7552b17c..6d995875 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -392,10 +392,12 @@ void CHyprRenderer::renderLayer(SLayerSurface* pLayer, CMonitor* pMonitor, times renderdata.h = pLayer->geometry.height; renderdata.blockBlurOptimization = pLayer->layer == ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM || pLayer->layer == ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND; - if (pLayer->ignoreZero) - g_pHyprOpenGL->m_RenderData.discardMode |= DISCARD_ALPHAZERO; + if (pLayer->ignoreAlpha) { + g_pHyprOpenGL->m_RenderData.discardMode |= DISCARD_ALPHA; + g_pHyprOpenGL->m_RenderData.discardOpacity = pLayer->ignoreAlphaValue; + } wlr_surface_for_each_surface(pLayer->layerSurface->surface, renderSurface, &renderdata); - g_pHyprOpenGL->m_RenderData.discardMode &= ~DISCARD_ALPHAZERO; + g_pHyprOpenGL->m_RenderData.discardMode &= ~DISCARD_ALPHA; renderdata.squishOversized = false; // don't squish popups renderdata.dontRound = true; diff --git a/src/render/Shader.hpp b/src/render/Shader.hpp index 416e62fe..a9c1f7a6 100644 --- a/src/render/Shader.hpp +++ b/src/render/Shader.hpp @@ -7,44 +7,45 @@ class CShader { public: ~CShader(); - GLuint program = 0; - GLint proj; - GLint color; - GLint tex; - GLint alpha; - GLint posAttrib; - GLint texAttrib; - GLint discardOpaque; - GLint discardAlphaZero; + GLuint program = 0; + GLint proj; + GLint color; + GLint tex; + GLint alpha; + GLint posAttrib; + GLint texAttrib; + GLint discardOpaque; + GLint discardAlpha; + GLfloat discardAlphaValue; - GLint topLeft; - GLint bottomRight; - GLint fullSize; - GLint fullSizeUntransformed; - GLint radius; - GLint primitiveMultisample; + GLint topLeft; + GLint bottomRight; + GLint fullSize; + GLint fullSizeUntransformed; + GLint radius; + GLint primitiveMultisample; - GLint thick; + GLint thick; - GLint halfpixel; + GLint halfpixel; - GLint range; - GLint shadowPower; + GLint range; + GLint shadowPower; - GLint applyTint; - GLint tint; + GLint applyTint; + GLint tint; - GLint gradient; - GLint gradientLength; - GLint angle; + GLint gradient; + GLint gradientLength; + GLint angle; - GLint time; - GLint distort; - GLint output; + GLint time; + GLint distort; + GLint output; - GLint getUniformLocation(const std::string&); + GLint getUniformLocation(const std::string&); - void destroy(); + void destroy(); private: std::unordered_map m_muUniforms; diff --git a/src/render/shaders/Textures.hpp b/src/render/shaders/Textures.hpp index 45068839..e571d662 100644 --- a/src/render/shaders/Textures.hpp +++ b/src/render/shaders/Textures.hpp @@ -96,7 +96,8 @@ uniform vec2 fullSize; uniform float radius; uniform int discardOpaque; -uniform int discardAlphaZero; +uniform int discardAlpha; +uniform float discardAlphaValue; uniform int applyTint; uniform vec3 tint; @@ -110,7 +111,7 @@ void main() { if (discardOpaque == 1 && pixColor[3] * alpha == 1.0) discard; - if (discardAlphaZero == 1 && pixColor[3] == 0.0) + if (discardAlpha == 1 && pixColor[3] <= discardAlphaValue) discard; if (applyTint == 1) { @@ -145,7 +146,8 @@ uniform vec2 fullSize; uniform float radius; uniform int discardOpaque; -uniform int discardAlphaZero; +uniform int discardAlpha; +uniform int discardAlphaValue; uniform int applyTint; uniform vec3 tint; @@ -232,7 +234,8 @@ uniform vec2 fullSize; uniform float radius; uniform int discardOpaque; -uniform int discardAlphaZero; +uniform int discardAlpha; +uniform int discardAlphaValue; uniform int applyTint; uniform vec3 tint;