aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorVaxry <[email protected]>2023-11-04 13:10:52 +0000
committerGitHub <[email protected]>2023-11-04 13:10:52 +0000
commit73e78f05ad5cafa20ac5bf177c94ac9ecca37097 (patch)
tree20a61de56d8542ef0d7e9be463aea181d7a73387
parent54e51b7acf809b4cf705ae516f78a910c70e651f (diff)
downloadHyprland-73e78f05ad5cafa20ac5bf177c94ac9ecca37097.tar.gz
Hyprland-73e78f05ad5cafa20ac5bf177c94ac9ecca37097.zip
Decos: Window decoration flags, shadow improvements (#3739)
-rw-r--r--src/Window.cpp2
-rw-r--r--src/layout/DwindleLayout.cpp2
-rw-r--r--src/layout/MasterLayout.cpp2
-rw-r--r--src/managers/KeybindManager.cpp2
-rw-r--r--src/managers/input/InputManager.cpp8
-rw-r--r--src/render/OpenGL.cpp53
-rw-r--r--src/render/OpenGL.hpp2
-rw-r--r--src/render/Renderer.cpp30
-rw-r--r--src/render/Shader.hpp13
-rw-r--r--src/render/decorations/CHyprDropShadowDecoration.cpp80
-rw-r--r--src/render/decorations/CHyprDropShadowDecoration.hpp4
-rw-r--r--src/render/decorations/CHyprGroupBarDecoration.cpp12
-rw-r--r--src/render/decorations/CHyprGroupBarDecoration.hpp6
-rw-r--r--src/render/decorations/IHyprWindowDecoration.cpp18
-rw-r--r--src/render/decorations/IHyprWindowDecoration.hpp23
-rw-r--r--src/render/shaders/Shadow.hpp7
-rw-r--r--src/render/shaders/Textures.hpp3
17 files changed, 192 insertions, 75 deletions
diff --git a/src/Window.cpp b/src/Window.cpp
index 2f0809bf..f66a3139 100644
--- a/src/Window.cpp
+++ b/src/Window.cpp
@@ -146,7 +146,7 @@ wlr_box CWindow::getWindowInputBox() {
for (auto& wd : m_dWindowDecorations) {
- if (!wd->allowsInput())
+ if (!(wd->getDecorationFlags() & DECORATION_ALLOWS_MOUSE_INPUT))
continue;
const auto EXTENTS = wd->getWindowDecorationExtents();
diff --git a/src/layout/DwindleLayout.cpp b/src/layout/DwindleLayout.cpp
index 30568375..45db3855 100644
--- a/src/layout/DwindleLayout.cpp
+++ b/src/layout/DwindleLayout.cpp
@@ -317,7 +317,7 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow, eDirection dire
if (!m_vOverrideFocalPoint && g_pInputManager->m_bWasDraggingWindow) {
for (auto& wd : OPENINGON->pWindow->m_dWindowDecorations) {
- if (!wd->allowsInput())
+ if (!(wd->getDecorationFlags() & DECORATION_ALLOWS_MOUSE_INPUT))
continue;
if (wd->getWindowDecorationRegion().containsPoint(MOUSECOORDS)) {
diff --git a/src/layout/MasterLayout.cpp b/src/layout/MasterLayout.cpp
index 8cc35ee6..0fbb2391 100644
--- a/src/layout/MasterLayout.cpp
+++ b/src/layout/MasterLayout.cpp
@@ -96,7 +96,7 @@ void CHyprMasterLayout::onWindowCreatedTiling(CWindow* pWindow, eDirection direc
if (g_pInputManager->m_bWasDraggingWindow && OPENINGON) {
for (auto& wd : OPENINGON->pWindow->m_dWindowDecorations) {
- if (!wd->allowsInput())
+ if (!(wd->getDecorationFlags() & DECORATION_ALLOWS_MOUSE_INPUT))
continue;
if (wd->getWindowDecorationRegion().containsPoint(MOUSECOORDS)) {
diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp
index 23adc165..ac995ad9 100644
--- a/src/managers/KeybindManager.cpp
+++ b/src/managers/KeybindManager.cpp
@@ -1841,7 +1841,7 @@ void CKeybindManager::mouse(std::string args) {
if (pWindow && !pWindow->m_bIsFullscreen && !pWindow->hasPopupAt(mouseCoords)) {
for (auto& wd : pWindow->m_dWindowDecorations) {
- if (!wd->allowsInput())
+ if (!(wd->getDecorationFlags() & DECORATION_ALLOWS_MOUSE_INPUT))
continue;
if (wd->getWindowDecorationRegion().containsPoint(mouseCoords)) {
diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp
index 09571291..dcbf4e3c 100644
--- a/src/managers/input/InputManager.cpp
+++ b/src/managers/input/InputManager.cpp
@@ -585,7 +585,7 @@ void CInputManager::processMouseDownNormal(wlr_pointer_button_event* e) {
if (w && !w->m_bIsFullscreen && !w->hasPopupAt(mouseCoords)) {
for (auto& wd : w->m_dWindowDecorations) {
- if (!wd->allowsInput())
+ if (!(wd->getDecorationFlags() & DECORATION_ALLOWS_MOUSE_INPUT))
continue;
if (wd->getWindowDecorationRegion().containsPoint(mouseCoords)) {
@@ -1634,11 +1634,11 @@ void CInputManager::setCursorIconOnBorder(CWindow* w) {
bool onDeco = false;
- for (auto& d : w->m_dWindowDecorations) {
- if (!d->allowsInput())
+ for (auto& wd : w->m_dWindowDecorations) {
+ if (!(wd->getDecorationFlags() & DECORATION_ALLOWS_MOUSE_INPUT))
continue;
- if (d->getWindowDecorationRegion().containsPoint(mouseCoords)) {
+ if (wd->getWindowDecorationRegion().containsPoint(mouseCoords)) {
onDeco = true;
break;
}
diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp
index d23a1d38..d8637a53 100644
--- a/src/render/OpenGL.cpp
+++ b/src/render/OpenGL.cpp
@@ -329,18 +329,21 @@ void CHyprOpenGLImpl::initShaders() {
m_RenderData.pCurrentMonData->m_shBLURFINISH.contrast = glGetUniformLocation(prog, "contrast");
m_RenderData.pCurrentMonData->m_shBLURFINISH.brightness = glGetUniformLocation(prog, "brightness");
- prog = createProgram(QUADVERTSRC, FRAGSHADOW);
- m_RenderData.pCurrentMonData->m_shSHADOW.program = prog;
- m_RenderData.pCurrentMonData->m_shSHADOW.proj = glGetUniformLocation(prog, "proj");
- m_RenderData.pCurrentMonData->m_shSHADOW.posAttrib = glGetAttribLocation(prog, "pos");
- m_RenderData.pCurrentMonData->m_shSHADOW.texAttrib = glGetAttribLocation(prog, "texcoord");
- m_RenderData.pCurrentMonData->m_shSHADOW.topLeft = glGetUniformLocation(prog, "topLeft");
- m_RenderData.pCurrentMonData->m_shSHADOW.bottomRight = glGetUniformLocation(prog, "bottomRight");
- m_RenderData.pCurrentMonData->m_shSHADOW.fullSize = glGetUniformLocation(prog, "fullSize");
- m_RenderData.pCurrentMonData->m_shSHADOW.radius = glGetUniformLocation(prog, "radius");
- m_RenderData.pCurrentMonData->m_shSHADOW.range = glGetUniformLocation(prog, "range");
- m_RenderData.pCurrentMonData->m_shSHADOW.shadowPower = glGetUniformLocation(prog, "shadowPower");
- m_RenderData.pCurrentMonData->m_shSHADOW.color = glGetUniformLocation(prog, "color");
+ prog = createProgram(QUADVERTSRC, FRAGSHADOW);
+ m_RenderData.pCurrentMonData->m_shSHADOW.program = prog;
+ m_RenderData.pCurrentMonData->m_shSHADOW.proj = glGetUniformLocation(prog, "proj");
+ m_RenderData.pCurrentMonData->m_shSHADOW.posAttrib = glGetAttribLocation(prog, "pos");
+ m_RenderData.pCurrentMonData->m_shSHADOW.texAttrib = glGetAttribLocation(prog, "texcoord");
+ m_RenderData.pCurrentMonData->m_shSHADOW.matteTexAttrib = glGetAttribLocation(prog, "texcoordMatte");
+ m_RenderData.pCurrentMonData->m_shSHADOW.alphaMatte = glGetUniformLocation(prog, "alphaMatte");
+ m_RenderData.pCurrentMonData->m_shSHADOW.topLeft = glGetUniformLocation(prog, "topLeft");
+ m_RenderData.pCurrentMonData->m_shSHADOW.bottomRight = glGetUniformLocation(prog, "bottomRight");
+ m_RenderData.pCurrentMonData->m_shSHADOW.fullSize = glGetUniformLocation(prog, "fullSize");
+ m_RenderData.pCurrentMonData->m_shSHADOW.radius = glGetUniformLocation(prog, "radius");
+ m_RenderData.pCurrentMonData->m_shSHADOW.range = glGetUniformLocation(prog, "range");
+ m_RenderData.pCurrentMonData->m_shSHADOW.shadowPower = glGetUniformLocation(prog, "shadowPower");
+ m_RenderData.pCurrentMonData->m_shSHADOW.color = glGetUniformLocation(prog, "color");
+ m_RenderData.pCurrentMonData->m_shSHADOW.useAlphaMatte = glGetUniformLocation(prog, "useAlphaMatte");
prog = createProgram(QUADVERTSRC, FRAGBORDER1);
m_RenderData.pCurrentMonData->m_shBORDER1.program = prog;
@@ -1637,7 +1640,7 @@ void CHyprOpenGLImpl::renderSnapshot(SLayerSurface** pLayer) {
m_bEndFrame = false;
}
-void CHyprOpenGLImpl::renderRoundedShadow(wlr_box* box, int round, int range, float a) {
+void CHyprOpenGLImpl::renderRoundedShadow(wlr_box* box, int round, int range, float a, CFramebuffer* matte) {
RASSERT(m_RenderData.pMonitor, "Tried to render shadow without begin()!");
RASSERT((box->width > 0 && box->height > 0), "Tried to render shadow with width/height < 0!");
RASSERT(m_pCurrentWindow, "Tried to render shadow without a window!");
@@ -1657,6 +1660,7 @@ void CHyprOpenGLImpl::renderRoundedShadow(wlr_box* box, int round, int range, fl
static auto* const PSHADOWPOWER = &g_pConfigManager->getConfigValuePtr("decoration:shadow_render_power")->intValue;
const auto SHADOWPOWER = std::clamp((int)*PSHADOWPOWER, 1, 4);
+ const auto USEMATTE = matte;
const auto col = m_pCurrentWindow->m_cRealShadowColor.col();
@@ -1691,11 +1695,33 @@ void CHyprOpenGLImpl::renderRoundedShadow(wlr_box* box, int round, int range, fl
glUniform1f(m_RenderData.pCurrentMonData->m_shSHADOW.range, range);
glUniform1f(m_RenderData.pCurrentMonData->m_shSHADOW.shadowPower, SHADOWPOWER);
+ if (USEMATTE) {
+ glUniform1i(m_RenderData.pCurrentMonData->m_shSHADOW.useAlphaMatte, 1);
+ glUniform1i(m_RenderData.pCurrentMonData->m_shSHADOW.alphaMatte, 0);
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(matte->m_cTex.m_iTarget, matte->m_cTex.m_iTexID);
+ } else {
+ glUniform1i(m_RenderData.pCurrentMonData->m_shSHADOW.useAlphaMatte, 0);
+ }
+
+ const float texVerts[] = {
+ ((float)(box->x + box->width) / m_RenderData.pMonitor->vecPixelSize.x),
+ ((float)box->y / m_RenderData.pMonitor->vecPixelSize.y), // top right
+ ((float)box->x / m_RenderData.pMonitor->vecPixelSize.x),
+ ((float)box->y / m_RenderData.pMonitor->vecPixelSize.y), // top left
+ ((float)(box->x + box->width) / m_RenderData.pMonitor->vecPixelSize.x),
+ ((float)(box->y + box->height) / m_RenderData.pMonitor->vecPixelSize.y), // bottom right
+ ((float)box->x / m_RenderData.pMonitor->vecPixelSize.x),
+ ((float)(box->y + box->height) / m_RenderData.pMonitor->vecPixelSize.y), // bottom left
+ };
+
glVertexAttribPointer(m_RenderData.pCurrentMonData->m_shSHADOW.posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
glVertexAttribPointer(m_RenderData.pCurrentMonData->m_shSHADOW.texAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
+ glVertexAttribPointer(m_RenderData.pCurrentMonData->m_shSHADOW.matteTexAttrib, 2, GL_FLOAT, GL_FALSE, 0, texVerts);
glEnableVertexAttribArray(m_RenderData.pCurrentMonData->m_shSHADOW.posAttrib);
glEnableVertexAttribArray(m_RenderData.pCurrentMonData->m_shSHADOW.texAttrib);
+ glEnableVertexAttribArray(m_RenderData.pCurrentMonData->m_shSHADOW.matteTexAttrib);
if (m_RenderData.clipBox.width != 0 && m_RenderData.clipBox.height != 0) {
CRegion damageClip{m_RenderData.clipBox.x, m_RenderData.clipBox.y, m_RenderData.clipBox.width, m_RenderData.clipBox.height};
@@ -1714,6 +1740,7 @@ void CHyprOpenGLImpl::renderRoundedShadow(wlr_box* box, int round, int range, fl
}
}
+ glDisableVertexAttribArray(m_RenderData.pCurrentMonData->m_shSHADOW.matteTexAttrib);
glDisableVertexAttribArray(m_RenderData.pCurrentMonData->m_shSHADOW.posAttrib);
glDisableVertexAttribArray(m_RenderData.pCurrentMonData->m_shSHADOW.texAttrib);
}
diff --git a/src/render/OpenGL.hpp b/src/render/OpenGL.hpp
index 0d4b7852..ab3eb7cf 100644
--- a/src/render/OpenGL.hpp
+++ b/src/render/OpenGL.hpp
@@ -111,7 +111,7 @@ class CHyprOpenGLImpl {
void renderTexture(wlr_texture*, wlr_box*, float a, int round = 0, bool allowCustomUV = false);
void renderTexture(const CTexture&, wlr_box*, float a, int round = 0, bool discardActive = false, bool allowCustomUV = false);
void renderTextureWithBlur(const CTexture&, wlr_box*, float a, wlr_surface* pSurface, int round = 0, bool blockBlurOptimization = false, float blurA = 1.f);
- void renderRoundedShadow(wlr_box*, int round, int range, float a = 1.0);
+ void renderRoundedShadow(wlr_box*, int round, int range, float a = 1.0, CFramebuffer* matte = nullptr);
void renderBorder(wlr_box*, const CGradientValueData&, int round, int borderSize, float a = 1.0, int outerRound = -1 /* use round */);
void saveMatrix();
diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp
index 1b59afe8..82175b99 100644
--- a/src/render/Renderer.cpp
+++ b/src/render/Renderer.cpp
@@ -425,9 +425,21 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, CMonitor* pMonitor, timespec*
}
}
- if (!pWindow->m_bIsFullscreen || PWORKSPACE->m_efFullscreenMode != FULLSCREEN_FULL)
- for (auto& wd : pWindow->m_dWindowDecorations)
+ if (!pWindow->m_bIsFullscreen || PWORKSPACE->m_efFullscreenMode != FULLSCREEN_FULL) {
+ for (auto& wd : pWindow->m_dWindowDecorations) {
+ if (wd->getDecorationLayer() != DECORATION_LAYER_BOTTOM)
+ continue;
+
+ wd->draw(pMonitor, renderdata.alpha * renderdata.fadeAlpha, Vector2D{renderdata.x, renderdata.y} - PREOFFSETPOS);
+ }
+
+ for (auto& wd : pWindow->m_dWindowDecorations) {
+ if (wd->getDecorationLayer() != DECORATION_LAYER_UNDER)
+ continue;
+
wd->draw(pMonitor, renderdata.alpha * renderdata.fadeAlpha, Vector2D{renderdata.x, renderdata.y} - PREOFFSETPOS);
+ }
+ }
static auto* const PXWLUSENN = &g_pConfigManager->getConfigValuePtr("xwayland:use_nearest_neighbor")->intValue;
if ((pWindow->m_bIsX11 && *PXWLUSENN) || pWindow->m_sAdditionalConfigData.nearestNeighbor.toUnderlying())
@@ -470,6 +482,13 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, CMonitor* pMonitor, timespec*
}
}
+ for (auto& wd : pWindow->m_dWindowDecorations) {
+ if (wd->getDecorationLayer() != DECORATION_LAYER_OVER)
+ continue;
+
+ wd->draw(pMonitor, renderdata.alpha * renderdata.fadeAlpha, Vector2D{renderdata.x, renderdata.y} - PREOFFSETPOS);
+ }
+
if (TRANSFORMERSPRESENT) {
CFramebuffer* last = g_pHyprOpenGL->m_RenderData.currentFB;
@@ -501,6 +520,13 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, CMonitor* pMonitor, timespec*
g_pHyprOpenGL->m_RenderData.useNearestNeighbor = false;
}
+
+ for (auto& wd : pWindow->m_dWindowDecorations) {
+ if (wd->getDecorationLayer() != DECORATION_LAYER_OVERLAY)
+ continue;
+
+ wd->draw(pMonitor, renderdata.alpha * renderdata.fadeAlpha, Vector2D{renderdata.x, renderdata.y} - PREOFFSETPOS);
+ }
}
EMIT_HOOK_EVENT("render", RENDER_POST_WINDOW);
diff --git a/src/render/Shader.hpp b/src/render/Shader.hpp
index e972eeb9..b67f61ef 100644
--- a/src/render/Shader.hpp
+++ b/src/render/Shader.hpp
@@ -10,10 +10,12 @@ class CShader {
GLuint program = 0;
GLint proj = -1;
GLint color = -1;
+ GLint alphaMatte = -1;
GLint tex = -1;
GLint alpha = -1;
GLint posAttrib = -1;
GLint texAttrib = -1;
+ GLint matteTexAttrib = -1;
GLint discardOpaque = -1;
GLint discardAlpha = -1;
GLfloat discardAlphaValue = -1;
@@ -29,8 +31,9 @@ class CShader {
GLint halfpixel = -1;
- GLint range = -1;
- GLint shadowPower = -1;
+ GLint range = -1;
+ GLint shadowPower = -1;
+ GLint useAlphaMatte = -1; // always inverted
GLint applyTint = -1;
GLint tint = -1;
@@ -43,9 +46,9 @@ class CShader {
GLint distort = -1;
GLint output = -1;
- GLint noise = -1;
- GLint contrast = -1;
- GLint brightness = -1;
+ GLint noise = -1;
+ GLint contrast = -1;
+ GLint brightness = -1;
GLint getUniformLocation(const std::string&);
diff --git a/src/render/decorations/CHyprDropShadowDecoration.cpp b/src/render/decorations/CHyprDropShadowDecoration.cpp
index ee1a65a5..c2edb9ce 100644
--- a/src/render/decorations/CHyprDropShadowDecoration.cpp
+++ b/src/render/decorations/CHyprDropShadowDecoration.cpp
@@ -45,6 +45,32 @@ void CHyprDropShadowDecoration::updateWindow(CWindow* pWindow) {
m_vLastWindowSize = pWindow->m_vRealSize.vec();
damageEntire();
+
+ const auto BORDER = m_pWindow->getRealBorderSize();
+
+ // calculate extents of decos with the DECORATION_PART_OF_MAIN_WINDOW flag
+ SWindowDecorationExtents maxExtents;
+
+ for (auto& wd : m_pWindow->m_dWindowDecorations) {
+ // conveniently, this will also skip us.
+ if (!(wd->getDecorationFlags() & DECORATION_PART_OF_MAIN_WINDOW))
+ continue;
+
+ const auto EXTENTS = wd->getWindowDecorationExtents();
+
+ if (maxExtents.topLeft.x < EXTENTS.topLeft.x)
+ maxExtents.topLeft.x = EXTENTS.topLeft.x;
+ if (maxExtents.topLeft.y < EXTENTS.topLeft.y)
+ maxExtents.topLeft.y = EXTENTS.topLeft.y;
+ if (maxExtents.bottomRight.x < EXTENTS.bottomRight.x)
+ maxExtents.bottomRight.x = EXTENTS.bottomRight.x;
+ if (maxExtents.bottomRight.y < EXTENTS.bottomRight.y)
+ maxExtents.bottomRight.y = EXTENTS.bottomRight.y;
+ }
+
+ m_bLastWindowBox = {(int)(m_vLastWindowPos.x - maxExtents.topLeft.x - BORDER), (int)(m_vLastWindowPos.y - maxExtents.topLeft.y - BORDER),
+ (int)(m_vLastWindowSize.x + maxExtents.topLeft.x + maxExtents.bottomRight.x + 2 * BORDER),
+ (int)(m_vLastWindowSize.y + maxExtents.topLeft.y + maxExtents.bottomRight.y + 2 * BORDER)};
}
}
@@ -67,7 +93,6 @@ void CHyprDropShadowDecoration::draw(CMonitor* pMonitor, float a, const Vector2D
static auto* const PSHADOWS = &g_pConfigManager->getConfigValuePtr("decoration:drop_shadow")->intValue;
static auto* const PSHADOWSIZE = &g_pConfigManager->getConfigValuePtr("decoration:shadow_range")->intValue;
- static auto* const PROUNDING = &g_pConfigManager->getConfigValuePtr("decoration:rounding")->intValue;
static auto* const PSHADOWIGNOREWINDOW = &g_pConfigManager->getConfigValuePtr("decoration:shadow_ignore_window")->intValue;
static auto* const PSHADOWSCALE = &g_pConfigManager->getConfigValuePtr("decoration:shadow_scale")->floatValue;
static auto* const PSHADOWOFFSET = &g_pConfigManager->getConfigValuePtr("decoration:shadow_offset")->vecValue;
@@ -75,12 +100,11 @@ void CHyprDropShadowDecoration::draw(CMonitor* pMonitor, float a, const Vector2D
if (*PSHADOWS != 1)
return; // disabled
- const auto ROUNDING = !m_pWindow->m_sSpecialRenderData.rounding ?
- 0 :
- (m_pWindow->m_sAdditionalConfigData.rounding.toUnderlying() == -1 ? *PROUNDING : m_pWindow->m_sAdditionalConfigData.rounding.toUnderlying());
+ const auto ROUNDING = m_pWindow->rounding() + m_pWindow->getRealBorderSize();
// draw the shadow
- wlr_box fullBox = {m_vLastWindowPos.x - *PSHADOWSIZE, m_vLastWindowPos.y - *PSHADOWSIZE, m_vLastWindowSize.x + 2.0 * *PSHADOWSIZE, m_vLastWindowSize.y + 2.0 * *PSHADOWSIZE};
+ wlr_box fullBox = {m_bLastWindowBox.x - *PSHADOWSIZE, m_bLastWindowBox.y - *PSHADOWSIZE, m_bLastWindowBox.width + 2.0 * *PSHADOWSIZE,
+ m_bLastWindowBox.height + 2.0 * *PSHADOWSIZE};
fullBox.x -= pMonitor->vecPosition.x;
fullBox.y -= pMonitor->vecPosition.y;
@@ -95,17 +119,17 @@ void CHyprDropShadowDecoration::draw(CMonitor* pMonitor, float a, const Vector2D
if (PSHADOWOFFSET->x < 0) {
fullBox.x += PSHADOWOFFSET->x;
} else if (PSHADOWOFFSET->x > 0) {
- fullBox.x = m_vLastWindowPos.x + m_vLastWindowSize.x - fullBox.width + (SHADOWSCALE * *PSHADOWSIZE) + PSHADOWOFFSET->x - pMonitor->vecPosition.x;
+ fullBox.x = m_bLastWindowBox.x + m_bLastWindowBox.width - fullBox.width + (SHADOWSCALE * *PSHADOWSIZE) + PSHADOWOFFSET->x - pMonitor->vecPosition.x;
} else {
- fullBox.x += ((m_vLastWindowSize.x + 2.0 * *PSHADOWSIZE) - NEWSIZE.x) / 2.0;
+ fullBox.x += ((m_bLastWindowBox.width + 2.0 * *PSHADOWSIZE) - NEWSIZE.x) / 2.0;
}
if (PSHADOWOFFSET->y < 0) {
fullBox.y += PSHADOWOFFSET->y;
} else if (PSHADOWOFFSET->y > 0) {
- fullBox.y = m_vLastWindowPos.y + m_vLastWindowSize.y - fullBox.height + (SHADOWSCALE * *PSHADOWSIZE) + PSHADOWOFFSET->y - pMonitor->vecPosition.y;
+ fullBox.y = m_bLastWindowBox.y + m_bLastWindowBox.height - fullBox.height + (SHADOWSCALE * *PSHADOWSIZE) + PSHADOWOFFSET->y - pMonitor->vecPosition.y;
} else {
- fullBox.y += ((m_vLastWindowSize.y + 2.0 * *PSHADOWSIZE) - NEWSIZE.y) / 2.0;
+ fullBox.y += ((m_bLastWindowBox.height + 2.0 * *PSHADOWSIZE) - NEWSIZE.y) / 2.0;
}
m_seExtents = {{m_vLastWindowPos.x - fullBox.x - pMonitor->vecPosition.x + 2, m_vLastWindowPos.y - fullBox.y - pMonitor->vecPosition.y + 2},
@@ -120,39 +144,31 @@ void CHyprDropShadowDecoration::draw(CMonitor* pMonitor, float a, const Vector2D
g_pHyprOpenGL->scissor((wlr_box*)nullptr);
- if (*PSHADOWIGNOREWINDOW) {
- glEnable(GL_STENCIL_TEST);
-
- glClearStencil(0);
- glClear(GL_STENCIL_BUFFER_BIT);
-
- glStencilFunc(GL_ALWAYS, 1, -1);
- glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
+ // we'll take the liberty of using this as it should not be used rn
+ CFramebuffer& alphaFB = g_pHyprOpenGL->m_RenderData.pCurrentMonData->mirrorFB;
+ auto* LASTFB = g_pHyprOpenGL->m_RenderData.currentFB;
- wlr_box windowBox = {m_vLastWindowPos.x - pMonitor->vecPosition.x, m_vLastWindowPos.y - pMonitor->vecPosition.y, m_vLastWindowSize.x, m_vLastWindowSize.y};
+ if (*PSHADOWIGNOREWINDOW) {
+ wlr_box windowBox = {m_bLastWindowBox.x - pMonitor->vecPosition.x, m_bLastWindowBox.y - pMonitor->vecPosition.y, m_bLastWindowBox.width, m_bLastWindowBox.height};
scaleBox(&windowBox, pMonitor->scale);
if (windowBox.width < 1 || windowBox.height < 1) {
- glClearStencil(0);
- glClear(GL_STENCIL_BUFFER_BIT);
- glDisable(GL_STENCIL_TEST);
return; // prevent assert failed
}
- g_pHyprOpenGL->renderRect(&windowBox, CColor(0, 0, 0, 0), ROUNDING * pMonitor->scale);
+ alphaFB.bind();
+ g_pHyprOpenGL->clear(CColor(0, 0, 0, 0));
+
+ g_pHyprOpenGL->renderRect(&windowBox, CColor(1.0, 1.0, 1.0, 1.0), ROUNDING * pMonitor->scale);
- glStencilFunc(GL_NOTEQUAL, 1, -1);
- glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
+ LASTFB->bind();
}
scaleBox(&fullBox, pMonitor->scale);
- g_pHyprOpenGL->renderRoundedShadow(&fullBox, ROUNDING * pMonitor->scale, *PSHADOWSIZE * pMonitor->scale, a);
-
- if (*PSHADOWIGNOREWINDOW) {
- // cleanup
- glClearStencil(0);
- glClear(GL_STENCIL_BUFFER_BIT);
- glDisable(GL_STENCIL_TEST);
- }
+ g_pHyprOpenGL->renderRoundedShadow(&fullBox, ROUNDING * pMonitor->scale, *PSHADOWSIZE * pMonitor->scale, a, &alphaFB);
}
+
+eDecorationLayer CHyprDropShadowDecoration::getDecorationLayer() {
+ return DECORATION_LAYER_BOTTOM;
+} \ No newline at end of file
diff --git a/src/render/decorations/CHyprDropShadowDecoration.hpp b/src/render/decorations/CHyprDropShadowDecoration.hpp
index 3a7ffb2b..7fadf851 100644
--- a/src/render/decorations/CHyprDropShadowDecoration.hpp
+++ b/src/render/decorations/CHyprDropShadowDecoration.hpp
@@ -17,6 +17,8 @@ class CHyprDropShadowDecoration : public IHyprWindowDecoration {
virtual void damageEntire();
+ virtual eDecorationLayer getDecorationLayer();
+
private:
SWindowDecorationExtents m_seExtents;
@@ -24,4 +26,6 @@ class CHyprDropShadowDecoration : public IHyprWindowDecoration {
Vector2D m_vLastWindowPos;
Vector2D m_vLastWindowSize;
+
+ wlr_box m_bLastWindowBox = {0};
}; \ No newline at end of file
diff --git a/src/render/decorations/CHyprGroupBarDecoration.cpp b/src/render/decorations/CHyprGroupBarDecoration.cpp
index 3e3075ea..a34a47b7 100644
--- a/src/render/decorations/CHyprGroupBarDecoration.cpp
+++ b/src/render/decorations/CHyprGroupBarDecoration.cpp
@@ -301,10 +301,6 @@ void CHyprGroupBarDecoration::refreshGradients() {
renderGradientTo(m_tGradientInactive, ((CGradientValueData*)PCOLINACTIVE->get())->m_vColors[0]);
}
-bool CHyprGroupBarDecoration::allowsInput() {
- return true;
-}
-
bool CHyprGroupBarDecoration::onEndWindowDragOnDeco(CWindow* pDraggedWindow, const Vector2D& pos) {
if (!pDraggedWindow->canBeGroupedInto(m_pWindow))
@@ -407,3 +403,11 @@ void CHyprGroupBarDecoration::onBeginWindowDragOnDeco(const Vector2D& pos) {
if (!g_pCompositor->isWindowActive(pWindow))
g_pCompositor->focusWindow(pWindow);
}
+
+eDecorationLayer CHyprGroupBarDecoration::getDecorationLayer() {
+ return DECORATION_LAYER_OVER;
+}
+
+uint64_t CHyprGroupBarDecoration::getDecorationFlags() {
+ return DECORATION_ALLOWS_MOUSE_INPUT;
+} \ No newline at end of file
diff --git a/src/render/decorations/CHyprGroupBarDecoration.hpp b/src/render/decorations/CHyprGroupBarDecoration.hpp
index 05736d4b..569fda21 100644
--- a/src/render/decorations/CHyprGroupBarDecoration.hpp
+++ b/src/render/decorations/CHyprGroupBarDecoration.hpp
@@ -33,14 +33,16 @@ class CHyprGroupBarDecoration : public IHyprWindowDecoration {
virtual SWindowDecorationExtents getWindowDecorationReservedArea();
- virtual bool allowsInput();
-
virtual void onBeginWindowDragOnDeco(const Vector2D&);
virtual bool onEndWindowDragOnDeco(CWindow* pDraggedWindow, const Vector2D&);
virtual void onMouseButtonOnDeco(const Vector2D&, wlr_pointer_button_event*);
+ virtual eDecorationLayer getDecorationLayer();
+
+ virtual uint64_t getDecorationFlags();
+
private:
SWindowDecorationExtents m_seExtents;
diff --git a/src/render/decorations/IHyprWindowDecoration.cpp b/src/render/decorations/IHyprWindowDecoration.cpp
index e0868b0b..d2b9b0f9 100644
--- a/src/render/decorations/IHyprWindowDecoration.cpp
+++ b/src/render/decorations/IHyprWindowDecoration.cpp
@@ -25,14 +25,22 @@ CRegion IHyprWindowDecoration::getWindowDecorationRegion() {
m_pWindow->m_vRealSize.vec().y + 2 * BORDERSIZE));
}
-bool IHyprWindowDecoration::allowsInput() {
- return false;
+void IHyprWindowDecoration::onBeginWindowDragOnDeco(const Vector2D&) {
+ ;
}
-void IHyprWindowDecoration::onBeginWindowDragOnDeco(const Vector2D&) {}
-
bool IHyprWindowDecoration::onEndWindowDragOnDeco(CWindow* pDraggedWindow, const Vector2D&) {
return true;
}
-void IHyprWindowDecoration::onMouseButtonOnDeco(const Vector2D&, wlr_pointer_button_event*) {}
+void IHyprWindowDecoration::onMouseButtonOnDeco(const Vector2D&, wlr_pointer_button_event*) {
+ ;
+}
+
+eDecorationLayer IHyprWindowDecoration::getDecorationLayer() {
+ return DECORATION_LAYER_UNDER;
+}
+
+uint64_t IHyprWindowDecoration::getDecorationFlags() {
+ return 0;
+} \ No newline at end of file
diff --git a/src/render/decorations/IHyprWindowDecoration.hpp b/src/render/decorations/IHyprWindowDecoration.hpp
index eadc486f..29d50595 100644
--- a/src/render/decorations/IHyprWindowDecoration.hpp
+++ b/src/render/decorations/IHyprWindowDecoration.hpp
@@ -3,7 +3,8 @@
#include "../../defines.hpp"
#include "../../helpers/Region.hpp"
-enum eDecorationType {
+enum eDecorationType
+{
DECORATION_NONE = -1,
DECORATION_GROUPBAR,
DECORATION_SHADOW,
@@ -15,6 +16,20 @@ struct SWindowDecorationExtents {
Vector2D bottomRight;
};
+enum eDecorationLayer
+{
+ DECORATION_LAYER_BOTTOM = 0, /* lowest. */
+ DECORATION_LAYER_UNDER, /* under the window, but above BOTTOM */
+ DECORATION_LAYER_OVER, /* above the window, but below its popups */
+ DECORATION_LAYER_OVERLAY /* above everything of the window, including popups */
+};
+
+enum eDecorationFlags
+{
+ DECORATION_ALLOWS_MOUSE_INPUT = 1 << 0, /* this decoration accepts mouse input */
+ DECORATION_PART_OF_MAIN_WINDOW = 1 << 1, /* this decoration is a *seamless* part of the main window, so stuff like shadows will include it */
+};
+
class CWindow;
class CMonitor;
@@ -37,14 +52,16 @@ class IHyprWindowDecoration {
virtual CRegion getWindowDecorationRegion();
- virtual bool allowsInput();
-
virtual void onBeginWindowDragOnDeco(const Vector2D&); // called when the user calls the "movewindow" mouse dispatcher on the deco
virtual bool onEndWindowDragOnDeco(CWindow* pDraggedWindow, const Vector2D&); // returns true if the window should be placed by the layout
virtual void onMouseButtonOnDeco(const Vector2D&, wlr_pointer_button_event*);
+ virtual eDecorationLayer getDecorationLayer();
+
+ virtual uint64_t getDecorationFlags();
+
private:
CWindow* m_pWindow = nullptr;
};
diff --git a/src/render/shaders/Shadow.hpp b/src/render/shaders/Shadow.hpp
index 2c7b07b2..f9bdeb8d 100644
--- a/src/render/shaders/Shadow.hpp
+++ b/src/render/shaders/Shadow.hpp
@@ -5,7 +5,9 @@
inline const std::string FRAGSHADOW = R"#(
precision mediump float;
varying vec4 v_color;
+uniform sampler2D alphaMatte;
varying vec2 v_texcoord;
+varying vec2 v_texcoordMatte;
uniform vec2 topLeft;
uniform vec2 bottomRight;
@@ -13,6 +15,7 @@ uniform vec2 fullSize;
uniform float radius;
uniform float range;
uniform float shadowPower;
+uniform int useAlphaMatte;
float pixAlphaRoundedDistance(float distanceToCorner) {
if (distanceToCorner > radius) {
@@ -74,6 +77,10 @@ void main() {
}
}
+ if (useAlphaMatte == 1) {
+ pixColor[3] *= 1.0 - texture2D(alphaMatte, v_texcoordMatte)[3];
+ }
+
if (pixColor[3] == 0.0) {
discard; return;
}
diff --git a/src/render/shaders/Textures.hpp b/src/render/shaders/Textures.hpp
index 109840ca..6f19ac9f 100644
--- a/src/render/shaders/Textures.hpp
+++ b/src/render/shaders/Textures.hpp
@@ -37,13 +37,16 @@ uniform mat3 proj;
uniform vec4 color;
attribute vec2 pos;
attribute vec2 texcoord;
+attribute vec2 texcoordMatte;
varying vec4 v_color;
varying vec2 v_texcoord;
+varying vec2 v_texcoordMatte;
void main() {
gl_Position = vec4(proj * vec3(pos, 1.0), 1.0);
v_color = color;
v_texcoord = texcoord;
+ v_texcoordMatte = texcoordMatte;
})#";
inline const std::string QUADFRAGSRC = R"#(