From 477fb57c48588647979a7e40267a520dae5646bc Mon Sep 17 00:00:00 2001 From: Vaxry Date: Wed, 3 Apr 2024 21:11:05 +0100 Subject: [PATCH] expo: add gesture support --- hyprexpo/README.md | 3 ++ hyprexpo/main.cpp | 65 +++++++++++++++++++------------------------ hyprexpo/overview.cpp | 15 +++++++--- hyprexpo/overview.hpp | 3 +- 4 files changed, 45 insertions(+), 41 deletions(-) diff --git a/hyprexpo/README.md b/hyprexpo/README.md index 12a3929..7723724 100644 --- a/hyprexpo/README.md +++ b/hyprexpo/README.md @@ -12,7 +12,10 @@ plugin { gap_size = 5 bg_col = rgb(111111) workspace_method = center current # [center/first] [workspace] e.g. first 1 or center m+1 + enable_gesture = true # laptop touchpad, 4 fingers + gesture_distance = 300 # how far is the "max" + gesture_positive = true # positive = swipe down. Negative = swipe up. } } diff --git a/hyprexpo/main.cpp b/hyprexpo/main.cpp index 096eba2..949d72e 100644 --- a/hyprexpo/main.cpp +++ b/hyprexpo/main.cpp @@ -63,16 +63,21 @@ static void hkAddDamageB(void* thisptr, const pixman_region32_t* rg) { static float gestured = 0; -static void hkSwipeBegin(void* thisptr, wlr_pointer_swipe_begin_event* e) { +// +static void swipeBegin(void* self, SCallbackInfo& info, std::any param) { static auto* const* PENABLE = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprexpo:enable_gesture")->getDataStaticPtr(); - if (g_pOverview) + if (g_pOverview) { + info.cancelled = true; return; + } - if (!**PENABLE || e->fingers != 4) { - ((origSwipeBegin)g_pSwipeBeginHook->m_pOriginal)(thisptr, e); + auto e = std::any_cast(param); + + if (!**PENABLE || e->fingers != 4) return; - } + + info.cancelled = true; renderingOverview = true; g_pOverview = std::make_unique(g_pCompositor->m_pLastMonitor->activeWorkspace, true); @@ -81,22 +86,26 @@ static void hkSwipeBegin(void* thisptr, wlr_pointer_swipe_begin_event* e) { gestured = 0; } -static void hkSwipeUpdate(void* thisptr, wlr_pointer_swipe_update_event* e) { - if (!g_pOverview) { - ((origSwipeUpdate)g_pSwipeUpdateHook->m_pOriginal)(thisptr, e); +static void swipeUpdate(void* self, SCallbackInfo& info, std::any param) { + if (!g_pOverview) return; - } - gestured += e->dy; + static auto* const* PPOSITIVE = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprexpo:gesture_positive")->getDataStaticPtr(); + + info.cancelled = true; + + auto e = std::any_cast(param); + + gestured += (**PPOSITIVE ? 1.0 : -1.0) * e->dy; g_pOverview->onSwipeUpdate(gestured); } -static void hkSwipeEnd(void* thisptr, wlr_pointer_swipe_end_event* e) { - if (!g_pOverview) { - ((origSwipeEnd)g_pSwipeEndHook->m_pOriginal)(thisptr, e); +static void swipeEnd(void* self, SCallbackInfo& info, std::any param) { + if (!g_pOverview) return; - } + + info.cancelled = true; g_pOverview->onSwipeEnd(); } @@ -157,31 +166,9 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) { g_pAddDamageHookA = HyprlandAPI::createFunctionHook(PHANDLE, FNS[0].address, (void*)hkAddDamageA); - FNS = HyprlandAPI::findFunctionsByName(PHANDLE, "onSwipeBegin"); - if (FNS.empty()) - throw std::runtime_error("[he] No fns for hook onSwipeBegin"); - - g_pSwipeBeginHook = HyprlandAPI::createFunctionHook(PHANDLE, FNS[0].address, (void*)hkSwipeBegin); - - FNS = HyprlandAPI::findFunctionsByName(PHANDLE, "onSwipeEnd"); - if (FNS.empty()) - throw std::runtime_error("[he] No fns for hook onSwipeEnd"); - - g_pSwipeEndHook = HyprlandAPI::createFunctionHook(PHANDLE, FNS[0].address, (void*)hkSwipeEnd); - - FNS = HyprlandAPI::findFunctionsByName(PHANDLE, "onSwipeUpdate"); - if (FNS.empty()) - throw std::runtime_error("[he] No fns for hook onSwipeUpdate"); - - g_pSwipeUpdateHook = HyprlandAPI::createFunctionHook(PHANDLE, FNS[0].address, (void*)hkSwipeUpdate); - bool success = g_pRenderWorkspaceHook->hook(); success = success && g_pAddDamageHookA->hook(); success = success && g_pAddDamageHookB->hook(); - // mega buggy, I'll have to fix it one day. - // success = success && g_pSwipeBeginHook->hook(); - // success = success && g_pSwipeEndHook->hook(); - // success = success && g_pSwipeUpdateHook->hook(); if (!success) throw std::runtime_error("[he] Failed initializing hooks"); @@ -192,6 +179,10 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) { g_pOverview->onPreRender(); }); + HyprlandAPI::registerCallbackDynamic(PHANDLE, "swipeBegin", [](void* self, SCallbackInfo& info, std::any data) { swipeBegin(self, info, data); }); + HyprlandAPI::registerCallbackDynamic(PHANDLE, "swipeEnd", [](void* self, SCallbackInfo& info, std::any data) { swipeEnd(self, info, data); }); + HyprlandAPI::registerCallbackDynamic(PHANDLE, "swipeUpdate", [](void* self, SCallbackInfo& info, std::any data) { swipeUpdate(self, info, data); }); + HyprlandAPI::addDispatcher(PHANDLE, "hyprexpo:expo", onExpoDispatcher); HyprlandAPI::addConfigValue(PHANDLE, "plugin:hyprexpo:columns", Hyprlang::INT{3}); @@ -200,6 +191,8 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) { HyprlandAPI::addConfigValue(PHANDLE, "plugin:hyprexpo:workspace_method", Hyprlang::STRING{"center current"}); HyprlandAPI::addConfigValue(PHANDLE, "plugin:hyprexpo:enable_gesture", Hyprlang::INT{1}); + HyprlandAPI::addConfigValue(PHANDLE, "plugin:hyprexpo:gesture_distance", Hyprlang::INT{200}); + HyprlandAPI::addConfigValue(PHANDLE, "plugin:hyprexpo:gesture_positive", Hyprlang::INT{1}); HyprlandAPI::reloadConfig(); diff --git a/hyprexpo/overview.cpp b/hyprexpo/overview.cpp index fa9e1c2..4ded8ba 100644 --- a/hyprexpo/overview.cpp +++ b/hyprexpo/overview.cpp @@ -388,12 +388,17 @@ static Vector2D lerp(const Vector2D& from, const Vector2D& to, const float perc) } void COverview::onSwipeUpdate(double delta) { - const float PERC = std::clamp(delta / 300.0, 0.0, 1.0); + if (swipeWasCommenced) + return; - Vector2D tileSize = (pMonitor->vecSize / SIDE_LENGTH); + static auto* const* PDISTANCE = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprexpo:gesture_distance")->getDataStaticPtr(); + + const float PERC = 1.0 - std::clamp(delta / (double)**PDISTANCE, 0.0, 1.0); - const auto SIZEMAX = pMonitor->vecSize * pMonitor->vecSize / tileSize; - const auto POSMAX = + Vector2D tileSize = (pMonitor->vecSize / SIDE_LENGTH); + + const auto SIZEMAX = pMonitor->vecSize * pMonitor->vecSize / tileSize; + const auto POSMAX = (-((pMonitor->vecSize / (double)SIDE_LENGTH) * Vector2D{openedID % SIDE_LENGTH, openedID / SIDE_LENGTH}) * pMonitor->scale) * (pMonitor->vecSize / tileSize); const auto SIZEMIN = pMonitor->vecSize; @@ -408,4 +413,6 @@ void COverview::onSwipeEnd() { pos = {0, 0}; size.setCallbackOnEnd([this](void*) { redrawAll(true); }); + + swipeWasCommenced = true; } \ No newline at end of file diff --git a/hyprexpo/overview.hpp b/hyprexpo/overview.hpp index dda3d36..4e75c02 100644 --- a/hyprexpo/overview.hpp +++ b/hyprexpo/overview.hpp @@ -71,7 +71,8 @@ class COverview { HOOK_CALLBACK_FN* mouseMoveHook = nullptr; HOOK_CALLBACK_FN* mouseButtonHook = nullptr; - bool swipe = false; + bool swipe = false; + bool swipeWasCommenced = false; }; inline std::unique_ptr g_pOverview; \ No newline at end of file