aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorvaxerski <[email protected]>2022-06-22 15:45:56 +0200
committervaxerski <[email protected]>2022-06-22 15:45:56 +0200
commit770bada5d541e737ae17744f70eb019494471a29 (patch)
tree9be90ba75ffed8b22cbe98d4db3468b93ff813df
parent499d2e41bfbc76525c3f03e1fb0a057b910c0c4b (diff)
downloadHyprland-770bada5d541e737ae17744f70eb019494471a29.tar.gz
Hyprland-770bada5d541e737ae17744f70eb019494471a29.zip
Fixed oversized apps' incorrect layout
-rw-r--r--src/Compositor.cpp9
-rw-r--r--src/config/ConfigManager.cpp1
-rw-r--r--src/events/Windows.cpp8
-rw-r--r--src/managers/XWaylandManager.cpp10
-rw-r--r--src/managers/input/InputManager.cpp8
-rw-r--r--src/render/OpenGL.cpp40
-rw-r--r--src/render/OpenGL.hpp8
-rw-r--r--src/render/Renderer.cpp28
8 files changed, 90 insertions, 22 deletions
diff --git a/src/Compositor.cpp b/src/Compositor.cpp
index 32ffab34..a5339948 100644
--- a/src/Compositor.cpp
+++ b/src/Compositor.cpp
@@ -443,7 +443,11 @@ wlr_surface* CCompositor::vectorWindowToSurface(const Vector2D& pos, CWindow* pW
double subx, suby;
- const auto PFOUND = wlr_xdg_surface_surface_at(PSURFACE, pos.x - pWindow->m_vRealPosition.vec().x, pos.y - pWindow->m_vRealPosition.vec().y, &subx, &suby);
+ // calc for oversized windows... fucking bullshit, again.
+ wlr_box geom;
+ wlr_xdg_surface_get_geometry(pWindow->m_uSurface.xdg, &geom);
+
+ const auto PFOUND = wlr_xdg_surface_surface_at(PSURFACE, pos.x - pWindow->m_vRealPosition.vec().x + geom.x, pos.y - pWindow->m_vRealPosition.vec().y + geom.y, &subx, &suby);
if (PFOUND) {
sl.x = subx;
@@ -454,6 +458,9 @@ wlr_surface* CCompositor::vectorWindowToSurface(const Vector2D& pos, CWindow* pW
sl.x = pos.x - pWindow->m_vRealPosition.vec().x;
sl.y = pos.y - pWindow->m_vRealPosition.vec().y;
+ sl.x += geom.x;
+ sl.y += geom.y;
+
return PSURFACE->surface;
}
diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp
index aba0b1ff..d95f5a05 100644
--- a/src/config/ConfigManager.cpp
+++ b/src/config/ConfigManager.cpp
@@ -47,6 +47,7 @@ void CConfigManager::setDefaultVars() {
configValues["decoration:inactive_opacity"].floatValue = 1;
configValues["decoration:fullscreen_opacity"].floatValue = 1;
configValues["decoration:multisample_edges"].intValue = 0;
+ configValues["decoration:no_blur_on_oversized"].intValue = 1;
configValues["dwindle:pseudotile"].intValue = 0;
configValues["dwindle:col.group_border"].intValue = 0x66777700;
diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp
index b84b9d2d..48571892 100644
--- a/src/events/Windows.cpp
+++ b/src/events/Windows.cpp
@@ -19,6 +19,14 @@ void addViewCoords(void* pWindow, int* x, int* y) {
const auto PWINDOW = (CWindow*)pWindow;
*x += PWINDOW->m_vRealPosition.goalv().x;
*y += PWINDOW->m_vRealPosition.goalv().y;
+
+ if (!PWINDOW->m_bIsX11) {
+ wlr_box geom;
+ wlr_xdg_surface_get_geometry(PWINDOW->m_uSurface.xdg, &geom);
+
+ *x -= geom.x;
+ *y -= geom.y;
+ }
}
void Events::listener_mapWindow(void* owner, void* data) {
diff --git a/src/managers/XWaylandManager.cpp b/src/managers/XWaylandManager.cpp
index 5927274e..65f5ddd8 100644
--- a/src/managers/XWaylandManager.cpp
+++ b/src/managers/XWaylandManager.cpp
@@ -124,14 +124,8 @@ void CHyprXWaylandManager::sendCloseWindow(CWindow* pWindow) {
void CHyprXWaylandManager::setWindowSize(CWindow* pWindow, const Vector2D& size) {
if (pWindow->m_bIsX11)
wlr_xwayland_surface_configure(pWindow->m_uSurface.xwayland, pWindow->m_vRealPosition.vec().x, pWindow->m_vRealPosition.vec().y, size.x, size.y);
- else {
- // I don't know if this is fucking correct, but the fucking idea of putting shadows into a window's surface is borderline criminal.
-
- const auto XDELTA = pWindow->m_uSurface.xdg->current.geometry.width && pWindow->m_uSurface.xdg->current.geometry.height ? pWindow->m_uSurface.xdg->surface->current.width - pWindow->m_uSurface.xdg->current.geometry.width : 0;
- const auto YDELTA = pWindow->m_uSurface.xdg->current.geometry.width && pWindow->m_uSurface.xdg->current.geometry.height ? pWindow->m_uSurface.xdg->surface->current.height - pWindow->m_uSurface.xdg->current.geometry.height : 0;
-
- wlr_xdg_toplevel_set_size(pWindow->m_uSurface.xdg->toplevel, size.x - XDELTA, size.y - YDELTA);
- }
+ else
+ wlr_xdg_toplevel_set_size(pWindow->m_uSurface.xdg->toplevel, size.x, size.y);
}
void CHyprXWaylandManager::setWindowStyleTiled(CWindow* pWindow, uint32_t edgez) {
diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp
index 63e2d970..6bc59472 100644
--- a/src/managers/input/InputManager.cpp
+++ b/src/managers/input/InputManager.cpp
@@ -172,6 +172,14 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
Vector2D surfaceLocal = surfacePos == Vector2D(-1337, -1337) ? surfaceCoords : mouseCoords - surfacePos;
+ if (pFoundWindow && !pFoundWindow->m_bIsX11 && surfacePos != Vector2D(-1337, -1337)) {
+ // calc for oversized windows... fucking bullshit.
+ wlr_box geom;
+ wlr_xdg_surface_get_geometry(pFoundWindow->m_uSurface.xdg, &geom);
+
+ surfaceLocal = mouseCoords - surfacePos + Vector2D(geom.x, geom.y);
+ }
+
if (pFoundWindow) {
static auto *const PFOLLOWMOUSE = &g_pConfigManager->getConfigValuePtr("input:follow_mouse")->intValue;
if (*PFOLLOWMOUSE != 1 && !refocus) {
diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp
index d8f64e0c..c503cb64 100644
--- a/src/render/OpenGL.cpp
+++ b/src/render/OpenGL.cpp
@@ -303,15 +303,15 @@ void CHyprOpenGLImpl::renderTexture(wlr_texture* tex, wlr_box* pBox, float alpha
renderTexture(CTexture(tex), pBox, alpha, round);
}
-void CHyprOpenGLImpl::renderTexture(const CTexture& tex, wlr_box* pBox, float alpha, int round, bool discardopaque, bool border) {
+void CHyprOpenGLImpl::renderTexture(const CTexture& tex, wlr_box* pBox, float alpha, int round, bool discardopaque, bool border, bool allowPrimary) {
RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!");
- renderTextureInternalWithDamage(tex, pBox, alpha, m_RenderData.pDamage, round, discardopaque, border);
+ renderTextureInternalWithDamage(tex, pBox, alpha, m_RenderData.pDamage, round, discardopaque, border, false, allowPrimary);
scissor((wlr_box*)nullptr);
}
-void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_box* pBox, float alpha, pixman_region32_t* damage, int round, bool discardOpaque, bool border, bool noAA) {
+void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_box* pBox, float alpha, pixman_region32_t* damage, int round, bool discardOpaque, bool border, bool noAA, bool allowPrimary) {
RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!");
RASSERT((tex.m_iTexID > 0), "Attempted to draw NULL texture!");
@@ -358,6 +358,8 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_b
// hacky fix to fix broken borders.
// TODO: this is kinda slow... question mark?
renderRect(pBox, CColor(0, 0, 0, 0), round);
+
+ glDisable(GL_STENCIL_TEST);
}
glActiveTexture(GL_TEXTURE0);
@@ -388,7 +390,19 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_b
glUniform1i(glGetUniformLocation(shader->program, "primitiveMultisample"), (int)(*PMULTISAMPLEEDGES == 1 && round != 0 && !border && !noAA));
glVertexAttribPointer(shader->posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
- glVertexAttribPointer(shader->texAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
+
+ if (allowPrimary && m_RenderData.renderingPrimarySurface && m_RenderData.primarySurfaceUVTopLeft != Vector2D(-1, -1)) {
+ const float verts[] = {
+ m_RenderData.primarySurfaceUVBottomRight.x, m_RenderData.primarySurfaceUVTopLeft.y, // top right
+ m_RenderData.primarySurfaceUVTopLeft.x, m_RenderData.primarySurfaceUVTopLeft.y, // top left
+ m_RenderData.primarySurfaceUVBottomRight.x, m_RenderData.primarySurfaceUVBottomRight.y, // bottom right
+ m_RenderData.primarySurfaceUVTopLeft.x, m_RenderData.primarySurfaceUVBottomRight.y, // bottom left
+ };
+
+ glVertexAttribPointer(shader->texAttrib, 2, GL_FLOAT, GL_FALSE, 0, verts);
+ } else {
+ glVertexAttribPointer(shader->texAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
+ }
glEnableVertexAttribArray(shader->posAttrib);
glEnableVertexAttribArray(shader->texAttrib);
@@ -402,6 +416,8 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_b
}
if (border) {
+ glEnable(GL_STENCIL_TEST);
+
glStencilFunc(GL_EQUAL, 1, -1);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
}
@@ -548,9 +564,10 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, wlr_box* pBox,
RASSERT(m_RenderData.pMonitor, "Tried to render texture with blur without begin()!");
static auto *const PBLURENABLED = &g_pConfigManager->getConfigValuePtr("decoration:blur")->intValue;
+ static auto* const PNOBLUROVERSIZED = &g_pConfigManager->getConfigValuePtr("decoration:no_blur_on_oversized")->intValue;
- if (*PBLURENABLED == 0) {
- renderTexture(tex, pBox, a, round, false, border);
+ if (*PBLURENABLED == 0 || (*PNOBLUROVERSIZED && m_RenderData.primarySurfaceUVTopLeft != Vector2D(-1, -1))) {
+ renderTexture(tex, pBox, a, round, false, border, true);
return;
}
@@ -607,13 +624,18 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, wlr_box* pBox,
if (pixman_region32_not_empty(&damage)) {
// render our great blurred FB
static auto *const PBLURIGNOREOPACITY = &g_pConfigManager->getConfigValuePtr("decoration:blur_ignore_opacity")->intValue;
- renderTextureInternalWithDamage(POUTFB->m_cTex, &MONITORBOX, *PBLURIGNOREOPACITY ? 255.f : a, &damage);
+ renderTextureInternalWithDamage(POUTFB->m_cTex, &MONITORBOX, *PBLURIGNOREOPACITY ? 255.f : a, &damage, 0, false, false, false, true);
// render the window, but clear stencil
glClearStencil(0);
glClear(GL_STENCIL_BUFFER_BIT);
- // and write to it
+ // draw window
+ glDisable(GL_STENCIL_TEST);
+ renderTextureInternalWithDamage(tex, pBox, a, &damage, round, false, false, true, true);
+ glEnable(GL_STENCIL_TEST);
+
+ // prep stencil for border
glStencilFunc(GL_ALWAYS, 1, -1);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
@@ -623,8 +645,6 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, wlr_box* pBox,
renderRectWithDamage(pBox, CColor(0,0,0,0), &damage, round);
}
- renderTextureInternalWithDamage(tex, pBox, a, &damage, round, false, false, true);
-
// then stop
glStencilFunc(GL_EQUAL, 1, -1);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
diff --git a/src/render/OpenGL.hpp b/src/render/OpenGL.hpp
index 76de6311..0648e73a 100644
--- a/src/render/OpenGL.hpp
+++ b/src/render/OpenGL.hpp
@@ -34,6 +34,10 @@ struct SCurrentRenderData {
float projection[9];
pixman_region32_t* pDamage = nullptr;
+
+ bool renderingPrimarySurface = false;
+ Vector2D primarySurfaceUVTopLeft = Vector2D(-1, -1);
+ Vector2D primarySurfaceUVBottomRight = Vector2D(-1, -1);
};
struct SMonitorRenderData {
@@ -55,7 +59,7 @@ public:
void renderRect(wlr_box*, const CColor&, int round = 0);
void renderRectWithDamage(wlr_box*, const CColor&, pixman_region32_t* damage, int round = 0);
void renderTexture(wlr_texture*, wlr_box*, float a, int round = 0);
- void renderTexture(const CTexture&, wlr_box*, float a, int round = 0, bool discardOpaque = false, bool border = false);
+ void renderTexture(const CTexture&, wlr_box*, float a, int round = 0, bool discardOpaque = false, bool border = false, bool allowPrimary = false);
void renderTextureWithBlur(const CTexture&, wlr_box*, float a, wlr_surface* pSurface, int round = 0, bool border = false);
void makeWindowSnapshot(CWindow*);
@@ -111,7 +115,7 @@ private:
// returns the out FB, can be either Mirror or MirrorSwap
CFramebuffer* blurMainFramebufferWithDamage(float a, wlr_box* pBox, pixman_region32_t* damage);
- void renderTextureInternalWithDamage(const CTexture&, wlr_box* pBox, float a, pixman_region32_t* damage, int round = 0, bool discardOpaque = false, bool border = false, bool noAA = false);
+ void renderTextureInternalWithDamage(const CTexture&, wlr_box* pBox, float a, pixman_region32_t* damage, int round = 0, bool discardOpaque = false, bool border = false, bool noAA = false, bool allowPrimary = false);
void renderBorder(wlr_box*, const CColor&, int thick = 1, int round = 0);
};
diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp
index b760dac0..8118af48 100644
--- a/src/render/Renderer.cpp
+++ b/src/render/Renderer.cpp
@@ -23,8 +23,12 @@ void renderSurface(struct wlr_surface* surface, int x, int y, void* data) {
float rounding = RDATA->dontRound ? 0 : RDATA->rounding == -1 ? *PROUNDING : RDATA->rounding;
- if (RDATA->surface && surface == RDATA->surface)
+ g_pHyprOpenGL->m_RenderData.renderingPrimarySurface = false;
+
+ if (RDATA->surface && surface == RDATA->surface) {
+ g_pHyprOpenGL->m_RenderData.renderingPrimarySurface = true;
g_pHyprOpenGL->renderTextureWithBlur(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, surface, rounding, RDATA->decorate);
+ }
else
g_pHyprOpenGL->renderTexture(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, rounding, false, false);
@@ -166,8 +170,30 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, SMonitor* pMonitor, timespec*
for (auto& wd : pWindow->m_dWindowDecorations)
wd->draw(pMonitor);
+ if (!pWindow->m_bIsX11) {
+
+ // To everyone who makes apps with improperly aligned surfaces,
+ // For example chromium, or GTK devs who allow shadows on windows,
+ // a sincere FUCK YOU.
+
+ wlr_box geom;
+ wlr_xdg_surface_get_geometry(pWindow->m_uSurface.xdg, &geom);
+
+ g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D((double)geom.x / (double)pWindow->m_uSurface.xdg->surface->current.width, (double)geom.y / (double)pWindow->m_uSurface.xdg->surface->current.height);
+ g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D((double)(geom.width + geom.x) / (double)pWindow->m_uSurface.xdg->surface->current.width, (double)(geom.y + geom.height) / (double)pWindow->m_uSurface.xdg->surface->current.height);
+
+ if (g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft == Vector2D() && g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight == Vector2D(1, 1)) {
+ // No special UV mods needed
+ g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(-1, -1);
+ g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D(-1, -1);
+ }
+ }
+
wlr_surface_for_each_surface(g_pXWaylandManager->getWindowSurface(pWindow), renderSurface, &renderdata);
+ g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(-1, -1);
+ g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D(-1, -1);
+
if (pWindow->m_bIsX11) {
if (pWindow->m_uSurface.xwayland->surface) {
wlr_surface_for_each_surface(pWindow->m_uSurface.xwayland->surface, renderSurface, &renderdata);