hyprtrails: fix for hyprland@#3755

This commit is contained in:
Vaxry 2023-11-04 17:28:57 +00:00
parent 18107f141b
commit 793c779002
2 changed files with 92 additions and 73 deletions

View File

@ -12,10 +12,11 @@ void CTrail::onTick() {
m_iTimer++;
if (m_iTimer > *PHISTORYSTEP) {
m_dLastGeoms.push_front({box{(float)m_pWindow->m_vRealPosition.vec().x, (float)m_pWindow->m_vRealPosition.vec().y,
(float)m_pWindow->m_vRealSize.vec().x, (float)m_pWindow->m_vRealSize.vec().y},
m_dLastGeoms.push_front({box{(float)m_pWindow->m_vRealPosition.vec().x, (float)m_pWindow->m_vRealPosition.vec().y, (float)m_pWindow->m_vRealSize.vec().x,
(float)m_pWindow->m_vRealSize.vec().y},
std::chrono::system_clock::now()});
while (m_dLastGeoms.size() > *PHISTORYPOINTS) m_dLastGeoms.pop_back();
while (m_dLastGeoms.size() > *PHISTORYPOINTS)
m_dLastGeoms.pop_back();
m_iTimer = 0;
}
@ -38,9 +39,13 @@ CTrail::~CTrail() {
g_pHookSystem->unhook(pTickCb);
}
SWindowDecorationExtents CTrail::getWindowDecorationExtents() { return m_seExtents; }
SWindowDecorationExtents CTrail::getWindowDecorationExtents() {
return m_seExtents;
}
SWindowDecorationExtents CTrail::getWindowDecorationReservedArea() { return m_seExtents; }
SWindowDecorationExtents CTrail::getWindowDecorationReservedArea() {
return m_seExtents;
}
void scaleBox2(box& box, float coeff) {
float hwl = (box.w - (box.w * coeff)) / 2.0;
@ -72,9 +77,11 @@ Vector2D vecForBezierT(const float& t, const std::vector<Vector2D>& verts) {
}
void CTrail::draw(CMonitor* pMonitor, float a, const Vector2D& offset) {
if (!g_pCompositor->windowValidMapped(m_pWindow)) return;
if (!g_pCompositor->windowValidMapped(m_pWindow))
return;
if (!m_pWindow->m_sSpecialRenderData.decorate) return;
if (!m_pWindow->m_sSpecialRenderData.decorate)
return;
static auto* const PBEZIERSTEP = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprtrails:bezier_step")->floatValue;
static auto* const PPOINTSPERSTEP = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprtrails:points_per_step")->intValue;
@ -82,13 +89,14 @@ void CTrail::draw(CMonitor* pMonitor, float a, const Vector2D& offset) {
const CColor COLOR = *PCOLOR;
if (m_dLastGeoms.size() < 2) return;
if (m_dLastGeoms.size() < 2)
return;
box thisbox = box{(float)m_pWindow->m_vRealPosition.vec().x, (float)m_pWindow->m_vRealPosition.vec().y, (float)m_pWindow->m_vRealSize.vec().x,
(float)m_pWindow->m_vRealSize.vec().y};
wlr_box wlrbox = {thisbox.x - pMonitor->vecPosition.x, thisbox.y - pMonitor->vecPosition.y, thisbox.w, thisbox.h};
box thisbox =
box{(float)m_pWindow->m_vRealPosition.vec().x, (float)m_pWindow->m_vRealPosition.vec().y, (float)m_pWindow->m_vRealSize.vec().x, (float)m_pWindow->m_vRealSize.vec().y};
CBox wlrbox = {thisbox.x - pMonitor->vecPosition.x, thisbox.y - pMonitor->vecPosition.y, thisbox.w, thisbox.h};
g_pHyprOpenGL->scissor((wlr_box*)nullptr); // allow the entire window and stencil to render
g_pHyprOpenGL->scissor((CBox*)nullptr); // allow the entire window and stencil to render
glClearStencil(0);
glClear(GL_STENCIL_BUFFER_BIT);
@ -104,10 +112,10 @@ void CTrail::draw(CMonitor* pMonitor, float a, const Vector2D& offset) {
glStencilFunc(GL_NOTEQUAL, 1, -1);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
wlr_box monbox = {0, 0, g_pHyprOpenGL->m_RenderData.pMonitor->vecPixelSize.x, g_pHyprOpenGL->m_RenderData.pMonitor->vecPixelSize.y};
CBox monbox = {0, 0, g_pHyprOpenGL->m_RenderData.pMonitor->vecPixelSize.x, g_pHyprOpenGL->m_RenderData.pMonitor->vecPixelSize.y};
float matrix[9];
wlr_matrix_project_box(matrix, &monbox, wlr_output_transform_invert(WL_OUTPUT_TRANSFORM_NORMAL), 0,
wlr_matrix_project_box(matrix, monbox.pWlr(), wlr_output_transform_invert(WL_OUTPUT_TRANSFORM_NORMAL), 0,
g_pHyprOpenGL->m_RenderData.pMonitor->output->transform_matrix); // TODO: write own, don't use WLR here
float glMatrix[9];
@ -165,7 +173,8 @@ void CTrail::draw(CMonitor* pMonitor, float a, const Vector2D& offset) {
box.y -= pMonitor->vecPosition.y;
Vector2D middle = {box.x + box.w / 2.0, box.y + box.h / 2.0};
if (middle == pointsForBezier[pointsForBezier.size() - 1]) continue;
if (middle == pointsForBezier[pointsForBezier.size() - 1])
continue;
pointsForBezier.push_back(middle);
agesForBezier.push_back(msFrom(m_dLastGeoms[i].second));
@ -178,7 +187,7 @@ void CTrail::draw(CMonitor* pMonitor, float a, const Vector2D& offset) {
glStencilMask(-1);
glStencilFunc(GL_ALWAYS, 1, 0xFF);
g_pHyprOpenGL->scissor((wlr_box*)nullptr);
g_pHyprOpenGL->scissor((CBox*)nullptr);
return;
}
@ -211,12 +220,13 @@ void CTrail::draw(CMonitor* pMonitor, float a, const Vector2D& offset) {
float ageCoeff = t * (agesForBezier.size() - 1);
float ageFloor = std::floor(ageCoeff);
float ageCeil = std::ceil(ageCoeff);
float approxAge = agesForBezier[static_cast<int>(ageFloor)] +
(agesForBezier[static_cast<int>(ageCeil)] - agesForBezier[static_cast<int>(ageFloor)]) * (ageCoeff - ageFloor);
float approxAge =
agesForBezier[static_cast<int>(ageFloor)] + (agesForBezier[static_cast<int>(ageCeil)] - agesForBezier[static_cast<int>(ageFloor)]) * (ageCoeff - ageFloor);
float coeff = originalCoeff * (1.0 - (approxAge / maxAge));
Vector2D newVec = {vecNormal.x * coeff / pMonitor->vecSize.x, vecNormal.y * coeff / pMonitor->vecSize.y};
if ((newVec.x == 0 && newVec.y == 0) || std::isnan(newVec.x) || std::isnan(newVec.y)) continue;
if ((newVec.x == 0 && newVec.y == 0) || std::isnan(newVec.x) || std::isnan(newVec.y))
continue;
// rotate by 90 and -90 and add middle
points.push_back(Vector2D{cos(M_PI_2) * newVec.x - sin(M_PI_2) * newVec.y + middle.x / pMonitor->vecPixelSize.x,
@ -233,9 +243,9 @@ void CTrail::draw(CMonitor* pMonitor, float a, const Vector2D& offset) {
glUniform4f(g_pGlobalState->trailShader.gradient, thisboxopengl.x, thisboxopengl.y, thisboxopengl.w, thisboxopengl.h);
glUniform4f(g_pGlobalState->trailShader.color, COLOR.r, COLOR.g, COLOR.b, COLOR.a);
wlr_box transformedBox;
wlr_box_transform(&transformedBox, &monbox, wlr_output_transform_invert(g_pHyprOpenGL->m_RenderData.pMonitor->transform),
g_pHyprOpenGL->m_RenderData.pMonitor->vecTransformedSize.x, g_pHyprOpenGL->m_RenderData.pMonitor->vecTransformedSize.y);
CBox transformedBox = monbox;
transformedBox.transform(wlr_output_transform_invert(g_pHyprOpenGL->m_RenderData.pMonitor->transform), g_pHyprOpenGL->m_RenderData.pMonitor->vecTransformedSize.x,
g_pHyprOpenGL->m_RenderData.pMonitor->vecTransformedSize.y);
glVertexAttribPointer(g_pGlobalState->trailShader.posAttrib, 2, GL_FLOAT, GL_FALSE, 0, (float*)points.data());
@ -267,7 +277,7 @@ void CTrail::draw(CMonitor* pMonitor, float a, const Vector2D& offset) {
glStencilMask(-1);
glStencilFunc(GL_ALWAYS, 1, 0xFF);
g_pHyprOpenGL->scissor((wlr_box*)nullptr);
g_pHyprOpenGL->scissor((CBox*)nullptr);
// calculate damage
float minX = 9999999;
@ -276,10 +286,14 @@ void CTrail::draw(CMonitor* pMonitor, float a, const Vector2D& offset) {
float maxY = -9999999;
for (auto& p : points) {
if (p.x < minX) minX = p.x;
if (p.y < minY) minY = p.y;
if (p.x > maxX) maxX = p.x;
if (p.y > maxY) maxY = p.y;
if (p.x < minX)
minX = p.x;
if (p.y < minY)
minY = p.y;
if (p.x > maxX)
maxX = p.x;
if (p.y > maxY)
maxY = p.y;
}
// bring back to global coords
@ -296,7 +310,9 @@ void CTrail::draw(CMonitor* pMonitor, float a, const Vector2D& offset) {
m_bNeedsDamage = true;
}
eDecorationType CTrail::getDecorationType() { return DECORATION_CUSTOM; }
eDecorationType CTrail::getDecorationType() {
return DECORATION_CUSTOM;
}
void CTrail::updateWindow(CWindow* pWindow) {
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID);
@ -310,7 +326,7 @@ void CTrail::updateWindow(CWindow* pWindow) {
}
void CTrail::damageEntire() {
wlr_box dm = {(int)(m_vLastWindowPos.x - m_seExtents.topLeft.x), (int)(m_vLastWindowPos.y - m_seExtents.topLeft.y),
CBox dm = {(int)(m_vLastWindowPos.x - m_seExtents.topLeft.x), (int)(m_vLastWindowPos.y - m_seExtents.topLeft.y),
(int)(m_vLastWindowSize.x + m_seExtents.topLeft.x + m_seExtents.bottomRight.x), (int)m_seExtents.topLeft.y};
g_pHyprRenderer->damageBox(&dm);
}

View File

@ -9,7 +9,10 @@
struct box {
float x = 0, y = 0, w = 0, h = 0;
Vector2D middle() { return Vector2D{x + w / 2.0, y + h / 2.0}; }
//
Vector2D middle() {
return Vector2D{x + w / 2.0, y + h / 2.0};
}
};
struct point2 {
point2(const Vector2D& v) {
@ -57,6 +60,6 @@ class CTrail : public IHyprWindowDecoration {
Vector2D m_vLastWindowPos;
Vector2D m_vLastWindowSize;
wlr_box m_bLastBox = {0};
CBox m_bLastBox = {0};
bool m_bNeedsDamage = false;
};