Skip to content

Commit

Permalink
expo: add gesture support
Browse files Browse the repository at this point in the history
  • Loading branch information
vaxerski committed Apr 3, 2024
1 parent 455b2d8 commit 477fb57
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 41 deletions.
3 changes: 3 additions & 0 deletions hyprexpo/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
}
}

Expand Down
65 changes: 29 additions & 36 deletions hyprexpo/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<wlr_pointer_swipe_begin_event*>(param);

if (!**PENABLE || e->fingers != 4)
return;
}

info.cancelled = true;

renderingOverview = true;
g_pOverview = std::make_unique<COverview>(g_pCompositor->m_pLastMonitor->activeWorkspace, true);
Expand All @@ -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<wlr_pointer_swipe_update_event*>(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();
}
Expand Down Expand Up @@ -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");
Expand All @@ -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});
Expand All @@ -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();

Expand Down
15 changes: 11 additions & 4 deletions hyprexpo/overview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -408,4 +413,6 @@ void COverview::onSwipeEnd() {
pos = {0, 0};

size.setCallbackOnEnd([this](void*) { redrawAll(true); });

swipeWasCommenced = true;
}
3 changes: 2 additions & 1 deletion hyprexpo/overview.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<COverview> g_pOverview;

0 comments on commit 477fb57

Please sign in to comment.