diff --git a/hyprlandd.conf b/hyprlandd.conf index c26ce95..f9172a0 100644 --- a/hyprlandd.conf +++ b/hyprlandd.conf @@ -1,7 +1,11 @@ monitor=,preferred,auto,auto -# exec_once=kitty --hold sh -c "hyprctl plugin load $(pwd)/build/src/libhyprwiggle.so" +# TODO: does not work!! +exec-once=sh -c "hyprctl plugin load $(pwd)/build/src/libhyprwiggle.so" +debug { + disable_logs = false +} general { gaps_in = 5 gaps_out = 20 diff --git a/src/main.cpp b/src/main.cpp index b3f21ec..53c49a1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,20 +1,132 @@ +#include "src/helpers/math/Math.hpp" +#include #define WLR_USE_UNSTABLE #include "globals.hpp" // version.hpp will be generated by meson #include "version.hpp" -// #include #include +#include +#include +#include #include -#include // Do NOT change this function. APICALL EXPORT std::string PLUGIN_API_VERSION() { return HYPRLAND_API_VERSION; } +class CWindowTransformer : public IWindowTransformer { + public: + virtual CFramebuffer* transform(CFramebuffer* in); + virtual void preWindowRender(CSurfacePassElement::SRenderData* pRenderData); + + private: + float rot = 0; +}; + +std::vector ptrs; +Vector2D oldPos, newPos; + +void renderTex(CBox monbox, CTexture& tex, float rot) { + if (g_pHyprOpenGL->m_renderData.damage.empty()) return; + + CBox newBox = monbox.scale(g_pHyprOpenGL->m_renderData.renderModif.combinedScale()); + g_pHyprOpenGL->m_renderData.renderModif.applyToBox(newBox); + + Mat3x3 matrix = g_pHyprOpenGL->m_renderData.monitorProjection.projectBox(monbox, wlTransformToHyprutils(invertTransform(WL_OUTPUT_TRANSFORM_NORMAL)), monbox.rot); + Mat3x3 glMatrix = g_pHyprOpenGL->m_renderData.projection.copy().multiply(matrix); + + SShader* shader = &g_pHyprOpenGL->m_shaders->m_shPASSTHRURGBA; + + glActiveTexture(GL_TEXTURE0); + glBindTexture(tex.m_target, tex.m_texID); + + glUseProgram(shader->program); + +#ifndef GLES2 + glUniformMatrix3fv(shader->proj, 1, GL_TRUE, glMatrix.getMatrix().data()); +#else + glMatrix.transpose(); + glUniformMatrix3fv(shader->proj, 1, GL_FALSE, glMatrix.getMatrix().data()); +#endif + glUniform1i(shader->tex, 0); + + const auto TOPLEFT = Vector2D(newBox.x, newBox.y); + const auto FULLSIZE = Vector2D(newBox.width, newBox.height); + + glUniform2f(shader->topLeft, TOPLEFT.x, TOPLEFT.y); + glUniform2f(shader->fullSize, FULLSIZE.x, FULLSIZE.y); + glUniform1f(shader->radius, 0); + + glUniform1i(shader->discardOpaque, 0); + glUniform1i(shader->discardAlpha, 0); + + glUniform1f(shader->alpha, 1); + + glVertexAttribPointer(shader->posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts); + glVertexAttribPointer(shader->texAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts); + + glEnableVertexAttribArray(shader->posAttrib); + glEnableVertexAttribArray(shader->texAttrib); + + for (auto& RECT : g_pHyprOpenGL->m_renderData.damage.getRects()) { + g_pHyprOpenGL->scissor(&RECT); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + } + + g_pHyprOpenGL->scissor(nullptr); + + glDisableVertexAttribArray(shader->posAttrib); + glDisableVertexAttribArray(shader->texAttrib); + + glBindTexture(tex.m_target, 0); +} + +void CWindowTransformer::preWindowRender(CSurfacePassElement::SRenderData* pRenderData) { + oldPos = pRenderData->pos; + + pRenderData->pos.x = pRenderData->pMonitor->m_size.x / 2.f - pRenderData->w / 2.f; + pRenderData->pos.y = pRenderData->pMonitor->m_size.y / 2.f - pRenderData->h / 2.f; + + newPos = {(double)pRenderData->pos.x, (double)pRenderData->pos.y}; +} + +CFramebuffer* CWindowTransformer::transform(CFramebuffer* in) { + static CFramebuffer off; + + if (!off.isAllocated() || off.m_size != in->m_size) { + off.release(); + off.alloc(in->m_size.x, in->m_size.y); + } + + off.bind(); + g_pHyprOpenGL->clear(CHyprColor{0,0,0,0}); + + CBox monbox = {oldPos.x - newPos.x, oldPos.y - newPos.y, g_pHyprOpenGL->m_renderData.pMonitor->m_transformedSize.x, + g_pHyprOpenGL->m_renderData.pMonitor->m_transformedSize.y}; + + renderTex(monbox, *in->getTexture(), rot); + + rot += 0.01; + + return &off; +} + +void onNewWindow(void* self, std::any data) { + // data is guaranteed + auto* const PWINDOW = std::any_cast(data); + + ptrs.push_back(static_cast(PWINDOW->m_transformers.emplace_back(new CWindowTransformer{}).get())); + + HyprlandAPI::addNotification(PHANDLE, "onnewwindow", CHyprColor{0.f, 1.f, 1.f, 1.f}, 5000); + std::println("onnewwindow"); + throw "up"; +} + + APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) { PHANDLE = handle; @@ -28,13 +140,16 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) { throw std::runtime_error("[WiggleWobble] Version mismatch"); } - HyprlandAPI::addNotification(PHANDLE, "WiggleWobble loaded!", CHyprColor{0.f, 1.f, 1.f, 1.f}, 5000); + + static auto P = HyprlandAPI::registerCallbackDynamic(PHANDLE, "openWindow", [&](void* self, SCallbackInfo& info, std::any data) { onNewWindow(self, data); }); HyprlandAPI::reloadConfig(); + HyprlandAPI::addNotification(PHANDLE, "[WiggleWobble] Successfully loaded!", CHyprColor{0.f, 1.f, 1.f, 1.f}, 5000); + return {"wigglewobble", "Wobbly windows for Hyprland", "All-Purpose Mat", PLUGIN_VERSION}; } APICALL EXPORT void PLUGIN_EXIT() { - HyprlandAPI::invokeHyprctlCommand("seterror", "disable"); + throw "down"; }