diff --git a/hyprexpo/OverviewPassElement.hpp b/hyprexpo/OverviewPassElement.hpp index 428b257..61da4bd 100644 --- a/hyprexpo/OverviewPassElement.hpp +++ b/hyprexpo/OverviewPassElement.hpp @@ -8,17 +8,16 @@ class COverviewPassElement : public IPassElement { COverviewPassElement(); virtual ~COverviewPassElement() = default; - virtual std::vector> draw() override; - virtual bool needsLiveBlur() override; - virtual bool needsPrecomputeBlur() override; - virtual std::optional boundingBox() override; - virtual CRegion opaqueRegion() override; - - virtual const char* passName() override { - return "COverviewPassElement"; - } - - virtual ePassElementType type() override { + virtual void draw(const CRegion& damage); + virtual bool needsLiveBlur(); + virtual bool needsPrecomputeBlur(); + virtual std::optional boundingBox(); + virtual CRegion opaqueRegion(); + virtual ePassElementType type() { return EK_CUSTOM; } + + virtual const char* passName() { + return "COverviewPassElement"; + } }; diff --git a/hyprexpo/README.md b/hyprexpo/README.md index 97bd1d4..09267df 100644 --- a/hyprexpo/README.md +++ b/hyprexpo/README.md @@ -57,4 +57,3 @@ off | hides the overview disable | same as `off` on | displays the overview enable | same as `on` - diff --git a/hyprexpo/main.cpp b/hyprexpo/main.cpp index 3b3dff1..32c1c02 100644 --- a/hyprexpo/main.cpp +++ b/hyprexpo/main.cpp @@ -6,12 +6,18 @@ #include #include #include +#include +#include +#include +#include #include +#include #include #include #include #include +#include #include using namespace Hyprutils::String; @@ -23,7 +29,7 @@ using namespace Hyprutils::String; inline CFunctionHook* g_pRenderWorkspaceHook = nullptr; inline CFunctionHook* g_pAddDamageHookA = nullptr; inline CFunctionHook* g_pAddDamageHookB = nullptr; -typedef void (*origRenderWorkspace)(void*, PHLMONITOR, PHLWORKSPACE, timespec*, const CBox&); +typedef void (*origRenderWorkspace)(void*, PHLMONITOR, PHLWORKSPACE, const Time::steady_tp&, const CBox&); typedef void (*origAddDamageA)(void*, const CBox&); typedef void (*origAddDamageB)(void*, const pixman_region32_t*); @@ -39,7 +45,7 @@ static bool renderingOverview = false; const std::string KEYWORD_EXPO_GESTURE = "hyprexpo-gesture"; // -static void hkRenderWorkspace(void* thisptr, PHLMONITOR pMonitor, PHLWORKSPACE pWorkspace, timespec* now, const CBox& geometry) { +static void hkRenderWorkspace(void* thisptr, PHLMONITOR pMonitor, PHLWORKSPACE pWorkspace, const Time::steady_tp& now, const CBox& geometry) { if (!g_pOverview || renderingOverview || g_pOverview->blockOverviewRendering || g_pOverview->pMonitor != pMonitor) ((origRenderWorkspace)(g_pRenderWorkspaceHook->m_original))(thisptr, pMonitor, pWorkspace, now, geometry); else @@ -106,6 +112,13 @@ static SDispatchResult onExpoDispatcher(std::string arg) { return {}; } +static int luaExpo(lua_State* L) { + const auto RESULT = onExpoDispatcher(luaL_optstring(L, 1, "toggle")); + if (!RESULT.success) + return luaL_error(L, "%s", RESULT.error.c_str()); + return 0; +} + static void failNotif(const std::string& reason) { HyprlandAPI::addNotification(PHANDLE, "[hyprexpo] Failure in initialization: " + reason, CHyprColor{1.0, 0.2, 0.2, 1.0}, 5000); } @@ -242,16 +255,16 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) { }); HyprlandAPI::addDispatcherV2(PHANDLE, "hyprexpo:expo", ::onExpoDispatcher); + HyprlandAPI::addLuaFunction(PHANDLE, "hyprexpo", "expo", ::luaExpo); HyprlandAPI::addConfigKeyword(PHANDLE, KEYWORD_EXPO_GESTURE, ::expoGestureKeyword, {true}); - HyprlandAPI::addConfigValue(PHANDLE, "plugin:hyprexpo:columns", Hyprlang::INT{3}); - HyprlandAPI::addConfigValue(PHANDLE, "plugin:hyprexpo:gap_size", Hyprlang::INT{5}); - HyprlandAPI::addConfigValue(PHANDLE, "plugin:hyprexpo:bg_col", Hyprlang::INT{0xFF111111}); - HyprlandAPI::addConfigValue(PHANDLE, "plugin:hyprexpo:workspace_method", Hyprlang::STRING{"center current"}); - HyprlandAPI::addConfigValue(PHANDLE, "plugin:hyprexpo:skip_empty", Hyprlang::INT{0}); - - HyprlandAPI::addConfigValue(PHANDLE, "plugin:hyprexpo:gesture_distance", Hyprlang::INT{200}); + HyprlandAPI::addConfigValueV2(PHANDLE, makeShared("plugin:hyprexpo:columns", "columns", 3)); + HyprlandAPI::addConfigValueV2(PHANDLE, makeShared("plugin:hyprexpo:gap_size", "gap size", 5)); + HyprlandAPI::addConfigValueV2(PHANDLE, makeShared("plugin:hyprexpo:bg_col", "background color", 0xFF111111)); + HyprlandAPI::addConfigValueV2(PHANDLE, makeShared("plugin:hyprexpo:workspace_method", "workspace method", "center current")); + HyprlandAPI::addConfigValueV2(PHANDLE, makeShared("plugin:hyprexpo:skip_empty", "skip empty workspaces", 0)); + HyprlandAPI::addConfigValueV2(PHANDLE, makeShared("plugin:hyprexpo:gesture_distance", "gesture distance", 200)); HyprlandAPI::reloadConfig(); diff --git a/hyprexpo/overview.cpp b/hyprexpo/overview.cpp index 26c7162..f21a81e 100644 --- a/hyprexpo/overview.cpp +++ b/hyprexpo/overview.cpp @@ -1,63 +1,80 @@ +#include "overview.hpp" +#include #include -#include +#define private public #define protected public #include -#undef protected -#include "overview.hpp" -#include -#include -#include -#include -#include #include #include #include #include +#include +#include #include #include #include #include #include #include +#include +#include +#undef private +#undef protected #include "OverviewPassElement.hpp" using namespace Hyprutils::String; -using namespace Render; -using namespace Render::GL; + +static const CConfigValue PCOLUMNS("plugin:hyprexpo:columns"); +static const CConfigValue PGAPS("plugin:hyprexpo:gap_size"); +static const CConfigValue PCOL("plugin:hyprexpo:bg_col"); +static const CConfigValue PSKIP("plugin:hyprexpo:skip_empty"); +static const CConfigValue PMETHOD("plugin:hyprexpo:workspace_method"); +static const CConfigValue PDISTANCE("plugin:hyprexpo:gesture_distance"); + +static void clearWithColor(const CHyprColor& color) { + glClearColor(color.r, color.g, color.b, color.a); + glClear(GL_COLOR_BUFFER_BIT); +} + +static void ensureFramebuffer(COverview::SWorkspaceImage& image, const CBox& monbox, uint32_t drmFormat) { + if (!image.fb) + image.fb = g_pHyprRenderer->createFB("hyprexpo"); + + if (image.fb->m_size != monbox.size()) { + image.fb->release(); + image.fb->alloc(monbox.w, monbox.h, drmFormat); + } +} static void damageMonitor(WP thisptr) { g_pOverview->damage(); } COverview::~COverview() { + Render::GL::g_pHyprOpenGL->makeEGLCurrent(); images.clear(); // otherwise we get a vram leak Cursor::overrideController->unsetOverride(Cursor::CURSOR_OVERRIDE_UNKNOWN); - g_pHyprRenderer->damageMonitor(pMonitor.lock()); + if (pMonitor) + pMonitor->m_blurFBDirty = true; } COverview::COverview(PHLWORKSPACE startedOn_, bool swipe_) : startedOn(startedOn_), swipe(swipe_) { const auto PMONITOR = Desktop::focusState()->monitor(); pMonitor = PMONITOR; - static auto* const* PCOLUMNS = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprexpo:columns")->getDataStaticPtr(); - static auto* const* PGAPS = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprexpo:gap_size")->getDataStaticPtr(); - static auto* const* PCOL = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprexpo:bg_col")->getDataStaticPtr(); - static auto* const* PSKIP = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprexpo:skip_empty")->getDataStaticPtr(); - static auto const* PMETHOD = (Hyprlang::STRING const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprexpo:workspace_method")->getDataStaticPtr(); - - SIDE_LENGTH = **PCOLUMNS; - GAP_WIDTH = **PGAPS; - BG_COLOR = **PCOL; + SIDE_LENGTH = *PCOLUMNS; + GAP_WIDTH = *PGAPS; + BG_COLOR = CHyprColor(*PCOL); // process the method bool methodCenter = true; int methodStartID = pMonitor->activeWorkspaceID(); - CConstVarList method{*PMETHOD, 0, 's', true}; + CVarList method{*PMETHOD, 0, 's', true}; if (method.size() < 2) Log::logger->log(Log::ERR, "[he] invalid workspace_method"); else { methodCenter = method[0] == "center"; - methodStartID = getWorkspaceIDNameFromString(std::string{method[1]}).id; + methodStartID = getWorkspaceIDNameFromString(method[1]).id; if (methodStartID == WORKSPACE_INVALID) methodStartID = pMonitor->activeWorkspaceID(); } @@ -65,7 +82,7 @@ COverview::COverview(PHLWORKSPACE startedOn_, bool swipe_) : startedOn(startedOn images.resize(SIDE_LENGTH * SIDE_LENGTH); // r includes empty workspaces; m skips over them - std::string selector = **PSKIP ? "m" : "r"; + std::string selector = *PSKIP ? "m" : "r"; if (methodCenter) { int currentID = methodStartID; @@ -129,6 +146,8 @@ COverview::COverview(PHLWORKSPACE startedOn_, bool swipe_) : startedOn(startedOn pMonitor->m_activeWorkspace = startedOn; } + Render::GL::g_pHyprOpenGL->makeEGLCurrent(); + Vector2D tileSize = pMonitor->m_size / SIDE_LENGTH; Vector2D tileRenderSize = (pMonitor->m_size - Vector2D{GAP_WIDTH * pMonitor->m_scale, GAP_WIDTH * pMonitor->m_scale} * (SIDE_LENGTH - 1)) / SIDE_LENGTH; CBox monbox{0, 0, tileSize.x * 2, tileSize.y * 2}; @@ -148,13 +167,12 @@ COverview::COverview(PHLWORKSPACE startedOn_, bool swipe_) : startedOn(startedOn for (size_t i = 0; i < (size_t)(SIDE_LENGTH * SIDE_LENGTH); ++i) { COverview::SWorkspaceImage& image = images[i]; - image.fb = makeShared(); - image.fb->alloc(monbox.w, monbox.h, PMONITOR->m_output->state->state().drmFormat); + ensureFramebuffer(image, monbox, PMONITOR->m_output->state->state().drmFormat); CRegion fakeDamage{0, 0, INT16_MAX, INT16_MAX}; - g_pHyprRenderer->beginRender(PMONITOR, fakeDamage, RENDER_MODE_FULL_FAKE, nullptr, image.fb); + g_pHyprRenderer->beginRender(PMONITOR, fakeDamage, Render::RENDER_MODE_FULL_FAKE, nullptr, image.fb); - g_pHyprRenderer->draw(CClearPassElement::SClearData{CHyprColor{0, 0, 0, 1.0}}); + clearWithColor(CHyprColor{0, 0, 0, 1.0}); const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(image.workspaceID); @@ -265,6 +283,8 @@ void COverview::redrawID(int id, bool forcelowres) { blockOverviewRendering = true; + Render::GL::g_pHyprOpenGL->makeEGLCurrent(); + id = std::clamp(id, 0, SIDE_LENGTH * SIDE_LENGTH); Vector2D tileSize = pMonitor->m_size / SIDE_LENGTH; @@ -279,16 +299,12 @@ void COverview::redrawID(int id, bool forcelowres) { auto& image = images[id]; - if (image.fb->m_size != monbox.size()) { - image.fb->release(); - image.fb = makeShared(); - image.fb->alloc(monbox.w, monbox.h, pMonitor->m_output->state->state().drmFormat); - } + ensureFramebuffer(image, monbox, pMonitor->m_output->state->state().drmFormat); CRegion fakeDamage{0, 0, INT16_MAX, INT16_MAX}; - g_pHyprRenderer->beginRender(pMonitor.lock(), fakeDamage, RENDER_MODE_FULL_FAKE, nullptr, image.fb); + g_pHyprRenderer->beginRender(pMonitor.lock(), fakeDamage, Render::RENDER_MODE_FULL_FAKE, nullptr, image.fb); - g_pHyprRenderer->draw(CClearPassElement::SClearData{CHyprColor{0, 0, 0, 1.0}}); + clearWithColor(CHyprColor{0, 0, 0, 1.0}); const auto PWORKSPACE = image.pWorkspace; @@ -450,7 +466,7 @@ void COverview::fullRender() { Vector2D tileSize = (SIZE / SIDE_LENGTH); Vector2D tileRenderSize = (SIZE - Vector2D{GAPSIZE, GAPSIZE} * (SIDE_LENGTH - 1)) / SIDE_LENGTH; - g_pHyprRenderer->draw(CClearPassElement::SClearData{BG_COLOR.stripA()}); + clearWithColor(BG_COLOR.stripA()); for (size_t y = 0; y < (size_t)SIDE_LENGTH; ++y) { for (size_t x = 0; x < (size_t)SIDE_LENGTH; ++x) { @@ -458,7 +474,7 @@ void COverview::fullRender() { texbox.scale(pMonitor->m_scale).translate(pos->value()); texbox.round(); CRegion damage{0, 0, INT16_MAX, INT16_MAX}; - g_pHyprOpenGL->renderTexture(images[x + y * SIDE_LENGTH].fb->getTexture(), texbox, {.damage = &damage, .a = 1.0}); + Render::GL::g_pHyprOpenGL->renderTextureInternal(images[x + y * SIDE_LENGTH].fb->getTexture(), texbox, {.damage = &damage, .a = 1.0}); } } } @@ -482,15 +498,13 @@ void COverview::resetSwipe() { void COverview::onSwipeUpdate(double delta) { m_isSwiping = true; - static auto* const* PDISTANCE = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprexpo:gesture_distance")->getDataStaticPtr(); + const float PERC = closing ? std::clamp(delta / (double)*PDISTANCE, 0.0, 1.0) : 1.0 - std::clamp(delta / (double)*PDISTANCE, 0.0, 1.0); + const auto WORKSPACE_FOCUS_ID = closing && closeOnID != -1 ? closeOnID : openedID; - const float PERC = closing ? std::clamp(delta / (double)**PDISTANCE, 0.0, 1.0) : 1.0 - std::clamp(delta / (double)**PDISTANCE, 0.0, 1.0); - const auto WORKSPACE_FOCUS_ID = closing && closeOnID != -1 ? closeOnID : openedID; + Vector2D tileSize = (pMonitor->m_size / SIDE_LENGTH); - Vector2D tileSize = (pMonitor->m_size / SIDE_LENGTH); - - const auto SIZEMAX = pMonitor->m_size * pMonitor->m_size / tileSize; - const auto POSMAX = (-((pMonitor->m_size / (double)SIDE_LENGTH) * Vector2D{WORKSPACE_FOCUS_ID % SIDE_LENGTH, WORKSPACE_FOCUS_ID / SIDE_LENGTH}) * pMonitor->m_scale) * + const auto SIZEMAX = pMonitor->m_size * pMonitor->m_size / tileSize; + const auto POSMAX = (-((pMonitor->m_size / (double)SIDE_LENGTH) * Vector2D{WORKSPACE_FOCUS_ID % SIDE_LENGTH, WORKSPACE_FOCUS_ID / SIDE_LENGTH}) * pMonitor->m_scale) * (pMonitor->m_size / tileSize); const auto SIZEMIN = pMonitor->m_size; diff --git a/hyprexpo/overview.hpp b/hyprexpo/overview.hpp index 7ecc64f..799df0b 100644 --- a/hyprexpo/overview.hpp +++ b/hyprexpo/overview.hpp @@ -4,17 +4,11 @@ #include "globals.hpp" #include -#include +#include #include #include #include -using namespace Hyprutils::Memory; - -namespace Render { - class IFramebuffer; -} - // saves on resources, but is a bit broken rn with blur. // hyprland's fault, but cba to fix. constexpr bool ENABLE_LOWRES = false; @@ -47,25 +41,25 @@ class COverview { PHLMONITORREF pMonitor; bool m_isSwiping = false; - private: - void redrawID(int id, bool forcelowres = false); - void redrawAll(bool forcelowres = false); - void onWorkspaceChange(); - void fullRender(); - - int SIDE_LENGTH = 3; - int GAP_WIDTH = 5; - CHyprColor BG_COLOR = CHyprColor{0.1, 0.1, 0.1, 1.0}; - - bool damageDirty = false; - struct SWorkspaceImage { SP fb; - int64_t workspaceID = -1; - PHLWORKSPACE pWorkspace; - CBox box; + int64_t workspaceID = -1; + PHLWORKSPACE pWorkspace; + CBox box; }; + private: + void redrawID(int id, bool forcelowres = false); + void redrawAll(bool forcelowres = false); + void onWorkspaceChange(); + void fullRender(); + + int SIDE_LENGTH = 3; + int GAP_WIDTH = 5; + CHyprColor BG_COLOR = CHyprColor{0.1, 0.1, 0.1, 1.0}; + + bool damageDirty = false; + Vector2D lastMousePosLocal = Vector2D{}; int openedID = -1;